feat(utils): define file config (#13283)
** What
- Allow auto-loaded Medusa files to export a config object.
- Currently supports isDisabled to control loading.
- new instance `FeatureFlag` exported by `@medusajs/framework/utils`
- `feature-flags` is now a supported folder for medusa projects, modules, providers and plugins. They will be loaded and added to `FeatureFlag`
** Why
- Enables conditional loading of routes, migrations, jobs, subscribers, workflows, and other files based on feature flags.
```ts
// /src/feature-flags
import { FlagSettings } from "@medusajs/framework/feature-flags"
const CustomFeatureFlag: FlagSettings = {
key: "custom_feature",
default_val: false,
env_key: "FF_MY_CUSTOM_FEATURE",
description: "Enable xyz",
}
export default CustomFeatureFlag
```
```ts
// /src/modules/my-custom-module/migration/Migration20250822135845.ts
import { FeatureFlag } from "@medusajs/framework/utils"
export class Migration20250822135845 extends Migration {
override async up(){ }
override async down(){ }
}
defineFileConfig({
isDisabled: () => !FeatureFlag.isFeatureEnabled("custom_feature")
})
```
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { logger } from "@medusajs/framework/logger"
|
||||
import { CustomDBMigrator } from "@medusajs/framework/utils"
|
||||
|
||||
import {
|
||||
defineConfig,
|
||||
MikroORM,
|
||||
@@ -54,6 +56,7 @@ export function getMikroOrmConfig({
|
||||
pathTs: pathToMigrations,
|
||||
silent: true,
|
||||
},
|
||||
extensions: [CustomDBMigrator],
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { logger } from "@medusajs/framework/logger"
|
||||
import {
|
||||
ExternalModuleDeclaration,
|
||||
InternalModuleDeclaration,
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
createPgConnection,
|
||||
promiseAll,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { logger } from "@medusajs/framework/logger"
|
||||
|
||||
export interface InitModulesOptions {
|
||||
injectedDependencies?: Record<string, unknown>
|
||||
@@ -24,6 +24,7 @@ export interface InitModulesOptions {
|
||||
}
|
||||
joinerConfig?: ModuleJoinerConfig[]
|
||||
preventConnectionDestroyWarning?: boolean
|
||||
cwd?: string
|
||||
}
|
||||
|
||||
export async function initModules({
|
||||
@@ -32,6 +33,7 @@ export async function initModules({
|
||||
modulesConfig,
|
||||
joinerConfig,
|
||||
preventConnectionDestroyWarning = false,
|
||||
cwd,
|
||||
}: InitModulesOptions) {
|
||||
const moduleSdkImports = require("@medusajs/framework/modules-sdk")
|
||||
|
||||
@@ -55,6 +57,7 @@ export async function initModules({
|
||||
modulesConfig,
|
||||
servicesConfig: joinerConfig,
|
||||
injectedDependencies,
|
||||
cwd,
|
||||
})
|
||||
|
||||
await medusaApp.onApplicationStart()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { logger } from "@medusajs/framework/logger"
|
||||
import { MedusaContainer } from "@medusajs/framework/types"
|
||||
import { GracefulShutdownServer, promiseAll } from "@medusajs/framework/utils"
|
||||
import express from "express"
|
||||
import getPort from "get-port"
|
||||
import { resolve } from "path"
|
||||
import { MedusaContainer } from "@medusajs/framework/types"
|
||||
import { applyEnvVarsToProcess, execOrTimeout } from "./utils"
|
||||
import { promiseAll, GracefulShutdownServer } from "@medusajs/framework/utils"
|
||||
import { logger } from "@medusajs/framework/logger"
|
||||
|
||||
async function bootstrapApp({
|
||||
cwd,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { MedusaAppLoader } from "@medusajs/framework"
|
||||
import { Logger, MedusaContainer } from "@medusajs/framework/types"
|
||||
import { logger } from "@medusajs/framework/logger"
|
||||
import { Logger, MedusaContainer } from "@medusajs/framework/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
getResolvedPlugins,
|
||||
@@ -11,12 +11,9 @@ import { join } from "path"
|
||||
* Initiates the database connection
|
||||
*/
|
||||
export async function initDb() {
|
||||
const { pgConnectionLoader, featureFlagsLoader } = await import(
|
||||
"@medusajs/framework"
|
||||
)
|
||||
const { pgConnectionLoader } = await import("@medusajs/framework")
|
||||
|
||||
const pgConnection = await pgConnectionLoader()
|
||||
await featureFlagsLoader()
|
||||
|
||||
return pgConnection
|
||||
}
|
||||
|
||||
@@ -51,11 +51,13 @@ interface TestRunnerConfig {
|
||||
hooks?: {
|
||||
beforeServerStart?: (container: MedusaContainer) => Promise<void>
|
||||
}
|
||||
cwd?: string
|
||||
}
|
||||
|
||||
class MedusaTestRunner {
|
||||
private dbName: string
|
||||
private schema: string
|
||||
private modulesConfigPath: string
|
||||
private cwd: string
|
||||
private env: Record<string, any>
|
||||
private debug: boolean
|
||||
@@ -85,7 +87,8 @@ class MedusaTestRunner {
|
||||
config.dbName ??
|
||||
`medusa-${moduleName.toLowerCase()}-integration-${tempName}`
|
||||
this.schema = config.schema ?? "public"
|
||||
this.cwd = config.medusaConfigFile ?? process.cwd()
|
||||
this.cwd = config.cwd ?? config.medusaConfigFile ?? process.cwd()
|
||||
this.modulesConfigPath = config.medusaConfigFile ?? this.cwd
|
||||
this.env = config.env ?? {}
|
||||
this.debug = config.debug ?? false
|
||||
this.inApp = config.inApp ?? false
|
||||
@@ -150,7 +153,10 @@ class MedusaTestRunner {
|
||||
|
||||
private async setupApplication(): Promise<void> {
|
||||
const { container, MedusaAppLoader } = await import("@medusajs/framework")
|
||||
const appLoader = new MedusaAppLoader()
|
||||
const appLoader = new MedusaAppLoader({
|
||||
medusaConfigPath: this.modulesConfigPath,
|
||||
cwd: this.cwd,
|
||||
})
|
||||
|
||||
// Load plugins modules
|
||||
const configModule = container.resolve(
|
||||
@@ -173,7 +179,7 @@ class MedusaTestRunner {
|
||||
`Migrating database with core migrations and links ${this.dbName}`
|
||||
)
|
||||
await migrateDatabase(appLoader)
|
||||
await syncLinks(appLoader, this.cwd, container, logger)
|
||||
await syncLinks(appLoader, this.modulesConfigPath, container, logger)
|
||||
await clearInstances()
|
||||
|
||||
this.loadedApplication = await appLoader.load()
|
||||
@@ -184,7 +190,7 @@ class MedusaTestRunner {
|
||||
container: appContainer,
|
||||
port,
|
||||
} = await startApp({
|
||||
cwd: this.cwd,
|
||||
cwd: this.modulesConfigPath,
|
||||
env: this.env,
|
||||
})
|
||||
|
||||
@@ -270,6 +276,8 @@ class MedusaTestRunner {
|
||||
const { MedusaAppLoader } = await import("@medusajs/framework")
|
||||
const medusaAppLoader = new MedusaAppLoader({
|
||||
container: copiedContainer,
|
||||
medusaConfigPath: this.modulesConfigPath,
|
||||
cwd: this.cwd,
|
||||
})
|
||||
await medusaAppLoader.runModulesLoader()
|
||||
} catch (error) {
|
||||
@@ -319,6 +327,7 @@ export function medusaIntegrationTestRunner({
|
||||
inApp = false,
|
||||
testSuite,
|
||||
hooks,
|
||||
cwd,
|
||||
}: {
|
||||
moduleName?: string
|
||||
env?: Record<string, any>
|
||||
@@ -329,6 +338,7 @@ export function medusaIntegrationTestRunner({
|
||||
inApp?: boolean
|
||||
testSuite: (options: MedusaSuiteOptions) => void
|
||||
hooks?: TestRunnerConfig["hooks"]
|
||||
cwd?: string
|
||||
}) {
|
||||
const runner = new MedusaTestRunner({
|
||||
moduleName,
|
||||
@@ -339,6 +349,7 @@ export function medusaIntegrationTestRunner({
|
||||
debug,
|
||||
inApp,
|
||||
hooks,
|
||||
cwd,
|
||||
})
|
||||
|
||||
return describe("", () => {
|
||||
|
||||
@@ -27,6 +27,7 @@ function createMikroOrmWrapper(options: {
|
||||
moduleModels?: (Function | DmlEntity<any, any>)[]
|
||||
resolve?: string
|
||||
dbConfig: any
|
||||
cwd?: string
|
||||
}): {
|
||||
MikroOrmWrapper: TestDatabase
|
||||
models: (Function | DmlEntity<any, any>)[]
|
||||
@@ -36,7 +37,7 @@ function createMikroOrmWrapper(options: {
|
||||
|
||||
if (!options.moduleModels) {
|
||||
const basePath = normalizeImportPathWithSource(
|
||||
options.resolve ?? process.cwd()
|
||||
options.resolve ?? options.cwd ?? process.cwd()
|
||||
)
|
||||
|
||||
const modelsPath = fs.existsSync(`${basePath}/dist/models`)
|
||||
@@ -74,6 +75,7 @@ export function moduleIntegrationTestRunner<TService = any>({
|
||||
testSuite,
|
||||
resolve,
|
||||
injectedDependencies = {},
|
||||
cwd,
|
||||
}: {
|
||||
moduleName: string
|
||||
moduleModels?: any[]
|
||||
@@ -85,6 +87,7 @@ export function moduleIntegrationTestRunner<TService = any>({
|
||||
injectedDependencies?: Record<string, any>
|
||||
resolve?: string
|
||||
debug?: boolean
|
||||
cwd?: string
|
||||
testSuite: (options: SuiteOptions<TService>) => void
|
||||
}) {
|
||||
const moduleSdkImports = require("@medusajs/framework/modules-sdk")
|
||||
@@ -107,6 +110,7 @@ export function moduleIntegrationTestRunner<TService = any>({
|
||||
moduleModels,
|
||||
resolve,
|
||||
dbConfig,
|
||||
cwd,
|
||||
})
|
||||
|
||||
moduleModels = models
|
||||
@@ -135,6 +139,7 @@ export function moduleIntegrationTestRunner<TService = any>({
|
||||
databaseConfig: dbConfig,
|
||||
joinerConfig,
|
||||
preventConnectionDestroyWarning: true,
|
||||
cwd,
|
||||
}
|
||||
|
||||
let shutdown: () => Promise<void>
|
||||
|
||||
Reference in New Issue
Block a user