Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@mikro-orm/migrations

Package Overview
Dependencies
Maintainers
1
Versions
4075
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mikro-orm/migrations - npm Package Compare versions

Comparing version
7.0.0-dev.260
to
7.0.0-dev.261
+2
-3
MigrationGenerator.js

@@ -1,3 +0,1 @@

import { fs } from '@mikro-orm/core/fs-utils';
import { writeFile } from 'node:fs/promises';
export class MigrationGenerator {

@@ -16,2 +14,3 @@ driver;

async generate(diff, path, name) {
const { fs } = await import('@mikro-orm/core/fs-utils');
/* v8 ignore next */

@@ -25,3 +24,3 @@ const defaultPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path;

const ret = await this.generateMigrationFile(className, diff);
await writeFile(path + '/' + fileName, ret, { flush: true });
await fs.writeFile(path + '/' + fileName, ret, { flush: true });
return [ret, fileName];

@@ -28,0 +27,0 @@ }

+7
-4
import { type MigrationsOptions, type Transaction, type EntitySchema } from '@mikro-orm/core';
import { type AbstractSqlDriver } from '@mikro-orm/sql';
import type { MigrationParams, UmzugStorage } from 'umzug';
import type { MigrationRow } from './typings.js';
export declare class MigrationStorage implements UmzugStorage {
export declare class MigrationStorage {
protected readonly driver: AbstractSqlDriver;

@@ -14,4 +13,8 @@ protected readonly options: MigrationsOptions;

executed(): Promise<string[]>;
logMigration(params: MigrationParams<any>): Promise<void>;
unlogMigration(params: MigrationParams<any>): Promise<void>;
logMigration(params: {
name: string;
}): Promise<void>;
unlogMigration(params: {
name: string;
}): Promise<void>;
getExecutedMigrations(): Promise<MigrationRow[]>;

@@ -18,0 +21,0 @@ ensureTable(): Promise<void>;

import { defineEntity, p } from '@mikro-orm/core';
import { DatabaseTable, } from '@mikro-orm/sql';
import { parse } from 'node:path';
export class MigrationStorage {

@@ -91,8 +90,3 @@ driver;

getMigrationName(name) {
const parsedName = parse(name);
if (['.js', '.ts'].includes(parsedName.ext)) {
// strip extension
return parsedName.name;
}
return name;
return name.replace(/\.[jt]s$/, '');
}

@@ -99,0 +93,0 @@ /**

@@ -1,30 +0,16 @@

import { type MigrationParams, type RunnableMigration } from 'umzug';
import { type Constructor, type IMigrator, type MaybePromise, type MigratorEvent, type MikroORM } from '@mikro-orm/core';
import { DatabaseSchema, type EntityManager } from '@mikro-orm/sql';
import type { Migration } from './Migration.js';
import { type IMigrationGenerator, type IMigrationRunner, type IMigratorStorage, type MikroORM } from '@mikro-orm/core';
import { AbstractMigrator } from '@mikro-orm/core/migrations';
import { type AbstractSqlDriver, DatabaseSchema, type EntityManager } from '@mikro-orm/sql';
import { MigrationStorage } from './MigrationStorage.js';
import type { MigrateOptions, MigrationResult, MigrationRow, UmzugMigration } from './typings.js';
export declare class Migrator implements IMigrator {
private readonly em;
private umzug;
private runner;
private storage;
private generator;
private readonly driver;
import type { MigrationResult } from './typings.js';
export declare class Migrator extends AbstractMigrator<AbstractSqlDriver> {
private readonly schemaGenerator;
private readonly config;
private readonly options;
private readonly absolutePath;
private readonly snapshotPath;
private snapshotPath?;
constructor(em: EntityManager);
/**
* Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
* If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
* used for the TS variant (`pathTs` option).
*
* If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
* break existing projects, only help with the new ones.
*/
private detectSourceFolder;
static register(orm: MikroORM): void;
protected createRunner(): IMigrationRunner;
protected createStorage(): IMigratorStorage;
protected getDefaultGenerator(): IMigrationGenerator;
private getSnapshotPath;
protected init(): Promise<void>;
/**

@@ -39,12 +25,4 @@ * @inheritDoc

createInitial(path?: string, name?: string, blank?: boolean): Promise<MigrationResult>;
getStorage(): MigrationStorage;
/**
* @inheritDoc
*/
on(eventName: MigratorEvent, listener: (event: UmzugMigration) => MaybePromise<void>): this;
/**
* @inheritDoc
*/
off(eventName: MigratorEvent, listener: (event: UmzugMigration) => MaybePromise<void>): this;
private createUmzug;
/**
* Initial migration can be created only if:

@@ -58,30 +36,5 @@ * 1. no previous migrations were generated or executed

private validateInitialMigration;
/**
* @inheritDoc
*/
getExecuted(): Promise<MigrationRow[]>;
private ensureDatabase;
/**
* @inheritDoc
*/
getPending(): Promise<UmzugMigration[]>;
/**
* @inheritDoc
*/
up(options?: string | string[] | MigrateOptions): Promise<UmzugMigration[]>;
/**
* @inheritDoc
*/
down(options?: string | string[] | MigrateOptions): Promise<UmzugMigration[]>;
getStorage(): MigrationStorage;
protected resolve(params: MigrationParams<any>): RunnableMigration<any>;
protected getSchemaFromSnapshot(): DatabaseSchema | undefined;
protected getSchemaFromSnapshot(): Promise<DatabaseSchema | undefined>;
protected storeCurrentSchema(): Promise<void>;
protected initialize(MigrationClass: Constructor<Migration>, name: string): RunnableMigration<any>;
private getSchemaDiff;
private getMigrationFilename;
private prefix;
private runMigrations;
private runInTransaction;
private ensureMigrationsDirExists;
}

@@ -1,6 +0,3 @@

import { Umzug, } from 'umzug';
import { basename, join } from 'node:path';
import { existsSync, writeFileSync } from 'node:fs';
import { t, Type, UnknownType, Utils, } from '@mikro-orm/core';
import { fs } from '@mikro-orm/core/fs-utils';
import { t, Type, UnknownType, } from '@mikro-orm/core';
import { AbstractMigrator } from '@mikro-orm/core/migrations';
import { DatabaseSchema, DatabaseTable, } from '@mikro-orm/sql';

@@ -11,63 +8,49 @@ import { MigrationRunner } from './MigrationRunner.js';

import { JSMigrationGenerator } from './JSMigrationGenerator.js';
export class Migrator {
em;
umzug;
runner;
storage;
generator;
driver;
export class Migrator extends AbstractMigrator {
schemaGenerator;
config;
options;
absolutePath;
snapshotPath;
constructor(em) {
this.em = em;
this.driver = this.em.getDriver();
this.config = this.em.config;
this.options = this.config.get('migrations');
super(em);
this.schemaGenerator = this.config.getExtension('@mikro-orm/schema-generator');
this.detectSourceFolder();
/* v8 ignore next */
const key = (this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.options.pathTs) ? 'pathTs' : 'path';
this.absolutePath = fs.absolutePath(this.options[key], this.config.get('baseDir'));
// for snapshots, we always want to use the path based on `emit` option, regardless of whether we run in TS context
/* v8 ignore next */
const snapshotPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path;
const absoluteSnapshotPath = fs.absolutePath(snapshotPath, this.config.get('baseDir'));
const dbName = basename(this.config.get('dbName'));
const snapshotName = this.options.snapshotName ?? `.snapshot-${dbName}`;
this.snapshotPath = fs.normalizePath(absoluteSnapshotPath, `${snapshotName}.json`);
this.createUmzug();
}
/**
* Checks if `src` folder exists, it so, tries to adjust the migrations and seeders paths automatically to use it.
* If there is a `dist` or `build` folder, it will be used for the JS variant (`path` option), while the `src` folder will be
* used for the TS variant (`pathTs` option).
*
* If the default folder exists (e.g. `/migrations`), the config will respect that, so this auto-detection should not
* break existing projects, only help with the new ones.
*/
detectSourceFolder() {
const baseDir = this.config.get('baseDir');
const defaultPath = './migrations';
if (!fs.pathExists(baseDir + '/src')) {
this.options.path ??= defaultPath;
static register(orm) {
orm.config.registerExtension('@mikro-orm/migrator', () => new Migrator(orm.em));
}
createRunner() {
return new MigrationRunner(this.driver, this.options, this.config);
}
createStorage() {
return new MigrationStorage(this.driver, this.options);
}
getDefaultGenerator() {
if (this.options.emit === 'js' || this.options.emit === 'cjs') {
return new JSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
}
return new TSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
}
async getSnapshotPath() {
if (!this.snapshotPath) {
const { fs } = await import('@mikro-orm/core/fs-utils');
// for snapshots, we always want to use the path based on `emit` option, regardless of whether we run in TS context
/* v8 ignore next */
const snapshotPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path;
const absoluteSnapshotPath = fs.absolutePath(snapshotPath, this.config.get('baseDir'));
const dbName = this.config.get('dbName').replace(/\\/g, '/').split('/').pop();
const snapshotName = this.options.snapshotName ?? `.snapshot-${dbName}`;
this.snapshotPath = fs.normalizePath(absoluteSnapshotPath, `${snapshotName}.json`);
}
return this.snapshotPath;
}
async init() {
if (this.initialized) {
return;
}
const exists = fs.pathExists(`${baseDir}/${defaultPath}`);
const distDir = fs.pathExists(baseDir + '/dist');
const buildDir = fs.pathExists(baseDir + '/build');
// if neither `dist` nor `build` exist, we use the `src` folder as it might be a JS project without building, but with `src` folder
await super.init();
const created = await this.schemaGenerator.ensureDatabase();
/* v8 ignore next */
const path = distDir ? './dist' : (buildDir ? './build' : './src');
// only if the user did not provide any values and if the default path does not exist
if (!this.options.path && !this.options.pathTs && !exists) {
this.options.path = `${path}/migrations`;
this.options.pathTs = './src/migrations';
if (created) {
this.initServices();
}
await this.storage.ensureTable();
}
static register(orm) {
orm.config.registerExtension('@mikro-orm/migrator', () => new Migrator(orm.em));
}
/**

@@ -77,6 +60,6 @@ * @inheritDoc

async create(path, blank = false, initial = false, name) {
await this.init();
if (initial) {
return this.createInitial(path, name, blank);
}
this.ensureMigrationsDirExists();
const diff = await this.getSchemaDiff(blank, initial);

@@ -95,3 +78,3 @@ if (diff.up.length === 0) {

async checkSchema() {
this.ensureMigrationsDirExists();
await this.init();
const diff = await this.getSchemaDiff(false, false);

@@ -104,3 +87,3 @@ return diff.up.length > 0;

async createInitial(path, name, blank = false) {
this.ensureMigrationsDirExists();
await this.init();
const schemaExists = await this.validateInitialMigration(blank);

@@ -111,3 +94,3 @@ const diff = await this.getSchemaDiff(blank, true);

if (schemaExists && !blank) {
await this.storage.logMigration({ name: migration[1], context: null });
await this.storage.logMigration({ name: migration[1] });
}

@@ -120,55 +103,6 @@ return {

}
/**
* @inheritDoc
*/
on(eventName, listener) {
this.umzug.on(eventName, listener);
return this;
getStorage() {
return this.storage;
}
/**
* @inheritDoc
*/
off(eventName, listener) {
this.umzug.off(eventName, listener);
return this;
}
createUmzug() {
this.runner = new MigrationRunner(this.driver, this.options, this.config);
this.storage = new MigrationStorage(this.driver, this.options);
let migrations = {
glob: join(this.absolutePath, this.options.glob).replace(/\\/g, '/'),
resolve: (params) => this.resolve(params),
};
if (this.options.migrationsList) {
migrations = this.options.migrationsList.map(migration => {
if (typeof migration === 'function') {
return this.initialize(migration, migration.name);
}
return this.initialize(migration.class, migration.name);
});
}
this.umzug = new Umzug({
storage: this.storage,
logger: undefined,
migrations,
});
/* v8 ignore else */
if (!this.options.silent) {
const logger = this.config.getLogger();
this.umzug.on('migrating', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
this.umzug.on('migrated', event => logger.log('migrator', `Applied '${event.name}'`, { enabled: true }));
this.umzug.on('reverting', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
this.umzug.on('reverted', event => logger.log('migrator', `Reverted '${event.name}'`, { enabled: true }));
}
if (this.options.generator) {
this.generator = new this.options.generator(this.driver, this.config.getNamingStrategy(), this.options);
}
else if (this.options.emit === 'js' || this.options.emit === 'cjs') {
this.generator = new JSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
}
else {
this.generator = new TSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
}
}
/**
* Initial migration can be created only if:

@@ -211,58 +145,12 @@ * 1. no previous migrations were generated or executed

}
/**
* @inheritDoc
*/
async getExecuted() {
await this.ensureDatabase();
return this.storage.getExecutedMigrations();
}
async ensureDatabase() {
this.ensureMigrationsDirExists();
const created = await this.schemaGenerator.ensureDatabase();
/* v8 ignore next */
if (created) {
this.createUmzug();
async getSchemaFromSnapshot() {
if (!this.options.snapshot) {
return undefined;
}
await this.storage.ensureTable();
}
/**
* @inheritDoc
*/
async getPending() {
await this.ensureDatabase();
return this.umzug.pending();
}
/**
* @inheritDoc
*/
async up(options) {
return this.runMigrations('up', options);
}
/**
* @inheritDoc
*/
async down(options) {
return this.runMigrations('down', options);
}
getStorage() {
return this.storage;
}
resolve(params) {
const createMigrationHandler = async (method) => {
const migration = await fs.dynamicImport(params.path);
const MigrationClass = Object.values(migration).find(cls => typeof cls === 'function' && typeof cls.constructor === 'function');
const instance = new MigrationClass(this.driver, this.config);
await this.runner.run(instance, method);
};
return {
name: this.storage.getMigrationName(params.name),
up: () => createMigrationHandler('up'),
down: () => createMigrationHandler('down'),
};
}
getSchemaFromSnapshot() {
if (!this.options.snapshot || !existsSync(this.snapshotPath)) {
const snapshotPath = await this.getSnapshotPath();
const { fs } = await import('@mikro-orm/core/fs-utils');
if (!fs.pathExists(snapshotPath)) {
return undefined;
}
const data = fs.readJSONSync(this.snapshotPath);
const data = fs.readJSONSync(snapshotPath);
const schema = new DatabaseSchema(this.driver.getPlatform(), this.config.get('schema'));

@@ -289,13 +177,7 @@ const { tables, namespaces, ...rest } = data;

}
const snapshotPath = await this.getSnapshotPath();
const schema = this.schemaGenerator.getTargetSchema();
writeFileSync(this.snapshotPath, JSON.stringify(schema, null, 2));
const { fs } = await import('@mikro-orm/core/fs-utils');
await fs.writeFile(snapshotPath, JSON.stringify(schema, null, 2));
}
initialize(MigrationClass, name) {
const instance = new MigrationClass(this.driver, this.config);
return {
name: this.storage.getMigrationName(name),
up: () => this.runner.run(instance, 'up'),
down: () => this.runner.run(instance, 'down'),
};
}
async getSchemaDiff(blank, initial) {

@@ -342,3 +224,3 @@ const up = [];

dropTables: this.options.dropTables,
fromSchema: this.getSchemaFromSnapshot(),
fromSchema: await this.getSchemaFromSnapshot(),
});

@@ -353,2 +235,3 @@ up.push(...splitStatements(diff.up));

}
/* v8 ignore next */
diff.splice(i, 1);

@@ -361,45 +244,2 @@ }

}
getMigrationFilename(name) {
name = name.replace(/\.[jt]s$/, '');
return name.match(/^\d{14}$/) ? this.options.fileName(name) : name;
}
prefix(options) {
if (typeof options === 'string' || Array.isArray(options)) {
return { migrations: Utils.asArray(options).map(name => this.getMigrationFilename(name)) };
}
if (!options) {
return {};
}
if (options.migrations) {
options.migrations = options.migrations.map(name => this.getMigrationFilename(name));
}
if (options.transaction) {
delete options.transaction;
}
['from', 'to'].filter(k => options[k]).forEach(k => options[k] = this.getMigrationFilename(options[k]));
return options;
}
async runMigrations(method, options) {
await this.ensureDatabase();
if (!this.options.transactional || !this.options.allOrNothing) {
return this.umzug[method](this.prefix(options));
}
if (Utils.isObject(options) && options.transaction) {
return this.runInTransaction(options.transaction, method, options);
}
return this.driver.getConnection().transactional(trx => this.runInTransaction(trx, method, options));
}
async runInTransaction(trx, method, options) {
this.runner.setMasterMigration(trx);
this.storage.setMasterMigration(trx);
const ret = await this.umzug[method](this.prefix(options));
this.runner.unsetMasterMigration();
this.storage.unsetMasterMigration();
return ret;
}
ensureMigrationsDirExists() {
if (!this.options.migrationsList) {
fs.ensureDir(this.absolutePath);
}
}
}
{
"name": "@mikro-orm/migrations",
"type": "module",
"version": "7.0.0-dev.260",
"version": "7.0.0-dev.261",
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",

@@ -53,4 +53,3 @@ "exports": {

"dependencies": {
"@mikro-orm/sql": "7.0.0-dev.260",
"umzug": "3.8.2"
"@mikro-orm/sql": "7.0.0-dev.261"
},

@@ -61,4 +60,4 @@ "devDependencies": {

"peerDependencies": {
"@mikro-orm/core": "7.0.0-dev.260"
"@mikro-orm/core": "7.0.0-dev.261"
}
}

@@ -1,1 +0,1 @@

export type { UmzugMigration, MigrateOptions, MigrationResult, MigrationRow } from '@mikro-orm/core';
export type { MigrationInfo, MigrateOptions, MigrationResult, MigrationRow } from '@mikro-orm/core';

Sorry, the diff of this file is too big to display