fix(medusa, modules-sdk): Fix migrate command and fix revert support (#7340)

This commit is contained in:
Adrien de Peretti
2024-05-15 15:46:23 +02:00
committed by GitHub
parent bb2b041954
commit 13ce60b999
4 changed files with 163 additions and 73 deletions
+76 -23
View File
@@ -149,7 +149,7 @@ async function initializeLinks({
moduleExports, moduleExports,
}) { }) {
try { try {
const { initialize, runMigrations } = const { initialize, runMigrations, revertMigrations } =
moduleExports ?? (await import(LinkModulePackage)) moduleExports ?? (await import(LinkModulePackage))
const linkResolution = await initialize( const linkResolution = await initialize(
@@ -158,7 +158,12 @@ async function initializeLinks({
injectedDependencies injectedDependencies
) )
return { remoteLink: new RemoteLink(), linkResolution, runMigrations } return {
remoteLink: new RemoteLink(),
linkResolution,
runMigrations,
revertMigrations,
}
} catch (err) { } catch (err) {
console.warn("Error initializing link modules.", err) console.warn("Error initializing link modules.", err)
@@ -209,6 +214,7 @@ export type MedusaAppOutput = {
entitiesMap?: Record<string, any> entitiesMap?: Record<string, any>
notFound?: Record<string, Record<string, string>> notFound?: Record<string, Record<string, string>>
runMigrations: RunMigrationFn runMigrations: RunMigrationFn
revertMigrations: RunMigrationFn
onApplicationShutdown: () => Promise<void> onApplicationShutdown: () => Promise<void>
onApplicationPrepareShutdown: () => Promise<void> onApplicationPrepareShutdown: () => Promise<void>
} }
@@ -333,6 +339,9 @@ async function MedusaApp_({
runMigrations: async () => { runMigrations: async () => {
throw new Error("Migrations not allowed in loaderOnly mode") throw new Error("Migrations not allowed in loaderOnly mode")
}, },
revertMigrations: async () => {
throw new Error("Revert migrations not allowed in loaderOnly mode")
},
} }
} }
@@ -342,13 +351,16 @@ async function MedusaApp_({
allowUnregistered: true, allowUnregistered: true,
}) })
const { remoteLink, runMigrations: linkModuleMigration } = const {
await initializeLinks({ remoteLink,
config: linkModuleOptions, runMigrations: linkModuleMigration,
linkModules, revertMigrations: revertLinkModuleMigration,
injectedDependencies, } = await initializeLinks({
moduleExports: isMedusaModule(linkModule) ? linkModule : undefined, config: linkModuleOptions,
}) linkModules,
injectedDependencies,
moduleExports: isMedusaModule(linkModule) ? linkModule : undefined,
})
const loadedSchema = getLoadedSchema() const loadedSchema = getLoadedSchema()
const { schema, notFound } = cleanAndMergeSchema(loadedSchema) const { schema, notFound } = cleanAndMergeSchema(loadedSchema)
@@ -366,9 +378,7 @@ async function MedusaApp_({
return await remoteQuery.query(query, variables, options) return await remoteQuery.query(query, variables, options)
} }
const runMigrations: RunMigrationFn = async ( const applyMigration = async (linkModuleOptions, revert = false) => {
linkModuleOptions
): Promise<void> => {
for (const moduleName of Object.keys(allModules)) { for (const moduleName of Object.keys(allModules)) {
const moduleResolution = MedusaModule.getModuleResolutions(moduleName) const moduleResolution = MedusaModule.getModuleResolutions(moduleName)
@@ -379,12 +389,21 @@ async function MedusaApp_({
} }
} }
await MedusaModule.migrateUp( if (!revert) {
moduleResolution.definition.key, await MedusaModule.migrateUp(
moduleResolution.resolutionPath as string, moduleResolution.definition.key,
moduleResolution.options, moduleResolution.resolutionPath as string,
moduleResolution.moduleExports moduleResolution.options,
) moduleResolution.moduleExports
)
} else {
await MedusaModule.migrateDown(
moduleResolution.definition.key,
moduleResolution.resolutionPath as string,
moduleResolution.options,
moduleResolution.moduleExports
)
}
} }
const linkModuleOpt = { ...(linkModuleOptions ?? {}) } const linkModuleOpt = { ...(linkModuleOptions ?? {}) }
@@ -392,11 +411,31 @@ async function MedusaApp_({
...(sharedResourcesConfig?.database ?? {}), ...(sharedResourcesConfig?.database ?? {}),
} }
linkModuleMigration && if (!revert) {
(await linkModuleMigration({ linkModuleMigration &&
options: linkModuleOpt, (await linkModuleMigration({
injectedDependencies, options: linkModuleOpt,
})) injectedDependencies,
}))
} else {
revertLinkModuleMigration &&
(await revertLinkModuleMigration({
options: linkModuleOpt,
injectedDependencies,
}))
}
}
const runMigrations: RunMigrationFn = async (
linkModuleOptions
): Promise<void> => {
await applyMigration(linkModuleOptions)
}
const revertMigrations: RunMigrationFn = async (
linkModuleOptions
): Promise<void> => {
await applyMigration(linkModuleOptions, true)
} }
return { return {
@@ -408,6 +447,7 @@ async function MedusaApp_({
entitiesMap: schema.getTypeMap(), entitiesMap: schema.getTypeMap(),
notFound, notFound,
runMigrations, runMigrations,
revertMigrations,
} }
} }
@@ -433,3 +473,16 @@ export async function MedusaAppMigrateUp(
await runMigrations().finally(MedusaModule.clearInstances) await runMigrations().finally(MedusaModule.clearInstances)
} }
export async function MedusaAppMigrateDown(
options: MedusaAppOptions = {}
): Promise<void> {
const migrationOnly = true
const { revertMigrations } = await MedusaApp_({
...options,
migrationOnly,
})
await revertMigrations().finally(MedusaModule.clearInstances)
}
+19 -46
View File
@@ -1,41 +1,16 @@
import { asValue, createContainer } from "awilix" import { asValue } from "awilix"
import getMigrations, { import { revertIsolatedModulesMigration } from "./utils/get-migrations"
getModuleSharedResources,
revertIsolatedModulesMigration,
} from "./utils/get-migrations"
import { import {
ContainerRegistrationKeys, ContainerRegistrationKeys,
createMedusaContainer, createMedusaContainer,
} from "@medusajs/utils" } from "@medusajs/utils"
import configModuleLoader from "../loaders/config" import configModuleLoader from "../loaders/config"
import databaseLoader from "../loaders/database"
import featureFlagLoader from "../loaders/feature-flags" import featureFlagLoader from "../loaders/feature-flags"
import Logger from "../loaders/logger" import Logger from "../loaders/logger"
import { migrateMedusaApp, loadMedusaApp } from "../loaders/medusa-app" import { loadMedusaApp, migrateMedusaApp } from "../loaders/medusa-app"
import pgConnectionLoader from "../loaders/pg-connection" import pgConnectionLoader from "../loaders/pg-connection"
import { MedusaAppMigrateDown } from "@medusajs/modules-sdk"
const getDataSource = async (directory) => {
const configModule = configModuleLoader(directory)
const featureFlagRouter = featureFlagLoader(configModule)
const { coreMigrations } = getMigrations(directory, featureFlagRouter)
const { migrations: moduleMigrations } = getModuleSharedResources(
configModule,
featureFlagRouter
)
const container = createContainer()
container.register("db_entities", asValue([]))
return await databaseLoader({
container,
configModule,
customOptions: {
migrations: coreMigrations.concat(moduleMigrations),
logging: "all",
},
})
}
const runLinkMigrations = async (directory) => { const runLinkMigrations = async (directory) => {
const configModule = configModuleLoader(directory) const configModule = configModuleLoader(directory)
@@ -72,16 +47,16 @@ const main = async function ({ directory }) {
const configModule = configModuleLoader(directory) const configModule = configModuleLoader(directory)
const featureFlagRouter = featureFlagLoader(configModule) const featureFlagRouter = featureFlagLoader(configModule)
const container = createMedusaContainer()
const pgConnection = await pgConnectionLoader({ configModule, container })
container.register({
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
[ContainerRegistrationKeys.LOGGER]: asValue(Logger),
[ContainerRegistrationKeys.PG_CONNECTION]: asValue(pgConnection),
[ContainerRegistrationKeys.FEATURE_FLAG_ROUTER]: asValue(featureFlagRouter),
})
if (args[0] === "run") { if (args[0] === "run") {
const container = createMedusaContainer()
const pgConnection = await pgConnectionLoader({ configModule, container })
container.register({
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
[ContainerRegistrationKeys.LOGGER]: asValue(Logger),
[ContainerRegistrationKeys.PG_CONNECTION]: asValue(pgConnection),
[ContainerRegistrationKeys.FEATURE_FLAG_ROUTER]:
asValue(featureFlagRouter),
})
await migrateMedusaApp( await migrateMedusaApp(
{ configModule, container }, { configModule, container },
{ registerInContainer: false } { registerInContainer: false }
@@ -90,17 +65,15 @@ const main = async function ({ directory }) {
Logger.info("Migrations completed.") Logger.info("Migrations completed.")
process.exit() process.exit()
} else if (args[0] === "revert") { } else if (args[0] === "revert") {
const dataSource = await getDataSource(directory) await MedusaAppMigrateDown(
await dataSource.undoLastMigration({ transaction: "all" }) { configModule, container },
await dataSource.destroy() { registerInContainer: false }
)
await revertIsolatedModulesMigration(configModule) await revertIsolatedModulesMigration(configModule)
Logger.info("Migrations reverted.") Logger.info("Migrations reverted.")
} else if (args[0] === "show") { } else if (args[0] === "show") {
const dataSource = await getDataSource(directory) Logger.info("not supported")
const unapplied = await dataSource.showMigrations() process.exit(0)
Logger.info(unapplied)
await dataSource.destroy()
process.exit(unapplied ? 1 : 0)
} }
} }
@@ -22,7 +22,7 @@ import {
toPascalCase, toPascalCase,
} from "@medusajs/utils" } from "@medusajs/utils"
import * as linkDefinitions from "../definitions" import * as linkDefinitions from "../definitions"
import { getMigration } from "../migration" import { getMigration, getRevertMigration } from "../migration"
import { InitializeModuleInjectableDependencies } from "../types" import { InitializeModuleInjectableDependencies } from "../types"
import { import {
composeLinkName, composeLinkName,
@@ -164,12 +164,13 @@ export const initialize = async (
return allLinks return allLinks
} }
export async function runMigrations( async function applyMigrationUpOrDown(
{ {
options, options,
logger, logger,
}: Omit<LoaderOptions<ModuleServiceInitializeOptions>, "container">, }: Omit<LoaderOptions<ModuleServiceInitializeOptions>, "container">,
modulesDefinition?: ModuleJoinerConfig[] modulesDefinition?: ModuleJoinerConfig[],
revert = false
) { ) {
const modulesLoadedKeys = MedusaModule.getLoadedModules().map( const modulesLoadedKeys = MedusaModule.getLoadedModules().map(
(mod) => Object.keys(mod)[0] (mod) => Object.keys(mod)[0]
@@ -215,7 +216,29 @@ export async function runMigrations(
continue continue
} }
const migrate = getMigration(definition, serviceKey, primary, foreign) const migrate = revert
? getRevertMigration(definition, serviceKey, primary, foreign)
: getMigration(definition, serviceKey, primary, foreign)
await migrate({ options, logger }) await migrate({ options, logger })
} }
} }
export async function runMigrations(
{
options,
logger,
}: Omit<LoaderOptions<ModuleServiceInitializeOptions>, "container">,
modulesDefinition?: ModuleJoinerConfig[]
) {
await applyMigrationUpOrDown({ options, logger }, modulesDefinition)
}
export async function revertMigrations(
{
options,
logger,
}: Omit<LoaderOptions<ModuleServiceInitializeOptions>, "container">,
modulesDefinition?: ModuleJoinerConfig[]
) {
await applyMigrationUpOrDown({ options, logger }, modulesDefinition, true)
}
@@ -84,3 +84,44 @@ export function getMigration(
await orm.close() await orm.close()
} }
} }
export function getRevertMigration(
joinerConfig: ModuleJoinerConfig,
serviceName: string,
primary: JoinerRelationship,
foreign: JoinerRelationship
) {
return async function revertMigrations(
{
options,
logger,
}: Pick<
LoaderOptions<ModuleServiceInitializeOptions>,
"options" | "logger"
> = {} as any
) {
logger ??= console as unknown as Logger
const dbData = ModulesSdkUtils.loadDatabaseConfig("link_modules", options)
const entity = generateEntity(joinerConfig, primary, foreign)
const pathToMigrations = __dirname + "/../migrations"
const orm = await DALUtils.mikroOrmCreateConnection(
dbData,
[entity],
pathToMigrations
)
try {
const migrator = orm.getMigrator()
await migrator.down()
logger.info(`Link module "${serviceName}" migration executed`)
} catch (error) {
logger.error(
`Link module "${serviceName}" migration failed to run - Error: ${error}`
)
}
await orm.close()
}
}