diff --git a/README.md b/README.md index 273098f..6935902 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,22 @@ Migrations.add({ }); ``` -For Meteor 2.8+ you can pass async function directly. +Starting from Meteor 2.8+, you can use async functions directly in your migrations: + +```js +Migrations.add({ + version: 3, + name: 'Add belts to people wearing pants.', + up: async function () { + // Asynchronous migration code + await SomeCollection.updateAsync({ wearsPants: true }, { $set: { hasBelt: true } }, { multi: true }); + }, + down: async function () { + // Asynchronous rollback code + await SomeCollection.updateAsync({}, { $unset: { hasBelt: true } }, { multi: true }); + }, +}); +``` * Note: You may want to call migration after startup in case your host (such as Heroku) limits the amount of time given for startup ``` javascript diff --git a/migrations_server.js b/migrations_server.js index b5f6111..5375499 100644 --- a/migrations_server.js +++ b/migrations_server.js @@ -7,37 +7,50 @@ import { Log } from 'meteor/logging'; Adds migration capabilities. Migrations are defined like: Migrations.add({ - up: function() {}, //*required* code to run to migrate upwards version: 1, //*required* number to identify migration order - down: function() {}, //*optional* code to run to migrate downwards - name: 'Something' //*optional* display name for the migration + name: 'Something', //*optional* display name for the migration + up: async function() { //*required* code to run to migrate upwards + // Your migration code here + // This function can be asynchronous + }, + down: async function() { //*optional* code to run to migrate downwards + // Your migration rollback code here + // This function can be asynchronous + } }); The ordering of migrations is determined by the version you set. To run the migrations, set the MIGRATE environment variable to either 'latest' or the version number you want to migrate to. Optionally, append - ',exit' if you want the migrations to exit the meteor process, e.g if you're + ',exit' if you want the migrations to exit the Meteor process, e.g., if you're migrating from a script (remember to pass the --once parameter). - e.g: - MIGRATE="latest" mrt # ensure we'll be at the latest version and run the app - MIGRATE="latest,exit" mrt --once # ensure we'll be at the latest version and exit - MIGRATE="2,exit" mrt --once # migrate to version 2 and exit + e.g.: + MIGRATE="latest" meteor # ensure we'll be at the latest version and run the app + MIGRATE="latest,exit" meteor --once # ensure we'll be at the latest version and exit + MIGRATE="2,exit" meteor --once # migrate to version 2 and exit - Note: Migrations will lock ensuring only 1 app can be migrating at once. If + Note: Migrations will lock ensuring only one app can be migrating at once. If a migration crashes, the control record in the migrations collection will - remain locked and at the version it was at previously, however the db could - be in an inconsistent state. + remain locked and at the version it was at previously; however, the database + could be in an inconsistent state. + + **Async Migrations**: + - The `up` and `down` functions can be asynchronous (return a Promise or be async functions). + - The migration runner will await these functions, ensuring that migrations run sequentially + and complete before the next one starts. */ -// since we'll be at version 0 by default, we should have a migration set for -// it. const DefaultMigration = { version: 0, up: function() {} }; /** * - * @type {{_list: {up: DefaultMigration.up, version: number}[], options: {logIfLatest: boolean, log: boolean, logger: null, collectionName: string}, config: Migrations.config}} + * @type {{ + * _list: {up: DefaultMigration.up, version: number}[], + * options: {logIfLatest: boolean, log: boolean, logger: null, collectionName: string}, + * config: Migrations.config + * }} */ export const Migrations = { _list: [DefaultMigration], @@ -98,21 +111,21 @@ let log; Meteor.startup(async function() { const options = Migrations.options; - // collection holding the control record + // Collection holding the control record Migrations._collection = new Mongo.Collection(options.collectionName); log = createLogger('Migrations'); ['info', 'warn', 'error', 'debug'].forEach(function(level) { - log[level] = (message) => log(level, message) + log[level] = (message) => log(level, message); }); if (process.env.MIGRATE) { try { await Migrations.migrateTo(process.env.MIGRATE); } catch (e) { - log.error('Failed to run migrations') - log.error(e.message || e.reason) + log.error('Failed to run migrations'); + log.error(e.message || e.reason); } } }); @@ -121,9 +134,9 @@ Meteor.startup(async function() { * Add a new migration * @param migration {Object} * @param migration.version {Number} required - * @param migration.up {function} required migration function * @param migration.name {String} Optional name for the migration step - * @param migration.down {function} Optional function to migrate back from this step to previous version + * @param migration.up {function} required migration function (can be async) + * @param migration.down {function} Optional function to migrate back from this step to previous version (can be async) */ Migrations.add = function(migration) { if (typeof migration.up !== 'function') @@ -139,18 +152,24 @@ Migrations.add = function(migration) { Object.freeze(migration); this._list.push(migration); - this._list.sort((a, b) => (a.version > b.version) ? 1 : ((b.version > a.version) ? -1 : 0)); + this._list.sort((a, b) => + a.version > b.version ? 1 : b.version > a.version ? -1 : 0, + ); }; /** * Attempts to run the migrations using command in the form of: - * e.g 'latest', 'latest,exit', 2 + * e.g., 'latest', 'latest,exit', 2 * use 'XX,rerun' to re-run the migration at that version * @param command {string|number} * @returns {Promise} */ Migrations.migrateTo = async function(command) { - if (typeof command === 'undefined' || command === '' || this._list.length === 0) + if ( + typeof command === 'undefined' || + command === '' || + this._list.length === 0 + ) throw new Error('Cannot migrate using invalid command: ' + command); let version; @@ -158,31 +177,31 @@ Migrations.migrateTo = async function(command) { if (typeof command === 'number') { version = command; } else { - version = command.split(',')[0]; //.trim(); - subcommand = command.split(',')[1]; //.trim(); + version = command.split(',')[0]; + subcommand = command.split(',')[1]; } if (version === 'latest') { - await this._migrateTo(this._list[this._list.length -1].version); + await this._migrateTo(this._list[this._list.length - 1].version); } else { await this._migrateTo(parseInt(version), subcommand === 'rerun'); } - // remember to run meteor with --once otherwise it will restart + // Remember to run Meteor with --once otherwise it will restart if (subcommand === 'exit') process.exit(0); }; /** * Just returns the current version - * @returns {Promise} + * @returns {Promise} */ Migrations.getVersion = async function() { - const control = await this._getControl() + const control = await this._getControl(); return control.version; }; /** - * migrates to the specific version passed in + * Migrates to the specific version passed in * @param version {number} * @param rerun {boolean} * @returns {Promise} @@ -193,7 +212,7 @@ Migrations._migrateTo = async function(version, rerun) { const control = await this._getControl(); // Side effect: upserts control document. let currentVersion = control.version; - //Avoid unneeded locking, check if migration actually is going to run + // Avoid unneeded locking, check if migration actually is going to run if (!rerun && currentVersion === version) { if (Migrations.options.logIfLatest) { log.info('Not migrating, already at version ' + version); @@ -201,17 +220,23 @@ Migrations._migrateTo = async function(version, rerun) { return; } - const isLock = await lock() - if (isLock === false) { + const isLocked = await lock(); + if (isLocked === false) { log.info('Not migrating, control is locked.'); return; } if (rerun) { log.info('Rerunning version ' + version); - migrate('up', this._findIndexByVersion(version)); - log.info('Finished migrating.'); - await unlock(); + try { + await migrate('up', this._findIndexByVersion(version)); + log.info('Finished migrating.'); + } catch (error) { + log.error('Migration failed:', error); + throw error; + } finally { + await unlock(); + } return; } @@ -220,20 +245,25 @@ Migrations._migrateTo = async function(version, rerun) { // log.info('startIdx:' + startIdx + ' endIdx:' + endIdx); log.info( - 'Migrating from version ' + + 'Migrating from version ' + this._list[startIdx].version + ' -> ' + this._list[endIdx].version, ); - // run the actual migration - function migrate(direction, idx) { + // Run the actual migration + /** + * Runs a single migration step. + * @param direction {'up'|'down'} + * @param idx {number} Index in the migration list + */ + async function migrate(direction, idx) { const migration = self._list[idx]; if (typeof migration[direction] !== 'function') { - unlock(); + await unlock(); throw new Meteor.Error( - 'Cannot migrate ' + direction + ' on version ' + migration.version, + 'Cannot migrate ' + direction + ' on version ' + migration.version, ); } @@ -242,14 +272,15 @@ Migrations._migrateTo = async function(version, rerun) { } log.info( - 'Running ' + + 'Running ' + direction + '() on version ' + migration.version + maybeName(), ); - migration[direction](migration); + // Await the migration function to ensure it completes + await migration[direction](migration); } // Returns true if lock was acquired. @@ -257,12 +288,11 @@ Migrations._migrateTo = async function(version, rerun) { // This is atomic. The selector ensures only one caller at a time will see // the unlocked control, and locking occurs in the same update's modifier. // All other simultaneous callers will get false back from the update. - return ( - await self._collection.updateAsync( + const result = await self._collection.updateAsync( { _id: 'control', locked: false }, { $set: { locked: true, lockedAt: new Date() } }, - ) === 1 ); + return result === 1; } // Side effect: saves version. @@ -274,37 +304,42 @@ Migrations._migrateTo = async function(version, rerun) { await self._setControl({ locked: true, version: currentVersion }); } - if (currentVersion < version) { - for (let i = startIdx; i < endIdx; i++) { - migrate('up', i + 1); - currentVersion = self._list[i + 1].version; - await updateVersion(); - } - } else { - for (let i = startIdx; i > endIdx; i--) { - migrate('down', i); - currentVersion = self._list[i - 1].version; - await updateVersion(); + try { + if (currentVersion < version) { + for (let i = startIdx; i < endIdx; i++) { + await migrate('up', i + 1); + currentVersion = self._list[i + 1].version; + await updateVersion(); + } + } else { + for (let i = startIdx; i > endIdx; i--) { + await migrate('down', i); + currentVersion = self._list[i - 1].version; + await updateVersion(); + } } + log.info('Finished migrating.'); + } catch (error) { + log.error('Migration failed:', error); + throw error; + } finally { + await unlock(); } - - await unlock(); - log.info('Finished migrating.'); }; /** - * gets the current control record, optionally creating it if non-existent + * Gets the current control record, optionally creating it if non-existent * @returns {Promise<{ version: number, locked: boolean }>} * @private */ Migrations._getControl = async function() { const control = await this._collection.findOneAsync({ _id: 'control' }); - return control || await this._setControl({ version: 0, locked: false }); + return control || (await this._setControl({ version: 0, locked: false })); }; /** - * sets the control record + * Sets the control record * @param control {Object} * @param control.version {number} * @param control.locked {boolean} @@ -312,14 +347,20 @@ Migrations._getControl = async function() { * @private */ Migrations._setControl = async function(control) { - // be quite strict + // Be quite strict check(control.version, Number); check(control.locked, Boolean); await this._collection.updateAsync( - { _id: 'control' }, - { $set: { version: control.version, locked: control.locked } }, - { upsert: true }, + { _id: 'control' }, + { + $set: { + version: control.version, + locked: control.locked, + lockedAt: new Date(), + }, + }, + { upsert: true }, ); return control; @@ -340,7 +381,7 @@ Migrations._findIndexByVersion = function(version) { }; /** - * reset (mainly intended for tests) + * Reset (mainly intended for tests) * @returns {Promise} * @private */ @@ -350,9 +391,12 @@ Migrations._reset = async function() { }; /** - * unlock control + * Unlock control * @returns {Promise} */ Migrations.unlock = async function() { - return await this._collection.updateAsync({ _id: 'control' }, { $set: { locked: false } }); -}; + return await this._collection.updateAsync( + { _id: 'control' }, + { $set: { locked: false } }, + ); +}; \ No newline at end of file diff --git a/migrations_tests.js b/migrations_tests.js index 0a7b6ee..1335a2d 100644 --- a/migrations_tests.js +++ b/migrations_tests.js @@ -1,201 +1,208 @@ /* global Tinytest */ -import { Migrations } from './migrations_server' +import { Migrations } from './migrations_server'; -Tinytest.addAsync('Migrates up once and only once.', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Migrates up once and only once with async up function.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); - // first one + // First migration with async up function Migrations.add({ - up: function() { + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 100)); // Simulate async operation run.push('u1'); }, version: 1, }); - // migrates once + // Migrate up await Migrations.migrateTo('latest'); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); - // shouldn't do anything + // Shouldn't do anything since we're already at the latest version await Migrations.migrateTo('latest'); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); }); -Tinytest.addAsync('Migrates up once and back down.', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Migrates up once and back down with async up and down functions.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); - // first one + // Migration with async up and down functions Migrations.add({ - up: function() { + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 100)); // Simulate async operation run.push('u1'); }, - down: function() { + down: async function () { + await new Promise((resolve) => setTimeout(resolve, 100)); // Simulate async operation run.push('d1'); }, version: 1, }); + // Migrate up await Migrations.migrateTo('latest'); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); - // shouldn't do anything + // Migrate down await Migrations.migrateTo('0'); test.equal(run, ['u1', 'd1']); test.equal(await Migrations.getVersion(), 0); }); -Tinytest.addAsync('Migrates up several times.', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Migrates up several times with async migrations.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); - // first one + // First migration Migrations.add({ - up: function() { + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 50)); // Simulate async operation run.push('u1'); }, version: 1, }); - // migrates once + // Migrate up await Migrations.migrateTo('latest'); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); - // add two more, out of order + // Add two more migrations out of order Migrations.add({ - up: function() { + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 50)); run.push('u4'); }, version: 4, }); Migrations.add({ - up: function() { + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 50)); run.push('u3'); }, version: 3, }); - // should run the next two nicely in order + // Migrate up to latest await Migrations.migrateTo('latest'); test.equal(run, ['u1', 'u3', 'u4']); test.equal(await Migrations.getVersion(), 4); }); -Tinytest.addAsync('Tests migrating down', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Tests migrating down with async down function.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); - // add the migrations + // Add migrations Migrations.add({ - up: function() { + up: async function () { run.push('u1'); }, version: 1, }); Migrations.add({ - up: function() { + up: async function () { run.push('u2'); }, version: 2, }); Migrations.add({ - up: function() { + up: async function () { run.push('u3'); }, - down: function() { + down: async function () { + await new Promise((resolve) => setTimeout(resolve, 50)); run.push('d3'); }, version: 3, - name: 'Down Migration', //give it a name, just for shits + name: 'Down Migration', // Give it a name }); - // migrates up + // Migrate up await Migrations.migrateTo('latest'); test.equal(run, ['u1', 'u2', 'u3']); test.equal(await Migrations.getVersion(), 3); - // migrates down + // Migrate down to version 2 await Migrations.migrateTo('2'); test.equal(run, ['u1', 'u2', 'u3', 'd3']); test.equal(await Migrations.getVersion(), 2); - // should throw as migration u2 has no down method and remain at the save ver - await test.throwsAsync(async function() { + // Should throw since migration u2 has no down method + await test.throwsAsync(async function () { await Migrations.migrateTo('1'); }, /Cannot migrate/); test.equal(run, ['u1', 'u2', 'u3', 'd3']); test.equal(await Migrations.getVersion(), 2); }); -Tinytest.addAsync('Tests migrating down to version 0', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Tests migrating down to version 0 with async down functions.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); test.equal(await Migrations.getVersion(), 0); Migrations.add({ - up: function() { + up: async function () { run.push('u1'); }, - down: function() { + down: async function () { run.push('d1'); }, version: 1, }); - // migrates up + // Migrate up await Migrations.migrateTo('latest'); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); - // migrates down + // Migrate down to version 0 await Migrations.migrateTo(0); test.equal(run, ['u1', 'd1']); test.equal(await Migrations.getVersion(), 0); }); -Tinytest.addAsync('Checks that locking works correctly', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Checks that locking works correctly with async migrations.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); - // add the migrations + // Add migration that attempts to start another migration within it Migrations.add({ version: 1, - up: async function() { + up: async function () { run.push('u1'); - // attempts a migration from within the migration, this should have no - // effect due to locking + // Attempts a migration from within the migration, this should have no effect due to locking await Migrations.migrateTo('latest'); }, }); - // migrates up, should only migrate once + // Migrate up, should only migrate once await Migrations.migrateTo('latest'); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); }); -Tinytest.addAsync('Checks that version is updated if subsequent migration fails', async function(test) { +Tinytest.addAsync('Checks that version is updated if subsequent async migration fails.', async function (test) { const run = []; let shouldError = true; await Migrations._reset(); - // add the migrations + // Add migrations Migrations.add({ version: 1, - up: function() { + up: async function () { run.push('u1'); }, }); Migrations.add({ version: 2, - up: function() { + up: async function () { if (shouldError) { throw new Error('Error in migration'); } @@ -203,37 +210,37 @@ Tinytest.addAsync('Checks that version is updated if subsequent migration fails' }, }); - // migrate up, which should throw - await test.throwsAsync(async function() { + // Migrate up, which should throw + await test.throwsAsync(async function () { await Migrations.migrateTo('latest'); }); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); shouldError = false; - // migrate up again, should succeed + // Migrate up again, should succeed await Migrations.unlock(); await Migrations.migrateTo('latest'); test.equal(run, ['u1', 'u2']); test.equal(await Migrations.getVersion(), 2); }); -Tinytest.addAsync('Does nothing for no migrations.', async function(test) { +Tinytest.addAsync('Does nothing for no migrations.', async function (test) { await Migrations._reset(); - // shouldnt do anything + // Shouldn't do anything await Migrations.migrateTo('latest'); test.equal(await Migrations.getVersion(), 0); }); -Tinytest.addAsync('Checks that rerun works correctly', async function(test) { - const run = []; //keeps track of migrations in here +Tinytest.addAsync('Checks that rerun works correctly with async migrations.', async function (test) { + const run = []; // Keeps track of migrations await Migrations._reset(); - // add the migrations + // Add migration Migrations.add({ version: 1, - up: function() { + up: async function () { run.push('u1'); }, }); @@ -242,152 +249,141 @@ Tinytest.addAsync('Checks that rerun works correctly', async function(test) { test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); - // shouldn't migrate + // Shouldn't migrate await Migrations.migrateTo(1); test.equal(run, ['u1']); test.equal(await Migrations.getVersion(), 1); - // should migrate again + // Should migrate again with rerun await Migrations.migrateTo('1,rerun'); test.equal(run, ['u1', 'u1']); test.equal(await Migrations.getVersion(), 1); }); -Tinytest.addAsync( - 'Checks that rerun works even if there are missing versions', - async function(test) { - const run = []; //keeps track of migrations in here - await Migrations._reset(); +Tinytest.addAsync('Checks that rerun works even if there are missing versions.', async function (test) { + const run = []; // Keeps track of migrations + await Migrations._reset(); + + // Add migration with a missing step + Migrations.add({ + version: 3, + up: async function () { + run.push('u1'); + }, + }); + + await Migrations.migrateTo('latest'); + test.equal(run, ['u1']); + test.equal(await Migrations.getVersion(), 3); - // add the migration with a missing step - Migrations.add({ - version: 3, - up: function() { - run.push('u1'); - }, - }); + // Shouldn't migrate + await Migrations.migrateTo(3); + test.equal(run, ['u1']); + test.equal(await Migrations.getVersion(), 3); - await Migrations.migrateTo('latest'); - test.equal(run, ['u1']); - test.equal(await Migrations.getVersion(), 3); - - // shouldn't migrate - await Migrations.migrateTo(3); - test.equal(run, ['u1']); - test.equal(await Migrations.getVersion(), 3); - - // should migrate again - await Migrations.migrateTo('3,rerun'); - test.equal(run, ['u1', 'u1']); - test.equal(await Migrations.getVersion(), 3); - }, -); - -Tinytest.addAsync( - 'Migration callbacks include the migration as an argument', - async function(test) { - let contextArg; - await Migrations._reset(); - - // add the migrations - const migration = { - version: 1, - up: function(m) { - contextArg = m; - }, - }; - Migrations.add(migration); - - await Migrations.migrateTo(1); - test.equal(contextArg === migration, true); - }, -); - -Tinytest.addAsync('Migrations can log to injected logger', async function( - test, - done, -) { + // Should migrate again with rerun + await Migrations.migrateTo('3,rerun'); + test.equal(run, ['u1', 'u1']); + test.equal(await Migrations.getVersion(), 3); +}); + +Tinytest.addAsync('Migration callbacks include the migration as an argument.', async function (test) { + let contextArg; + await Migrations._reset(); + + // Add migration + const migration = { + version: 1, + up: async function (m) { + contextArg = m; + }, + }; + Migrations.add(migration); + + await Migrations.migrateTo(1); + test.equal(contextArg === migration, true); +}); + +Tinytest.addAsync('Migrations can log to injected logger.', async function (test) { await Migrations._reset(); - // Ensure this logging code only runs once. More than once and we get - // Tinytest errors that the test "returned multiple times", or "Trace: event - // after complete!". Give me a ping, Vasili. One ping only, please. let calledDone = false; - Migrations.options.logger = function() { + Migrations.options.logger = function () { if (!calledDone) { calledDone = true; test.isTrue(true); - done(); } }; - Migrations.add({ version: 1, up: function() {} }); + Migrations.add({ version: 1, up: async function () {} }); await Migrations.migrateTo(1); Migrations.options.logger = null; }); -Tinytest.addAsync( - 'Migrations should pass correct arguments to logger', - async function(test, done) { - await Migrations._reset(); - - // Ensure this logging code only runs once. More than once and we get - // Tinytest errors that the test "returned multiple times", or "Trace: event - // after complete!". Give me a ping, Vasili. One ping only, please. - let calledDone = false; - const logger = function(opts) { - if (!calledDone) { - calledDone = true; - test.include(opts, 'level'); - test.include(opts, 'message'); - test.include(opts, 'tag'); - test.equal(opts.tag, 'Migrations'); - done(); - } - }; +Tinytest.addAsync('Migrations should pass correct arguments to logger.', async function (test) { + await Migrations._reset(); - Migrations.options.logger = logger; + let calledDone = false; + const logger = function (opts) { + if (!calledDone) { + calledDone = true; + test.include(opts, 'level'); + test.include(opts, 'message'); + test.include(opts, 'tag'); + test.equal(opts.tag, 'Migrations'); + } + }; - Migrations.add({ version: 1, up: function() {} }); - await Migrations.migrateTo(1); + Migrations.options.logger = logger; - Migrations.options.logger = null; - }, -); + Migrations.add({ version: 1, up: async function () {} }); + await Migrations.migrateTo(1); -Tinytest.addAsync('Async migrations', async function(test) { + Migrations.options.logger = null; +}); + +Tinytest.addAsync('Async migrations execute in order.', async function (test) { await Migrations._reset(); - let num = 10 + const run = []; Migrations.add({ version: 1, - up: async function() { - num = 20 + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 100)); + run.push('u1'); }, - down: async function () { - num = 10 - } }); - await Migrations.migrateTo(1); - test.equal(num, 20) + Migrations.add({ + version: 2, + up: async function () { + await new Promise((resolve) => setTimeout(resolve, 50)); + run.push('u2'); + }, + }); - await Migrations.migrateTo(0); - test.equal(num, 10) -}) - -// Tinytest.addAsync('Fail migration when not a function', async function(test) { -// await Migrations._reset(); -// -// Migrations.add({ -// version: 1, -// name: 'Failure of a migration', -// up: 'this should fail' -// }); -// -// test.throwsAsync(async function() { -// await Migrations.migrateTo('latest'); -// }, /Migration must supply an up function/); -// -// }) + Migrations.add({ + version: 3, + up: async function () { + run.push('u3'); + }, + }); + + await Migrations.migrateTo('latest'); + test.equal(run, ['u1', 'u2', 'u3']); +}); + +Tinytest.addAsync('Fails migration when up is not a function.', async function (test) { + await Migrations._reset(); + + Migrations.add({ + version: 1, + name: 'Failure of a migration', + up: 'this should fail', + }); + + await test.throwsAsync(async function () { + await Migrations.migrateTo('latest'); + }, /Migration must supply an up function/); +}); \ No newline at end of file diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json deleted file mode 100644 index 32f27f7..0000000 --- a/npm-shrinkwrap.json +++ /dev/null @@ -1,734 +0,0 @@ -{ - "name": "meteor-migrations-tests", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - }, - "assertion-error": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha512-g/gZV+G476cnmtYI+Ko9d5khxSoCSoom/EaNmmCfwpOvBXEJ18qwFrxfP1/CsIqk2no1sAKKwxndV0tP7ROOFQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" - }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "chai": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", - "integrity": "sha512-olRoaitftnzWHFEAza6MXR4w+FfZrOVyV7r7U/Z8ObJefCgL8IuWkAuASJjSXrpP9wvgoL8+1dB9RbMLc2FkNg==", - "requires": { - "assertion-error": "1.0.0", - "deep-eql": "0.1.3" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg==", - "requires": { - "type-detect": "0.1.1" - } - }, - "deep-extend": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz", - "integrity": "sha512-t2N+4ihO7YgydJOUI47I6GdXpONJ+jUZmYeTNiifALaEduiCja1mKcq3tuSp0RhA9mMfxdMN3YskpwB7puMAtw==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "requires": { - "pend": "~1.2.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.6.tgz", - "integrity": "sha512-D0H1thJnOVgI0zRV3H/Vmb9HWmDgGTTR7PeT8Lk0ri2kMmfK3oKQBolfqJuRpBVpTx5Q5PKGl9hdQEQNTXJI7Q==", - "requires": { - "graceful-fs": "^3.0.2", - "inherits": "2", - "minimatch": "^1.0.0", - "once": "^1.3.0" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ==", - "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.1.0.tgz", - "integrity": "sha512-B6L/jfyFRcG2dqKiHggWnfby52Iy07iabE4F6srQAr/OmVKBRE5uU+B5MQ+nQ7NiYnjz93gENh1GhqHzpDgHgA==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==" - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "loglevel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.1.0.tgz", - "integrity": "sha512-zFPzVD3sGndaceAZW/cHlAACcsV1Lv9j7S5sOPX7/uAkipMOu4z9VhxZCDbt1J3lrMrBYPOZ7eE/Be08VZDkBQ==" - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz", - "integrity": "sha512-Ejh5Odk/uFXAj5nf/NSXk0UamqcGAfOdHI7nY0zvCHyn4f3nKLFoUTp+lYxDxSih/40uW8lpwDplOWHdWkQXWA==", - "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "requires": { - "minimist": "^1.2.6" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==", - "requires": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "requires": { - "pinkie": "^2.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==" - }, - "psext": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/psext/-/psext-0.0.4.tgz", - "integrity": "sha512-oxcbuaCIerJNNkmqVVNpAdPUYNDsoOSppYf9h1kdX7D5Vu01kfMT5M8bTiWH3+crpWdXEp0g7sxZf3efrEmb5Q==", - "requires": { - "table-parser": "0.0.3" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" - }, - "rc": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-0.5.1.tgz", - "integrity": "sha512-B1EiD9IPNyNm0i4JAdyakpxah4jNUmxbx5uhaVRmjZ/py4MnjNLxX2hyk+kTQVatPDgdquY3pat+HsGj6n87Vg==", - "requires": { - "deep-extend": "~0.2.5", - "ini": "~1.1.0", - "minimist": "~0.0.7", - "strip-json-comments": "0.1.x" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==" - } - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA==", - "requires": { - "throttleit": "^1.0.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.1.0.tgz", - "integrity": "sha512-lLkkQcdd/nO1WKpCh2rljlJ17truE0Bs2x+Nor41/yKwnYeHtyOQJqA97NP4zkez3+gJ1Uh5rUqiEOYgOBMXbw==" - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==" - }, - "spacejam": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/spacejam/-/spacejam-1.6.1.tgz", - "integrity": "sha512-cz0GFoNd+qfGIAu0Oa7gxxk+qamTmGOf25B0sgeVjjlSI5mpb2JRug4VHF26hRaZCvin0LE+HnRRiPAEDuJ59Q==", - "requires": { - "chai": "1.9.2", - "glob": "4.0.6", - "loglevel": "1.1.0", - "phantomjs-prebuilt": "^2.1.7", - "psext": "0.0.4", - "rc": "0.5.1", - "semver": "4.1.0", - "underscore": "1.7.0" - } - }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-json-comments": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", - "integrity": "sha512-d2RPtrkLs8TurFFAIhW8IdM0+cOq+QFETWBGKHO+93eZ4Zt4P1CeJB5LHKW4EfEwabEpPL8/UTO3QX94+lqxwQ==" - }, - "table-parser": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/table-parser/-/table-parser-0.0.3.tgz", - "integrity": "sha512-Bhc3OeDPu9MQqk1D9TXTewnhm43Oke0UdCStZSsAAfg38meleNUXWvdgTNPdkkeVyqeP7aUFkBGQLLuAFlN97Q==" - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA==" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha512-cp0oQQyZhUM1kpJDLdGO1jPZHgS/MpzoWYfe9+CM2h/QGDZlqwT2T3YGukuBdaNJ/CAPoeyAZRRHz8JFo176vA==" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } -} diff --git a/package-lock.json b/package-lock.json index d0c7c52..6882e19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -313,11 +313,6 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, - "jquery": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", - "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", diff --git a/package.js b/package.js index 1f3301b..b4c5f39 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: 'Define and run db migrations.', - version: '2.0.0', + version: '2.0.1', name: 'percolate:migrations', git: 'https://github.com/percolatestudio/meteor-migrations.git', });