@cedarjs/pg 0.1.0-alpha.1 → 0.2.0-alpha.0
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/README.md +276 -25
- package/dist/cli.cjs +60 -14
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +59 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/{constants-CNZn5Xro.cjs → constants-Ct8myrEn.cjs} +2 -2
- package/dist/{constants-BY97wXjA.mjs.map → constants-Ct8myrEn.cjs.map} +1 -1
- package/dist/{constants-BY97wXjA.mjs → constants-NLR0U4NR.mjs} +2 -2
- package/dist/{constants-CNZn5Xro.cjs.map → constants-NLR0U4NR.mjs.map} +1 -1
- package/dist/dev-env.cjs +12 -0
- package/dist/dev-env.cjs.map +1 -0
- package/dist/dev-env.d.cts +1 -0
- package/dist/dev-env.d.mts +1 -0
- package/dist/dev-env.mjs +14 -0
- package/dist/dev-env.mjs.map +1 -0
- package/dist/index.cjs +50 -10
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +168 -82
- package/dist/index.d.mts +168 -82
- package/dist/index.mjs +32 -2
- package/dist/index.mjs.map +1 -0
- package/dist/jest-teardown.cjs +18 -0
- package/dist/jest-teardown.cjs.map +1 -0
- package/dist/jest-teardown.d.cts +13 -0
- package/dist/jest-teardown.d.mts +14 -0
- package/dist/jest-teardown.mjs +18 -0
- package/dist/jest-teardown.mjs.map +1 -0
- package/dist/jest-template.cjs +41 -0
- package/dist/jest-template.cjs.map +1 -0
- package/dist/jest-template.d.cts +28 -0
- package/dist/jest-template.d.mts +28 -0
- package/dist/jest-template.mjs +35 -0
- package/dist/jest-template.mjs.map +1 -0
- package/dist/jest.cjs +12 -15
- package/dist/jest.cjs.map +1 -1
- package/dist/jest.d.cts +10 -7
- package/dist/jest.d.mts +10 -6
- package/dist/jest.mjs +12 -10
- package/dist/jest.mjs.map +1 -1
- package/dist/lease-B3TuX92y.d.mts +24 -0
- package/dist/lease-BSBBpaR4.mjs +201 -0
- package/dist/lease-BSBBpaR4.mjs.map +1 -0
- package/dist/lease-Bq9wKwQa.cjs +272 -0
- package/dist/lease-Bq9wKwQa.cjs.map +1 -0
- package/dist/lease-t4I9JahV.d.cts +24 -0
- package/dist/lifecycle-BOo6xBjD.mjs +684 -0
- package/dist/lifecycle-BOo6xBjD.mjs.map +1 -0
- package/dist/lifecycle-DEJ4GgWV.cjs +856 -0
- package/dist/lifecycle-DEJ4GgWV.cjs.map +1 -0
- package/dist/load-dev-env-7UjMHhw7.mjs +10 -0
- package/dist/load-dev-env-7UjMHhw7.mjs.map +1 -0
- package/dist/load-dev-env-cII6N4ZP.cjs +15 -0
- package/dist/load-dev-env-cII6N4ZP.cjs.map +1 -0
- package/dist/load-mode-env-B0qO9DZx.cjs +39 -0
- package/dist/load-mode-env-B0qO9DZx.cjs.map +1 -0
- package/dist/load-mode-env-C8gy4v9V.mjs +28 -0
- package/dist/load-mode-env-C8gy4v9V.mjs.map +1 -0
- package/dist/load-test-env-C34wpkIX.mjs +18 -0
- package/dist/load-test-env-C34wpkIX.mjs.map +1 -0
- package/dist/load-test-env-CkdUjTpV.cjs +23 -0
- package/dist/load-test-env-CkdUjTpV.cjs.map +1 -0
- package/dist/naming-C2nGVxPk.d.cts +39 -0
- package/dist/naming-C2nGVxPk.d.mts +39 -0
- package/dist/nx.cjs +26 -17
- package/dist/nx.cjs.map +1 -1
- package/dist/nx.d.cts +9 -20
- package/dist/nx.d.mts +9 -20
- package/dist/nx.mjs +20 -18
- package/dist/nx.mjs.map +1 -1
- package/dist/tasks-Caud9yHr.cjs +67 -0
- package/dist/tasks-Caud9yHr.cjs.map +1 -0
- package/dist/tasks-CjaZRi_G.d.mts +19 -0
- package/dist/tasks-DdQoP9We.d.cts +19 -0
- package/dist/tasks-KherHLac.mjs +38 -0
- package/dist/tasks-KherHLac.mjs.map +1 -0
- package/dist/template-CGw3C1Ob.mjs +88 -0
- package/dist/template-CGw3C1Ob.mjs.map +1 -0
- package/dist/template-D0gJ_MS2.cjs +105 -0
- package/dist/template-D0gJ_MS2.cjs.map +1 -0
- package/dist/template-mode-BkEs9LnY.cjs +91 -0
- package/dist/template-mode-BkEs9LnY.cjs.map +1 -0
- package/dist/template-mode-CcxV_Iju.d.cts +28 -0
- package/dist/template-mode-CcxV_Iju.d.mts +28 -0
- package/dist/template-mode-IjlFOG4O.mjs +80 -0
- package/dist/template-mode-IjlFOG4O.mjs.map +1 -0
- package/dist/test-env.cjs +16 -0
- package/dist/test-env.cjs.map +1 -0
- package/dist/test-env.d.cts +1 -0
- package/dist/test-env.d.mts +1 -0
- package/dist/test-env.mjs +18 -0
- package/dist/test-env.mjs.map +1 -0
- package/dist/vite-plus.cjs +8 -33
- package/dist/vite-plus.cjs.map +1 -1
- package/dist/vite-plus.d.cts +4 -48
- package/dist/vite-plus.d.mts +4 -48
- package/dist/vite-plus.mjs +5 -30
- package/dist/vite-plus.mjs.map +1 -1
- package/dist/vitest-template.cjs +48 -0
- package/dist/vitest-template.cjs.map +1 -0
- package/dist/vitest-template.d.cts +31 -0
- package/dist/vitest-template.d.mts +31 -0
- package/dist/vitest-template.mjs +42 -0
- package/dist/vitest-template.mjs.map +1 -0
- package/dist/vitest.cjs +10 -10
- package/dist/vitest.cjs.map +1 -1
- package/dist/vitest.d.cts +7 -3
- package/dist/vitest.d.mts +7 -2
- package/dist/vitest.mjs +10 -5
- package/dist/vitest.mjs.map +1 -1
- package/package.json +36 -12
- package/scripts/autopg-version +1 -0
- package/scripts/ci-install-autopg.sh +73 -0
- package/scripts/postinstall.js +35 -9
- package/dist/lifecycle-BGYtVXtx.cjs +0 -743
- package/dist/lifecycle-BGYtVXtx.cjs.map +0 -1
- package/dist/lifecycle-CT_8AWPv.mjs +0 -577
- package/dist/lifecycle-CT_8AWPv.mjs.map +0 -1
- package/dist/tasks-13P6tMth.mjs +0 -16
- package/dist/tasks-13P6tMth.mjs.map +0 -1
- package/dist/tasks-B8ryV9xo.cjs +0 -21
- package/dist/tasks-B8ryV9xo.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle-DEJ4GgWV.cjs","names":["PASSWORD_SALT_PREFIX","leaseDir","envPath","resolveWorktreeIdentity","readLease","listRegistryLeases","isOrphanLease"],"sources":["../src/core/naming.ts","../src/core/policy.ts","../src/providers/autopg.ts","../src/providers/host.ts","../src/core/lifecycle.ts"],"sourcesContent":["import type { WorktreeIdentity } from \"./worktree.ts\";\n\nexport type DbMode = \"dev\" | \"test\";\n\nconst PG_MAX = 63;\nconst PREFIX = \"cpg_\";\n\n/**\n * Build an observable Postgres database name:\n * cpg_<repoSlug>_<worktreeSlug>_<mode>_<pathHash8>\n *\n * Never drops `mode` or `pathHash`. Truncates slugs to fit ≤63 chars.\n */\nexport function buildDatabaseName(identity: WorktreeIdentity, mode: DbMode): string {\n const modePart = mode;\n const hashPart = identity.pathHash;\n // PREFIX + slug + '_' + slug + '_' + mode + '_' + hash\n // fixed: PREFIX(4) + 2 underscores around mode/hash segments + mode + hash\n // layout: cpg_<repo>_<wt>_<mode>_<hash>\n const fixed =\n PREFIX.length +\n 1 + // after repo\n 1 + // after worktree\n modePart.length +\n 1 +\n hashPart.length;\n\n let budget = PG_MAX - fixed;\n if (budget < 2) {\n // Extreme truncation: keep mode+hash, minimal slugs\n return `${PREFIX}${modePart}_${hashPart}`.slice(0, PG_MAX);\n }\n\n let repo = identity.repoSlug;\n let wt = identity.worktreeSlug;\n // Split budget roughly evenly, preferring to keep both readable\n while (repo.length + wt.length > budget) {\n if (repo.length >= wt.length && repo.length > 1) {\n repo = repo.slice(0, -1);\n } else if (wt.length > 1) {\n wt = wt.slice(0, -1);\n } else {\n break;\n }\n }\n\n const name = `${PREFIX}${repo}_${wt}_${modePart}_${hashPart}`;\n if (name.length > PG_MAX) {\n return name.slice(0, PG_MAX);\n }\n return name;\n}\n\nexport function buildRoleName(databaseName: string): string {\n const suffix = \"_role\";\n const maxBase = PG_MAX - suffix.length;\n const base = databaseName.slice(0, maxBase);\n return `${base}${suffix}`;\n}\n\n/**\n * Build a worker clone datname from a TEMPLATE database name.\n * Layout: `<template>_c_<suffix>` truncated to ≤63 chars (keeps suffix).\n */\nexport function buildCloneDatabaseName(templateName: string, suffix: string): string {\n const safe = suffix\n .toLowerCase()\n .replace(/[^a-z0-9_]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 24);\n const tag = safe.length > 0 ? safe : \"w\";\n const sep = \"_c_\";\n const maxTemplate = PG_MAX - sep.length - tag.length;\n const base = templateName.slice(0, Math.max(1, maxTemplate));\n return `${base}${sep}${tag}`.slice(0, PG_MAX);\n}\n","/**\n * Shared acquire skip policy for test-runner adapters and Cedar CLI bridges.\n */\n\nexport type AcquireSkip =\n | { skip: false }\n | { skip: true; reason: \"disabled\" }\n | { skip: true; reason: \"external-url\"; databaseUrl: string };\n\nexport type ResolveAcquireSkipInput = {\n /** Candidate URL (TEST_DATABASE_URL for tests, DATABASE_URL for dev). */\n url?: string;\n /** When true, never skip (CEDAR_PG_FORCE=1). */\n force?: boolean;\n /**\n * When true, skip acquire entirely.\n * Defaults from CEDAR_PG=0|false (opt-out adapters). Pass `false` for Cedar opt-in flows.\n */\n disabled?: boolean;\n};\n\n/**\n * Inject DATABASE_URL (and TEST_DATABASE_URL for test mode) from a resolved URL.\n * Single env path for acquire, clone, and external-url skip.\n */\nexport function applyDatabaseUrlEnv(\n databaseUrl: string,\n options: { mode?: \"dev\" | \"test\" } = {},\n): void {\n process.env.DATABASE_URL = databaseUrl;\n if ((options.mode ?? \"test\") === \"test\") {\n process.env.TEST_DATABASE_URL = databaseUrl;\n }\n}\n\nexport type RunIfNeededOptions = ResolveAcquireSkipInput & {\n mode: \"dev\" | \"test\";\n /** Default true (same as acquire / clone host wrappers). */\n setEnv?: boolean;\n};\n\nexport type RunIfNeededSkipped =\n | { status: \"skipped\"; reason: \"disabled\" }\n | { status: \"skipped\"; reason: \"external-url\"; databaseUrl: string };\n\nexport type RunIfNeededResult<T> = RunIfNeededSkipped | { status: \"ran\"; value: T };\n\n/**\n * Shared host skip+env gate for `acquireIfNeeded` / `cloneFromTemplateIfNeeded`.\n * On external-url skip, applies env when `setEnv` is not false.\n */\nexport async function runIfNeeded<T>(\n options: RunIfNeededOptions,\n run: () => Promise<T>,\n): Promise<RunIfNeededResult<T>> {\n const skip = resolveAcquireSkip({\n url: options.url,\n force: options.force,\n disabled: options.disabled,\n });\n if (skip.skip) {\n if (skip.reason === \"external-url\") {\n if (options.setEnv !== false) {\n applyDatabaseUrlEnv(skip.databaseUrl, { mode: options.mode });\n }\n return { status: \"skipped\", reason: \"external-url\", databaseUrl: skip.databaseUrl };\n }\n return { status: \"skipped\", reason: \"disabled\" };\n }\n return { status: \"ran\", value: await run() };\n}\n\n/**\n * True when the URL looks like a cedarpg provisioned database (`cpg_*` name/role).\n * These must never be treated as an external escape hatch; always re-acquire so\n * disposed/stale shell env cannot skip provisioning.\n */\nexport function isCedarPgManagedUrl(url: string | undefined): boolean {\n if (!url || url.startsWith(\"file:\")) return false;\n try {\n const parsed = new URL(url);\n const databaseName = decodeURIComponent(\n (parsed.pathname.replace(/^\\//, \"\").split(\"?\")[0] ?? \"\").trim(),\n );\n const user = decodeURIComponent(parsed.username);\n return databaseName.startsWith(\"cpg_\") || user.startsWith(\"cpg_\");\n } catch {\n return false;\n }\n}\n\n/**\n * True when `url` still looks like an unset dotenv/template value\n * (e.g. `postgresql://{yourMachine}@localhost:5432/app_test` or\n * `postgresql://<user>@localhost/db`), not a real external database.\n */\nfunction isUnsetTemplateUrl(url: string): boolean {\n // `{yourMachine}`, `{user}`, etc.\n if (/\\{[^}]+\\}/.test(url)) return true;\n // `<user>`, `<password>` style templates\n if (/<[^>]+>/.test(url)) return true;\n return false;\n}\n\n/**\n * True when `url` is a real external database and acquire should be skipped.\n * Sqlite `file:` URLs, cedarpg `cpg_*` URLs, and unset template placeholders\n * are not external.\n */\nexport function isExternalDatabaseEscapeHatch(url: string | undefined): boolean {\n if (!url) return false;\n if (url.startsWith(\"file:\")) return false;\n if (isCedarPgManagedUrl(url)) return false;\n if (isUnsetTemplateUrl(url)) return false;\n return true;\n}\n\n/**\n * Decide whether acquire should run.\n * Adapters may call with no args (env defaults). Cedar opt-in should pass `disabled: false`\n * and the relevant `url` (`DATABASE_URL` or `TEST_DATABASE_URL`).\n */\nexport function resolveAcquireSkip(input: ResolveAcquireSkipInput = {}): AcquireSkip {\n const disabled =\n input.disabled ?? (process.env.CEDAR_PG === \"0\" || process.env.CEDAR_PG === \"false\");\n if (disabled) {\n return { skip: true, reason: \"disabled\" };\n }\n\n const force = input.force ?? process.env.CEDAR_PG_FORCE === \"1\";\n if (force) {\n return { skip: false };\n }\n\n const url = input.url !== undefined ? input.url : process.env.TEST_DATABASE_URL;\n if (url && isExternalDatabaseEscapeHatch(url)) {\n return { skip: true, reason: \"external-url\", databaseUrl: url };\n }\n return { skip: false };\n}\n","import { createHash } from \"node:crypto\";\nimport { execFileSync, spawnSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport pg from \"pg\";\nimport { PASSWORD_SALT_PREFIX } from \"../core/constants.ts\";\n\nexport type AutopgDiscovery = {\n port: number;\n adminUrl: string;\n bin: string;\n};\n\nexport const INSTALL_HINT =\n \"autopg is required. Install with:\\n\" +\n \" curl -fsSL https://raw.githubusercontent.com/automagik-dev/autopg/main/install.sh | bash\\n\" +\n \"Then ensure ~/.local/bin is on PATH, or set AUTOPG_BIN.\";\n\n/** Password scheme v2: sha256(PASSWORD_SALT_PREFIX + \"\\\\0\" + roleName) hex[:32]. Frozen for URL rebuild. */\nexport const ROLE_PASSWORD_SCHEME = \"v2\" as const;\n\nfunction candidateBins(): string[] {\n const out: string[] = [];\n if (process.env.AUTOPG_BIN) out.push(process.env.AUTOPG_BIN);\n out.push(\"autopg\");\n out.push(join(homedir(), \".local\", \"bin\", \"autopg\"));\n return out;\n}\n\nexport function resolveAutopgBin(): string | null {\n for (const bin of candidateBins()) {\n if (bin === \"autopg\") {\n const which = spawnSync(\"which\", [\"autopg\"], { encoding: \"utf8\" });\n if (which.status === 0 && which.stdout.trim()) return which.stdout.trim();\n continue;\n }\n if (existsSync(bin)) return bin;\n }\n return null;\n}\n\nexport function requireAutopgBin(): string {\n const bin = resolveAutopgBin();\n if (!bin) {\n throw new Error(INSTALL_HINT);\n }\n return bin;\n}\n\n/**\n * Parse `autopg status --json` output. Requires a numeric port and running !== false.\n */\nexport function parseHostStatus(json: string): { port: number } {\n let parsed: { port?: unknown; running?: unknown };\n try {\n parsed = JSON.parse(json) as { port?: unknown; running?: unknown };\n } catch {\n throw new Error(`autopg status --json returned invalid JSON.\\n${INSTALL_HINT}`);\n }\n if (typeof parsed.port !== \"number\") {\n throw new Error(`autopg status --json missing numeric port.\\n${INSTALL_HINT}`);\n }\n if (parsed.running === false) {\n throw new Error(`autopg host is not running.\\n${INSTALL_HINT}`);\n }\n return { port: parsed.port };\n}\n\n/**\n * Admin URL for an autopg host on `port`.\n *\n * Credentials follow autopg's own defaults / env chain (not \"any local Postgres\"):\n * - user: `AUTOPG_PG_USER` / `PGSERVE_PG_USER` / `postgres`\n * - password: `AUTOPG_PG_PASSWORD` / `PGSERVE_PG_PASSWORD` / `postgres`\n *\n * Port is never scanned: callers pass the port from `autopg status` (attach) or the\n * ephemeral recipe (`55432`). That keeps us off unrelated local servers (e.g. brew on 5432).\n */\nexport function adminUrlFor(port: number, env: NodeJS.ProcessEnv = process.env): string {\n const user = encodeURIComponent(env.AUTOPG_PG_USER || env.PGSERVE_PG_USER || \"postgres\");\n const password = encodeURIComponent(\n env.AUTOPG_PG_PASSWORD || env.PGSERVE_PG_PASSWORD || \"postgres\",\n );\n return `postgresql://${user}:${password}@127.0.0.1:${port}/postgres`;\n}\n\n/**\n * Discover a live autopg host via `autopg status --json`. Throws if the host is not proven live.\n */\nexport function discoverHost(bin = requireAutopgBin()): AutopgDiscovery {\n let status: string;\n try {\n status = execFileSync(bin, [\"status\", \"--json\"], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to query autopg status.\\n${detail}\\n${INSTALL_HINT}`);\n }\n const { port } = parseHostStatus(status);\n return { port, adminUrl: adminUrlFor(port), bin };\n}\n\nfunction quoteIdent(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction quoteLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nasync function withAdminClient<T>(\n adminUrl: string,\n fn: (client: pg.Client) => Promise<T>,\n): Promise<T> {\n const client = new pg.Client({ connectionString: adminUrl });\n await client.connect();\n try {\n return await fn(client);\n } finally {\n await client.end();\n }\n}\n\n/**\n * Deterministic local-only password for an app role (Prisma/TCP need it;\n * autopg hba uses `password` for 127.0.0.1).\n *\n * Keyed by `roleName` (not databaseName) so TEMPLATE clones that reuse the\n * same role keep working when `buildDatabaseUrl` is called with a new database.\n */\nexport function rolePasswordFor(roleName: string): string {\n return createHash(\"sha256\")\n .update(`${PASSWORD_SALT_PREFIX}\\0${roleName}`)\n .digest(\"hex\")\n .slice(0, 32);\n}\n\n/**\n * Idempotently CREATE ROLE + CREATE DATABASE with cedar-pg owned names.\n */\nexport async function ensureDatabase(opts: {\n adminUrl: string;\n databaseName: string;\n roleName: string;\n password?: string;\n}): Promise<void> {\n const password = opts.password ?? rolePasswordFor(opts.roleName);\n await withAdminClient(opts.adminUrl, async (client) => {\n const roleExists = await client.query(\"SELECT 1 FROM pg_roles WHERE rolname = $1\", [\n opts.roleName,\n ]);\n if (roleExists.rowCount === 0) {\n await client.query(\n `CREATE ROLE ${quoteIdent(opts.roleName)} WITH LOGIN PASSWORD ${quoteLiteral(password)}`,\n );\n } else {\n await client.query(\n `ALTER ROLE ${quoteIdent(opts.roleName)} WITH LOGIN PASSWORD ${quoteLiteral(password)}`,\n );\n }\n\n const dbExists = await client.query(\"SELECT 1 FROM pg_database WHERE datname = $1\", [\n opts.databaseName,\n ]);\n if (dbExists.rowCount === 0) {\n await client.query(\n `CREATE DATABASE ${quoteIdent(opts.databaseName)} OWNER ${quoteIdent(opts.roleName)}`,\n );\n } else {\n await client.query(\n `ALTER DATABASE ${quoteIdent(opts.databaseName)} OWNER TO ${quoteIdent(opts.roleName)}`,\n );\n }\n });\n}\n\n/**\n * Mark (or unmark) a database as a PostgreSQL template (`IS_TEMPLATE`).\n * Template DBs cannot be dropped until unset.\n */\nexport async function setDatabaseIsTemplate(opts: {\n adminUrl: string;\n databaseName: string;\n isTemplate: boolean;\n}): Promise<void> {\n const flag = opts.isTemplate ? \"true\" : \"false\";\n await withAdminClient(opts.adminUrl, async (client) => {\n await client.query(`ALTER DATABASE ${quoteIdent(opts.databaseName)} WITH IS_TEMPLATE ${flag}`);\n });\n}\n\n/**\n * CREATE DATABASE … TEMPLATE … OWNER via admin connection.\n * Test roles are LOGIN-only; workers cannot CREATE DATABASE themselves.\n */\nexport async function cloneDatabaseFromTemplate(opts: {\n adminUrl: string;\n templateName: string;\n databaseName: string;\n roleName: string;\n}): Promise<void> {\n await withAdminClient(opts.adminUrl, async (client) => {\n const tmpl = await client.query<{ datistemplate: boolean }>(\n `SELECT datistemplate FROM pg_database WHERE datname = $1`,\n [opts.templateName],\n );\n if (!tmpl.rowCount) {\n throw new Error(`template database not found: ${opts.templateName}`);\n }\n if (!tmpl.rows[0]?.datistemplate) {\n throw new Error(`database is not a TEMPLATE; run markTemplate first: ${opts.templateName}`);\n }\n\n const exists = await client.query(\"SELECT 1 FROM pg_database WHERE datname = $1\", [\n opts.databaseName,\n ]);\n if (exists.rowCount && exists.rowCount > 0) {\n throw new Error(`database already exists: ${opts.databaseName}`);\n }\n await client.query(\n `CREATE DATABASE ${quoteIdent(opts.databaseName)} WITH TEMPLATE ${quoteIdent(opts.templateName)} OWNER ${quoteIdent(opts.roleName)}`,\n );\n });\n}\n\nasync function listOwnedDatnames(client: pg.Client, roleName: string): Promise<string[]> {\n const result = await client.query<{ datname: string }>(\n `SELECT datname FROM pg_database\n WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname = $1)\n ORDER BY datname`,\n [roleName],\n );\n return result.rows.map((r) => r.datname);\n}\n\n/** Unset IS_TEMPLATE if needed, terminate backends, DROP DATABASE (no-op if missing). */\nasync function dropOneDatabase(client: pg.Client, databaseName: string): Promise<void> {\n const db = await client.query<{ datistemplate: boolean }>(\n `SELECT datistemplate FROM pg_database WHERE datname = $1`,\n [databaseName],\n );\n if (!db.rowCount || db.rowCount === 0) return;\n if (db.rows[0]?.datistemplate) {\n await client.query(`ALTER DATABASE ${quoteIdent(databaseName)} WITH IS_TEMPLATE false`);\n }\n await client.query(\n `\n SELECT pg_terminate_backend(pid)\n FROM pg_stat_activity\n WHERE datname = $1 AND pid <> pg_backend_pid()\n `,\n [databaseName],\n );\n await client.query(`DROP DATABASE IF EXISTS ${quoteIdent(databaseName)}`);\n}\n\n/**\n * DROP every database owned by `roleName` on one admin connection, then DROP ROLE.\n * When `preferLast` is owned, it is dropped after the other owned datnames (TEMPLATE after clones).\n * Never invents a DROP target beyond role ownership.\n */\nexport async function dropDatabasesOwnedByRole(opts: {\n adminUrl: string;\n roleName: string;\n preferLast?: string;\n}): Promise<string[]> {\n return withAdminClient(opts.adminUrl, async (client) => {\n const owned = await listOwnedDatnames(client, opts.roleName);\n const ordered = [\n ...owned.filter((name) => name !== opts.preferLast),\n ...owned.filter((name) => name === opts.preferLast),\n ];\n const dropped: string[] = [];\n for (const databaseName of ordered) {\n await dropOneDatabase(client, databaseName);\n dropped.push(databaseName);\n }\n await client.query(`DROP ROLE IF EXISTS ${quoteIdent(opts.roleName)}`);\n return dropped;\n });\n}\n\n/**\n * DROP DATABASE (unset IS_TEMPLATE, force terminate backends) + DROP ROLE\n * when the role owns no remaining databases.\n */\nexport async function dropDatabase(opts: {\n adminUrl: string;\n databaseName: string;\n roleName: string;\n}): Promise<void> {\n await withAdminClient(opts.adminUrl, async (client) => {\n await dropOneDatabase(client, opts.databaseName);\n const owns = await client.query(\n `SELECT 1 FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname = $1) LIMIT 1`,\n [opts.roleName],\n );\n if (owns.rowCount === 0) {\n await client.query(`DROP ROLE IF EXISTS ${quoteIdent(opts.roleName)}`);\n }\n });\n}\n\nexport function buildDatabaseUrl(opts: {\n port: number;\n databaseName: string;\n roleName: string;\n password?: string;\n}): string {\n const password = opts.password ?? rolePasswordFor(opts.roleName);\n const user = encodeURIComponent(opts.roleName);\n const pass = encodeURIComponent(password);\n return `postgresql://${user}:${pass}@127.0.0.1:${opts.port}/${opts.databaseName}`;\n}\n","import { spawn, spawnSync, type ChildProcess } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { createConnection } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n adminUrlFor,\n discoverHost,\n INSTALL_HINT,\n requireAutopgBin,\n type AutopgDiscovery,\n} from \"./autopg.ts\";\n\n/** How cedar-pg starts an autopg host when none is already live. */\nexport type HostStartPolicy = \"local\" | \"ephemeral\";\n\n/** Opinionated install + postmaster argv for CI / ephemeral runners. */\nexport type EphemeralHostRecipe = {\n dataDir: string;\n port: number;\n installArgs: string[];\n postmasterArgs: string[];\n};\n\n/** Inputs for {@link ephemeralHostRecipe} (production uses process defaults). */\nexport type EphemeralRecipeContext = {\n platform?: NodeJS.Platform;\n shmAvailable?: boolean;\n tmpDir?: string;\n uid?: number;\n port?: number;\n};\n\n/** Fixed CI TCP port so install registration and postmaster listen on the same port. */\nconst EPHEMERAL_PORT = 55432;\n\nconst OWNED_POSTMASTER_READY_MS = 30_000;\nconst OWNED_POSTMASTER_POLL_MS = 200;\n\n/**\n * Resolve whether to start an owned ephemeral postmaster or use local pm2 install.\n *\n * - `CEDAR_PG_EPHEMERAL_HOST=1` → ephemeral\n * - `CEDAR_PG_EPHEMERAL_HOST=0` → local (even when `CI=true`)\n * - unset + `CI=true` → ephemeral\n * - otherwise → local\n */\nexport function resolveEphemeralHostPolicy(env: NodeJS.ProcessEnv = process.env): HostStartPolicy {\n const force = env.CEDAR_PG_EPHEMERAL_HOST;\n if (force === \"1\") return \"ephemeral\";\n if (force === \"0\") return \"local\";\n if (env.CI === \"true\") return \"ephemeral\";\n return \"local\";\n}\n\n/**\n * Fixed CI recipe: shared `--port` on install + postmaster, `--no-pm2 --no-ui`,\n * and `--ram` + `/dev/shm/cedar-pg-<uid>` on Linux when shm exists.\n */\nexport function ephemeralHostRecipe(ctx: EphemeralRecipeContext = {}): EphemeralHostRecipe {\n const platform = ctx.platform ?? process.platform;\n const shmAvailable = ctx.shmAvailable ?? (platform === \"linux\" && existsSync(\"/dev/shm\"));\n const uid = ctx.uid ?? process.getuid?.() ?? 0;\n const port = ctx.port ?? EPHEMERAL_PORT;\n const useRam = platform === \"linux\" && shmAvailable;\n const dataDir = useRam\n ? `/dev/shm/cedar-pg-${uid}`\n : join(ctx.tmpDir ?? tmpdir(), \"cedar-pg-host\");\n\n const installArgs = [\"install\", \"--no-pm2\", \"--no-ui\", \"--port\", String(port), \"--data\", dataDir];\n // Always pass --port/--data/--socket-dir so postmaster matches the install record.\n const postmasterArgs = [\n \"postmaster\",\n ...(useRam ? [\"--ram\"] : []),\n \"--port\",\n String(port),\n \"--socket-dir\",\n dataDir,\n \"--data\",\n dataDir,\n ];\n\n return { dataDir, port, installArgs, postmasterArgs };\n}\n\n/** Discovery from the recipe port — TCP readiness is the authority, not `autopg status`. */\nexport function discoveryFromRecipe(bin: string, recipe: EphemeralHostRecipe): AutopgDiscovery {\n return { port: recipe.port, adminUrl: adminUrlFor(recipe.port), bin };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction runInstall(bin: string, args: string[]): void {\n const install = spawnSync(bin, args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n if (install.status !== 0) {\n throw new Error(\n `Failed to start autopg host (exit ${install.status}).\\n` +\n `${install.stderr || install.stdout || \"\"}\\n${INSTALL_HINT}`,\n );\n }\n}\n\n/** True when something accepts TCP on 127.0.0.1:port (postmaster live, not just admin.json). */\nfunction canConnect(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ host: \"127.0.0.1\", port }, () => {\n socket.end();\n resolve(true);\n });\n socket.on(\"error\", () => {\n resolve(false);\n });\n });\n}\n\n/** Kill a detached owned postmaster (process group when possible) and drop our handle. */\nfunction killOwnedChild(child: ChildProcess): void {\n const pid = child.pid;\n if (pid != null) {\n try {\n process.kill(-pid, \"SIGTERM\");\n } catch {\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // already exited\n }\n }\n }\n child.unref();\n}\n\nexport type WaitForOwnedPostmasterOptions = {\n port: number;\n readyMs?: number;\n pollMs?: number;\n canConnect?: (port: number) => Promise<boolean>;\n now?: () => number;\n sleep?: (ms: number) => Promise<void>;\n /** Return an Error to fail fast (spawn error / early exit). */\n failure?: () => Error | null;\n};\n\n/**\n * Poll until TCP accepts on port, or throw on timeout / {@link WaitForOwnedPostmasterOptions.failure}.\n * Exported for tests — the readiness seam for owned ephemeral start.\n */\nexport async function waitForOwnedPostmaster(opts: WaitForOwnedPostmasterOptions): Promise<void> {\n const probe = opts.canConnect ?? canConnect;\n const now = opts.now ?? Date.now;\n const pause = opts.sleep ?? sleep;\n const readyMs = opts.readyMs ?? OWNED_POSTMASTER_READY_MS;\n const pollMs = opts.pollMs ?? OWNED_POSTMASTER_POLL_MS;\n const deadline = now() + readyMs;\n let lastDetail = \"TCP not accepting\";\n\n while (now() < deadline) {\n const fail = opts.failure?.();\n if (fail) throw fail;\n if (await probe(opts.port)) return;\n lastDetail = `127.0.0.1:${opts.port} not accepting connections`;\n await pause(pollMs);\n }\n\n throw new Error(\n `Timed out waiting for autopg host after ${readyMs}ms.\\n${lastDetail}\\n${INSTALL_HINT}`,\n );\n}\n\n/**\n * Install + detached postmaster with fully ignored stdio so the CI job owns lifetime\n * (caller exit must not close pipes under the daemon).\n *\n * Readiness is TCP accept on the recipe port — not `autopg status`, which succeeds\n * after `install --no-pm2` before postmaster is listening. On success, discovery is\n * recipe-derived (same port). On failure, the spawned child is killed.\n */\nasync function startEphemeralHost(bin: string): Promise<AutopgDiscovery> {\n const recipe = ephemeralHostRecipe();\n mkdirSync(recipe.dataDir, { recursive: true });\n runInstall(bin, recipe.installArgs);\n\n const state: {\n exit: { code: number | null; signal: NodeJS.Signals | null } | null;\n spawnError: Error | null;\n } = { exit: null, spawnError: null };\n\n const child = spawn(bin, recipe.postmasterArgs, {\n detached: true,\n // Fully ignore stdio so unref'd postmaster is not tied to this process's pipes.\n stdio: \"ignore\",\n });\n child.on(\"error\", (err) => {\n state.spawnError = err;\n });\n child.on(\"exit\", (code, signal) => {\n state.exit = { code, signal };\n });\n\n try {\n await waitForOwnedPostmaster({\n port: recipe.port,\n failure: () => {\n if (state.spawnError) {\n return new Error(\n `Failed to spawn autopg postmaster.\\n${state.spawnError.message}\\n${INSTALL_HINT}`,\n );\n }\n if (state.exit) {\n return new Error(\n `autopg postmaster exited before ready (code=${state.exit.code}, signal=${state.exit.signal}).\\n` +\n INSTALL_HINT,\n );\n }\n return null;\n },\n });\n } catch (err) {\n killOwnedChild(child);\n throw err;\n }\n\n // Success: job owns lifetime — drop our handle without killing.\n child.unref();\n return discoveryFromRecipe(bin, recipe);\n}\n\n/**\n * Ensure the host postmaster is up.\n *\n * - Attaches when `autopg status --json` shows a live host.\n * - Otherwise starts from {@link resolveEphemeralHostPolicy}: local pm2 `install`,\n * or opinionated ephemeral (`--no-pm2 --no-ui` + detached postmaster).\n * - CI job owns ephemeral postmaster lifetime on success (no cedar-pg host dispose).\n * - Failed ephemeral start kills the spawned child so ensure is atomic for the caller.\n */\nexport async function ensureHostRunning(bin = requireAutopgBin()): Promise<AutopgDiscovery> {\n try {\n return discoverHost(bin);\n } catch {\n // status failed — start host per policy\n }\n\n if (resolveEphemeralHostPolicy() === \"ephemeral\") {\n return startEphemeralHost(bin);\n }\n\n runInstall(bin, [\"install\"]);\n return discoverHost(bin);\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { buildDatabaseName, buildRoleName, type DbMode } from \"./naming.ts\";\nimport {\n envPath,\n forgetLease,\n isOrphanLease,\n leaseDir,\n listRegistryLeases,\n readLease,\n writeLease,\n type Lease,\n} from \"./lease.ts\";\nimport { applyDatabaseUrlEnv, runIfNeeded, type ResolveAcquireSkipInput } from \"./policy.ts\";\nimport { resolveWorktreeIdentity } from \"./worktree.ts\";\nimport { buildDatabaseUrl, dropDatabasesOwnedByRole, ensureDatabase } from \"../providers/autopg.ts\";\nimport { ensureHostRunning } from \"../providers/host.ts\";\n\nfunction writeEnvFile(root: string, mode: DbMode, databaseUrl: string): void {\n mkdirSync(leaseDir(root), { recursive: true, mode: 0o700 });\n let body = `DATABASE_URL=${databaseUrl}\\n`;\n if (mode === \"test\") body += `TEST_DATABASE_URL=${databaseUrl}\\n`;\n writeFileSync(envPath(root, mode), body, { mode: 0o600 });\n}\n\nexport function urlFromLease(lease: Lease): string {\n return buildDatabaseUrl({\n port: lease.port,\n databaseName: lease.databaseName,\n roleName: lease.roleName,\n });\n}\n\n/**\n * DROP every DB owned by the lease role (TEMPLATE + clones), then forget lease.\n * Provider owns ordering (clones before leased datname) on one admin connection.\n */\nasync function dropThenForget(lease: Lease, adminUrl: string): Promise<string[]> {\n const dropped = await dropDatabasesOwnedByRole({\n adminUrl,\n roleName: lease.roleName,\n preferLast: lease.databaseName,\n });\n forgetLease(lease);\n return dropped;\n}\n\nexport type AcquireOptions = {\n root?: string;\n mode: DbMode;\n /** Inject DATABASE_URL / TEST_DATABASE_URL into process.env (default true). */\n setEnv?: boolean;\n};\n\nexport type AcquireResult = {\n databaseUrl: string;\n /** Superuser URL for privileged DDL (mark template, CREATE DATABASE … TEMPLATE). */\n adminUrl: string;\n databaseName: string;\n roleName: string;\n repoSlug: string;\n worktreeSlug: string;\n pathHash: string;\n root: string;\n mode: DbMode;\n port: number;\n dispose: () => Promise<void>;\n};\n\n/**\n * Acquire a worktree-scoped database and return connection info.\n *\n * - `dev`: keep DB across restarts.\n * - `test`: DROP when `dispose()` is awaited (callers / test runners own teardown).\n */\nexport async function acquire(options: AcquireOptions): Promise<AcquireResult> {\n const identity = resolveWorktreeIdentity(options.root);\n const mode = options.mode;\n const databaseName = buildDatabaseName(identity, mode);\n const roleName = buildRoleName(databaseName);\n\n const host = await ensureHostRunning();\n await ensureDatabase({\n adminUrl: host.adminUrl,\n databaseName,\n roleName,\n });\n\n const databaseUrl = buildDatabaseUrl({\n port: host.port,\n databaseName,\n roleName,\n });\n\n const lease: Lease = {\n schemaVersion: 1,\n mode,\n root: identity.root,\n repoSlug: identity.repoSlug,\n worktreeSlug: identity.worktreeSlug,\n pathHash: identity.pathHash,\n databaseName,\n roleName,\n port: host.port,\n pid: process.pid,\n createdAt: new Date().toISOString(),\n };\n writeLease(lease);\n writeEnvFile(identity.root, mode, databaseUrl);\n\n if (options.setEnv !== false) {\n applyDatabaseUrlEnv(databaseUrl, { mode });\n }\n\n const disposeFn = async () => {\n await dispose({ root: identity.root, mode });\n };\n\n return {\n databaseUrl,\n adminUrl: host.adminUrl,\n databaseName,\n roleName,\n repoSlug: identity.repoSlug,\n worktreeSlug: identity.worktreeSlug,\n pathHash: identity.pathHash,\n root: identity.root,\n mode,\n port: host.port,\n dispose: disposeFn,\n };\n}\n\nexport type AcquireIfNeededOptions = AcquireOptions & ResolveAcquireSkipInput;\n\nexport type AcquireIfNeededResult =\n | { status: \"skipped\"; reason: \"disabled\" }\n | { status: \"skipped\"; reason: \"external-url\"; databaseUrl: string }\n | ({ status: \"acquired\" } & AcquireResult);\n\n/**\n * Resolve skip policy then acquire. Single entry for hosts (Cedar CLI, Jest, Vitest).\n * On external-url skip, applies DATABASE_URL / TEST_DATABASE_URL when `setEnv` is not false.\n */\nexport async function acquireIfNeeded(\n options: AcquireIfNeededOptions,\n): Promise<AcquireIfNeededResult> {\n const outcome = await runIfNeeded(options, () =>\n acquire({\n root: options.root,\n mode: options.mode,\n setEnv: options.setEnv,\n }),\n );\n if (outcome.status === \"skipped\") return outcome;\n return { status: \"acquired\", ...outcome.value };\n}\n\nexport type DisposeOptions = {\n root?: string;\n mode?: DbMode;\n};\n\nexport type DisposeResult =\n | { dropped: true; databaseName: string; droppedDatabases: string[] }\n | { dropped: false; reason: \"no-lease\" | \"host-unavailable\" };\n\n/**\n * Role-scoped suite teardown: DROP every database owned by the lease role\n * (TEMPLATE + clones), then DROP ROLE and forget the lease. Unsets `IS_TEMPLATE`\n * as needed. This is not per-clone cleanup — use `CloneResult.dropClone` for that.\n * No-ops without a valid lease; never invents a DROP target beyond role ownership.\n * If the host is unavailable, leaves the lease so dispose/gc can retry.\n */\nexport async function dispose(options: DisposeOptions = {}): Promise<DisposeResult> {\n const identity = resolveWorktreeIdentity(options.root);\n const mode = options.mode ?? \"test\";\n const lease = readLease(identity.root, mode);\n if (!lease) return { dropped: false, reason: \"no-lease\" };\n\n let host;\n try {\n host = await ensureHostRunning();\n } catch {\n // Keep lease + registry so a later dispose/gc can still find the DB.\n return { dropped: false, reason: \"host-unavailable\" };\n }\n\n const droppedDatabases = await dropThenForget(lease, host.adminUrl);\n return {\n dropped: true,\n databaseName: lease.databaseName,\n droppedDatabases,\n };\n}\n\n/**\n * Drop databases whose registered worktree root no longer exists on disk.\n * Registry entries are removed only after a successful DROP (owned DBs + lease DB).\n */\nexport async function gc(): Promise<{\n dropped: string[];\n}> {\n const dropped: string[] = [];\n const orphans = listRegistryLeases().filter(isOrphanLease);\n if (orphans.length === 0) return { dropped };\n\n let host;\n try {\n host = await ensureHostRunning();\n } catch {\n return { dropped };\n }\n\n for (const lease of orphans) {\n try {\n const names = await dropThenForget(lease, host.adminUrl);\n dropped.push(...names);\n } catch {\n // Keep registry entry for retry\n }\n }\n return { dropped };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { n as normalizeLoadOptions, t as loadModeEnv } from "./load-mode-env-C8gy4v9V.mjs";
|
|
2
|
+
//#region src/adapters/load-dev-env.ts
|
|
3
|
+
/** Load `.cedarpg/dev.env` into `process.env`. Use `{ overwrite: true }` to beat `.env`. */
|
|
4
|
+
function loadDevEnv(rootOrOptions) {
|
|
5
|
+
loadModeEnv("dev", normalizeLoadOptions(rootOrOptions));
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { loadDevEnv as t };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=load-dev-env-7UjMHhw7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-dev-env-7UjMHhw7.mjs","names":[],"sources":["../src/adapters/load-dev-env.ts"],"sourcesContent":["import { loadModeEnv, normalizeLoadOptions, type LoadModeEnvOptions } from \"./load-mode-env.ts\";\n\nexport type LoadDevEnvOptions = LoadModeEnvOptions;\n\n/** Load `.cedarpg/dev.env` into `process.env`. Use `{ overwrite: true }` to beat `.env`. */\nexport function loadDevEnv(rootOrOptions?: string | LoadDevEnvOptions): void {\n loadModeEnv(\"dev\", normalizeLoadOptions(rootOrOptions));\n}\n"],"mappings":";;;AAKA,SAAgB,WAAW,eAAkD;CAC3E,YAAY,OAAO,qBAAqB,aAAa,CAAC;AACxD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const require_load_mode_env = require("./load-mode-env-B0qO9DZx.cjs");
|
|
2
|
+
//#region src/adapters/load-dev-env.ts
|
|
3
|
+
/** Load `.cedarpg/dev.env` into `process.env`. Use `{ overwrite: true }` to beat `.env`. */
|
|
4
|
+
function loadDevEnv(rootOrOptions) {
|
|
5
|
+
require_load_mode_env.loadModeEnv("dev", require_load_mode_env.normalizeLoadOptions(rootOrOptions));
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
Object.defineProperty(exports, "loadDevEnv", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function() {
|
|
11
|
+
return loadDevEnv;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=load-dev-env-cII6N4ZP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-dev-env-cII6N4ZP.cjs","names":["normalizeLoadOptions"],"sources":["../src/adapters/load-dev-env.ts"],"sourcesContent":["import { loadModeEnv, normalizeLoadOptions, type LoadModeEnvOptions } from \"./load-mode-env.ts\";\n\nexport type LoadDevEnvOptions = LoadModeEnvOptions;\n\n/** Load `.cedarpg/dev.env` into `process.env`. Use `{ overwrite: true }` to beat `.env`. */\nexport function loadDevEnv(rootOrOptions?: string | LoadDevEnvOptions): void {\n loadModeEnv(\"dev\", normalizeLoadOptions(rootOrOptions));\n}\n"],"mappings":";;;AAKA,SAAgB,WAAW,eAAkD;CAC3E,sBAAA,YAAY,OAAOA,sBAAAA,qBAAqB,aAAa,CAAC;AACxD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const require_lease = require("./lease-Bq9wKwQa.cjs");
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
//#region src/adapters/load-mode-env.ts
|
|
4
|
+
function normalizeLoadOptions(rootOrOptions) {
|
|
5
|
+
if (typeof rootOrOptions === "string" || rootOrOptions === void 0) return { root: rootOrOptions };
|
|
6
|
+
return rootOrOptions;
|
|
7
|
+
}
|
|
8
|
+
/** Load `.cedarpg/<mode>.env` when a matching lease exists; no-op if stale/missing. */
|
|
9
|
+
function loadModeEnv(mode, options = {}) {
|
|
10
|
+
const resolved = require_lease.resolveRoot(options.root);
|
|
11
|
+
if (!(0, node_fs.existsSync)(require_lease.leasePath(resolved, mode))) return;
|
|
12
|
+
const file = require_lease.envPath(resolved, mode);
|
|
13
|
+
if (!(0, node_fs.existsSync)(file)) return;
|
|
14
|
+
const overwrite = options.overwrite === true;
|
|
15
|
+
for (const line of (0, node_fs.readFileSync)(file, "utf8").split("\n")) {
|
|
16
|
+
const trimmed = line.trim();
|
|
17
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
18
|
+
const eq = trimmed.indexOf("=");
|
|
19
|
+
if (eq <= 0) continue;
|
|
20
|
+
const key = trimmed.slice(0, eq);
|
|
21
|
+
const value = trimmed.slice(eq + 1);
|
|
22
|
+
if (overwrite || process.env[key] === void 0) process.env[key] = value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
Object.defineProperty(exports, "loadModeEnv", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function() {
|
|
29
|
+
return loadModeEnv;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, "normalizeLoadOptions", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function() {
|
|
35
|
+
return normalizeLoadOptions;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=load-mode-env-B0qO9DZx.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-mode-env-B0qO9DZx.cjs","names":["resolveRoot","leasePath","envPath"],"sources":["../src/adapters/load-mode-env.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { envPath, leasePath } from \"../core/lease.ts\";\nimport type { DbMode } from \"../core/naming.ts\";\nimport { resolveRoot } from \"../core/worktree.ts\";\n\nexport type LoadModeEnvOptions = {\n root?: string;\n /** Overwrite existing `process.env` keys (default: only fill undefined). */\n overwrite?: boolean;\n};\n\nexport function normalizeLoadOptions(\n rootOrOptions?: string | LoadModeEnvOptions,\n): LoadModeEnvOptions {\n if (typeof rootOrOptions === \"string\" || rootOrOptions === undefined) {\n return { root: rootOrOptions };\n }\n return rootOrOptions;\n}\n\n/** Load `.cedarpg/<mode>.env` when a matching lease exists; no-op if stale/missing. */\nexport function loadModeEnv(mode: DbMode, options: LoadModeEnvOptions = {}): void {\n const resolved = resolveRoot(options.root);\n if (!existsSync(leasePath(resolved, mode))) return;\n\n const file = envPath(resolved, mode);\n if (!existsSync(file)) return;\n\n const overwrite = options.overwrite === true;\n for (const line of readFileSync(file, \"utf8\").split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq <= 0) continue;\n const key = trimmed.slice(0, eq);\n const value = trimmed.slice(eq + 1);\n if (overwrite || process.env[key] === undefined) {\n process.env[key] = value;\n }\n }\n}\n"],"mappings":";;;AAWA,SAAgB,qBACd,eACoB;CACpB,IAAI,OAAO,kBAAkB,YAAY,kBAAkB,KAAA,GACzD,OAAO,EAAE,MAAM,cAAc;CAE/B,OAAO;AACT;;AAGA,SAAgB,YAAY,MAAc,UAA8B,CAAC,GAAS;CAChF,MAAM,WAAWA,cAAAA,YAAY,QAAQ,IAAI;CACzC,IAAI,EAAA,GAAA,QAAA,WAAA,CAAYC,cAAAA,UAAU,UAAU,IAAI,CAAC,GAAG;CAE5C,MAAM,OAAOC,cAAAA,QAAQ,UAAU,IAAI;CACnC,IAAI,EAAA,GAAA,QAAA,WAAA,CAAY,IAAI,GAAG;CAEvB,MAAM,YAAY,QAAQ,cAAc;CACxC,KAAK,MAAM,SAAA,GAAA,QAAA,aAAA,CAAqB,MAAM,MAAM,CAAC,CAAC,MAAM,IAAI,GAAG;EACzD,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,GAAG;EACzC,MAAM,KAAK,QAAQ,QAAQ,GAAG;EAC9B,IAAI,MAAM,GAAG;EACb,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE;EAC/B,MAAM,QAAQ,QAAQ,MAAM,KAAK,CAAC;EAClC,IAAI,aAAa,QAAQ,IAAI,SAAS,KAAA,GACpC,QAAQ,IAAI,OAAO;CAEvB;AACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { d as resolveRoot, n as envPath, o as leasePath } from "./lease-BSBBpaR4.mjs";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
//#region src/adapters/load-mode-env.ts
|
|
4
|
+
function normalizeLoadOptions(rootOrOptions) {
|
|
5
|
+
if (typeof rootOrOptions === "string" || rootOrOptions === void 0) return { root: rootOrOptions };
|
|
6
|
+
return rootOrOptions;
|
|
7
|
+
}
|
|
8
|
+
/** Load `.cedarpg/<mode>.env` when a matching lease exists; no-op if stale/missing. */
|
|
9
|
+
function loadModeEnv(mode, options = {}) {
|
|
10
|
+
const resolved = resolveRoot(options.root);
|
|
11
|
+
if (!existsSync(leasePath(resolved, mode))) return;
|
|
12
|
+
const file = envPath(resolved, mode);
|
|
13
|
+
if (!existsSync(file)) return;
|
|
14
|
+
const overwrite = options.overwrite === true;
|
|
15
|
+
for (const line of readFileSync(file, "utf8").split("\n")) {
|
|
16
|
+
const trimmed = line.trim();
|
|
17
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
18
|
+
const eq = trimmed.indexOf("=");
|
|
19
|
+
if (eq <= 0) continue;
|
|
20
|
+
const key = trimmed.slice(0, eq);
|
|
21
|
+
const value = trimmed.slice(eq + 1);
|
|
22
|
+
if (overwrite || process.env[key] === void 0) process.env[key] = value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { normalizeLoadOptions as n, loadModeEnv as t };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=load-mode-env-C8gy4v9V.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-mode-env-C8gy4v9V.mjs","names":[],"sources":["../src/adapters/load-mode-env.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { envPath, leasePath } from \"../core/lease.ts\";\nimport type { DbMode } from \"../core/naming.ts\";\nimport { resolveRoot } from \"../core/worktree.ts\";\n\nexport type LoadModeEnvOptions = {\n root?: string;\n /** Overwrite existing `process.env` keys (default: only fill undefined). */\n overwrite?: boolean;\n};\n\nexport function normalizeLoadOptions(\n rootOrOptions?: string | LoadModeEnvOptions,\n): LoadModeEnvOptions {\n if (typeof rootOrOptions === \"string\" || rootOrOptions === undefined) {\n return { root: rootOrOptions };\n }\n return rootOrOptions;\n}\n\n/** Load `.cedarpg/<mode>.env` when a matching lease exists; no-op if stale/missing. */\nexport function loadModeEnv(mode: DbMode, options: LoadModeEnvOptions = {}): void {\n const resolved = resolveRoot(options.root);\n if (!existsSync(leasePath(resolved, mode))) return;\n\n const file = envPath(resolved, mode);\n if (!existsSync(file)) return;\n\n const overwrite = options.overwrite === true;\n for (const line of readFileSync(file, \"utf8\").split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq <= 0) continue;\n const key = trimmed.slice(0, eq);\n const value = trimmed.slice(eq + 1);\n if (overwrite || process.env[key] === undefined) {\n process.env[key] = value;\n }\n }\n}\n"],"mappings":";;;AAWA,SAAgB,qBACd,eACoB;CACpB,IAAI,OAAO,kBAAkB,YAAY,kBAAkB,KAAA,GACzD,OAAO,EAAE,MAAM,cAAc;CAE/B,OAAO;AACT;;AAGA,SAAgB,YAAY,MAAc,UAA8B,CAAC,GAAS;CAChF,MAAM,WAAW,YAAY,QAAQ,IAAI;CACzC,IAAI,CAAC,WAAW,UAAU,UAAU,IAAI,CAAC,GAAG;CAE5C,MAAM,OAAO,QAAQ,UAAU,IAAI;CACnC,IAAI,CAAC,WAAW,IAAI,GAAG;CAEvB,MAAM,YAAY,QAAQ,cAAc;CACxC,KAAK,MAAM,QAAQ,aAAa,MAAM,MAAM,CAAC,CAAC,MAAM,IAAI,GAAG;EACzD,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,GAAG;EACzC,MAAM,KAAK,QAAQ,QAAQ,GAAG;EAC9B,IAAI,MAAM,GAAG;EACb,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE;EAC/B,MAAM,QAAQ,QAAQ,MAAM,KAAK,CAAC;EAClC,IAAI,aAAa,QAAQ,IAAI,SAAS,KAAA,GACpC,QAAQ,IAAI,OAAO;CAEvB;AACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { n as normalizeLoadOptions, t as loadModeEnv } from "./load-mode-env-C8gy4v9V.mjs";
|
|
2
|
+
//#region src/adapters/load-test-env.ts
|
|
3
|
+
/**
|
|
4
|
+
* Load `.cedarpg/test.env` into `process.env` (worker-side).
|
|
5
|
+
*
|
|
6
|
+
* Jest (and optional Vitest `setupFiles`) run tests in a different process than
|
|
7
|
+
* `globalSetup`, so `setEnv` in acquire does not reach workers — the env file does.
|
|
8
|
+
*
|
|
9
|
+
* No-ops unless a matching `test.json` lease exists, so a leftover env after dispose
|
|
10
|
+
* cannot inject a dropped DATABASE_URL.
|
|
11
|
+
*/
|
|
12
|
+
function loadTestEnv(rootOrOptions) {
|
|
13
|
+
loadModeEnv("test", normalizeLoadOptions(rootOrOptions));
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { loadTestEnv as t };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=load-test-env-C34wpkIX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-test-env-C34wpkIX.mjs","names":[],"sources":["../src/adapters/load-test-env.ts"],"sourcesContent":["import { loadModeEnv, normalizeLoadOptions, type LoadModeEnvOptions } from \"./load-mode-env.ts\";\n\nexport type LoadTestEnvOptions = LoadModeEnvOptions;\n\n/**\n * Load `.cedarpg/test.env` into `process.env` (worker-side).\n *\n * Jest (and optional Vitest `setupFiles`) run tests in a different process than\n * `globalSetup`, so `setEnv` in acquire does not reach workers — the env file does.\n *\n * No-ops unless a matching `test.json` lease exists, so a leftover env after dispose\n * cannot inject a dropped DATABASE_URL.\n */\nexport function loadTestEnv(rootOrOptions?: string | LoadTestEnvOptions): void {\n loadModeEnv(\"test\", normalizeLoadOptions(rootOrOptions));\n}\n"],"mappings":";;;;;;;;;;;AAaA,SAAgB,YAAY,eAAmD;CAC7E,YAAY,QAAQ,qBAAqB,aAAa,CAAC;AACzD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const require_load_mode_env = require("./load-mode-env-B0qO9DZx.cjs");
|
|
2
|
+
//#region src/adapters/load-test-env.ts
|
|
3
|
+
/**
|
|
4
|
+
* Load `.cedarpg/test.env` into `process.env` (worker-side).
|
|
5
|
+
*
|
|
6
|
+
* Jest (and optional Vitest `setupFiles`) run tests in a different process than
|
|
7
|
+
* `globalSetup`, so `setEnv` in acquire does not reach workers — the env file does.
|
|
8
|
+
*
|
|
9
|
+
* No-ops unless a matching `test.json` lease exists, so a leftover env after dispose
|
|
10
|
+
* cannot inject a dropped DATABASE_URL.
|
|
11
|
+
*/
|
|
12
|
+
function loadTestEnv(rootOrOptions) {
|
|
13
|
+
require_load_mode_env.loadModeEnv("test", require_load_mode_env.normalizeLoadOptions(rootOrOptions));
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
Object.defineProperty(exports, "loadTestEnv", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function() {
|
|
19
|
+
return loadTestEnv;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=load-test-env-CkdUjTpV.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-test-env-CkdUjTpV.cjs","names":["normalizeLoadOptions"],"sources":["../src/adapters/load-test-env.ts"],"sourcesContent":["import { loadModeEnv, normalizeLoadOptions, type LoadModeEnvOptions } from \"./load-mode-env.ts\";\n\nexport type LoadTestEnvOptions = LoadModeEnvOptions;\n\n/**\n * Load `.cedarpg/test.env` into `process.env` (worker-side).\n *\n * Jest (and optional Vitest `setupFiles`) run tests in a different process than\n * `globalSetup`, so `setEnv` in acquire does not reach workers — the env file does.\n *\n * No-ops unless a matching `test.json` lease exists, so a leftover env after dispose\n * cannot inject a dropped DATABASE_URL.\n */\nexport function loadTestEnv(rootOrOptions?: string | LoadTestEnvOptions): void {\n loadModeEnv(\"test\", normalizeLoadOptions(rootOrOptions));\n}\n"],"mappings":";;;;;;;;;;;AAaA,SAAgB,YAAY,eAAmD;CAC7E,sBAAA,YAAY,QAAQA,sBAAAA,qBAAqB,aAAa,CAAC;AACzD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/core/worktree.d.ts
|
|
2
|
+
type WorktreeIdentity = {
|
|
3
|
+
/** Absolute path to the worktree / project root. */
|
|
4
|
+
root: string;
|
|
5
|
+
/** Basename of the git common dir / main checkout (e.g. `cedar`). */
|
|
6
|
+
repoSlug: string;
|
|
7
|
+
/** Basename of this worktree directory (e.g. `feat-auth`). */
|
|
8
|
+
worktreeSlug: string;
|
|
9
|
+
/** First 8 hex chars of sha256(absolute root). */
|
|
10
|
+
pathHash: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the project / worktree root.
|
|
14
|
+
* Explicit `root` wins (app project path). Otherwise prefer git toplevel, then cwd.
|
|
15
|
+
*/
|
|
16
|
+
declare function resolveRoot(root?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Identify repo + worktree for observable DB naming.
|
|
19
|
+
*/
|
|
20
|
+
declare function resolveWorktreeIdentity(root?: string): WorktreeIdentity;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/core/naming.d.ts
|
|
23
|
+
type DbMode = "dev" | "test";
|
|
24
|
+
/**
|
|
25
|
+
* Build an observable Postgres database name:
|
|
26
|
+
* cpg_<repoSlug>_<worktreeSlug>_<mode>_<pathHash8>
|
|
27
|
+
*
|
|
28
|
+
* Never drops `mode` or `pathHash`. Truncates slugs to fit ≤63 chars.
|
|
29
|
+
*/
|
|
30
|
+
declare function buildDatabaseName(identity: WorktreeIdentity, mode: DbMode): string;
|
|
31
|
+
declare function buildRoleName(databaseName: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Build a worker clone datname from a TEMPLATE database name.
|
|
34
|
+
* Layout: `<template>_c_<suffix>` truncated to ≤63 chars (keeps suffix).
|
|
35
|
+
*/
|
|
36
|
+
declare function buildCloneDatabaseName(templateName: string, suffix: string): string;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { WorktreeIdentity as a, buildRoleName as i, buildCloneDatabaseName as n, resolveRoot as o, buildDatabaseName as r, resolveWorktreeIdentity as s, DbMode as t };
|
|
39
|
+
//# sourceMappingURL=naming-C2nGVxPk.d.cts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/core/worktree.d.ts
|
|
2
|
+
type WorktreeIdentity = {
|
|
3
|
+
/** Absolute path to the worktree / project root. */
|
|
4
|
+
root: string;
|
|
5
|
+
/** Basename of the git common dir / main checkout (e.g. `cedar`). */
|
|
6
|
+
repoSlug: string;
|
|
7
|
+
/** Basename of this worktree directory (e.g. `feat-auth`). */
|
|
8
|
+
worktreeSlug: string;
|
|
9
|
+
/** First 8 hex chars of sha256(absolute root). */
|
|
10
|
+
pathHash: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the project / worktree root.
|
|
14
|
+
* Explicit `root` wins (app project path). Otherwise prefer git toplevel, then cwd.
|
|
15
|
+
*/
|
|
16
|
+
declare function resolveRoot(root?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Identify repo + worktree for observable DB naming.
|
|
19
|
+
*/
|
|
20
|
+
declare function resolveWorktreeIdentity(root?: string): WorktreeIdentity;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/core/naming.d.ts
|
|
23
|
+
type DbMode = "dev" | "test";
|
|
24
|
+
/**
|
|
25
|
+
* Build an observable Postgres database name:
|
|
26
|
+
* cpg_<repoSlug>_<worktreeSlug>_<mode>_<pathHash8>
|
|
27
|
+
*
|
|
28
|
+
* Never drops `mode` or `pathHash`. Truncates slugs to fit ≤63 chars.
|
|
29
|
+
*/
|
|
30
|
+
declare function buildDatabaseName(identity: WorktreeIdentity, mode: DbMode): string;
|
|
31
|
+
declare function buildRoleName(databaseName: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Build a worker clone datname from a TEMPLATE database name.
|
|
34
|
+
* Layout: `<template>_c_<suffix>` truncated to ≤63 chars (keeps suffix).
|
|
35
|
+
*/
|
|
36
|
+
declare function buildCloneDatabaseName(templateName: string, suffix: string): string;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { WorktreeIdentity as a, buildRoleName as i, buildCloneDatabaseName as n, resolveRoot as o, buildDatabaseName as r, resolveWorktreeIdentity as s, DbMode as t };
|
|
39
|
+
//# sourceMappingURL=naming-C2nGVxPk.d.mts.map
|
package/dist/nx.cjs
CHANGED
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_constants = require("./constants-
|
|
3
|
-
const
|
|
2
|
+
const require_constants = require("./constants-Ct8myrEn.cjs");
|
|
3
|
+
const require_lease = require("./lease-Bq9wKwQa.cjs");
|
|
4
|
+
const require_tasks = require("./tasks-Caud9yHr.cjs");
|
|
4
5
|
//#region src/adapters/nx.ts
|
|
5
6
|
/**
|
|
6
|
-
* Nx
|
|
7
|
+
* Nx targets. `dependsOn` does not forward acquire env (unlike Vite+ `env: [...]`);
|
|
8
|
+
* wrap children with `cedarpg run`, or set `envFile` to `.cedarpg/<mode>.env`.
|
|
7
9
|
*
|
|
8
10
|
* ```json
|
|
9
11
|
* {
|
|
10
12
|
* "targets": {
|
|
11
|
-
* "
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* "dev": {
|
|
14
|
+
* "command": "cedarpg run --mode=dev -- yarn tsx scripts/apiServer/dev.ts"
|
|
15
|
+
* },
|
|
16
|
+
* "db:acquire": { "command": "cedarpg acquire --mode=dev" },
|
|
17
|
+
* "serve": {
|
|
18
|
+
* "dependsOn": ["db:acquire"],
|
|
19
|
+
* "command": "node dist/server.js",
|
|
20
|
+
* "options": { "envFile": ".cedarpg/dev.env" }
|
|
15
21
|
* }
|
|
16
22
|
* }
|
|
17
23
|
* }
|
|
18
24
|
* ```
|
|
19
|
-
*
|
|
20
|
-
* Prefer the CLI (`cedarpg` from `@cedarjs/pg`) for ensure/dispose;
|
|
21
|
-
* there is no separate Nx runtime wrapper.
|
|
22
25
|
*/
|
|
23
|
-
/**
|
|
26
|
+
/** Relative path for Nx `envFile` / dotenv. */
|
|
27
|
+
function relativeEnvFile(mode) {
|
|
28
|
+
return `${require_constants.STATE_DIRNAME}/${mode}.env`;
|
|
29
|
+
}
|
|
30
|
+
/** @deprecated Prefer `cedarPgNxTargets()`. */
|
|
24
31
|
function nxTargetHints(bin = require_constants.CLI_NAME) {
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
"db:ensure": { command: cmds.ensureDev },
|
|
28
|
-
"db:ensure-test": { command: cmds.ensureTest },
|
|
29
|
-
"db:dispose-test": { command: cmds.disposeTest }
|
|
30
|
-
};
|
|
32
|
+
return Object.fromEntries(Object.entries(require_tasks.cedarPgLifecycleTargets({ bin })).map(([name, def]) => [name, { command: def.command }]));
|
|
31
33
|
}
|
|
32
34
|
//#endregion
|
|
35
|
+
exports.CEDAR_PG_NX_ACQUIRE_DEV = require_tasks.CEDAR_PG_TASK_ACQUIRE_DEV;
|
|
36
|
+
exports.CEDAR_PG_NX_ACQUIRE_TEST = require_tasks.CEDAR_PG_TASK_ACQUIRE_TEST;
|
|
37
|
+
exports.CEDAR_PG_NX_DISPOSE_TEST = require_tasks.CEDAR_PG_TASK_DISPOSE_TEST;
|
|
38
|
+
exports.cedarPgNxTargets = require_tasks.cedarPgLifecycleTargets;
|
|
39
|
+
exports.cedarPgRunCommand = require_tasks.cedarPgRunCommand;
|
|
40
|
+
exports.envFilePath = require_lease.envFilePath;
|
|
33
41
|
exports.nxTargetHints = nxTargetHints;
|
|
42
|
+
exports.relativeEnvFile = relativeEnvFile;
|
|
34
43
|
|
|
35
44
|
//# sourceMappingURL=nx.cjs.map
|
package/dist/nx.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nx.cjs","names":["CLI_NAME","
|
|
1
|
+
{"version":3,"file":"nx.cjs","names":["STATE_DIRNAME","CLI_NAME","cedarPgLifecycleTargets"],"sources":["../src/adapters/nx.ts"],"sourcesContent":["/**\n * Nx targets. `dependsOn` does not forward acquire env (unlike Vite+ `env: [...]`);\n * wrap children with `cedarpg run`, or set `envFile` to `.cedarpg/<mode>.env`.\n *\n * ```json\n * {\n * \"targets\": {\n * \"dev\": {\n * \"command\": \"cedarpg run --mode=dev -- yarn tsx scripts/apiServer/dev.ts\"\n * },\n * \"db:acquire\": { \"command\": \"cedarpg acquire --mode=dev\" },\n * \"serve\": {\n * \"dependsOn\": [\"db:acquire\"],\n * \"command\": \"node dist/server.js\",\n * \"options\": { \"envFile\": \".cedarpg/dev.env\" }\n * }\n * }\n * }\n * ```\n */\n\nimport { CLI_NAME, STATE_DIRNAME } from \"../core/constants.ts\";\nimport { envFilePath } from \"../core/lease.ts\";\nimport type { DbMode } from \"../core/naming.ts\";\nimport {\n cedarPgLifecycleTargets,\n cedarPgRunCommand,\n type CedarPgLifecycleTarget,\n type CedarPgLifecycleTargetsOptions,\n CEDAR_PG_TASK_DISPOSE_TEST,\n CEDAR_PG_TASK_ACQUIRE_DEV,\n CEDAR_PG_TASK_ACQUIRE_TEST,\n} from \"./tasks.ts\";\n\nexport {\n CEDAR_PG_TASK_ACQUIRE_DEV as CEDAR_PG_NX_ACQUIRE_DEV,\n CEDAR_PG_TASK_ACQUIRE_TEST as CEDAR_PG_NX_ACQUIRE_TEST,\n CEDAR_PG_TASK_DISPOSE_TEST as CEDAR_PG_NX_DISPOSE_TEST,\n cedarPgLifecycleTargets as cedarPgNxTargets,\n cedarPgRunCommand,\n envFilePath,\n};\n\n/** Relative path for Nx `envFile` / dotenv. */\nexport function relativeEnvFile(mode: DbMode): string {\n return `${STATE_DIRNAME}/${mode}.env`;\n}\n\nexport type NxTargetHint = CedarPgLifecycleTarget;\nexport type CedarPgNxTargetsOptions = CedarPgLifecycleTargetsOptions;\n\n/** @deprecated Prefer `cedarPgNxTargets()`. */\nexport function nxTargetHints(bin = CLI_NAME): Record<string, { command: string }> {\n return Object.fromEntries(\n Object.entries(cedarPgLifecycleTargets({ bin })).map(([name, def]) => [\n name,\n { command: def.command },\n ]),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,gBAAgB,MAAsB;CACpD,OAAO,GAAGA,kBAAAA,cAAc,GAAG,KAAK;AAClC;;AAMA,SAAgB,cAAc,MAAMC,kBAAAA,UAA+C;CACjF,OAAO,OAAO,YACZ,OAAO,QAAQC,cAAAA,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,CACpE,MACA,EAAE,SAAS,IAAI,QAAQ,CACzB,CAAC,CACH;AACF"}
|
package/dist/nx.d.cts
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
|
+
import { t as DbMode } from "./naming-C2nGVxPk.cjs";
|
|
2
|
+
import { n as envFilePath } from "./lease-t4I9JahV.cjs";
|
|
3
|
+
import { a as CedarPgLifecycleTargetsOptions, i as CedarPgLifecycleTarget, n as CEDAR_PG_TASK_ACQUIRE_TEST, o as cedarPgLifecycleTargets, r as CEDAR_PG_TASK_DISPOSE_TEST, s as cedarPgRunCommand, t as CEDAR_PG_TASK_ACQUIRE_DEV } from "./tasks-DdQoP9We.cjs";
|
|
1
4
|
//#region src/adapters/nx.d.ts
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* "targets": {
|
|
8
|
-
* "db:ensure": { "command": "cedarpg ensure --mode=dev" },
|
|
9
|
-
* "test": {
|
|
10
|
-
* "dependsOn": ["db:ensure-test"],
|
|
11
|
-
* "command": "vitest run"
|
|
12
|
-
* }
|
|
13
|
-
* }
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* Prefer the CLI (`cedarpg` from `@cedarjs/pg`) for ensure/dispose;
|
|
18
|
-
* there is no separate Nx runtime wrapper.
|
|
19
|
-
*/
|
|
20
|
-
/** Suggested target definitions for project.json / package.json nx targets. */
|
|
5
|
+
/** Relative path for Nx `envFile` / dotenv. */
|
|
6
|
+
declare function relativeEnvFile(mode: DbMode): string;
|
|
7
|
+
type NxTargetHint = CedarPgLifecycleTarget;
|
|
8
|
+
type CedarPgNxTargetsOptions = CedarPgLifecycleTargetsOptions;
|
|
9
|
+
/** @deprecated Prefer `cedarPgNxTargets()`. */
|
|
21
10
|
declare function nxTargetHints(bin?: string): Record<string, {
|
|
22
11
|
command: string;
|
|
23
12
|
}>;
|
|
24
13
|
//#endregion
|
|
25
|
-
export { nxTargetHints };
|
|
14
|
+
export { CEDAR_PG_TASK_ACQUIRE_DEV as CEDAR_PG_NX_ACQUIRE_DEV, CEDAR_PG_TASK_ACQUIRE_TEST as CEDAR_PG_NX_ACQUIRE_TEST, CEDAR_PG_TASK_DISPOSE_TEST as CEDAR_PG_NX_DISPOSE_TEST, CedarPgNxTargetsOptions, NxTargetHint, cedarPgLifecycleTargets as cedarPgNxTargets, cedarPgRunCommand, envFilePath, nxTargetHints, relativeEnvFile };
|
|
26
15
|
//# sourceMappingURL=nx.d.cts.map
|
package/dist/nx.d.mts
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
|
+
import { t as DbMode } from "./naming-C2nGVxPk.mjs";
|
|
2
|
+
import { n as envFilePath } from "./lease-B3TuX92y.mjs";
|
|
3
|
+
import { a as CedarPgLifecycleTargetsOptions, i as CedarPgLifecycleTarget, n as CEDAR_PG_TASK_ACQUIRE_TEST, o as cedarPgLifecycleTargets, r as CEDAR_PG_TASK_DISPOSE_TEST, s as cedarPgRunCommand, t as CEDAR_PG_TASK_ACQUIRE_DEV } from "./tasks-CjaZRi_G.mjs";
|
|
1
4
|
//#region src/adapters/nx.d.ts
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* "targets": {
|
|
8
|
-
* "db:ensure": { "command": "cedarpg ensure --mode=dev" },
|
|
9
|
-
* "test": {
|
|
10
|
-
* "dependsOn": ["db:ensure-test"],
|
|
11
|
-
* "command": "vitest run"
|
|
12
|
-
* }
|
|
13
|
-
* }
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* Prefer the CLI (`cedarpg` from `@cedarjs/pg`) for ensure/dispose;
|
|
18
|
-
* there is no separate Nx runtime wrapper.
|
|
19
|
-
*/
|
|
20
|
-
/** Suggested target definitions for project.json / package.json nx targets. */
|
|
5
|
+
/** Relative path for Nx `envFile` / dotenv. */
|
|
6
|
+
declare function relativeEnvFile(mode: DbMode): string;
|
|
7
|
+
type NxTargetHint = CedarPgLifecycleTarget;
|
|
8
|
+
type CedarPgNxTargetsOptions = CedarPgLifecycleTargetsOptions;
|
|
9
|
+
/** @deprecated Prefer `cedarPgNxTargets()`. */
|
|
21
10
|
declare function nxTargetHints(bin?: string): Record<string, {
|
|
22
11
|
command: string;
|
|
23
12
|
}>;
|
|
24
13
|
//#endregion
|
|
25
|
-
export { nxTargetHints };
|
|
14
|
+
export { CEDAR_PG_TASK_ACQUIRE_DEV as CEDAR_PG_NX_ACQUIRE_DEV, CEDAR_PG_TASK_ACQUIRE_TEST as CEDAR_PG_NX_ACQUIRE_TEST, CEDAR_PG_TASK_DISPOSE_TEST as CEDAR_PG_NX_DISPOSE_TEST, CedarPgNxTargetsOptions, NxTargetHint, cedarPgLifecycleTargets as cedarPgNxTargets, cedarPgRunCommand, envFilePath, nxTargetHints, relativeEnvFile };
|
|
26
15
|
//# sourceMappingURL=nx.d.mts.map
|
package/dist/nx.mjs
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
|
-
import { t as CLI_NAME } from "./constants-
|
|
2
|
-
import { t as
|
|
1
|
+
import { r as STATE_DIRNAME, t as CLI_NAME } from "./constants-NLR0U4NR.mjs";
|
|
2
|
+
import { t as envFilePath } from "./lease-BSBBpaR4.mjs";
|
|
3
|
+
import { a as cedarPgRunCommand, i as cedarPgLifecycleTargets, n as CEDAR_PG_TASK_ACQUIRE_TEST, r as CEDAR_PG_TASK_DISPOSE_TEST, t as CEDAR_PG_TASK_ACQUIRE_DEV } from "./tasks-KherHLac.mjs";
|
|
3
4
|
//#region src/adapters/nx.ts
|
|
4
5
|
/**
|
|
5
|
-
* Nx
|
|
6
|
+
* Nx targets. `dependsOn` does not forward acquire env (unlike Vite+ `env: [...]`);
|
|
7
|
+
* wrap children with `cedarpg run`, or set `envFile` to `.cedarpg/<mode>.env`.
|
|
6
8
|
*
|
|
7
9
|
* ```json
|
|
8
10
|
* {
|
|
9
11
|
* "targets": {
|
|
10
|
-
* "
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* "dev": {
|
|
13
|
+
* "command": "cedarpg run --mode=dev -- yarn tsx scripts/apiServer/dev.ts"
|
|
14
|
+
* },
|
|
15
|
+
* "db:acquire": { "command": "cedarpg acquire --mode=dev" },
|
|
16
|
+
* "serve": {
|
|
17
|
+
* "dependsOn": ["db:acquire"],
|
|
18
|
+
* "command": "node dist/server.js",
|
|
19
|
+
* "options": { "envFile": ".cedarpg/dev.env" }
|
|
14
20
|
* }
|
|
15
21
|
* }
|
|
16
22
|
* }
|
|
17
23
|
* ```
|
|
18
|
-
*
|
|
19
|
-
* Prefer the CLI (`cedarpg` from `@cedarjs/pg`) for ensure/dispose;
|
|
20
|
-
* there is no separate Nx runtime wrapper.
|
|
21
24
|
*/
|
|
22
|
-
/**
|
|
25
|
+
/** Relative path for Nx `envFile` / dotenv. */
|
|
26
|
+
function relativeEnvFile(mode) {
|
|
27
|
+
return `${STATE_DIRNAME}/${mode}.env`;
|
|
28
|
+
}
|
|
29
|
+
/** @deprecated Prefer `cedarPgNxTargets()`. */
|
|
23
30
|
function nxTargetHints(bin = CLI_NAME) {
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
"db:ensure": { command: cmds.ensureDev },
|
|
27
|
-
"db:ensure-test": { command: cmds.ensureTest },
|
|
28
|
-
"db:dispose-test": { command: cmds.disposeTest }
|
|
29
|
-
};
|
|
31
|
+
return Object.fromEntries(Object.entries(cedarPgLifecycleTargets({ bin })).map(([name, def]) => [name, { command: def.command }]));
|
|
30
32
|
}
|
|
31
33
|
//#endregion
|
|
32
|
-
export { nxTargetHints };
|
|
34
|
+
export { CEDAR_PG_TASK_ACQUIRE_DEV as CEDAR_PG_NX_ACQUIRE_DEV, CEDAR_PG_TASK_ACQUIRE_TEST as CEDAR_PG_NX_ACQUIRE_TEST, CEDAR_PG_TASK_DISPOSE_TEST as CEDAR_PG_NX_DISPOSE_TEST, cedarPgLifecycleTargets as cedarPgNxTargets, cedarPgRunCommand, envFilePath, nxTargetHints, relativeEnvFile };
|
|
33
35
|
|
|
34
36
|
//# sourceMappingURL=nx.mjs.map
|
package/dist/nx.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nx.mjs","names":[],"sources":["../src/adapters/nx.ts"],"sourcesContent":["/**\n * Nx
|
|
1
|
+
{"version":3,"file":"nx.mjs","names":[],"sources":["../src/adapters/nx.ts"],"sourcesContent":["/**\n * Nx targets. `dependsOn` does not forward acquire env (unlike Vite+ `env: [...]`);\n * wrap children with `cedarpg run`, or set `envFile` to `.cedarpg/<mode>.env`.\n *\n * ```json\n * {\n * \"targets\": {\n * \"dev\": {\n * \"command\": \"cedarpg run --mode=dev -- yarn tsx scripts/apiServer/dev.ts\"\n * },\n * \"db:acquire\": { \"command\": \"cedarpg acquire --mode=dev\" },\n * \"serve\": {\n * \"dependsOn\": [\"db:acquire\"],\n * \"command\": \"node dist/server.js\",\n * \"options\": { \"envFile\": \".cedarpg/dev.env\" }\n * }\n * }\n * }\n * ```\n */\n\nimport { CLI_NAME, STATE_DIRNAME } from \"../core/constants.ts\";\nimport { envFilePath } from \"../core/lease.ts\";\nimport type { DbMode } from \"../core/naming.ts\";\nimport {\n cedarPgLifecycleTargets,\n cedarPgRunCommand,\n type CedarPgLifecycleTarget,\n type CedarPgLifecycleTargetsOptions,\n CEDAR_PG_TASK_DISPOSE_TEST,\n CEDAR_PG_TASK_ACQUIRE_DEV,\n CEDAR_PG_TASK_ACQUIRE_TEST,\n} from \"./tasks.ts\";\n\nexport {\n CEDAR_PG_TASK_ACQUIRE_DEV as CEDAR_PG_NX_ACQUIRE_DEV,\n CEDAR_PG_TASK_ACQUIRE_TEST as CEDAR_PG_NX_ACQUIRE_TEST,\n CEDAR_PG_TASK_DISPOSE_TEST as CEDAR_PG_NX_DISPOSE_TEST,\n cedarPgLifecycleTargets as cedarPgNxTargets,\n cedarPgRunCommand,\n envFilePath,\n};\n\n/** Relative path for Nx `envFile` / dotenv. */\nexport function relativeEnvFile(mode: DbMode): string {\n return `${STATE_DIRNAME}/${mode}.env`;\n}\n\nexport type NxTargetHint = CedarPgLifecycleTarget;\nexport type CedarPgNxTargetsOptions = CedarPgLifecycleTargetsOptions;\n\n/** @deprecated Prefer `cedarPgNxTargets()`. */\nexport function nxTargetHints(bin = CLI_NAME): Record<string, { command: string }> {\n return Object.fromEntries(\n Object.entries(cedarPgLifecycleTargets({ bin })).map(([name, def]) => [\n name,\n { command: def.command },\n ]),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,gBAAgB,MAAsB;CACpD,OAAO,GAAG,cAAc,GAAG,KAAK;AAClC;;AAMA,SAAgB,cAAc,MAAM,UAA+C;CACjF,OAAO,OAAO,YACZ,OAAO,QAAQ,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,CACpE,MACA,EAAE,SAAS,IAAI,QAAQ,CACzB,CAAC,CACH;AACF"}
|