Feat: Improvements to the migrations CLI and workflow (#8060)
This commit is contained in:
@@ -180,7 +180,6 @@ export async function loadModuleMigrations(
|
||||
let runMigrations = loadedModule.runMigrations
|
||||
let revertMigration = loadedModule.revertMigration
|
||||
|
||||
// Generate migration scripts if they are not present
|
||||
if (!runMigrations || !revertMigration) {
|
||||
const moduleResources = await loadResources(
|
||||
resolution,
|
||||
@@ -190,8 +189,7 @@ export async function loadModuleMigrations(
|
||||
|
||||
const migrationScriptOptions = {
|
||||
moduleName: resolution.definition.key,
|
||||
models: moduleResources.models,
|
||||
pathToMigrations: moduleResources.normalizedPath + "/migrations",
|
||||
pathToMigrations: join(moduleResources.normalizedPath, "migrations"),
|
||||
}
|
||||
|
||||
runMigrations ??= ModulesSdkUtils.buildMigrationScript(
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
LoadedModule,
|
||||
Logger,
|
||||
MedusaContainer,
|
||||
ModuleBootstrapDeclaration,
|
||||
ModuleDefinition,
|
||||
ModuleExports,
|
||||
ModuleJoinerConfig,
|
||||
@@ -21,6 +22,7 @@ import {
|
||||
createMedusaContainer,
|
||||
isObject,
|
||||
isString,
|
||||
MedusaError,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
ModulesSdkUtils,
|
||||
@@ -47,10 +49,8 @@ declare module "@medusajs/types" {
|
||||
}
|
||||
}
|
||||
|
||||
export type RunMigrationFn = (
|
||||
options?: ModuleServiceInitializeOptions,
|
||||
injectedDependencies?: Record<any, any>
|
||||
) => Promise<void>
|
||||
export type RunMigrationFn = () => Promise<void>
|
||||
export type RevertMigrationFn = (moduleNames: string[]) => Promise<void>
|
||||
|
||||
export type MedusaModuleConfig = {
|
||||
[key: string | Modules]:
|
||||
@@ -176,11 +176,11 @@ async function initializeLinks({
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Error initializing link modules.", err)
|
||||
|
||||
return {
|
||||
remoteLink: undefined,
|
||||
linkResolution: undefined,
|
||||
runMigrations: undefined,
|
||||
runMigrations: () => void 0,
|
||||
revertMigrations: () => void 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,7 +224,7 @@ export type MedusaAppOutput = {
|
||||
entitiesMap?: Record<string, any>
|
||||
notFound?: Record<string, Record<string, string>>
|
||||
runMigrations: RunMigrationFn
|
||||
revertMigrations: RunMigrationFn
|
||||
revertMigrations: RevertMigrationFn
|
||||
onApplicationShutdown: () => Promise<void>
|
||||
onApplicationPrepareShutdown: () => Promise<void>
|
||||
sharedContainer?: MedusaContainer
|
||||
@@ -317,10 +317,12 @@ async function MedusaApp_({
|
||||
delete modules[LinkModulePackage]
|
||||
delete modules[Modules.LINK]
|
||||
|
||||
let linkModuleOptions = {}
|
||||
let linkModuleOrOptions:
|
||||
| Partial<ModuleServiceInitializeOptions>
|
||||
| Partial<ModuleBootstrapDeclaration> = {}
|
||||
|
||||
if (isObject(linkModule)) {
|
||||
linkModuleOptions = linkModule
|
||||
linkModuleOrOptions = linkModule
|
||||
}
|
||||
|
||||
for (const injectedDependency of Object.keys(injectedDependencies)) {
|
||||
@@ -380,7 +382,7 @@ async function MedusaApp_({
|
||||
runMigrations: linkModuleMigration,
|
||||
revertMigrations: revertLinkModuleMigration,
|
||||
} = await initializeLinks({
|
||||
config: linkModuleOptions,
|
||||
config: linkModuleOrOptions,
|
||||
linkModules,
|
||||
injectedDependencies,
|
||||
moduleExports: isMedusaModule(linkModule) ? linkModule : undefined,
|
||||
@@ -402,10 +404,38 @@ async function MedusaApp_({
|
||||
return await remoteQuery.query(query, variables, options)
|
||||
}
|
||||
|
||||
const applyMigration = async (linkModuleOptions, revert = false) => {
|
||||
for (const moduleName of Object.keys(allModules)) {
|
||||
const moduleResolution = MedusaModule.getModuleResolutions(moduleName)
|
||||
const applyMigration = async ({
|
||||
modulesNames,
|
||||
revert = false,
|
||||
}: {
|
||||
modulesNames: string[]
|
||||
revert?: boolean
|
||||
}) => {
|
||||
const moduleResolutions = modulesNames.map((moduleName) => {
|
||||
return {
|
||||
moduleName,
|
||||
resolution: MedusaModule.getModuleResolutions(moduleName),
|
||||
}
|
||||
})
|
||||
|
||||
const missingModules = moduleResolutions
|
||||
.filter(({ resolution }) => !resolution)
|
||||
.map(({ moduleName }) => moduleName)
|
||||
|
||||
if (missingModules.length) {
|
||||
const action = revert ? "revert" : "run"
|
||||
const error = new MedusaError(
|
||||
MedusaError.Types.UNKNOWN_MODULES,
|
||||
`Cannot ${action} migrations for unknown module(s) ${missingModules.join(
|
||||
","
|
||||
)}`,
|
||||
MedusaError.Codes.UNKNOWN_MODULES
|
||||
)
|
||||
error["allModules"] = Object.keys(allModules)
|
||||
throw error
|
||||
}
|
||||
|
||||
for (const { resolution: moduleResolution } of moduleResolutions) {
|
||||
if (!moduleResolution.options?.database) {
|
||||
moduleResolution.options ??= {}
|
||||
moduleResolution.options.database = {
|
||||
@@ -417,6 +447,7 @@ async function MedusaApp_({
|
||||
await MedusaModule.migrateDown(
|
||||
moduleResolution.definition.key,
|
||||
moduleResolution.resolutionPath as string,
|
||||
sharedContainer,
|
||||
moduleResolution.options,
|
||||
moduleResolution.moduleExports
|
||||
)
|
||||
@@ -424,48 +455,65 @@ async function MedusaApp_({
|
||||
await MedusaModule.migrateUp(
|
||||
moduleResolution.definition.key,
|
||||
moduleResolution.resolutionPath as string,
|
||||
sharedContainer,
|
||||
moduleResolution.options,
|
||||
moduleResolution.moduleExports
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const linkModuleOpt = { ...(linkModuleOptions ?? {}) }
|
||||
linkModuleOpt.database ??= {
|
||||
...(sharedResourcesConfig?.database ?? {}),
|
||||
}
|
||||
|
||||
if (revert) {
|
||||
revertLinkModuleMigration &&
|
||||
(await revertLinkModuleMigration(
|
||||
{
|
||||
options: linkModuleOpt,
|
||||
injectedDependencies,
|
||||
},
|
||||
linkModules
|
||||
))
|
||||
} else {
|
||||
linkModuleMigration &&
|
||||
(await linkModuleMigration(
|
||||
{
|
||||
options: linkModuleOpt,
|
||||
injectedDependencies,
|
||||
},
|
||||
linkModules
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
const runMigrations: RunMigrationFn = async (
|
||||
linkModuleOptions
|
||||
): Promise<void> => {
|
||||
await applyMigration(linkModuleOptions)
|
||||
const runMigrations: RunMigrationFn = async (): Promise<void> => {
|
||||
await applyMigration({
|
||||
modulesNames: Object.keys(allModules),
|
||||
})
|
||||
|
||||
const options: Partial<ModuleServiceInitializeOptions> =
|
||||
"scope" in linkModuleOrOptions
|
||||
? { ...linkModuleOrOptions.options }
|
||||
: {
|
||||
...(linkModuleOrOptions as Partial<ModuleServiceInitializeOptions>),
|
||||
}
|
||||
|
||||
options.database ??= {
|
||||
...sharedResourcesConfig?.database,
|
||||
}
|
||||
|
||||
await linkModuleMigration(
|
||||
{
|
||||
options,
|
||||
injectedDependencies,
|
||||
},
|
||||
linkModules
|
||||
)
|
||||
}
|
||||
|
||||
const revertMigrations: RunMigrationFn = async (
|
||||
linkModuleOptions
|
||||
const revertMigrations: RevertMigrationFn = async (
|
||||
modulesNames
|
||||
): Promise<void> => {
|
||||
await applyMigration(linkModuleOptions, true)
|
||||
await applyMigration({
|
||||
modulesNames,
|
||||
revert: true,
|
||||
})
|
||||
|
||||
const options: Partial<ModuleServiceInitializeOptions> =
|
||||
"scope" in linkModuleOrOptions
|
||||
? { ...linkModuleOrOptions.options }
|
||||
: {
|
||||
...(linkModuleOrOptions as Partial<ModuleServiceInitializeOptions>),
|
||||
}
|
||||
|
||||
options.database ??= {
|
||||
...sharedResourcesConfig?.database,
|
||||
}
|
||||
|
||||
await revertLinkModuleMigration(
|
||||
{
|
||||
options,
|
||||
injectedDependencies,
|
||||
},
|
||||
linkModules
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -506,6 +554,7 @@ export async function MedusaAppMigrateUp(
|
||||
}
|
||||
|
||||
export async function MedusaAppMigrateDown(
|
||||
moduleNames: string[],
|
||||
options: MedusaAppOptions = {}
|
||||
): Promise<void> {
|
||||
const migrationOnly = true
|
||||
@@ -515,5 +564,5 @@ export async function MedusaAppMigrateDown(
|
||||
migrationOnly,
|
||||
})
|
||||
|
||||
await revertMigrations().finally(MedusaModule.clearInstances)
|
||||
await revertMigrations(moduleNames).finally(MedusaModule.clearInstances)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
ModuleResolution,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
createMedusaContainer,
|
||||
promiseAll,
|
||||
simpleHash,
|
||||
@@ -344,7 +345,9 @@ class MedusaModule {
|
||||
)
|
||||
|
||||
const logger_ =
|
||||
container.resolve("logger", { allowUnregistered: true }) ?? logger
|
||||
container.resolve(ContainerRegistrationKeys.LOGGER, {
|
||||
allowUnregistered: true,
|
||||
}) ?? logger
|
||||
|
||||
try {
|
||||
await moduleLoader({
|
||||
@@ -475,7 +478,9 @@ class MedusaModule {
|
||||
)
|
||||
|
||||
const logger_ =
|
||||
container.resolve("logger", { allowUnregistered: true }) ?? logger
|
||||
container.resolve(ContainerRegistrationKeys.LOGGER, {
|
||||
allowUnregistered: true,
|
||||
}) ?? logger
|
||||
|
||||
try {
|
||||
await moduleLoader({
|
||||
@@ -534,6 +539,7 @@ class MedusaModule {
|
||||
public static async migrateUp(
|
||||
moduleKey: string,
|
||||
modulePath: string,
|
||||
container?: MedusaContainer,
|
||||
options?: Record<string, any>,
|
||||
moduleExports?: ModuleExports
|
||||
): Promise<void> {
|
||||
@@ -544,6 +550,11 @@ class MedusaModule {
|
||||
options,
|
||||
})
|
||||
|
||||
const logger_ =
|
||||
container?.resolve(ContainerRegistrationKeys.LOGGER, {
|
||||
allowUnregistered: true,
|
||||
}) ?? logger
|
||||
|
||||
for (const mod in moduleResolutions) {
|
||||
const [migrateUp] = await loadModuleMigrations(
|
||||
moduleResolutions[mod],
|
||||
@@ -553,7 +564,7 @@ class MedusaModule {
|
||||
if (typeof migrateUp === "function") {
|
||||
await migrateUp({
|
||||
options,
|
||||
logger,
|
||||
logger: logger_,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -562,6 +573,7 @@ class MedusaModule {
|
||||
public static async migrateDown(
|
||||
moduleKey: string,
|
||||
modulePath: string,
|
||||
container?: MedusaContainer,
|
||||
options?: Record<string, any>,
|
||||
moduleExports?: ModuleExports
|
||||
): Promise<void> {
|
||||
@@ -572,6 +584,11 @@ class MedusaModule {
|
||||
options,
|
||||
})
|
||||
|
||||
const logger_ =
|
||||
container?.resolve(ContainerRegistrationKeys.LOGGER, {
|
||||
allowUnregistered: true,
|
||||
}) ?? logger
|
||||
|
||||
for (const mod in moduleResolutions) {
|
||||
const [, migrateDown] = await loadModuleMigrations(
|
||||
moduleResolutions[mod],
|
||||
@@ -581,7 +598,7 @@ class MedusaModule {
|
||||
if (typeof migrateDown === "function") {
|
||||
await migrateDown({
|
||||
options,
|
||||
logger,
|
||||
logger: logger_,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user