From 79ec2bcfe248e7dc648a6e24bc46acaf4ea2028c Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Thu, 11 Jul 2024 18:21:09 +0200 Subject: [PATCH] fix: Migration generator and generated migrations (#8090) --- .../__tests__/ts-migration-generator.spec.ts | 42 +++------ .../mikro-orm/mikro-orm-create-connection.ts | 93 +++++++------------ .../integration-tests/many-to-many.spec.ts | 4 +- .../mikro-orm-cli-config-builder.ts | 4 +- .../src/migrations/Migration20240529080336.ts | 62 +++++++++---- 5 files changed, 92 insertions(+), 113 deletions(-) diff --git a/packages/core/utils/src/dal/mikro-orm/__tests__/ts-migration-generator.spec.ts b/packages/core/utils/src/dal/mikro-orm/__tests__/ts-migration-generator.spec.ts index b6328a421c..71d7b4de21 100644 --- a/packages/core/utils/src/dal/mikro-orm/__tests__/ts-migration-generator.spec.ts +++ b/packages/core/utils/src/dal/mikro-orm/__tests__/ts-migration-generator.spec.ts @@ -1,14 +1,14 @@ -import { TSMigrationGenerator } from "../mikro-orm-create-connection" +import { CustomTsMigrationGenerator } from "../mikro-orm-create-connection" function unwrapSql(sql: string) { return sql.match(/this.addSql\('(.*?)'\)/)?.[1] } -describe("TSMigrationGenerator", () => { +describe("CustomTsMigrationGenerator", () => { it('should add "if not exists" to "create table" statements', () => { const sql = "create table my_table (id int)" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("create table if not exists my_table (id int)") }) @@ -16,7 +16,7 @@ describe("TSMigrationGenerator", () => { it('should add "if exists" to "alter table" statements as well as to the add column', () => { const sql = "alter table my_table add column name varchar(100)" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe( "alter table if exists my_table add column if not exists name varchar(100)" @@ -26,27 +26,17 @@ describe("TSMigrationGenerator", () => { it('should add "if exists" to "alter table" statements as well as to the drop column', () => { const sql = "alter table my_table drop column name" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe( "alter table if exists my_table drop column if exists name" ) }) - it('should add "if exists" to "alter table" statements as well as to the alter column', () => { - const sql = "alter table my_table alter column name" - const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) - ) - expect(result).toBe( - "alter table if exists my_table alter column if exists name" - ) - }) - it('should add "if not exists" to "create index" statements', () => { const sql = "create index idx_name on my_table(name)" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("create index if not exists idx_name on my_table(name)") }) @@ -54,7 +44,7 @@ describe("TSMigrationGenerator", () => { it('should add "if exists" to "drop index" statements', () => { const sql = "drop index idx_name" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("drop index if exists idx_name") }) @@ -62,7 +52,7 @@ describe("TSMigrationGenerator", () => { it('should add "if not exists" to "create unique index" statements', () => { const sql = "create unique index idx_unique_name on my_table(name)" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe( "create unique index if not exists idx_unique_name on my_table(name)" @@ -72,7 +62,7 @@ describe("TSMigrationGenerator", () => { it('should add "if exists" to "drop unique index" statements', () => { const sql = "drop unique index idx_unique_name" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("drop unique index if exists idx_unique_name") }) @@ -80,7 +70,7 @@ describe("TSMigrationGenerator", () => { it('should add "if not exists" to "add column" statements', () => { const sql = "add column name varchar(100)" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("add column if not exists name varchar(100)") }) @@ -88,23 +78,15 @@ describe("TSMigrationGenerator", () => { it('should add "if exists" to "drop column" statements', () => { const sql = "drop column name" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("drop column if exists name") }) - it('should add "if exists" to "alter column" statements', () => { - const sql = "alter column name" - const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) - ) - expect(result).toBe("alter column if exists name") - }) - it('should add "if exists" to "drop constraint" statements', () => { const sql = "drop constraint fk_name" const result = unwrapSql( - TSMigrationGenerator.prototype.createStatement(sql, 0) + CustomTsMigrationGenerator.prototype.createStatement(sql, 0) ) expect(result).toBe("drop constraint if exists fk_name") }) diff --git a/packages/core/utils/src/dal/mikro-orm/mikro-orm-create-connection.ts b/packages/core/utils/src/dal/mikro-orm/mikro-orm-create-connection.ts index 745b1d4e5c..9fd34dbc92 100644 --- a/packages/core/utils/src/dal/mikro-orm/mikro-orm-create-connection.ts +++ b/packages/core/utils/src/dal/mikro-orm/mikro-orm-create-connection.ts @@ -3,71 +3,42 @@ import { TSMigrationGenerator } from "@mikro-orm/migrations" import { isString } from "../../common" import { FilterDef } from "@mikro-orm/core/typings" -// Monkey patch due to the compilation version issue which prevents us from creating a proper class that extends the TSMigrationGenerator -const originalCreateStatement = TSMigrationGenerator.prototype.createStatement - -/** - * Safe migration generation for MikroORM - * - * @param sql The sql statement - * @param padLeft The padding - * - * @example see test file - */ -TSMigrationGenerator.prototype.createStatement = function ( - sql: string, - padLeft: number -) { - if (isString(sql)) { - if (!sql.includes("create table if not exists")) { - sql = sql.replace("create table", "create table if not exists") - } - - if (!sql.includes("alter table if exists")) { - sql = sql.replace("alter table", "alter table if exists") - } - - if (!sql.includes("create index if not exists")) { - sql = sql.replace("create index", "create index if not exists") - } - - if (!sql.includes("drop index if exists")) { - sql = sql.replace("drop index", "drop index if exists") - } - - if (!sql.includes("create unique index if not exists")) { +export class CustomTsMigrationGenerator extends TSMigrationGenerator { + createStatement(sql: string, padLeft: number): string { + if (isString(sql)) { sql = sql.replace( - "create unique index", - "create unique index if not exists" + /create table (?!if not exists)/g, + "create table if not exists " + ) + sql = sql.replace(/alter table (?!if exists)/g, "alter table if exists ") + sql = sql.replace( + /create index (?!if not exists)/g, + "create index if not exists " + ) + sql = sql.replace(/drop index (?!if exists)/g, "drop index if exists ") + sql = sql.replace( + /create unique index (?!if not exists)/g, + "create unique index if not exists " + ) + sql = sql.replace( + /drop unique index (?!if exists)/g, + "drop unique index if exists " + ) + sql = sql.replace( + /add column (?!if not exists)/g, + "add column if not exists " + ) + sql = sql.replace(/drop column (?!if exists)/g, "drop column if exists ") + sql = sql.replace( + /drop constraint (?!if exists)/g, + "drop constraint if exists " ) } - if (!sql.includes("drop unique index if exists")) { - sql = sql.replace("drop unique index", "drop unique index if exists") - } - - if (!sql.includes("add column if not exists")) { - sql = sql.replace("add column", "add column if not exists") - } - - if (!sql.includes("alter column if exists exists")) { - sql = sql.replace("alter column", "alter column if exists") - } - - if (!sql.includes("drop column if exists")) { - sql = sql.replace("drop column", "drop column if exists") - } - - if (!sql.includes("drop constraint if exists")) { - sql = sql.replace("drop constraint", "drop constraint if exists") - } + return super.createStatement(sql, padLeft) } - - return originalCreateStatement(sql, padLeft) } -export { TSMigrationGenerator } - export type Filter = { name?: string } & Omit @@ -99,7 +70,7 @@ export async function mikroOrmCreateConnection( const { MikroORM } = await import("@mikro-orm/postgresql") return await MikroORM.init({ - discovery: { disableDynamicFileAccess: true, warnWhenNoEntities: false, }, + discovery: { disableDynamicFileAccess: true, warnWhenNoEntities: false }, entities, debug: database.debug ?? process.env.NODE_ENV?.startsWith("dev") ?? false, baseDir: process.cwd(), @@ -112,7 +83,7 @@ export async function mikroOrmCreateConnection( migrations: { disableForeignKeys: false, path: pathToMigrations, - generator: TSMigrationGenerator, + generator: CustomTsMigrationGenerator, silent: !( database.debug ?? process.env.NODE_ENV?.startsWith("dev") ?? @@ -120,7 +91,7 @@ export async function mikroOrmCreateConnection( ), }, schemaGenerator: { - disableForeignKeys: false + disableForeignKeys: false, }, pool: database.pool as any, }) diff --git a/packages/core/utils/src/dml/integration-tests/many-to-many.spec.ts b/packages/core/utils/src/dml/integration-tests/many-to-many.spec.ts index 6e7525a2e1..b2ce26236f 100644 --- a/packages/core/utils/src/dml/integration-tests/many-to-many.spec.ts +++ b/packages/core/utils/src/dml/integration-tests/many-to-many.spec.ts @@ -2,7 +2,7 @@ import { MetadataStorage, MikroORM } from "@mikro-orm/core" import { model } from "../entity-builder" import { toMikroOrmEntities } from "../helpers/create-mikro-orm-entity" import { createDatabase, dropDatabase } from "pg-god" -import { mikroOrmSerializer, TSMigrationGenerator } from "../../dal" +import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../dal" import { FileSystem } from "../../common" import { join } from "path" import { EntityConstructor } from "@medusajs/types" @@ -70,7 +70,7 @@ describe("manyToMany - manyToMany", () => { debug: true, type: "postgresql", migrations: { - generator: TSMigrationGenerator, + generator: CustomTsMigrationGenerator, }, }) diff --git a/packages/core/utils/src/modules-sdk/mikro-orm-cli-config-builder.ts b/packages/core/utils/src/modules-sdk/mikro-orm-cli-config-builder.ts index 6670acde82..4e416df4e3 100644 --- a/packages/core/utils/src/modules-sdk/mikro-orm-cli-config-builder.ts +++ b/packages/core/utils/src/modules-sdk/mikro-orm-cli-config-builder.ts @@ -1,6 +1,6 @@ import { MikroORMOptions } from "@mikro-orm/core/utils/Configuration" import { DmlEntity, toMikroOrmEntities } from "../dml" -import { TSMigrationGenerator } from "../dal" +import { CustomTsMigrationGenerator } from "../dal" import type { AnyEntity, EntityClass, @@ -59,7 +59,7 @@ export function defineMikroOrmCliConfig( ...options, entities, migrations: { - generator: TSMigrationGenerator, + generator: CustomTsMigrationGenerator, ...options.migrations, }, } diff --git a/packages/modules/auth/src/migrations/Migration20240529080336.ts b/packages/modules/auth/src/migrations/Migration20240529080336.ts index 0394962a9b..77fa4c1ee9 100644 --- a/packages/modules/auth/src/migrations/Migration20240529080336.ts +++ b/packages/modules/auth/src/migrations/Migration20240529080336.ts @@ -1,30 +1,56 @@ -import { Migration } from '@mikro-orm/migrations'; +import { Migration } from "@mikro-orm/migrations" export class Migration20240529080336 extends Migration { - async up(): Promise { - this.addSql('create table if not exists "provider_identity" ("id" text not null, "entity_id" text not null, "provider" text not null, "auth_identity_id" text not null, "user_metadata" jsonb null, "provider_metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), constraint "provider_identity_pkey" primary key ("id"));'); - this.addSql('CREATE INDEX IF NOT EXISTS "IDX_provider_identity_auth_identity_id" ON "provider_identity" (auth_identity_id);'); - this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_provider_identity_provider_entity_id" ON "provider_identity" (entity_id, provider);'); + this.addSql( + 'create table if not exists "provider_identity" ("id" text not null, "entity_id" text not null, "provider" text not null, "auth_identity_id" text not null, "user_metadata" jsonb null, "provider_metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), constraint "provider_identity_pkey" primary key ("id"));' + ) + this.addSql( + 'CREATE INDEX IF NOT EXISTS "IDX_provider_identity_auth_identity_id" ON "provider_identity" (auth_identity_id);' + ) + this.addSql( + 'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_provider_identity_provider_entity_id" ON "provider_identity" (entity_id, provider);' + ) - this.addSql('alter table if exists "provider_identity" add constraint "provider_identity_auth_identity_id_foreign" foreign key ("auth_identity_id") references "auth_identity" ("id") on update cascade on delete cascade;'); + this.addSql( + 'alter table if exists "provider_identity" add constraint "provider_identity_auth_identity_id_foreign" foreign key ("auth_identity_id") references "auth_identity" ("id") on update cascade on delete cascade;' + ) - this.addSql('alter table if exists "auth_identity" add column if not exists "created_at" timestamptz not null default now(), add column "updated_at" timestamptz not null default now();'); + this.addSql( + 'alter table if exists "auth_identity" add column if not exists "created_at" timestamptz not null default now(), add column "updated_at" timestamptz not null default now();' + ) - this.addSql('alter table if exists "auth_identity" drop constraint if exists "IDX_auth_identity_provider_entity_id";'); - this.addSql('alter table if exists "auth_identity" drop column if exists "entity_id";'); - this.addSql('alter table if exists "auth_identity" drop column if exists "provider";'); - this.addSql('alter table if exists "auth_identity" drop column if exists "user_metadata";'); - this.addSql('alter table if exists "auth_identity" drop column if exists "provider_metadata";'); + this.addSql( + 'alter table if exists "auth_identity" drop constraint if exists "IDX_auth_identity_provider_entity_id";' + ) + this.addSql( + 'alter table if exists "auth_identity" drop column if exists "entity_id";' + ) + this.addSql( + 'alter table if exists "auth_identity" drop column if exists "provider";' + ) + this.addSql( + 'alter table if exists "auth_identity" drop column if exists "user_metadata";' + ) + this.addSql( + 'alter table if exists "auth_identity" drop column if exists "provider_metadata";' + ) } async down(): Promise { - this.addSql('drop table if exists "provider_identity" cascade;'); + this.addSql('drop table if exists "provider_identity" cascade;') - this.addSql('alter table if exists "auth_identity" add column if not exists "entity_id" text not null, add column "provider" text not null, add column "user_metadata" jsonb null, add column "provider_metadata" jsonb null;'); - this.addSql('alter table if exists "auth_identity" alter column if exists "app_metadata" type jsonb using ("app_metadata"::jsonb);'); - this.addSql('alter table if exists "auth_identity" alter column if exists "app_metadata" set not null;'); - this.addSql('alter table if exists "auth_identity" add constraint "IDX_auth_identity_provider_entity_id" unique ("provider", "entity_id");'); + this.addSql( + 'alter table if exists "auth_identity" add column if not exists "entity_id" text not null, add column "provider" text not null, add column "user_metadata" jsonb null, add column "provider_metadata" jsonb null;' + ) + this.addSql( + 'alter table if exists "auth_identity" alter column "app_metadata" type jsonb using ("app_metadata"::jsonb);' + ) + this.addSql( + 'alter table if exists "auth_identity" alter column "app_metadata" set not null;' + ) + this.addSql( + 'alter table if exists "auth_identity" add constraint "IDX_auth_identity_provider_entity_id" unique ("provider", "entity_id");' + ) } - }