{"id":45047512,"url":"https://github.com/jmcantrell/node-postgres-migrator","last_synced_at":"2026-02-19T08:17:49.560Z","repository":{"id":57328757,"uuid":"314330307","full_name":"jmcantrell/node-postgres-migrator","owner":"jmcantrell","description":"Simple database migrations for PostgreSQL.","archived":false,"fork":false,"pushed_at":"2020-11-23T01:35:24.000Z","size":384,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-11T07:41:22.163Z","etag":null,"topics":["database","migration","nodejs","postgres","postgresql"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmcantrell.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-11-19T18:04:32.000Z","updated_at":"2020-11-23T01:35:26.000Z","dependencies_parsed_at":"2022-09-05T14:01:35.212Z","dependency_job_id":null,"html_url":"https://github.com/jmcantrell/node-postgres-migrator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jmcantrell/node-postgres-migrator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmcantrell%2Fnode-postgres-migrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmcantrell%2Fnode-postgres-migrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmcantrell%2Fnode-postgres-migrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmcantrell%2Fnode-postgres-migrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmcantrell","download_url":"https://codeload.github.com/jmcantrell/node-postgres-migrator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmcantrell%2Fnode-postgres-migrator/sbom","scorecard":{"id":524087,"data":{"date":"2025-08-11","repo":{"name":"github.com/jmcantrell/node-postgres-migrator","commit":"811eaec03ffd0d43520f7310f5d5a7c53d48700c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: The Unlicense: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"19 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-px4h-xg32-q955","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-38fc-wpqx-33j7","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T03:54:06.438Z","repository_id":57328757,"created_at":"2025-08-20T03:54:06.438Z","updated_at":"2025-08-20T03:54:06.438Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29608206,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T06:47:36.664Z","status":"ssl_error","status_checked_at":"2026-02-19T06:45:47.551Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["database","migration","nodejs","postgres","postgresql"],"created_at":"2026-02-19T08:17:48.724Z","updated_at":"2026-02-19T08:17:49.552Z","avatar_url":"https://github.com/jmcantrell.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# postgres-migrator\n\nSimple database migrations for PostgreSQL.\n\n## Getting started\n\n### Install\n\n```bash\n$ npm install postgres postgres-migrator\n```\n\n### Example\n\n```js\nconst postgres = require(\"postgres\");\nconst postgresMigrator = require(\"postgres-migrator\");\n\nconst sql = postgres();\nconst migrator = postgresMigrator(sql);\n\nconst migrated = await migrator.apply();\n```\n\n## Behavior\n\nMigration is one-way. There is no ability to reverse a migration, as\nthis is rarely used, and is better handled with a new migration that\nreverts a previous one.\n\nDirectories being migrated are expected to contain zero or more\nmigration files. Any unrecognized file types will be ignored.\n\nMigration files are sorted before being applied, so you can be certain\nthat `001.sql` will be applied before `002.sql`.\n\nAs you would expect, only unapplied migrations will be applied.\n\nEach migration is run in a database transaction. Any errors\nencountered are left uncaught and migration ceases at that point.\nMigrations completed previously are left applied, and once the error\nis corrected, `migrator.apply` can be run again and migration will\ncontinue from the last migration that was successfully applied.\n\nEach migrator instance represents a directory of migration files. If\nyou need to support multiple directories, you can create a migrator\ninstance for each directory with a different table name.\n\nOnly the filename of the migration file is recorded, so relocating or\nrenaming the directory will not affect the tracking.\n\nMigrations are tracked using a database table named `migrations`\n(configurable).\n\nMigrations are assumed to be in the directory `./migrations`\n(configurable).\n\n### Migration files\n\n#### SQL migration files\n\nSQL migration files are just plain `sql`, as you would expect. The\nonly restriction is that they have the extension \".sql\" (lower case).\n\nAn example `sql` migration file might be `010-users-table-add-email.sql`:\n\n```sql\nalter table users add column email text not null unique;\n```\n\n#### JavaScript migration files\n\nJavaScript migration files are `javascript` modules that export a\ndefault function (can be async) that takes as its only argument an\ninstance of a postgres client (typically named `sql`).\n\nSee the [postgres][1] documentation for its capabilities.\n\nIf a promise is returned, it will be `await`ed.\n\nThe filename's extension must be `.js`, `.cjs`, or `.mjs`.\n\nThe file can be CommonJS (`module.exports`) or ES Module\n(`import`/`export`) syntax.\n\nAn example `javascript` migration file might be `010-users-table-add-email.js`:\n\n```js\nmodule.exports = (sql) =\u003e {\n\treturn sql`alter table users add column email text not null unique`;\n};\n```\n\n## API\n\n### Creating a migrator object\n\n```js\nconst migrator = postgresMigrator(sql, { ...options });\n```\n\nThe first argument must be a [postgres][1] client object.\n\nThe second argument is an optional options object with the following\ndefault properties:\n\n```js\nconst migrator = postgresMigrator(sql, {\n\ttable: \"migrations\",\n\tdirectory: \"./migrations\",\n\tlogger: undefined,\n});\n```\n\nThe `logger` option, if defined, is expected to be a standard logging\nobject. For example, if you want to log activity using `console`, you\nwould do the following:\n\n```js\nconst migrator = postgresMigrator(sql, { logger: console });\n```\n\nCurrently the only thing logged is the filename of the migration that\nis about to be applied.\n\n### Applying migrations\n\n```js\nconst migrated = await migrator.apply();\n```\n\nIf needed, the return value is an array of migration files that were\napplied during that function call.\n\n### Testing if a file has been migrated\n\n```js\nconst exists = await migrator.has(filename);\n```\n\n### Getting all migrated files\n\n```js\nconst migrated = await migrator.all();\n```\n\n## Recommendations\n\n### Creating migration files\n\nTo reduce confusion, new migration files should be sorted after old\nones. You can ensure this by using a shell function like the following to\ngenerate new migrations that are sorted by the timestamp when they\nwere created:\n\n```bash\nfunction mkmigration() {\n\tlocal name=$1\n\tlocal ext=${2:-sql}\n\tlocal ts=$(date +%Y%m%d%H%M%S)\n\ttouch \"${PWD}/migrations/${ts}.${ext}\"\n}\n```\n\nThis will allow you to do the following:\n\n```bash\n$ mkmigration users-table\n$ ls migrations\n20201225103045-users-table.sql\n```\n\nObviously this could be easily tailored to your project, such as using\na template for new migrations or a different way to establish proper\nsorting.\n\n### Command-line interface\n\nI originally planned to include a command-line interface, but could\nnot decide how to make it flexible enough. I'll leave it to you to\ndecide how best to implement that for your project, but the following\nshould be sufficient for most:\n\n```js\n#!/usr/bin/env node\n\nconst postgres = require(\"postgres\");\nconst postgresMigrator = require(\"postgres-migrator\");\n\nconst sql = postgres(process.env.POSTGRES_URL);\nconst migrator = createMigrator(sql, { logger: console });\n\nmigrator\n\t.apply()\n\t.catch((error) =\u003e {\n\t\tlogger.error(error);\n\t\tprocess.exit(1);\n\t})\n\t.finally(sql.end);\n```\n\nObviously this could be easily tailored to your project, such as using\na command-line parser to allow options to be configurable, or\nmigrating multiple directories.\n\n## Contributing\n\n### Testing\n\nTest files expect the environment variable `POSTGRES_URL` to point to\nyour database. No existing tables will be affected, including\n`migrations`, as unique table names are used and dropped after the\ntest finishes.\n\nA docker compose file is included which provisions a database that's\nconfigured as expected:\n\n```bash\n$ docker-compose up\n```\n\nTo run tests:\n\n```bash\n$ npm test\n```\n\n[1]: https://github.com/porsager/postgres/blob/master/README.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmcantrell%2Fnode-postgres-migrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmcantrell%2Fnode-postgres-migrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmcantrell%2Fnode-postgres-migrator/lists"}