fewer
Version:
A minimal ORM for Node.js.
128 lines • 4.29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CONTAINS_IRREVERSIBLE = Symbol('irreversible');
class MigrationBuilder {
constructor(direction, isChangeMigration) {
this.operations = [];
this.direction = direction;
this.isChangeMigration = isChangeMigration;
}
get flipped() {
return this.isChangeMigration && this.direction === 'down';
}
addOperation(operation) {
this.operations.push(operation);
return this;
}
createTable(name, options, columns) {
if (this.flipped) {
return this.addOperation({
type: 'dropTable',
name,
options,
columns,
});
}
else {
return this.addOperation({
type: 'createTable',
name,
options,
columns,
});
}
}
dropTable(name, options, columns) {
if (this.flipped) {
if (options && columns) {
return this.addOperation({
type: 'createTable',
name,
options,
columns,
});
}
else {
throw new Error('Change migration containing `dropTable` is not reversible. You must provide the table options and columns to the dropTable to allow the migration to be reversed.');
}
}
else {
return this.addOperation({
type: 'dropTable',
name,
options,
columns,
});
}
}
}
exports.MigrationBuilder = MigrationBuilder;
class Migration {
constructor(version, database, definition) {
this.version = version;
this.database = database;
this.definition = definition;
this.type = definition.type;
this.operations = [];
}
/**
* Prepares the migration to be run. Populates the operations.
*/
prepare(direction) {
this.operations = [];
const builder = new MigrationBuilder(direction, this.definition.type === 'change');
const columnTypes = this.database.adapter.ColumnTypes;
if (this.definition.type === 'change') {
this.definition.change(builder, columnTypes);
}
else if (this.definition.type === 'irreversible') {
if (direction === 'down') {
throw new Error('Attempting to rollback an irreversible migration.');
}
this.definition.up(builder, columnTypes);
}
else {
this.definition[direction](builder, columnTypes);
}
this.operations.push(...builder.operations);
}
/**
* Runs the migration against the underlying adapter.
*/
async run(direction) {
this.prepare(direction);
const hasVersion = await this.database.adapter.migrateHasVersion(String(this.version));
if (direction === 'up' && hasVersion) {
throw new Error('This migration has already been run on the database.');
}
else if (direction === 'down' && !hasVersion) {
throw new Error('This migration has not yet been run, it cannot be run down.');
}
await this.database.adapter.migrate(direction, this);
if (direction === 'up') {
await this.database.adapter.migrateAddVersion(String(this.version));
}
else {
await this.database.adapter.migrateRemoveVersion(String(this.version));
}
}
}
exports.Migration = Migration;
function createMigration(version, db, definition) {
// Accept shorthand to define change migraitons:
if (typeof definition === 'function') {
const change = definition;
definition = {
change,
};
}
const type = definition.hasOwnProperty('change')
? 'change'
: definition.hasOwnProperty('down')
? 'updown'
: 'irreversible';
const taggedDefinition = Object.assign({}, definition, { type });
return new Migration(version, db, taggedDefinition);
}
exports.createMigration = createMigration;
//# sourceMappingURL=index.js.map