Skip to content

Commit e413cfe

Browse files
feat(utils): define file config (medusajs#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") }) ```
1 parent 4cda412 commit e413cfe

File tree

183 files changed

+1087
-603
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

183 files changed

+1087
-603
lines changed

.changeset/dry-geckos-act.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@medusajs/modules-sdk": patch
3+
"@medusajs/framework": patch
4+
"@medusajs/types": patch
5+
"@medusajs/utils": patch
6+
"@medusajs/medusa": patch
7+
"@medusajs/test-utils": patch
8+
"@medusajs/workflows-sdk": patch
9+
"@medusajs/cli": patch
10+
---
11+
12+
feat: define file config and improved feature flag support
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const { defineConfig } = require("@medusajs/framework/utils")
2+
3+
const DB_HOST = process.env.DB_HOST
4+
const DB_USERNAME = process.env.DB_USERNAME
5+
const DB_PASSWORD = process.env.DB_PASSWORD
6+
const DB_NAME = process.env.DB_TEMP_NAME
7+
const DB_URL = `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`
8+
9+
process.env.DATABASE_URL = DB_URL
10+
11+
module.exports = defineConfig({
12+
admin: {
13+
disable: true,
14+
},
15+
projectConfig: {
16+
http: {
17+
jwtSecret: "secret",
18+
},
19+
},
20+
modules: [
21+
{
22+
key: "custom",
23+
resolve: "src/modules/custom",
24+
},
25+
],
26+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
2+
import { defineFileConfig, FeatureFlag } from "@medusajs/utils"
3+
4+
defineFileConfig({
5+
isDisabled: () => !FeatureFlag.isFeatureEnabled("custom_ff"),
6+
})
7+
8+
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
9+
res.json({ message: "Custom GET" })
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { FlagSettings } from "@medusajs/framework/feature-flags"
2+
3+
export const CustomFeatureFlag: FlagSettings = {
4+
key: "custom_ff",
5+
default_val: false,
6+
env_key: "CUSTOM_FF",
7+
description: "Custom feature flag",
8+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { MedusaContainer } from "@medusajs/framework/types"
2+
import { defineFileConfig, FeatureFlag } from "@medusajs/framework/utils"
3+
4+
export const testJobHandler = jest.fn()
5+
6+
export default async function greetingJob(container: MedusaContainer) {
7+
testJobHandler()
8+
}
9+
10+
export const config = {
11+
name: "greeting-every-second",
12+
numberOfExecutions: 1,
13+
schedule: "* * * * * *",
14+
}
15+
16+
defineFileConfig({
17+
isDisabled: () => !FeatureFlag.isFeatureEnabled("custom_ff"),
18+
})
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { ModuleExports } from "@medusajs/types"
2+
import { ModuleService } from "./services/module-service"
3+
4+
const moduleExports: ModuleExports = {
5+
service: ModuleService,
6+
}
7+
8+
export default moduleExports
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { FeatureFlag, defineFileConfig } from "@medusajs/framework/utils"
2+
import { Migration } from "@mikro-orm/migrations"
3+
4+
defineFileConfig({
5+
isDisabled: () => !FeatureFlag.isFeatureEnabled("custom_ff"),
6+
})
7+
8+
export class MigrationTest extends Migration {
9+
override async up(): Promise<void> {}
10+
11+
override async down(): Promise<void> {}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { IModuleService } from "@medusajs/types"
2+
import { MedusaContext } from "@medusajs/utils"
3+
4+
// @ts-expect-error
5+
export class ModuleService implements IModuleService {
6+
public property = "value"
7+
8+
constructor() {}
9+
async methodName(input, @MedusaContext() context) {
10+
return input + " called"
11+
}
12+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { defineFileConfig, FeatureFlag } from "@medusajs/framework/utils"
2+
3+
const testProductCreatedHandlerMock = jest.fn()
4+
5+
export default testProductCreatedHandlerMock
6+
7+
export const config = {
8+
event: "event.test",
9+
}
10+
11+
defineFileConfig({
12+
isDisabled: () => !FeatureFlag.isFeatureEnabled("custom_ff"),
13+
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineFileConfig, FeatureFlag } from "@medusajs/framework/utils"
2+
import { createStep, createWorkflow } from "@medusajs/framework/workflows-sdk"
3+
4+
const testWorkflowHandler = jest.fn()
5+
6+
const step1 = createStep("step1", () => testWorkflowHandler())
7+
8+
export const testWorkflow = createWorkflow("test-workflow", () => {
9+
step1()
10+
})
11+
12+
defineFileConfig({
13+
isDisabled: () => !FeatureFlag.isFeatureEnabled("custom_ff"),
14+
})

0 commit comments

Comments
 (0)