From 7c5ea99b3164306cd8816c9d1b026d2cbc8969fa Mon Sep 17 00:00:00 2001 From: Pieter Wigboldus Date: Fri, 4 Apr 2025 20:05:33 +0200 Subject: [PATCH] feat: generate ESM migrations via esm flag (#10802) Including jsdoc for typehinting Add esm as an option in the migrate cli Update the documentation for the JS migrations fixes #10801 Co-authored-by: Mike Guida --- docs/migrations.md | 35 +++++++++++++++++++ src/commands/MigrationCreateCommand.ts | 19 +++++++++- src/commands/MigrationGenerateCommand.ts | 20 ++++++++++- .../templates/generate/cockroachdb.ts | 10 +++++- .../commands/templates/generate/mssql.ts | 10 +++++- .../commands/templates/generate/mysql.ts | 10 +++++- .../commands/templates/generate/oracle.ts | 10 +++++- .../commands/templates/generate/postgres.ts | 10 +++++- .../commands/templates/generate/sqlite.ts | 10 +++++- .../templates/result-templates-create.ts | 10 +++++- 10 files changed, 135 insertions(+), 9 deletions(-) diff --git a/docs/migrations.md b/docs/migrations.md index b3de9f2e8..53b2a26e6 100644 --- a/docs/migrations.md +++ b/docs/migrations.md @@ -260,6 +260,14 @@ export class PostRefactoringTIMESTAMP implements MigrationInterface { Alternatively you can also output your migrations as Javascript files using the `o` (alias for `--outputJs`) flag. This is useful for Javascript only projects in which TypeScript additional packages are not installed. This command, will generate a new migration file `{TIMESTAMP}-PostRefactoring.js` with the following content: ```javascript +/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class PostRefactoringTIMESTAMP { async up(queryRunner) { await queryRunner.query( @@ -273,6 +281,33 @@ module.exports = class PostRefactoringTIMESTAMP { ) } } + +``` +By default, it generates CommonJS JavaScript code with the `o` (alias for `--outputJs`) flag, but you can also generate ESM code with the `esm` flag. This is useful for Javascript projects that use ESM: + +```javascript +/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + + +/** + * @class + * @implements {MigrationInterface} + */ +export class PostRefactoringTIMESTAMP { + async up(queryRunner) { + await queryRunner.query( + `ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"`, + ) + } + + async down(queryRunner) { + await queryRunner.query( + `ALTER TABLE "post" ALTER COLUMN "name" RENAME TO "title"`, + ) + } +} ``` See, you don't need to write the queries on your own. diff --git a/src/commands/MigrationCreateCommand.ts b/src/commands/MigrationCreateCommand.ts index 931b8abca..56ecee191 100644 --- a/src/commands/MigrationCreateCommand.ts +++ b/src/commands/MigrationCreateCommand.ts @@ -26,6 +26,12 @@ export class MigrationCreateCommand implements yargs.CommandModule { describe: "Generate a migration file on Javascript instead of Typescript", }) + .option("esm", { + type: "boolean", + default: false, + describe: + "Generate a migration file on ESM instead of CommonJS", + }) .option("t", { alias: "timestamp", type: "number", @@ -48,6 +54,7 @@ export class MigrationCreateCommand implements yargs.CommandModule { ? MigrationCreateCommand.getJavascriptTemplate( filename, timestamp, + args.esm, ) : MigrationCreateCommand.getTemplate(filename, timestamp) @@ -97,8 +104,18 @@ export class ${camelCase( protected static getJavascriptTemplate( name: string, timestamp: number, + esm: boolean, ): string { - return `module.exports = class ${camelCase(name, true)}${timestamp} { + const exportMethod = esm ? "export" : "module.exports =" + return `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +${exportMethod} class ${camelCase(name, true)}${timestamp} { async up(queryRunner) { } diff --git a/src/commands/MigrationGenerateCommand.ts b/src/commands/MigrationGenerateCommand.ts index 32f0695dd..b212c5f67 100644 --- a/src/commands/MigrationGenerateCommand.ts +++ b/src/commands/MigrationGenerateCommand.ts @@ -43,6 +43,12 @@ export class MigrationGenerateCommand implements yargs.CommandModule { describe: "Generate a migration file on Javascript instead of Typescript", }) + .option("esm", { + type: "boolean", + default: false, + describe: + "Generate a migration file on ESM instead of CommonJS", + }) .option("dr", { alias: "dryrun", type: "boolean", @@ -157,6 +163,7 @@ export class MigrationGenerateCommand implements yargs.CommandModule { timestamp, upSqls, downSqls.reverse(), + args.esm, ) : MigrationGenerateCommand.getTemplate( path.basename(fullPath), @@ -255,10 +262,21 @@ ${downSqls.join(` timestamp: number, upSqls: string[], downSqls: string[], + esm: boolean, ): string { const migrationName = `${camelCase(name, true)}${timestamp}` - return `module.exports = class ${migrationName} { + const exportMethod = esm ? "export" : "module.exports =" + + return `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +${exportMethod} class ${migrationName} { name = '${migrationName}' async up(queryRunner) { diff --git a/test/functional/commands/templates/generate/cockroachdb.ts b/test/functional/commands/templates/generate/cockroachdb.ts index 77943e581..4a75d88fc 100644 --- a/test/functional/commands/templates/generate/cockroachdb.ts +++ b/test/functional/commands/templates/generate/cockroachdb.ts @@ -15,7 +15,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' async up(queryRunner) { diff --git a/test/functional/commands/templates/generate/mssql.ts b/test/functional/commands/templates/generate/mssql.ts index d3035d08a..ed7c2db90 100644 --- a/test/functional/commands/templates/generate/mssql.ts +++ b/test/functional/commands/templates/generate/mssql.ts @@ -13,7 +13,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' async up(queryRunner) { diff --git a/test/functional/commands/templates/generate/mysql.ts b/test/functional/commands/templates/generate/mysql.ts index 721004396..05b04be89 100644 --- a/test/functional/commands/templates/generate/mysql.ts +++ b/test/functional/commands/templates/generate/mysql.ts @@ -13,7 +13,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' async up(queryRunner) { diff --git a/test/functional/commands/templates/generate/oracle.ts b/test/functional/commands/templates/generate/oracle.ts index 9165d99f0..aeea51b3a 100644 --- a/test/functional/commands/templates/generate/oracle.ts +++ b/test/functional/commands/templates/generate/oracle.ts @@ -13,7 +13,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' async up(queryRunner) { diff --git a/test/functional/commands/templates/generate/postgres.ts b/test/functional/commands/templates/generate/postgres.ts index 59f008676..0d07f3f1c 100644 --- a/test/functional/commands/templates/generate/postgres.ts +++ b/test/functional/commands/templates/generate/postgres.ts @@ -13,7 +13,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' async up(queryRunner) { diff --git a/test/functional/commands/templates/generate/sqlite.ts b/test/functional/commands/templates/generate/sqlite.ts index 0f7b5d30c..26bdddcf0 100644 --- a/test/functional/commands/templates/generate/sqlite.ts +++ b/test/functional/commands/templates/generate/sqlite.ts @@ -13,7 +13,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' async up(queryRunner) { diff --git a/test/functional/commands/templates/result-templates-create.ts b/test/functional/commands/templates/result-templates-create.ts index 6b232b341..b45e94bb8 100644 --- a/test/functional/commands/templates/result-templates-create.ts +++ b/test/functional/commands/templates/result-templates-create.ts @@ -11,7 +11,15 @@ export class TestMigration1610975184784 implements MigrationInterface { } `, - javascript: `module.exports = class TestMigration1610975184784 { + javascript: `/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class TestMigration1610975184784 { async up(queryRunner) { }