feature: bundle all modules (#9324)
This commit is contained in:
@@ -7,31 +7,31 @@ import {
|
||||
import { MODULE_RESOURCE_TYPE, MODULE_SCOPE } from "./types"
|
||||
|
||||
export const MODULE_PACKAGE_NAMES = {
|
||||
[Modules.AUTH]: "@medusajs/auth",
|
||||
[Modules.CACHE]: "@medusajs/cache-inmemory",
|
||||
[Modules.CART]: "@medusajs/cart",
|
||||
[Modules.CUSTOMER]: "@medusajs/customer",
|
||||
[Modules.EVENT_BUS]: "@medusajs/event-bus-local",
|
||||
[Modules.INVENTORY]: "@medusajs/inventory-next", // TODO: To be replaced when current `@medusajs/inventory` is deprecated
|
||||
[Modules.LINK]: "@medusajs/link-modules",
|
||||
[Modules.PAYMENT]: "@medusajs/payment",
|
||||
[Modules.PRICING]: "@medusajs/pricing",
|
||||
[Modules.PRODUCT]: "@medusajs/product",
|
||||
[Modules.PROMOTION]: "@medusajs/promotion",
|
||||
[Modules.SALES_CHANNEL]: "@medusajs/sales-channel",
|
||||
[Modules.FULFILLMENT]: "@medusajs/fulfillment",
|
||||
[Modules.STOCK_LOCATION]: "@medusajs/stock-location-next", // TODO: To be replaced when current `@medusajs/stock-location` is deprecated
|
||||
[Modules.TAX]: "@medusajs/tax",
|
||||
[Modules.USER]: "@medusajs/user",
|
||||
[Modules.WORKFLOW_ENGINE]: "@medusajs/workflow-engine-inmemory",
|
||||
[Modules.REGION]: "@medusajs/region",
|
||||
[Modules.ORDER]: "@medusajs/order",
|
||||
[Modules.API_KEY]: "@medusajs/api-key",
|
||||
[Modules.STORE]: "@medusajs/store",
|
||||
[Modules.CURRENCY]: "@medusajs/currency",
|
||||
[Modules.FILE]: "@medusajs/file",
|
||||
[Modules.NOTIFICATION]: "@medusajs/notification",
|
||||
[Modules.INDEX]: "@medusajs/index",
|
||||
[Modules.AUTH]: "@medusajs/medusa/auth",
|
||||
[Modules.CACHE]: "@medusajs/medusa/cache-inmemory",
|
||||
[Modules.CART]: "@medusajs/medusa/cart",
|
||||
[Modules.CUSTOMER]: "@medusajs/medusa/customer",
|
||||
[Modules.EVENT_BUS]: "@medusajs/medusa/event-bus-local",
|
||||
[Modules.INVENTORY]: "@medusajs/medusa/inventory-next", // TODO: To be replaced when current `@medusajs/inventory` is deprecated
|
||||
[Modules.LINK]: "@medusajs/medusa/link-modules",
|
||||
[Modules.PAYMENT]: "@medusajs/medusa/payment",
|
||||
[Modules.PRICING]: "@medusajs/medusa/pricing",
|
||||
[Modules.PRODUCT]: "@medusajs/medusa/product",
|
||||
[Modules.PROMOTION]: "@medusajs/medusa/promotion",
|
||||
[Modules.SALES_CHANNEL]: "@medusajs/medusa/sales-channel",
|
||||
[Modules.FULFILLMENT]: "@medusajs/medusa/fulfillment",
|
||||
[Modules.STOCK_LOCATION]: "@medusajs/medusa/stock-location-next", // TODO: To be replaced when current `@medusajs/stock-location` is deprecated
|
||||
[Modules.TAX]: "@medusajs/medusa/tax",
|
||||
[Modules.USER]: "@medusajs/medusa/user",
|
||||
[Modules.WORKFLOW_ENGINE]: "@medusajs/medusa/workflow-engine-inmemory",
|
||||
[Modules.REGION]: "@medusajs/medusa/region",
|
||||
[Modules.ORDER]: "@medusajs/medusa/order",
|
||||
[Modules.API_KEY]: "@medusajs/medusa/api-key",
|
||||
[Modules.STORE]: "@medusajs/medusa/store",
|
||||
[Modules.CURRENCY]: "@medusajs/medusa/currency",
|
||||
[Modules.FILE]: "@medusajs/medusa/file",
|
||||
[Modules.NOTIFICATION]: "@medusajs/medusa/notification",
|
||||
[Modules.INDEX]: "@medusajs/medusa/index-module",
|
||||
}
|
||||
|
||||
export const ModulesDefinition: {
|
||||
|
||||
@@ -35,7 +35,10 @@ describe("load internal - load resources", () => {
|
||||
(ModuleService.prototype as IModuleService).__joinerConfig
|
||||
).toBeUndefined()
|
||||
|
||||
const resources = await loadResources(moduleResolution)
|
||||
const resources = await loadResources({
|
||||
moduleResolution,
|
||||
discoveryPath: moduleResolution.resolutionPath as string,
|
||||
})
|
||||
|
||||
expect(resources).toBeDefined()
|
||||
expect(resources.services).toHaveLength(1)
|
||||
@@ -115,7 +118,10 @@ describe("load internal - load resources", () => {
|
||||
(ModuleService.prototype as IModuleService).__joinerConfig
|
||||
).toBeUndefined()
|
||||
|
||||
const resources = await loadResources(moduleResolution)
|
||||
const resources = await loadResources({
|
||||
moduleResolution,
|
||||
discoveryPath: moduleResolution.resolutionPath as string,
|
||||
})
|
||||
|
||||
expect(resources).toBeDefined()
|
||||
expect(resources.services).toHaveLength(1)
|
||||
@@ -195,7 +201,10 @@ describe("load internal - load resources", () => {
|
||||
(ModuleService.prototype as IModuleService).__joinerConfig
|
||||
).toBeUndefined()
|
||||
|
||||
const resources = await loadResources(moduleResolution)
|
||||
const resources = await loadResources({
|
||||
moduleResolution,
|
||||
discoveryPath: moduleResolution.resolutionPath as string,
|
||||
})
|
||||
|
||||
expect(resources).toBeDefined()
|
||||
expect(resources.services).toHaveLength(1)
|
||||
@@ -274,7 +283,10 @@ describe("load internal - load resources", () => {
|
||||
(ModuleService.prototype as IModuleService).__joinerConfig
|
||||
).toBeDefined()
|
||||
|
||||
const resources = await loadResources(moduleResolution)
|
||||
const resources = await loadResources({
|
||||
moduleResolution,
|
||||
discoveryPath: moduleResolution.resolutionPath as string,
|
||||
})
|
||||
|
||||
expect(resources).toBeDefined()
|
||||
expect(resources.services).toHaveLength(1)
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
import { asFunction, asValue } from "awilix"
|
||||
import { statSync } from "fs"
|
||||
import { readdir } from "fs/promises"
|
||||
import { join, resolve } from "path"
|
||||
import { dirname, join, resolve } from "path"
|
||||
import { MODULE_RESOURCE_TYPE } from "../../types"
|
||||
|
||||
type ModuleResource = {
|
||||
@@ -39,35 +39,40 @@ type MigrationFunction = (
|
||||
moduleDeclaration?: InternalModuleDeclaration
|
||||
) => Promise<void>
|
||||
|
||||
export async function loadInternalModule(
|
||||
container: MedusaContainer,
|
||||
resolution: ModuleResolution,
|
||||
logger: Logger,
|
||||
migrationOnly?: boolean,
|
||||
loaderOnly?: boolean
|
||||
): Promise<{ error?: Error } | void> {
|
||||
const keyName = !loaderOnly
|
||||
? resolution.definition.key
|
||||
: resolution.definition.key + "__loaderOnly"
|
||||
|
||||
const { resources } =
|
||||
resolution.moduleDeclaration as InternalModuleDeclaration
|
||||
|
||||
let loadedModule: ModuleExports
|
||||
export async function resolveModuleExports({
|
||||
resolution,
|
||||
}: {
|
||||
resolution: ModuleResolution
|
||||
}): Promise<
|
||||
| (ModuleExports & {
|
||||
discoveryPath: string
|
||||
})
|
||||
| { error: any }
|
||||
> {
|
||||
let resolvedModuleExports: ModuleExports
|
||||
try {
|
||||
// When loading manually, we pass the exports to be loaded, meaning that we do not need to import the package to find
|
||||
// the exports. This is useful when a package export an initialize function which will bootstrap itself and therefore
|
||||
// does not need to import the package that is currently being loaded as it would create a
|
||||
// circular reference.
|
||||
const modulePath = resolution.resolutionPath as string
|
||||
|
||||
if (resolution.moduleExports) {
|
||||
// TODO:
|
||||
// If we want to benefit from the auto load mechanism, even if the module exports is provided, we need to ask for the module path
|
||||
loadedModule = resolution.moduleExports
|
||||
resolvedModuleExports = resolution.moduleExports
|
||||
resolvedModuleExports.discoveryPath = resolution.resolutionPath as string
|
||||
} else {
|
||||
loadedModule = await dynamicImport(modulePath)
|
||||
loadedModule = (loadedModule as any).default
|
||||
const module = await dynamicImport(resolution.resolutionPath as string)
|
||||
|
||||
if ("discoveryPath" in module) {
|
||||
const reExportedLoadedModule = await dynamicImport(module.discoveryPath)
|
||||
const discoveryPath = module.discoveryPath
|
||||
resolvedModuleExports = reExportedLoadedModule.default
|
||||
resolvedModuleExports.discoveryPath = discoveryPath as string
|
||||
} else {
|
||||
resolvedModuleExports = (module as { default: ModuleExports }).default
|
||||
resolvedModuleExports.discoveryPath =
|
||||
resolution.resolutionPath as string
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedModuleExports as ModuleExports & {
|
||||
discoveryPath: string
|
||||
}
|
||||
} catch (error) {
|
||||
if (
|
||||
@@ -83,15 +88,37 @@ export async function loadInternalModule(
|
||||
|
||||
return { error }
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadInternalModule(
|
||||
container: MedusaContainer,
|
||||
resolution: ModuleResolution,
|
||||
logger: Logger,
|
||||
migrationOnly?: boolean,
|
||||
loaderOnly?: boolean
|
||||
): Promise<{ error?: Error } | void> {
|
||||
const keyName = !loaderOnly
|
||||
? resolution.definition.key
|
||||
: resolution.definition.key + "__loaderOnly"
|
||||
|
||||
const { resources } =
|
||||
resolution.moduleDeclaration as InternalModuleDeclaration
|
||||
|
||||
const loadedModule = await resolveModuleExports({ resolution })
|
||||
|
||||
if ("error" in loadedModule) {
|
||||
return loadedModule
|
||||
}
|
||||
|
||||
let moduleResources = {} as ModuleResource
|
||||
|
||||
if (resolution.resolutionPath) {
|
||||
moduleResources = await loadResources(
|
||||
resolution,
|
||||
if (loadedModule.discoveryPath) {
|
||||
moduleResources = await loadResources({
|
||||
moduleResolution: resolution,
|
||||
discoveryPath: loadedModule.discoveryPath,
|
||||
logger,
|
||||
loadedModule?.loaders ?? []
|
||||
)
|
||||
loadedModuleLoaders: loadedModule?.loaders,
|
||||
})
|
||||
}
|
||||
|
||||
if (!loadedModule?.service && !moduleResources.moduleService) {
|
||||
@@ -193,22 +220,25 @@ export async function loadModuleMigrations(
|
||||
revertMigration?: MigrationFunction
|
||||
generateMigration?: MigrationFunction
|
||||
}> {
|
||||
let loadedModule: ModuleExports
|
||||
try {
|
||||
loadedModule =
|
||||
moduleExports ??
|
||||
(await dynamicImport(resolution.resolutionPath as string))
|
||||
const loadedModule = await resolveModuleExports({
|
||||
resolution: { ...resolution, moduleExports },
|
||||
})
|
||||
|
||||
if ("error" in loadedModule) {
|
||||
throw loadedModule.error
|
||||
}
|
||||
|
||||
try {
|
||||
let runMigrations = loadedModule.runMigrations
|
||||
let revertMigration = loadedModule.revertMigration
|
||||
let generateMigration = loadedModule.generateMigration
|
||||
|
||||
if (!runMigrations || !revertMigration) {
|
||||
const moduleResources = await loadResources(
|
||||
resolution,
|
||||
console as unknown as Logger,
|
||||
loadedModule?.loaders ?? []
|
||||
)
|
||||
const moduleResources = await loadResources({
|
||||
moduleResolution: resolution,
|
||||
discoveryPath: loadedModule.discoveryPath,
|
||||
loadedModuleLoaders: loadedModule?.loaders,
|
||||
})
|
||||
|
||||
const migrationScriptOptions = {
|
||||
moduleName: resolution.definition.key,
|
||||
@@ -269,15 +299,22 @@ async function importAllFromDir(path: string) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function loadResources(
|
||||
moduleResolution: ModuleResolution,
|
||||
logger: Logger = console as unknown as Logger,
|
||||
export async function loadResources({
|
||||
moduleResolution,
|
||||
discoveryPath,
|
||||
logger,
|
||||
loadedModuleLoaders,
|
||||
}: {
|
||||
moduleResolution: ModuleResolution
|
||||
discoveryPath: string
|
||||
logger?: Logger
|
||||
loadedModuleLoaders?: ModuleLoaderFunction[]
|
||||
): Promise<ModuleResource> {
|
||||
let modulePath = moduleResolution.resolutionPath as string
|
||||
let normalizedPath = modulePath
|
||||
.replace("index.js", "")
|
||||
.replace("index.ts", "")
|
||||
}): Promise<ModuleResource> {
|
||||
logger ??= console as unknown as Logger
|
||||
loadedModuleLoaders ??= []
|
||||
|
||||
const modulePath = discoveryPath
|
||||
let normalizedPath = dirname(require.resolve(modulePath))
|
||||
normalizedPath = resolve(normalizedPath)
|
||||
|
||||
try {
|
||||
|
||||
@@ -206,8 +206,16 @@ async function initializeLinks({
|
||||
moduleExports,
|
||||
}) {
|
||||
try {
|
||||
const { initialize, getMigrationPlanner } =
|
||||
moduleExports ?? (await dynamicImport(LinkModulePackage))
|
||||
let resources = moduleExports
|
||||
if (!resources) {
|
||||
const module = await dynamicImport(LinkModulePackage)
|
||||
if ("discoveryPath" in module) {
|
||||
const reExportedLoadedModule = await dynamicImport(module.discoveryPath)
|
||||
resources = reExportedLoadedModule.default ?? reExportedLoadedModule
|
||||
}
|
||||
}
|
||||
|
||||
const { initialize, getMigrationPlanner } = resources
|
||||
|
||||
const linkResolution = await initialize(
|
||||
config,
|
||||
|
||||
Reference in New Issue
Block a user