migrator-js
v5.2.1
Published
Simple extensible one-way migration tool for performing various tasks in order in multiple environments.
Downloads
27
Readme
Simple extensible node migrator library.
Simple extensible one-way migration tool for performing various tasks in order in multiple environments.
- Can be used for running any kind of tasks that need to be executed on multiple environments.
- Works great for migrating database schemas and data but also for changing image file formats etc.
- The storage method is extensive so the information about which migrations have been carried out can be stored anywhere (database, simple file etc).
- Has built-in TypeORM storage that can use MySQL / MariaDB / Postgres / SQLite / Microsoft SQL Server / Oracle / WebSQL.
- Each migration is a simple async function receiving a custom context and returning anything serializable for success or throwing error on failure.
- Written in TypeScript.
- Includes 100% test coverage.
Installation
This package is distributed via npm
npm install migrator-js
Commands
yarn start
to start the example application.yarn build
to build the production version.yarn test
to run tests.yarn coverage
to gather code coverage.yarn lint
to lint the codebase.yarn prettier
to run prettier.yarn audit
to run all pre-commit checks (prettier, build, lint, test)
Example migration script
import { IMigrationContext } from "../";
export default async (context: IMigrationContext): Promise<string> => {
// run any query, crop images etc
const sum = await context.connection.query("SELECT 1+1 AS sum");
return `1+1=${sum}`;
};
Example script that runs chosen migrations
Store it in src/scripts/migrate.ts
etc and add NPM script to run it.
package.json
{
"scripts": {
"migrate": "yarn build && node build/example"
}
}
src/scripts/migrate.ts
import chalk from "chalk";
import path from "path";
import { Migrator, MigratorTypeormStorage } from "../src";
// the contents of this file is usually kept in scripts/migrate.ts etc file and run through NPM scripts
// any context resources passed on to all migrations
export interface MigrationContext {
version: string;
}
async function run() {
// show an empty line between previous content
console.log("");
// create migrator
const migrator = new Migrator<MigrationContext>(
// this is the custom context matching MigrationContext
{
version: "1",
},
// migrator configuration
{
// pattern for finding the migration scripts
pattern: path.join(__dirname, "migrations", "!(*.spec|*.test|*.d).{ts,js}"),
// you can use MySQL / MariaDB / Postgres / SQLite / Microsoft SQL Server / Oracle / WebSQL
// see http://typeorm.io
storage: new MigratorTypeormStorage({
type: "sqlite",
database: path.join(__dirname, "..", "..", "migrate.sqlite3"),
}),
},
);
// attempt to run the migrator
try {
// run migrator providing pattern of migration files, storage to use and context to pass to each migration
// run the migrations and extract results
const { pendingMigrations, chosenMigrations, performedMigrations, failedMigrations } = await migrator.migrate();
// print results to console
if (pendingMigrations.length === 0) {
console.error(`${chalk.black.bgWhite(` NOTHING TO MIGRATE `)} `);
} else if (chosenMigrations.length === 0) {
console.error(`${chalk.black.bgWhite(` NO MIGRATIONS CHOSEN `)} `);
} else if (performedMigrations.length > 0 && failedMigrations.length === 0) {
console.error(`${chalk.black.bgGreen(` ALL MIGRATIONS SUCCEEDED `)} - ${performedMigrations.length} total`);
} else if (performedMigrations.length === 0 && failedMigrations.length > 0) {
console.error(`${chalk.black.bgRed(` ALL MIGRATIONS FAILED `)} - ${failedMigrations.length} total`);
} else {
console.error(
`${chalk.black.bgYellow(` SOME MIGRATIONS FAILED `)} - ${performedMigrations.length} succeeded, ${
failedMigrations.length
} failed`,
);
}
// exit with a non-zero code if any of the migrations failed
if (failedMigrations.length === 0) {
process.exit(0);
} else {
process.exit(1);
}
} catch (e) {
console.error(`${chalk.black.bgRed(` RUNNING MIGRATOR FAILED `)}`, e.stack);
} finally {
// gracefully close the connection
await migrator.close();
}
}
run().catch(e => console.error(chalk.black.bgRed(` RUNNING MIGRATOR FAILED `), e.stack));