{"_id":"@alcyone-labs/postgres-shift-ts","name":"@alcyone-labs/postgres-shift-ts","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@alcyone-labs/postgres-shift-ts","version":"1.0.0","description":"A simple, forward-only migration tool for PostgreSQL using postgres.js, callable via CLI or MCP","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"bin":{"migrate":"dist/migrate.mjs"},"author":{"name":"Rasmus Porsager","email":"rasmus@porsager.com"},"contributors":[{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"}],"maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"license":"MIT","repository":{"type":"git","url":"git+ssh://git@github.com/Alcyone-Labs/postgres-shift-ts.git"},"homepage":"https://github.com/Alcyone-Labs/postgres-shift-ts/","bugs":{"url":"https://github.com/Alcyone-Labs/postgres-shift-ts/issues"},"keywords":["migration","postgresql","postgres.js","postgres","database","sql","cli","forward-only","schema","db"],"dependencies":{"@alcyone-labs/arg-parser":"^2.1.1","dotenv":"^17.2.0","postgres":"^3.4.7"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^4.5.1","@types/node":"^22.16.4","prettier":"^3.6.2","prettier-plugin-embed":"^0.5.0","prettier-plugin-sql":"^0.19.2","tsdown":"^0.12.9","typescript":"^5.8.3","vite-tsconfig-paths":"^5.1.4","vitest":"^3.2.4"},"scripts":{"test:watch":"vitest","test:run":"vitest run","test:ui":"vitest --ui","test:integration":"bun run ./scripts/test-integration.ts","format":"prettier . --write","check:cir-dep":"madge ./ -c --ts-config tsconfig.json","check:types":"tsc --project ./tsconfig.json","build:checks":"pnpm check:cir-dep && pnpm check:types","build:tsdown":"tsdown","build":"pnpm build:checks && pnpm build:tsdown"},"_id":"@alcyone-labs/postgres-shift-ts@1.0.0","_integrity":"sha512-zb0u3d70Bh1kr75cL2HagEqolJsvrnMCWIHhSVxH3ESrVFgEQu7BTllKCHAM8R1BGZadnigkum1dW8WaXRyhcg==","_resolved":"/private/var/folders/27/xlh5p6rd54vgnqk_t2kq551c0000gn/T/087322c222f813acc43e7fd690d4cbd9/alcyone-labs-postgres-shift-ts-1.0.0.tgz","_from":"file:alcyone-labs-postgres-shift-ts-1.0.0.tgz","_nodeVersion":"22.17.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-zb0u3d70Bh1kr75cL2HagEqolJsvrnMCWIHhSVxH3ESrVFgEQu7BTllKCHAM8R1BGZadnigkum1dW8WaXRyhcg==","shasum":"1d466f659810bb95b5ac4cca11d26dcab6094153","tarball":"https://registry.npmjs.org/@alcyone-labs/postgres-shift-ts/-/postgres-shift-ts-1.0.0.tgz","fileCount":12,"unpackedSize":38516,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICTuJ40rYx4oDOgTumQ50rQ13wcfkOSmE17ENrKMvPcXAiEA+gRsFJtOLtm0IFVDdhV6tQbW5H+IKE7LVq3CYwZTMT4="}]},"_npmUser":{"name":"nembleton","email":"nicolas.embleton@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/postgres-shift-ts_1.0.0_1752740058206_0.7901044969819833"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-17T08:14:18.098Z","1.0.0":"2025-07-17T08:14:18.387Z","modified":"2025-07-17T08:14:18.692Z"},"maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"description":"A simple, forward-only migration tool for PostgreSQL using postgres.js, callable via CLI or MCP","homepage":"https://github.com/Alcyone-Labs/postgres-shift-ts/","keywords":["migration","postgresql","postgres.js","postgres","database","sql","cli","forward-only","schema","db"],"repository":{"type":"git","url":"git+ssh://git@github.com/Alcyone-Labs/postgres-shift-ts.git"},"contributors":[{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"}],"author":{"name":"Rasmus Porsager","email":"rasmus@porsager.com"},"bugs":{"url":"https://github.com/Alcyone-Labs/postgres-shift-ts/issues"},"license":"MIT","readme":"# postgres-shift\n\nA simple, forward-only migration tool for PostgreSQL ported from [postgres.js](https://github.com/porsager/postgres) to TypeScript and extended to have more features, and ported to [@alcyone-labs/arg-parser](https://github.com/alcyone-labs/arg-parser) as a CLI handler, making it MCP-compatible out-of-the-box.\n\n## Features\n\n- Forward-only migrations (no rollbacks)\n- Schema-based organization\n- Both SQL and JavaScript migrations\n- CLI tool and programmatic API\n- Built specifically for postgres.js\n- TypeScript support\n- MCP support\n\n## Installation\n\n```bash\npnpm add @alcyone-labs/postgres-shift-ts\n# or\nnpm install @alcyone-labs/postgres-shift-ts\n# or\nyarn add @alcyone-labs/postgres-shift-ts\n# or\nbun add @alcyone-labs/postgres-shift-ts\n# or\ndeno add npm:@alcyone-labs/postgres-shift-ts\n```\n\n## Quick Start\n\n### CLI Usage\n\n0. Check options\n\n```bash\nnpx migrate --help\n# or\npnpx migrate --help\n```\n\n1. Set your database connection string:\n\n```bash\nexport DB_CONNECTION_STRING=\"postgres://username:password@localhost:5432/database\"\n```\n\n2. Create migration directories:\n\n```\nsrc/db/migrations/\n├── public/\n│   ├── 00001_create_users_table/\n│   │   └── index.sql\n│   └── 00002_add_email_index/\n│       └── index.sql\n└── analytics/\n    └── 00001_create_events_table/\n        └── index.sql\n```\n\n3. Run migrations:\n\n```bash\nnpx migrate --path src/db/migrations\n# or\npnpx migrate --path src/db/migrations\n```\n\n### Programmatic Usage\n\n```typescript\nimport postgres from \"postgres\";\nimport shift from \"@ophiuchus/postgres-shift\";\n\nconst sql = postgres(\"postgres://username:password@localhost:5432/database\");\n\nawait shift({\n  sql,\n  path: \"./migrations/public\",\n  schema: \"public\",\n  before: (migration) => console.log(`Running: ${migration.name}`),\n  after: (migration) => console.log(`Completed: ${migration.name}`),\n});\n```\n\n## Migration Structure\n\n### Directory Organization\n\nMigrations are organized by schema, with each migration in its own numbered directory:\n\n```\nmigrations/\n├── public/                    # Schema name\n│   ├── 00001_initial_schema/  # Migration directory (5-digit prefix)\n│   │   └── index.sql         # SQL migration\n│   ├── 00002_add_users/\n│   │   └── index.sql\n│   └── 00003_complex_migration/\n│       └── index.js          # JavaScript migration\n└── analytics/\n    └── 00001_create_tables/\n        └── index.sql\n```\n\n### Naming Convention\n\n- Migration directories must start with a 5-digit number: `00001_`, `00002_`, etc.\n- Numbers must be consecutive (no gaps)\n- Use descriptive names after the number: `00001_create_users_table`\n- Underscores in names are converted to spaces in the migration log\n\n### SQL Migrations\n\nCreate an `index.sql` file in your migration directory:\n\n```sql\n-- 00001_create_users_table/index.sql\nCREATE TABLE users (\n  id SERIAL PRIMARY KEY,\n  email VARCHAR(255) UNIQUE NOT NULL,\n  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n);\n\nCREATE INDEX idx_users_email ON users(email);\n```\n\n### JavaScript Migrations\n\nCreate an `index.js` file that exports a default function:\n\n```javascript\n// 00002_seed_data/index.js\nexport default async function (sql) {\n  await sql`\n    INSERT INTO users (email) VALUES\n    ('admin@example.com'),\n    ('user@example.com')\n  `;\n\n  // You can perform complex logic here\n  const users = await sql`SELECT * FROM users`;\n  console.log(`Seeded ${users.length} users`);\n}\n```\n\n## CLI Reference\n\n### migrate\n\nRun database migrations for all schemas in the specified directory.\n\n```bash\nnpx migrate [options]\n```\n\n#### Options\n\n- `--path, -p, --migrations <path>` - Path to migrations directory (default: `src/db/migrations`)\n\n#### Environment Variables\n\n- `DB_CONNECTION_STRING` - PostgreSQL connection string (required)\n\n#### Examples\n\n```bash\n# Use default path\nnpx migrate\n\n# Specify custom path\nnpx migrate --path ./db/migrations\n\n# Using environment file\nDB_CONNECTION_STRING=\"postgres://localhost/mydb\" npx migrate\n```\n\n## API Reference\n\n### shift(options)\n\nMain migration function.\n\n#### Parameters\n\n- `sql` (Sql) - postgres.js database connection\n- `path` (string) - Path to migration files for a specific schema\n- `schema` (string) - PostgreSQL schema name (default: 'public')\n- `before` (function, optional) - Callback called before each migration\n- `after` (function, optional) - Callback called after each migration\n\n#### Returns\n\nPromise that resolves when all migrations are complete.\n\n#### Example\n\n```typescript\nimport postgres from \"postgres\";\nimport shift from \"@ophiuchus/postgres-shift\";\n\nconst sql = postgres(process.env.DATABASE_URL);\n\ntry {\n  await shift({\n    sql,\n    path: \"./migrations/public\",\n    schema: \"public\",\n    before: ({ migration_id, name, path }) => {\n      console.log(`Starting migration ${migration_id}: ${name}`);\n    },\n    after: ({ migration_id, name, path }) => {\n      console.log(`Completed migration ${migration_id}: ${name}`);\n    },\n  });\n  console.log(\"All migrations completed successfully\");\n} catch (error) {\n  console.error(\"Migration failed:\", error);\n  process.exit(1);\n}\n```\n\n### Migration Object\n\nThe migration object passed to `before` and `after` callbacks:\n\n```typescript\ntype TMigration = {\n  path: string; // Full path to migration directory\n  migration_id: number; // Numeric ID from directory name\n  name: string; // Migration name (underscores converted to spaces)\n};\n```\n\n## How It Works\n\n1. **Discovery**: Scans the specified directory for migration folders matching the pattern `/^[0-9]{5}_/`\n2. **Validation**: Ensures migration numbers are consecutive with no gaps\n3. **Tracking**: Creates a `migrations` table in the target schema to track completed migrations\n4. **Execution**: Runs migrations in order, skipping those already completed\n5. **Recording**: Records each successful migration in the tracking table\n\n### Migration Table Schema\n\n```sql\nCREATE TABLE migrations (\n  migration_id SERIAL PRIMARY KEY,\n  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),\n  name TEXT\n);\n```\n\n## Error Handling\n\n- **Missing consecutive numbers**: Throws error if migration numbers have gaps\n- **Schema creation**: Automatically creates the target schema if it doesn't exist\n- **Transaction safety**: Each migration runs in its own transaction\n- **Rollback**: Failed migrations are automatically rolled back\n\n## Best Practices\n\n1. **Never modify completed migrations** - Always create new migrations for changes\n2. **Use descriptive names** - Make migration purposes clear from the directory name\n3. **Keep migrations small** - One logical change per migration\n4. **Test migrations** - Run against a copy of production data\n5. **Backup before running** - Always backup production databases first\n\n## Development\n\n### Running Tests\n\n```bash\npnpm test:run\n```\n\n### Building\n\n```bash\npnpm build:tsup\n```\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines before submitting PRs.\n\n## Credits\n\nOriginally forked from [postgres-shift](https://github.com/porsager/postgres-shift) by Rasmus Porsager.\n","readmeFilename":"README.md","_rev":"1-86ecfa8888d07ba4437effea78726819"}