@autofleet/sequelize-utils 6.2.0-alpha.1 → 6.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import{fork as e}from"node:child_process";import{existsSync as t,readFileSync as n,unlinkSync as r,writeFileSync as i}from"node:fs";import a from"pg";try{let e=n(`.env`,`utf8`).split(`
|
|
3
|
-
`);for(let t of e){let e=/^([^#=\s][^=]*)=(.*)$/.exec(t);if(e){let t=e[1].trim(),n=e[2].trim().replace(/^["']|["']$/g,``);t in process.env||(process.env[t]=n)}}}catch{}const o=`/tmp/__sequelize_migration_lock.pid`,s=e=>process.stdout.write(`[sequelize-utils] ${e}\n`),c=e=>process.stderr.write(`[sequelize-utils] ${e}\n`),l=e=>process.stderr.write(`[sequelize-utils] ${e}\n`);function u(e){let t={};for(let n=0;n<e.length;n++)e[n].startsWith(`--`)&&n+1<e.length&&!e[n+1].startsWith(`--`)&&(t[e[n].slice(2)]=e[n+1],n++);return t}function d(e,t,n){return process.env[e[t]??n]}async function f(e){let t=Number(d(e,`lock-key-env`,`MIGRATION_LOCK_KEY`))||1234567890,n=new a.Client({host:d(e,`db-host-env`,`DB_HOST`)??`localhost`,port:Number(d(e,`db-port-env`,`DB_PORT`))||5432,database:d(e,`db-name-env`,`DB_NAME`),user:d(e,`db-username-env`,`DB_USERNAME`),password:d(e,`db-password-env`,`DB_PASSWORD`)});await n.connect(),await n.query(`SELECT pg_advisory_lock(${t})`),process.send?.(`locked`);let r=()=>{n.query(`SELECT pg_advisory_unlock(${t})`).then(()=>n.end()).finally(()=>process.exit(0))};process.once(`SIGTERM`,r),process.once(`SIGINT`,r)}async function p(t){let n=Number(d(t,`lock-timeout-env`,`MIGRATION_LOCK_TIMEOUT_MS`))||6e4,r=Object.entries(t).flatMap(([e,t])=>[`--${e}`,t]),a=e(process.argv[1],[`--daemon`,...r],{stdio:[`ignore`,`inherit`,`inherit`,`ipc`],env:process.env,execArgv:process.execArgv});await new Promise((e,t)=>{let r=setTimeout(()=>{a.kill(),t(Error(`Timed out waiting for migration lock after ${n}ms`))},n);a.once(`message`,n=>{clearTimeout(r),n===`locked`?e():(a.kill(),t(Error(`Lock daemon error: ${JSON.stringify(n)}`)))}),a.once(`error`,e=>{clearTimeout(r),t(e)})}),i(o,String(a.pid)),a.unref(),s(`Migration lock acquired (pid=${a.pid})`)}function m(){if(!t(o)){c(`No lock file found — nothing to release`);return}let e=Number(n(o,`utf8`).trim());try{process.kill(e,`SIGTERM`)}catch{c(`Daemon pid=${e} not found (may have already exited)`)}r(o),s(`Migration lock released`)}if(process.argv.includes(`--daemon`)){let e=process.argv.indexOf(`--daemon`);f(u(process.argv.slice(e+1))).catch(e=>{l(`Lock daemon failed: ${e.message}`),process.exit(1)})}else{let[,,e,...t]=process.argv,n=u(t);switch(e){case`lock-migrations`:p(n).catch(e=>{l(e.message),process.exit(1)});break;case`unlock-migrations`:m();break;default:l(`Unknown command: ${e}`),process.stderr.write(`Usage: sequelize-utils <lock-migrations|unlock-migrations> [--db-host-env VAR] [--db-port-env VAR] [--db-name-env VAR] [--db-username-env VAR] [--db-password-env VAR]
|
|
3
|
+
`);for(let t of e){let e=/^([^#=\s][^=]*)=(.*)$/.exec(t);if(e){let t=e[1].trim(),n=e[2].trim().replace(/^["']|["']$/g,``);t in process.env||(process.env[t]=n)}}}catch{}const o=`/tmp/__sequelize_migration_lock.pid`,s=e=>process.stdout.write(`[sequelize-utils] ${e}\n`),c=e=>process.stderr.write(`[sequelize-utils] ${e}\n`),l=e=>process.stderr.write(`[sequelize-utils] ${e}\n`);function u(e){let t={};for(let n=0;n<e.length;n++)e[n].startsWith(`--`)&&n+1<e.length&&!e[n+1].startsWith(`--`)&&(t[e[n].slice(2)]=e[n+1],n++);return t}function d(e,t,n){return process.env[e[t]??n]}async function f(e){let t=Number(d(e,`lock-key-env`,`MIGRATION_LOCK_KEY`))||1234567890,n=new a.Client({host:d(e,`db-host-env`,`DB_HOST`)??`localhost`,port:Number(d(e,`db-port-env`,`DB_PORT`))||5432,database:d(e,`db-name-env`,`DB_NAME`),user:d(e,`db-username-env`,`DB_USERNAME`),password:d(e,`db-password-env`,`DB_PASSWORD`)});await n.connect(),await n.query(`SELECT pg_advisory_lock(${t})`),process.send?.(`locked`);let r=()=>{n.query(`SELECT pg_advisory_unlock(${t})`).then(()=>n.end()).finally(()=>process.exit(0))};process.once(`SIGTERM`,r),process.once(`SIGINT`,r)}async function p(t){let n=Number(d(t,`lock-timeout-env`,`MIGRATION_LOCK_TIMEOUT_MS`))||6e4,r=Object.entries(t).flatMap(([e,t])=>[`--${e}`,t]),a=e(process.argv[1],[`--daemon`,...r],{stdio:[`ignore`,`inherit`,`inherit`,`ipc`],env:process.env,execArgv:process.execArgv});await new Promise((e,t)=>{let r=setTimeout(()=>{a.kill(),t(Error(`Timed out waiting for migration lock after ${n}ms`))},n);a.once(`message`,n=>{clearTimeout(r),n===`locked`?e():(a.kill(),t(Error(`Lock daemon error: ${JSON.stringify(n)}`)))}),a.once(`error`,e=>{clearTimeout(r),t(e)})}),i(o,String(a.pid)),a.disconnect(),a.unref(),s(`Migration lock acquired (pid=${a.pid})`)}function m(){if(!t(o)){c(`No lock file found — nothing to release`);return}let e=Number(n(o,`utf8`).trim());try{process.kill(e,`SIGTERM`)}catch{c(`Daemon pid=${e} not found (may have already exited)`)}r(o),s(`Migration lock released`)}if(process.argv.includes(`--daemon`)){let e=process.argv.indexOf(`--daemon`);f(u(process.argv.slice(e+1))).catch(e=>{l(`Lock daemon failed: ${e.message}`),process.exit(1)})}else{let[,,e,...t]=process.argv,n=u(t);switch(e){case`lock-migrations`:p(n).catch(e=>{l(e.message),process.exit(1)});break;case`unlock-migrations`:m();break;default:l(`Unknown command: ${e}`),process.stderr.write(`Usage: sequelize-utils <lock-migrations|unlock-migrations> [--db-host-env VAR] [--db-port-env VAR] [--db-name-env VAR] [--db-username-env VAR] [--db-password-env VAR]
|
|
4
4
|
`),process.exit(1)}}export{};
|
|
5
5
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":["result: Args"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { fork } from 'node:child_process';\nimport { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport pg from 'pg';\n\n// Auto-load .env from the current working directory (same behaviour as dotenv).\n// Only sets variables that are not already present in process.env.\ntry {\n const lines = readFileSync('.env', 'utf8').split('\\n');\n for (const line of lines) {\n const match = /^([^#=\\s][^=]*)=(.*)$/.exec(line);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim().replace(/^[\"']|[\"']$/g, '');\n if (!(key in process.env)) {\n process.env[key] = value;\n }\n }\n }\n} catch {\n // no .env file — that's fine\n}\n\nconst LOCK_FILE = '/tmp/__sequelize_migration_lock.pid';\nconst DEFAULT_LOCK_KEY = 1_234_567_890;\nconst DEFAULT_LOCK_TIMEOUT_MS = 60_000;\n\nconst log = (msg: string) => process.stdout.write(`[sequelize-utils] ${msg}\\n`);\nconst warn = (msg: string) => process.stderr.write(`[sequelize-utils] ${msg}\\n`);\nconst fatal = (msg: string) => process.stderr.write(`[sequelize-utils] ${msg}\\n`);\n\n// ─── Arg parsing ──────────────────────────────────────────────────────────────\n\ntype Args = Record<string, string>;\n\nfunction parseArgs(argv: string[]): Args {\n const result: Args = {};\n for (let i = 0; i < argv.length; i++) {\n if (argv[i].startsWith('--') && i + 1 < argv.length && !argv[i + 1].startsWith('--')) {\n result[argv[i].slice(2)] = argv[i + 1];\n i++;\n }\n }\n return result;\n}\n\n// Resolves the value of an env var whose name may be overridden by a CLI arg.\n// e.g. --db-name-env MY_SERVICE_DB_NAME → process.env['MY_SERVICE_DB_NAME']\nfunction env(args: Args, argName: string, defaultEnvVar: string): string | undefined {\n return process.env[args[argName] ?? defaultEnvVar];\n}\n\n// ─── Daemon ───────────────────────────────────────────────────────────────────\n// Spawned as a detached subprocess by `lock-migrations`.\n// Holds a PostgreSQL session-level advisory lock for as long as it lives.\n// When killed by `unlock-migrations`, the connection closes and pg auto-releases the lock.\n\nasync function runDaemon(args: Args): Promise<void> {\n const lockKey = Number(env(args, 'lock-key-env', 'MIGRATION_LOCK_KEY')) || DEFAULT_LOCK_KEY;\n\n const client = new pg.Client({\n host: env(args, 'db-host-env', 'DB_HOST') ?? 'localhost',\n port: Number(env(args, 'db-port-env', 'DB_PORT')) || 5432,\n database: env(args, 'db-name-env', 'DB_NAME'),\n user: env(args, 'db-username-env', 'DB_USERNAME'),\n password: env(args, 'db-password-env', 'DB_PASSWORD'),\n });\n\n await client.connect();\n\n // Blocking — waits until no other pod holds the lock\n await client.query(`SELECT pg_advisory_lock(${lockKey})`);\n\n // Signal parent that the lock is held\n process.send?.('locked');\n\n const release = () => {\n void client.query(`SELECT pg_advisory_unlock(${lockKey})`)\n .then(() => client.end())\n .finally(() => process.exit(0));\n };\n\n process.once('SIGTERM', release);\n process.once('SIGINT', release);\n}\n\n// ─── lock-migrations ──────────────────────────────────────────────────────────\n\nasync function lockMigrations(args: Args): Promise<void> {\n const lockTimeoutMs = Number(env(args, 'lock-timeout-env', 'MIGRATION_LOCK_TIMEOUT_MS')) || DEFAULT_LOCK_TIMEOUT_MS;\n\n // Forward all --*-env args to the daemon so it resolves the same env vars.\n const forwardedArgs = Object.entries(args).flatMap(([k, v]) => [`--${k}`, v]);\n\n const daemon = fork(process.argv[1], ['--daemon', ...forwardedArgs], {\n stdio: ['ignore', 'inherit', 'inherit', 'ipc'],\n env: process.env,\n execArgv: process.execArgv,\n });\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n daemon.kill();\n reject(new Error(`Timed out waiting for migration lock after ${lockTimeoutMs}ms`));\n }, lockTimeoutMs);\n\n daemon.once('message', (msg) => {\n clearTimeout(timeout);\n if (msg === 'locked') {\n resolve();\n } else {\n daemon.kill();\n reject(new Error(`Lock daemon error: ${JSON.stringify(msg)}`));\n }\n });\n\n daemon.once('error', (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n\n writeFileSync(LOCK_FILE, String(daemon.pid));\n daemon.unref();\n\n log(`Migration lock acquired (pid=${daemon.pid})`);\n}\n\n// ─── unlock-migrations ────────────────────────────────────────────────────────\n\nfunction unlockMigrations(): void {\n if (!existsSync(LOCK_FILE)) {\n warn('No lock file found — nothing to release');\n return;\n }\n\n const pid = Number(readFileSync(LOCK_FILE, 'utf8').trim());\n\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n warn(`Daemon pid=${pid} not found (may have already exited)`);\n }\n\n unlinkSync(LOCK_FILE);\n log('Migration lock released');\n}\n\n// ─── Entry point ──────────────────────────────────────────────────────────────\n\nif (process.argv.includes('--daemon')) {\n const daemonArgIdx = process.argv.indexOf('--daemon');\n const args = parseArgs(process.argv.slice(daemonArgIdx + 1));\n runDaemon(args).catch((err: Error) => {\n fatal(`Lock daemon failed: ${err.message}`);\n process.exit(1);\n });\n} else {\n const [,, command, ...rest] = process.argv;\n const args = parseArgs(rest);\n\n switch (command) {\n case 'lock-migrations':\n lockMigrations(args).catch((err: Error) => {\n fatal(err.message);\n process.exit(1);\n });\n break;\n\n case 'unlock-migrations':\n unlockMigrations();\n break;\n\n default:\n fatal(`Unknown command: ${command}`);\n process.stderr.write('Usage: sequelize-utils <lock-migrations|unlock-migrations> [--db-host-env VAR] [--db-port-env VAR] [--db-name-env VAR] [--db-username-env VAR] [--db-password-env VAR]\\n');\n process.exit(1);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":["result: Args"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { fork } from 'node:child_process';\nimport { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport pg from 'pg';\n\n// Auto-load .env from the current working directory (same behaviour as dotenv).\n// Only sets variables that are not already present in process.env.\ntry {\n const lines = readFileSync('.env', 'utf8').split('\\n');\n for (const line of lines) {\n const match = /^([^#=\\s][^=]*)=(.*)$/.exec(line);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim().replace(/^[\"']|[\"']$/g, '');\n if (!(key in process.env)) {\n process.env[key] = value;\n }\n }\n }\n} catch {\n // no .env file — that's fine\n}\n\nconst LOCK_FILE = '/tmp/__sequelize_migration_lock.pid';\nconst DEFAULT_LOCK_KEY = 1_234_567_890;\nconst DEFAULT_LOCK_TIMEOUT_MS = 60_000;\n\nconst log = (msg: string) => process.stdout.write(`[sequelize-utils] ${msg}\\n`);\nconst warn = (msg: string) => process.stderr.write(`[sequelize-utils] ${msg}\\n`);\nconst fatal = (msg: string) => process.stderr.write(`[sequelize-utils] ${msg}\\n`);\n\n// ─── Arg parsing ──────────────────────────────────────────────────────────────\n\ntype Args = Record<string, string>;\n\nfunction parseArgs(argv: string[]): Args {\n const result: Args = {};\n for (let i = 0; i < argv.length; i++) {\n if (argv[i].startsWith('--') && i + 1 < argv.length && !argv[i + 1].startsWith('--')) {\n result[argv[i].slice(2)] = argv[i + 1];\n i++;\n }\n }\n return result;\n}\n\n// Resolves the value of an env var whose name may be overridden by a CLI arg.\n// e.g. --db-name-env MY_SERVICE_DB_NAME → process.env['MY_SERVICE_DB_NAME']\nfunction env(args: Args, argName: string, defaultEnvVar: string): string | undefined {\n return process.env[args[argName] ?? defaultEnvVar];\n}\n\n// ─── Daemon ───────────────────────────────────────────────────────────────────\n// Spawned as a detached subprocess by `lock-migrations`.\n// Holds a PostgreSQL session-level advisory lock for as long as it lives.\n// When killed by `unlock-migrations`, the connection closes and pg auto-releases the lock.\n\nasync function runDaemon(args: Args): Promise<void> {\n const lockKey = Number(env(args, 'lock-key-env', 'MIGRATION_LOCK_KEY')) || DEFAULT_LOCK_KEY;\n\n const client = new pg.Client({\n host: env(args, 'db-host-env', 'DB_HOST') ?? 'localhost',\n port: Number(env(args, 'db-port-env', 'DB_PORT')) || 5432,\n database: env(args, 'db-name-env', 'DB_NAME'),\n user: env(args, 'db-username-env', 'DB_USERNAME'),\n password: env(args, 'db-password-env', 'DB_PASSWORD'),\n });\n\n await client.connect();\n\n // Blocking — waits until no other pod holds the lock\n await client.query(`SELECT pg_advisory_lock(${lockKey})`);\n\n // Signal parent that the lock is held\n process.send?.('locked');\n\n const release = () => {\n void client.query(`SELECT pg_advisory_unlock(${lockKey})`)\n .then(() => client.end())\n .finally(() => process.exit(0));\n };\n\n process.once('SIGTERM', release);\n process.once('SIGINT', release);\n}\n\n// ─── lock-migrations ──────────────────────────────────────────────────────────\n\nasync function lockMigrations(args: Args): Promise<void> {\n const lockTimeoutMs = Number(env(args, 'lock-timeout-env', 'MIGRATION_LOCK_TIMEOUT_MS')) || DEFAULT_LOCK_TIMEOUT_MS;\n\n // Forward all --*-env args to the daemon so it resolves the same env vars.\n const forwardedArgs = Object.entries(args).flatMap(([k, v]) => [`--${k}`, v]);\n\n const daemon = fork(process.argv[1], ['--daemon', ...forwardedArgs], {\n stdio: ['ignore', 'inherit', 'inherit', 'ipc'],\n env: process.env,\n execArgv: process.execArgv,\n });\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n daemon.kill();\n reject(new Error(`Timed out waiting for migration lock after ${lockTimeoutMs}ms`));\n }, lockTimeoutMs);\n\n daemon.once('message', (msg) => {\n clearTimeout(timeout);\n if (msg === 'locked') {\n resolve();\n } else {\n daemon.kill();\n reject(new Error(`Lock daemon error: ${JSON.stringify(msg)}`));\n }\n });\n\n daemon.once('error', (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n\n writeFileSync(LOCK_FILE, String(daemon.pid));\n daemon.disconnect(); // close IPC channel so the parent process can exit\n daemon.unref();\n\n log(`Migration lock acquired (pid=${daemon.pid})`);\n}\n\n// ─── unlock-migrations ────────────────────────────────────────────────────────\n\nfunction unlockMigrations(): void {\n if (!existsSync(LOCK_FILE)) {\n warn('No lock file found — nothing to release');\n return;\n }\n\n const pid = Number(readFileSync(LOCK_FILE, 'utf8').trim());\n\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n warn(`Daemon pid=${pid} not found (may have already exited)`);\n }\n\n unlinkSync(LOCK_FILE);\n log('Migration lock released');\n}\n\n// ─── Entry point ──────────────────────────────────────────────────────────────\n\nif (process.argv.includes('--daemon')) {\n const daemonArgIdx = process.argv.indexOf('--daemon');\n const args = parseArgs(process.argv.slice(daemonArgIdx + 1));\n runDaemon(args).catch((err: Error) => {\n fatal(`Lock daemon failed: ${err.message}`);\n process.exit(1);\n });\n} else {\n const [,, command, ...rest] = process.argv;\n const args = parseArgs(rest);\n\n switch (command) {\n case 'lock-migrations':\n lockMigrations(args).catch((err: Error) => {\n fatal(err.message);\n process.exit(1);\n });\n break;\n\n case 'unlock-migrations':\n unlockMigrations();\n break;\n\n default:\n fatal(`Unknown command: ${command}`);\n process.stderr.write('Usage: sequelize-utils <lock-migrations|unlock-migrations> [--db-host-env VAR] [--db-port-env VAR] [--db-name-env VAR] [--db-username-env VAR] [--db-password-env VAR]\\n');\n process.exit(1);\n }\n}\n"],"mappings":"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"}
|