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 <mike@mguida.com>
This commit is contained in:
Pieter Wigboldus 2025-04-04 20:05:33 +02:00 committed by GitHub
parent 04f3d3ff4c
commit 7c5ea99b31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 135 additions and 9 deletions

View File

@ -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.

View File

@ -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) {
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {
}