chore(framework): Continue to move loaders to framework (#8258)

**What**
More move and cleanup

FIXES FRMW-2603
FIXES FRMW-2608
FIXES FRMW-2610
FIXES FRMW-2611

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Adrien de PerettiandOli Juhl authored and GitHub committed 2024-07-30 08:52:12 +00:00
1 parent a2a377c8ca
commit bcd9d9c2b1
30 files changed
+204 -359

No files matched your search

+1 -1
View File
@@ -45,7 +45,7 @@
"@inquirer/checkbox": "^2.3.11",
"@medusajs/admin-sdk": "0.0.1",
"@medusajs/core-flows": "^0.0.9",
"@medusajs/framework": "^0.0.1-preview-20240724081425",
"@medusajs/framework": "^0.0.1",
"@medusajs/link-modules": "^0.2.11",
"@medusajs/medusa-cli": "^1.3.22",
"@medusajs/modules-sdk": "^1.12.11",
+8 -7
View File
@@ -5,7 +5,7 @@ import Store from "medusa-telemetry/dist/store"
import { EOL } from "os"
import path from "path"
import Logger from "../loaders/logger"
import { logger } from "@medusajs/framework"
const defaultConfig = {
padding: 5,
@@ -57,8 +57,9 @@ export default async function ({ port, directory }) {
execArgv: argv,
})
this.childProcess.on("error", (error) => {
Logger.error("Dev server failed to start", error)
Logger.info("The server will restart automatically after your changes")
// @ts-ignore
logger.error("Dev server failed to start", error)
logger.info("The server will restart automatically after your changes")
})
},
@@ -100,26 +101,26 @@ export default async function ({ port, directory }) {
})
this.watcher.on("add", (file) => {
Logger.info(
logger.info(
`${path.relative(directory, file)} created: Restarting dev server`
)
this.restart()
})
this.watcher.on("change", (file) => {
Logger.info(
logger.info(
`${path.relative(directory, file)} modified: Restarting dev server`
)
this.restart()
})
this.watcher.on("unlink", (file) => {
Logger.info(
logger.info(
`${path.relative(directory, file)} removed: Restarting dev server`
)
this.restart()
})
this.watcher.on("ready", function () {
Logger.info(`Watching filesystem to reload dev server on file change`)
logger.info(`Watching filesystem to reload dev server on file change`)
})
},
}
+1 -1
View File
@@ -2,7 +2,7 @@ import loaders from "../loaders"
import express from "express"
import path from "path"
import { existsSync } from "fs"
import logger from "../loaders/logger"
import { logger } from "@medusajs/framework"
import { ExecArgs } from "@medusajs/types"
type Options = {
+6 -6
View File
@@ -2,7 +2,7 @@ import boxen from "boxen"
import chalk from "chalk"
import checkbox from "@inquirer/checkbox"
import Logger from "../loaders/logger"
import { logger } from "@medusajs/framework"
import { initializeContainer } from "../loaders"
import { ContainerRegistrationKeys } from "@medusajs/utils"
import { getResolvedPlugins } from "../loaders/helpers/resolve-plugins"
@@ -96,7 +96,7 @@ const main = async function ({ directory }) {
}
try {
const container = await initializeContainer(directory)
const container = initializeContainer(directory)
const configModule = container.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
@@ -111,7 +111,7 @@ const main = async function ({ directory }) {
container,
})
Logger.info("Syncing links...")
logger.info("Syncing links...")
const actionPlan = await planner.createPlan()
const groupActionPlan = groupByActionPlan(actionPlan)
@@ -162,13 +162,13 @@ const main = async function ({ directory }) {
}
if (actionsToExecute.length) {
Logger.info("Links sync completed")
logger.info("Links sync completed")
} else {
Logger.info("Database already up-to-date")
logger.info("Database already up-to-date")
}
process.exit()
} catch (e) {
Logger.error(e)
logger.error(e)
process.exit(1)
}
}
+15 -15
View File
@@ -1,4 +1,4 @@
import Logger from "../loaders/logger"
import { logger } from "@medusajs/framework"
import { runMedusaAppMigrations } from "../loaders/medusa-app"
import { initializeContainer } from "../loaders"
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
@@ -19,17 +19,17 @@ function validateInputArgs({
const actionsRequiringModules = ["revert", "generate"]
if (modules.length && !actionsRequiringModules.includes(action)) {
Logger.error(
logger.error(
`<modules> cannot be specified with the "${action}" action. Please remove the <modules> argument and try again.`
)
process.exit(1)
}
if (!modules.length && actionsRequiringModules.includes(action)) {
Logger.error(
logger.error(
"Please provide the modules for which you want to revert migrations"
)
Logger.error(`For example: "npx medusa migration revert <moduleName>"`)
logger.error(`For example: "npx medusa migration revert <moduleName>"`)
process.exit(1)
}
}
@@ -45,7 +45,7 @@ const main = async function ({ directory }) {
validateInputArgs({ action, modules })
const container = await initializeContainer(directory)
const container = initializeContainer(directory)
const configModule = container.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
@@ -55,7 +55,7 @@ const main = async function ({ directory }) {
const pluginLinks = await resolvePluginsLinks(plugins, container)
if (action === "run") {
Logger.info("Running migrations...")
logger.info("Running migrations...")
await runMedusaAppMigrations({
configModule,
@@ -65,10 +65,10 @@ const main = async function ({ directory }) {
})
console.log(new Array(TERMINAL_SIZE).join("-"))
Logger.info("Migrations completed")
logger.info("Migrations completed")
process.exit()
} else if (action === "revert") {
Logger.info("Reverting migrations...")
logger.info("Reverting migrations...")
try {
await runMedusaAppMigrations({
@@ -79,23 +79,23 @@ const main = async function ({ directory }) {
action: "revert",
})
console.log(new Array(TERMINAL_SIZE).join("-"))
Logger.info("Migrations reverted")
logger.info("Migrations reverted")
process.exit()
} catch (error) {
console.log(new Array(TERMINAL_SIZE).join("-"))
if (error.code && error.code === MedusaError.Codes.UNKNOWN_MODULES) {
Logger.error(error.message)
logger.error(error.message)
const modulesList = error.allModules.map(
(name: string) => ` - ${name}`
)
Logger.error(`Available modules:\n${modulesList.join("\n")}`)
logger.error(`Available modules:\n${modulesList.join("\n")}`)
} else {
Logger.error(error.message, error)
logger.error(error.message, error)
}
process.exit(1)
}
} else if (action === "generate") {
Logger.info("Generating migrations...")
logger.info("Generating migrations...")
await runMedusaAppMigrations({
moduleNames: modules,
@@ -106,10 +106,10 @@ const main = async function ({ directory }) {
})
console.log(new Array(TERMINAL_SIZE).join("-"))
Logger.info("Migrations generated")
logger.info("Migrations generated")
process.exit()
} else if (action === "show") {
Logger.info("Action not supported yet")
logger.info("Action not supported yet")
process.exit(0)
}
}
@@ -8,8 +8,8 @@ import { scheduleJob } from "node-schedule"
import os from "os"
import loaders from "../loaders"
import Logger from "../loaders/logger"
import { isPresent, GracefulShutdownServer } from "@medusajs/utils"
import { logger } from "@medusajs/framework"
import { GracefulShutdownServer, isPresent } from "@medusajs/utils"
const EVERY_SIXTH_HOUR = "0 */6 * * *"
const CRON_SCHEDULE = EVERY_SIXTH_HOUR
@@ -58,10 +58,10 @@ export default async function ({ port, cpus, directory }) {
directory,
expressApp: app,
})
const serverActivity = Logger.activity(`Creating server`)
const serverActivity = logger.activity(`Creating server`)
const server = GracefulShutdownServer.create(
app.listen(port).on("listening", () => {
Logger.success(serverActivity, `Server is ready on port: ${port}`)
logger.success(serverActivity, `Server is ready on port: ${port}`)
track("CLI_START_COMPLETED")
})
)
+6 -6
View File
@@ -6,7 +6,7 @@ import { track } from "medusa-telemetry"
import { scheduleJob } from "node-schedule"
import loaders from "../loaders"
import Logger from "../loaders/logger"
import { logger } from "@medusajs/framework"
import { GracefulShutdownServer } from "@medusajs/utils"
const EVERY_SIXTH_HOUR = "0 */6 * * *"
@@ -24,17 +24,17 @@ export default async function ({ port, directory }) {
expressApp: app,
})
const serverActivity = Logger.activity(`Creating server`)
const serverActivity = logger.activity(`Creating server`)
const server = GracefulShutdownServer.create(
app.listen(port).on("listening", () => {
Logger.success(serverActivity, `Server is ready on port: ${port}`)
logger.success(serverActivity, `Server is ready on port: ${port}`)
track("CLI_START_COMPLETED")
})
)
// Handle graceful shutdown
const gracefulShutDown = () => {
Logger.info("Gracefully shutting down server")
logger.info("Gracefully shutting down server")
server
.shutdown()
.then(async () => {
@@ -42,7 +42,7 @@ export default async function ({ port, directory }) {
process.exit(0)
})
.catch((e) => {
Logger.error("Error received when shutting down the server.", e)
logger.error("Error received when shutting down the server.", e)
process.exit(1)
})
}
@@ -56,7 +56,7 @@ export default async function ({ port, directory }) {
return { server }
} catch (err) {
Logger.error("Error starting server", err)
logger.error("Error starting server", err)
process.exit(1)
}
}
+3 -3
View File
@@ -6,7 +6,7 @@ import { track } from "medusa-telemetry"
import { ModuleRegistrationName } from "@medusajs/utils"
import loaders from "../loaders"
import Logger from "../loaders/logger"
import { logger } from "@medusajs/framework"
export default async function ({
directory,
@@ -38,7 +38,7 @@ export default async function ({
if (invite) {
const invite = await userService.createInvites({ email })
Logger.info(`
logger.info(`
Invite token: ${invite.token}
Open the invite in Medusa Admin at: [your-admin-url]/invite?token=${invite.token}`)
} else {
@@ -52,7 +52,7 @@ export default async function ({
})
if (error) {
Logger.error(error)
logger.error(error)
process.exit(1)
}
-85
View File
@@ -1,85 +0,0 @@
import { ConfigModule } from "@medusajs/types"
import createStore from "connect-redis"
import cookieParser from "cookie-parser"
import express, { Express } from "express"
import session from "express-session"
import Redis from "ioredis"
import morgan from "morgan"
import path from "path"
type Options = {
app: Express
configModule: ConfigModule
rootDirectory: string
}
export default async ({
app,
configModule,
rootDirectory,
}: Options): Promise<{
app: Express
shutdown: () => Promise<void>
}> => {
let sameSite: string | boolean = false
let secure = false
if (
process.env.NODE_ENV === "production" ||
process.env.NODE_ENV === "staging"
) {
secure = true
sameSite = "none"
}
const { http, sessionOptions } = configModule.projectConfig
const sessionOpts = {
name: sessionOptions?.name ?? "connect.sid",
resave: sessionOptions?.resave ?? true,
rolling: sessionOptions?.rolling ?? false,
saveUninitialized: sessionOptions?.saveUninitialized ?? true,
proxy: true,
secret: sessionOptions?.secret ?? http?.cookieSecret,
cookie: {
sameSite,
secure,
maxAge: sessionOptions?.ttl ?? 10 * 60 * 60 * 1000,
},
store: null,
}
let redisClient
if (configModule?.projectConfig?.redisUrl) {
const RedisStore = createStore(session)
redisClient = new Redis(
configModule.projectConfig.redisUrl,
configModule.projectConfig.redisOptions ?? {}
)
sessionOpts.store = new RedisStore({
client: redisClient,
prefix: `${configModule?.projectConfig?.redisPrefix ?? ""}sess:`,
})
}
app.set("trust proxy", 1)
app.use(
morgan("combined", {
skip: () => process.env.NODE_ENV === "test",
})
)
app.use(cookieParser())
app.use(session(sessionOpts))
// Currently we don't allow configuration of static files, but this can be revisited as needed.
app.use("/static", express.static(path.join(rootDirectory, "static")))
app.get("/health", (req, res) => {
res.status(200).send("OK")
})
const shutdown = async () => {
redisClient?.disconnect()
}
return { app, shutdown }
}
@@ -1,10 +1,10 @@
import {
StepResponse,
createStep,
createWorkflow,
StepResponse,
} from "@medusajs/workflows-sdk"
import { glob } from "glob"
import logger from "../logger"
import { logger } from "@medusajs/framework"
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
export const registerJobs = async (plugins) => {
@@ -6,7 +6,7 @@ import { readdir } from "fs/promises"
import { extname, join, sep } from "path"
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
import { authenticate, errorHandler } from "../../../utils/middlewares"
import logger from "../../logger"
import { logger } from "@medusajs/framework"
import {
AsyncRouteHandler,
GlobalMiddlewareDescriptor,
@@ -9,7 +9,7 @@ import { readdir } from "fs/promises"
import { extname, join, sep } from "path"
import { SubscriberArgs, SubscriberConfig } from "../../../types/subscribers"
import logger from "../../logger"
import { logger } from "@medusajs/framework"
type SubscriberHandler<T> = (args: SubscriberArgs<T>) => Promise<void>
+12 -14
View File
@@ -1,10 +1,6 @@
import { createDefaultsWorkflow } from "@medusajs/core-flows"
import { ConfigModule, MedusaContainer, PluginDetails } from "@medusajs/types"
import {
ContainerRegistrationKeys,
createMedusaContainer,
promiseAll,
} from "@medusajs/utils"
import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils"
import { asValue } from "awilix"
import { Express, NextFunction, Request, Response } from "express"
import path from "path"
@@ -12,8 +8,13 @@ import requestIp from "request-ip"
import { v4 } from "uuid"
import adminLoader from "./admin"
import apiLoader from "./api"
import { configLoader, logger } from "@medusajs/framework"
import expressLoader from "./express"
import {
configLoader,
container,
expressLoader,
logger,
pgConnectionLoader,
} from "@medusajs/framework"
import featureFlagsLoader from "./feature-flags"
import { registerJobs } from "./helpers/register-jobs"
import { registerWorkflows } from "./helpers/register-workflows"
@@ -21,7 +22,6 @@ import { getResolvedPlugins } from "./helpers/resolve-plugins"
import { resolvePluginsLinks } from "./helpers/resolve-plugins-links"
import { SubscriberLoader } from "./helpers/subscribers"
import loadMedusaApp from "./medusa-app"
import registerPgConnection from "./pg-connection"
type Options = {
directory: string
@@ -93,9 +93,8 @@ async function loadEntrypoints(
const { shutdown } = await expressLoader({
app: expressApp,
configModule,
rootDirectory,
})
expressApp.use((req: Request, res: Response, next: NextFunction) => {
req.scope = container.createScope() as MedusaContainer
req.requestId = (req.headers["x-request-id"] as string) ?? v4()
@@ -121,8 +120,7 @@ async function loadEntrypoints(
return shutdown
}
export async function initializeContainer(rootDirectory: string) {
const container = createMedusaContainer()
export function initializeContainer(rootDirectory: string): MedusaContainer {
const configModule = configLoader(rootDirectory, "medusa-config.js")
const featureFlagRouter = featureFlagsLoader(configModule, logger)
@@ -133,7 +131,7 @@ export async function initializeContainer(rootDirectory: string) {
[ContainerRegistrationKeys.REMOTE_QUERY]: asValue(null),
})
await registerPgConnection({ container, configModule })
pgConnectionLoader()
return container
}
@@ -145,7 +143,7 @@ export default async ({
app: Express
shutdown: () => Promise<void>
}> => {
const container = await initializeContainer(rootDirectory)
const container = initializeContainer(rootDirectory)
const configModule = container.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
)
-3
View File
@@ -1,3 +0,0 @@
import logger from "@medusajs/medusa-cli/dist/reporter"
export default logger
@@ -1,41 +0,0 @@
import { ConfigModule } from "@medusajs/framework"
import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils"
import { asValue, AwilixContainer } from "awilix"
type Options = {
container: AwilixContainer
configModule: ConfigModule
}
export default async ({ container, configModule }: Options): Promise<any> => {
if (container.hasRegistration(ContainerRegistrationKeys.PG_CONNECTION)) {
return container.resolve(ContainerRegistrationKeys.PG_CONNECTION)
}
// Share a knex connection to be consumed by the shared modules
const connectionString = configModule.projectConfig.databaseUrl
const driverOptions: any =
configModule.projectConfig.databaseDriverOptions || {}
const schema = configModule.projectConfig.databaseSchema || "public"
const idleTimeoutMillis = driverOptions.pool?.idleTimeoutMillis ?? undefined // prevent null to be passed
const poolMax = driverOptions.pool?.max
delete driverOptions.pool
const pgConnection = ModulesSdkUtils.createPgConnection({
clientUrl: connectionString,
schema,
driverOptions,
pool: {
max: poolMax,
idleTimeoutMillis,
},
})
container.register(
ContainerRegistrationKeys.PG_CONNECTION,
asValue(pgConnection)
)
return pgConnection
}
-63
View File
@@ -1,63 +0,0 @@
import { asValue } from "awilix"
import Redis from "ioredis"
import FakeRedis from "ioredis-mock"
import { EOL } from "os"
import { Logger, MedusaContainer } from "../types/global"
import { ConfigModule } from "@medusajs/types"
type Options = {
container: MedusaContainer
configModule: ConfigModule
logger: Logger
}
// TODO: Will be removed when the strict dependency on Redis in the core is removed
async function redisLoader({
container,
configModule,
logger,
}: Options): Promise<{ shutdown: () => Promise<void> }> {
let client!: Redis | FakeRedis
if (configModule.projectConfig.redisUrl) {
client = new Redis(configModule.projectConfig.redisUrl, {
// Lazy connect to properly handle connection errors
lazyConnect: true,
...(configModule.projectConfig.redisOptions ?? {}),
})
try {
await client.connect()
logger?.info(`Connection to Redis established`)
} catch (err) {
logger?.error(`An error occurred while connecting to Redis:${EOL} ${err}`)
}
container.register({
redisClient: asValue(client),
})
} else {
if (process.env.NODE_ENV === "production") {
logger.warn(
`No Redis url was provided - using Medusa in production without a proper Redis instance is not recommended`
)
}
logger.info("Using fake Redis")
// Economical way of dealing with redis clients
client = new FakeRedis()
container.register({
redisClient: asValue(client),
})
}
return {
shutdown: async () => {
client.disconnect()
},
}
}
export default redisLoader