From 104b00d4e9143c080fdb5d4a9884a237083783ef Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Fri, 12 Jul 2024 13:12:49 +0200 Subject: [PATCH] feat(migrations): CLI generate command (#8103) --- .../environment-helpers/use-db.js | 9 +- packages/cli/medusa-cli/src/create-cli.ts | 4 +- .../src/medusa-test-runner-utils/use-db.ts | 4 +- .../src/loaders/utils/load-internal.ts | 22 +++- packages/core/modules-sdk/src/medusa-app.ts | 70 ++++++++---- .../core/modules-sdk/src/medusa-module.ts | 91 ++++++++++++---- packages/core/types/src/modules-sdk/index.ts | 4 + packages/core/utils/src/migrations/index.ts | 35 ++++++ .../__tests__/migrations-generate.spec.ts | 13 +-- .../modules-sdk/migration-scripts/index.ts | 1 + .../migration-scripts/migration-generate.ts | 63 +++++++++++ packages/medusa/src/commands/migrate.ts | 66 ++++++++--- .../src/commands/utils/get-migrations.js | 20 ++-- packages/medusa/src/loaders/medusa-app.ts | 103 +++++------------- 14 files changed, 341 insertions(+), 164 deletions(-) create mode 100644 packages/core/utils/src/modules-sdk/migration-scripts/migration-generate.ts diff --git a/integration-tests/environment-helpers/use-db.js b/integration-tests/environment-helpers/use-db.js index 20e1f45601..8c86841c05 100644 --- a/integration-tests/environment-helpers/use-db.js +++ b/integration-tests/environment-helpers/use-db.js @@ -11,7 +11,9 @@ const { dropDatabase } = require("pg-god") const { DataSource } = require("typeorm") const dbFactory = require("./use-template-db") const { ContainerRegistrationKeys } = require("@medusajs/utils") -const { migrateMedusaApp } = require("@medusajs/medusa/dist/loaders/medusa-app") +const { + runMedusaAppMigrations, +} = require("@medusajs/medusa/dist/loaders/medusa-app") const DB_HOST = process.env.DB_HOST const DB_USERNAME = process.env.DB_USERNAME @@ -181,10 +183,7 @@ module.exports = { instance.setPgConnection(pgConnection) - await migrateMedusaApp( - { configModule, container }, - { registerInContainer: false } - ) + await runMedusaAppMigrations({ configModule, container }) } return dbDataSource diff --git a/packages/cli/medusa-cli/src/create-cli.ts b/packages/cli/medusa-cli/src/create-cli.ts index 9022c50106..779e43ee4c 100644 --- a/packages/cli/medusa-cli/src/create-cli.ts +++ b/packages/cli/medusa-cli/src/create-cli.ts @@ -176,10 +176,10 @@ function buildLocalCommands(cli, isLocalProject) { action: { demand: true, description: "The action to perform on migrations", - choices: ["run", "revert", "show"], + choices: ["run", "revert", "show", "generate"], }, modules: { - description: "Revert migrations for defined modules", + description: "Modules for which to run the action (revert, generate)", demand: false, }, }, diff --git a/packages/core/medusa-test-utils/src/medusa-test-runner-utils/use-db.ts b/packages/core/medusa-test-utils/src/medusa-test-runner-utils/use-db.ts index bcfa93d29b..9f29260d65 100644 --- a/packages/core/medusa-test-utils/src/medusa-test-runner-utils/use-db.ts +++ b/packages/core/medusa-test-utils/src/medusa-test-runner-utils/use-db.ts @@ -39,9 +39,9 @@ export async function initDb({ try { const { - migrateMedusaApp, + runMedusaAppMigrations, } = require("@medusajs/medusa/dist/loaders/medusa-app") - await migrateMedusaApp({ configModule, container }) + await runMedusaAppMigrations({ configModule, container }) } catch (err) { console.error("Something went wrong while running the migrations") throw err diff --git a/packages/core/modules-sdk/src/loaders/utils/load-internal.ts b/packages/core/modules-sdk/src/loaders/utils/load-internal.ts index 11d35640c8..df25cbacfe 100644 --- a/packages/core/modules-sdk/src/loaders/utils/load-internal.ts +++ b/packages/core/modules-sdk/src/loaders/utils/load-internal.ts @@ -2,6 +2,7 @@ import { Constructor, IModuleService, InternalModuleDeclaration, + LoaderOptions, Logger, MedusaContainer, ModuleExports, @@ -32,6 +33,11 @@ type ModuleResource = { normalizedPath: string } +type MigrationFunction = ( + options: LoaderOptions, + moduleDeclaration?: InternalModuleDeclaration +) => Promise + export async function loadInternalModule( container: MedusaContainer, resolution: ModuleResolution, @@ -171,7 +177,11 @@ export async function loadInternalModule( export async function loadModuleMigrations( resolution: ModuleResolution, moduleExports?: ModuleExports -): Promise<[Function | undefined, Function | undefined]> { +): Promise<{ + runMigrations?: MigrationFunction + revertMigration?: MigrationFunction + generateMigration?: MigrationFunction +}> { let loadedModule: ModuleExports try { loadedModule = @@ -179,6 +189,7 @@ export async function loadModuleMigrations( let runMigrations = loadedModule.runMigrations let revertMigration = loadedModule.revertMigration + let generateMigration = loadedModule.generateMigration if (!runMigrations || !revertMigration) { const moduleResources = await loadResources( @@ -189,6 +200,7 @@ export async function loadModuleMigrations( const migrationScriptOptions = { moduleName: resolution.definition.key, + models: moduleResources.models, pathToMigrations: join(moduleResources.normalizedPath, "migrations"), } @@ -199,11 +211,15 @@ export async function loadModuleMigrations( revertMigration ??= ModulesSdkUtils.buildRevertMigrationScript( migrationScriptOptions ) + + generateMigration ??= ModulesSdkUtils.buildGenerateMigrationScript( + migrationScriptOptions + ) } - return [runMigrations, revertMigration] + return { runMigrations, revertMigration, generateMigration } } catch { - return [undefined, undefined] + return {} } } diff --git a/packages/core/modules-sdk/src/medusa-app.ts b/packages/core/modules-sdk/src/medusa-app.ts index bd68bd9305..d62ec3f063 100644 --- a/packages/core/modules-sdk/src/medusa-app.ts +++ b/packages/core/modules-sdk/src/medusa-app.ts @@ -31,7 +31,11 @@ import { import { asValue } from "awilix" import type { Knex } from "knex" import { MODULE_PACKAGE_NAMES } from "./definitions" -import { MedusaModule, RegisterModuleJoinerConfig } from "./medusa-module" +import { + MedusaModule, + MigrationOptions, + RegisterModuleJoinerConfig, +} from "./medusa-module" import { RemoteLink } from "./remote-link" import { RemoteQuery } from "./remote-query" import { MODULE_RESOURCE_TYPE, MODULE_SCOPE } from "./types" @@ -51,6 +55,7 @@ declare module "@medusajs/types" { export type RunMigrationFn = () => Promise export type RevertMigrationFn = (moduleNames: string[]) => Promise +export type GenerateMigrations = (moduleNames: string[]) => Promise export type MedusaModuleConfig = { [key: string | Modules]: @@ -225,6 +230,7 @@ export type MedusaAppOutput = { notFound?: Record> runMigrations: RunMigrationFn revertMigrations: RevertMigrationFn + generateMigrations: GenerateMigrations onApplicationShutdown: () => Promise onApplicationPrepareShutdown: () => Promise sharedContainer?: MedusaContainer @@ -354,6 +360,9 @@ async function MedusaApp_({ revertMigrations: async () => { throw new Error("Revert migrations not allowed in loaderOnly mode") }, + generateMigrations: async () => { + throw new Error("Generate migrations not allowed in loaderOnly mode") + }, } } @@ -406,10 +415,10 @@ async function MedusaApp_({ const applyMigration = async ({ modulesNames, - revert = false, + action = "run", }: { modulesNames: string[] - revert?: boolean + action?: "run" | "revert" | "generate" }) => { const moduleResolutions = modulesNames.map((moduleName) => { return { @@ -423,7 +432,6 @@ async function MedusaApp_({ .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( @@ -443,22 +451,20 @@ async function MedusaApp_({ } } - if (revert) { - await MedusaModule.migrateDown( - moduleResolution.definition.key, - moduleResolution.resolutionPath as string, - sharedContainer, - moduleResolution.options, - moduleResolution.moduleExports - ) + const migrationOptions: MigrationOptions = { + moduleKey: moduleResolution.definition.key, + modulePath: moduleResolution.resolutionPath as string, + container: sharedContainer, + options: moduleResolution.options, + moduleExports: moduleResolution.moduleExports, + } + + if (action === "revert") { + await MedusaModule.migrateDown(migrationOptions) + } else if (action === "run") { + await MedusaModule.migrateUp(migrationOptions) } else { - await MedusaModule.migrateUp( - moduleResolution.definition.key, - moduleResolution.resolutionPath as string, - sharedContainer, - moduleResolution.options, - moduleResolution.moduleExports - ) + await MedusaModule.migrateGenerate(migrationOptions) } } } @@ -493,7 +499,7 @@ async function MedusaApp_({ ): Promise => { await applyMigration({ modulesNames, - revert: true, + action: "revert", }) const options: Partial = @@ -516,6 +522,15 @@ async function MedusaApp_({ ) } + const generateMigrations: GenerateMigrations = async ( + modulesNames + ): Promise => { + await applyMigration({ + modulesNames, + action: "generate", + }) + } + return { onApplicationShutdown, onApplicationPrepareShutdown, @@ -526,6 +541,7 @@ async function MedusaApp_({ notFound, runMigrations, revertMigrations, + generateMigrations, sharedContainer: sharedContainer_, } } @@ -566,3 +582,17 @@ export async function MedusaAppMigrateDown( await revertMigrations(moduleNames).finally(MedusaModule.clearInstances) } + +export async function MedusaAppMigrateGenerate( + moduleNames: string[], + options: MedusaAppOptions = {} +): Promise { + const migrationOnly = true + + const { generateMigrations } = await MedusaApp_({ + ...options, + migrationOnly, + }) + + await generateMigrations(moduleNames).finally(MedusaModule.clearInstances) +} diff --git a/packages/core/modules-sdk/src/medusa-module.ts b/packages/core/modules-sdk/src/medusa-module.ts index bac1fc147e..9f6d2dc29e 100644 --- a/packages/core/modules-sdk/src/medusa-module.ts +++ b/packages/core/modules-sdk/src/medusa-module.ts @@ -52,6 +52,14 @@ type ModuleAlias = { main?: boolean } +export type MigrationOptions = { + moduleKey: string + modulePath: string + container?: MedusaContainer + options?: Record + moduleExports?: ModuleExports +} + export type ModuleBootstrapOptions = { moduleKey: string defaultPath: string @@ -536,13 +544,13 @@ class MedusaModule { return services } - public static async migrateUp( - moduleKey: string, - modulePath: string, - container?: MedusaContainer, - options?: Record, - moduleExports?: ModuleExports - ): Promise { + public static async migrateGenerate({ + options, + container, + moduleExports, + moduleKey, + modulePath, + }: MigrationOptions): Promise { const moduleResolutions = registerMedusaModule(moduleKey, { scope: MODULE_SCOPE.INTERNAL, resources: MODULE_RESOURCE_TYPE.ISOLATED, @@ -555,28 +563,31 @@ class MedusaModule { allowUnregistered: true, }) ?? logger + container ??= createMedusaContainer() + for (const mod in moduleResolutions) { - const [migrateUp] = await loadModuleMigrations( + const { generateMigration } = await loadModuleMigrations( moduleResolutions[mod], moduleExports ) - if (typeof migrateUp === "function") { - await migrateUp({ + if (typeof generateMigration === "function") { + await generateMigration({ options, + container: container!, logger: logger_, }) } } } - public static async migrateDown( - moduleKey: string, - modulePath: string, - container?: MedusaContainer, - options?: Record, - moduleExports?: ModuleExports - ): Promise { + public static async migrateUp({ + options, + container, + moduleExports, + moduleKey, + modulePath, + }: MigrationOptions): Promise { const moduleResolutions = registerMedusaModule(moduleKey, { scope: MODULE_SCOPE.INTERNAL, resources: MODULE_RESOURCE_TYPE.ISOLATED, @@ -589,15 +600,55 @@ class MedusaModule { allowUnregistered: true, }) ?? logger + container ??= createMedusaContainer() + for (const mod in moduleResolutions) { - const [, migrateDown] = await loadModuleMigrations( + const { runMigrations } = await loadModuleMigrations( moduleResolutions[mod], moduleExports ) - if (typeof migrateDown === "function") { - await migrateDown({ + if (typeof runMigrations === "function") { + await runMigrations({ options, + container: container!, + logger: logger_, + }) + } + } + } + + public static async migrateDown({ + options, + container, + moduleExports, + moduleKey, + modulePath, + }: MigrationOptions): Promise { + const moduleResolutions = registerMedusaModule(moduleKey, { + scope: MODULE_SCOPE.INTERNAL, + resources: MODULE_RESOURCE_TYPE.ISOLATED, + resolve: modulePath, + options, + }) + + const logger_ = + container?.resolve(ContainerRegistrationKeys.LOGGER, { + allowUnregistered: true, + }) ?? logger + + container ??= createMedusaContainer() + + for (const mod in moduleResolutions) { + const { revertMigration } = await loadModuleMigrations( + moduleResolutions[mod], + moduleExports + ) + + if (typeof revertMigration === "function") { + await revertMigration({ + options, + container: container!, logger: logger_, }) } diff --git a/packages/core/types/src/modules-sdk/index.ts b/packages/core/types/src/modules-sdk/index.ts index d6caf986d3..d770bad69c 100644 --- a/packages/core/types/src/modules-sdk/index.ts +++ b/packages/core/types/src/modules-sdk/index.ts @@ -235,6 +235,10 @@ export type ModuleExports> = { options: LoaderOptions, moduleDeclaration?: InternalModuleDeclaration ): Promise + generateMigration?( + options: LoaderOptions, + moduleDeclaration?: InternalModuleDeclaration + ): Promise } export interface ModuleServiceInitializeOptions { diff --git a/packages/core/utils/src/migrations/index.ts b/packages/core/utils/src/migrations/index.ts index d4c9478b8a..b69321eab5 100644 --- a/packages/core/utils/src/migrations/index.ts +++ b/packages/core/utils/src/migrations/index.ts @@ -6,6 +6,8 @@ import { } from "@mikro-orm/migrations" import { MikroORM, MikroORMOptions } from "@mikro-orm/core" import { PostgreSqlDriver } from "@mikro-orm/postgresql" +import { dirname } from "path" +import { access, mkdir, writeFile } from "fs/promises" /** * Events emitted by the migrations class @@ -56,7 +58,9 @@ export class Migrations extends EventEmitter { async generate(): Promise { const connection = await this.#getConnection() const migrator = connection.getMigrator() + try { + await this.ensureSnapshot(migrator["snapshotPath"]) return await migrator.createMigration() } finally { await connection.close(true) @@ -134,4 +138,35 @@ export class Migrations extends EventEmitter { await connection.close(true) } } + + /** + * Generate a default snapshot file if it does not already exists. This + * prevent from creating a database to manage the migrations and instead + * rely on the snapshot. + * + * @param snapshotPath + * @protected + */ + protected async ensureSnapshot(snapshotPath: string): Promise { + await mkdir(dirname(snapshotPath), { recursive: true }) + + const doesFileExists = await access(snapshotPath) + .then(() => true) + .catch(() => false) + + if (doesFileExists) { + return + } + + const emptySnapshotContent = JSON.stringify( + { + tables: [], + namespaces: [], + }, + null, + 2 + ) + + await writeFile(snapshotPath, emptySnapshotContent, "utf-8") + } } diff --git a/packages/core/utils/src/migrations/integration-tests/__tests__/migrations-generate.spec.ts b/packages/core/utils/src/migrations/integration-tests/__tests__/migrations-generate.spec.ts index 08732b5002..b6fb09f245 100644 --- a/packages/core/utils/src/migrations/integration-tests/__tests__/migrations-generate.spec.ts +++ b/packages/core/utils/src/migrations/integration-tests/__tests__/migrations-generate.spec.ts @@ -1,7 +1,6 @@ import { join } from "path" import { setTimeout } from "timers/promises" import { MetadataStorage } from "@mikro-orm/core" -import { createDatabase, dropDatabase } from "pg-god" import { Migrations } from "../../index" import { FileSystem } from "../../../common" @@ -22,22 +21,12 @@ const pgGodCredentials = { host: DB_HOST, } -// TODO: Reenable once flakiness is taken care of -describe.skip("Generate migrations", () => { +describe("Generate migrations", () => { beforeEach(async () => { - await dropDatabase( - { databaseName: dbName, errorIfNonExist: false }, - pgGodCredentials - ) await fs.cleanup() - await createDatabase({ databaseName: dbName }, pgGodCredentials) }) afterEach(async () => { - await dropDatabase( - { databaseName: dbName, errorIfNonExist: false }, - pgGodCredentials - ) await fs.cleanup() MetadataStorage.clear() }, 300 * 1000) diff --git a/packages/core/utils/src/modules-sdk/migration-scripts/index.ts b/packages/core/utils/src/modules-sdk/migration-scripts/index.ts index 125b5cdbe6..53e4c33a0c 100644 --- a/packages/core/utils/src/modules-sdk/migration-scripts/index.ts +++ b/packages/core/utils/src/modules-sdk/migration-scripts/index.ts @@ -1,3 +1,4 @@ export * from "./migration-down" export * from "./migration-up" +export * from "./migration-generate" export * from "./seed" diff --git a/packages/core/utils/src/modules-sdk/migration-scripts/migration-generate.ts b/packages/core/utils/src/modules-sdk/migration-scripts/migration-generate.ts new file mode 100644 index 0000000000..b682be3606 --- /dev/null +++ b/packages/core/utils/src/modules-sdk/migration-scripts/migration-generate.ts @@ -0,0 +1,63 @@ +import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types" +import { mikroOrmCreateConnection } from "../../dal" +import { loadDatabaseConfig } from "../load-module-database-config" +import { Migrations } from "../../migrations" +import { toMikroOrmEntities } from "../../dml" + +const TERMINAL_SIZE = process.stdout.columns + +/** + * Utility function to build a migration generation script that will generate the migrations. + * Only used in mikro orm based modules. + * @param moduleName + * @param models + * @param pathToMigrations + */ +export function buildGenerateMigrationScript({ + moduleName, + models, + pathToMigrations, +}) { + /** + * This script is only valid for mikro orm managers. If a user provide a custom manager + * he is in charge of running the migrations. + * @param options + * @param logger + * @param moduleDeclaration + */ + return async function ({ + options, + logger, + }: Pick< + LoaderOptions, + "options" | "logger" + > = {}) { + logger ??= console as unknown as Logger + + console.log(new Array(TERMINAL_SIZE).join("-")) + console.log("") + logger.info(`MODULE: ${moduleName}`) + + const dbData = loadDatabaseConfig(moduleName, options)! + + const normalizedModels = toMikroOrmEntities(models) + const orm = await mikroOrmCreateConnection( + dbData, + normalizedModels, + pathToMigrations + ) + + const migrations = new Migrations(orm) + + try { + const { fileName } = await migrations.generate() + if (fileName) { + logger.info(`Generated successfully (${fileName}).`) + } else { + logger.info(`Skipped. No changes detected in your models.`) + } + } catch (error) { + logger.error(`Failed with error ${error.message}`, error) + } + } +} diff --git a/packages/medusa/src/commands/migrate.ts b/packages/medusa/src/commands/migrate.ts index c8cb131b41..41f147e675 100644 --- a/packages/medusa/src/commands/migrate.ts +++ b/packages/medusa/src/commands/migrate.ts @@ -1,5 +1,5 @@ import Logger from "../loaders/logger" -import { migrateMedusaApp, revertMedusaApp } from "../loaders/medusa-app" +import { runMedusaAppMigrations } from "../loaders/medusa-app" import { initializeContainer } from "../loaders" import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils" import { getResolvedPlugins } from "../loaders/helpers/resolve-plugins" @@ -7,13 +7,44 @@ import { resolvePluginsLinks } from "../loaders/helpers/resolve-plugins-links" const TERMINAL_SIZE = process.stdout.columns +type Action = "run" | "revert" | "generate" | "show" + +function validateInputArgs({ + action, + modules, +}: { + action: Action + modules: string[] +}) { + const actionsRequiringModules = ["revert", "generate"] + + if (modules.length && !actionsRequiringModules.includes(action)) { + Logger.error( + ` cannot be specified with the "${action}" action. Please remove the argument and try again.` + ) + process.exit(1) + } + + if (!modules.length && actionsRequiringModules.includes(action)) { + Logger.error( + "Please provide the modules for which you want to revert migrations" + ) + Logger.error(`For example: "npx medusa migration revert "`) + process.exit(1) + } +} + const main = async function ({ directory }) { const args = process.argv args.shift() args.shift() args.shift() - const action = args[0] + const action = args[0] as "run" | "revert" | "generate" | "show" + const modules = args.splice(1) + + validateInputArgs({ action, modules }) + const container = await initializeContainer(directory) const configModule = container.resolve( @@ -26,33 +57,26 @@ const main = async function ({ directory }) { if (action === "run") { Logger.info("Running migrations...") - await migrateMedusaApp({ + await runMedusaAppMigrations({ configModule, linkModules: pluginLinks, container, + action: "run", }) console.log(new Array(TERMINAL_SIZE).join("-")) Logger.info("Migrations completed") process.exit() } else if (action === "revert") { - const modulesToRevert = args.slice(1) - if (!modulesToRevert.length) { - Logger.error( - "Please provide the modules for which you want to revert migrations" - ) - Logger.error(`For example: "npx medusa migration revert "`) - process.exit(1) - } - Logger.info("Reverting migrations...") try { - await revertMedusaApp({ - modulesToRevert, + await runMedusaAppMigrations({ + moduleNames: modules, configModule, linkModules: pluginLinks, container, + action: "revert", }) console.log(new Array(TERMINAL_SIZE).join("-")) Logger.info("Migrations reverted") @@ -70,6 +94,20 @@ const main = async function ({ directory }) { } process.exit(1) } + } else if (action === "generate") { + Logger.info("Generating migrations...") + + await runMedusaAppMigrations({ + moduleNames: modules, + configModule, + linkModules: pluginLinks, + container, + action: "generate", + }) + + console.log(new Array(TERMINAL_SIZE).join("-")) + Logger.info("Migrations generated") + process.exit() } else if (action === "show") { Logger.info("Action not supported yet") process.exit(0) diff --git a/packages/medusa/src/commands/utils/get-migrations.js b/packages/medusa/src/commands/utils/get-migrations.js index 4d4af59481..b7c1b32f32 100644 --- a/packages/medusa/src/commands/utils/get-migrations.js +++ b/packages/medusa/src/commands/utils/get-migrations.js @@ -126,11 +126,11 @@ export const runIsolatedModulesMigration = async (configModule) => { continue } - await MedusaModule.migrateUp( - moduleResolution.definition.key, - moduleResolution.resolutionPath, - moduleResolution.options - ) + await MedusaModule.migrateUp({ + moduleKey: moduleResolution.definition.key, + modulePath: moduleResolution.resolutionPath, + options: moduleResolution.options, + }) } } @@ -151,10 +151,10 @@ export const revertIsolatedModulesMigration = async (configModule) => { continue } - await MedusaModule.migrateDown( - moduleResolution.definition.key, - moduleResolution.resolutionPath, - moduleResolution.options - ) + await MedusaModule.migrateDown({ + moduleKey: moduleResolution.definition.key, + modulePath: moduleResolution.resolutionPath, + options: moduleResolution.options, + }) } } diff --git a/packages/medusa/src/loaders/medusa-app.ts b/packages/medusa/src/loaders/medusa-app.ts index 06e661b0bc..2c1c316095 100644 --- a/packages/medusa/src/loaders/medusa-app.ts +++ b/packages/medusa/src/loaders/medusa-app.ts @@ -1,6 +1,7 @@ import { MedusaApp, MedusaAppMigrateDown, + MedusaAppMigrateGenerate, MedusaAppMigrateUp, MedusaAppOptions, MedusaAppOutput, @@ -57,12 +58,21 @@ export function mergeDefaultModules( return configModules } -async function runMedusaAppMigrations({ +/** + * Run, Revert or Generate the migrations for the medusa app. + * + * @param configModule + * @param container + * @param moduleNames + * @param linkModules + * @param action + */ +export async function runMedusaAppMigrations({ configModule, container, moduleNames, - revert = false, linkModules, + action = "run", }: { configModule: { modules?: CommonTypes.ConfigModule["modules"] @@ -73,11 +83,11 @@ async function runMedusaAppMigrations({ } & ( | { moduleNames?: never - revert: false + action: "run" } | { moduleNames: string[] - revert: true + action: "revert" | "generate" } )): Promise { const injectedDependencies = { @@ -101,82 +111,23 @@ async function runMedusaAppMigrations({ } const configModules = mergeDefaultModules(configModule.modules) - if (revert) { - await MedusaAppMigrateDown(moduleNames!, { - modulesConfig: configModules, - sharedContainer: container, - linkModules, - sharedResourcesConfig, - injectedDependencies, - }) + const migrationOptions = { + modulesConfig: configModules, + sharedContainer: container, + linkModules, + sharedResourcesConfig, + injectedDependencies, + } + + if (action === "revert") { + await MedusaAppMigrateDown(moduleNames!, migrationOptions) + } else if (action === "run") { + await MedusaAppMigrateUp(migrationOptions) } else { - await MedusaAppMigrateUp({ - modulesConfig: configModules, - sharedContainer: container, - linkModules, - sharedResourcesConfig, - injectedDependencies, - }) + await MedusaAppMigrateGenerate(moduleNames!, migrationOptions) } } -/** - * - * @param configModule The config module - * @param linkModules Custom links from the plugins - * @param container The medusa container - */ -export async function migrateMedusaApp({ - configModule, - linkModules, - container, -}: { - configModule: { - modules?: CommonTypes.ConfigModule["modules"] - projectConfig: CommonTypes.ConfigModule["projectConfig"] - } - container: MedusaContainer - linkModules?: MedusaAppOptions["linkModules"] -}): Promise { - await runMedusaAppMigrations({ - configModule, - container, - linkModules, - revert: false, - }) -} - -/** - * - * @param modulesToRevert An array of modules for which you want to revert - * migrations - * @param configModule The config module - * @param linkModules Custom links from the plugins - * @param container The medusa container - */ -export async function revertMedusaApp({ - modulesToRevert, - configModule, - linkModules, - container, -}: { - modulesToRevert: string[] - configModule: { - modules?: CommonTypes.ConfigModule["modules"] - projectConfig: CommonTypes.ConfigModule["projectConfig"] - } - container: MedusaContainer - linkModules?: MedusaAppOptions["linkModules"] -}): Promise { - await runMedusaAppMigrations({ - moduleNames: modulesToRevert, - configModule, - container, - revert: true, - linkModules, - }) -} - export const loadMedusaApp = async ( { container,