feat(medusa, modules-sdk, types, utils): Re work modules loading and remove legacy functions (#5496)
This commit is contained in:
committed by
GitHub
parent
ca411e54eb
commit
154c9b43bd
@@ -3,6 +3,5 @@ export * from "./definitions"
|
||||
export * from "./loaders"
|
||||
export * from "./medusa-app"
|
||||
export * from "./medusa-module"
|
||||
export * from "./module-helper"
|
||||
export * from "./remote-link"
|
||||
export * from "./remote-query"
|
||||
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
MODULE_SCOPE,
|
||||
ModuleDefinition,
|
||||
} from "@medusajs/types"
|
||||
import MODULE_DEFINITIONS from "../../definitions"
|
||||
import { registerModules } from "../register-modules"
|
||||
import { ModulesDefinition } from "../../definitions"
|
||||
import { registerMedusaModule } from "../register-modules"
|
||||
|
||||
const RESOLVED_PACKAGE = "@medusajs/test-service-resolved"
|
||||
jest.mock("resolve-cwd", () => jest.fn(() => RESOLVED_PACKAGE))
|
||||
@@ -30,13 +30,18 @@ describe("module definitions loader", () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
// Clear module definitions
|
||||
MODULE_DEFINITIONS.splice(0, MODULE_DEFINITIONS.length)
|
||||
const allProperties = Object.getOwnPropertyNames(ModulesDefinition)
|
||||
allProperties.forEach((property) => {
|
||||
delete ModulesDefinition[property]
|
||||
})
|
||||
})
|
||||
|
||||
it("Resolves module with default definition given empty config", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: defaultDefinition,
|
||||
})
|
||||
|
||||
const res = registerModules({})
|
||||
const res = registerMedusaModule(defaultDefinition.key)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
@@ -53,9 +58,11 @@ describe("module definitions loader", () => {
|
||||
|
||||
describe("boolean config", () => {
|
||||
it("Resolves module with no resolution path when given false", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: defaultDefinition,
|
||||
})
|
||||
|
||||
const res = registerModules({ [defaultDefinition.key]: false })
|
||||
const res = registerMedusaModule(defaultDefinition.key, false)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
@@ -68,10 +75,12 @@ describe("module definitions loader", () => {
|
||||
|
||||
it("Fails to resolve module with no resolution path when given false for a required module", () => {
|
||||
expect.assertions(1)
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition, isRequired: true })
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: { ...defaultDefinition, isRequired: true },
|
||||
})
|
||||
|
||||
try {
|
||||
registerModules({ [defaultDefinition.key]: false })
|
||||
registerMedusaModule(defaultDefinition.key, false)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
`Module: ${defaultDefinition.label} is required`
|
||||
@@ -87,9 +96,11 @@ describe("module definitions loader", () => {
|
||||
isRequired: true,
|
||||
}
|
||||
|
||||
MODULE_DEFINITIONS.push(definition)
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: definition,
|
||||
})
|
||||
|
||||
const res = registerModules({})
|
||||
const res = registerMedusaModule(defaultDefinition.key)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
@@ -106,12 +117,15 @@ describe("module definitions loader", () => {
|
||||
|
||||
describe("string config", () => {
|
||||
it("Resolves module with default definition given empty config", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = registerModules({
|
||||
[defaultDefinition.key]: defaultDefinition.defaultPackage,
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: defaultDefinition,
|
||||
})
|
||||
|
||||
const res = registerMedusaModule(
|
||||
defaultDefinition.key,
|
||||
defaultDefinition.defaultPackage
|
||||
)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
resolutionPath: RESOLVED_PACKAGE,
|
||||
@@ -128,16 +142,16 @@ describe("module definitions loader", () => {
|
||||
|
||||
describe("object config", () => {
|
||||
it("Resolves resolution path and provides empty options when none are provided", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = registerModules({
|
||||
[defaultDefinition.key]: {
|
||||
scope: MODULE_SCOPE.INTERNAL,
|
||||
resolve: defaultDefinition.defaultPackage,
|
||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||
} as InternalModuleDeclaration,
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: defaultDefinition,
|
||||
})
|
||||
|
||||
const res = registerMedusaModule(defaultDefinition.key, {
|
||||
scope: MODULE_SCOPE.INTERNAL,
|
||||
resolve: defaultDefinition.defaultPackage,
|
||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||
} as InternalModuleDeclaration)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
resolutionPath: RESOLVED_PACKAGE,
|
||||
@@ -153,12 +167,12 @@ describe("module definitions loader", () => {
|
||||
})
|
||||
|
||||
it("Resolves default resolution path and provides options when only options are provided", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: defaultDefinition,
|
||||
})
|
||||
|
||||
const res = registerModules({
|
||||
[defaultDefinition.key]: {
|
||||
options: { test: 123 },
|
||||
},
|
||||
const res = registerMedusaModule(defaultDefinition.key, {
|
||||
options: { test: 123 },
|
||||
} as any)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
@@ -176,15 +190,15 @@ describe("module definitions loader", () => {
|
||||
})
|
||||
|
||||
it("Resolves resolution path and provides options when only options are provided", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
Object.assign(ModulesDefinition, {
|
||||
[defaultDefinition.key]: defaultDefinition,
|
||||
})
|
||||
|
||||
const res = registerModules({
|
||||
[defaultDefinition.key]: {
|
||||
resolve: defaultDefinition.defaultPackage,
|
||||
options: { test: 123 },
|
||||
scope: "internal",
|
||||
resources: "isolated",
|
||||
},
|
||||
const res = registerMedusaModule(defaultDefinition.key, {
|
||||
resolve: defaultDefinition.defaultPackage,
|
||||
options: { test: 123 },
|
||||
scope: "internal",
|
||||
resources: "isolated",
|
||||
} as any)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import {
|
||||
Logger,
|
||||
MODULE_SCOPE,
|
||||
MedusaContainer,
|
||||
MODULE_SCOPE,
|
||||
ModuleResolution,
|
||||
} from "@medusajs/types"
|
||||
|
||||
import { asValue } from "awilix"
|
||||
import { EOL } from "os"
|
||||
import { ModulesHelper } from "../module-helper"
|
||||
import { loadInternalModule } from "./utils"
|
||||
|
||||
export const moduleHelper = new ModulesHelper()
|
||||
|
||||
export const moduleLoader = async ({
|
||||
container,
|
||||
moduleResolutions,
|
||||
@@ -38,17 +35,6 @@ export const moduleLoader = async ({
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
moduleHelper.setModules(
|
||||
Object.entries(moduleResolutions).reduce((acc, [k, v]) => {
|
||||
if (v.resolutionPath) {
|
||||
acc[k] = v
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
)
|
||||
|
||||
container.register("modulesHelper", asValue(moduleHelper))
|
||||
}
|
||||
|
||||
async function loadModule(
|
||||
|
||||
@@ -9,57 +9,11 @@ import {
|
||||
|
||||
import { isObject } from "@medusajs/utils"
|
||||
import resolveCwd from "resolve-cwd"
|
||||
import { MODULE_DEFINITIONS, ModulesDefinition } from "../definitions"
|
||||
|
||||
/**
|
||||
*
|
||||
* @param modules
|
||||
* @param isolatedModules Will be removed once the isolated flag is being removed
|
||||
*/
|
||||
// TODO: Remove once we have all modules migrated + rename to something like getResolutions
|
||||
export const registerModules = (
|
||||
modules?: Record<
|
||||
string,
|
||||
| false
|
||||
| string
|
||||
| Partial<InternalModuleDeclaration | ExternalModuleDeclaration>
|
||||
>,
|
||||
{ loadLegacyOnly } = { loadLegacyOnly: false }
|
||||
): Record<string, ModuleResolution> => {
|
||||
const moduleResolutions = {} as Record<string, ModuleResolution>
|
||||
const projectModules = modules ?? {}
|
||||
|
||||
for (const definition of MODULE_DEFINITIONS) {
|
||||
// Skip non legacy modules
|
||||
if (loadLegacyOnly && !definition.isLegacy) {
|
||||
continue
|
||||
}
|
||||
|
||||
const customConfig = projectModules[definition.key]
|
||||
|
||||
const canSkip =
|
||||
!customConfig && !definition.isRequired && !definition.defaultPackage
|
||||
|
||||
const isObj = isObject(customConfig)
|
||||
if (isObj && customConfig.scope === MODULE_SCOPE.EXTERNAL) {
|
||||
// TODO: getExternalModuleResolution(...)
|
||||
if (!canSkip) {
|
||||
throw new Error("External Modules are not supported yet.")
|
||||
}
|
||||
}
|
||||
|
||||
moduleResolutions[definition.key] = getInternalModuleResolution(
|
||||
definition,
|
||||
customConfig as InternalModuleDeclaration
|
||||
)
|
||||
}
|
||||
|
||||
return moduleResolutions
|
||||
}
|
||||
import { ModulesDefinition } from "../definitions"
|
||||
|
||||
export const registerMedusaModule = (
|
||||
moduleKey: string,
|
||||
moduleDeclaration:
|
||||
moduleDeclaration?:
|
||||
| Partial<InternalModuleDeclaration | ExternalModuleDeclaration>
|
||||
| string
|
||||
| false,
|
||||
@@ -74,9 +28,17 @@ export const registerMedusaModule = (
|
||||
throw new Error(`Module: ${moduleKey} is not defined.`)
|
||||
}
|
||||
|
||||
const modDeclaration =
|
||||
moduleDeclaration ??
|
||||
(modDefinition?.defaultModuleDeclaration as InternalModuleDeclaration)
|
||||
|
||||
if (modDeclaration !== false && !modDeclaration) {
|
||||
throw new Error(`Module: ${moduleKey} has no declaration.`)
|
||||
}
|
||||
|
||||
if (
|
||||
isObject(moduleDeclaration) &&
|
||||
moduleDeclaration?.scope === MODULE_SCOPE.EXTERNAL
|
||||
isObject(modDeclaration) &&
|
||||
modDeclaration?.scope === MODULE_SCOPE.EXTERNAL
|
||||
) {
|
||||
// TODO: getExternalModuleResolution(...)
|
||||
throw new Error("External Modules are not supported yet.")
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import {
|
||||
Constructor,
|
||||
InternalModuleDeclaration,
|
||||
Logger,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
MODULE_SCOPE,
|
||||
MedusaContainer,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
ModuleExports,
|
||||
ModuleResolution,
|
||||
} from "@medusajs/types"
|
||||
@@ -65,18 +63,6 @@ export async function loadInternalModule(
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
scope === MODULE_SCOPE.INTERNAL &&
|
||||
resources === MODULE_RESOURCE_TYPE.SHARED
|
||||
) {
|
||||
const moduleModels = loadedModule?.models || null
|
||||
if (moduleModels) {
|
||||
moduleModels.map((val: Constructor<unknown>) => {
|
||||
container.registerAdd("db_entities", asValue(val))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const localContainer = createMedusaContainer()
|
||||
|
||||
const dependencies = resolution?.dependencies ?? []
|
||||
|
||||
@@ -40,8 +40,8 @@ export type RunMigrationFn = (
|
||||
|
||||
export type MedusaModuleConfig = {
|
||||
[key: string | Modules]:
|
||||
| boolean
|
||||
| Partial<InternalModuleDeclaration | ExternalModuleDeclaration>
|
||||
| true
|
||||
}
|
||||
|
||||
export type SharedResources = {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { ModuleResolution, ModulesResponse } from "@medusajs/types"
|
||||
|
||||
export class ModulesHelper {
|
||||
private modules_: Record<string, ModuleResolution> = {}
|
||||
|
||||
setModules(modules: Record<string, ModuleResolution>) {
|
||||
this.modules_ = modules
|
||||
}
|
||||
|
||||
get modules(): ModulesResponse {
|
||||
return Object.values(this.modules_ || {}).map((value) => ({
|
||||
module: value.definition.key,
|
||||
resolution: value.resolutionPath,
|
||||
}))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user