Files
medusa-store/packages/medusa/src/loaders/index.ts
T
Adrien de Peretti 9b6de8c02d chore(framework): Move feature flags related resources and cleanup (#8297)
**What**
cleanup and move the feature flag related resources to manage them.

It also include some refactoring around loading and registering the flag as well as not relying on the `glob` package anymore plus some reorganization of the code itself

FIXES FRMW-2625
2024-07-30 12:20:03 +00:00

199 lines
5.1 KiB
TypeScript

import { createDefaultsWorkflow } from "@medusajs/core-flows"
import { ConfigModule, MedusaContainer, PluginDetails } from "@medusajs/types"
import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils"
import { asValue } from "awilix"
import { Express, NextFunction, Request, Response } from "express"
import path, { join } from "path"
import requestIp from "request-ip"
import { v4 } from "uuid"
import adminLoader from "./admin"
import apiLoader from "./api"
import {
configLoader,
container,
expressLoader,
featureFlagsLoader,
logger,
pgConnectionLoader,
} from "@medusajs/framework"
import { registerJobs } from "./helpers/register-jobs"
import { registerWorkflows } from "./helpers/register-workflows"
import { getResolvedPlugins } from "./helpers/resolve-plugins"
import { resolvePluginsLinks } from "./helpers/resolve-plugins-links"
import { SubscriberLoader } from "./helpers/subscribers"
import loadMedusaApp from "./medusa-app"
type Options = {
directory: string
expressApp: Express
}
const isWorkerMode = (configModule) => {
return configModule.projectConfig.workerMode === "worker"
}
const shouldLoadBackgroundProcessors = (configModule) => {
return (
configModule.projectConfig.workerMode === "worker" ||
configModule.projectConfig.workerMode === "shared"
)
}
async function subscribersLoader(
plugins: PluginDetails[],
container: MedusaContainer
) {
/**
* Load subscribers from the medusa/medusa package
*/
await new SubscriberLoader(
path.join(__dirname, "../subscribers"),
container
).load()
/**
* Load subscribers from all the plugins.
*/
await Promise.all(
plugins.map(async (pluginDetails) => {
await new SubscriberLoader(
path.join(pluginDetails.resolve, "subscribers"),
container
).load()
})
)
}
async function jobsLoader(plugins: PluginDetails[]) {
/**
* Load jobs from the medusa/medusa package. Remove once the medusa core is converted to a plugin
*/
await registerJobs([{ resolve: path.join(__dirname, "../") }])
await registerJobs(plugins)
}
async function loadEntrypoints(
plugins: PluginDetails[],
container: MedusaContainer,
expressApp: Express,
rootDirectory: string
) {
const configModule: ConfigModule = container.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
)
if (shouldLoadBackgroundProcessors(configModule)) {
await subscribersLoader(plugins, container)
await jobsLoader(plugins)
}
if (isWorkerMode(configModule)) {
return async () => {}
}
const { shutdown } = await expressLoader({
app: expressApp,
})
expressApp.use((req: Request, res: Response, next: NextFunction) => {
req.scope = container.createScope() as MedusaContainer
req.requestId = (req.headers["x-request-id"] as string) ?? v4()
next()
})
// Add additional information to context of request
expressApp.use((req: Request, res: Response, next: NextFunction) => {
const ipAddress = requestIp.getClientIp(req) as string
;(req as any).request_context = {
ip_address: ipAddress,
}
next()
})
await adminLoader({ app: expressApp, configModule, rootDirectory })
await apiLoader({
container,
plugins,
app: expressApp,
})
return shutdown
}
export async function initializeContainer(
rootDirectory: string
): Promise<MedusaContainer> {
const configModule = configLoader(rootDirectory, "medusa-config.js")
const featureFlagRouter = await featureFlagsLoader(
join(__dirname, "feature-flags")
)
container.register({
[ContainerRegistrationKeys.LOGGER]: asValue(logger),
[ContainerRegistrationKeys.FEATURE_FLAG_ROUTER]: asValue(featureFlagRouter),
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
[ContainerRegistrationKeys.REMOTE_QUERY]: asValue(null),
})
pgConnectionLoader()
return container
}
export default async ({
directory: rootDirectory,
expressApp,
}: Options): Promise<{
container: MedusaContainer
app: Express
shutdown: () => Promise<void>
}> => {
const container = await initializeContainer(rootDirectory)
const configModule = container.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
)
const plugins = getResolvedPlugins(rootDirectory, configModule, true) || []
const pluginLinks = await resolvePluginsLinks(plugins, container)
const {
onApplicationStart,
onApplicationShutdown,
onApplicationPrepareShutdown,
} = await loadMedusaApp({
container,
linkModules: pluginLinks,
})
await registerWorkflows(plugins)
const entrypointsShutdown = await loadEntrypoints(
plugins,
container,
expressApp,
rootDirectory
)
await createDefaultsWorkflow(container).run()
await onApplicationStart()
const shutdown = async () => {
const pgConnection = container.resolve(
ContainerRegistrationKeys.PG_CONNECTION
)
await onApplicationPrepareShutdown()
await onApplicationShutdown()
await promiseAll([
container.dispose(),
// @ts-expect-error "Do we want to call `client.destroy` "
pgConnection?.context?.destroy(),
entrypointsShutdown(),
])
}
return {
container,
app: expressApp,
shutdown,
}
}