chore(framework,medusa): load custom flags before medusa config (#13312)
* chore(framework,medusa): load custom flags before medusa config * test * test runner * changeset * check manager featureFlags * discover and register flags * rm comments * update changeset * changeset * use local cli * execute from local medusa command --------- Co-authored-by: Adrien de Peretti <adrien.deperetti@gmail.com>
This commit is contained in:
committed by
GitHub
parent
2a94dbd243
commit
b4c0f131b7
9
.changeset/good-meals-watch.md
Normal file
9
.changeset/good-meals-watch.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/framework": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/test-utils": patch
|
||||||
|
"@medusajs/modules-sdk": patch
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
chore(framework): load custom flags before medusa config
|
||||||
8
.github/workflows/test-cli-with-database.yml
vendored
8
.github/workflows/test-cli-with-database.yml
vendored
@@ -71,22 +71,22 @@ jobs:
|
|||||||
working-directory: ../cli-test
|
working-directory: ../cli-test
|
||||||
|
|
||||||
- name: Run migrations
|
- name: Run migrations
|
||||||
run: npx medusa db:migrate
|
run: yarn medusa db:migrate
|
||||||
working-directory: ../cli-test
|
working-directory: ../cli-test
|
||||||
|
|
||||||
- name: Create admin user
|
- name: Create admin user
|
||||||
run: npx medusa user -e test@test.com -p password -i admin_123
|
run: yarn medusa user -e test@test.com -p password -i admin_123
|
||||||
working-directory: ../cli-test
|
working-directory: ../cli-test
|
||||||
|
|
||||||
- name: Run development server
|
- name: Run development server
|
||||||
run: npx medusa develop &
|
run: yarn medusa develop &
|
||||||
working-directory: ../cli-test
|
working-directory: ../cli-test
|
||||||
|
|
||||||
- name: Testing development server
|
- name: Testing development server
|
||||||
uses: ./.github/actions/test-server
|
uses: ./.github/actions/test-server
|
||||||
|
|
||||||
- name: Starting medusa
|
- name: Starting medusa
|
||||||
run: npx medusa start &
|
run: yarn medusa start &
|
||||||
working-directory: ../cli-test
|
working-directory: ../cli-test
|
||||||
|
|
||||||
- name: Testing server
|
- name: Testing server
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { InputConfigModules } from "@medusajs/types"
|
||||||
|
import { FeatureFlag } from "@medusajs/utils"
|
||||||
|
import { EnvFeatureFlag } from "./src/feature-flags/env-ff"
|
||||||
|
|
||||||
const { defineConfig } = require("@medusajs/framework/utils")
|
const { defineConfig } = require("@medusajs/framework/utils")
|
||||||
|
|
||||||
const DB_HOST = process.env.DB_HOST
|
const DB_HOST = process.env.DB_HOST
|
||||||
@@ -8,6 +12,16 @@ const DB_URL = `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`
|
|||||||
|
|
||||||
process.env.DATABASE_URL = DB_URL
|
process.env.DATABASE_URL = DB_URL
|
||||||
|
|
||||||
|
const modules = [] as InputConfigModules
|
||||||
|
|
||||||
|
// The custom feature is available here and has default value set to true
|
||||||
|
if (FeatureFlag.isFeatureEnabled(EnvFeatureFlag.key)) {
|
||||||
|
modules.push({
|
||||||
|
key: "custom",
|
||||||
|
resolve: "src/modules/custom",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
admin: {
|
admin: {
|
||||||
disable: true,
|
disable: true,
|
||||||
@@ -17,10 +31,5 @@ module.exports = defineConfig({
|
|||||||
jwtSecret: "secret",
|
jwtSecret: "secret",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modules: [
|
modules,
|
||||||
{
|
|
||||||
key: "custom",
|
|
||||||
resolve: "src/modules/custom",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { FlagSettings } from "@medusajs/framework/feature-flags"
|
||||||
|
|
||||||
|
export const EnvFeatureFlag: FlagSettings = {
|
||||||
|
key: "env_ff",
|
||||||
|
default_val: true,
|
||||||
|
env_key: "ENV_FF",
|
||||||
|
description: "Environment feature flag",
|
||||||
|
}
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
import { trackFeatureFlag } from "@medusajs/telemetry"
|
import { trackFeatureFlag } from "@medusajs/telemetry"
|
||||||
import {
|
import {
|
||||||
ContainerRegistrationKeys,
|
ContainerRegistrationKeys,
|
||||||
discoverFeatureFlagsFromDir,
|
discoverAndRegisterFeatureFlags,
|
||||||
FeatureFlag,
|
FeatureFlag,
|
||||||
FlagRouter,
|
FlagRouter,
|
||||||
registerFeatureFlag,
|
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { asFunction } from "awilix"
|
import { asFunction } from "awilix"
|
||||||
import { normalize } from "path"
|
import { normalize } from "path"
|
||||||
import { configManager } from "../config"
|
import { configManager } from "../config"
|
||||||
import { container } from "../container"
|
import { container } from "../container"
|
||||||
import { FlagSettings } from "./types"
|
import { logger as defaultLogger } from "../logger"
|
||||||
|
|
||||||
container.register(
|
container.register(
|
||||||
ContainerRegistrationKeys.FEATURE_FLAG_ROUTER,
|
ContainerRegistrationKeys.FEATURE_FLAG_ROUTER,
|
||||||
@@ -24,7 +23,11 @@ container.register(
|
|||||||
export async function featureFlagsLoader(
|
export async function featureFlagsLoader(
|
||||||
sourcePath?: string
|
sourcePath?: string
|
||||||
): Promise<FlagRouter> {
|
): Promise<FlagRouter> {
|
||||||
const { featureFlags: projectConfigFlags = {}, logger } = configManager.config
|
const confManager = !!configManager.baseDir
|
||||||
|
? configManager.config
|
||||||
|
: { featureFlags: {}, logger: defaultLogger }
|
||||||
|
|
||||||
|
const { featureFlags: projectConfigFlags = {}, logger } = confManager
|
||||||
|
|
||||||
if (!sourcePath) {
|
if (!sourcePath) {
|
||||||
return FeatureFlag
|
return FeatureFlag
|
||||||
@@ -32,16 +35,13 @@ export async function featureFlagsLoader(
|
|||||||
|
|
||||||
const flagDir = normalize(sourcePath)
|
const flagDir = normalize(sourcePath)
|
||||||
|
|
||||||
const discovered = await discoverFeatureFlagsFromDir(flagDir)
|
await discoverAndRegisterFeatureFlags({
|
||||||
for (const def of discovered) {
|
flagDir,
|
||||||
registerFeatureFlag({
|
projectConfigFlags,
|
||||||
flag: def as FlagSettings,
|
router: FeatureFlag,
|
||||||
projectConfigFlags,
|
logger,
|
||||||
router: FeatureFlag,
|
track: (key) => trackFeatureFlag(key),
|
||||||
logger,
|
})
|
||||||
track: (key) => trackFeatureFlag(key),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return FeatureFlag
|
return FeatureFlag
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
ContainerRegistrationKeys,
|
ContainerRegistrationKeys,
|
||||||
createMedusaContainer,
|
createMedusaContainer,
|
||||||
defineJoinerConfig,
|
defineJoinerConfig,
|
||||||
discoverFeatureFlagsFromDir,
|
discoverAndRegisterFeatureFlags,
|
||||||
DmlEntity,
|
DmlEntity,
|
||||||
dynamicImport,
|
dynamicImport,
|
||||||
FeatureFlag,
|
FeatureFlag,
|
||||||
@@ -28,7 +28,6 @@ import {
|
|||||||
MedusaModuleType,
|
MedusaModuleType,
|
||||||
Modules,
|
Modules,
|
||||||
ModulesSdkUtils,
|
ModulesSdkUtils,
|
||||||
registerFeatureFlag,
|
|
||||||
stringifyCircular,
|
stringifyCircular,
|
||||||
toMikroOrmEntities,
|
toMikroOrmEntities,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
@@ -579,7 +578,6 @@ export async function loadResources({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const flagDir = resolve(normalizedPath)
|
const flagDir = resolve(normalizedPath)
|
||||||
const discovered = await discoverFeatureFlagsFromDir(flagDir, 1)
|
|
||||||
|
|
||||||
const configModule = container.resolve(
|
const configModule = container.resolve(
|
||||||
ContainerRegistrationKeys.CONFIG_MODULE,
|
ContainerRegistrationKeys.CONFIG_MODULE,
|
||||||
@@ -588,14 +586,13 @@ export async function loadResources({
|
|||||||
}
|
}
|
||||||
) as ConfigModule
|
) as ConfigModule
|
||||||
|
|
||||||
for (const def of discovered) {
|
await discoverAndRegisterFeatureFlags({
|
||||||
registerFeatureFlag({
|
flagDir,
|
||||||
flag: def,
|
projectConfigFlags: configModule?.featureFlags ?? {},
|
||||||
projectConfigFlags: configModule?.featureFlags ?? {},
|
router: FeatureFlag,
|
||||||
router: FeatureFlag,
|
logger,
|
||||||
logger,
|
maxDepth: 1,
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const [moduleService, services, models, repositories] = await Promise.all([
|
const [moduleService, services, models, repositories] = await Promise.all([
|
||||||
dynamicImport(modulePath).then((moduleExports) => {
|
dynamicImport(modulePath).then((moduleExports) => {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { FlagSettings, Logger } from "@medusajs/types"
|
||||||
|
import { discoverFeatureFlagsFromDir } from "./discover-feature-flags"
|
||||||
|
import { FlagRouter } from "./flag-router"
|
||||||
|
import { registerFeatureFlag } from "./register-flag"
|
||||||
|
|
||||||
|
export interface DiscoverAndRegisterOptions {
|
||||||
|
flagDir: string
|
||||||
|
projectConfigFlags?: Record<string, any>
|
||||||
|
router: FlagRouter
|
||||||
|
logger?: Logger
|
||||||
|
track?: (key: string) => void
|
||||||
|
maxDepth?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to discover and register feature flags from a directory
|
||||||
|
*/
|
||||||
|
export async function discoverAndRegisterFeatureFlags(
|
||||||
|
options: DiscoverAndRegisterOptions
|
||||||
|
): Promise<void> {
|
||||||
|
const {
|
||||||
|
flagDir,
|
||||||
|
projectConfigFlags = {},
|
||||||
|
router,
|
||||||
|
logger,
|
||||||
|
track,
|
||||||
|
maxDepth,
|
||||||
|
} = options
|
||||||
|
|
||||||
|
const discovered = await discoverFeatureFlagsFromDir(flagDir, maxDepth)
|
||||||
|
|
||||||
|
for (const def of discovered) {
|
||||||
|
const registerOptions: Parameters<typeof registerFeatureFlag>[0] = {
|
||||||
|
flag: def as FlagSettings,
|
||||||
|
projectConfigFlags,
|
||||||
|
router,
|
||||||
|
logger,
|
||||||
|
track,
|
||||||
|
}
|
||||||
|
|
||||||
|
registerFeatureFlag(registerOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from "./discover-feature-flags"
|
export * from "./discover-feature-flags"
|
||||||
|
export * from "./discover-and-register-feature-flags"
|
||||||
export * from "./flag-router"
|
export * from "./flag-router"
|
||||||
export * from "./register-flag"
|
export * from "./register-flag"
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { getConfigFile } from "@medusajs/framework/utils"
|
import {
|
||||||
|
FeatureFlag,
|
||||||
|
getConfigFile,
|
||||||
|
discoverAndRegisterFeatureFlags,
|
||||||
|
} from "@medusajs/framework/utils"
|
||||||
|
|
||||||
export async function configLoaderOverride(
|
export async function configLoaderOverride(
|
||||||
entryDirectory: string,
|
entryDirectory: string,
|
||||||
@@ -6,6 +10,14 @@ export async function configLoaderOverride(
|
|||||||
) {
|
) {
|
||||||
const { configManager } = await import("@medusajs/framework/config")
|
const { configManager } = await import("@medusajs/framework/config")
|
||||||
const { logger } = await import("@medusajs/framework")
|
const { logger } = await import("@medusajs/framework")
|
||||||
|
|
||||||
|
await discoverAndRegisterFeatureFlags({
|
||||||
|
flagDir: entryDirectory,
|
||||||
|
projectConfigFlags: {},
|
||||||
|
router: FeatureFlag,
|
||||||
|
logger,
|
||||||
|
})
|
||||||
|
|
||||||
const { configModule, error } = await getConfigFile<
|
const { configModule, error } = await getConfigFile<
|
||||||
ReturnType<typeof configManager.loadConfig>
|
ReturnType<typeof configManager.loadConfig>
|
||||||
>(entryDirectory, "medusa-config")
|
>(entryDirectory, "medusa-config")
|
||||||
|
|||||||
@@ -139,7 +139,10 @@ export async function initializeContainer(
|
|||||||
skipDbConnection?: boolean
|
skipDbConnection?: boolean
|
||||||
}
|
}
|
||||||
): Promise<MedusaContainer> {
|
): Promise<MedusaContainer> {
|
||||||
|
// custom flags from medusa project
|
||||||
|
await featureFlagsLoader(rootDirectory)
|
||||||
const configDir = await configLoader(rootDirectory, "medusa-config")
|
const configDir = await configLoader(rootDirectory, "medusa-config")
|
||||||
|
// core flags
|
||||||
await featureFlagsLoader(join(__dirname, ".."))
|
await featureFlagsLoader(join(__dirname, ".."))
|
||||||
|
|
||||||
const customLogger = configDir.logger ?? defaultLogger
|
const customLogger = configDir.logger ?? defaultLogger
|
||||||
|
|||||||
Reference in New Issue
Block a user