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 Peretti
2024-07-30 10:52:12 +02:00
committed by GitHub
parent a2a377c8ca
commit bcd9d9c2b1
30 changed files with 204 additions and 359 deletions

View File

@@ -2,11 +2,7 @@ const path = require("path")
const { getConfigFile } = require("@medusajs/utils")
const { asValue } = require("awilix")
const {
isObject,
createMedusaContainer,
MedusaV2Flag,
} = require("@medusajs/utils")
const { isObject, MedusaV2Flag } = require("@medusajs/utils")
const { dropDatabase } = require("pg-god")
const { DataSource } = require("typeorm")
const dbFactory = require("./use-template-db")
@@ -52,7 +48,7 @@ const DbTestUtil = {
this.pgConnection_ = pgConnection
},
clear: async function () {
clear: function () {
this.db_.synchronize(true)
},
@@ -161,17 +157,16 @@ module.exports = {
force_modules_migration ||
featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)
) {
const pgConnectionLoader =
require("@medusajs/medusa/dist/loaders/pg-connection").default
const { container, pgConnectionLoader } = await import(
"@medusajs/framework"
)
const featureFlagLoader =
require("@medusajs/medusa/dist/loaders/feature-flags").default
const container = createMedusaContainer()
const featureFlagRouter = await featureFlagLoader(configModule)
const pgConnection = await pgConnectionLoader({ configModule, container })
const pgConnection = pgConnectionLoader()
container.register({
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),

View File

@@ -60,7 +60,7 @@ export class Reporter {
this.ora_ = activityLogger
}
panic = (data) => {
panic(data) {
const parsedPanic = panicHandler(data)
this.loggerInstance_.log({
@@ -81,17 +81,17 @@ export class Reporter {
* @param {string} level - the level to check if logger is configured for
* @return {boolean} whether we should log
*/
shouldLog = (level) => {
level = this.loggerInstance_.levels[level]
shouldLog = (level: string) => {
const levelValue = this.loggerInstance_.levels[level]
const logLevel = this.loggerInstance_.levels[this.loggerInstance_.level]
return level <= logLevel
return levelValue <= logLevel
}
/**
* Sets the log level of the logger.
* @param {string} level - the level to set the logger to
*/
setLogLevel = (level) => {
setLogLevel(level: string) {
this.loggerInstance_.level = level
}
@@ -99,7 +99,7 @@ export class Reporter {
* Resets the logger to the value specified by the LOG_LEVEL env var. If no
* LOG_LEVEL is set it defaults to "silly".
*/
unsetLogLevel = () => {
unsetLogLevel() {
this.loggerInstance_.level = LOG_LEVEL
}
@@ -111,7 +111,7 @@ export class Reporter {
* @returns {string} the id of the activity; this should be passed to do
* further operations on the activity such as success, failure, progress.
*/
activity = (message, config = {}) => {
activity(message: string, config: any = {}) {
const id = ulid()
if (IS_DEV && this.shouldLog("info")) {
const activity = this.ora_(message).start()
@@ -146,13 +146,13 @@ export class Reporter {
* @param {string} activityId - the id of the activity as returned by activity
* @param {string} message - the message to log
*/
progress = (activityId, message) => {
progress(activityId: string, message: string) {
const toLog = {
level: "info",
message,
}
if (typeof activityId === "string" && this.activities_[activityId]) {
if (this.activities_[activityId]) {
const activity = this.activities_[activityId]
if (activity.activity) {
activity.text = message
@@ -172,8 +172,9 @@ export class Reporter {
* message to log the error under; or an error object.
* @param {Error?} error - an error object to log message with
*/
error = (messageOrError, error: any = null) => {
let message = messageOrError
error(messageOrError: string | Error, error?: Error) {
let message = messageOrError as string
if (typeof messageOrError === "object") {
message = messageOrError.message
error = messageOrError
@@ -204,14 +205,14 @@ export class Reporter {
* @param {string} message - the message to log
* @returns {object} data about the activity
*/
failure = (activityId, message) => {
failure(activityId: string, message: string) {
const time = Date.now()
const toLog = {
level: "error",
message,
}
if (typeof activityId === "string" && this.activities_[activityId]) {
if (this.activities_[activityId]) {
const activity = this.activities_[activityId]
if (activity.activity) {
activity.activity.fail(`${message} ${time - activity.start}`)
@@ -243,14 +244,14 @@ export class Reporter {
* @param {string} message - the message to log
* @returns {Record<string, any>} data about the activity
*/
success = (activityId, message) => {
success(activityId: string, message: string) {
const time = Date.now()
const toLog = {
level: "info",
message,
}
if (typeof activityId === "string" && this.activities_[activityId]) {
if (this.activities_[activityId]) {
const activity = this.activities_[activityId]
if (activity.activity) {
activity.activity.succeed(`${message} ${time - activity.start}ms`)
@@ -278,7 +279,7 @@ export class Reporter {
* Logs a message at the info level.
* @param {string} message - the message to log
*/
debug = (message) => {
debug(message: string) {
this.loggerInstance_.log({
level: "debug",
message,
@@ -289,7 +290,7 @@ export class Reporter {
* Logs a message at the info level.
* @param {string} message - the message to log
*/
info = (message) => {
info(message: string) {
this.loggerInstance_.log({
level: "info",
message,
@@ -300,7 +301,7 @@ export class Reporter {
* Logs a message at the warn level.
* @param {string} message - the message to log
*/
warn = (message) => {
warn = (message: string) => {
this.loggerInstance_.warn({
level: "warn",
message,
@@ -310,7 +311,7 @@ export class Reporter {
/**
* A wrapper around winston's log method.
*/
log = (...args) => {
log(...args) {
if (args.length > 1) {
// @ts-ignore
this.loggerInstance_.log(...args)

View File

@@ -1,5 +1,5 @@
import { ApiKeyDTO, CreateApiKeyDTO } from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { createWorkflow, WorkflowData } from "@medusajs/workflows-sdk"
import { createApiKeysStep } from "../steps"
type WorkflowInput = { api_keys: CreateApiKeyDTO[] }

View File

@@ -24,14 +24,15 @@
"author": "Medusa",
"license": "MIT",
"devDependencies": {
"@medusajs/framework": "^0.0.1",
"@medusajs/types": "^1.11.16",
"@medusajs/utils": "^1.11.9",
"cross-env": "^5.2.1",
"jest": "^29.7.0",
"rimraf": "^3.0.2",
"typescript": "^5.1.6"
},
"peerDependencies": {
"@medusajs/framework": "workspace:^",
"@medusajs/medusa": ">1.19",
"@medusajs/modules-sdk": "^1.12.10",
"axios": "^0.28.0",
@@ -40,9 +41,6 @@
"pg-god": "^1.0.12"
},
"peerDependenciesMeta": {
"@medusajs/framework": {
"optional": true
},
"@medusajs/medusa": {
"optional": true
},

View File

@@ -4,8 +4,6 @@ export async function configLoaderOverride(
entryDirectory: string,
override: { clientUrl: string; debug?: boolean }
) {
// in case it is not install as it is optional and required only when using this util
// @ts-ignore
const { configManager } = await import("@medusajs/framework/config")
const { configModule, error } = getConfigFile<
ReturnType<typeof configManager.loadConfig>
@@ -27,5 +25,8 @@ export async function configLoaderOverride(
idle_in_transaction_session_timeout: 20000,
}
configManager.loadConfig(configModule)
configManager.loadConfig({
projectConfig: configModule,
baseDir: entryDirectory,
})
}

View File

@@ -1,8 +1,4 @@
import {
ContainerRegistrationKeys,
createMedusaContainer,
isObject,
} from "@medusajs/utils"
import { ContainerRegistrationKeys, isObject } from "@medusajs/utils"
import { asValue } from "awilix"
export async function initDb({ env = {} }: { env?: Record<any, any> }) {
@@ -10,18 +6,12 @@ export async function initDb({ env = {} }: { env?: Record<any, any> }) {
Object.entries(env).forEach(([k, v]) => (process.env[k] = v))
}
const container = createMedusaContainer()
// in case it is not install as it is optional and required only when using this util
// @ts-ignore
const { configManager } = await import("@medusajs/framework/config")
const { configManager, pgConnectionLoader, container } = await import(
"@medusajs/framework"
)
const configModule = configManager.config
const pgConnection =
await require("@medusajs/medusa/dist/loaders/pg-connection").default({
configModule,
container,
})
const pgConnection = pgConnectionLoader()
const featureFlagRouter =
require("@medusajs/medusa/dist/loaders/feature-flags").default(configModule)

View File

@@ -26,6 +26,12 @@
"import": "./dist/logger/index.js",
"require": "./dist/logger/index.js",
"node": "./dist/logger/index.js"
},
"./database": {
"types": "./dist/database/index.d.ts",
"import": "./dist/database/index.js",
"require": "./dist/database/index.js",
"node": "./dist/database/index.js"
}
},
"engines": {
@@ -42,7 +48,7 @@
"author": "Medusa",
"license": "MIT",
"scripts": {
"watch": "tsc --build --watch -p ./tsconfig.build.json",
"watch": "tsc --watch -p ./tsconfig.build.json",
"watch:test": "tsc --build tsconfig.spec.json --watch",
"prepublishOnly": "cross-env NODE_ENV=production tsc -p ./tsconfig.build.json && tsc-alias -p ./tsconfig.build.json",
"build": "rimraf dist && tsc --build && tsc-alias",
@@ -50,17 +56,23 @@
"test:integration": "jest --forceExit -- integration-tests/**/__tests__/**/*.ts"
},
"devDependencies": {
"@medusajs/types": "^1.11.17-preview-20240510084332",
"@medusajs/types": "^1.11.16",
"@types/express": "^4.17.17",
"cross-env": "^7.0.3",
"ioredis": "^5.2.5",
"rimraf": "^3.0.2",
"tsc-alias": "^1.8.6",
"typescript": "^5.1.6",
"vite": "^5.2.11"
},
"dependencies": {
"@medusajs/medusa-cli": "^1.3.23",
"@medusajs/utils": "^1.12.0-preview-20240724081425",
"awilix": "^8.0.0"
"@medusajs/medusa-cli": "^1.3.22",
"@medusajs/utils": "^1.11.9",
"awilix": "^8.0.0",
"cookie-parser": "^1.4.6",
"express": "^4.18.2",
"express-session": "^1.17.3",
"ioredis": "^5.2.5",
"ioredis-mock": "8.4.0",
"morgan": "^1.9.1"
}
}

View File

@@ -1,8 +1,14 @@
import { ConfigModule } from "./types"
import { deepCopy, isDefined } from "@medusajs/utils"
import { Logger } from "@medusajs/types"
import { logger } from "../logger"
export class ConfigManager {
/**
* Root dir from where to start
* @private
*/
#baseDir: string
/**
* A flag to specify if we are in production or not, determine whether an error would be critical and thrown or just logged as a warning in developement
* @private
@@ -18,12 +24,6 @@ export class ConfigManager {
readonly #envWorkMode?: ConfigModule["projectConfig"]["workerMode"] = process
.env.MEDUSA_WORKER_MODE as ConfigModule["projectConfig"]["workerMode"]
/**
* The logger instance to use
* @private
*/
readonly #logger: Logger
/**
* The config object after loading it
* @private
@@ -39,10 +39,16 @@ export class ConfigManager {
return this.#config
}
constructor({ logger }: { logger: Logger }) {
this.#logger = logger
get baseDir(): string {
return this.#baseDir
}
get isProduction(): boolean {
return this.#isProduction
}
constructor() {}
/**
* Rejects an error either by throwing when in production or by logging the error as a warning
* @param error
@@ -53,7 +59,7 @@ export class ConfigManager {
throw new Error(`[config] ⚠️ ${error}`)
}
this.#logger.warn(error)
logger.warn(error)
}
/**
@@ -141,17 +147,25 @@ export class ConfigManager {
/**
* Prepare the full configuration after validation and normalization
*/
loadConfig(rawConfig: Partial<ConfigModule> = {}): ConfigModule {
const projectConfig = this.normalizeProjectConfig(
rawConfig.projectConfig ?? {}
loadConfig({
projectConfig = {},
baseDir,
}: {
projectConfig: Partial<ConfigModule>
baseDir: string
}): ConfigModule {
this.#baseDir = baseDir
const normalizedProjectConfig = this.normalizeProjectConfig(
projectConfig.projectConfig ?? {}
)
this.#config = {
projectConfig,
admin: rawConfig.admin ?? {},
modules: rawConfig.modules ?? {},
featureFlags: rawConfig.featureFlags ?? {},
plugins: rawConfig.plugins ?? [],
projectConfig: normalizedProjectConfig,
admin: projectConfig.admin ?? {},
modules: projectConfig.modules ?? {},
featureFlags: projectConfig.featureFlags ?? {},
plugins: projectConfig.plugins ?? [],
}
return this.#config

View File

@@ -1,7 +1,9 @@
import { ConfigModule } from "./types"
import { getConfigFile } from "@medusajs/utils"
import { ContainerRegistrationKeys, getConfigFile } from "@medusajs/utils"
import { logger } from "../logger"
import { ConfigManager } from "./config"
import { container } from "../container"
import { asFunction } from "awilix"
const handleConfigError = (error: Error): void => {
logger.error(`Error in loading config: ${error.message}`)
@@ -12,9 +14,12 @@ const handleConfigError = (error: Error): void => {
}
// TODO: Later on we could store the config manager into the unique container
export const configManager = new ConfigManager({
logger,
})
export const configManager = new ConfigManager()
container.register(
ContainerRegistrationKeys.CONFIG_MODULE,
asFunction(() => configManager)
)
/**
* Loads the config file and returns the config module after validating, normalizing the configurations
@@ -35,5 +40,8 @@ export function configLoader(
handleConfigError(error)
}
return configManager.loadConfig(configModule)
return configManager.loadConfig({
projectConfig: configModule,
baseDir: entryDirectory,
})
}

View File

@@ -0,0 +1,3 @@
import { createMedusaContainer } from "@medusajs/utils"
export const container = createMedusaContainer()

View File

@@ -0,0 +1 @@
export * from "./pg-connection-loader"

View File

@@ -1,17 +1,20 @@
import { ConfigModule } from "@medusajs/framework"
import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils"
import { asValue, AwilixContainer } from "awilix"
import { asValue } from "awilix"
import { container } from "../container"
import { configManager } from "../config"
type Options = {
container: AwilixContainer
configModule: ConfigModule
}
export default async ({ container, configModule }: Options): Promise<any> => {
/**
* Initialize a knex connection that can then be shared to any resources if needed
*/
export function pgConnectionLoader(): ReturnType<
typeof ModulesSdkUtils.createPgConnection
> {
if (container.hasRegistration(ContainerRegistrationKeys.PG_CONNECTION)) {
return container.resolve(ContainerRegistrationKeys.PG_CONNECTION)
}
const configModule = configManager.config
// Share a knex connection to be consumed by the shared modules
const connectionString = configModule.projectConfig.databaseUrl
const driverOptions: any =

View File

@@ -1,4 +1,3 @@
import { ConfigModule } from "@medusajs/types"
import createStore from "connect-redis"
import cookieParser from "cookie-parser"
import express, { Express } from "express"
@@ -6,27 +5,21 @@ import session from "express-session"
import Redis from "ioredis"
import morgan from "morgan"
import path from "path"
import { configManager } from "../config"
type Options = {
app: Express
configModule: ConfigModule
rootDirectory: string
}
export default async ({
app,
configModule,
rootDirectory,
}: Options): Promise<{
export async function expressLoader({ app }: { app: Express }): Promise<{
app: Express
shutdown: () => Promise<void>
}> => {
}> {
const baseDir = configManager.baseDir
const configModule = configManager.config
const isProduction = configManager.isProduction
const isStaging = process.env.NODE_ENV === "staging"
const isTest = process.env.NODE_ENV === "test"
let sameSite: string | boolean = false
let secure = false
if (
process.env.NODE_ENV === "production" ||
process.env.NODE_ENV === "staging"
) {
if (isProduction || isStaging) {
secure = true
sameSite = "none"
}
@@ -64,14 +57,14 @@ export default async ({
app.set("trust proxy", 1)
app.use(
morgan("combined", {
skip: () => process.env.NODE_ENV === "test",
skip: () => isTest,
})
)
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.use("/static", express.static(path.join(baseDir, "static")))
app.get("/health", (req, res) => {
res.status(200).send("OK")

View File

@@ -0,0 +1 @@
export * from "./express-loader"

View File

@@ -1,2 +1,5 @@
export * from "./config"
export * from "./logger"
export * from "./http"
export * from "./database"
export * from "./container"

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",

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`)
})
},
}

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 = {

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)
}
}

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)
}
}

View File

@@ -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")
})
)

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)
}
}

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)
}

View File

@@ -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) => {

View File

@@ -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,

View File

@@ -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>

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
)

View File

@@ -1,3 +0,0 @@
import logger from "@medusajs/medusa-cli/dist/reporter"
export default logger

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

135
yarn.lock
View File

@@ -4604,16 +4604,22 @@ __metadata:
languageName: unknown
linkType: soft
"@medusajs/framework@^0.0.1-preview-20240724081425, @medusajs/framework@workspace:packages/framework/framework":
"@medusajs/framework@^0.0.1, @medusajs/framework@workspace:packages/framework/framework":
version: 0.0.0-use.local
resolution: "@medusajs/framework@workspace:packages/framework/framework"
dependencies:
"@medusajs/medusa-cli": ^1.3.23
"@medusajs/types": ^1.11.17-preview-20240510084332
"@medusajs/utils": ^1.12.0-preview-20240724081425
"@medusajs/medusa-cli": ^1.3.22
"@medusajs/types": ^1.11.16
"@medusajs/utils": ^1.11.9
"@types/express": ^4.17.17
awilix: ^8.0.0
cookie-parser: ^1.4.6
cross-env: ^7.0.3
express: ^4.18.2
express-session: ^1.17.3
ioredis: ^5.2.5
ioredis-mock: 8.4.0
morgan: ^1.9.1
rimraf: ^3.0.2
tsc-alias: ^1.8.6
typescript: ^5.1.6
@@ -4803,44 +4809,6 @@ __metadata:
languageName: unknown
linkType: soft
"@medusajs/medusa-cli@npm:^1.3.23":
version: 1.3.23
resolution: "@medusajs/medusa-cli@npm:1.3.23"
dependencies:
"@medusajs/utils": ^1.11.10
axios: ^0.21.4
chalk: ^4.0.0
configstore: 5.0.1
core-js: ^3.6.5
dotenv: ^16.4.5
execa: ^5.1.1
fs-exists-cached: ^1.0.0
fs-extra: ^10.0.0
glob: ^7.1.6
hosted-git-info: ^4.0.2
inquirer: ^8.0.0
is-valid-path: ^0.1.1
meant: ^1.0.3
medusa-core-utils: ^1.2.3
medusa-telemetry: ^0.0.18
open: ^8.0.6
ora: ^5.4.1
pg: ^8.11.0
pg-god: ^1.0.12
prompts: ^2.4.2
regenerator-runtime: ^0.13.11
resolve-cwd: ^3.0.0
semver: ^7.3.8
stack-trace: ^0.0.10
ulid: ^2.3.0
winston: ^3.8.2
yargs: ^15.3.1
bin:
medusa: cli.js
checksum: c6d276d5a1bae3313342196f8387c2588dd68c2fe8b230a7018fb0a17170c02ccb28d407780bf2a1081cc5925c79d27a144a2f3794779c781fa06d2bd4d7d891
languageName: node
linkType: hard
"@medusajs/medusa-oas-cli@0.3.2, @medusajs/medusa-oas-cli@workspace:packages/cli/oas/medusa-oas-cli":
version: 0.0.0-use.local
resolution: "@medusajs/medusa-oas-cli@workspace:packages/cli/oas/medusa-oas-cli"
@@ -4877,7 +4845,7 @@ __metadata:
"@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
@@ -5316,20 +5284,6 @@ __metadata:
languageName: unknown
linkType: soft
"@medusajs/types@npm:1.12.0-snapshot-20240723115023":
version: 1.12.0-snapshot-20240723115023
resolution: "@medusajs/types@npm:1.12.0-snapshot-20240723115023"
checksum: 676a9f359000fc688346b3e0a1bc4d9c13bba35e613e98fed8e47a8f6b50177ab4295c3cb2d404795c5ad7cd2b8c131e1bddd4a6e139bd82347a6388b688ac2f
languageName: node
linkType: hard
"@medusajs/types@npm:^1.11.17, @medusajs/types@npm:^1.11.17-preview-20240510084332":
version: 1.11.17
resolution: "@medusajs/types@npm:1.11.17"
checksum: 544099b215cd4de87682c2154696ff4849704f74290f15e3e383e6cf503a335767b399b9fe2a381ffa4405fa2ec7ed911a8a5eecff6c7f10d5ef95af802064b6
languageName: node
linkType: hard
"@medusajs/ui-preset@1.1.3, @medusajs/ui-preset@^1.1.3, @medusajs/ui-preset@workspace:packages/design-system/ui-preset":
version: 0.0.0-use.local
resolution: "@medusajs/ui-preset@workspace:packages/design-system/ui-preset"
@@ -5471,42 +5425,6 @@ __metadata:
languageName: unknown
linkType: soft
"@medusajs/utils@npm:^1.11.10":
version: 1.11.10
resolution: "@medusajs/utils@npm:1.11.10"
dependencies:
"@medusajs/types": ^1.11.17
"@mikro-orm/core": 5.9.7
"@mikro-orm/migrations": 5.9.7
"@mikro-orm/postgresql": 5.9.7
awilix: ^8.0.1
bignumber.js: ^9.1.2
knex: 2.4.2
ulid: ^2.3.0
checksum: 5f9c1e021a029c1176e8fb8e71257a2503e38aa033fb133cad5aa6ac0a73e46b715a2622269b44f6b65a7477e90c288b7b762ae012c65f143c3b6aa460ef3101
languageName: node
linkType: hard
"@medusajs/utils@npm:^1.12.0-preview-20240724081425":
version: 1.12.0-snapshot-20240723115023
resolution: "@medusajs/utils@npm:1.12.0-snapshot-20240723115023"
dependencies:
"@medusajs/types": 1.12.0-snapshot-20240723115023
"@mikro-orm/core": 5.9.7
"@mikro-orm/migrations": 5.9.7
"@mikro-orm/postgresql": 5.9.7
awilix: ^8.0.1
bignumber.js: ^9.1.2
dotenv: ^16.4.5
json-2-csv: ^5.5.4
jsonwebtoken: ^9.0.2
knex: 2.4.2
pluralize: ^8.0.0
ulid: ^2.3.0
checksum: ae0d42e4a937c5941c4365de6be3908a5d75b121b50d0ba9d93ce948babea43b8c3d9eaedc1cd22fd7455b984e3ba209feb9217b311c28d679a92e9715376542
languageName: node
linkType: hard
"@medusajs/workflow-engine-inmemory@workspace:*, @medusajs/workflow-engine-inmemory@workspace:packages/modules/workflow-engine-inmemory":
version: 0.0.0-use.local
resolution: "@medusajs/workflow-engine-inmemory@workspace:packages/modules/workflow-engine-inmemory"
@@ -22737,15 +22655,6 @@ __metadata:
languageName: node
linkType: hard
"medusa-core-utils@npm:^1.2.3":
version: 1.2.3
resolution: "medusa-core-utils@npm:1.2.3"
dependencies:
awilix: ^8.0.0
checksum: 8547b2bd6cf51e155885bdbb622b2897035b1369a7b758158a2c71df0b349f5dc23d664a23db1a8654306bf08226d483efd75829cbc232980574af8097147e02
languageName: node
linkType: hard
"medusa-dev-cli@workspace:packages/cli/medusa-dev-cli":
version: 0.0.0-use.local
resolution: "medusa-dev-cli@workspace:packages/cli/medusa-dev-cli"
@@ -22795,28 +22704,11 @@ __metadata:
languageName: unknown
linkType: soft
"medusa-telemetry@npm:^0.0.18":
version: 0.0.18
resolution: "medusa-telemetry@npm:0.0.18"
dependencies:
"@babel/runtime": ^7.22.10
axios: ^0.21.4
axios-retry: ^3.1.9
boxen: ^5.0.1
ci-info: ^3.2.0
configstore: 5.0.1
global: ^4.4.0
is-docker: ^2.2.1
remove-trailing-slash: ^0.1.1
uuid: ^8.3.2
checksum: 3571c3f578582667b3a48f2f3d9d27299a954fcc1e9165c2fdc441219d6faa0cd0f6be453f0edec783acea83500586c199a21d8b052e6ed3c815da85850fef7f
languageName: node
linkType: hard
"medusa-test-utils@^1.1.42, medusa-test-utils@^1.1.43, medusa-test-utils@^1.1.44, medusa-test-utils@workspace:*, medusa-test-utils@workspace:^, medusa-test-utils@workspace:packages/core/medusa-test-utils":
version: 0.0.0-use.local
resolution: "medusa-test-utils@workspace:packages/core/medusa-test-utils"
dependencies:
"@medusajs/framework": ^0.0.1
"@medusajs/types": ^1.11.16
"@medusajs/utils": ^1.11.9
"@mikro-orm/migrations": 5.9.7
@@ -22827,7 +22719,6 @@ __metadata:
rimraf: ^3.0.2
typescript: ^5.1.6
peerDependencies:
"@medusajs/framework": "workspace:^"
"@medusajs/medusa": ">1.19"
"@medusajs/modules-sdk": ^1.12.10
axios: ^0.28.0
@@ -22835,8 +22726,6 @@ __metadata:
get-port: ^5.1.0
pg-god: ^1.0.12
peerDependenciesMeta:
"@medusajs/framework":
optional: true
"@medusajs/medusa":
optional: true
axios: