UNPKG

ts-migrate-mongoose

Version:

A migration framework for Mongoose, built with TypeScript.

292 lines (224 loc) 10.5 kB
# ts-migrate-mongoose A migration framework for Mongoose, built with TypeScript. [![npm](https://img.shields.io/npm/v/ts-migrate-mongoose)](https://www.npmjs.com/package/ts-migrate-mongoose) [![npm](https://img.shields.io/npm/dt/ts-migrate-mongoose)](https://www.npmjs.com/package/ts-migrate-mongoose) [![GitHub](https://img.shields.io/github/license/ilovepixelart/ts-migrate-mongoose)](https://github.com/ilovepixelart/ts-migrate-mongoose/blob/main/LICENSE) \ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ilovepixelart_ts-migrate-mongoose&metric=coverage)](https://sonarcloud.io/summary/new_code?id=ilovepixelart_ts-migrate-mongoose) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ilovepixelart_ts-migrate-mongoose&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ilovepixelart_ts-migrate-mongoose) \ [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=ilovepixelart_ts-migrate-mongoose&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=ilovepixelart_ts-migrate-mongoose) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=ilovepixelart_ts-migrate-mongoose&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=ilovepixelart_ts-migrate-mongoose) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=ilovepixelart_ts-migrate-mongoose&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=ilovepixelart_ts-migrate-mongoose) ## Features - Stores migration state in MongoDB - Flexible configuration using `migrate.json`, `migrate.ts`, `.env` - Utilizes mongoose models during migrations - Supports async/await in migrations - Run migrations from the CLI or programmatically - Prune old migrations and sync new migrations - Create custom templates for migrations - Run individual migration up/down using -s, --single - Supports ESM and CommonJS ## Example How to use it with: - Express: [ts-express-tsx](https://github.com/ilovepixelart/ts-express-tsx), [ts-express-esbuild](https://github.com/ilovepixelart/ts-express-esbuild) - Nest: [ts-express-nest](https://github.com/ilovepixelart/ts-express-nest) ## Installation - Locally inside your project ```bash npm install ts-migrate-mongoose pnpm add ts-migrate-mongoose yarn add ts-migrate-mongoose bun add ts-migrate-mongoose ``` - Install it globally ```bash npm install -g ts-migrate-mongoose pnpm add -g ts-migrate-mongoose yarn global add ts-migrate-mongoose bun add -g ts-migrate-mongoose ``` ## Migrations and alias imports If you are using alias imports in your project, you can use `tsconfig.json` paths to resolve them for your project. ## Configuration If you don't want to provide `-d` or `--uri` flag in CLI or Programmatic mode, you can configure it. \ Create a `migrate.json` or `migrate.ts` or `.env` file in the root of your project: - `migrate.json` ```json { "uri": "mongodb://localhost/my-db", "collection": "migrations", "migrationsPath": "./migrations", "templatePath": "./migrations/template.ts", "autosync": false } ``` - `migrate.ts` ```typescript export default { uri: "mongodb://localhost/my-db", collection: "migrations", migrationsPath: "./migrations", templatePath: "./migrations/template.ts", autosync: false, }; ``` - `.env` ```bash # You can set this variable or in your CI/CD pipeline # Or use --mode flag in CLI mode to switch between .env files MIGRATE_MODE=development ``` If mode is set, it will look for `.env.[mode]` file in the root of your project \ For example, if `MIGRATE_MODE=development` it will look for `.env.development` file \ If mode is not set, it will look for `.env` file in the root of your project ```bash .env # loaded in all cases .env.local # loaded in all cases (used as override for local development) .env.[mode] # only loaded in specified mode .env.[mode].local # only loaded in specified mode (used as override for local development) ``` ```bash # Example .env file content MIGRATE_MONGO_URI=mongodb://localhost/my-db MIGRATE_MONGO_COLLECTION=migrations MIGRATE_CONFIG_PATH=./migrate MIGRATE_MIGRATIONS_PATH=./migrations MIGRATE_TEMPLATE_PATH=./migrations/template.ts MIGRATE_AUTOSYNC=false ``` | Config file | `.env` / export | Default | Required | Description | | -------------------- | ------------------------ | ------------ | -------- | ------------------------------------------------ | | mode | MIGRATE_MODE | - | No | environment mode to use .env.[mode] file | | uri | MIGRATE_MONGO_URI | - | Yes | mongo connection string | | collection | MIGRATE_MONGO_COLLECTION | migrations | No | collection name to use for the migrations | | configPath | MIGRATE_CONFIG_PATH | - | No | will lookup ./migrate[.ts,.js,.json] in root | | migrationsPath | MIGRATE_MIGRATIONS_PATH | ./migrations | No | path to the migration files | | templatePath | MIGRATE_TEMPLATE_PATH | - | No | template file to use when creating a migration | | autosync | MIGRATE_AUTOSYNC | false | No | automatically sync new migrations without prompt | ## Getting started with the CLI Explore and learn commands, rest of the tutorial will be using npm ```bash npx migrate -h pnpm migrate -h yarn migrate -h bun migrate -h ``` ```text CLI migration tool for mongoose Options: -f, --config-path <path> path to the config file -d, --uri <string> mongo connection string -c, --collection <string> collection name to use for the migrations -a, --autosync <boolean> automatically sync new migrations without prompt -m, --migrations-path <path> path to the migration files -t, --template-path <path> template file to use when creating a migration --mode <string> environment mode to use .env.[mode] file -h, --help display help for command Commands: list list all migrations create <migration-name> create a new migration file up [options] [migration-name] run all migrations or a specific migration if name is provided down [options] <migration-name> roll back migrations down to given name prune delete extraneous migrations from migration folder or database help [command] display help for command ``` Before you start make sure you setup .env file or migrate.ts/json file so you don't need to provide -d on each command ```bash npx migrate create add-users -d mongodb://localhost/my-db ``` In case you want to run just one migration up or down use option --single ```bash npx migrate create first-migration npx migrate create second-migration npx migrate list npx migrate up second-migration -s # will migrate up only second-migration npx migrate down second-migration -s # will migrate down only second-migration npx migrate up -s # will migrate up first-migration ``` ## Options override order Note that options are overridden in the following order: - Command line args > Env vars > Config file ## Migration files This example demonstrates how you can create a migration file using the CLI \ By default, ts-migrate-mongoose assumes your migration folder exists (if it does not it will create one for you) Here's an example of a migration created using: ```bash npx migrate create first-migration pnpm migrate create first-migration yarn migrate create first-migration bun migrate create first-migration ``` Executing the above command will create a migration file in the `./migrations` folder with the following content: - 1673525773572-first-migration.ts ```typescript // Import your schemas here import type { Connection } from 'mongoose' export async function up (connection: Connection): Promise<void> { // Write migration here } export async function down (connection: Connection): Promise<void> { // Write migration here } ``` ## Using mongoose models in your migrations As long as you can import the references to your models you can use them in migrations \ Below is an example of a typical setup in a mongoose project: - models/User.ts - defines the User model ```typescript import { Schema, model, models } from 'mongoose' interface IUser { firstName: string lastName?: string } export const UserSchema = new Schema<IUser>({ firstName: { type: String, required: true }, lastName: { type: String } }) export default models.User ?? model<IUser>('User', UserSchema) ``` - 1673525773572-first-migration-demo.ts - your migration file ```typescript import { UserSchema } from '../models/User' import type { Connection } from 'mongoose' export async function up(connection: Connection) { const User = connection.model('User', UserSchema) await User.create([ { firstName: 'John', lastName: 'Doe', }, { firstName: 'Jane', lastName: 'Doe', }, ]) } export async function down(connection: Connection) { const User = connection.model('User', UserSchema) await User.deleteMany({ firstName: { $in: ['Jane', 'John'] } }).exec() } ``` ## Contributing We welcome contributions from the community. Please read our [Contributing Guidelines](CONTRIBUTING.md) before submitting a pull request. ## Code of Conduct Please read our [Code of Conduct](CODE_OF_CONDUCT.md) to understand the expectations we have for everyone who participates in our community. ## Notes - Currently, the `-d` or `--uri` must include the database to use for migrations in the uri. - Example: `-d mongodb://localhost:27017/development` - If you don't want to pass it every time feel free to use `migrate.ts` or `migrate.json` config file or an environment variable - Feel Free to check out the `/examples` folder in the project to get a better idea of usage in Programmatic and CLI mode ## Check my other projects - [ts-patch-mongoose](https://github.com/ilovepixelart/ts-patch-mongoose) - Patch history & events plugin for mongoose - [ts-cache-mongoose](https://github.com/ilovepixelart/ts-cache-mongoose) - Cache plugin for mongoose Queries and Aggregate (in-memory, redis)