fix(medusa, modules-sdk, modules): Module loading missing dependencies + remote query reference issue (#5468)
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/cache-inmemory": patch
|
||||||
|
"@medusajs/cache-redis": patch
|
||||||
|
"@medusajs/event-bus-local": patch
|
||||||
|
"@medusajs/event-bus-redis": patch
|
||||||
|
"@medusajs/inventory": patch
|
||||||
|
"@medusajs/link-modules": patch
|
||||||
|
"@medusajs/modules-sdk": patch
|
||||||
|
"@medusajs/pricing": patch
|
||||||
|
"@medusajs/product": patch
|
||||||
|
"@medusajs/stock-location": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(medusa, modules-sdk, modules): Module loading was missing the expected dependencies and remote query reference fix
|
||||||
@@ -11,12 +11,13 @@ export const initialize = async (
|
|||||||
options?: InMemoryCacheModuleOptions | ExternalModuleDeclaration
|
options?: InMemoryCacheModuleOptions | ExternalModuleDeclaration
|
||||||
): Promise<ICacheService> => {
|
): Promise<ICacheService> => {
|
||||||
const serviceKey = Modules.CACHE
|
const serviceKey = Modules.CACHE
|
||||||
const loaded = await MedusaModule.bootstrap<ICacheService>(
|
const loaded = await MedusaModule.bootstrap<ICacheService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
"@medusajs/cache-inmemory",
|
defaultPath: "@medusajs/cache-inmemory",
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
undefined
|
| InternalModuleDeclaration
|
||||||
)
|
| ExternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ export const initialize = async (
|
|||||||
options?: RedisCacheModuleOptions | ExternalModuleDeclaration
|
options?: RedisCacheModuleOptions | ExternalModuleDeclaration
|
||||||
): Promise<ICacheService> => {
|
): Promise<ICacheService> => {
|
||||||
const serviceKey = Modules.CACHE
|
const serviceKey = Modules.CACHE
|
||||||
const loaded = await MedusaModule.bootstrap<ICacheService>(
|
const loaded = await MedusaModule.bootstrap<ICacheService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
"@medusajs/cache-redis",
|
defaultPath: "@medusajs/cache-redis",
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
undefined
|
| InternalModuleDeclaration
|
||||||
)
|
| ExternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { IEventBusService } from "@medusajs/types"
|
|||||||
|
|
||||||
export const initialize = async (): Promise<IEventBusService> => {
|
export const initialize = async (): Promise<IEventBusService> => {
|
||||||
const serviceKey = Modules.EVENT_BUS
|
const serviceKey = Modules.EVENT_BUS
|
||||||
const loaded = await MedusaModule.bootstrap<IEventBusService>(
|
const loaded = await MedusaModule.bootstrap<IEventBusService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
"@medusajs/event-bus-local"
|
defaultPath: "@medusajs/event-bus-local",
|
||||||
)
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ export const initialize = async (
|
|||||||
options?: EventBusRedisModuleOptions | ExternalModuleDeclaration
|
options?: EventBusRedisModuleOptions | ExternalModuleDeclaration
|
||||||
): Promise<IEventBusService> => {
|
): Promise<IEventBusService> => {
|
||||||
const serviceKey = Modules.EVENT_BUS
|
const serviceKey = Modules.EVENT_BUS
|
||||||
const loaded = await MedusaModule.bootstrap<IEventBusService>(
|
const loaded = await MedusaModule.bootstrap<IEventBusService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
"@medusajs/event-bus-redis",
|
defaultPath: "@medusajs/event-bus-redis",
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
undefined
|
| InternalModuleDeclaration
|
||||||
)
|
| ExternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
ExternalModuleDeclaration,
|
ExternalModuleDeclaration,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
MedusaModule,
|
MedusaModule,
|
||||||
|
MODULE_PACKAGE_NAMES,
|
||||||
Modules,
|
Modules,
|
||||||
} from "@medusajs/modules-sdk"
|
} from "@medusajs/modules-sdk"
|
||||||
import { IEventBusService, IInventoryService } from "@medusajs/types"
|
import { IEventBusService, IInventoryService } from "@medusajs/types"
|
||||||
@@ -15,13 +16,15 @@ export const initialize = async (
|
|||||||
}
|
}
|
||||||
): Promise<IInventoryService> => {
|
): Promise<IInventoryService> => {
|
||||||
const serviceKey = Modules.INVENTORY
|
const serviceKey = Modules.INVENTORY
|
||||||
const loaded = await MedusaModule.bootstrap<IInventoryService>(
|
const loaded = await MedusaModule.bootstrap<IInventoryService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
"@medusajs/inventory",
|
defaultPath: MODULE_PACKAGE_NAMES[Modules.INVENTORY],
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
moduleDefinition,
|
| InternalModuleDeclaration
|
||||||
injectedDependencies
|
| ExternalModuleDeclaration,
|
||||||
)
|
injectedDependencies,
|
||||||
|
moduleExports: moduleDefinition,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,12 +120,12 @@ export const initialize = async (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const loaded = await MedusaModule.bootstrapLink(
|
const loaded = await MedusaModule.bootstrapLink({
|
||||||
linkModuleDefinition,
|
definition: linkModuleDefinition,
|
||||||
options as InternalModuleDeclaration,
|
declaration: options as InternalModuleDeclaration,
|
||||||
moduleDefinition,
|
moduleExports: moduleDefinition,
|
||||||
injectedDependencies
|
injectedDependencies,
|
||||||
)
|
})
|
||||||
|
|
||||||
allLinks[serviceKey as string] = Object.values(loaded)[0]
|
allLinks[serviceKey as string] = Object.values(loaded)[0]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ export default async ({
|
|||||||
modulesConfig,
|
modulesConfig,
|
||||||
servicesConfig: joinerConfig,
|
servicesConfig: joinerConfig,
|
||||||
remoteFetchData: remoteQueryFetchData(container),
|
remoteFetchData: remoteQueryFetchData(container),
|
||||||
|
sharedContainer: container,
|
||||||
injectedDependencies: {
|
injectedDependencies: {
|
||||||
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
||||||
ContainerRegistrationKeys.PG_CONNECTION
|
ContainerRegistrationKeys.PG_CONNECTION
|
||||||
|
|||||||
@@ -46,35 +46,47 @@ describe("Medusa Modules", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should create singleton instances", async () => {
|
it("should create singleton instances", async () => {
|
||||||
await MedusaModule.bootstrap("moduleKey", "@path", {
|
await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
abc: 123,
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
expect(mockRegisterMedusaModule).toBeCalledTimes(1)
|
expect(mockRegisterMedusaModule).toBeCalledTimes(1)
|
||||||
expect(mockModuleLoader).toBeCalledTimes(1)
|
expect(mockModuleLoader).toBeCalledTimes(1)
|
||||||
|
|
||||||
await MedusaModule.bootstrap("moduleKey", "@path", {
|
await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
abc: 123,
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
await MedusaModule.bootstrap("moduleKey", "@path", {
|
await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
different_options: "abc",
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
different_options: "abc",
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
expect(mockRegisterMedusaModule).toBeCalledTimes(2)
|
expect(mockRegisterMedusaModule).toBeCalledTimes(2)
|
||||||
expect(mockModuleLoader).toBeCalledTimes(2)
|
expect(mockModuleLoader).toBeCalledTimes(2)
|
||||||
@@ -85,14 +97,18 @@ describe("Medusa Modules", () => {
|
|||||||
|
|
||||||
for (let i = 5; i--; ) {
|
for (let i = 5; i--; ) {
|
||||||
load.push(
|
load.push(
|
||||||
MedusaModule.bootstrap("moduleKey", "@path", {
|
MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
abc: 123,
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,81 +120,109 @@ describe("Medusa Modules", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("getModuleInstance should return the first instance of the module if there is none flagged as 'main'", async () => {
|
it("getModuleInstance should return the first instance of the module if there is none flagged as 'main'", async () => {
|
||||||
const moduleA = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleA = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
abc: 123,
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
const moduleB = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleB = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
different_options: "abc",
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
different_options: "abc",
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
expect(MedusaModule.getModuleInstance("moduleKey")).toEqual(moduleA)
|
expect(MedusaModule.getModuleInstance("moduleKey")).toEqual(moduleA)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return the module flagged as 'main' when multiple instances are available", async () => {
|
it("should return the module flagged as 'main' when multiple instances are available", async () => {
|
||||||
const moduleA = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleA = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
options: {
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
abc: 123,
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
},
|
resolve: "@path",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
const moduleB = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleB = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
main: true,
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
options: {
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
different_options: "abc",
|
resolve: "@path",
|
||||||
},
|
main: true,
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
different_options: "abc",
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
expect(MedusaModule.getModuleInstance("moduleKey")).toEqual(moduleB)
|
expect(MedusaModule.getModuleInstance("moduleKey")).toEqual(moduleB)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should retrieve the module by their given alias", async () => {
|
it("should retrieve the module by their given alias", async () => {
|
||||||
const moduleA = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleA = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
alias: "mod_A",
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
options: {
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
abc: 123,
|
resolve: "@path",
|
||||||
},
|
alias: "mod_A",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
const moduleB = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleB = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
main: true,
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
alias: "mod_B",
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
options: {
|
resolve: "@path",
|
||||||
different_options: "abc",
|
main: true,
|
||||||
},
|
alias: "mod_B",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
different_options: "abc",
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
const moduleC = await MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleC = await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
alias: "mod_C",
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
options: {
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
moduleC: true,
|
resolve: "@path",
|
||||||
},
|
alias: "mod_C",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
moduleC: true,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
// main
|
// main
|
||||||
expect(MedusaModule.getModuleInstance("moduleKey")).toEqual(moduleB)
|
expect(MedusaModule.getModuleInstance("moduleKey")).toEqual(moduleB)
|
||||||
@@ -195,37 +239,49 @@ describe("Medusa Modules", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should prevent two main modules being set as 'main'", async () => {
|
it("should prevent two main modules being set as 'main'", async () => {
|
||||||
await MedusaModule.bootstrap("moduleKey", "@path", {
|
await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
alias: "mod_A",
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
options: {
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
abc: 123,
|
resolve: "@path",
|
||||||
},
|
alias: "mod_A",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
abc: 123,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
await MedusaModule.bootstrap("moduleKey", "@path", {
|
await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
main: true,
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
alias: "mod_B",
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
options: {
|
resolve: "@path",
|
||||||
different_options: "abc",
|
main: true,
|
||||||
},
|
alias: "mod_B",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
different_options: "abc",
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
const moduleC = MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleC = MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
main: true,
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
alias: "mod_C",
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
options: {
|
resolve: "@path",
|
||||||
moduleC: true,
|
main: true,
|
||||||
},
|
alias: "mod_C",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
moduleC: true,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
expect(moduleC).rejects.toThrow(
|
expect(moduleC).rejects.toThrow(
|
||||||
"Module moduleKey already have a 'main' registered."
|
"Module moduleKey already have a 'main' registered."
|
||||||
@@ -233,25 +289,33 @@ describe("Medusa Modules", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should prevent the same alias be used for different instances of the same module", async () => {
|
it("should prevent the same alias be used for different instances of the same module", async () => {
|
||||||
await MedusaModule.bootstrap("moduleKey", "@path", {
|
await MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
alias: "module_alias",
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
options: {
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
different_options: "abc",
|
resolve: "@path",
|
||||||
},
|
alias: "module_alias",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
different_options: "abc",
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
const moduleC = MedusaModule.bootstrap("moduleKey", "@path", {
|
const moduleC = MedusaModule.bootstrap({
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
moduleKey: "moduleKey",
|
||||||
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
defaultPath: "@path",
|
||||||
resolve: "@path",
|
declaration: {
|
||||||
alias: "module_alias",
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
options: {
|
resources: MODULE_RESOURCE_TYPE.ISOLATED,
|
||||||
moduleC: true,
|
resolve: "@path",
|
||||||
},
|
alias: "module_alias",
|
||||||
} as InternalModuleDeclaration)
|
options: {
|
||||||
|
moduleC: true,
|
||||||
|
},
|
||||||
|
} as InternalModuleDeclaration,
|
||||||
|
})
|
||||||
|
|
||||||
expect(moduleC).rejects.toThrow(
|
expect(moduleC).rejects.toThrow(
|
||||||
"Module moduleKey already registed as 'module_alias'. Please choose a different alias."
|
"Module moduleKey already registed as 'module_alias'. Please choose a different alias."
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
LoadedModule,
|
LoadedModule,
|
||||||
LoaderOptions,
|
LoaderOptions,
|
||||||
|
MedusaContainer,
|
||||||
MODULE_RESOURCE_TYPE,
|
MODULE_RESOURCE_TYPE,
|
||||||
MODULE_SCOPE,
|
MODULE_SCOPE,
|
||||||
ModuleDefinition,
|
ModuleDefinition,
|
||||||
@@ -15,14 +16,20 @@ import {
|
|||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
ContainerRegistrationKeys,
|
ContainerRegistrationKeys,
|
||||||
ModulesSdkUtils,
|
createMedusaContainer,
|
||||||
isObject,
|
isObject,
|
||||||
|
ModulesSdkUtils,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { MODULE_PACKAGE_NAMES, Modules } from "./definitions"
|
import {
|
||||||
|
MODULE_PACKAGE_NAMES,
|
||||||
|
ModuleRegistrationName,
|
||||||
|
Modules,
|
||||||
|
} from "./definitions"
|
||||||
import { MedusaModule } from "./medusa-module"
|
import { MedusaModule } from "./medusa-module"
|
||||||
import { RemoteLink } from "./remote-link"
|
import { RemoteLink } from "./remote-link"
|
||||||
import { RemoteQuery } from "./remote-query"
|
import { RemoteQuery } from "./remote-query"
|
||||||
import { cleanGraphQLSchema } from "./utils"
|
import { cleanGraphQLSchema } from "./utils"
|
||||||
|
import { asValue } from "awilix"
|
||||||
|
|
||||||
const LinkModulePackage = "@medusajs/link-modules"
|
const LinkModulePackage = "@medusajs/link-modules"
|
||||||
|
|
||||||
@@ -57,7 +64,7 @@ export type SharedResources = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadModules(modulesConfig, injectedDependencies) {
|
async function loadModules(modulesConfig, sharedContainer) {
|
||||||
const allModules = {}
|
const allModules = {}
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
@@ -85,14 +92,18 @@ async function loadModules(modulesConfig, injectedDependencies) {
|
|||||||
declaration.resources = MODULE_RESOURCE_TYPE.SHARED
|
declaration.resources = MODULE_RESOURCE_TYPE.SHARED
|
||||||
}
|
}
|
||||||
|
|
||||||
const loaded = (await MedusaModule.bootstrap(
|
const loaded = (await MedusaModule.bootstrap({
|
||||||
moduleName,
|
moduleKey: moduleName,
|
||||||
path,
|
defaultPath: path,
|
||||||
declaration,
|
declaration,
|
||||||
undefined,
|
sharedContainer,
|
||||||
injectedDependencies,
|
moduleDefinition: definition,
|
||||||
definition
|
})) as LoadedModule
|
||||||
)) as LoadedModule
|
|
||||||
|
const service = loaded[moduleName]
|
||||||
|
sharedContainer.register({
|
||||||
|
[service.__definition.registrationName]: asValue(service),
|
||||||
|
})
|
||||||
|
|
||||||
if (allModules[moduleName] && !Array.isArray(allModules[moduleName])) {
|
if (allModules[moduleName] && !Array.isArray(allModules[moduleName])) {
|
||||||
allModules[moduleName] = []
|
allModules[moduleName] = []
|
||||||
@@ -153,6 +164,7 @@ function registerCustomJoinerConfigs(servicesConfig: ModuleJoinerConfig[]) {
|
|||||||
|
|
||||||
export async function MedusaApp(
|
export async function MedusaApp(
|
||||||
{
|
{
|
||||||
|
sharedContainer,
|
||||||
sharedResourcesConfig,
|
sharedResourcesConfig,
|
||||||
servicesConfig,
|
servicesConfig,
|
||||||
modulesConfigPath,
|
modulesConfigPath,
|
||||||
@@ -162,6 +174,7 @@ export async function MedusaApp(
|
|||||||
remoteFetchData,
|
remoteFetchData,
|
||||||
injectedDependencies,
|
injectedDependencies,
|
||||||
}: {
|
}: {
|
||||||
|
sharedContainer?: MedusaContainer
|
||||||
sharedResourcesConfig?: SharedResources
|
sharedResourcesConfig?: SharedResources
|
||||||
loadedModules?: LoadedModule[]
|
loadedModules?: LoadedModule[]
|
||||||
servicesConfig?: ModuleJoinerConfig[]
|
servicesConfig?: ModuleJoinerConfig[]
|
||||||
@@ -185,6 +198,8 @@ export async function MedusaApp(
|
|||||||
notFound?: Record<string, Record<string, string>>
|
notFound?: Record<string, Record<string, string>>
|
||||||
runMigrations: RunMigrationFn
|
runMigrations: RunMigrationFn
|
||||||
}> {
|
}> {
|
||||||
|
const sharedContainer_ = createMedusaContainer({}, sharedContainer)
|
||||||
|
|
||||||
const modules: MedusaModuleConfig =
|
const modules: MedusaModuleConfig =
|
||||||
modulesConfig ??
|
modulesConfig ??
|
||||||
(
|
(
|
||||||
@@ -222,7 +237,20 @@ export async function MedusaApp(
|
|||||||
linkModuleOptions = linkModule
|
linkModuleOptions = linkModule
|
||||||
}
|
}
|
||||||
|
|
||||||
const allModules = await loadModules(modules, injectedDependencies)
|
for (const injectedDependency of Object.keys(injectedDependencies)) {
|
||||||
|
sharedContainer_.register({
|
||||||
|
[injectedDependency]: asValue(injectedDependencies[injectedDependency]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const allModules = await loadModules(modules, sharedContainer_)
|
||||||
|
|
||||||
|
// Share Event bus with link modules
|
||||||
|
injectedDependencies[ModuleRegistrationName.EVENT_BUS] =
|
||||||
|
sharedContainer_.resolve(ModuleRegistrationName.EVENT_BUS, {
|
||||||
|
allowUnregistered: true,
|
||||||
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
remoteLink,
|
remoteLink,
|
||||||
linkResolution,
|
linkResolution,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
LinkModuleDefinition,
|
LinkModuleDefinition,
|
||||||
LoadedModule,
|
LoadedModule,
|
||||||
|
MedusaContainer,
|
||||||
MODULE_RESOURCE_TYPE,
|
MODULE_RESOURCE_TYPE,
|
||||||
MODULE_SCOPE,
|
MODULE_SCOPE,
|
||||||
ModuleDefinition,
|
ModuleDefinition,
|
||||||
@@ -48,6 +49,23 @@ type ModuleAlias = {
|
|||||||
main?: boolean
|
main?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ModuleBootstrapOptions = {
|
||||||
|
moduleKey: string
|
||||||
|
defaultPath: string
|
||||||
|
declaration?: InternalModuleDeclaration | ExternalModuleDeclaration
|
||||||
|
moduleExports?: ModuleExports
|
||||||
|
sharedContainer?: MedusaContainer
|
||||||
|
moduleDefinition?: ModuleDefinition
|
||||||
|
injectedDependencies?: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkModuleBootstrapOptions = {
|
||||||
|
definition: LinkModuleDefinition
|
||||||
|
declaration?: InternalModuleDeclaration
|
||||||
|
moduleExports?: ModuleExports
|
||||||
|
injectedDependencies?: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
export class MedusaModule {
|
export class MedusaModule {
|
||||||
private static instances_: Map<string, any> = new Map()
|
private static instances_: Map<string, any> = new Map()
|
||||||
private static modules_: Map<string, ModuleAlias[]> = new Map()
|
private static modules_: Map<string, ModuleAlias[]> = new Map()
|
||||||
@@ -146,14 +164,15 @@ export class MedusaModule {
|
|||||||
MedusaModule.modules_.set(moduleKey, modules!)
|
MedusaModule.modules_.set(moduleKey, modules!)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async bootstrap<T>(
|
public static async bootstrap<T>({
|
||||||
moduleKey: string,
|
moduleKey,
|
||||||
defaultPath: string,
|
defaultPath,
|
||||||
declaration?: InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration,
|
||||||
moduleExports?: ModuleExports,
|
moduleExports,
|
||||||
injectedDependencies?: Record<string, any>,
|
sharedContainer,
|
||||||
moduleDefinition?: ModuleDefinition
|
moduleDefinition,
|
||||||
): Promise<{
|
injectedDependencies,
|
||||||
|
}: ModuleBootstrapOptions): Promise<{
|
||||||
[key: string]: T
|
[key: string]: T
|
||||||
}> {
|
}> {
|
||||||
const hashKey = simpleHash(
|
const hashKey = simpleHash(
|
||||||
@@ -193,11 +212,14 @@ export class MedusaModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = createMedusaContainer()
|
const container = createMedusaContainer({}, sharedContainer)
|
||||||
|
|
||||||
if (injectedDependencies) {
|
if (injectedDependencies) {
|
||||||
for (const service in injectedDependencies) {
|
for (const service in injectedDependencies) {
|
||||||
container.register(service, asValue(injectedDependencies[service]))
|
container.register(service, asValue(injectedDependencies[service]))
|
||||||
|
if (!container.hasRegistration(service)) {
|
||||||
|
container.register(service, asValue(injectedDependencies[service]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,19 +277,19 @@ export class MedusaModule {
|
|||||||
return services
|
return services
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async bootstrapLink(
|
public static async bootstrapLink({
|
||||||
definition: LinkModuleDefinition,
|
definition,
|
||||||
declaration?: InternalModuleDeclaration,
|
declaration,
|
||||||
moduleExports?: ModuleExports,
|
moduleExports,
|
||||||
injectedDependencies?: Record<string, any>
|
injectedDependencies,
|
||||||
): Promise<{
|
}: LinkModuleBootstrapOptions): Promise<{
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}> {
|
}> {
|
||||||
const moduleKey = definition.key
|
const moduleKey = definition.key
|
||||||
const hashKey = simpleHash(stringifyCircular({ moduleKey, declaration }))
|
const hashKey = simpleHash(stringifyCircular({ moduleKey, declaration }))
|
||||||
|
|
||||||
if (MedusaModule.instances_.has(hashKey)) {
|
if (MedusaModule.instances_.has(hashKey)) {
|
||||||
return MedusaModule.instances_.get(hashKey)
|
return { [moduleKey]: MedusaModule.instances_.get(hashKey) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MedusaModule.loading_.has(hashKey)) {
|
if (MedusaModule.loading_.has(hashKey)) {
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ export class RemoteQuery {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const servicesConfig_ = [...servicesConfig]
|
||||||
|
|
||||||
for (const mod of modulesLoaded) {
|
for (const mod of modulesLoaded) {
|
||||||
if (!mod.__definition.isQueryable) {
|
if (!mod.__definition.isQueryable) {
|
||||||
continue
|
continue
|
||||||
@@ -48,12 +50,12 @@ export class RemoteQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.modulesMap.set(serviceName, mod)
|
this.modulesMap.set(serviceName, mod)
|
||||||
servicesConfig!.push(mod.__joinerConfig)
|
servicesConfig_!.push(mod.__joinerConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.customRemoteFetchData = customRemoteFetchData
|
this.customRemoteFetchData = customRemoteFetchData
|
||||||
this.remoteJoiner = new RemoteJoiner(
|
this.remoteJoiner = new RemoteJoiner(
|
||||||
servicesConfig as JoinerServiceConfig[],
|
servicesConfig_ as JoinerServiceConfig[],
|
||||||
this.remoteFetchData.bind(this)
|
this.remoteFetchData.bind(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,15 @@ export const initialize = async (
|
|||||||
): Promise<IPricingModuleService> => {
|
): Promise<IPricingModuleService> => {
|
||||||
const serviceKey = Modules.PRICING
|
const serviceKey = Modules.PRICING
|
||||||
|
|
||||||
const loaded = await MedusaModule.bootstrap<IPricingModuleService>(
|
const loaded = await MedusaModule.bootstrap<IPricingModuleService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
MODULE_PACKAGE_NAMES[Modules.PRICING],
|
defaultPath: MODULE_PACKAGE_NAMES[Modules.PRICING],
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
moduleDefinition,
|
| InternalModuleDeclaration
|
||||||
injectedDependencies
|
| ExternalModuleDeclaration,
|
||||||
)
|
injectedDependencies,
|
||||||
|
moduleExports: moduleDefinition,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
ExternalModuleDeclaration,
|
ExternalModuleDeclaration,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
MODULE_PACKAGE_NAMES,
|
|
||||||
MedusaModule,
|
MedusaModule,
|
||||||
|
MODULE_PACKAGE_NAMES,
|
||||||
Modules,
|
Modules,
|
||||||
} from "@medusajs/modules-sdk"
|
} from "@medusajs/modules-sdk"
|
||||||
import { IProductModuleService, ModulesSdkTypes } from "@medusajs/types"
|
import { IProductModuleService, ModulesSdkTypes } from "@medusajs/types"
|
||||||
@@ -20,13 +20,15 @@ export const initialize = async (
|
|||||||
): Promise<IProductModuleService> => {
|
): Promise<IProductModuleService> => {
|
||||||
const serviceKey = Modules.PRODUCT
|
const serviceKey = Modules.PRODUCT
|
||||||
|
|
||||||
const loaded = await MedusaModule.bootstrap<IProductModuleService>(
|
const loaded = await MedusaModule.bootstrap<IProductModuleService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
MODULE_PACKAGE_NAMES[Modules.PRODUCT],
|
defaultPath: MODULE_PACKAGE_NAMES[Modules.PRODUCT],
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
moduleDefinition,
|
| InternalModuleDeclaration
|
||||||
injectedDependencies
|
| ExternalModuleDeclaration,
|
||||||
)
|
injectedDependencies,
|
||||||
|
moduleExports: moduleDefinition,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
ExternalModuleDeclaration,
|
ExternalModuleDeclaration,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
MedusaModule,
|
MedusaModule,
|
||||||
|
MODULE_PACKAGE_NAMES,
|
||||||
Modules,
|
Modules,
|
||||||
} from "@medusajs/modules-sdk"
|
} from "@medusajs/modules-sdk"
|
||||||
import { IEventBusService, IStockLocationService } from "@medusajs/types"
|
import { IEventBusService, IStockLocationService } from "@medusajs/types"
|
||||||
@@ -15,13 +16,15 @@ export const initialize = async (
|
|||||||
}
|
}
|
||||||
): Promise<IStockLocationService> => {
|
): Promise<IStockLocationService> => {
|
||||||
const serviceKey = Modules.STOCK_LOCATION
|
const serviceKey = Modules.STOCK_LOCATION
|
||||||
const loaded = await MedusaModule.bootstrap<IStockLocationService>(
|
const loaded = await MedusaModule.bootstrap<IStockLocationService>({
|
||||||
serviceKey,
|
moduleKey: serviceKey,
|
||||||
"@medusajs/stock-location",
|
defaultPath: MODULE_PACKAGE_NAMES[Modules.STOCK_LOCATION],
|
||||||
options as InternalModuleDeclaration | ExternalModuleDeclaration,
|
declaration: options as
|
||||||
moduleDefinition,
|
| InternalModuleDeclaration
|
||||||
injectedDependencies
|
| ExternalModuleDeclaration,
|
||||||
)
|
injectedDependencies,
|
||||||
|
moduleExports: moduleDefinition,
|
||||||
|
})
|
||||||
|
|
||||||
return loaded[serviceKey]
|
return loaded[serviceKey]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user