chore: Remove FlagRouter from core (#4710)

* Allow nested feature flags

* clean up

* Create loud-wombats-shave.md

* add warning

* Add more tests

* Address PR comments

* add back boolean check

* Replace core flag router with utils one

* lol - actually remove it

* Create eleven-doors-roll.md

---------

Co-authored-by: carlos-r-l-rodrigues <rodrigolr@gmail.com>
This commit is contained in:
Oli Juhl
2023-08-08 13:05:50 +02:00
committed by GitHub
co-authored by carlos-r-l-rodrigues
parent 281b0746cf
commit d1e298f5dc
54 changed files with 495 additions and 593 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
chore: Remove FlagRouter from core
@@ -1,5 +1,5 @@
import { FlagRouter } from "@medusajs/utils"
import { NextFunction, Request, Response } from "express"
import { FlagRouter } from "../../utils/flag-router"
export function isFeatureFlagEnabled(
flagKey: string
@@ -1,7 +1,7 @@
import { FlagRouter } from "@medusajs/utils"
import { NextFunction, Request, Response } from "express"
import SalesChannelFeatureFlag from "../../loaders/feature-flags/sales-channels"
import { SalesChannelService } from "../../services"
import { FlagRouter } from "../../utils/flag-router"
/**
* Middleware that includes the default sales channel on the request, if no sales channels present
@@ -1,81 +1,81 @@
import { FlagRouter } from "@medusajs/utils"
import { Router } from "express"
import "reflect-metadata"
import { Order } from "../../../.."
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { FindParams, PaginatedResponse } from "../../../../types/common"
import { FlagRouter } from "../../../../utils/flag-router"
import {
defaultAdminOrdersFields,
defaultAdminOrdersRelations,
} from "../../../../types/orders"
import middlewares, {
transformBody,
transformIncludesOptions,
transformQuery,
} from "../../../middlewares"
import { checkRegisteredModules } from "../../../middlewares/check-registered-modules"
import { AdminOrdersOrderLineItemReservationReq } from "./create-reservation-for-line-item"
import { AdminGetOrdersOrderReservationsParams } from "./get-reservations"
import { AdminGetOrdersParams } from "./list-orders"
import {
AdminPostOrdersOrderSwapsParams,
AdminPostOrdersOrderSwapsReq,
} from "./create-swap"
import {
AdminPostOrdersOrderParams,
AdminPostOrdersOrderReq,
} from "./update-order"
import { AdminPostOrdersOrderCompleteParams } from "./complete-order"
import {
AdminPostOrdersOrderRefundsParams,
AdminPostOrdersOrderRefundsReq,
} from "./refund-payment"
import { AdminPostOrdersOrderCaptureParams } from "./capture-payment"
import {
AdminPostOrdersOrderFulfillmentsParams,
AdminPostOrdersOrderFulfillmentsReq,
} from "./create-fulfillment"
import { AdminPostOrdersOrderFulfillementsCancelParams } from "./cancel-fulfillment"
import { AdminPostOrdersOrderSwapFulfillementsCancelParams } from "./cancel-fulfillment-swap"
import { AdminPostOrdersClaimFulfillmentsCancelParams } from "./cancel-fulfillment-claim"
import {
AdminPostOrdersOrderShipmentParams,
AdminPostOrdersOrderShipmentReq,
} from "./create-shipment"
import {
AdminPostOrdersOrderReturnsParams,
AdminPostOrdersOrderReturnsReq,
} from "./request-return"
import { AdminPostOrdersOrderCancel } from "./cancel-order"
import {
AdminPostOrdersOrderShippingMethodsParams,
AdminPostOrdersOrderShippingMethodsReq,
} from "./add-shipping-method"
import { AdminPostOrdersOrderArchiveParams } from "./archive-order"
import { AdminPostOrdersClaimCancel } from "./cancel-claim"
import { AdminPostOrdersOrderFulfillementsCancelParams } from "./cancel-fulfillment"
import { AdminPostOrdersClaimFulfillmentsCancelParams } from "./cancel-fulfillment-claim"
import { AdminPostOrdersOrderSwapFulfillementsCancelParams } from "./cancel-fulfillment-swap"
import { AdminPostOrdersOrderCancel } from "./cancel-order"
import { AdminPostOrdersSwapCancelParams } from "./cancel-swap"
import { AdminPostOrdersOrderSwapsSwapFulfillmentsParams } from "./fulfill-swap"
import {
AdminPostOrdersOrderSwapsSwapShipmentsParams,
AdminPostOrdersOrderSwapsSwapShipmentsReq,
} from "./create-swap-shipment"
import { AdminPostOrdersOrderSwapsSwapProcessPaymentParams } from "./process-swap-payment"
import { AdminPostOrdersOrderCaptureParams } from "./capture-payment"
import { AdminPostOrdersOrderCompleteParams } from "./complete-order"
import {
AdminPostOrdersOrderClaimsParams,
AdminPostOrdersOrderClaimsReq,
} from "./create-claim"
import { AdminPostOrdersClaimCancel } from "./cancel-claim"
import {
AdminPostOrdersOrderClaimsClaimParams,
AdminPostOrdersOrderClaimsClaimReq,
} from "./update-claim"
import {
AdminPostOrdersOrderClaimsClaimFulfillmentsParams,
AdminPostOrdersOrderClaimsClaimFulfillmentsReq,
} from "./fulfill-claim"
import {
AdminPostOrdersOrderClaimsClaimShipmentsParams,
AdminPostOrdersOrderClaimsClaimShipmentsReq,
} from "./create-claim-shipment"
import {
defaultAdminOrdersFields,
defaultAdminOrdersRelations,
} from "../../../../types/orders"
AdminPostOrdersOrderFulfillmentsParams,
AdminPostOrdersOrderFulfillmentsReq,
} from "./create-fulfillment"
import { AdminOrdersOrderLineItemReservationReq } from "./create-reservation-for-line-item"
import {
AdminPostOrdersOrderShipmentParams,
AdminPostOrdersOrderShipmentReq,
} from "./create-shipment"
import {
AdminPostOrdersOrderSwapsParams,
AdminPostOrdersOrderSwapsReq,
} from "./create-swap"
import {
AdminPostOrdersOrderSwapsSwapShipmentsParams,
AdminPostOrdersOrderSwapsSwapShipmentsReq,
} from "./create-swap-shipment"
import {
AdminPostOrdersOrderClaimsClaimFulfillmentsParams,
AdminPostOrdersOrderClaimsClaimFulfillmentsReq,
} from "./fulfill-claim"
import { AdminPostOrdersOrderSwapsSwapFulfillmentsParams } from "./fulfill-swap"
import { AdminGetOrdersOrderReservationsParams } from "./get-reservations"
import { AdminGetOrdersParams } from "./list-orders"
import { AdminPostOrdersOrderSwapsSwapProcessPaymentParams } from "./process-swap-payment"
import {
AdminPostOrdersOrderRefundsParams,
AdminPostOrdersOrderRefundsReq,
} from "./refund-payment"
import {
AdminPostOrdersOrderReturnsParams,
AdminPostOrdersOrderReturnsReq,
} from "./request-return"
import {
AdminPostOrdersOrderClaimsClaimParams,
AdminPostOrdersOrderClaimsClaimReq,
} from "./update-claim"
import {
AdminPostOrdersOrderParams,
AdminPostOrdersOrderReq,
} from "./update-order"
const route = Router()
@@ -779,3 +779,4 @@ export * from "./refund-payment"
export * from "./request-return"
export * from "./update-claim"
export * from "./update-order"
@@ -1,20 +1,20 @@
import { FlagRouter } from "@medusajs/utils"
import { Router } from "express"
import "reflect-metadata"
import { PriceList, Product } from "../../../.."
import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing"
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
import middlewares, {
transformBody,
transformQuery,
} from "../../../middlewares"
import { AdminGetPriceListPaginationParams } from "./list-price-lists"
import { AdminGetPriceListsPriceListProductsParams } from "./list-price-list-products"
import {
defaultAdminProductFields,
defaultAdminProductRelations,
} from "../products"
import { AdminPostPriceListsPriceListReq } from "./create-price-list"
import { FlagRouter } from "../../../../utils/flag-router"
import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing"
import { AdminGetPriceListsPriceListProductsParams } from "./list-price-list-products"
import { AdminGetPriceListPaginationParams } from "./list-price-lists"
const route = Router()
@@ -280,8 +280,9 @@ export type AdminPriceListsProductsListRes = PaginatedResponse & {
export * from "./add-prices-batch"
export * from "./create-price-list"
export * from "./delete-price-list"
export * from "./delete-prices-batch"
export * from "./get-price-list"
export * from "./list-price-list-products"
export * from "./list-price-lists"
export * from "./update-price-list"
export * from "./delete-prices-batch"
export * from "./list-price-list-products"
@@ -1,14 +1,14 @@
import "reflect-metadata"
import { FindParams, PaginatedResponse } from "../../../../types/common"
import { Product, ProductTag, ProductType, ProductVariant } from "../../../.."
import { FindParams, PaginatedResponse } from "../../../../types/common"
import middlewares, { transformQuery } from "../../../middlewares"
import { AdminGetProductsParams } from "./list-products"
import { FlagRouter } from "../../../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import { Router } from "express"
import { validateSalesChannelsExist } from "../../../middlewares/validators/sales-channel-existence"
import { PricedProduct } from "../../../../types/pricing"
import { validateSalesChannelsExist } from "../../../middlewares/validators/sales-channel-existence"
import { AdminGetProductsParams } from "./list-products"
const route = Router()
@@ -407,3 +407,4 @@ export * from "./set-metadata"
export * from "./update-option"
export * from "./update-product"
export * from "./update-variant"
@@ -1,10 +1,10 @@
import { FlagRouter } from "@medusajs/utils"
import { Router } from "express"
import "reflect-metadata"
import { Region } from "../../../.."
import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing"
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
import middlewares from "../../../middlewares"
import "reflect-metadata"
import { FlagRouter } from "../../../../utils/flag-router"
import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing"
const route = Router()
@@ -204,9 +204,10 @@ export class AdminGetRegionsRegionFulfillmentOptionsRes {
fulfillment_options: FulfillmentOption[]
}
export * from "./add-country"
export * from "./add-fulfillment-provider"
export * from "./add-payment-provider"
export * from "./create-region"
export * from "./list-regions"
export * from "./update-region"
export * from "./create-region"
export * from "./add-country"
export * from "./add-payment-provider"
export * from "./add-fulfillment-provider"
@@ -1,9 +1,9 @@
import { FlagRouter } from "@medusajs/utils"
import { Router } from "express"
import { ShippingOption } from "../../../.."
import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing"
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
import middlewares from "../../../middlewares"
import { FlagRouter } from "../../../../utils/flag-router"
import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing"
const route = Router()
@@ -139,3 +139,4 @@ export * from "./delete-shipping-option"
export * from "./get-shipping-option"
export * from "./list-shipping-options"
export * from "./update-shipping-option"
@@ -1,4 +1,5 @@
import { ModulesHelper } from "@medusajs/modules-sdk"
import { FlagRouter } from "@medusajs/utils"
import { defaultRelationsExtended } from "."
import {
FulfillmentProviderService,
@@ -6,7 +7,6 @@ import {
StoreService,
} from "../../../../services"
import { ExtendedStoreDTO } from "../../../../types/store"
import { FlagRouter } from "../../../../utils/flag-router"
/**
* @oas [get] /admin/store
@@ -17,6 +17,7 @@ import reqIp from "request-ip"
import { EntityManager } from "typeorm"
import { Logger } from "@medusajs/types"
import { FlagRouter } from "@medusajs/utils"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { Cart, LineItem } from "../../../../models"
@@ -28,7 +29,6 @@ import {
import { CartCreateProps } from "../../../../types/cart"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { FlagRouter } from "../../../../utils/flag-router"
/**
* @oas [post] /store/carts
@@ -1,10 +1,10 @@
import { FlagRouter } from "@medusajs/utils"
import { AwilixContainer } from "awilix"
import { EntityManager } from "typeorm"
import { Cart } from "../../../../../../models"
import { CartService, LineItemService } from "../../../../../../services"
import { WithRequiredProperty } from "../../../../../../types/common"
import { IdempotencyCallbackResult } from "../../../../../../types/idempotency-key"
import { FlagRouter } from "../../../../../../utils/flag-router"
import { defaultStoreCartFields, defaultStoreCartRelations } from "../../index"
export const CreateLineItemSteps = {
@@ -2,17 +2,17 @@ import "reflect-metadata"
import middlewares, { transformStoreQuery } from "../../../middlewares"
import { FlagRouter } from "../../../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import { Router } from "express"
import { Product } from "../../../.."
import { PaginatedResponse } from "../../../../types/common"
import { PricedProduct } from "../../../../types/pricing"
import { Product } from "../../../.."
import { Router } from "express"
import { StoreGetProductsParams } from "./list-products"
import { StoreGetProductsProductParams } from "./get-product"
import { extendRequestParams } from "../../../middlewares/publishable-api-key/extend-request-params"
import { validateProductSalesChannelAssociation } from "../../../middlewares/publishable-api-key/validate-product-sales-channel-association"
import { validateSalesChannelParam } from "../../../middlewares/publishable-api-key/validate-sales-channel-param"
import { withDefaultSalesChannel } from "../../../middlewares/with-default-sales-channel"
import { StoreGetProductsProductParams } from "./get-product"
import { StoreGetProductsParams } from "./list-products"
const route = Router()
+11 -11
View File
@@ -1,14 +1,18 @@
import { FlagRouter } from "@medusajs/utils"
import { AwilixContainer } from "awilix"
import {
BaseFulfillmentService,
BaseNotificationService,
BasePaymentService,
} from "medusa-interfaces"
import { currencies } from "../utils/currencies"
import { countries } from "../utils/countries"
import { AwilixContainer } from "awilix"
import { Logger } from "../types/global"
import { EntityManager } from "typeorm"
import {
AbstractPaymentProcessor,
AbstractPaymentService,
AbstractTaxService,
} from "../interfaces"
import { CountryRepository } from "../repositories/country"
import { CurrencyRepository } from "../repositories/currency"
import {
FulfillmentProviderService,
NotificationService,
@@ -18,14 +22,10 @@ import {
StoreService,
TaxProviderService,
} from "../services"
import { CurrencyRepository } from "../repositories/currency"
import { FlagRouter } from "../utils/flag-router"
import { Logger } from "../types/global"
import { countries } from "../utils/countries"
import { currencies } from "../utils/currencies"
import SalesChannelFeatureFlag from "./feature-flags/sales-channels"
import {
AbstractPaymentProcessor,
AbstractPaymentService,
AbstractTaxService,
} from "../interfaces"
const silentResolution = <T>(
container: AwilixContainer,
@@ -1,7 +1,6 @@
import { FlagRouter } from "@medusajs/utils"
import { asClass, asValue, createContainer } from "awilix"
import { IdMap, MockManager } from "medusa-test-utils"
import { taxProviderServiceMock } from "../__mocks__/tax-provider"
import { FlagRouter } from "../../utils/flag-router"
import {
GiftCard,
LineItem,
@@ -10,6 +9,7 @@ import {
ShippingMethodTaxLine,
} from "../../models"
import TaxCalculationStrategy from "../../strategies/tax-calculation"
import { taxProviderServiceMock } from "../__mocks__/tax-provider"
export const defaultContainerMock = createContainer()
defaultContainerMock.register("manager", asValue(MockManager))
@@ -1,18 +1,18 @@
import { FlagRouter } from "@medusajs/utils"
import { asClass, asFunction, asValue, createContainer } from "awilix"
import { MockManager, MockRepository } from "medusa-test-utils"
import PaymentProviderService from "../payment-provider"
import { PaymentProviderServiceMock } from "../__mocks__/payment-provider"
import { CustomerServiceMock } from "../__mocks__/customer"
import { FlagRouter } from "../../utils/flag-router"
import Logger from "../../loaders/logger"
import {
AbstractPaymentProcessor,
PaymentProcessorContext,
PaymentProcessorError,
PaymentProcessorSessionResponse,
} from "../../interfaces"
import Logger from "../../loaders/logger"
import { PaymentSessionStatus } from "../../models"
import { CustomerServiceMock } from "../__mocks__/customer"
import { PaymentServiceMock } from "../__mocks__/payment"
import { PaymentProviderServiceMock } from "../__mocks__/payment-provider"
import PaymentProviderService from "../payment-provider"
export const defaultContainer = createContainer()
defaultContainer.register(
@@ -2,7 +2,7 @@ import _ from "lodash"
import { asClass, asValue, createContainer } from "awilix"
import { MedusaError } from "medusa-core-utils"
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import CartService from "../cart"
import { ProductVariantInventoryServiceMock } from "../__mocks__/product-variant-inventory"
import { LineItemAdjustmentServiceMock } from "../__mocks__/line-item-adjustment"
@@ -1,7 +1,7 @@
import { FlagRouter } from "@medusajs/utils"
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
import { Currency } from "../../models"
import { FlagRouter } from "../../utils/flag-router"
import CurrencyService from "../currency"
import EventBusService from "../event-bus"
@@ -1,5 +1,5 @@
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import DiscountService from "../discount"
import { TotalsServiceMock } from "../__mocks__/totals"
import { newTotalsServiceMock } from "../__mocks__/new-totals"
@@ -1,5 +1,5 @@
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import LineItemService from "../line-item"
import { PricingServiceMock } from "../__mocks__/pricing"
import { ProductVariantServiceMock } from "../__mocks__/product-variant"
@@ -1,14 +1,7 @@
import { FlagRouter } from "@medusajs/utils"
import { asClass, asValue, createContainer } from "awilix"
import {
defaultContainerMock,
giftCards,
giftCardsWithTaxRate,
lineItems,
shippingMethods,
} from "../__fixtures__/new-totals"
import { NewTotalsService } from "../index"
import { TaxCalculationContext } from "../../interfaces"
import { taxProviderServiceMock } from "../__mocks__/tax-provider"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
import {
Discount,
DiscountRuleType,
@@ -17,8 +10,15 @@ import {
Region,
ShippingMethod,
} from "../../models"
import { FlagRouter } from "../../utils/flag-router"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
import {
defaultContainerMock,
giftCards,
giftCardsWithTaxRate,
lineItems,
shippingMethods,
} from "../__fixtures__/new-totals"
import { taxProviderServiceMock } from "../__mocks__/tax-provider"
import { NewTotalsService } from "../index"
describe("New totals service", () => {
describe("Without [MEDUSA_FF_TAX_INCLUSIVE_PRICING]", () => {
@@ -1,7 +1,7 @@
import { MedusaError } from "medusa-core-utils"
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import { MoneyAmountRepository } from "../../repositories/money-amount"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import PriceListService from "../price-list"
import { RegionServiceMock } from "../__mocks__/region"
@@ -1,6 +1,6 @@
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import ProductService from "../product"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
const eventBusService = {
emit: jest.fn(),
@@ -1,6 +1,6 @@
import { FlagRouter } from "@medusajs/utils"
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import { CreateRegionInput } from "../../types/region"
import { FlagRouter } from "../../utils/flag-router"
import EventBusService from "../event-bus"
import {
FulfillmentProviderService,
@@ -1,6 +1,6 @@
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import ShippingOptionService from "../shipping-option"
describe("ShippingOptionService", () => {
@@ -1,6 +1,6 @@
import { IdMap } from "medusa-test-utils"
import TotalsService from "../totals"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
import { calculatePriceTaxAmount } from "../../utils"
+5 -5
View File
@@ -1,9 +1,10 @@
import { FlagRouter } from "@medusajs/utils"
import { isEmpty, isEqual } from "lodash"
import { isDefined, MedusaError } from "medusa-core-utils"
import { MedusaError, isDefined } from "medusa-core-utils"
import { DeepPartial, EntityManager, In, IsNull, Not } from "typeorm"
import {
CustomerService,
CustomShippingOptionService,
CustomerService,
DiscountService,
EventBusService,
GiftCardService,
@@ -26,8 +27,8 @@ import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
import {
Address,
Cart,
Customer,
CustomShippingOption,
Customer,
Discount,
DiscountRule,
DiscountRuleType,
@@ -46,9 +47,9 @@ import {
CartCreateProps,
CartUpdateProps,
FilterableCartProps,
isCart,
LineItemUpdate,
LineItemValidateData,
isCart,
} from "../types/cart"
import {
AddressPayload,
@@ -58,7 +59,6 @@ import {
} from "../types/common"
import { PaymentSessionInput } from "../types/payment"
import { buildQuery, isString, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import { validateEmail } from "../utils/is-email"
type InjectedDependencies = {
+1 -1
View File
@@ -1,3 +1,4 @@
import { FlagRouter } from "@medusajs/utils"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { TransactionBaseService } from "../interfaces"
@@ -7,7 +8,6 @@ import { CurrencyRepository } from "../repositories/currency"
import { FindConfig, Selector } from "../types/common"
import { UpdateCurrencyInput } from "../types/currency"
import { buildQuery } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import EventBusService from "./event-bus"
type InjectedDependencies = {
+1 -1
View File
@@ -1,3 +1,4 @@
import { FlagRouter } from "@medusajs/utils"
import { parse, toSeconds } from "iso8601-duration"
import { isEmpty, omit } from "lodash"
import { MedusaError, isDefined } from "medusa-core-utils"
@@ -44,7 +45,6 @@ import {
import { CalculationContextData } from "../types/totals"
import { buildQuery, setMetadata } from "../utils"
import { isFuture, isPast } from "../utils/date-helpers"
import { FlagRouter } from "../utils/flag-router"
import CustomerService from "./customer"
import DiscountConditionService from "./discount-condition"
import EventBusService from "./event-bus"
+1 -1
View File
@@ -2,6 +2,7 @@ import { MedusaError } from "medusa-core-utils"
import { EntityManager, In } from "typeorm"
import { DeepPartial } from "typeorm/common/DeepPartial"
import { FlagRouter } from "@medusajs/utils"
import { TransactionBaseService } from "../interfaces"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import {
@@ -17,7 +18,6 @@ import { FindConfig, Selector } from "../types/common"
import { GenerateInputData, GenerateLineItemContext } from "../types/line-item"
import { ProductVariantPricing } from "../types/pricing"
import { buildQuery, isString, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import {
PricingService,
ProductService,
+5 -5
View File
@@ -1,9 +1,12 @@
import { FlagRouter } from "@medusajs/utils"
import { MedusaError, isDefined } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import {
ITaxCalculationStrategy,
TaxCalculationContext,
TransactionBaseService,
} from "../interfaces"
import { EntityManager } from "typeorm"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import {
Discount,
DiscountRuleType,
@@ -14,12 +17,9 @@ import {
ShippingMethod,
ShippingMethodTaxLine,
} from "../models"
import { TaxProviderService } from "./index"
import { LineAllocationsMap } from "../types/totals"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { FlagRouter } from "../utils/flag-router"
import { calculatePriceTaxAmount } from "../utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { TaxProviderService } from "./index"
type LineItemTotals = {
unit_price: number
+2 -2
View File
@@ -2,6 +2,7 @@ import { IInventoryService } from "@medusajs/types"
import {
buildRelations,
buildSelects,
FlagRouter,
isDefined,
MedusaError,
} from "@medusajs/utils"
@@ -32,6 +33,7 @@ import {
TaxProviderService,
TotalsService,
} from "."
import { TransactionBaseService } from "../interfaces"
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
import {
Address,
@@ -50,7 +52,6 @@ import {
Swap,
TrackingLink,
} from "../models"
import { TransactionBaseService } from "../interfaces"
import { AddressRepository } from "../repositories/address"
import { OrderRepository } from "../repositories/order"
import { FindConfig, QuerySelector, Selector } from "../types/common"
@@ -61,7 +62,6 @@ import {
import { TotalsContext, UpdateOrderInput } from "../types/orders"
import { CreateShippingMethodDto } from "../types/shipping-options"
import { buildQuery, isString, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import EventBusService from "./event-bus"
export const ORDER_CART_ALREADY_EXISTS_ERROR = "Order from cart already exists"
@@ -1,5 +1,7 @@
import { FlagRouter } from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { BasePaymentService } from "medusa-interfaces"
import { EOL } from "os"
import { EntityManager } from "typeorm"
import {
AbstractPaymentProcessor,
@@ -26,10 +28,8 @@ import { FindConfig, Selector } from "../types/common"
import { Logger } from "../types/global"
import { CreatePaymentInput, PaymentSessionInput } from "../types/payment"
import { buildQuery, isString } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import { CustomerService } from "./index"
import PaymentService from "./payment"
import { EOL } from "os"
type PaymentProviderKey = `pp_${string}` | "systemPaymentProviderService"
type InjectedDependencies = {
+8 -8
View File
@@ -1,9 +1,13 @@
import { FlagRouter } from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { DeepPartial, EntityManager } from "typeorm"
import { CustomerGroupService } from "."
import { TransactionBaseService } from "../interfaces"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { CustomerGroup, PriceList, Product, ProductVariant } from "../models"
import { MoneyAmountRepository } from "../repositories/money-amount"
import { PriceListRepository } from "../repositories/price-list"
import { ProductVariantRepository } from "../repositories/product-variant"
import { FindConfig, Selector } from "../types/common"
import {
CreatePriceListInput,
@@ -12,16 +16,12 @@ import {
PriceListPriceUpdateInput,
UpdatePriceListInput,
} from "../types/price-list"
import ProductService from "./product"
import RegionService from "./region"
import { TransactionBaseService } from "../interfaces"
import { buildQuery } from "../utils"
import { FilterableProductProps } from "../types/product"
import ProductVariantService from "./product-variant"
import { FilterableProductVariantProps } from "../types/product-variant"
import { ProductVariantRepository } from "../repositories/product-variant"
import { FlagRouter } from "../utils/flag-router"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { buildQuery } from "../utils"
import ProductService from "./product"
import ProductVariantService from "./product-variant"
import RegionService from "./region"
type PriceListConstructorProps = {
manager: EntityManager
+1 -1
View File
@@ -1,3 +1,4 @@
import { FlagRouter } from "@medusajs/utils"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { ProductVariantService, RegionService, TaxProviderService } from "."
@@ -18,7 +19,6 @@ import {
} from "../types/pricing"
import { TaxServiceRate } from "../types/tax-service"
import { calculatePriceTaxAmount } from "../utils"
import { FlagRouter } from "../utils/flag-router"
type InjectedDependencies = {
manager: EntityManager
+4 -6
View File
@@ -1,3 +1,7 @@
import {
buildRelations,
buildSelects, FlagRouter, objectToStringPath
} from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager, In } from "typeorm"
import { ProductVariantService, SearchService } from "."
@@ -33,13 +37,7 @@ import {
UpdateProductInput,
} from "../types/product"
import { buildQuery, isString, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import EventBusService from "./event-bus"
import {
buildRelations,
buildSelects,
objectToStringPath,
} from "@medusajs/utils"
type InjectedDependencies = {
manager: EntityManager
+11 -11
View File
@@ -1,24 +1,24 @@
import { Country, Currency, Region } from "../models"
import { CreateRegionInput, UpdateRegionInput } from "../types/region"
import { DeepPartial, EntityManager } from "typeorm"
import { FindConfig, Selector } from "../types/common"
import { MedusaError, isDefined } from "medusa-core-utils"
import { DeepPartial, EntityManager } from "typeorm"
import { Country, Currency, Region } from "../models"
import { FindConfig, Selector } from "../types/common"
import { CreateRegionInput, UpdateRegionInput } from "../types/region"
import { buildQuery, setMetadata } from "../utils"
import { FlagRouter } from "@medusajs/utils"
import { TransactionBaseService } from "../interfaces"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { CountryRepository } from "../repositories/country"
import { CurrencyRepository } from "../repositories/currency"
import EventBusService from "./event-bus"
import { FlagRouter } from "../utils/flag-router"
import { FulfillmentProviderRepository } from "../repositories/fulfillment-provider"
import FulfillmentProviderService from "./fulfillment-provider"
import { PaymentProviderRepository } from "../repositories/payment-provider"
import { PaymentProviderService } from "./index"
import { RegionRepository } from "../repositories/region"
import StoreService from "./store"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { TaxProviderRepository } from "../repositories/tax-provider"
import { TransactionBaseService } from "../interfaces"
import { countries } from "../utils/countries"
import EventBusService from "./event-bus"
import FulfillmentProviderService from "./fulfillment-provider"
import { PaymentProviderService } from "./index"
import StoreService from "./store"
type InjectedDependencies = {
manager: EntityManager
@@ -1,3 +1,4 @@
import { FlagRouter } from "@medusajs/utils"
import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { TransactionBaseService } from "../interfaces"
@@ -22,7 +23,6 @@ import {
ValidatePriceTypeAndAmountInput,
} from "../types/shipping-options"
import { buildQuery, isString, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import FulfillmentProviderService from "./fulfillment-provider"
import RegionService from "./region"
+1 -1
View File
@@ -28,9 +28,9 @@ import {
} from "../types/totals"
import { NewTotalsService, TaxProviderService } from "./index"
import { FlagRouter } from "@medusajs/utils"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { calculatePriceTaxAmount } from "../utils"
import { FlagRouter } from "../utils/flag-router"
type ShippingMethodTotals = {
price: number
+1 -1
View File
@@ -1,3 +1,4 @@
import { FlagRouter } from "@medusajs/utils"
import jwt from "jsonwebtoken"
import { isDefined, MedusaError } from "medusa-core-utils"
import Scrypt from "scrypt-kdf"
@@ -13,7 +14,6 @@ import {
UpdateUserInput,
} from "../types/user"
import { buildQuery, setMetadata } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import { validateEmail } from "../utils/is-email"
import AnalyticsConfigService from "./analytics-config"
import EventBusService from "./event-bus"
@@ -1,10 +1,10 @@
import OrderExportStrategy from "../../../batch-jobs/order/export"
import { FlagRouter } from "@medusajs/utils"
import { IdMap, MockManager } from "medusa-test-utils"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { User } from "../../../../models"
import { BatchJobStatus } from "../../../../types/batch-job"
import { ordersToExport } from "../../../__fixtures__/order-export-data"
import { FlagRouter } from "../../../../utils/flag-router";
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels";
import OrderExportStrategy from "../../../batch-jobs/order/export"
const orderServiceMock = {
withTransaction: function (): any {
@@ -1,13 +1,13 @@
import ProductExportStrategy from "../../../batch-jobs/product/export"
import { FlagRouter } from "@medusajs/utils"
import { Request } from "express"
import { IdMap, MockManager } from "medusa-test-utils"
import { AdminPostBatchesReq, defaultAdminProductRelations, } from "../../../../api"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { User } from "../../../../models"
import { BatchJobStatus } from "../../../../types/batch-job"
import { productsToExport } from "../../../__fixtures__/product-export-data"
import { AdminPostBatchesReq, defaultAdminProductRelations, } from "../../../../api"
import ProductExportStrategy from "../../../batch-jobs/product/export"
import { ProductExportBatchJob } from "../../../batch-jobs/product/types"
import { Request } from "express"
import { FlagRouter } from "../../../../utils/flag-router"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
const productServiceMock = {
withTransaction: function () {
@@ -4,6 +4,7 @@ import { EntityManager } from "typeorm"
import { FileService } from "medusa-interfaces"
import { IdMap, MockManager } from "medusa-test-utils"
import { FlagRouter } from "@medusajs/utils"
import { User } from "../../../../models"
import {
BatchJobService,
@@ -13,7 +14,6 @@ import {
ShippingProfileService,
} from "../../../../services"
import { BatchJobStatus } from "../../../../types/batch-job"
import { FlagRouter } from "../../../../utils/flag-router"
import ProductImportStrategy from "../../../batch-jobs/product/import"
import { ProductImportInjectedProps } from "../../../batch-jobs/product/types"
@@ -1,4 +1,4 @@
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
import PriceSelectionStrategy from "../price-selection"
import { cacheServiceMock } from "../../services/__mocks__/cache"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
@@ -1,6 +1,6 @@
import TaxCalculationStrategy from "../tax-calculation"
import TaxInclusivePricingFeatureFlag from "../../loaders/feature-flags/tax-inclusive-pricing"
import { FlagRouter } from "../../utils/flag-router"
import { FlagRouter } from "@medusajs/utils"
const toTest = [
[
@@ -1,3 +1,4 @@
import { FlagRouter } from "@medusajs/utils"
import { EntityManager } from "typeorm"
import {
OrderDescriptor,
@@ -13,7 +14,6 @@ import { OrderService } from "../../../services"
import BatchJobService from "../../../services/batch-job"
import { BatchJobStatus } from "../../../types/batch-job"
import { FindConfig } from "../../../types/common"
import { FlagRouter } from "../../../utils/flag-router"
import { prepareListQuery } from "../../../utils/get-query-config"
type InjectedDependencies = {
@@ -2,11 +2,16 @@ import { EntityManager } from "typeorm"
import { humanizeAmount } from "medusa-core-utils"
import { FlagRouter } from "@medusajs/utils"
import { defaultAdminProductRelations } from "../../../api"
import { AbstractBatchJobStrategy, IFileService } from "../../../interfaces"
import ProductCategoryFeatureFlag from "../../../loaders/feature-flags/product-categories"
import SalesChannelFeatureFlag from "../../../loaders/feature-flags/sales-channels"
import { Product, ProductVariant } from "../../../models"
import { BatchJobService, ProductService } from "../../../services"
import { BatchJobStatus, CreateBatchJobInput } from "../../../types/batch-job"
import { defaultAdminProductRelations } from "../../../api"
import { FindProductConfig } from "../../../types/product"
import { csvCellContentFormatter } from "../../../utils"
import { prepareListQuery } from "../../../utils/get-query-config"
import {
DynamicProductExportDescriptor,
@@ -15,16 +20,11 @@ import {
ProductExportInjectedDependencies,
ProductExportPriceData,
} from "./types"
import { FindProductConfig } from "../../../types/product"
import { FlagRouter } from "../../../utils/flag-router"
import SalesChannelFeatureFlag from "../../../loaders/feature-flags/sales-channels"
import { csvCellContentFormatter } from "../../../utils"
import {
productCategoriesColumnsDefinition,
productColumnsDefinition,
productSalesChannelColumnsDefinition,
} from "./types/columns-definition"
import ProductCategoryFeatureFlag from "../../../loaders/feature-flags/product-categories"
export default class ProductExportStrategy extends AbstractBatchJobStrategy {
public static identifier = "product-export-strategy"
@@ -2,7 +2,9 @@
import { computerizeAmount, MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { FlagRouter } from "@medusajs/utils"
import { AbstractBatchJobStrategy, IFileService } from "../../../interfaces"
import ProductCategoryFeatureFlag from "../../../loaders/feature-flags/product-categories"
import SalesChannelFeatureFlag from "../../../loaders/feature-flags/sales-channels"
import { BatchJob, SalesChannel } from "../../../models"
import {
@@ -18,7 +20,6 @@ import {
import CsvParser from "../../../services/csv-parser"
import { CreateProductInput } from "../../../types/product"
import { CreateProductVariantInput } from "../../../types/product-variant"
import { FlagRouter } from "../../../utils/flag-router"
import {
OperationType,
ProductImportBatchJob,
@@ -29,11 +30,10 @@ import {
} from "./types"
import {
productImportColumnsDefinition,
productImportSalesChannelsColumnsDefinition,
productImportProductCategoriesColumnsDefinition,
productImportSalesChannelsColumnsDefinition,
} from "./types/columns-definition"
import { transformProductData, transformVariantData } from "./utils"
import ProductCategoryFeatureFlag from "../../../loaders/feature-flags/product-categories"
/**
* Process this many variant rows before reporting progress.
@@ -1,6 +1,9 @@
import { BatchJob, Product, ProductVariant } from "../../../../models"
import { Selector } from "../../../../types/common"
import { FlagRouter } from "@medusajs/utils"
import { FileService } from "medusa-interfaces"
import { EntityManager } from "typeorm"
import { IFileService } from "../../../../interfaces"
import { CsvSchema, CsvSchemaColumn } from "../../../../interfaces/csv-parser"
import { BatchJob, Product, ProductVariant } from "../../../../models"
import {
BatchJobService,
ProductCategoryService,
@@ -11,10 +14,7 @@ import {
SalesChannelService,
ShippingProfileService,
} from "../../../../services"
import { FileService } from "medusa-interfaces"
import { FlagRouter } from "../../../../utils/flag-router"
import { EntityManager } from "typeorm"
import { IFileService } from "../../../../interfaces"
import { Selector } from "../../../../types/common"
export type ProductExportInjectedDependencies = {
manager: EntityManager
@@ -5,13 +5,13 @@ import {
PriceType,
} from "../interfaces"
import { EntityManager } from "typeorm"
import { FlagRouter } from "../utils/flag-router"
import { ICacheService } from "@medusajs/types"
import { MoneyAmountRepository } from "../repositories/money-amount"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { TaxServiceRate } from "../types/tax-service"
import { FlagRouter } from "@medusajs/utils"
import { isDefined } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { MoneyAmountRepository } from "../repositories/money-amount"
import { TaxServiceRate } from "../types/tax-service"
class PriceSelectionStrategy extends AbstractPriceSelectionStrategy {
protected manager_: EntityManager
@@ -1,13 +1,13 @@
import { FlagRouter } from "@medusajs/utils"
import { ITaxCalculationStrategy, TaxCalculationContext } from "../interfaces"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import {
LineItem,
LineItemTaxLine,
ShippingMethod,
ShippingMethodTaxLine,
} from "../models"
import { ITaxCalculationStrategy, TaxCalculationContext } from "../interfaces"
import { calculatePriceTaxAmount } from "../utils"
import { FlagRouter } from "../utils/flag-router"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
class TaxCalculationStrategy implements ITaxCalculationStrategy {
protected readonly featureFlagRouter_: FlagRouter
@@ -1,11 +1,10 @@
import { IEventBusService, ISearchService } from "@medusajs/types"
import { defaultSearchIndexingProductRelations } from "@medusajs/utils"
import { FlagRouter, defaultSearchIndexingProductRelations } from "@medusajs/utils"
import { indexTypes } from "medusa-core-utils"
import ProductCategoryFeatureFlag from "../loaders/feature-flags/product-categories"
import { SEARCH_INDEX_EVENT } from "../loaders/search-index"
import { Product } from "../models"
import ProductService from "../services/product"
import { FlagRouter } from "../utils/flag-router"
type InjectedDependencies = {
eventBusService: IEventBusService
@@ -1,5 +1,5 @@
import { FlagRouter } from "@medusajs/utils"
import { calculatePriceTaxAmount } from "../calculate-price-tax-amount"
import { FlagRouter } from "../../utils/flag-router"
describe("calculatePriceTaxAmount", () => {
describe("Calculate taxes from a given price", () => {
@@ -1,30 +0,0 @@
import { FlagRouter } from "../flag-router"
describe("Flag Router", () => {
describe("listFlags", () => {
it("should list all feature flags", () => {
const flagRouter = new FlagRouter({})
flagRouter.setFlag("test", false)
flagRouter.setFlag("test2", true)
flagRouter.setFlag("test3", false)
const listOfFlags = flagRouter.listFlags()
expect(listOfFlags).toEqual([
{
key: "test",
value: false,
},
{
key: "test2",
value: true,
},
{
key: "test3",
value: false,
},
])
})
})
})
-75
View File
@@ -1,75 +0,0 @@
import { FeatureFlagTypes } from "@medusajs/types"
import { isObject, isString } from "@medusajs/utils"
export class FlagRouter implements FeatureFlagTypes.IFlagRouter {
private readonly flags: Record<string, boolean | Record<string, boolean>> = {}
constructor(flags: Record<string, boolean | Record<string, boolean>>) {
this.flags = flags
}
/**
* Check if a feature flag is enabled.
* There are two ways of using this method:
* 1. `isFeatureEnabled("myFeatureFlag")`
* 2. `isFeatureEnabled({ myNestedFeatureFlag: "someNestedFlag" })`
* We use 1. for top-level feature flags and 2. for nested feature flags. Almost all flags are top-level.
* An example of a nested flag is workflows. To use it, you would do:
* `isFeatureEnabled({ workflows: Workflows.CreateCart })`
* @param flag - The flag to check
* @return {boolean} - Whether the flag is enabled or not
*/
public isFeatureEnabled(flag: string | Record<string, string>): boolean {
if (isString(flag)) {
return !!this.flags[flag]
}
if (isObject(flag)) {
const [nestedFlag, value] = Object.entries(flag)[0]
if (typeof this.flags[nestedFlag] === "boolean") {
return this.flags[nestedFlag] as boolean
}
return !!this.flags[nestedFlag]?.[value]
}
throw Error("Flag must be a string or an object")
}
/**
* Sets a feature flag.
* Flags take two shapes:
* setFlag("myFeatureFlag", true)
* setFlag("myFeatureFlag", { nestedFlag: true })
* These shapes are used for top-level and nested flags respectively, as explained in isFeatureEnabled.
* @param key - The key of the flag to set.
* @param value - The value of the flag to set.
* @return {void} - void
*/
public setFlag(
key: string,
value: boolean | { [key: string]: boolean }
): void {
if (isObject(value)) {
const existing = this.flags[key]
if (!existing) {
this.flags[key] = value
return
}
this.flags[key] = { ...(this.flags[key] as object), ...value }
return
}
this.flags[key] = value
}
public listFlags(): FeatureFlagTypes.FeatureFlagsResponse {
return Object.entries(this.flags || {}).map(([key, value]) => ({
key,
value,
}))
}
}