diff --git a/docs/docs/migrations.md b/docs/docs/migrations.md index 1f6068b858d1..1f220131f556 100644 --- a/docs/docs/migrations.md +++ b/docs/docs/migrations.md @@ -76,10 +76,46 @@ await MikroORM.init({ safe: false, // allow to disable table and column dropping snapshot: true, // save snapshot when creating new migrations emit: 'ts', // migration generation mode + generator: TSMigrationGenerator, // migration generator, e.g. to allow custom formatting }, }) ``` +## Using custom `MigrationGenerator` + +When we generate new migrations, `MigrationGenerator` class is responsible for +generating the file contents. We can provide our own implementation to do things +like formatting the SQL statement. + +```ts +import { TSMigrationGenerator } from '@mikro-orm/migrations'; +import { format } from 'sql-formatter'; + +class CustomMigrationGenerator extends TSMigrationGenerator { + + generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { + const comment = '// this file was generated via custom migration generator\n\n'; + return comment + super.generateMigrationFile(className, diff); + } + + createStatement(sql: string, padLeft: number): string { + sql = format(sql, { language: 'postgresql' }); + // a bit of indenting magic + sql = sql.split('\n').map((l, i) => i === 0 ? l : `${' '.repeat(padLeft + 13)}${l}`).join('\n'); + + return super.createStatement(sql, padLeft); + } + +} + +await MikroORM.init({ + // ... + migrations: { + generator: CustomMigrationGenerator, + }, +}); +``` + ## Using via CLI You can use it via CLI: diff --git a/package.json b/package.json index 7d9318ae3eb9..df1bbade7f43 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,10 @@ "separateMajorMinor": false, "packageRules": [ { - "matchUpdateTypes": ["patch", "minor"], + "matchUpdateTypes": [ + "patch", + "minor" + ], "groupName": "patch/minor dependencies", "groupSlug": "all-non-major", "automerge": true, @@ -140,6 +143,7 @@ "lint-staged": "11.1.2", "rimraf": "3.0.2", "run-rs": "0.7.5", + "sql-formatter": "^4.0.2", "ts-jest": "26.5.6", "ts-node": "10.2.1", "typescript": "4.4.2", diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 921aec3637bc..957576e74a03 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -5,8 +5,8 @@ /* istanbul ignore file */ export { Constructor, Dictionary, PrimaryKeyType, PrimaryKeyProp, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, EntityName, EntityData, Highlighter, - AnyEntity, EntityProperty, EntityMetadata, QBFilterQuery, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, - GetRepository, EntityRepositoryType, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, PlainObject, + AnyEntity, EntityProperty, EntityMetadata, QBFilterQuery, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, + GetRepository, EntityRepositoryType, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, PlainObject, MigrationDiff, } from './typings'; export * from './enums'; export * from './errors'; diff --git a/packages/core/src/typings.ts b/packages/core/src/typings.ts index e3a9199bc4c3..e5481fa92f52 100644 --- a/packages/core/src/typings.ts +++ b/packages/core/src/typings.ts @@ -391,18 +391,66 @@ export interface IEntityGenerator { type UmzugMigration = { path?: string; file: string }; type MigrateOptions = { from?: string | number; to?: string | number; migrations?: string[] }; -type MigrationResult = { fileName: string; code: string; diff: string[] }; +type MigrationResult = { fileName: string; code: string; diff: MigrationDiff }; type MigrationRow = { name: string; executed_at: Date }; export interface IMigrator { + /** + * Checks current schema for changes, generates new migration if there are any. + */ createMigration(path?: string, blank?: boolean, initial?: boolean): Promise; + + /** + * Creates initial migration. This generates the schema based on metadata, and checks whether all the tables + * are already present. If yes, it will also automatically log the migration as executed. + * Initial migration can be created only if the schema is already aligned with the metadata, or when no schema + * is present - in such case regular migration would have the same effect. + */ createInitialMigration(path?: string): Promise; + + /** + * Returns list of already executed migrations. + */ getExecutedMigrations(): Promise; + + /** + * Returns list of pending (not yet executed) migrations found in the migration directory. + */ getPendingMigrations(): Promise; + + /** + * Executes specified migrations. Without parameter it will migrate up to the latest version. + */ up(options?: string | string[] | MigrateOptions): Promise; + + /** + * Executes down migrations to the given point. Without parameter it will migrate one version down. + */ down(options?: string | string[] | MigrateOptions): Promise; } +export interface MigrationDiff { + up: string[]; + down: string[]; +} + +export interface IMigrationGenerator { + /** + * Generates the full contents of migration file. Uses `generateMigrationFile` to get the file contents. + */ + generate(diff: MigrationDiff, path?: string): Promise<[string, string]>; + + /** + * Creates single migration statement. By default adds `this.addSql(sql);` to the code. + */ + createStatement(sql: string, padLeft: number): string; + + /** + * Returns the file contents of given migration. + */ + generateMigrationFile(className: string, diff: MigrationDiff): string; +} + export interface Migration { up(): Promise; down(): Promise; diff --git a/packages/core/src/utils/Configuration.ts b/packages/core/src/utils/Configuration.ts index 0a0a60ff6767..4b5367de9af4 100644 --- a/packages/core/src/utils/Configuration.ts +++ b/packages/core/src/utils/Configuration.ts @@ -3,7 +3,21 @@ import { inspect } from 'util'; import { NamingStrategy } from '../naming-strategy'; import { CacheAdapter, FileCacheAdapter, NullCacheAdapter } from '../cache'; import { EntityRepository } from '../entity'; -import { AnyEntity, Constructor, Dictionary, EntityClass, EntityClassGroup, FilterDef, Highlighter, HydratorConstructor, IHydrator, IPrimaryKey, MaybePromise, MigrationObject } from '../typings'; +import { + AnyEntity, + Constructor, + Dictionary, + EntityClass, + EntityClassGroup, + FilterDef, + Highlighter, + HydratorConstructor, + IHydrator, + IMigrationGenerator, + IPrimaryKey, + MaybePromise, + MigrationObject, +} from '../typings'; import { ObjectHydrator } from '../hydration'; import { NullHighlighter } from '../utils/NullHighlighter'; import { Logger, LoggerNamespace } from '../utils/Logger'; @@ -318,6 +332,7 @@ export type MigrationsOptions = { safe?: boolean; snapshot?: boolean; emit?: 'js' | 'ts'; + generator?: Constructor; fileName?: (timestamp: string) => string; migrationsList?: MigrationObject[]; }; diff --git a/packages/migrations/src/JSMigrationGenerator.ts b/packages/migrations/src/JSMigrationGenerator.ts new file mode 100644 index 000000000000..e16dba7bfd03 --- /dev/null +++ b/packages/migrations/src/JSMigrationGenerator.ts @@ -0,0 +1,30 @@ +import { MigrationGenerator } from './MigrationGenerator'; + +export class JSMigrationGenerator extends MigrationGenerator { + + /** + * @inheritDoc + */ + generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { + let ret = `'use strict';\n`; + ret += `Object.defineProperty(exports, '__esModule', { value: true });\n`; + ret += `const Migration = require('@mikro-orm/migrations').Migration;\n\n`; + ret += `class ${className} extends Migration {\n\n`; + ret += ` async up() {\n`; + diff.up.forEach(sql => ret += this.createStatement(sql, 4)); + ret += ` }\n\n`; + + /* istanbul ignore else */ + if (diff.down.length > 0) { + ret += ` async down() {\n`; + diff.down.forEach(sql => ret += this.createStatement(sql, 4)); + ret += ` }\n\n`; + } + + ret += `}\n`; + ret += `exports.${className} = ${className};\n`; + + return ret; + } + +} diff --git a/packages/migrations/src/MigrationGenerator.ts b/packages/migrations/src/MigrationGenerator.ts index 3fe3e7cf5494..3be081d28fd1 100644 --- a/packages/migrations/src/MigrationGenerator.ts +++ b/packages/migrations/src/MigrationGenerator.ts @@ -1,32 +1,31 @@ import { ensureDir, writeFile } from 'fs-extra'; -import { MigrationsOptions, NamingStrategy, Utils } from '@mikro-orm/core'; +import { IMigrationGenerator, MigrationsOptions, NamingStrategy, Utils } from '@mikro-orm/core'; import { AbstractSqlDriver } from '@mikro-orm/knex'; -export class MigrationGenerator { +export abstract class MigrationGenerator implements IMigrationGenerator { constructor(protected readonly driver: AbstractSqlDriver, protected readonly namingStrategy: NamingStrategy, protected readonly options: MigrationsOptions) { } + /** + * @inheritDoc + */ async generate(diff: { up: string[]; down: string[] }, path?: string): Promise<[string, string]> { path = Utils.normalizePath(path || this.options.path!); await ensureDir(path); const timestamp = new Date().toISOString().replace(/[-T:]|\.\d{3}z$/ig, ''); const className = this.namingStrategy.classToMigrationName(timestamp); const fileName = `${this.options.fileName!(timestamp)}.${this.options.emit}`; - let ret: string; - - if (this.options.emit === 'js') { - ret = this.generateJSMigrationFile(className, diff); - } else { - ret = this.generateTSMigrationFile(className, diff); - } - + const ret = this.generateMigrationFile(className, diff); await writeFile(path + '/' + fileName, ret); return [ret, fileName]; } + /** + * @inheritDoc + */ createStatement(sql: string, padLeft: number): string { if (sql) { const padding = ' '.repeat(padLeft); @@ -36,44 +35,9 @@ export class MigrationGenerator { return '\n'; } - generateJSMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { - let ret = `'use strict';\n`; - ret += `Object.defineProperty(exports, '__esModule', { value: true });\n`; - ret += `const Migration = require('@mikro-orm/migrations').Migration;\n\n`; - ret += `class ${className} extends Migration {\n\n`; - ret += ` async up() {\n`; - diff.up.forEach(sql => ret += this.createStatement(sql, 4)); - ret += ` }\n\n`; - - /* istanbul ignore else */ - if (diff.down.length > 0) { - ret += ` async down() {\n`; - diff.down.forEach(sql => ret += this.createStatement(sql, 4)); - ret += ` }\n\n`; - } - - ret += `}\n`; - ret += `exports.${className} = ${className};\n`; - - return ret; - } - - generateTSMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { - let ret = `import { Migration } from '@mikro-orm/migrations';\n\n`; - ret += `export class ${className} extends Migration {\n\n`; - ret += ` async up(): Promise {\n`; - diff.up.forEach(sql => ret += this.createStatement(sql, 4)); - ret += ` }\n\n`; - - if (diff.down.length > 0) { - ret += ` async down(): Promise {\n`; - diff.down.forEach(sql => ret += this.createStatement(sql, 4)); - ret += ` }\n\n`; - } - - ret += `}\n`; - - return ret; - } + /** + * @inheritDoc + */ + abstract generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string; } diff --git a/packages/migrations/src/Migrator.ts b/packages/migrations/src/Migrator.ts index 2bf4ec0c46c5..f6935f0ab84d 100644 --- a/packages/migrations/src/Migrator.ts +++ b/packages/migrations/src/Migrator.ts @@ -1,15 +1,16 @@ import umzug, { migrationsList, Umzug } from 'umzug'; import { join } from 'path'; import { ensureDir, pathExists, writeJSON } from 'fs-extra'; -import { Constructor, Dictionary, Transaction, Utils, t, Type } from '@mikro-orm/core'; +import { Constructor, Dictionary, Transaction, Utils, t, Type, IMigrator, IMigrationGenerator } from '@mikro-orm/core'; import { DatabaseSchema, DatabaseTable, EntityManager, SchemaGenerator } from '@mikro-orm/knex'; import { Migration } from './Migration'; import { MigrationRunner } from './MigrationRunner'; -import { MigrationGenerator } from './MigrationGenerator'; import { MigrationStorage } from './MigrationStorage'; import { MigrateOptions, MigrationResult, MigrationRow, UmzugMigration } from './typings'; +import { TSMigrationGenerator } from './TSMigrationGenerator'; +import { JSMigrationGenerator } from './JSMigrationGenerator'; -export class Migrator { +export class Migrator implements IMigrator { private readonly umzug: Umzug; private readonly driver = this.em.getDriver(); @@ -17,7 +18,7 @@ export class Migrator { private readonly config = this.em.config; private readonly options = this.config.get('migrations'); private readonly runner = new MigrationRunner(this.driver, this.options, this.config); - private readonly generator = new MigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options); + private readonly generator: IMigrationGenerator; private readonly storage = new MigrationStorage(this.driver, this.options); private readonly absolutePath = Utils.absolutePath(this.options.path!, this.config.get('baseDir')); private readonly snapshotPath = join(this.absolutePath, `.snapshot-${this.config.get('dbName')}.json`); @@ -39,8 +40,19 @@ export class Migrator { logging: this.config.get('logger'), migrations, }); + + if (this.options.generator) { + this.generator = new this.options.generator(this.driver, this.config.getNamingStrategy(), this.options); + } else if (this.options.emit === 'js') { + this.generator = new JSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options); + } else { + this.generator = new TSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options); + } } + /** + * @inheritDoc + */ async createMigration(path?: string, blank = false, initial = false): Promise { if (initial) { return this.createInitialMigration(path); @@ -63,6 +75,9 @@ export class Migrator { }; } + /** + * @inheritDoc + */ async createInitialMigration(path?: string): Promise { await this.ensureMigrationsDirExists(); const schemaExists = await this.validateInitialMigration(); @@ -124,6 +139,9 @@ export class Migrator { return expected.size === exists.size; } + /** + * @inheritDoc + */ async getExecutedMigrations(): Promise { await this.ensureMigrationsDirExists(); await this.schemaGenerator.ensureDatabase(); @@ -131,6 +149,9 @@ export class Migrator { return this.storage.getExecutedMigrations(); } + /** + * @inheritDoc + */ async getPendingMigrations(): Promise { await this.ensureMigrationsDirExists(); await this.schemaGenerator.ensureDatabase(); @@ -138,10 +159,16 @@ export class Migrator { return this.umzug.pending(); } + /** + * @inheritDoc + */ async up(options?: string | string[] | MigrateOptions): Promise { return this.runMigrations('up', options); } + /** + * @inheritDoc + */ async down(options?: string | string[] | MigrateOptions): Promise { return this.runMigrations('down', options); } diff --git a/packages/migrations/src/TSMigrationGenerator.ts b/packages/migrations/src/TSMigrationGenerator.ts new file mode 100644 index 000000000000..0d838e93fdf7 --- /dev/null +++ b/packages/migrations/src/TSMigrationGenerator.ts @@ -0,0 +1,26 @@ +import { MigrationGenerator } from './MigrationGenerator'; + +export class TSMigrationGenerator extends MigrationGenerator { + + /** + * @inheritDoc + */ + generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { + let ret = `import { Migration } from '@mikro-orm/migrations';\n\n`; + ret += `export class ${className} extends Migration {\n\n`; + ret += ` async up(): Promise {\n`; + diff.up.forEach(sql => ret += this.createStatement(sql, 4)); + ret += ` }\n\n`; + + if (diff.down.length > 0) { + ret += ` async down(): Promise {\n`; + diff.down.forEach(sql => ret += this.createStatement(sql, 4)); + ret += ` }\n\n`; + } + + ret += `}\n`; + + return ret; + } + +} diff --git a/packages/migrations/src/index.ts b/packages/migrations/src/index.ts index 5badf12fa2e9..c8b248e4cff3 100644 --- a/packages/migrations/src/index.ts +++ b/packages/migrations/src/index.ts @@ -6,5 +6,7 @@ export * from './Migrator'; export * from './Migration'; export * from './MigrationRunner'; export * from './MigrationGenerator'; +export * from './JSMigrationGenerator'; +export * from './TSMigrationGenerator'; export * from './MigrationStorage'; export * from './typings'; diff --git a/packages/migrations/src/typings.ts b/packages/migrations/src/typings.ts index 8639c62b5f18..57d950a6e3f3 100644 --- a/packages/migrations/src/typings.ts +++ b/packages/migrations/src/typings.ts @@ -1,6 +1,6 @@ -import { Transaction } from '@mikro-orm/core'; +import { Transaction, MigrationDiff } from '@mikro-orm/core'; export type UmzugMigration = { name?: string; path?: string; file: string }; export type MigrateOptions = { from?: string | number; to?: string | number; migrations?: string[]; transaction?: Transaction }; -export type MigrationResult = { fileName: string; code: string; diff: { up: string[]; down: string[] } }; +export type MigrationResult = { fileName: string; code: string; diff: MigrationDiff }; export type MigrationRow = { name: string; executed_at: Date }; diff --git a/tests/features/migrations/Migrator.postgres.test.ts b/tests/features/migrations/Migrator.postgres.test.ts index f49dfce1fe0b..db3cde268689 100644 --- a/tests/features/migrations/Migrator.postgres.test.ts +++ b/tests/features/migrations/Migrator.postgres.test.ts @@ -1,7 +1,8 @@ (global as any).process.env.FORCE_COLOR = 0; import umzug from 'umzug'; +import { format } from 'sql-formatter'; import { Logger, MetadataStorage, MikroORM } from '@mikro-orm/core'; -import { Migration, MigrationStorage, Migrator } from '@mikro-orm/migrations'; +import { Migration, MigrationStorage, Migrator, TSMigrationGenerator } from '@mikro-orm/migrations'; import { DatabaseSchema, DatabaseTable, PostgreSqlDriver } from '@mikro-orm/postgresql'; import { remove } from 'fs-extra'; import { initORMPostgreSql } from '../../bootstrap'; @@ -53,6 +54,32 @@ describe('Migrator (postgres)', () => { await remove(process.cwd() + '/temp/migrations/' + migration.fileName); }); + test('generate migration with custom migrator', async () => { + const dateMock = jest.spyOn(Date.prototype, 'toISOString'); + dateMock.mockReturnValue('2019-10-13T21:48:13.382Z'); + const migrationsSettings = orm.config.get('migrations'); + orm.config.set('migrations', { ...migrationsSettings, generator: class extends TSMigrationGenerator { + + generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { + const comment = '// this file was generated via custom migration generator\n\n'; + return comment + super.generateMigrationFile(className, diff); + } + + createStatement(sql: string, padLeft: number): string { + sql = format(sql, { language: 'postgresql' }); + sql = sql.split('\n').map((l, i) => i === 0 ? l : `${' '.repeat(padLeft + 13)}${l}`).join('\n'); + + return super.createStatement(sql, padLeft); + } + + } }); + const migrator = orm.getMigrator(); + const migration = await migrator.createMigration(); + expect(migration).toMatchSnapshot('migration-ts-dump'); + orm.config.set('migrations', migrationsSettings); // Revert migration config changes + await remove(process.cwd() + '/temp/migrations/' + migration.fileName); + }); + test('generate migration with custom name', async () => { const dateMock = jest.spyOn(Date.prototype, 'toISOString'); dateMock.mockReturnValue('2019-10-13T21:48:13.382Z'); diff --git a/tests/features/migrations/Migrator.sqlite.test.ts b/tests/features/migrations/Migrator.sqlite.test.ts index 380c749a5255..72e1640d7e3b 100644 --- a/tests/features/migrations/Migrator.sqlite.test.ts +++ b/tests/features/migrations/Migrator.sqlite.test.ts @@ -1,7 +1,7 @@ (global as any).process.env.FORCE_COLOR = 0; import umzug from 'umzug'; import { Logger, MetadataStorage, MikroORM } from '@mikro-orm/core'; -import { Migration, MigrationStorage, Migrator } from '@mikro-orm/migrations'; +import { Migration, MigrationStorage, Migrator, TSMigrationGenerator } from '@mikro-orm/migrations'; import { DatabaseSchema, DatabaseTable, SqliteDriver } from '@mikro-orm/sqlite'; import { remove } from 'fs-extra'; import { initORMSqlite2 } from '../../bootstrap'; @@ -307,16 +307,4 @@ describe('Migrator (sqlite)', () => { expect(calls).toMatchSnapshot('all-or-nothing-disabled'); }); - test('generate js schema migration', async () => { - const dateMock = jest.spyOn(Date.prototype, 'toISOString'); - dateMock.mockReturnValue('2019-10-13T21:48:13.382Z'); - const migrationsSettings = orm.config.get('migrations'); - orm.config.set('migrations', { ...migrationsSettings, emit: 'js' }); // Set migration type to js - const migrator = orm.getMigrator(); - const migration = await migrator.createMigration(); - expect(migration).toMatchSnapshot('migration-js-dump'); - orm.config.set('migrations', migrationsSettings); // Revert migration config changes - await remove(process.cwd() + '/temp/migrations/' + migration.fileName); - }); - }); diff --git a/tests/features/migrations/__snapshots__/Migrator.postgres.test.ts.snap b/tests/features/migrations/__snapshots__/Migrator.postgres.test.ts.snap index 5825b121f834..29eef680c317 100644 --- a/tests/features/migrations/__snapshots__/Migrator.postgres.test.ts.snap +++ b/tests/features/migrations/__snapshots__/Migrator.postgres.test.ts.snap @@ -455,6 +455,68 @@ exports.Migration20191013214813 = Migration20191013214813; } `; +exports[`Migrator (postgres) generate migration with custom migrator: migration-ts-dump 1`] = ` +Object { + "code": "// this file was generated via custom migration generator + +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20191013214813 extends Migration { + + async up(): Promise { + this.addSql('alter table + \\"book2\\" drop constraint if exists \\"book2_double_check\\";'); + this.addSql('alter table + \\"book2\\" + alter column + \\"double\\" type double precision using (\\"double\\" :: double precision);'); + this.addSql('alter table + \\"book2\\" drop column \\"foo\\";'); + + this.addSql('alter table + \\"test2\\" drop column \\"path\\";'); + } + + async down(): Promise { + this.addSql('alter table + \\"book2\\" + add + column \\"foo\\" varchar null default \\\\'lol\\\\';'); + this.addSql('alter table + \\"book2\\" drop constraint if exists \\"book2_double_check\\";'); + this.addSql('alter table + \\"book2\\" + alter column + \\"double\\" type numeric using (\\"double\\" :: numeric);'); + + this.addSql('alter table + \\"test2\\" + add + column \\"path\\" polygon null default null;'); + } + +} +", + "diff": Object { + "down": Array [ + "alter table \\"book2\\" add column \\"foo\\" varchar null default 'lol';", + "alter table \\"book2\\" drop constraint if exists \\"book2_double_check\\";", + "alter table \\"book2\\" alter column \\"double\\" type numeric using (\\"double\\"::numeric);", + "", + "alter table \\"test2\\" add column \\"path\\" polygon null default null;", + ], + "up": Array [ + "alter table \\"book2\\" drop constraint if exists \\"book2_double_check\\";", + "alter table \\"book2\\" alter column \\"double\\" type double precision using (\\"double\\"::double precision);", + "alter table \\"book2\\" drop column \\"foo\\";", + "", + "alter table \\"test2\\" drop column \\"path\\";", + ], + }, + "fileName": "Migration20191013214813.ts", +} +`; + exports[`Migrator (postgres) generate migration with custom name: migration-dump 1`] = ` Object { "code": "import { Migration } from '@mikro-orm/migrations'; diff --git a/tests/features/migrations/__snapshots__/Migrator.sqlite.test.ts.snap b/tests/features/migrations/__snapshots__/Migrator.sqlite.test.ts.snap index dd6b49f315a1..b99b48c1bea8 100644 --- a/tests/features/migrations/__snapshots__/Migrator.sqlite.test.ts.snap +++ b/tests/features/migrations/__snapshots__/Migrator.sqlite.test.ts.snap @@ -183,17 +183,6 @@ Object { } `; -exports[`Migrator (sqlite) generate js schema migration: migration-js-dump 2`] = ` -Object { - "code": "", - "diff": Object { - "down": Array [], - "up": Array [], - }, - "fileName": "", -} -`; - exports[`Migrator (sqlite) generate migration with custom name: migration-dump 1`] = ` Object { "code": "", diff --git a/yarn.lock b/yarn.lock index 49712d4ef948..f23e8a20c41c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2094,6 +2094,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -7934,6 +7939,13 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sql-formatter@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/sql-formatter/-/sql-formatter-4.0.2.tgz#2b359e5a4c611498d327b9659da7329d71724607" + integrity sha512-R6u9GJRiXZLr/lDo8p56L+OyyN2QFJPCDnsyEOsbdIpsnDKL8gubYFo7lNR7Zx7hfdWT80SfkoVS0CMaF/DE2w== + dependencies: + argparse "^2.0.1" + sqlite3@5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.2.tgz#00924adcc001c17686e0a6643b6cbbc2d3965083"