{"id":20020593,"url":"https://github.com/sleavely/exodus-migrations","last_synced_at":"2025-05-05T01:30:41.605Z","repository":{"id":42869394,"uuid":"258530957","full_name":"Sleavely/exodus-migrations","owner":"Sleavely","description":"🧘 Framework-agnostic 🛬 migrations 🛫 for NodeJS","archived":false,"fork":false,"pushed_at":"2023-03-04T14:13:57.000Z","size":1223,"stargazers_count":4,"open_issues_count":23,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-21T09:05:39.719Z","etag":null,"topics":["cli","migrations","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sleavely.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-24T14:12:14.000Z","updated_at":"2023-03-04T03:32:17.000Z","dependencies_parsed_at":"2023-02-05T07:00:59.921Z","dependency_job_id":null,"html_url":"https://github.com/Sleavely/exodus-migrations","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fexodus-migrations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fexodus-migrations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fexodus-migrations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fexodus-migrations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sleavely","download_url":"https://codeload.github.com/Sleavely/exodus-migrations/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252422921,"owners_count":21745515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","migrations","nodejs"],"created_at":"2024-11-13T08:33:07.408Z","updated_at":"2025-05-05T01:30:41.134Z","avatar_url":"https://github.com/Sleavely.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# exodus\n\n\u003e Framework-agnostic migrations\n\n[ ![npm version](https://img.shields.io/npm/v/exodus.svg?style=flat) ](https://npmjs.org/package/exodus \"View this project on npm\") [ ![CircleCI](https://img.shields.io/circleci/build/github/Sleavely/exodus-migrations?token=22848581bf01ecc38384dd7f568a8404e84c21d2) ](https://circleci.com/gh/Sleavely/exodus-migrations)\n\n[Github](https://github.com/Sleavely/exodus-migrations) | [NPM](https://www.npmjs.com/package/exodus) | [Changelog](https://github.com/Sleavely/exodus-migrations/releases)\n\n## Install\n\n```\n$ npm i -g exodus\n```\n\nNode 10+ is recommended.\n\n## Usage\n\nExodus allows you to create migration definitions, modules that allow you to introduce version-controlled changes in your application, such as adding a field to a database or changing a configuration for your e-commerce.\n\nExodus was largely inspired by the flexibility and user experience of [`migrat`](https://github.com/naturalatlas/migrat), and much of the configurable behavior and templates have been forked from there.\n\n\n### CLI\n\n```\n$ exodus --help\n\n  Usage\n    $ exodus \u003caction\u003e\n\n  Possible actions\n    init              Adds a config file in your project directory\n    create \u003cname\u003e     Creates a new file in your migrations dir\n    migrate           Runs all remaining migrations\n\n  Options\n    --help\n\n  For more information, see:\n  https://github.com/Sleavely/exodus-migrations\n```\n\n\n### Migrations\n\nA migration definition is a regular Node module that exposes an `up()` method that introduces a change, and a `down()` method that allows the user (that's you!) to reverse the change later.\n\nAn example migration might look like:\n\n```js\nconst { load, save } = require('../utils/db-methods')\n//Apply the change\nexports.up = async () =\u003e {\n  const users = await load('users')\n  for (let user of users) {\n    user.age = user.age + 1\n  }\n  await save('users', users)\n}\n\n// Revert the change\nexports.down = async () =\u003e {\n  const users = await load('users')\n  for (let user of users) {\n    user.age = user.age - 1\n  }\n  await save('users', users)\n}\n```\n\n\n### Configuration\n\nThe `init` command will create a configuration file in your current directory.\n\nAll properties are optional.\n\n```js\nmodule.exports = exports = {\n  /**\n   * @name migrationsDirectory\n   *\n   * The folder to store migration scripts in,\n   * relative to your configuration file.\n   */\n  // migrationsDirectory: './migrations',\n\n  /**\n   * @name context\n   *\n   * Invoked at the beginning of a run, this method can return\n   * an object with any details you want passed through to all\n   * migrations, such as database connections, loggers, etc.\n   *\n   * @return {object}\n   */\n  // context: async () =\u003e { return {} },\n\n  /**\n   * @name storeState\n   *\n   * Called to persist current migration state. Use this to store\n   * the `state` argument in Redis, to disk, your database etc.\n   * If undefined, Exodus falls back to exodus.state.json\n   *\n   * @param state The state object to be stored.\n   * @param context The object you returned in `context`\n   */\n  // storeState: async (state, context) =\u003e {},\n\n  /**\n   * @name fetchState\n   *\n   * This method is responsible for fetching the current\n   * migration state, persisted by `storeState`.\n   * If undefined, Exodus falls back to exodus.state.json\n   *\n   * @param context The object you returned in `context`\n   * @return {object}\n   */\n  // fetchState: async (context) =\u003e {},\n\n  /**\n   * @name beforeAll\n   *\n   * Executed right before any of the queued migrations are run.\n   *\n   * @param {migrationJob[]}\n   */\n  // beforeAll: async (pendingMigrations) =\u003e {},\n\n  /**\n   * @name beforeEach\n   *\n   * Executed before each migration.\n   *\n   * @param {migrationJob}\n   */\n  // beforeEach: async (migrationJob) =\u003e {},\n\n  /**\n   * @name afterEach\n   *\n   * Executed after each migration.\n   *\n   * @param {migrationJob}\n   */\n  // afterEach: async (migrationJob) =\u003e {},\n\n  /**\n   * @name afterAll\n   *\n   * Executed after the final pending migration was run.\n   *\n   * @param {migrationJob[]}\n   */\n  // afterAll: async (pendingMigrations) =\u003e {},\n\n}\n```\n\n### Examples\n\nSee the [examples directory](./examples) for guides on use-cases the community has found helpful.\n\n\n## Contributing\n\nOpen source software is awesome, and so are you!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleavely%2Fexodus-migrations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleavely%2Fexodus-migrations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleavely%2Fexodus-migrations/lists"}