diff --git a/docs/migrations.md b/docs/migrations.md index 088b759127..92d1ef2c63 100644 --- a/docs/migrations.md +++ b/docs/migrations.md @@ -258,8 +258,15 @@ 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 -const { MigrationInterface, QueryRunner } = require("typeorm") - +/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class PostRefactoringTIMESTAMP { async up(queryRunner) { await queryRunner.query( @@ -273,6 +280,34 @@ module.exports = class PostRefactoringTIMESTAMP { ) } } + +``` +By default, it generates CommonJS JavaScript code with the `o` (alias for `--outputJs`) flag, but you can generate also ESM code with the `esm` flag. This is useful for Javascript projects that use ESM modules: + +```javascript +/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @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 321f8ac58e..5fc1c8839f 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,14 +104,31 @@ export class ${camelCase( protected static getJavascriptTemplate( name: string, timestamp: number, + esm: boolean, ): string { - return `const { MigrationInterface, QueryRunner } = require("typeorm"); + const exportMethod = esm ? "export" : "module.exports =" + return `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ -module.exports = class ${camelCase(name, true)}${timestamp} { +/** + * @class + * @implements {MigrationInterface} + */ +${exportMethod} class ${camelCase(name, true)}${timestamp} { + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { } diff --git a/src/commands/MigrationGenerateCommand.ts b/src/commands/MigrationGenerateCommand.ts index 8ccdaae736..015370faee 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", @@ -162,6 +168,7 @@ export class MigrationGenerateCommand implements yargs.CommandModule { timestamp, upSqls, downSqls.reverse(), + args.esm, ) : MigrationGenerateCommand.getTemplate( path.basename(fullPath), @@ -264,19 +271,37 @@ ${downSqls.join(` timestamp: number, upSqls: string[], downSqls: string[], + esm: boolean, ): string { const migrationName = `${camelCase(name, true)}${timestamp}` - return `const { MigrationInterface, QueryRunner } = require("typeorm"); + const exportMethod = esm ? "export" : "module.exports =" + + return `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ -module.exports = class ${migrationName} { +/** + * @class + * @implements {MigrationInterface} + */ +${exportMethod} class ${migrationName} { name = '${migrationName}' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { ${upSqls.join(` `)} } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { ${downSqls.join(` `)} diff --git a/test/functional/commands/templates/generate/cockroachdb.ts b/test/functional/commands/templates/generate/cockroachdb.ts index cb9c1eb8fd..64915c838a 100644 --- a/test/functional/commands/templates/generate/cockroachdb.ts +++ b/test/functional/commands/templates/generate/cockroachdb.ts @@ -15,16 +15,31 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { await queryRunner.query(\`CREATE SEQUENCE "post_id_seq"\`); await queryRunner.query(\`CREATE TABLE "post" ("id" INT DEFAULT nextval('"post_id_seq"') NOT NULL, "title" varchar NOT NULL, "createdAt" timestamptz NOT NULL DEFAULT now(), CONSTRAINT "PK_be5fda3aac270b134ff9c21cdee" PRIMARY KEY ("id"))\`); } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { await queryRunner.query(\`DROP TABLE "post"\`); await queryRunner.query(\`DROP SEQUENCE "post_id_seq"\`); diff --git a/test/functional/commands/templates/generate/mssql.ts b/test/functional/commands/templates/generate/mssql.ts index 7bde7f2857..e26188cf75 100644 --- a/test/functional/commands/templates/generate/mssql.ts +++ b/test/functional/commands/templates/generate/mssql.ts @@ -13,15 +13,30 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); - + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { await queryRunner.query(\`CREATE TABLE "post" ("id" int NOT NULL IDENTITY(1,1), "title" nvarchar(255) NOT NULL, "createdAt" datetime2 NOT NULL CONSTRAINT "DF_fb91bea2d37140a877b775e6b2a" DEFAULT getdate(), CONSTRAINT "PK_be5fda3aac270b134ff9c21cdee" PRIMARY KEY ("id"))\`); } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { await queryRunner.query(\`DROP TABLE "post"\`); } diff --git a/test/functional/commands/templates/generate/mysql.ts b/test/functional/commands/templates/generate/mysql.ts index 29e069eeb9..2ab054fcd7 100644 --- a/test/functional/commands/templates/generate/mysql.ts +++ b/test/functional/commands/templates/generate/mysql.ts @@ -13,15 +13,30 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); - + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { await queryRunner.query(\`CREATE TABLE \\\`post\\\` (\\\`id\\\` int NOT NULL AUTO_INCREMENT, \\\`title\\\` varchar(255) NOT NULL, \\\`createdAt\\\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (\\\`id\\\`)) ENGINE=InnoDB\`); } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { await queryRunner.query(\`DROP TABLE \\\`post\\\`\`); } diff --git a/test/functional/commands/templates/generate/oracle.ts b/test/functional/commands/templates/generate/oracle.ts index 6ab8444ad0..c0da4a1117 100644 --- a/test/functional/commands/templates/generate/oracle.ts +++ b/test/functional/commands/templates/generate/oracle.ts @@ -13,15 +13,30 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); - + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { await queryRunner.query(\`CREATE TABLE "post" ("id" number GENERATED BY DEFAULT AS IDENTITY, "title" varchar2(255) NOT NULL, "createdAt" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT "PK_be5fda3aac270b134ff9c21cdee" PRIMARY KEY ("id"))\`); } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { await queryRunner.query(\`DROP TABLE "post"\`); } diff --git a/test/functional/commands/templates/generate/postgres.ts b/test/functional/commands/templates/generate/postgres.ts index a25ead2e20..b540f44c0c 100644 --- a/test/functional/commands/templates/generate/postgres.ts +++ b/test/functional/commands/templates/generate/postgres.ts @@ -13,15 +13,30 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); - + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { await queryRunner.query(\`CREATE TABLE "post" ("id" SERIAL NOT NULL, "title" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_be5fda3aac270b134ff9c21cdee" PRIMARY KEY ("id"))\`); } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { await queryRunner.query(\`DROP TABLE "post"\`); } diff --git a/test/functional/commands/templates/generate/sqlite.ts b/test/functional/commands/templates/generate/sqlite.ts index 26bd28e64c..bb3d9d964c 100644 --- a/test/functional/commands/templates/generate/sqlite.ts +++ b/test/functional/commands/templates/generate/sqlite.ts @@ -13,15 +13,30 @@ export class TestMigration1610975184784 implements MigrationInterface { } }`, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); - + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { name = 'TestMigration1610975184784' + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { await queryRunner.query(\`CREATE TABLE "post" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')))\`); } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { await queryRunner.query(\`DROP TABLE "post"\`); } diff --git a/test/functional/commands/templates/result-templates-create.ts b/test/functional/commands/templates/result-templates-create.ts index 8d3ed7c931..340ca5afc8 100644 --- a/test/functional/commands/templates/result-templates-create.ts +++ b/test/functional/commands/templates/result-templates-create.ts @@ -11,13 +11,28 @@ export class TestMigration1610975184784 implements MigrationInterface { } `, - javascript: `const { MigrationInterface, QueryRunner } = require("typeorm"); - + javascript: `/** + * @typedef {import('typeorm').QueryRunner} QueryRunner + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ module.exports = class TestMigration1610975184784 { + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async up(queryRunner) { } + /** + * @param {QueryRunner} queryRunner + * @returns {Promise} + */ async down(queryRunner) { }