Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add format function #196

Merged
merged 13 commits into from
Mar 29, 2020
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,14 @@ const umzug = new Umzug({
// read raw sql etc.
// See https://github.com/sequelize/umzug/tree/master/test/fixtures
// for examples.
customResolver: function (sqlPath) {
return { up: () => sequelize.query(require('fs').readFileSync(sqlPath, 'utf8')) }
customResolver: function (sqlPath) {
return { up: () => sequelize.query(require('fs').readFileSync(sqlPath, 'utf8')) };
papb marked this conversation as resolved.
Show resolved Hide resolved
}

// A function that receives the file path of the migration and returns the name of the
// migration. This can be used to remove file extensions for example.
nameFormatter: function (filePath) {
return path.parse(fileName).name;
jaulz marked this conversation as resolved.
Show resolved Hide resolved
}
}
})
Expand Down
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ module.exports = class Umzug extends EventEmitter {
* function that specifies how to get a migration object from a path. This
* should return an object of the form { up: Function, down: Function }.
* Without this defined, a regular javascript import will be performed.
* @param {Migration~nameFormatter} [options.migrations.nameFormatter] - A
* function that receives the file path of the migration and returns the name
* of the migration. This can be used to remove file extensions for example.
* @constructs Umzug
*/
constructor (options = {}) {
Expand Down Expand Up @@ -155,7 +158,7 @@ module.exports = class Umzug extends EventEmitter {
* @returns {Promise.<Migration>}
*/
executed () {
return Bluebird.resolve(this.storage.executed()).bind(this).map((file) => new Migration(file));
return Bluebird.resolve(this.storage.executed()).bind(this).map((file) => new Migration(file, this.options));
}

/**
Expand Down
22 changes: 18 additions & 4 deletions src/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,25 @@ module.exports = class Migration {
* function that specifies how to get a migration object from a path. This
* should return an object of the form { up: Function, down: Function }.
* Without this defined, a regular javascript import will be performed.
* @param {Migration~nameFormatter} [options.migrations.nameFormatter] - A
* function that receives the file path of the migration and returns the name
* of the migration. This can be used to remove file extensions for example.
* @constructs Migration
*/
constructor (path, options) {
constructor (path, options = {}) {
this.path = _path.resolve(path);
this.file = _path.basename(this.path);
this.options = options;
this.options = {
...options,
migrations: {
nameFormatter: (path) => _path.basename(path),
...options.migrations,
},
};

this.file = this.options.migrations.nameFormatter(this.path);
if (typeof this.file !== 'string') {
throw new Error(`Unexpected migration formatter result for '${this.path}': expected string, got ${typeof this.file}`);
}
}

/**
Expand Down Expand Up @@ -92,7 +105,8 @@ module.exports = class Migration {
* @returns {boolean}
*/
testFileName (needle) {
return this.file.indexOf(needle) === 0;
const formattedNeedle = this.options.migrations.nameFormatter(needle);
return this.file.indexOf(formattedNeedle) === 0;
papb marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
15 changes: 14 additions & 1 deletion test/fixtures/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFileSync } from 'fs';
import { resolve, dirname, join } from 'path';
import { resolve, dirname, join, parse } from 'path';
import { expect } from 'chai';
import Sequelize from 'sequelize';
import typescript from 'typescript';
Expand Down Expand Up @@ -32,6 +32,7 @@ describe('custom resolver', () => {
],
pattern: this.pattern,
customResolver: this.customResolver,
nameFormatter: (path) => parse(path).name,
},
storage: 'sequelize',
storageOptions: {
Expand All @@ -49,6 +50,11 @@ describe('custom resolver', () => {

expect(tables.sort()).to.deep.equal(['SequelizeMeta', 'thing', 'user']);
};
this.verifyMeta = async () => {
const [meta] = await this.sequelize.query('select * from `SequelizeMeta`');

expect(meta).to.deep.equal([ { name: '1.users' }, { name: '2.things' } ]);
};
});

it('resolves javascript files if no custom resolver is defined', async function () {
Expand All @@ -59,6 +65,7 @@ describe('custom resolver', () => {
await this.umzug().up();

await this.verifyTables();
await this.verifyMeta();
});

it('an array of migrations created manually can be passed in', async function () {
Expand All @@ -69,13 +76,15 @@ describe('custom resolver', () => {
downName: 'down',
migrations: {
wrap: fn => () => fn(this.sequelize.getQueryInterface(), this.sequelize.constructor),
nameFormatter: (path) => parse(path).name,
papb marked this conversation as resolved.
Show resolved Hide resolved
},
}),
new Migration(require.resolve('./javascript/2.things'), {
upName: 'up',
downName: 'down',
migrations: {
wrap: fn => () => fn(this.sequelize.getQueryInterface(), this.sequelize.constructor),
nameFormatter: (path) => parse(path).name,
},
}),
],
Expand All @@ -89,6 +98,7 @@ describe('custom resolver', () => {
await umzug.up();

await this.verifyTables();
await this.verifyMeta();
});

it('can resolve sql files', async function () {
Expand All @@ -101,6 +111,7 @@ describe('custom resolver', () => {
await this.umzug().up();

await this.verifyTables();
await this.verifyMeta();
});

it('can resolve typescript files', async function () {
Expand All @@ -120,6 +131,7 @@ describe('custom resolver', () => {
await this.umzug().up();

await this.verifyTables();
await this.verifyMeta();
});

it('can resolve coffeescript files', async function () {
Expand All @@ -139,5 +151,6 @@ describe('custom resolver', () => {
await this.umzug().up();

await this.verifyTables();
await this.verifyMeta();
});
});