Skip to content

Commit

Permalink
feat(cli): support NodeJS callback style migration functions
Browse files Browse the repository at this point in the history
  • Loading branch information
joakimbeng committed Nov 16, 2023
1 parent 0c49249 commit 8dadfe9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/blue-steaks-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@emigrate/cli': minor
---

Support migration functions using the old NodeJS callback style API, i.e. accepting a callback as a single parameter which in turns takes any error as its first parameter (any other parameters are ignored)
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ It's effectively a successor of [klei-migrate](https://www.npmjs.com/package/kle
- Emigrate makes sure the migration history does not get stuck in a locked state if that's the case
- Supports any file type for your migration files
- You can easily write migrations in JavaScript, TypeScript or plain SQL (or any other language)
- JavaScript migration files written using CommonJS or ES modules (ESM) are supported out of the box
- You can customize the template for your migration files to fit your needs (or use a plugin to do it for you)
- Easy to debug
- Emigrate will store any errors that occur during migration in the migration history so you can easily debug them
Expand Down
22 changes: 19 additions & 3 deletions packages/cli/src/plugin-loader-js.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import { promisify } from 'node:util';
import { type LoaderPlugin } from '@emigrate/plugin-tools/types';

// eslint-disable-next-line @typescript-eslint/ban-types
const promisifyIfNeeded = <T extends Function>(fn: T) => {
if (fn.length === 0) {
return fn;
}

if (fn.length === 1) {
return promisify(fn);
}

throw new Error(
`Unexpected arguments length of migration function, expected 0 or 1 argument but got: ${fn.length} arguments`,
);
};

const loaderJs: LoaderPlugin = {
loadableExtensions: ['.js', '.cjs', '.mjs'],
async loadMigration(migration) {
const migrationModule: unknown = await import(migration.filePath);

if (typeof migrationModule === 'function') {
return async () => {
await migrationModule();
await promisifyIfNeeded(migrationModule)();
};
}

Expand All @@ -19,7 +35,7 @@ const loaderJs: LoaderPlugin = {
) {
const migrationFunction = migrationModule.default;
return async () => {
await migrationFunction();
await promisifyIfNeeded(migrationFunction)();
};
}

Expand All @@ -31,7 +47,7 @@ const loaderJs: LoaderPlugin = {
) {
const migrationFunction = migrationModule.up;
return async () => {
await migrationFunction();
await promisifyIfNeeded(migrationFunction)();
};
}

Expand Down

0 comments on commit 8dadfe9

Please sign in to comment.