feat(medusa): Validate module required properties (#3029)
This commit is contained in:
1 parent
142c8aa70f
commit
f6ec05f3f9
2 files changed
+112
-4
No files matched your search
@@ -95,6 +95,10 @@ describe("modules loader", () => {
|
|||||||
resources: MODULE_RESOURCE_TYPE.SHARED,
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
moduleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +127,10 @@ describe("modules loader", () => {
|
|||||||
resources: MODULE_RESOURCE_TYPE.SHARED,
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
moduleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +170,10 @@ describe("modules loader", () => {
|
|||||||
resources: MODULE_RESOURCE_TYPE.SHARED,
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
moduleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +206,10 @@ describe("modules loader", () => {
|
|||||||
resources: MODULE_RESOURCE_TYPE.SHARED,
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
moduleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +244,10 @@ describe("modules loader", () => {
|
|||||||
resources: MODULE_RESOURCE_TYPE.SHARED,
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
moduleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,4 +262,74 @@ describe("modules loader", () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("throws error if no scope is defined to the module", async () => {
|
||||||
|
expect.assertions(1)
|
||||||
|
const moduleResolutions: Record<string, ModuleResolution> = {
|
||||||
|
testService: {
|
||||||
|
resolutionPath: "@modules/no-service",
|
||||||
|
definition: {
|
||||||
|
registrationName: "testService",
|
||||||
|
key: "testService",
|
||||||
|
defaultPackage: "testService",
|
||||||
|
label: "TestService",
|
||||||
|
isRequired: true,
|
||||||
|
defaultModuleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
moduleDeclaration: {
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const configModule = buildConfigModule({
|
||||||
|
moduleResolutions,
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await registerModules({ container, configModule, logger: Logger })
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.message).toEqual(
|
||||||
|
"The module TestService has to define its scope (internal | external)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it("throws error if resources is not set when scope is defined as internal", async () => {
|
||||||
|
expect.assertions(1)
|
||||||
|
const moduleResolutions: Record<string, ModuleResolution> = {
|
||||||
|
testService: {
|
||||||
|
resolutionPath: "@modules/no-service",
|
||||||
|
definition: {
|
||||||
|
registrationName: "testService",
|
||||||
|
key: "testService",
|
||||||
|
defaultPackage: "testService",
|
||||||
|
label: "TestService",
|
||||||
|
isRequired: true,
|
||||||
|
defaultModuleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
moduleDeclaration: {
|
||||||
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const configModule = buildConfigModule({
|
||||||
|
moduleResolutions,
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await registerModules({ container, configModule, logger: Logger })
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.message).toEqual(
|
||||||
|
"The module TestService is missing its resources config"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -22,9 +22,27 @@ const registerModule = async (
|
|||||||
configModule: ConfigModule,
|
configModule: ConfigModule,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
): Promise<{ error?: Error } | void> => {
|
): Promise<{ error?: Error } | void> => {
|
||||||
|
const constainerName = resolution.definition.registrationName
|
||||||
|
|
||||||
|
const { scope, resources } = resolution.moduleDeclaration ?? {}
|
||||||
|
if (!scope || (scope === MODULE_SCOPE.INTERNAL && !resources)) {
|
||||||
|
let message = `The module ${resolution.definition.label} has to define its scope (internal | external)`
|
||||||
|
if (scope && !resources) {
|
||||||
|
message = `The module ${resolution.definition.label} is missing its resources config`
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register({
|
||||||
|
[constainerName]: asValue(false),
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
error: new Error(message),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!resolution.resolutionPath) {
|
if (!resolution.resolutionPath) {
|
||||||
container.register({
|
container.register({
|
||||||
[resolution.definition.registrationName]: asValue(false),
|
[constainerName]: asValue(false),
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -48,8 +66,8 @@ const registerModule = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
resolution.moduleDeclaration?.scope === MODULE_SCOPE.INTERNAL &&
|
scope === MODULE_SCOPE.INTERNAL &&
|
||||||
resolution.moduleDeclaration?.resources === MODULE_RESOURCE_TYPE.SHARED
|
resources === MODULE_RESOURCE_TYPE.SHARED
|
||||||
) {
|
) {
|
||||||
const moduleModels = loadedModule?.models || null
|
const moduleModels = loadedModule?.models || null
|
||||||
if (moduleModels) {
|
if (moduleModels) {
|
||||||
@@ -61,7 +79,7 @@ const registerModule = async (
|
|||||||
|
|
||||||
// TODO: "cradle" should only contain dependent Modules and the EntityManager if module scope is shared
|
// TODO: "cradle" should only contain dependent Modules and the EntityManager if module scope is shared
|
||||||
container.register({
|
container.register({
|
||||||
[resolution.definition.registrationName]: asFunction((cradle) => {
|
[constainerName]: asFunction((cradle) => {
|
||||||
return new moduleService(
|
return new moduleService(
|
||||||
cradle,
|
cradle,
|
||||||
resolution.options,
|
resolution.options,
|
||||||
|
|||||||
Reference in new issue
Block a user