chore(framework): medusa app loaders (#8393)
RESOLVE FRMW-2636 **What** cleanup and move medusa app loader for now
This commit is contained in:
@@ -7,15 +7,13 @@ export async function initDb({ env = {} }: { env?: Record<any, any> }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
configManager,
|
|
||||||
pgConnectionLoader,
|
pgConnectionLoader,
|
||||||
logger,
|
logger,
|
||||||
container,
|
container,
|
||||||
featureFlagsLoader,
|
featureFlagsLoader,
|
||||||
|
MedusaAppLoader,
|
||||||
} = await import("@medusajs/framework")
|
} = await import("@medusajs/framework")
|
||||||
|
|
||||||
const configModule = configManager.config
|
|
||||||
|
|
||||||
const pgConnection = pgConnectionLoader()
|
const pgConnection = pgConnectionLoader()
|
||||||
await featureFlagsLoader()
|
await featureFlagsLoader()
|
||||||
|
|
||||||
@@ -24,15 +22,9 @@ export async function initDb({ env = {} }: { env?: Record<any, any> }) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {
|
const medusaAppLoader = new MedusaAppLoader()
|
||||||
runMedusaAppMigrations,
|
await medusaAppLoader.runModulesMigrations()
|
||||||
getLinksExecutionPlanner,
|
const planner = await medusaAppLoader.getLinksExecutionPlanner()
|
||||||
} = require("@medusajs/medusa/dist/loaders/medusa-app")
|
|
||||||
await runMedusaAppMigrations({ configModule, container })
|
|
||||||
const planner = await getLinksExecutionPlanner({
|
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
})
|
|
||||||
|
|
||||||
const actionPlan = await planner.createPlan()
|
const actionPlan = await planner.createPlan()
|
||||||
await planner.executePlan(actionPlan)
|
await planner.executePlan(actionPlan)
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { ContainerLike, MedusaContainer } from "@medusajs/types"
|
import { ContainerLike, MedusaContainer } from "@medusajs/types"
|
||||||
import {
|
import { createMedusaContainer } from "@medusajs/utils"
|
||||||
ContainerRegistrationKeys,
|
|
||||||
createMedusaContainer,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import { createDatabase, dropDatabase } from "pg-god"
|
import { createDatabase, dropDatabase } from "pg-god"
|
||||||
import { getDatabaseURL } from "./database"
|
import { getDatabaseURL } from "./database"
|
||||||
import { startApp } from "./medusa-test-runner-utils/bootstrap-app"
|
import { startApp } from "./medusa-test-runner-utils/bootstrap-app"
|
||||||
@@ -200,14 +197,12 @@ export function medusaIntegrationTestRunner({
|
|||||||
const copiedContainer = createMedusaContainer({}, container)
|
const copiedContainer = createMedusaContainer({}, container)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const medusaAppLoaderRunner =
|
const { MedusaAppLoader } = await import("@medusajs/framework")
|
||||||
require("@medusajs/medusa/dist/loaders/medusa-app").runModulesLoader
|
|
||||||
await medusaAppLoaderRunner({
|
const medusaAppLoader = new MedusaAppLoader({
|
||||||
container: copiedContainer,
|
container: copiedContainer,
|
||||||
configModule: container.resolve(
|
|
||||||
ContainerRegistrationKeys.CONFIG_MODULE
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
|
await medusaAppLoader.runModulesLoader()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error runner modules loaders", error?.message)
|
console.error("Error runner modules loaders", error?.message)
|
||||||
throw error
|
throw error
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ export * from "./links"
|
|||||||
export * from "./jobs"
|
export * from "./jobs"
|
||||||
export * from "./feature-flags"
|
export * from "./feature-flags"
|
||||||
export * from "./workflows"
|
export * from "./workflows"
|
||||||
|
export * from "./medusa-app-loader"
|
||||||
|
|||||||
@@ -0,0 +1,285 @@
|
|||||||
|
import {
|
||||||
|
MedusaApp,
|
||||||
|
MedusaAppGetLinksExecutionPlanner,
|
||||||
|
MedusaAppMigrateDown,
|
||||||
|
MedusaAppMigrateGenerate,
|
||||||
|
MedusaAppMigrateUp,
|
||||||
|
MedusaAppOutput,
|
||||||
|
ModulesDefinition,
|
||||||
|
RegisterModuleJoinerConfig,
|
||||||
|
} from "@medusajs/modules-sdk"
|
||||||
|
import {
|
||||||
|
CommonTypes,
|
||||||
|
ConfigModule,
|
||||||
|
ILinkMigrationsPlanner,
|
||||||
|
InternalModuleDeclaration,
|
||||||
|
LoadedModule,
|
||||||
|
ModuleDefinition,
|
||||||
|
ModuleServiceInitializeOptions,
|
||||||
|
} from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
isBoolean,
|
||||||
|
isObject,
|
||||||
|
isPresent,
|
||||||
|
upperCaseFirst,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import { pgConnectionLoader } from "./database"
|
||||||
|
|
||||||
|
import { asValue } from "awilix"
|
||||||
|
import {
|
||||||
|
container,
|
||||||
|
container as mainContainer,
|
||||||
|
MedusaContainer,
|
||||||
|
} from "./container"
|
||||||
|
import { configManager } from "./config"
|
||||||
|
|
||||||
|
export class MedusaAppLoader {
|
||||||
|
/**
|
||||||
|
* Container from where to resolve resources
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
readonly #container: MedusaContainer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra links modules config which should be added manually to the links to be loaded
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
readonly #customLinksModules:
|
||||||
|
| RegisterModuleJoinerConfig
|
||||||
|
| RegisterModuleJoinerConfig[]
|
||||||
|
|
||||||
|
// TODO: Adjust all loaders to accept an optional container such that in test env it is possible if needed to provide a specific container otherwise use the main container
|
||||||
|
// Maybe also adjust the different places to resolve the config from the container instead of the configManager for the same reason
|
||||||
|
// To be discussed
|
||||||
|
constructor({
|
||||||
|
container,
|
||||||
|
customLinksModules,
|
||||||
|
}: {
|
||||||
|
container?: MedusaContainer
|
||||||
|
customLinksModules?:
|
||||||
|
| RegisterModuleJoinerConfig
|
||||||
|
| RegisterModuleJoinerConfig[]
|
||||||
|
} = {}) {
|
||||||
|
this.#container = container ?? mainContainer
|
||||||
|
this.#customLinksModules = customLinksModules ?? []
|
||||||
|
}
|
||||||
|
|
||||||
|
protected mergeDefaultModules(
|
||||||
|
modulesConfig: CommonTypes.ConfigModule["modules"]
|
||||||
|
) {
|
||||||
|
const defaultModules = Object.values(ModulesDefinition).filter(
|
||||||
|
(definition: ModuleDefinition) => {
|
||||||
|
return !!definition.defaultPackage
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const configModules = { ...modulesConfig } ?? {}
|
||||||
|
|
||||||
|
for (const defaultModule of defaultModules as ModuleDefinition[]) {
|
||||||
|
configModules[defaultModule.key] ??=
|
||||||
|
defaultModule.defaultModuleDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(
|
||||||
|
configModules as Record<string, InternalModuleDeclaration>
|
||||||
|
)) {
|
||||||
|
const def = {} as ModuleDefinition
|
||||||
|
def.key ??= key
|
||||||
|
def.registrationName ??= ModulesDefinition[key]?.registrationName ?? key
|
||||||
|
def.label ??= ModulesDefinition[key]?.label ?? upperCaseFirst(key)
|
||||||
|
def.isQueryable = ModulesDefinition[key]?.isQueryable ?? true
|
||||||
|
|
||||||
|
const orignalDef = value?.definition ?? ModulesDefinition[key]
|
||||||
|
if (
|
||||||
|
!isBoolean(value) &&
|
||||||
|
(isObject(orignalDef) || !isPresent(value.definition))
|
||||||
|
) {
|
||||||
|
value.definition = {
|
||||||
|
...def,
|
||||||
|
...orignalDef,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return configModules
|
||||||
|
}
|
||||||
|
|
||||||
|
protected prepareSharedResourcesAndDeps() {
|
||||||
|
const injectedDependencies = {
|
||||||
|
[ContainerRegistrationKeys.PG_CONNECTION]: this.#container.resolve(
|
||||||
|
ContainerRegistrationKeys.PG_CONNECTION
|
||||||
|
),
|
||||||
|
[ContainerRegistrationKeys.LOGGER]: this.#container.resolve(
|
||||||
|
ContainerRegistrationKeys.LOGGER
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharedResourcesConfig: ModuleServiceInitializeOptions = {
|
||||||
|
database: {
|
||||||
|
clientUrl:
|
||||||
|
(
|
||||||
|
injectedDependencies[
|
||||||
|
ContainerRegistrationKeys.PG_CONNECTION
|
||||||
|
] as ReturnType<typeof pgConnectionLoader>
|
||||||
|
)?.client?.config?.connection?.connectionString ??
|
||||||
|
configManager.config.projectConfig.databaseUrl,
|
||||||
|
driverOptions: configManager.config.projectConfig.databaseDriverOptions,
|
||||||
|
debug: configManager.config.projectConfig.databaseLogging ?? false,
|
||||||
|
schema: configManager.config.projectConfig.databaseSchema,
|
||||||
|
database: configManager.config.projectConfig.databaseName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return { sharedResourcesConfig, injectedDependencies }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run, Revert or Generate the migrations for the medusa app.
|
||||||
|
*
|
||||||
|
* @param moduleNames
|
||||||
|
* @param linkModules
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
|
async runModulesMigrations(
|
||||||
|
{
|
||||||
|
moduleNames,
|
||||||
|
action = "run",
|
||||||
|
}:
|
||||||
|
| {
|
||||||
|
moduleNames?: never
|
||||||
|
action: "run"
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
moduleNames: string[]
|
||||||
|
action: "revert" | "generate"
|
||||||
|
} = {
|
||||||
|
action: "run",
|
||||||
|
}
|
||||||
|
): Promise<void> {
|
||||||
|
const configModules = this.mergeDefaultModules(configManager.config.modules)
|
||||||
|
|
||||||
|
const { sharedResourcesConfig, injectedDependencies } =
|
||||||
|
this.prepareSharedResourcesAndDeps()
|
||||||
|
|
||||||
|
const migrationOptions = {
|
||||||
|
modulesConfig: configModules,
|
||||||
|
sharedContainer: this.#container,
|
||||||
|
linkModules: this.#customLinksModules,
|
||||||
|
sharedResourcesConfig,
|
||||||
|
injectedDependencies,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "revert") {
|
||||||
|
await MedusaAppMigrateDown(moduleNames!, migrationOptions)
|
||||||
|
} else if (action === "run") {
|
||||||
|
await MedusaAppMigrateUp(migrationOptions)
|
||||||
|
} else {
|
||||||
|
await MedusaAppMigrateGenerate(moduleNames!, migrationOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance of the link module migration planner.
|
||||||
|
*/
|
||||||
|
async getLinksExecutionPlanner(): Promise<ILinkMigrationsPlanner> {
|
||||||
|
const configModules = this.mergeDefaultModules(configManager.config.modules)
|
||||||
|
const { sharedResourcesConfig, injectedDependencies } =
|
||||||
|
this.prepareSharedResourcesAndDeps()
|
||||||
|
|
||||||
|
const migrationOptions = {
|
||||||
|
modulesConfig: configModules,
|
||||||
|
sharedContainer: this.#container,
|
||||||
|
linkModules: this.#customLinksModules,
|
||||||
|
sharedResourcesConfig,
|
||||||
|
injectedDependencies,
|
||||||
|
}
|
||||||
|
|
||||||
|
return await MedusaAppGetLinksExecutionPlanner(migrationOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the modules loader without taking care of anything else. This is useful for running the loader as a separate action or to re run all modules loaders.
|
||||||
|
*/
|
||||||
|
async runModulesLoader(): Promise<void> {
|
||||||
|
const { sharedResourcesConfig, injectedDependencies } =
|
||||||
|
this.prepareSharedResourcesAndDeps()
|
||||||
|
const configModules = this.mergeDefaultModules(configManager.config.modules)
|
||||||
|
|
||||||
|
await MedusaApp({
|
||||||
|
modulesConfig: configModules,
|
||||||
|
sharedContainer: this.#container,
|
||||||
|
linkModules: this.#customLinksModules,
|
||||||
|
sharedResourcesConfig,
|
||||||
|
injectedDependencies,
|
||||||
|
loaderOnly: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all modules and bootstrap all the modules and links to be ready to be consumed
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
async load(config = { registerInContainer: true }): Promise<MedusaAppOutput> {
|
||||||
|
const configModule: ConfigModule = this.#container.resolve(
|
||||||
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
|
)
|
||||||
|
|
||||||
|
const { sharedResourcesConfig, injectedDependencies } =
|
||||||
|
this.prepareSharedResourcesAndDeps()
|
||||||
|
|
||||||
|
this.#container.register(
|
||||||
|
ContainerRegistrationKeys.REMOTE_QUERY,
|
||||||
|
asValue(undefined)
|
||||||
|
)
|
||||||
|
this.#container.register(
|
||||||
|
ContainerRegistrationKeys.REMOTE_LINK,
|
||||||
|
asValue(undefined)
|
||||||
|
)
|
||||||
|
|
||||||
|
const configModules = this.mergeDefaultModules(configModule.modules)
|
||||||
|
|
||||||
|
const medusaApp = await MedusaApp({
|
||||||
|
workerMode: configModule.projectConfig.workerMode,
|
||||||
|
modulesConfig: configModules,
|
||||||
|
sharedContainer: this.#container,
|
||||||
|
linkModules: this.#customLinksModules,
|
||||||
|
sharedResourcesConfig,
|
||||||
|
injectedDependencies,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!config.registerInContainer) {
|
||||||
|
return medusaApp
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(
|
||||||
|
ContainerRegistrationKeys.REMOTE_LINK,
|
||||||
|
asValue(medusaApp.link)
|
||||||
|
)
|
||||||
|
container.register(
|
||||||
|
ContainerRegistrationKeys.REMOTE_QUERY,
|
||||||
|
asValue(medusaApp.query)
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const moduleService of Object.values(medusaApp.modules)) {
|
||||||
|
const loadedModule = moduleService as LoadedModule
|
||||||
|
container.register(
|
||||||
|
loadedModule.__definition.registrationName,
|
||||||
|
asValue(moduleService)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register all unresolved modules as undefined to be present in the container with undefined value by default
|
||||||
|
// but still resolvable
|
||||||
|
for (const moduleDefinition of Object.values(ModulesDefinition)) {
|
||||||
|
if (!container.hasRegistration(moduleDefinition.registrationName)) {
|
||||||
|
container.register(
|
||||||
|
moduleDefinition.registrationName,
|
||||||
|
asValue(undefined)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return medusaApp
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,10 @@ import boxen from "boxen"
|
|||||||
import chalk from "chalk"
|
import chalk from "chalk"
|
||||||
import checkbox from "@inquirer/checkbox"
|
import checkbox from "@inquirer/checkbox"
|
||||||
|
|
||||||
import { LinkLoader, logger } from "@medusajs/framework"
|
import { LinkLoader, logger, MedusaAppLoader } from "@medusajs/framework"
|
||||||
import { initializeContainer } from "../loaders"
|
import { initializeContainer } from "../loaders"
|
||||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||||
import { getResolvedPlugins } from "../loaders/helpers/resolve-plugins"
|
import { getResolvedPlugins } from "../loaders/helpers/resolve-plugins"
|
||||||
import { getLinksExecutionPlanner } from "../loaders/medusa-app"
|
|
||||||
import { LinkMigrationsPlannerAction } from "@medusajs/types"
|
import { LinkMigrationsPlannerAction } from "@medusajs/types"
|
||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ function groupByActionPlan(actionPlan: LinkMigrationsPlannerAction[]) {
|
|||||||
* Creates the link description for printing it to the
|
* Creates the link description for printing it to the
|
||||||
* console
|
* console
|
||||||
*
|
*
|
||||||
* @param action: LinkMigrationsPlannerAction
|
* @param action LinkMigrationsPlannerAction
|
||||||
*/
|
*/
|
||||||
function buildLinkDescription(action: LinkMigrationsPlannerAction) {
|
function buildLinkDescription(action: LinkMigrationsPlannerAction) {
|
||||||
const { linkDescriptor } = action
|
const { linkDescriptor } = action
|
||||||
@@ -102,16 +101,15 @@ const main = async function ({ directory }) {
|
|||||||
ContainerRegistrationKeys.CONFIG_MODULE
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const medusaAppLoader = new MedusaAppLoader()
|
||||||
|
|
||||||
const plugins = getResolvedPlugins(directory, configModule, true) || []
|
const plugins = getResolvedPlugins(directory, configModule, true) || []
|
||||||
const linksSourcePaths = plugins.map((plugin) =>
|
const linksSourcePaths = plugins.map((plugin) =>
|
||||||
join(plugin.resolve, "links")
|
join(plugin.resolve, "links")
|
||||||
)
|
)
|
||||||
await new LinkLoader(linksSourcePaths).load()
|
await new LinkLoader(linksSourcePaths).load()
|
||||||
|
|
||||||
const planner = await getLinksExecutionPlanner({
|
const planner = await medusaAppLoader.getLinksExecutionPlanner()
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
})
|
|
||||||
|
|
||||||
logger.info("Syncing links...")
|
logger.info("Syncing links...")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { LinkLoader, logger } from "@medusajs/framework"
|
import { LinkLoader, logger, MedusaAppLoader } from "@medusajs/framework"
|
||||||
import { runMedusaAppMigrations } from "../loaders/medusa-app"
|
|
||||||
import { initializeContainer } from "../loaders"
|
import { initializeContainer } from "../loaders"
|
||||||
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
|
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
|
||||||
import { getResolvedPlugins } from "../loaders/helpers/resolve-plugins"
|
import { getResolvedPlugins } from "../loaders/helpers/resolve-plugins"
|
||||||
@@ -51,6 +50,8 @@ const main = async function ({ directory }) {
|
|||||||
ContainerRegistrationKeys.CONFIG_MODULE
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const medusaAppLoader = new MedusaAppLoader()
|
||||||
|
|
||||||
const plugins = getResolvedPlugins(directory, configModule, true) || []
|
const plugins = getResolvedPlugins(directory, configModule, true) || []
|
||||||
const linksSourcePaths = plugins.map((plugin) =>
|
const linksSourcePaths = plugins.map((plugin) =>
|
||||||
join(plugin.resolve, "links")
|
join(plugin.resolve, "links")
|
||||||
@@ -60,9 +61,7 @@ const main = async function ({ directory }) {
|
|||||||
if (action === "run") {
|
if (action === "run") {
|
||||||
logger.info("Running migrations...")
|
logger.info("Running migrations...")
|
||||||
|
|
||||||
await runMedusaAppMigrations({
|
await medusaAppLoader.runModulesMigrations({
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
action: "run",
|
action: "run",
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -73,10 +72,8 @@ const main = async function ({ directory }) {
|
|||||||
logger.info("Reverting migrations...")
|
logger.info("Reverting migrations...")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await runMedusaAppMigrations({
|
await medusaAppLoader.runModulesMigrations({
|
||||||
moduleNames: modules,
|
moduleNames: modules,
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
action: "revert",
|
action: "revert",
|
||||||
})
|
})
|
||||||
console.log(new Array(TERMINAL_SIZE).join("-"))
|
console.log(new Array(TERMINAL_SIZE).join("-"))
|
||||||
@@ -98,10 +95,8 @@ const main = async function ({ directory }) {
|
|||||||
} else if (action === "generate") {
|
} else if (action === "generate") {
|
||||||
logger.info("Generating migrations...")
|
logger.info("Generating migrations...")
|
||||||
|
|
||||||
await runMedusaAppMigrations({
|
await medusaAppLoader.runModulesMigrations({
|
||||||
moduleNames: modules,
|
moduleNames: modules,
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
action: "generate",
|
action: "generate",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ import {
|
|||||||
JobLoader,
|
JobLoader,
|
||||||
LinkLoader,
|
LinkLoader,
|
||||||
logger,
|
logger,
|
||||||
|
MedusaAppLoader,
|
||||||
pgConnectionLoader,
|
pgConnectionLoader,
|
||||||
SubscriberLoader,
|
SubscriberLoader,
|
||||||
WorkflowLoader,
|
WorkflowLoader,
|
||||||
} from "@medusajs/framework"
|
} from "@medusajs/framework"
|
||||||
import { getResolvedPlugins } from "./helpers/resolve-plugins"
|
import { getResolvedPlugins } from "./helpers/resolve-plugins"
|
||||||
import loadMedusaApp from "./medusa-app"
|
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
directory: string
|
directory: string
|
||||||
@@ -157,9 +157,7 @@ export default async ({
|
|||||||
onApplicationStart,
|
onApplicationStart,
|
||||||
onApplicationShutdown,
|
onApplicationShutdown,
|
||||||
onApplicationPrepareShutdown,
|
onApplicationPrepareShutdown,
|
||||||
} = await loadMedusaApp({
|
} = await new MedusaAppLoader().load()
|
||||||
container,
|
|
||||||
})
|
|
||||||
|
|
||||||
const workflowsSourcePaths = plugins.map((p) => join(p.resolve, "workflows"))
|
const workflowsSourcePaths = plugins.map((p) => join(p.resolve, "workflows"))
|
||||||
const workflowLoader = new WorkflowLoader(workflowsSourcePaths)
|
const workflowLoader = new WorkflowLoader(workflowsSourcePaths)
|
||||||
|
|||||||
@@ -1,314 +0,0 @@
|
|||||||
import {
|
|
||||||
MedusaApp,
|
|
||||||
MedusaAppGetLinksExecutionPlanner,
|
|
||||||
MedusaAppMigrateDown,
|
|
||||||
MedusaAppMigrateGenerate,
|
|
||||||
MedusaAppMigrateUp,
|
|
||||||
MedusaAppOptions,
|
|
||||||
MedusaAppOutput,
|
|
||||||
ModulesDefinition,
|
|
||||||
} from "@medusajs/modules-sdk"
|
|
||||||
import {
|
|
||||||
CommonTypes,
|
|
||||||
ConfigModule,
|
|
||||||
ILinkMigrationsPlanner,
|
|
||||||
InternalModuleDeclaration,
|
|
||||||
LoadedModule,
|
|
||||||
MedusaContainer,
|
|
||||||
ModuleDefinition,
|
|
||||||
} from "@medusajs/types"
|
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
isBoolean,
|
|
||||||
isObject,
|
|
||||||
isPresent,
|
|
||||||
upperCaseFirst,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
|
|
||||||
import { asValue } from "awilix"
|
|
||||||
|
|
||||||
export function mergeDefaultModules(
|
|
||||||
modulesConfig: CommonTypes.ConfigModule["modules"]
|
|
||||||
) {
|
|
||||||
const defaultModules = Object.values(ModulesDefinition).filter(
|
|
||||||
(definition: ModuleDefinition) => {
|
|
||||||
return !!definition.defaultPackage
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const configModules = { ...modulesConfig } ?? {}
|
|
||||||
|
|
||||||
for (const defaultModule of defaultModules as ModuleDefinition[]) {
|
|
||||||
configModules[defaultModule.key] ??= defaultModule.defaultModuleDeclaration
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(
|
|
||||||
configModules as Record<string, InternalModuleDeclaration>
|
|
||||||
)) {
|
|
||||||
const def = {} as ModuleDefinition
|
|
||||||
def.key ??= key
|
|
||||||
def.registrationName ??= ModulesDefinition[key]?.registrationName ?? key
|
|
||||||
def.label ??= ModulesDefinition[key]?.label ?? upperCaseFirst(key)
|
|
||||||
def.isQueryable = ModulesDefinition[key]?.isQueryable ?? true
|
|
||||||
|
|
||||||
const orignalDef = value?.definition ?? ModulesDefinition[key]
|
|
||||||
if (
|
|
||||||
!isBoolean(value) &&
|
|
||||||
(isObject(orignalDef) || !isPresent(value.definition))
|
|
||||||
) {
|
|
||||||
value.definition = {
|
|
||||||
...def,
|
|
||||||
...orignalDef,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return configModules
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run, Revert or Generate the migrations for the medusa app.
|
|
||||||
*
|
|
||||||
* @param configModule
|
|
||||||
* @param container
|
|
||||||
* @param moduleNames
|
|
||||||
* @param linkModules
|
|
||||||
* @param action
|
|
||||||
*/
|
|
||||||
export async function runMedusaAppMigrations({
|
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
moduleNames,
|
|
||||||
linkModules,
|
|
||||||
action = "run",
|
|
||||||
}: {
|
|
||||||
configModule: {
|
|
||||||
modules?: CommonTypes.ConfigModule["modules"]
|
|
||||||
projectConfig: CommonTypes.ConfigModule["projectConfig"]
|
|
||||||
}
|
|
||||||
linkModules?: MedusaAppOptions["linkModules"]
|
|
||||||
container: MedusaContainer
|
|
||||||
} & (
|
|
||||||
| {
|
|
||||||
moduleNames?: never
|
|
||||||
action: "run"
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
moduleNames: string[]
|
|
||||||
action: "revert" | "generate"
|
|
||||||
}
|
|
||||||
)): Promise<void> {
|
|
||||||
const injectedDependencies = {
|
|
||||||
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.PG_CONNECTION
|
|
||||||
),
|
|
||||||
[ContainerRegistrationKeys.LOGGER]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.LOGGER
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
const sharedResourcesConfig = {
|
|
||||||
database: {
|
|
||||||
clientUrl:
|
|
||||||
injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION]?.client
|
|
||||||
?.config?.connection?.connectionString ??
|
|
||||||
configModule.projectConfig.databaseUrl,
|
|
||||||
driverOptions: configModule.projectConfig.databaseDriverOptions,
|
|
||||||
debug: !!(configModule.projectConfig.databaseLogging ?? false),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const configModules = mergeDefaultModules(configModule.modules)
|
|
||||||
|
|
||||||
const migrationOptions = {
|
|
||||||
modulesConfig: configModules,
|
|
||||||
sharedContainer: container,
|
|
||||||
linkModules,
|
|
||||||
sharedResourcesConfig,
|
|
||||||
injectedDependencies,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action === "revert") {
|
|
||||||
await MedusaAppMigrateDown(moduleNames!, migrationOptions)
|
|
||||||
} else if (action === "run") {
|
|
||||||
await MedusaAppMigrateUp(migrationOptions)
|
|
||||||
} else {
|
|
||||||
await MedusaAppMigrateGenerate(moduleNames!, migrationOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an instance of the link module migration planner.
|
|
||||||
*
|
|
||||||
* @param configModule
|
|
||||||
* @param container
|
|
||||||
* @param linkModules
|
|
||||||
*/
|
|
||||||
export async function getLinksExecutionPlanner({
|
|
||||||
configModule,
|
|
||||||
container,
|
|
||||||
linkModules,
|
|
||||||
}: {
|
|
||||||
configModule: {
|
|
||||||
modules?: CommonTypes.ConfigModule["modules"]
|
|
||||||
projectConfig: CommonTypes.ConfigModule["projectConfig"]
|
|
||||||
}
|
|
||||||
linkModules?: MedusaAppOptions["linkModules"]
|
|
||||||
container: MedusaContainer
|
|
||||||
}): Promise<ILinkMigrationsPlanner> {
|
|
||||||
const injectedDependencies = {
|
|
||||||
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.PG_CONNECTION
|
|
||||||
),
|
|
||||||
[ContainerRegistrationKeys.LOGGER]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.LOGGER
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
const sharedResourcesConfig = {
|
|
||||||
database: {
|
|
||||||
clientUrl:
|
|
||||||
injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION]?.client
|
|
||||||
?.config?.connection?.connectionString ??
|
|
||||||
configModule.projectConfig.databaseUrl,
|
|
||||||
driverOptions: configModule.projectConfig.databaseDriverOptions,
|
|
||||||
debug: !!(configModule.projectConfig.databaseLogging ?? false),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const configModules = mergeDefaultModules(configModule.modules)
|
|
||||||
|
|
||||||
const migrationOptions = {
|
|
||||||
modulesConfig: configModules,
|
|
||||||
sharedContainer: container,
|
|
||||||
linkModules,
|
|
||||||
sharedResourcesConfig,
|
|
||||||
injectedDependencies,
|
|
||||||
}
|
|
||||||
|
|
||||||
return await MedusaAppGetLinksExecutionPlanner(migrationOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadMedusaApp = async (
|
|
||||||
{
|
|
||||||
container,
|
|
||||||
linkModules,
|
|
||||||
}: {
|
|
||||||
container: MedusaContainer
|
|
||||||
linkModules?: MedusaAppOptions["linkModules"]
|
|
||||||
},
|
|
||||||
config = { registerInContainer: true }
|
|
||||||
): Promise<MedusaAppOutput> => {
|
|
||||||
const injectedDependencies = {
|
|
||||||
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.PG_CONNECTION
|
|
||||||
),
|
|
||||||
[ContainerRegistrationKeys.LOGGER]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.LOGGER
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
const configModule: ConfigModule = container.resolve(
|
|
||||||
ContainerRegistrationKeys.CONFIG_MODULE
|
|
||||||
)
|
|
||||||
|
|
||||||
const sharedResourcesConfig = {
|
|
||||||
database: {
|
|
||||||
clientUrl: configModule.projectConfig.databaseUrl,
|
|
||||||
driverOptions: configModule.projectConfig.databaseDriverOptions,
|
|
||||||
debug: !!(configModule.projectConfig.databaseLogging ?? false),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register(ContainerRegistrationKeys.REMOTE_QUERY, asValue(undefined))
|
|
||||||
container.register(ContainerRegistrationKeys.REMOTE_LINK, asValue(undefined))
|
|
||||||
|
|
||||||
const configModules = mergeDefaultModules(configModule.modules)
|
|
||||||
|
|
||||||
const medusaApp = await MedusaApp({
|
|
||||||
workerMode: configModule.projectConfig.workerMode,
|
|
||||||
modulesConfig: configModules,
|
|
||||||
sharedContainer: container,
|
|
||||||
linkModules,
|
|
||||||
sharedResourcesConfig,
|
|
||||||
injectedDependencies,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!config.registerInContainer) {
|
|
||||||
return medusaApp
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register(
|
|
||||||
ContainerRegistrationKeys.REMOTE_LINK,
|
|
||||||
asValue(medusaApp.link)
|
|
||||||
)
|
|
||||||
container.register(
|
|
||||||
ContainerRegistrationKeys.REMOTE_QUERY,
|
|
||||||
asValue(medusaApp.query)
|
|
||||||
)
|
|
||||||
|
|
||||||
for (const moduleService of Object.values(medusaApp.modules)) {
|
|
||||||
const loadedModule = moduleService as LoadedModule
|
|
||||||
container.register(
|
|
||||||
loadedModule.__definition.registrationName,
|
|
||||||
asValue(moduleService)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register all unresolved modules as undefined to be present in the container with undefined value by default
|
|
||||||
// but still resolvable
|
|
||||||
for (const moduleDefinition of Object.values(ModulesDefinition)) {
|
|
||||||
if (!container.hasRegistration(moduleDefinition.registrationName)) {
|
|
||||||
container.register(moduleDefinition.registrationName, asValue(undefined))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return medusaApp
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the modules loader without taking care of anything else. This is useful for running the loader as a separate action or to re run all modules loaders.
|
|
||||||
*
|
|
||||||
* @param configModule
|
|
||||||
* @param container
|
|
||||||
*/
|
|
||||||
export async function runModulesLoader({
|
|
||||||
configModule,
|
|
||||||
linkModules,
|
|
||||||
container,
|
|
||||||
}: {
|
|
||||||
configModule: {
|
|
||||||
modules?: CommonTypes.ConfigModule["modules"]
|
|
||||||
projectConfig: CommonTypes.ConfigModule["projectConfig"]
|
|
||||||
}
|
|
||||||
container: MedusaContainer
|
|
||||||
linkModules?: MedusaAppOptions["linkModules"]
|
|
||||||
}): Promise<void> {
|
|
||||||
const injectedDependencies = {
|
|
||||||
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.PG_CONNECTION
|
|
||||||
),
|
|
||||||
[ContainerRegistrationKeys.LOGGER]: container.resolve(
|
|
||||||
ContainerRegistrationKeys.LOGGER
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
const sharedResourcesConfig = {
|
|
||||||
database: {
|
|
||||||
clientUrl: configModule.projectConfig.databaseUrl,
|
|
||||||
driverOptions: configModule.projectConfig.databaseDriverOptions,
|
|
||||||
debug: !!(configModule.projectConfig.databaseLogging ?? false),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const configModules = mergeDefaultModules(configModule.modules)
|
|
||||||
|
|
||||||
await MedusaApp({
|
|
||||||
modulesConfig: configModules,
|
|
||||||
sharedContainer: container,
|
|
||||||
linkModules,
|
|
||||||
sharedResourcesConfig,
|
|
||||||
injectedDependencies,
|
|
||||||
loaderOnly: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default loadMedusaApp
|
|
||||||
Reference in New Issue
Block a user