feat(medusa): Prevent build command from throwing on missing config (#14540)
**What** Prevent the build command from failing on mising config
This commit is contained in:
committed by
GitHub
parent
250b6fdf22
commit
8890f28470
@@ -38,4 +38,35 @@ describe("configLoader", () => {
|
||||
expect(configModule.projectConfig.databaseName).toBe("foo")
|
||||
expect(configModule.projectConfig.workerMode).toBe("worker")
|
||||
})
|
||||
|
||||
it("should load config without throwing errors when throwOnError is false", async () => {
|
||||
await configLoader(entryDirectory, "medusa-config", {
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
const configModule = container.resolve(
|
||||
ContainerRegistrationKeys.CONFIG_MODULE
|
||||
)
|
||||
|
||||
expect(configModule).toBeDefined()
|
||||
expect(configModule.projectConfig).toBeDefined()
|
||||
})
|
||||
|
||||
it("should pass throwOnError option through to buildHttpConfig", async () => {
|
||||
// When throwOnError is false, missing jwtSecret and cookieSecret should not cause errors
|
||||
await configLoader(entryDirectory, "medusa-config-2", {
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
const configModule = container.resolve(
|
||||
ContainerRegistrationKeys.CONFIG_MODULE
|
||||
)
|
||||
|
||||
expect(configModule).toBeDefined()
|
||||
expect(configModule.projectConfig.databaseName).toBe("foo")
|
||||
// http config should still be built with defaults even without throwing errors
|
||||
expect(configModule.projectConfig.http).toBeDefined()
|
||||
expect(configModule.projectConfig.http.jwtSecret).toBe("supersecret")
|
||||
expect(configModule.projectConfig.http.cookieSecret).toBe("supersecret")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -70,8 +70,12 @@ export class ConfigManager {
|
||||
* @protected
|
||||
*/
|
||||
protected buildHttpConfig(
|
||||
projectConfig: Partial<ConfigModule["projectConfig"]>
|
||||
projectConfig: Partial<ConfigModule["projectConfig"]>,
|
||||
options?: {
|
||||
throwOnError?: boolean
|
||||
}
|
||||
): ConfigModule["projectConfig"]["http"] {
|
||||
const { throwOnError = true } = options ?? {}
|
||||
const http = (projectConfig.http ??
|
||||
{}) as ConfigModule["projectConfig"]["http"]
|
||||
|
||||
@@ -87,6 +91,7 @@ export class ConfigManager {
|
||||
http.jwtPublicKey = http?.jwtPublicKey ?? process.env.JWT_PUBLIC_KEY
|
||||
|
||||
if (
|
||||
throwOnError &&
|
||||
http?.jwtPublicKey &&
|
||||
((http.jwtVerifyOptions && !http.jwtVerifyOptions.algorithms?.length) ||
|
||||
(http.jwtOptions && !http.jwtOptions.algorithm))
|
||||
@@ -97,11 +102,13 @@ export class ConfigManager {
|
||||
}
|
||||
|
||||
if (!http.jwtSecret) {
|
||||
this.rejectErrors(
|
||||
`http.jwtSecret not found.${
|
||||
this.#isProduction ? "" : "Using default 'supersecret'."
|
||||
}`
|
||||
)
|
||||
if (throwOnError) {
|
||||
this.rejectErrors(
|
||||
`http.jwtSecret not found.${
|
||||
this.#isProduction ? "" : "Using default 'supersecret'."
|
||||
}`
|
||||
)
|
||||
}
|
||||
|
||||
http.jwtSecret = "supersecret"
|
||||
}
|
||||
@@ -110,11 +117,13 @@ export class ConfigManager {
|
||||
process.env.COOKIE_SECRET)!
|
||||
|
||||
if (!http.cookieSecret) {
|
||||
this.rejectErrors(
|
||||
`http.cookieSecret not found.${
|
||||
this.#isProduction ? "" : " Using default 'supersecret'."
|
||||
}`
|
||||
)
|
||||
if (throwOnError) {
|
||||
this.rejectErrors(
|
||||
`http.cookieSecret not found.${
|
||||
this.#isProduction ? "" : " Using default 'supersecret'."
|
||||
}`
|
||||
)
|
||||
}
|
||||
|
||||
http.cookieSecret = "supersecret"
|
||||
}
|
||||
@@ -128,7 +137,10 @@ export class ConfigManager {
|
||||
* @protected
|
||||
*/
|
||||
protected normalizeProjectConfig(
|
||||
config: Partial<ConfigModule>
|
||||
config: Partial<ConfigModule>,
|
||||
options?: {
|
||||
throwOnError?: boolean
|
||||
}
|
||||
): ConfigModule["projectConfig"] {
|
||||
const projConfig = config?.projectConfig ?? {}
|
||||
const outputConfig = deepCopy(projConfig) as ConfigModule["projectConfig"]
|
||||
@@ -140,7 +152,9 @@ export class ConfigManager {
|
||||
)
|
||||
}
|
||||
|
||||
outputConfig.http = this.buildHttpConfig(projConfig)
|
||||
outputConfig.http = this.buildHttpConfig(projConfig, {
|
||||
throwOnError: options?.throwOnError,
|
||||
})
|
||||
|
||||
let workerMode = outputConfig?.workerMode!
|
||||
|
||||
@@ -168,13 +182,17 @@ export class ConfigManager {
|
||||
loadConfig({
|
||||
projectConfig = {},
|
||||
baseDir,
|
||||
throwOnError = true,
|
||||
}: {
|
||||
projectConfig: Partial<ConfigModule>
|
||||
baseDir: string
|
||||
throwOnError?: boolean
|
||||
}): ConfigModule {
|
||||
this.#baseDir = baseDir
|
||||
|
||||
const normalizedProjectConfig = this.normalizeProjectConfig(projectConfig)
|
||||
const normalizedProjectConfig = this.normalizeProjectConfig(projectConfig, {
|
||||
throwOnError,
|
||||
})
|
||||
|
||||
this.#config = {
|
||||
projectConfig: normalizedProjectConfig,
|
||||
|
||||
@@ -25,22 +25,29 @@ container.register(
|
||||
*
|
||||
* @param entryDirectory The directory to find the config file from
|
||||
* @param configFileName The name of the config file to search for in the entry directory
|
||||
* @param options.throwOnError When false, missing config files and validation errors won't throw.
|
||||
* Useful for build/compile commands. Defaults to true.
|
||||
*/
|
||||
export async function configLoader(
|
||||
entryDirectory: string,
|
||||
configFileName: string = "medusa-config"
|
||||
configFileName: string = "medusa-config",
|
||||
options?: {
|
||||
throwOnError?: boolean
|
||||
}
|
||||
): Promise<ConfigModule> {
|
||||
const { throwOnError = true } = options ?? {}
|
||||
const config = await getConfigFile<ConfigModule>(
|
||||
entryDirectory,
|
||||
configFileName
|
||||
)
|
||||
|
||||
if (config.error) {
|
||||
if (config.error && throwOnError) {
|
||||
handleConfigError(config.error)
|
||||
}
|
||||
|
||||
return configManager.loadConfig({
|
||||
projectConfig: config.configModule!,
|
||||
baseDir: entryDirectory,
|
||||
throwOnError,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user