We're close to v3!
This new beta version brings a lot more power and simplicity to the API. A minimal usage example is now:
const { Umzug } = require('umzug');
const umzug = new Umzug({
migrations: {
glob: 'path/to/migrations/*.js'
},
logger: console,
});Breaking changes
-
The Umzug constructor now receives a
migrations.globparameter, which is more flexible than the previouspath,patternandtraverseDirectoriesoptions (which were removed). This parameter can be a glob string (such as'**/*.migration.js') or have the form['**/*.migration.js', { cwd: 'some/path', ignore: '**/some-ignore-glob/**/*' }]. -
The Umzug constructor now receives a
migrations.resolveparameter, which is more flexible than the previouscustomResolver,wrapandnameFormatteroptions (which were removed). This parameter must be a function that receives an object with{ path, name, context }and must return an object withupanddownfunctions.pathis a string with the absolute path of the migration filenameis a string with the migration namecontextis what will be provided to the migration functions, so they can run, such asqueryInterfacefrom Sequelize, for example
-
The signature for the
upanddownmigration functions has changed. Previously, they would receive a single parameter of your choice (such asqueryInterfacefrom Sequelize, for example). That parameter is now called the migrationcontext. Now, theupanddownfunctions receive an object of the form{ name, path, context }instead of just receivingcontext, so you can also act based on the migration name and file path, if needed. One way to upgrade is to modify each of your migrations to change the function signature. Another way is to use the newmigrations.resolveparameter from the Umzug constructor, so that you automatically wrap your already existingupanddownfunctions with the new syntax. Both solutions are shown below:-
Slightly modifying each migration file:
// my-migration-12345679.js // Before: async up(queryInterface) { await queryInterface.foobar(); } // After: async up({ context: queryInterface }) { await queryInterface.foobar(); }
-
Using the new
migrations.resolveoption:const umzug = new Umzug({ migrations: { glob: 'migrations/umzug-v2-format/*.js', resolve({ path }) { // Get the `up` and `down` functions in the v2-style const { up, down } = require(path); // Return modified versions return { up: ({ context }) => up(context), down: ({ context }) => down(context) } } }, context: sequelize.getQueryInterface(), });
-
-
The
loggingoption was replaced with the newloggeroption. Instead of passing a single logging function, you can now pass a "complete" logger, which provides not onlylogbut alsowarnanderrorfunctions, for example. The default isundefined.// Before new Umzug({ logging: console.log }); new Umzug({ logging: false }); // After new Umzug({ logger: console }); new Umzug({ logger: undefined });
-
The
Umzug#executemethod was removed. UseUmzug#uporUmzug#downinstead. -
The options for
Umguz#upandUmzug#downhave changed:umzug.up({ to: 'some-name' })andumzug.down({ to: 'some-name' })are still valid.umzug.up({ from: '...' })andumzug.down({ from: '...' })are no longer supported. To run migrations out-of-order (which is not generally recommended), you can explicitly useumzug.up({ migrations: ['...'] })andumzug.down({ migrations: ['...'] }).- name matches must be exact.
umzug.up({ to: 'some-n' })will no longer match a migration calledsome-name. umzug.down({ to: 0 })is still valid butumzug.up({ to: 0 })is not.umzug.up({ migrations: ['m1', 'm2'] })is still valid but the shorthandumzug.up(['m1', 'm2'])has been removed.umzug.down({ migrations: ['m1', 'm2'] })is still valid but the shorthandumzug.down(['m1', 'm2'])has been removed.umzug.up({ migrations: ['m1', 'already-run'] })will throw an error, ifalready-runis not found in the list of pending migrations.umzug.down({ migrations: ['m1', 'has-not-been-run'] })will throw an error, ifhas-not-been-runis not found in the list of executed migrations.umzug.up({ migrations: ['m1', 'm2'], force: true })will re-apply migrationsm1andm2even if they've already been run.umzug.down({ migrations: ['m1', 'm2'], force: true })will "revert" migrationsm1andm2even if they've never been run.umzug.up({ migrations: ['m1', 'does-not-exist', 'm2'] })will throw an error if the migration name is not found. Note that the error will be thrown and no migrations run unless all migration names are found - whether or notforce: trueis added.
-
The return value of
Umzug#executed()andUmzug#pending()has changed. It now returns an object with anameproperty and, if applicable, apathproperty (this field will not be returned if the migration is not bound to a file on the filesystem). It no longer returns an object with afileproperty. -
The
migrationSortingoption was removed. The behavior can be replaced with the new (and much more powerful)Umzug#extendfunction, which creates a new Umzug instance based on your direct manipulation of the list of migrations. For example, to define a custom sorting for your migration files:const umzug = new Umzug({ migrations: { glob: 'migrations/**/*.js' }, context: sequelize.getQueryInterface(), }) .extend(migrations => migrations.sort((a, b) => b.path.localeCompare(a.path)));
-
Calling
umzug.down({ to: undefined })is now interpreted as equivalent toumzug.down(). Previously, it would be equivalent toumzug.down({ to: 0 })instead.
Features
-
Added
Umzug#extend, which creates a new Umzug instance based on your direct manipulation of the list of migrations. -
Added the
rerunoption toUmzug#upandUmzug#down, which can be one of'THROW','ALLOW','SKIP'. This lets you customize what umzug does when it is told to execute a migration that was already executed (or revert one that was not executed yet). The default is'THROW', which matches previous behavior, so this is not a breaking change.
Commits
- Prepare for v3.0.0-beta.6 release a45c4c9
- fix(deps): update dependency fs-jetpack to v3 (#260) efa8501
- docs: add example for multiple glob dirs (#343) 9e8b5dc
- feat: allow skipping re-runs (#342) 06f6b27
- feat: v3 api (#325) 34c94b2
- Update README.md (#321) ef1e0fd
- Configure Renovate (#234) f1410a3
- fix: sequelize latest (#232) a2002e8
- fix: to: undefined shouldn't be like to: 0 (#231) 1037e77
- test: code coverage (#229) 5efed93
- test: events (#225) f26ef47
- fix: workaround sequelize types in tests (#226) 03c53a8