feat: custom logger (#13156)
* feat: custom logger * mock log * unit test * FF and jobs loader * unit test * add to ResourceLoader * get from container * mock * rm log * default logger mock * link loaders, express * comments * initialize container as first step * db conn * test * initialize start * plugin build using default logger * ignore .medusa * revert ignroe --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
9412669e65
commit
e2213448ac
@@ -1,6 +1,6 @@
|
||||
import { ConfigModule } from "./types"
|
||||
import { deepCopy, isDefined } from "@medusajs/utils"
|
||||
import { logger } from "../logger"
|
||||
import { ConfigModule } from "./types"
|
||||
|
||||
export class ConfigManager {
|
||||
/**
|
||||
@@ -124,21 +124,23 @@ export class ConfigManager {
|
||||
|
||||
/**
|
||||
* Normalizes the project config object and assign the defaults if needed
|
||||
* @param projectConfig
|
||||
* @param config
|
||||
* @protected
|
||||
*/
|
||||
protected normalizeProjectConfig(
|
||||
projectConfig: Partial<ConfigModule["projectConfig"]>
|
||||
config: Partial<ConfigModule>
|
||||
): ConfigModule["projectConfig"] {
|
||||
const outputConfig = deepCopy(
|
||||
projectConfig
|
||||
) as ConfigModule["projectConfig"]
|
||||
const projConfig = config?.projectConfig ?? {}
|
||||
const outputConfig = deepCopy(projConfig) as ConfigModule["projectConfig"]
|
||||
|
||||
if (!outputConfig?.redisUrl) {
|
||||
console.log(`redisUrl not found. A fake redis instance will be used.`)
|
||||
const customLogger = config?.logger ?? logger
|
||||
customLogger.log(
|
||||
`redisUrl not found. A fake redis instance will be used.`
|
||||
)
|
||||
}
|
||||
|
||||
outputConfig.http = this.buildHttpConfig(projectConfig)
|
||||
outputConfig.http = this.buildHttpConfig(projConfig)
|
||||
|
||||
let workerMode = outputConfig?.workerMode!
|
||||
|
||||
@@ -172,9 +174,7 @@ export class ConfigManager {
|
||||
}): ConfigModule {
|
||||
this.#baseDir = baseDir
|
||||
|
||||
const normalizedProjectConfig = this.normalizeProjectConfig(
|
||||
projectConfig.projectConfig ?? {}
|
||||
)
|
||||
const normalizedProjectConfig = this.normalizeProjectConfig(projectConfig)
|
||||
|
||||
this.#config = {
|
||||
projectConfig: normalizedProjectConfig,
|
||||
@@ -184,6 +184,7 @@ export class ConfigManager {
|
||||
modules: projectConfig.modules ?? {},
|
||||
featureFlags: projectConfig.featureFlags ?? {},
|
||||
plugins: projectConfig.plugins ?? [],
|
||||
logger: projectConfig.logger ?? logger,
|
||||
}
|
||||
|
||||
return this.#config
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { ConfigModule } from "./types"
|
||||
import { ContainerRegistrationKeys, getConfigFile } from "@medusajs/utils"
|
||||
import { logger } from "../logger"
|
||||
import { ConfigManager } from "./config"
|
||||
import { container } from "../container"
|
||||
import { asFunction } from "awilix"
|
||||
import { container } from "../container"
|
||||
import { logger as defaultLogger } from "../logger"
|
||||
import { ConfigManager } from "./config"
|
||||
import { ConfigModule } from "./types"
|
||||
|
||||
const handleConfigError = (error: Error): void => {
|
||||
logger.error(`Error in loading config: ${error.message}`)
|
||||
defaultLogger.error(`Error in loading config: ${error.message}`)
|
||||
if (error.stack) {
|
||||
logger.error(error.stack)
|
||||
defaultLogger.error(error.stack)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
@@ -28,7 +28,7 @@ container.register(
|
||||
*/
|
||||
export async function configLoader(
|
||||
entryDirectory: string,
|
||||
configFileName: string
|
||||
configFileName: string = "medusa-config"
|
||||
): Promise<ConfigModule> {
|
||||
const config = await getConfigFile<ConfigModule>(
|
||||
entryDirectory,
|
||||
|
||||
@@ -10,7 +10,6 @@ import { asFunction } from "awilix"
|
||||
import { normalize } from "path"
|
||||
import { configManager } from "../config"
|
||||
import { container } from "../container"
|
||||
import { logger } from "../logger"
|
||||
import { FlagSettings } from "./types"
|
||||
|
||||
container.register(
|
||||
@@ -25,7 +24,7 @@ container.register(
|
||||
export async function featureFlagsLoader(
|
||||
sourcePath?: string
|
||||
): Promise<FlagRouter> {
|
||||
const { featureFlags: projectConfigFlags = {} } = configManager.config
|
||||
const { featureFlags: projectConfigFlags = {}, logger } = configManager.config
|
||||
|
||||
if (!sourcePath) {
|
||||
return FeatureFlag
|
||||
|
||||
@@ -3,17 +3,16 @@ import {
|
||||
ModulesDefinition,
|
||||
registerMedusaModule,
|
||||
} from "@medusajs/modules-sdk"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import { ContainerRegistrationKeys, generateJwtToken } from "@medusajs/utils"
|
||||
import { asValue } from "awilix"
|
||||
import express from "express"
|
||||
import querystring from "querystring"
|
||||
import supertest from "supertest"
|
||||
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import { configManager } from "../../../config"
|
||||
import { container } from "../../../container"
|
||||
import { featureFlagsLoader } from "../../../feature-flags"
|
||||
import { logger } from "../../../logger"
|
||||
import { logger as defaultLogger } from "../../../logger"
|
||||
import { ApiLoader } from "../../router"
|
||||
import { MedusaRequest } from "../../types"
|
||||
import { config } from "../mocks"
|
||||
@@ -66,11 +65,8 @@ export const createServer = async (rootDir) => {
|
||||
|
||||
container.register(ContainerRegistrationKeys.PG_CONNECTION, asValue({}))
|
||||
container.register("configModule", asValue(config))
|
||||
container.register(ContainerRegistrationKeys.LOGGER, asValue(defaultLogger))
|
||||
container.register({
|
||||
logger: asValue({
|
||||
error: () => {},
|
||||
info: () => {},
|
||||
}),
|
||||
manager: asValue({}),
|
||||
})
|
||||
|
||||
@@ -88,7 +84,7 @@ export const createServer = async (rootDir) => {
|
||||
})
|
||||
|
||||
await featureFlagsLoader()
|
||||
await moduleLoader({ container, moduleResolutions, logger })
|
||||
await moduleLoader({ container, moduleResolutions, logger: defaultLogger })
|
||||
|
||||
app.use((req, res, next) => {
|
||||
;(req as MedusaRequest).scope = container.createScope() as MedusaContainer
|
||||
@@ -98,6 +94,7 @@ export const createServer = async (rootDir) => {
|
||||
await new ApiLoader({
|
||||
app,
|
||||
sourceDir: rootDir,
|
||||
container,
|
||||
}).load()
|
||||
|
||||
const superRequest = supertest(app)
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
createMedusaContainer,
|
||||
} from "@medusajs/utils"
|
||||
import { asValue } from "awilix"
|
||||
import express from "express"
|
||||
import { resolve } from "path"
|
||||
import { logger as defaultLogger } from "../../logger"
|
||||
import {
|
||||
customersCreateMiddlewareMock,
|
||||
customersCreateMiddlewareValidatorMock,
|
||||
@@ -7,7 +13,7 @@ import {
|
||||
storeGlobalMiddlewareMock,
|
||||
} from "../__fixtures__/mocks"
|
||||
import { createServer } from "../__fixtures__/server"
|
||||
import { MedusaNextFunction, ApiLoader } from "../index"
|
||||
import { ApiLoader, MedusaNextFunction } from "../index"
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
@@ -335,9 +341,16 @@ describe("RoutesLoader", function () {
|
||||
__dirname,
|
||||
"../__fixtures__/routers-duplicate-parameter"
|
||||
)
|
||||
const container = createMedusaContainer()
|
||||
container.register(
|
||||
ContainerRegistrationKeys.LOGGER,
|
||||
asValue(defaultLogger)
|
||||
)
|
||||
|
||||
const err = await new ApiLoader({
|
||||
app,
|
||||
sourceDir: rootDir,
|
||||
container,
|
||||
})
|
||||
.load()
|
||||
.catch((e) => e)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { MedusaContainer } from "@medusajs/framework/types"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
import { dynamicImport } from "@medusajs/utils"
|
||||
import createStore from "connect-redis"
|
||||
import cookieParser from "cookie-parser"
|
||||
@@ -7,14 +9,19 @@ import Redis from "ioredis"
|
||||
import morgan from "morgan"
|
||||
import path from "path"
|
||||
import { configManager } from "../config"
|
||||
import { logger } from "../logger"
|
||||
import { MedusaRequest, MedusaResponse } from "./types"
|
||||
|
||||
const NOISY_ENDPOINTS_CHUNKS = ["@fs", "@id", "@vite", "@react", "node_modules"]
|
||||
|
||||
const isHealthCheck = (req: MedusaRequest) => req.path === "/health"
|
||||
|
||||
export async function expressLoader({ app }: { app: Express }): Promise<{
|
||||
export async function expressLoader({
|
||||
app,
|
||||
container,
|
||||
}: {
|
||||
app: Express
|
||||
container: MedusaContainer
|
||||
}): Promise<{
|
||||
app: Express
|
||||
shutdown: () => Promise<void>
|
||||
}> {
|
||||
@@ -25,6 +32,7 @@ export async function expressLoader({ app }: { app: Express }): Promise<{
|
||||
const IS_DEV = NODE_ENV.startsWith("dev")
|
||||
const isStaging = NODE_ENV === "staging"
|
||||
const isTest = NODE_ENV === "test"
|
||||
const logger = container.resolve(ContainerRegistrationKeys.LOGGER)
|
||||
|
||||
let sameSite: string | boolean = false
|
||||
let secure = false
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
import logger from "@medusajs/cli/dist/reporter"
|
||||
import { ContainerRegistrationKeys, parseCorsOrigins } from "@medusajs/utils"
|
||||
import cors, { CorsOptions } from "cors"
|
||||
import { parseCorsOrigins } from "@medusajs/utils"
|
||||
import type { Express, RequestHandler, ErrorRequestHandler } from "express"
|
||||
import type { ErrorRequestHandler, Express, RequestHandler } from "express"
|
||||
import type {
|
||||
AdditionalDataValidatorRoute,
|
||||
BodyParserConfigRoute,
|
||||
MedusaNextFunction,
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
MiddlewareDescriptor,
|
||||
MiddlewareFunction,
|
||||
MiddlewareVerb,
|
||||
RouteDescriptor,
|
||||
MiddlewareFunction,
|
||||
MedusaNextFunction,
|
||||
MiddlewareDescriptor,
|
||||
BodyParserConfigRoute,
|
||||
RouteHandler,
|
||||
AdditionalDataValidatorRoute,
|
||||
} from "./types"
|
||||
|
||||
import { RoutesLoader } from "./routes-loader"
|
||||
import { RoutesFinder } from "./routes-finder"
|
||||
import { RoutesSorter } from "./routes-sorter"
|
||||
import { wrapHandler } from "./utils/wrap-handler"
|
||||
import { authenticate, AuthType } from "./middlewares"
|
||||
import { errorHandler } from "./middlewares/error-handler"
|
||||
import { RestrictedFields } from "./utils/restricted-fields"
|
||||
import { Logger, MedusaContainer } from "@medusajs/types"
|
||||
import { configManager } from "../config"
|
||||
import { MiddlewareFileLoader } from "./middleware-file-loader"
|
||||
import { authenticate, AuthType } from "./middlewares"
|
||||
import { createBodyParserMiddlewaresStack } from "./middlewares/bodyparser"
|
||||
import { ensurePublishableApiKeyMiddleware } from "./middlewares/ensure-publishable-api-key"
|
||||
import { configManager } from "../config"
|
||||
import { errorHandler } from "./middlewares/error-handler"
|
||||
import { RoutesFinder } from "./routes-finder"
|
||||
import { RoutesLoader } from "./routes-loader"
|
||||
import { RoutesSorter } from "./routes-sorter"
|
||||
import { RestrictedFields } from "./utils/restricted-fields"
|
||||
import { wrapHandler } from "./utils/wrap-handler"
|
||||
|
||||
export class ApiLoader {
|
||||
/**
|
||||
@@ -58,18 +58,23 @@ export class ApiLoader {
|
||||
*/
|
||||
readonly #sourceDirs: string[]
|
||||
|
||||
readonly #logger: Logger
|
||||
|
||||
constructor({
|
||||
app,
|
||||
sourceDir,
|
||||
baseRestrictedFields = [],
|
||||
container,
|
||||
}: {
|
||||
app: Express
|
||||
sourceDir: string | string[]
|
||||
baseRestrictedFields?: string[]
|
||||
container: MedusaContainer
|
||||
}) {
|
||||
this.#app = app
|
||||
this.#sourceDirs = Array.isArray(sourceDir) ? sourceDir : [sourceDir]
|
||||
this.#assignRestrictedFields(baseRestrictedFields ?? [])
|
||||
this.#logger = container.resolve(ContainerRegistrationKeys.LOGGER)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +110,7 @@ export class ApiLoader {
|
||||
route: MiddlewareDescriptor | RouteDescriptor | RouteDescriptor
|
||||
) {
|
||||
if ("isRoute" in route) {
|
||||
logger.debug(`registering route ${route.method} ${route.matcher}`)
|
||||
this.#logger.debug(`registering route ${route.method} ${route.matcher}`)
|
||||
const handler = ApiLoader.traceRoute
|
||||
? ApiLoader.traceRoute(route.handler, {
|
||||
route: route.matcher,
|
||||
@@ -118,7 +123,7 @@ export class ApiLoader {
|
||||
}
|
||||
|
||||
if (!route.methods) {
|
||||
logger.debug(`registering global middleware for ${route.matcher}`)
|
||||
this.#logger.debug(`registering global middleware for ${route.matcher}`)
|
||||
const handler = ApiLoader.traceMiddleware
|
||||
? (ApiLoader.traceMiddleware(route.handler, {
|
||||
route: route.matcher,
|
||||
@@ -133,7 +138,9 @@ export class ApiLoader {
|
||||
? route.methods
|
||||
: [route.methods]
|
||||
methods.forEach((method) => {
|
||||
logger.debug(`registering route middleware ${method} ${route.matcher}`)
|
||||
this.#logger.debug(
|
||||
`registering route middleware ${method} ${route.matcher}`
|
||||
)
|
||||
const handler = ApiLoader.traceMiddleware
|
||||
? (ApiLoader.traceMiddleware(wrapHandler(route.handler), {
|
||||
route: route.matcher,
|
||||
@@ -192,6 +199,7 @@ export class ApiLoader {
|
||||
| "shouldAppendStoreCors",
|
||||
corsOptions: CorsOptions
|
||||
) {
|
||||
const logger = this.#logger
|
||||
const corsFn = cors(corsOptions)
|
||||
const corsMiddleware: RequestHandler = function corsMiddleware(
|
||||
req,
|
||||
@@ -234,6 +242,7 @@ export class ApiLoader {
|
||||
authType: AuthType | AuthType[],
|
||||
options?: { allowUnauthenticated?: boolean; allowUnregistered?: boolean }
|
||||
) {
|
||||
const logger = this.#logger
|
||||
logger.debug(`Registering auth middleware for prefix ${namespace}`)
|
||||
|
||||
const originalFn = authenticate(actorType, authType, options)
|
||||
@@ -273,7 +282,9 @@ export class ApiLoader {
|
||||
namespace: string,
|
||||
routesFinder: RoutesFinder<BodyParserConfigRoute>
|
||||
): void {
|
||||
logger.debug(`Registering bodyparser middleware for prefix ${namespace}`)
|
||||
this.#logger.debug(
|
||||
`Registering bodyparser middleware for prefix ${namespace}`
|
||||
)
|
||||
this.#app.use(
|
||||
namespace,
|
||||
createBodyParserMiddlewaresStack(
|
||||
@@ -292,6 +303,7 @@ export class ApiLoader {
|
||||
namespace: string,
|
||||
routesFinder: RoutesFinder<AdditionalDataValidatorRoute>
|
||||
) {
|
||||
const logger = this.#logger
|
||||
logger.debug(
|
||||
`Registering assignAdditionalDataValidator middleware for prefix ${namespace}`
|
||||
)
|
||||
@@ -329,7 +341,7 @@ export class ApiLoader {
|
||||
* a `x-publishable-key` header
|
||||
*/
|
||||
#applyStorePublishableKeyMiddleware(namespace: string) {
|
||||
logger.debug(
|
||||
this.#logger.debug(
|
||||
`Registering publishable key middleware for namespace ${namespace}`
|
||||
)
|
||||
let middleware = ApiLoader.traceMiddleware
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { join } from "path"
|
||||
import { WorkflowManager, WorkflowScheduler } from "@medusajs/orchestration"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
createMedusaContainer,
|
||||
} from "@medusajs/utils"
|
||||
import { asValue } from "awilix"
|
||||
import { join } from "path"
|
||||
import { logger } from "../../logger"
|
||||
import { MockSchedulerStorage } from "../__fixtures__/mock-scheduler-storage"
|
||||
import { JobLoader } from "../job-loader"
|
||||
|
||||
@@ -11,8 +17,12 @@ describe("register jobs", () => {
|
||||
})
|
||||
|
||||
it("should registers jobs from plugins", async () => {
|
||||
const container = createMedusaContainer()
|
||||
container.register(ContainerRegistrationKeys.LOGGER, asValue(logger))
|
||||
|
||||
const jobLoader: JobLoader = new JobLoader(
|
||||
join(__dirname, "../__fixtures__/plugin/jobs")
|
||||
join(__dirname, "../__fixtures__/plugin/jobs"),
|
||||
container
|
||||
)
|
||||
await jobLoader.load()
|
||||
const workflow = WorkflowManager.getWorkflow("job-summarize-orders")
|
||||
@@ -24,8 +34,12 @@ describe("register jobs", () => {
|
||||
})
|
||||
|
||||
it("should not load non js/ts files", async () => {
|
||||
const container = createMedusaContainer()
|
||||
container.register(ContainerRegistrationKeys.LOGGER, asValue(logger))
|
||||
|
||||
const jobLoader: JobLoader = new JobLoader(
|
||||
join(__dirname, "../__fixtures__/plugin/jobs-with-other-files")
|
||||
join(__dirname, "../__fixtures__/plugin/jobs-with-other-files"),
|
||||
container
|
||||
)
|
||||
await jobLoader.load()
|
||||
const workflow = WorkflowManager.getWorkflow("job-summarize-orders")
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
createWorkflow,
|
||||
StepResponse,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { logger } from "../logger"
|
||||
import { ResourceLoader } from "../utils/resource-loader"
|
||||
|
||||
type CronJobConfig = {
|
||||
@@ -20,8 +19,8 @@ type CronJobHandler = (container: MedusaContainer) => Promise<any>
|
||||
export class JobLoader extends ResourceLoader {
|
||||
protected resourceName = "job"
|
||||
|
||||
constructor(sourceDir: string | string[]) {
|
||||
super(sourceDir)
|
||||
constructor(sourceDir: string | string[], container: MedusaContainer) {
|
||||
super(sourceDir, container)
|
||||
}
|
||||
|
||||
protected async onFileLoaded(
|
||||
@@ -36,7 +35,7 @@ export class JobLoader extends ResourceLoader {
|
||||
}
|
||||
|
||||
this.validateConfig(fileExports.config)
|
||||
logger.debug(`Registering job from ${path}.`)
|
||||
this.logger.debug(`Registering job from ${path}.`)
|
||||
this.register({
|
||||
config: fileExports.config,
|
||||
handler: fileExports.default,
|
||||
@@ -96,7 +95,7 @@ export class JobLoader extends ResourceLoader {
|
||||
const res = await handler(container)
|
||||
return new StepResponse(res, res)
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
this.logger.error(
|
||||
`Scheduled job ${config.name} failed with error: ${error.message}`
|
||||
)
|
||||
throw error
|
||||
@@ -125,6 +124,6 @@ export class JobLoader extends ResourceLoader {
|
||||
async load() {
|
||||
await super.discoverResources()
|
||||
|
||||
logger.debug(`Jobs registered.`)
|
||||
this.logger.debug(`Jobs registered.`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Logger } from "@medusajs/types"
|
||||
import { dynamicImport, promiseAll, readDirRecursive } from "@medusajs/utils"
|
||||
import { Dirent } from "fs"
|
||||
import { access } from "fs/promises"
|
||||
import { join } from "path"
|
||||
import { logger } from "../logger"
|
||||
import { logger as defaultLogger } from "../logger"
|
||||
|
||||
export class LinkLoader {
|
||||
/**
|
||||
@@ -23,8 +24,11 @@ export class LinkLoader {
|
||||
/^_[^/\\]*(\.[^/\\]+)?$/,
|
||||
]
|
||||
|
||||
constructor(sourceDir: string | string[]) {
|
||||
#logger: Logger
|
||||
|
||||
constructor(sourceDir: string | string[], logger?: Logger) {
|
||||
this.#sourceDir = sourceDir
|
||||
this.#logger = logger ?? defaultLogger
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +44,7 @@ export class LinkLoader {
|
||||
try {
|
||||
await access(sourcePath)
|
||||
} catch {
|
||||
logger.info(`No link to load from ${sourcePath}. skipped.`)
|
||||
this.#logger.info(`No link to load from ${sourcePath}. skipped.`)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -52,7 +56,7 @@ export class LinkLoader {
|
||||
)
|
||||
})
|
||||
|
||||
logger.debug(`Registering links from ${sourcePath}.`)
|
||||
this.#logger.debug(`Registering links from ${sourcePath}.`)
|
||||
|
||||
return await promiseAll(
|
||||
fileEntries.map(async (entry: Dirent) => {
|
||||
@@ -65,6 +69,6 @@ export class LinkLoader {
|
||||
|
||||
await promiseAll(promises)
|
||||
|
||||
logger.debug(`Links registered.`)
|
||||
this.#logger.debug(`Links registered.`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Modules } from "@medusajs/utils"
|
||||
import { ContainerRegistrationKeys, Modules } from "@medusajs/utils"
|
||||
import { asValue } from "awilix"
|
||||
import { join } from "path"
|
||||
import { container } from "../../container"
|
||||
import { logger } from "../../logger"
|
||||
import { eventBusServiceMock } from "../__mocks__"
|
||||
import { SubscriberLoader } from "../subscriber-loader"
|
||||
|
||||
@@ -18,8 +19,13 @@ describe("SubscriberLoader", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
container.register(Modules.EVENT_BUS, asValue(eventBusServiceMock))
|
||||
container.register(ContainerRegistrationKeys.LOGGER, asValue(logger))
|
||||
|
||||
const paths = await new SubscriberLoader(rootDir, pluginOptions).load()
|
||||
const paths = await new SubscriberLoader(
|
||||
rootDir,
|
||||
pluginOptions,
|
||||
container
|
||||
).load()
|
||||
|
||||
if (paths) {
|
||||
registeredPaths = [...registeredPaths, ...paths]
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Event, IEventBusModuleService, Subscriber } from "@medusajs/types"
|
||||
import {
|
||||
Event,
|
||||
IEventBusModuleService,
|
||||
MedusaContainer,
|
||||
Subscriber,
|
||||
} from "@medusajs/types"
|
||||
import { isFileSkipped, kebabCase, Modules } from "@medusajs/utils"
|
||||
import { parse } from "path"
|
||||
|
||||
import { configManager } from "../config"
|
||||
import { container } from "../container"
|
||||
import { logger } from "../logger"
|
||||
import { ResourceLoader } from "../utils/resource-loader"
|
||||
import { SubscriberArgs, SubscriberConfig } from "./types"
|
||||
|
||||
@@ -32,9 +35,10 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
|
||||
constructor(
|
||||
sourceDir: string | string[],
|
||||
options: Record<string, unknown> = {}
|
||||
options: Record<string, unknown> = {},
|
||||
container: MedusaContainer
|
||||
) {
|
||||
super(sourceDir)
|
||||
super(sourceDir, container)
|
||||
this.#pluginOptions = options
|
||||
}
|
||||
|
||||
@@ -48,7 +52,7 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
|
||||
const isValid = this.validateSubscriber(fileExports, path)
|
||||
|
||||
logger.debug(`Registering subscribers from ${path}.`)
|
||||
this.logger.debug(`Registering subscribers from ${path}.`)
|
||||
|
||||
if (!isValid) {
|
||||
return
|
||||
@@ -73,7 +77,7 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
/**
|
||||
* If the handler is not a function, we can't use it
|
||||
*/
|
||||
logger.warn(`The subscriber in ${path} is not a function. skipped.`)
|
||||
this.logger.warn(`The subscriber in ${path} is not a function. skipped.`)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -83,7 +87,9 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
/**
|
||||
* If the subscriber is missing a config, we can't use it
|
||||
*/
|
||||
logger.warn(`The subscriber in ${path} is missing a config. skipped.`)
|
||||
this.logger.warn(
|
||||
`The subscriber in ${path} is missing a config. skipped.`
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -97,7 +103,7 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
`The subscriber in ${path} is missing an event in the config.`
|
||||
)
|
||||
} else {
|
||||
logger.warn(
|
||||
this.logger.warn(
|
||||
`The subscriber in ${path} is missing an event in the config. skipped.`
|
||||
)
|
||||
}
|
||||
@@ -111,7 +117,7 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
/**
|
||||
* If the subscribers event is not a string or an array of strings, we can't use it
|
||||
*/
|
||||
logger.warn(
|
||||
this.logger.warn(
|
||||
`The subscriber in ${path} has an invalid event config. The event must be a string or an array of strings. skipped.`
|
||||
)
|
||||
return false
|
||||
@@ -197,7 +203,7 @@ export class SubscriberLoader extends ResourceLoader {
|
||||
})
|
||||
}
|
||||
|
||||
logger.debug(`Subscribers registered.`)
|
||||
this.logger.debug(`Subscribers registered.`)
|
||||
|
||||
/**
|
||||
* Return the file paths of the registered subscribers, to prevent the
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { dynamicImport, promiseAll, readDirRecursive } from "@medusajs/utils"
|
||||
import { Logger, MedusaContainer } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
dynamicImport,
|
||||
promiseAll,
|
||||
readDirRecursive,
|
||||
} from "@medusajs/utils"
|
||||
import { Dirent } from "fs"
|
||||
import { access } from "fs/promises"
|
||||
import { join, parse } from "path"
|
||||
import { logger } from "../logger"
|
||||
|
||||
export abstract class ResourceLoader {
|
||||
/**
|
||||
@@ -22,8 +27,11 @@ export abstract class ResourceLoader {
|
||||
*/
|
||||
#excludes: RegExp[] = [/^_[^/\\]*(\.[^/\\]+)?$/]
|
||||
|
||||
constructor(sourceDir: string | string[]) {
|
||||
protected logger: Logger
|
||||
|
||||
constructor(sourceDir: string | string[], container: MedusaContainer) {
|
||||
this.#sourceDir = sourceDir
|
||||
this.logger = container.resolve(ContainerRegistrationKeys.LOGGER)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +69,7 @@ export abstract class ResourceLoader {
|
||||
try {
|
||||
await access(sourcePath)
|
||||
} catch {
|
||||
logger.info(
|
||||
this.logger.info(
|
||||
`No ${this.resourceName} to load from ${sourcePath}. skipped.`
|
||||
)
|
||||
return
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
import { join } from "path"
|
||||
import { WorkflowLoader } from "../workflow-loader"
|
||||
import { WorkflowManager } from "@medusajs/orchestration"
|
||||
import { orderWorkflowId } from "../__fixtures__/workflows/order-notifier"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
createMedusaContainer,
|
||||
} from "@medusajs/utils"
|
||||
import { asValue } from "awilix"
|
||||
import { join } from "path"
|
||||
import { logger } from "../../logger"
|
||||
import { productWorkflowId } from "../__fixtures__/workflows/deep-workflows/product-updater"
|
||||
import { orderWorkflowId } from "../__fixtures__/workflows/order-notifier"
|
||||
import { WorkflowLoader } from "../workflow-loader"
|
||||
|
||||
describe("WorkflowLoader", () => {
|
||||
const rootDir = join(__dirname, "../__fixtures__", "workflows")
|
||||
|
||||
beforeAll(async () => {
|
||||
await new WorkflowLoader(rootDir).load()
|
||||
const container = createMedusaContainer()
|
||||
container.register(ContainerRegistrationKeys.LOGGER, asValue(logger))
|
||||
|
||||
await new WorkflowLoader(rootDir, container).load()
|
||||
})
|
||||
|
||||
it("should register each workflow in the '/workflows' folder and sub folder", async () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import { isFileSkipped } from "@medusajs/utils"
|
||||
import { MedusaWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { logger } from "../logger"
|
||||
@@ -6,8 +7,8 @@ import { ResourceLoader } from "../utils/resource-loader"
|
||||
export class WorkflowLoader extends ResourceLoader {
|
||||
protected resourceName = "workflow"
|
||||
|
||||
constructor(sourceDir: string | string[]) {
|
||||
super(sourceDir)
|
||||
constructor(sourceDir: string | string[], container: MedusaContainer) {
|
||||
super(sourceDir, container)
|
||||
}
|
||||
|
||||
protected async onFileLoaded(
|
||||
@@ -35,6 +36,6 @@ export class WorkflowLoader extends ResourceLoader {
|
||||
async load() {
|
||||
await super.discoverResources()
|
||||
|
||||
logger.debug(`Workflows registered.`)
|
||||
this.logger.debug(`Workflows registered.`)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user