chore(framework): medusa app loaders (#8393)

RESOLVE FRMW-2636

**What**
cleanup and move medusa app loader for now
This commit is contained in:
Adrien de Peretti
2024-08-02 10:38:36 +00:00
committed by GitHub
parent c4ff8c27f0
commit 9950a7efe2
8 changed files with 308 additions and 358 deletions
@@ -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
}
}
+5 -7
View File
@@ -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...")
+6 -11
View File
@@ -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",
}) })
+2 -4
View File
@@ -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)
-314
View File
@@ -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