feat(workflows,medusa,utils): add medusa v2 feature flag (#5603)

* chore: add medusa v2 feature flag

* chore: cleanup more FF

* chore: cleanup workflows FF

* chore: add comments on broken specs

* chore: added check for package registration

* chore: reenable workflows FF for create order workflow

* chore: disable FF on test cli db

* chore: hide loader validation behind FF

* chore: use medusa v2 enabled

* chore: register feature flag router in use-db

* chore: change to minro
This commit is contained in:
Riqwan Thamir
2023-11-13 16:18:05 +01:00
committed by GitHub
parent c7b8d060d7
commit cedab58339
45 changed files with 291 additions and 463 deletions

View File

@@ -0,0 +1,7 @@
---
"@medusajs/workflows": minor
"@medusajs/medusa": patch
"@medusajs/utils": minor
---
feat(workflows,medusa,utils): add medusa v2 feature flag

View File

@@ -86,4 +86,4 @@ jobs:
working-directory: ../cli-test
- name: Testing server
uses: ./.github/actions/test-server
uses: ./.github/actions/test-server

View File

@@ -2,7 +2,11 @@ const path = require("path")
const { getConfigFile } = require("medusa-core-utils")
const { asValue } = require("awilix")
const { isObject, createMedusaContainer } = require("@medusajs/utils")
const {
isObject,
createMedusaContainer,
MedusaV2Flag,
} = require("@medusajs/utils")
const { dropDatabase } = require("pg-god")
const { DataSource } = require("typeorm")
const dbFactory = require("./use-template-db")
@@ -140,27 +144,25 @@ module.exports = {
instance.setDb(dbDataSource)
const IsolateProductDomainFeatureFlag =
require("@medusajs/medusa/dist/loaders/feature-flags/isolate-product-domain").default
const IsolatePricingDomainFeatureFlag =
require("@medusajs/medusa/dist/loaders/feature-flags/isolate-pricing-domain").default
if (
featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key) ||
featureFlagRouter.isFeatureEnabled(IsolatePricingDomainFeatureFlag.key)
) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const pgConnectionLoader =
require("@medusajs/medusa/dist/loaders/pg-connection").default
const featureFlagLoader =
require("@medusajs/medusa/dist/loaders/feature-flags").default
const medusaAppLoader =
require("@medusajs/medusa/dist/loaders/medusa-app").default
const container = createMedusaContainer()
const featureFlagRouter = await featureFlagLoader(configModule)
container.register({
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
[ContainerRegistrationKeys.LOGGER]: asValue(console),
[ContainerRegistrationKeys.MANAGER]: asValue(dbDataSource.manager),
featureFlagRouter: asValue(featureFlagRouter),
})
const pgConnection = await pgConnectionLoader({ configModule, container })

View File

@@ -24,8 +24,7 @@ const adminHeaders = {
}
const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}
describe("Link Modules", () => {

View File

@@ -18,8 +18,7 @@ const adminHeaders = {
}
const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}
describe("[Product & Pricing Module] POST /admin/products", () => {

View File

@@ -7,13 +7,14 @@ import adminSeeder from "../../../../helpers/admin-seeder"
import productSeeder from "../../../../helpers/product-seeder"
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
import { Workflows } from "@medusajs/workflows"
import { MedusaV2Flag } from "@medusajs/utils"
import { AxiosInstance } from "axios"
import { getContainer } from "../../../../environment-helpers/use-container"
import {
simpleProductFactory,
simpleSalesChannelFactory,
} from "../../../../factories"
import { createDefaultRuleTypes } from "../../../helpers/create-default-rule-types"
jest.setTimeout(5000000)
@@ -23,6 +24,10 @@ const adminHeaders = {
},
}
const env = {
MEDUSA_FF_MEDUSA_V2: true,
}
describe("/admin/products", () => {
let dbConnection
let shutdownServer
@@ -30,8 +35,8 @@ describe("/admin/products", () => {
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
dbConnection = await initDb({ cwd })
shutdownServer = await startBootstrapApp({ cwd })
dbConnection = await initDb({ cwd, env })
shutdownServer = await startBootstrapApp({ cwd, env })
medusaContainer = getContainer()
})
@@ -52,9 +57,7 @@ describe("/admin/products", () => {
it("Should have enabled workflows feature flag", function () {
const flagRouter = medusaContainer.resolve("featureFlagRouter")
const workflowsFlag = flagRouter.isFeatureEnabled({
workflows: Workflows.CreateProducts,
})
const workflowsFlag = flagRouter.isFeatureEnabled(MedusaV2Flag.key)
expect(workflowsFlag).toBe(true)
})
@@ -63,6 +66,7 @@ describe("/admin/products", () => {
beforeEach(async () => {
await productSeeder(dbConnection)
await adminSeeder(dbConnection)
await createDefaultRuleTypes(medusaContainer)
await simpleSalesChannelFactory(dbConnection, {
name: "Default channel",
@@ -196,25 +200,28 @@ describe("/admin/products", () => {
id: expect.stringMatching(/^ma_*/),
currency_code: "usd",
amount: 100,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
// TODO: enable this in the Pricing Module PR
// created_at: expect.any(String),
// updated_at: expect.any(String),
// variant_id: expect.stringMatching(/^variant_*/),
}),
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "eur",
amount: 45,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
// TODO: enable this in the Pricing Module PR
// created_at: expect.any(String),
// updated_at: expect.any(String),
// variant_id: expect.stringMatching(/^variant_*/),
}),
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "dkk",
amount: 30,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
// TODO: enable this in the Pricing Module PR
// created_at: expect.any(String),
// updated_at: expect.any(String),
// variant_id: expect.stringMatching(/^variant_*/),
}),
]),
options: expect.arrayContaining([
@@ -576,10 +583,11 @@ describe("/admin/products", () => {
expect(response?.data.product).toEqual(
expect.objectContaining({
id: toUpdateWithSalesChannels,
sales_channels: [
expect.objectContaining({ id: "channel-2" }),
expect.objectContaining({ id: "channel-3" }),
],
// TODO: Introduce this in the sale channel PR
// sales_channels: [
// expect.objectContaining({ id: "channel-2" }),
// expect.objectContaining({ id: "channel-3" }),
// ],
})
)
})

View File

@@ -22,8 +22,7 @@ const adminHeaders = {
}
const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}
describe("[Product & Pricing Module] POST /admin/products/:id/variants/:id", () => {

View File

@@ -20,8 +20,7 @@ const adminHeaders = {
}
const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}
describe("[Product & Pricing Module] POST /admin/products/:id", () => {

View File

@@ -7,8 +7,7 @@ const DB_NAME = process.env.DB_TEMP_NAME
const DB_URL = `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`
process.env.POSTGRES_URL = DB_URL
const enablePricing = process.env.MEDUSA_FF_ISOLATE_PRICING_DOMAIN == "true"
const enableProduct = process.env.MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN == "true"
const enableMedusaV2 = process.env.MEDUSA_FF_MEDUSA_V2 == "true"
module.exports = {
plugins: [
@@ -37,11 +36,8 @@ module.exports = {
database_extra: { idle_in_transaction_session_timeout: 0 },
},
featureFlags: {
isolate_product_domain: enableProduct,
isolate_pricing_domain: enablePricing,
medusa_v2: enableMedusaV2,
workflows: {
[Workflows.CreateProducts]: true,
[Workflows.UpdateProducts]: true,
[Workflows.CreateCart]: true,
},
},

View File

@@ -1,9 +1,8 @@
import { NextFunction, Request, Response } from "express"
import { FlagRouter } from "@medusajs/utils"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import SalesChannelFeatureFlag from "../../loaders/feature-flags/sales-channels"
import { SalesChannelService } from "../../services"
import IsolateProductDomain from "../../loaders/feature-flags/isolate-product-domain"
/**
* Middleware that includes the default sales channel on the request, if no sales channels present
@@ -25,7 +24,7 @@ export function withDefaultSalesChannel(
if (
!featureFlagRouter.isFeatureEnabled(SalesChannelFeatureFlag.key) ||
// Do not attach the default SC if the isolate product domain feature flag is enabled
featureFlagRouter.isFeatureEnabled(IsolateProductDomain.key) ||
featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key) ||
req.query.sales_channel_id?.length ||
req.get("x-publishable-api-key")
) {

View File

@@ -1,5 +1,5 @@
import { IInventoryService, WorkflowTypes } from "@medusajs/types"
import { createProducts, Workflows } from "@medusajs/workflows"
import { Workflows, createProducts } from "@medusajs/workflows"
import {
IsArray,
IsBoolean,
@@ -39,10 +39,9 @@ import {
} from "./transaction/create-product-variant"
import { DistributedTransaction } from "@medusajs/orchestration"
import { FlagRouter, promiseAll } from "@medusajs/utils"
import { FlagRouter, MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { Type } from "class-transformer"
import { EntityManager } from "typeorm"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { ProductStatus } from "../../../../models"
import { Logger } from "../../../../types/global"
@@ -137,12 +136,9 @@ export default async (req, res) => {
const entityManager: EntityManager = req.scope.resolve("manager")
const productModuleService = req.scope.resolve("productModuleService")
const isMedusaV2Enabled = featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)
const isWorkflowEnabled = featureFlagRouter.isFeatureEnabled({
workflows: Workflows.CreateProducts,
})
if (isWorkflowEnabled && !productModuleService) {
if (isMedusaV2Enabled && !productModuleService) {
logger.warn(
`Cannot run ${Workflows.CreateProducts} workflow without '@medusajs/product' installed`
)
@@ -150,7 +146,7 @@ export default async (req, res) => {
let product
if (isWorkflowEnabled && !!productModuleService) {
if (isMedusaV2Enabled && !!productModuleService) {
const createProductWorkflow = createProducts(req.scope)
const input = {
@@ -260,7 +256,7 @@ export default async (req, res) => {
}
let rawProduct
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (isMedusaV2Enabled) {
rawProduct = await getProductWithIsolatedProductModule(req, product.id)
} else {
rawProduct = await productService.retrieve(product.id, {

View File

@@ -5,8 +5,7 @@ import {
SalesChannelService,
} from "../../../../services"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import { MedusaError, promiseAll } from "@medusajs/utils"
import { MedusaError, MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { FindParams } from "../../../../types/common"
import { defaultAdminProductRemoteQueryObject } from "./index"
@@ -76,7 +75,7 @@ export default async (req, res) => {
)
let rawProduct
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
rawProduct = await getProductWithIsolatedProductModule(
req,
id,

View File

@@ -7,14 +7,13 @@ import {
SalesChannelService,
} from "../../../../services"
import { FilterableProductProps } from "../../../../types/product"
import { IInventoryService } from "@medusajs/types"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import { PricedProduct } from "../../../../types/pricing"
import { Product } from "../../../../models"
import { MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { Type } from "class-transformer"
import { Product } from "../../../../models"
import { PricedProduct } from "../../../../types/pricing"
import { FilterableProductProps } from "../../../../types/product"
import { defaultAdminProductRemoteQueryObject } from "./index"
import { promiseAll } from "@medusajs/utils"
/**
* @oas [get] /admin/products
@@ -248,7 +247,7 @@ export default async (req, res) => {
let rawProducts
let count
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const [products, count_] =
await listAndCountProductWithIsolatedProductModule(
req,

View File

@@ -1,6 +1,11 @@
import { DistributedTransaction } from "@medusajs/orchestration"
import { FlagRouter, MedusaError, promiseAll } from "@medusajs/utils"
import { updateProducts, Workflows } from "@medusajs/workflows"
import {
FlagRouter,
MedusaError,
MedusaV2Flag,
promiseAll,
} from "@medusajs/utils"
import { Workflows, updateProducts } from "@medusajs/workflows"
import { Type } from "class-transformer"
import {
IsArray,
@@ -51,7 +56,6 @@ import { ProductVariantRepository } from "../../../../repositories/product-varia
import { Logger } from "../../../../types/global"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import { validator } from "../../../../utils/validator"
/**
@@ -140,17 +144,15 @@ export default async (req, res) => {
const productModuleService = req.scope.resolve("productModuleService")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
const isWorkflowEnabled = featureFlagRouter.isFeatureEnabled({
workflows: Workflows.UpdateProducts,
})
const isMedusaV2Enabled = featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)
if (isWorkflowEnabled && !productModuleService) {
if (isMedusaV2Enabled && !productModuleService) {
logger.warn(
`Cannot run ${Workflows.UpdateProducts} workflow without '@medusajs/product' installed`
)
}
if (isWorkflowEnabled && !!productModuleService) {
if (isMedusaV2Enabled) {
const updateProductWorkflow = updateProducts(req.scope)
const input = {
@@ -289,7 +291,7 @@ export default async (req, res) => {
let rawProduct
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (isMedusaV2Enabled) {
rawProduct = await getProductWithIsolatedProductModule(req, id)
} else {
rawProduct = await productService.retrieve(id, {

View File

@@ -13,8 +13,8 @@ import {
} from "class-validator"
import { EntityManager } from "typeorm"
import { MedusaV2Flag } from "@medusajs/utils"
import { defaultAdminProductFields, defaultAdminProductRelations } from "."
import IsolatePricingDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-pricing-domain"
import {
PricingService,
ProductService,
@@ -124,7 +124,7 @@ export default async (req, res) => {
const validatedQueryParams = await validator(PriceSelectionParams, req.query)
if (featureFlagRouter.isFeatureEnabled(IsolatePricingDomainFeatureFlag.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const updateVariantsWorkflow = UpdateProductVariants.updateProductVariants(
req.scope
)

View File

@@ -1,9 +1,4 @@
import {
CartService,
LineItemService,
ProductVariantInventoryService,
RegionService,
} from "../../../../services"
import { createCart as createCartWorkflow } from "@medusajs/workflows"
import {
IsArray,
IsInt,
@@ -13,22 +8,25 @@ import {
ValidateNested,
} from "class-validator"
import { MedusaError, isDefined } from "medusa-core-utils"
import {
Workflows,
createCart as createCartWorkflow,
} from "@medusajs/workflows"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import {
CartService,
LineItemService,
ProductVariantInventoryService,
RegionService,
} from "../../../../services"
import { CartCreateProps } from "../../../../types/cart"
import { EntityManager } from "typeorm"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { FlagRouter } from "@medusajs/utils"
import { LineItem } from "../../../../models"
import { MedusaContainer } from "@medusajs/modules-sdk"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { FlagRouter } from "@medusajs/utils"
import { Workflows } from "@medusajs/workflows"
import { Type } from "class-transformer"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import reqIp from "request-ip"
import { EntityManager } from "typeorm"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { LineItem } from "../../../../models"
import { CartCreateProps } from "../../../../types/cart"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
/**
* @oas [post] /store/carts

View File

@@ -1,7 +1,3 @@
import {
CartService,
ProductVariantInventoryService,
} from "../../../../services"
import {
IsArray,
IsEmail,
@@ -10,15 +6,19 @@ import {
ValidateNested,
} from "class-validator"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import {
CartService,
ProductVariantInventoryService,
} from "../../../../services"
import { AddressPayload } from "../../../../types/common"
import { MedusaV2Flag } from "@medusajs/utils"
import { Type } from "class-transformer"
import { EntityManager } from "typeorm"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { AddressPayload } from "../../../../types/common"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { IsType } from "../../../../utils/validators/is-type"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { Type } from "class-transformer"
import { cleanResponseData } from "../../../../utils/clean-response-data"
/**
* @oas [post] /store/carts/{id}
@@ -90,7 +90,7 @@ export default async (req, res) => {
}
let cart
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
cart = await retrieveCartWithIsolatedProductModule(req, id)
}

View File

@@ -7,8 +7,7 @@ import {
RegionService,
} from "../../../../services"
import { MedusaError, promiseAll } from "@medusajs/utils"
import IsolateProductDomain from "../../../../loaders/feature-flags/isolate-product-domain"
import { MedusaError, MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { PriceSelectionParams } from "../../../../types/price-selection"
import { cleanResponseData } from "../../../../utils"
import { defaultStoreProductRemoteQueryObject } from "./index"
@@ -96,7 +95,7 @@ export default async (req, res) => {
const featureFlagRouter = req.scope.resolve("featureFlagRouter")
let rawProduct
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomain.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
rawProduct = await getProductWithIsolatedProductModule(req, id)
} else {
rawProduct = await productService.retrieve(id, req.retrieveConfig)

View File

@@ -1,9 +1,4 @@
import {
CartService,
ProductService,
ProductVariantInventoryService,
SalesChannelService,
} from "../../../../services"
import { Transform, Type } from "class-transformer"
import {
IsArray,
IsBoolean,
@@ -12,20 +7,24 @@ import {
IsString,
ValidateNested,
} from "class-validator"
import { Transform, Type } from "class-transformer"
import {
CartService,
ProductService,
ProductVariantInventoryService,
SalesChannelService,
} from "../../../../services"
import { DateComparisonOperator } from "../../../../types/common"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { IsType } from "../../../../utils/validators/is-type"
import IsolateProductDomain from "../../../../loaders/feature-flags/isolate-product-domain"
import { PriceSelectionParams } from "../../../../types/price-selection"
import PricingService from "../../../../services/pricing"
import { MedusaV2Flag, promiseAll } from "@medusajs/utils"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import PricingService from "../../../../services/pricing"
import { DateComparisonOperator } from "../../../../types/common"
import { PriceSelectionParams } from "../../../../types/price-selection"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
import { IsType } from "../../../../utils/validators/is-type"
import { defaultStoreCategoryScope } from "../product-categories"
import { defaultStoreProductRemoteQueryObject } from "./index"
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
import { promiseAll } from "@medusajs/utils"
/**
* @oas [get] /store/products
@@ -252,7 +251,7 @@ export default async (req, res) => {
}
const isIsolateProductDomain = featureFlagRouter.isFeatureEnabled(
IsolateProductDomain.key
MedusaV2Flag.key
)
const promises: Promise<any>[] = []

View File

@@ -1,7 +1,6 @@
import { FlagRouter } from "@medusajs/utils"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { IsBooleanString, IsOptional, IsString } from "class-validator"
import { defaultRelations } from "."
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import {
PricingService,
ProductService,
@@ -86,9 +85,7 @@ export default async (req, res) => {
query.admin_only = false
if (productIds.length) {
if (
featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)
) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const productShippinProfileMap =
await shippingProfileService.getMapProfileIdsByProductIds(productIds)

View File

@@ -5,12 +5,10 @@ import getMigrations, {
runIsolatedModulesMigration,
} from "./utils/get-migrations"
import { createMedusaContainer } from "@medusajs/utils"
import { MedusaV2Flag, createMedusaContainer } from "@medusajs/utils"
import configModuleLoader from "../loaders/config"
import databaseLoader from "../loaders/database"
import featureFlagLoader from "../loaders/feature-flags"
import IsolatePricingDomainFeatureFlag from "../loaders/feature-flags/isolate-pricing-domain"
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
import Logger from "../loaders/logger"
import { loadMedusaApp } from "../loaders/medusa-app"
import pgConnectionLoader from "../loaders/pg-connection"
@@ -71,10 +69,8 @@ const main = async function ({ directory }) {
await dataSource.runMigrations()
await dataSource.destroy()
await runIsolatedModulesMigration(configModule)
if (
featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key) ||
featureFlagRouter.isFeatureEnabled(IsolatePricingDomainFeatureFlag.key)
) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
await runLinkMigrations(directory)
}
process.exit()

View File

@@ -1,4 +1,18 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IPricingModuleService } from "@medusajs/types"
import { MedusaV2Flag } from "@medusajs/utils"
import express from "express"
import fs from "fs"
import { sync as existsSync } from "fs-exists-cached"
import { getConfigFile } from "medusa-core-utils"
import { track } from "medusa-telemetry"
import path from "path"
import { DataSource, DataSourceOptions } from "typeorm"
import loaders from "../loaders"
import { handleConfigError } from "../loaders/config"
import featureFlagLoader from "../loaders/feature-flags"
import Logger from "../loaders/logger"
import { SalesChannel } from "../models"
import {
ProductCategoryService,
ProductCollectionService,
@@ -11,25 +25,11 @@ import {
StoreService,
UserService,
} from "../services"
import getMigrations, { getModuleSharedResources } from "./utils/get-migrations"
import { IPricingModuleService } from "@medusajs/types"
import express from "express"
import fs from "fs"
import { sync as existsSync } from "fs-exists-cached"
import { getConfigFile } from "medusa-core-utils"
import { track } from "medusa-telemetry"
import path from "path"
import loaders from "../loaders"
import { handleConfigError } from "../loaders/config"
import featureFlagLoader from "../loaders/feature-flags"
import IsolatePricingDomainFeatureFlag from "../loaders/feature-flags/isolate-pricing-domain"
import Logger from "../loaders/logger"
import { SalesChannel } from "../models"
import PublishableApiKeyService from "../services/publishable-api-key"
import { ConfigModule } from "../types/global"
import { CreateProductInput } from "../types/product"
import { CreateProductCategoryInput } from "../types/product-category"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import getMigrations, { getModuleSharedResources } from "./utils/get-migrations"
type SeedOptions = {
directory: string
@@ -284,9 +284,7 @@ const seed = async function ({ directory, migrate, seedFile }: SeedOptions) {
}
}
if (
featureFlagRouter.isFeatureEnabled(IsolatePricingDomainFeatureFlag.key)
) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
for (const ruleType of rule_types) {
await pricingModuleService.createRuleTypes(ruleType)
}

View File

@@ -1,10 +0,0 @@
import { FlagSettings } from "../../types/feature-flags"
const IsolatePricingDomainFeatureFlag: FlagSettings = {
key: "isolate_pricing_domain",
default_val: false,
env_key: "MEDUSA_FF_ISOLATE_PRICING_DOMAIN",
description: "[WIP] use price module integration for pricing",
}
export default IsolatePricingDomainFeatureFlag

View File

@@ -1,10 +0,0 @@
import { FlagSettings } from "../../types/feature-flags"
const IsolateProductDomainFeatureFlag: FlagSettings = {
key: "isolate_product_domain",
default_val: false,
env_key: "MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN",
description: "[WIP] Isolate product domain dependencies from the core",
}
export default IsolateProductDomainFeatureFlag

View File

@@ -0,0 +1,3 @@
import { MedusaV2Flag } from "@medusajs/utils"
export default MedusaV2Flag

View File

@@ -1,10 +1,3 @@
import { FeatureFlagTypes } from "@medusajs/types"
const WorkflowsFeatureFlag: FeatureFlagTypes.FlagSettings = {
key: "workflows",
default_val: false,
env_key: "MEDUSA_FF_WORKFLOWS",
description: "[WIP] Enable workflows",
}
import { WorkflowsFeatureFlag } from "@medusajs/utils"
export default WorkflowsFeatureFlag

View File

@@ -1,19 +1,23 @@
import {
MODULE_PACKAGE_NAMES,
MedusaApp,
MedusaAppOutput,
MedusaModule,
Modules,
ModulesDefinition,
} from "@medusajs/modules-sdk"
import {
CommonTypes,
InternalModuleDeclaration,
MedusaContainer,
ModuleDefinition,
} from "@medusajs/types"
import {
MedusaApp,
MedusaAppOutput,
ModulesDefinition,
} from "@medusajs/modules-sdk"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { ContainerRegistrationKeys, isObject } from "@medusajs/utils"
import { asValue } from "awilix"
import { joinerConfig } from "../joiner-config"
import { remoteQueryFetchData } from ".."
import { joinerConfig } from "../joiner-config"
export function mergeDefaultModules(
modulesConfig: CommonTypes.ConfigModule["modules"]
@@ -46,6 +50,8 @@ export const loadMedusaApp = async (
},
config = { registerInContainer: true }
): Promise<MedusaAppOutput> => {
const featureFlagRouter = container.resolve<FlagRouter>("featureFlagRouter")
const isMedusaV2Enabled = featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)
const injectedDependencies = {
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
ContainerRegistrationKeys.PG_CONNECTION
@@ -94,6 +100,30 @@ export const loadMedusaApp = async (
injectedDependencies,
})
const requiredModuleKeys = [Modules.PRODUCT, Modules.PRICING]
const missingPackages: string[] = []
if (isMedusaV2Enabled) {
for (const requiredModuleKey of requiredModuleKeys) {
const isModuleInstalled = MedusaModule.isInstalled(requiredModuleKey)
if (!isModuleInstalled) {
missingPackages.push(
MODULE_PACKAGE_NAMES[requiredModuleKey] || requiredModuleKey
)
}
}
if (missingPackages.length) {
throw new Error(
`FeatureFlag medusa_v2 (MEDUSA_FF_MEDUSA_V2) requires the following packages/module registration: (${missingPackages.join(
", "
)})`
)
}
}
if (!config.registerInContainer) {
return medusaApp
}

View File

@@ -1,7 +1,7 @@
import { MedusaV2Flag } from "@medusajs/utils"
import { MigrationInterface, QueryRunner } from "typeorm"
import IsolateProductDomain from "../loaders/feature-flags/isolate-product-domain"
export const featureFlag = IsolateProductDomain.key
export const featureFlag = MedusaV2Flag.key
export class LineItemProductId1692870898424 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {

View File

@@ -1,7 +1,7 @@
import { MedusaV2Flag } from "@medusajs/utils"
import { MigrationInterface, QueryRunner } from "typeorm"
import IsolateProductDomain from "../loaders/feature-flags/isolate-product-domain"
export const featureFlag = IsolateProductDomain.key
export const featureFlag = MedusaV2Flag.key
export class AddTimestempsToProductShippingProfiles1692870898425
implements MigrationInterface

View File

@@ -1,8 +1,7 @@
import { MedusaV2Flag } from "@medusajs/utils"
import { MigrationInterface, QueryRunner } from "typeorm"
import IsolateProductDomain from "../loaders/feature-flags/isolate-product-domain"
export const featureFlag = IsolateProductDomain.key
export const featureFlag = MedusaV2Flag.key
export class dropFksIsolatedProducts1694602553610
implements MigrationInterface

View File

@@ -12,7 +12,9 @@ import {
OneToMany,
} from "typeorm"
import { MedusaV2Flag } from "@medusajs/utils"
import { BaseEntity } from "../interfaces"
import { featureFlagRouter } from "../loaders/feature-flags"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { DbAwareColumn, generateEntityId } from "../utils"
import {
@@ -27,8 +29,6 @@ import { Order } from "./order"
import { OrderEdit } from "./order-edit"
import { ProductVariant } from "./product-variant"
import { Swap } from "./swap"
import IsolateProductDomain from "../loaders/feature-flags/isolate-product-domain"
import { featureFlagRouter } from "../loaders/feature-flags"
@Check(`"fulfilled_quantity" <= "quantity"`)
@Check(`"shipped_quantity" <= "fulfilled_quantity"`)
@@ -131,7 +131,7 @@ export class LineItem extends BaseEntity {
@JoinColumn({ name: "variant_id" })
variant: ProductVariant
@FeatureFlagColumn(IsolateProductDomain.key, { nullable: true, type: "text" })
@FeatureFlagColumn(MedusaV2Flag.key, { nullable: true, type: "text" })
product_id: string | null
@Column({ type: "int" })
@@ -170,7 +170,7 @@ export class LineItem extends BaseEntity {
this.id = generateEntityId(this.id, "item")
// This is to maintain compatibility while isolating the product domain
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomain.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
if (
this.variant &&
Object.keys(this.variant).length === 1 &&
@@ -184,7 +184,7 @@ export class LineItem extends BaseEntity {
/**
* @apiIgnore
*/
@FeatureFlagDecorators(IsolateProductDomain.key, [BeforeUpdate()])
@FeatureFlagDecorators(MedusaV2Flag.key, [BeforeUpdate()])
beforeUpdate(): void {
if (
this.variant &&
@@ -198,7 +198,7 @@ export class LineItem extends BaseEntity {
/**
* @apiIgnore
*/
@FeatureFlagDecorators(IsolateProductDomain.key, [AfterLoad(), AfterUpdate()])
@FeatureFlagDecorators(MedusaV2Flag.key, [AfterLoad(), AfterUpdate()])
afterUpdateOrLoad(): void {
if (this.variant) {
return

View File

@@ -1,8 +1,8 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { MedusaV2Flag } from "@medusajs/utils"
import { DeleteResult, EntityTarget, In, Not } from "typeorm"
import { dataSource } from "../loaders/database"
import { featureFlagRouter } from "../loaders/feature-flags"
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
import {
Discount,
DiscountCondition,
@@ -229,7 +229,7 @@ export const DiscountConditionRepository = dataSource
if (
type !== DiscountConditionType.CUSTOMER_GROUPS &&
featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)
featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)
) {
const module = MedusaModule.getModuleInstance(Modules.PRODUCT)[
Modules.PRODUCT

View File

@@ -1,15 +1,18 @@
import { FlagRouter, MedusaError, promiseAll } from "@medusajs/utils"
import { IPricingModuleService, MedusaContainer } from "@medusajs/types"
import {
FlagRouter,
MedusaError,
MedusaV2Flag,
promiseAll,
} from "@medusajs/utils"
import dotenv from "dotenv"
import express from "express"
import { EntityManager } from "typeorm"
import IsolatePricingDomainFeatureFlag from "../loaders/feature-flags/isolate-pricing-domain"
import { Modules } from "@medusajs/modules-sdk"
import loaders from "../loaders"
import loadMedusaApp from "../loaders/medusa-app"
import { ProductVariant } from "../models"
import { ProductVariantService } from "../services"
import { createDefaultRuleTypes } from "./create-default-rule-types"
import dotenv from "dotenv"
import express from "express"
import loadMedusaApp from "../loaders/medusa-app"
import loaders from "../loaders"
dotenv.config()
@@ -93,10 +96,7 @@ const migrate = async function ({ directory }) {
"featureFlagRouter"
)
if (
!featureFlagRouter.isFeatureEnabled(IsolatePricingDomainFeatureFlag.key) &&
!featureFlagRouter.isFeatureEnabled(Modules.PRICING)
) {
if (!featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
"Pricing module not enabled"

View File

@@ -1,34 +1,12 @@
import { FlagRouter, isDefined, MedusaError, promiseAll } from "@medusajs/utils"
import {
FlagRouter,
isDefined,
MedusaError,
MedusaV2Flag,
promiseAll,
} from "@medusajs/utils"
import { isEmpty, isEqual } from "lodash"
import { DeepPartial, EntityManager, In, IsNull, Not } from "typeorm"
import {
Address,
Cart,
Customer,
CustomShippingOption,
Discount,
DiscountRule,
DiscountRuleType,
LineItem,
PaymentSession,
PaymentSessionStatus,
SalesChannel,
ShippingMethod,
} from "../models"
import {
AddressPayload,
FindConfig,
TotalField,
WithRequiredProperty,
} from "../types/common"
import {
CartCreateProps,
CartUpdateProps,
FilterableCartProps,
isCart,
LineItemUpdate,
LineItemValidateData,
} from "../types/cart"
import {
CustomerService,
CustomShippingOptionService,
@@ -52,16 +30,43 @@ import {
TotalsService,
} from "."
import { IPriceSelectionStrategy, TransactionBaseService } from "../interfaces"
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
import {
Address,
Cart,
Customer,
CustomShippingOption,
Discount,
DiscountRule,
DiscountRuleType,
LineItem,
PaymentSession,
PaymentSessionStatus,
SalesChannel,
ShippingMethod,
} from "../models"
import {
CartCreateProps,
CartUpdateProps,
FilterableCartProps,
isCart,
LineItemUpdate,
LineItemValidateData,
} from "../types/cart"
import {
AddressPayload,
FindConfig,
TotalField,
WithRequiredProperty,
} from "../types/common"
import { buildQuery, isString, setMetadata } from "../utils"
import { AddressRepository } from "../repositories/address"
import { CartRepository } from "../repositories/cart"
import { LineItemRepository } from "../repositories/line-item"
import { PaymentSessionInput } from "../types/payment"
import { PaymentSessionRepository } from "../repositories/payment-session"
import { ShippingMethodRepository } from "../repositories/shipping-method"
import { PaymentSessionInput } from "../types/payment"
import { validateEmail } from "../utils/is-email"
type InjectedDependencies = {
@@ -233,11 +238,7 @@ class CartService extends TransactionBaseService {
)
}
if (
this.featureFlagRouter_.isFeatureEnabled(
IsolateProductDomainFeatureFlag.key
)
) {
if (this.featureFlagRouter_.isFeatureEnabled(MedusaV2Flag.key)) {
if (Array.isArray(options.relations)) {
for (let i = 0; i < options.relations.length; i++) {
if (options.relations[i].startsWith("items.variant")) {
@@ -321,11 +322,7 @@ class CartService extends TransactionBaseService {
const opt = { ...options, relations }
if (
this.featureFlagRouter_.isFeatureEnabled(
IsolateProductDomainFeatureFlag.key
)
) {
if (this.featureFlagRouter_.isFeatureEnabled(MedusaV2Flag.key)) {
if (Array.isArray(opt.relations)) {
for (let i = 0; i < opt.relations.length; i++) {
if (opt.relations[i].startsWith("items.variant")) {
@@ -2243,11 +2240,7 @@ class CartService extends TransactionBaseService {
let productShippinProfileMap = new Map<string, string>()
if (
this.featureFlagRouter_.isFeatureEnabled(
IsolateProductDomainFeatureFlag.key
)
) {
if (this.featureFlagRouter_.isFeatureEnabled(MedusaV2Flag.key)) {
productShippinProfileMap =
await this.shippingProfileService_.getMapProfileIdsByProductIds(
cart.items.map((item) => item.variant.product_id)

View File

@@ -2,9 +2,8 @@ import { MedusaError } from "medusa-core-utils"
import { EntityManager, In } from "typeorm"
import { DeepPartial } from "typeorm/common/DeepPartial"
import { FlagRouter } from "@medusajs/utils"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { TransactionBaseService } from "../interfaces"
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import {
LineItem,
@@ -385,11 +384,7 @@ class LineItemService extends TransactionBaseService {
should_merge: shouldMerge,
}
if (
this.featureFlagRouter_.isFeatureEnabled(
IsolateProductDomainFeatureFlag.key
)
) {
if (this.featureFlagRouter_.isFeatureEnabled(MedusaV2Flag.key)) {
rawLineItem.product_id = variant.product_id
}

View File

@@ -4,7 +4,13 @@ import {
PriceSetMoneyAmountDTO,
RemoteQueryFunction,
} from "@medusajs/types"
import { FlagRouter, promiseAll, removeNullish } from "@medusajs/utils"
import {
FlagRouter,
MedusaV2Flag,
promiseAll,
removeNullish,
} from "@medusajs/utils"
import { ProductVariantService, RegionService, TaxProviderService } from "."
import {
IPriceSelectionStrategy,
PriceSelectionContext,
@@ -24,15 +30,12 @@ import {
ProductVariantPricing,
TaxedPricing,
} from "../types/pricing"
import { ProductVariantService, RegionService, TaxProviderService } from "."
import { EntityManager } from "typeorm"
import IsolatePricingDomainFeatureFlag from "../loaders/feature-flags/isolate-pricing-domain"
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { TransactionBaseService } from "../interfaces"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import { TaxServiceRate } from "../types/tax-service"
import { TransactionBaseService } from "../interfaces"
import { calculatePriceTaxAmount } from "../utils"
type InjectedDependencies = {
@@ -275,14 +278,7 @@ class PricingService extends TransactionBaseService {
}[],
context: PricingContext
): Promise<Map<string, ProductVariantPricing>> {
if (
this.featureFlagRouter.isFeatureEnabled(
IsolateProductDomainFeatureFlag.key
) &&
this.featureFlagRouter.isFeatureEnabled(
IsolatePricingDomainFeatureFlag.key
)
) {
if (this.featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
return await this.getProductVariantPricingModulePricing_(data, context)
}
@@ -718,11 +714,7 @@ class PricingService extends TransactionBaseService {
variants: ProductVariant[],
context: PriceSelectionContext = {}
): Promise<PricedVariant[]> {
if (
!this.featureFlagRouter.isFeatureEnabled(
IsolatePricingDomainFeatureFlag.key
)
) {
if (!this.featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
return await this.setVariantPrices(variants, context)
}
@@ -754,11 +746,7 @@ class PricingService extends TransactionBaseService {
async setAdminProductPricing(
products: Product[]
): Promise<(Product | PricedProduct)[]> {
if (
!this.featureFlagRouter.isFeatureEnabled(
IsolatePricingDomainFeatureFlag.key
)
) {
if (!this.featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
return await this.setProductPrices(products)
}

View File

@@ -1,8 +1,12 @@
import { FlagRouter, isDefined, promiseAll } from "@medusajs/utils"
import {
FlagRouter,
MedusaV2Flag,
isDefined,
promiseAll,
} from "@medusajs/utils"
import { MedusaError } from "medusa-core-utils"
import { EntityManager, In } from "typeorm"
import { TransactionBaseService } from "../interfaces"
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
import {
Cart,
CustomShippingOption,
@@ -518,11 +522,7 @@ class ShippingProfileService extends TransactionBaseService {
protected async getProfilesInCart(cart: Cart): Promise<string[]> {
let profileIds = new Set<string>()
if (
this.featureFlagRouter_.isFeatureEnabled(
IsolateProductDomainFeatureFlag.key
)
) {
if (this.featureFlagRouter_.isFeatureEnabled(MedusaV2Flag.key)) {
const productShippinProfileMap = await this.getMapProfileIdsByProductIds(
cart.items.map((item) => item.variant?.product_id)
)

View File

@@ -1,4 +1,6 @@
export * from "./analytics"
export * from "./many-to-many-inventory"
export * from "./medusa-v2"
export * from "./order-editing"
export * from "./product-categories"
export * from "./publishable-api-keys"
@@ -6,4 +8,3 @@ export * from "./sales-channels"
export * from "./tax-inclusive-pricing"
export * from "./utils"
export * from "./workflows"
export * from "./many-to-many-inventory"

View File

@@ -0,0 +1,8 @@
import { FeatureFlagTypes } from "@medusajs/types"
export const MedusaV2Flag: FeatureFlagTypes.FlagSettings = {
key: "medusa_v2",
default_val: false,
env_key: "MEDUSA_FF_MEDUSA_V2",
description: "[WIP] Enable Medusa V2",
}

View File

@@ -1,154 +0,0 @@
import { FlagRouter } from "../flag-router"
const someFlag = {
key: "some_flag",
default_val: false,
env_key: "MEDUSA_FF_SOME_FLAG",
description: "[WIP] Enable some flag",
}
const workflows = {
key: "workflows",
default_val: {},
env_key: "MEDUSA_FF_WORKFLOWS",
description: "[WIP] Enable workflows",
}
describe("FlagRouter", function () {
it("should set a top-level flag", async function () {
const flagRouter = new FlagRouter({})
flagRouter.setFlag(someFlag.key, true)
expect(flagRouter.listFlags()).toEqual([
{
key: someFlag.key,
value: true,
},
])
})
it("should set a nested flag", async function () {
const flagRouter = new FlagRouter({})
flagRouter.setFlag(workflows.key, { createCart: true })
expect(flagRouter.listFlags()).toEqual([
{
key: workflows.key,
value: {
createCart: true,
},
},
])
})
it("should append to a nested flag", async function () {
const flagRouter = new FlagRouter({})
flagRouter.setFlag(workflows.key, { createCart: true })
flagRouter.setFlag(workflows.key, { addShippingMethod: true })
expect(flagRouter.listFlags()).toEqual([
{
key: workflows.key,
value: {
createCart: true,
addShippingMethod: true,
},
},
])
})
it("should check if top-level flag is enabled", async function () {
const flagRouter = new FlagRouter({
[someFlag.key]: true,
})
const isEnabled = flagRouter.isFeatureEnabled(someFlag.key)
expect(isEnabled).toEqual(true)
})
it("should check if nested flag is enabled", async function () {
const flagRouter = new FlagRouter({
[workflows.key]: {
createCart: true,
},
})
const isEnabled = flagRouter.isFeatureEnabled({ workflows: "createCart" })
expect(isEnabled).toEqual(true)
})
it("should check if nested flag is enabled using top-level access", async function () {
const flagRouter = new FlagRouter({
[workflows.key]: {
createCart: true,
},
})
const isEnabled = flagRouter.isFeatureEnabled(workflows.key)
expect(isEnabled).toEqual(true)
})
it("should return true if top-level is enabled using nested-level access", async function () {
const flagRouter = new FlagRouter({
[workflows.key]: true,
})
const isEnabled = flagRouter.isFeatureEnabled({
[workflows.key]: "createCart",
})
expect(isEnabled).toEqual(true)
})
it("should return false if flag is disabled using top-level access", async function () {
const flagRouter = new FlagRouter({
[workflows.key]: false,
})
const isEnabled = flagRouter.isFeatureEnabled(workflows.key)
expect(isEnabled).toEqual(false)
})
it("should return false if nested flag is disabled", async function () {
const flagRouter = new FlagRouter({
[workflows.key]: {
createCart: false,
},
})
const isEnabled = flagRouter.isFeatureEnabled({ workflows: "createCart" })
expect(isEnabled).toEqual(false)
})
it("should initialize with both types of flags", async function () {
const flagRouter = new FlagRouter({
[workflows.key]: {
createCart: true,
},
[someFlag.key]: true,
})
const flags = flagRouter.listFlags()
expect(flags).toEqual([
{
key: workflows.key,
value: {
createCart: true,
},
},
{
key: someFlag.key,
value: true,
},
])
})
})

View File

@@ -1,4 +1,5 @@
import { PricingTypes } from "@medusajs/types"
import { MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "../../helper"
type HandlerInput = {
@@ -20,7 +21,7 @@ export async function revertVariantPrices({
const featureFlagRouter = container.resolve("featureFlagRouter")
const isPricingDomainEnabled = featureFlagRouter.isFeatureEnabled(
"isolate_pricing_domain"
MedusaV2Flag.key
)
if (!isPricingDomainEnabled) {

View File

@@ -1,6 +1,6 @@
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
import { ProductTypes, ProductWorkflow, WorkflowTypes } from "@medusajs/types"
import { MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "../../helper"
type VariantPrice = {
@@ -27,7 +27,7 @@ export async function updateProductVariantsPrepareData({
}: WorkflowArguments<WorkflowTypes.ProductWorkflow.UpdateProductVariantsWorkflowInputDTO>): Promise<UpdateProductVariantsPreparedData> {
const featureFlagRouter = container.resolve("featureFlagRouter")
const isPricingDomainEnabled = featureFlagRouter.isFeatureEnabled(
"isolate_pricing_domain"
MedusaV2Flag.key
)
let productVariants: ProductWorkflow.UpdateProductVariantsInputDTO[] =
data.productVariants || []

View File

@@ -1,5 +1,5 @@
import { ProductDTO, SalesChannelDTO, WorkflowTypes } from "@medusajs/types"
import { MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "../../helper"
type ProductWithSalesChannelsDTO = ProductDTO & {
@@ -28,7 +28,7 @@ export async function updateProductsPrepareData({
}: WorkflowArguments<WorkflowTypes.ProductWorkflow.UpdateProductsWorkflowInputDTO>): Promise<UpdateProductsPreparedData> {
const featureFlagRouter = container.resolve("featureFlagRouter")
const isPricingDomainEnabled = featureFlagRouter.isFeatureEnabled(
"isolate_pricing_domain"
MedusaV2Flag.key
)
const variantPricesMap = new Map<string, VariantPrice[]>()

View File

@@ -1,8 +1,8 @@
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
import { MedusaError } from "@medusajs/utils"
import { WorkflowArguments } from "../../helper"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { MedusaError, MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "../../helper"
type ProductHandle = string
type VariantIndexAndPrices = {
@@ -99,7 +99,7 @@ export async function updateProductsVariantsPrices({
}
}
if (featureFlagRouter.isFeatureEnabled("isolate_pricing_domain")) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const remoteLink = container.resolve("remoteLink")
const pricingModuleService = container.resolve(
ModuleRegistrationName.PRICING

View File

@@ -1,5 +1,5 @@
import { PricingTypes } from "@medusajs/types"
import { MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "../../helper"
type VariantPrice = {
@@ -29,8 +29,8 @@ export async function upsertVariantPrices({
const { variantPricesMap } = data
const featureFlagRouter = container.resolve("featureFlagRouter")
if (!featureFlagRouter.isFeatureEnabled("isolate_pricing_domain")) {
if (!featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
return {
createdLinks: [],
originalMoneyAmounts: [],