@cedarjs/pg 0.2.0-alpha.0 → 0.2.0-beta.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 +250 -229
- package/dist/cli.cjs +89 -39
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +73 -23
- package/dist/cli.mjs.map +1 -1
- package/dist/dev-env.cjs +1 -1
- package/dist/dev-env.mjs +1 -1
- package/dist/index.cjs +9 -8
- package/dist/index.d.cts +31 -3
- package/dist/index.d.mts +31 -3
- package/dist/index.mjs +7 -7
- package/dist/jest-teardown.cjs +1 -1
- package/dist/jest-teardown.mjs +1 -1
- package/dist/jest-template.cjs +4 -1
- package/dist/jest-template.cjs.map +1 -1
- package/dist/jest-template.d.cts +4 -1
- package/dist/jest-template.d.mts +4 -1
- package/dist/jest-template.mjs +4 -1
- package/dist/jest-template.mjs.map +1 -1
- package/dist/jest.cjs +1 -1
- package/dist/jest.mjs +1 -1
- package/dist/{lease-BSBBpaR4.mjs → lease-DS1SX8U_.mjs} +23 -3
- package/dist/lease-DS1SX8U_.mjs.map +1 -0
- package/dist/{lease-Bq9wKwQa.cjs → lease-WlmOnNDi.cjs} +41 -3
- package/dist/lease-WlmOnNDi.cjs.map +1 -0
- package/dist/{lifecycle-DEJ4GgWV.cjs → lifecycle-BbrvFQvg.cjs} +175 -78
- package/dist/lifecycle-BbrvFQvg.cjs.map +1 -0
- package/dist/{lifecycle-BOo6xBjD.mjs → lifecycle-BvIx0xqq.mjs} +175 -78
- package/dist/lifecycle-BvIx0xqq.mjs.map +1 -0
- package/dist/{load-dev-env-7UjMHhw7.mjs → load-dev-env-BULkXyen.mjs} +2 -2
- package/dist/{load-dev-env-7UjMHhw7.mjs.map → load-dev-env-BULkXyen.mjs.map} +1 -1
- package/dist/{load-dev-env-cII6N4ZP.cjs → load-dev-env-Bl6Ddv1U.cjs} +2 -2
- package/dist/{load-dev-env-cII6N4ZP.cjs.map → load-dev-env-Bl6Ddv1U.cjs.map} +1 -1
- package/dist/{load-mode-env-B0qO9DZx.cjs → load-mode-env-CX9vd56X.cjs} +2 -2
- package/dist/{load-mode-env-B0qO9DZx.cjs.map → load-mode-env-CX9vd56X.cjs.map} +1 -1
- package/dist/{load-mode-env-C8gy4v9V.mjs → load-mode-env-Ce9ujisN.mjs} +2 -2
- package/dist/{load-mode-env-C8gy4v9V.mjs.map → load-mode-env-Ce9ujisN.mjs.map} +1 -1
- package/dist/{load-test-env-C34wpkIX.mjs → load-test-env-BqtA6V-d.mjs} +2 -2
- package/dist/{load-test-env-C34wpkIX.mjs.map → load-test-env-BqtA6V-d.mjs.map} +1 -1
- package/dist/{load-test-env-CkdUjTpV.cjs → load-test-env-Dcgh6YHV.cjs} +2 -2
- package/dist/{load-test-env-CkdUjTpV.cjs.map → load-test-env-Dcgh6YHV.cjs.map} +1 -1
- package/dist/nx.cjs +12 -14
- package/dist/nx.cjs.map +1 -1
- package/dist/nx.mjs +10 -12
- package/dist/nx.mjs.map +1 -1
- package/dist/status-4Uz6A3LB.cjs +31 -0
- package/dist/status-4Uz6A3LB.cjs.map +1 -0
- package/dist/status-Dcnpgnlz.mjs +26 -0
- package/dist/status-Dcnpgnlz.mjs.map +1 -0
- package/dist/studio-DIFw1qWC.mjs +173 -0
- package/dist/studio-DIFw1qWC.mjs.map +1 -0
- package/dist/studio-oJE30_PO.cjs +208 -0
- package/dist/studio-oJE30_PO.cjs.map +1 -0
- package/dist/{tasks-Caud9yHr.cjs → tasks-CNHvvlsN.cjs} +4 -4
- package/dist/{tasks-Caud9yHr.cjs.map → tasks-CNHvvlsN.cjs.map} +1 -1
- package/dist/{tasks-KherHLac.mjs → tasks-D5iWIdlo.mjs} +2 -2
- package/dist/{tasks-KherHLac.mjs.map → tasks-D5iWIdlo.mjs.map} +1 -1
- package/dist/{template-CGw3C1Ob.mjs → template-BiJ-0TIF.mjs} +3 -3
- package/dist/{template-CGw3C1Ob.mjs.map → template-BiJ-0TIF.mjs.map} +1 -1
- package/dist/{template-D0gJ_MS2.cjs → template-CXMpODzK.cjs} +3 -3
- package/dist/{template-D0gJ_MS2.cjs.map → template-CXMpODzK.cjs.map} +1 -1
- package/dist/{template-mode-IjlFOG4O.mjs → template-mode-BTUsdBtA.mjs} +27 -13
- package/dist/template-mode-BTUsdBtA.mjs.map +1 -0
- package/dist/{template-mode-CcxV_Iju.d.cts → template-mode-CzyVwHsi.d.cts} +4 -1
- package/dist/{template-mode-CcxV_Iju.d.mts → template-mode-CzyVwHsi.d.mts} +4 -1
- package/dist/{template-mode-BkEs9LnY.cjs → template-mode-JTOxrEgE.cjs} +27 -13
- package/dist/template-mode-JTOxrEgE.cjs.map +1 -0
- package/dist/test-env.cjs +1 -1
- package/dist/test-env.mjs +1 -1
- package/dist/vite-plus.cjs +107 -4
- package/dist/vite-plus.cjs.map +1 -1
- package/dist/vite-plus.d.cts +25 -1
- package/dist/vite-plus.d.mts +25 -1
- package/dist/vite-plus.mjs +108 -5
- package/dist/vite-plus.mjs.map +1 -1
- package/dist/vitest-template.cjs +1 -1
- package/dist/vitest-template.d.cts +1 -1
- package/dist/vitest-template.d.mts +1 -1
- package/dist/vitest-template.mjs +1 -1
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/package.json +11 -2
- package/dist/constants-Ct8myrEn.cjs +0 -41
- package/dist/constants-Ct8myrEn.cjs.map +0 -1
- package/dist/constants-NLR0U4NR.mjs +0 -24
- package/dist/constants-NLR0U4NR.mjs.map +0 -1
- package/dist/lease-BSBBpaR4.mjs.map +0 -1
- package/dist/lease-Bq9wKwQa.cjs.map +0 -1
- package/dist/lifecycle-BOo6xBjD.mjs.map +0 -1
- package/dist/lifecycle-DEJ4GgWV.cjs.map +0 -1
- package/dist/template-mode-BkEs9LnY.cjs.map +0 -1
- package/dist/template-mode-IjlFOG4O.mjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_lifecycle = require("./lifecycle-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
2
|
+
const require_lifecycle = require("./lifecycle-BbrvFQvg.cjs");
|
|
3
|
+
const require_lease = require("./lease-WlmOnNDi.cjs");
|
|
4
|
+
const require_status = require("./status-4Uz6A3LB.cjs");
|
|
5
|
+
const require_studio = require("./studio-oJE30_PO.cjs");
|
|
6
6
|
//#region src/cli.ts
|
|
7
7
|
function printHelp() {
|
|
8
|
-
process.stdout.write(`${
|
|
8
|
+
process.stdout.write(`${require_lease.CLI_NAME}: worktree-isolated local Postgres (via autopg)
|
|
9
9
|
|
|
10
10
|
Usage:
|
|
11
|
-
${
|
|
12
|
-
${
|
|
13
|
-
${
|
|
14
|
-
${
|
|
15
|
-
${
|
|
16
|
-
${
|
|
11
|
+
${require_lease.CLI_NAME} acquire --mode=dev|test [--root <path>] [--force] [--json] [--print-env]
|
|
12
|
+
${require_lease.CLI_NAME} run --mode=dev|test [--root <path>] [--force] -- <cmd…>
|
|
13
|
+
${require_lease.CLI_NAME} dispose [--mode=dev|test] [--root <path>]
|
|
14
|
+
${require_lease.CLI_NAME} gc [--json]
|
|
15
|
+
${require_lease.CLI_NAME} print-url [--mode=dev|test] [--root <path>]
|
|
16
|
+
${require_lease.CLI_NAME} status [--mode=dev|test] [--root <path>] [--json]
|
|
17
|
+
${require_lease.CLI_NAME} studio [--mode=dev|test] [--root <path>] [--prisma|--drizzle]
|
|
18
|
+
${require_lease.CLI_NAME} --help
|
|
17
19
|
|
|
18
20
|
Modes:
|
|
19
21
|
dev Keep DB across restarts (default when --mode omitted)
|
|
@@ -23,6 +25,11 @@ run:
|
|
|
23
25
|
Acquire, set DATABASE_URL (+ TEST_DATABASE_URL in test) on the child, exec <cmd…>.
|
|
24
26
|
--force sets CEDAR_PG_FORCE (escape hatch); child env overwrite is always on.
|
|
25
27
|
|
|
28
|
+
status / studio:
|
|
29
|
+
Read-only lease inspection (no acquire). studio runs Prisma or Drizzle Kit Studio
|
|
30
|
+
attached (stdio + exit code) with DATABASE_URL from the lease. Detects from cwd
|
|
31
|
+
up to the worktree (auto; --prisma / --drizzle to force).
|
|
32
|
+
|
|
26
33
|
Env:
|
|
27
34
|
AUTOPG_BIN Path to autopg binary
|
|
28
35
|
CEDAR_PG=0 Disable adapters that auto-acquire
|
|
@@ -49,6 +56,8 @@ function parseArgs(argv) {
|
|
|
49
56
|
else if (a === "--json") out.json = true;
|
|
50
57
|
else if (a === "--print-env") out.printEnv = true;
|
|
51
58
|
else if (a === "--force") out.force = true;
|
|
59
|
+
else if (a === "--prisma") out.prisma = true;
|
|
60
|
+
else if (a === "--drizzle") out.drizzle = true;
|
|
52
61
|
else if (a.startsWith("--mode=")) out.mode = parseMode(a.slice(7));
|
|
53
62
|
else if (a === "--mode") out.mode = parseMode(flagArgs[++i]);
|
|
54
63
|
else if (a.startsWith("--root=")) out.root = a.slice(7);
|
|
@@ -57,18 +66,66 @@ function parseArgs(argv) {
|
|
|
57
66
|
}
|
|
58
67
|
return out;
|
|
59
68
|
}
|
|
69
|
+
function studioPrefer(args) {
|
|
70
|
+
if (args.prisma && args.drizzle) throw new Error("pass only one of --prisma or --drizzle");
|
|
71
|
+
if (args.prisma) return "prisma";
|
|
72
|
+
if (args.drizzle) return "drizzle";
|
|
73
|
+
}
|
|
74
|
+
function writeLines(stream, lines) {
|
|
75
|
+
for (const line of lines) stream.write(`${line}\n`);
|
|
76
|
+
}
|
|
60
77
|
function runChild(command, env) {
|
|
61
78
|
const [file, ...args] = command;
|
|
62
|
-
if (!file) throw new Error(`run requires a command after -- (e.g. ${
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
if (!file) throw new Error(`run requires a command after -- (e.g. ${require_lease.CLI_NAME} run --mode=dev -- yarn dev)`);
|
|
80
|
+
return require_studio.runAttached(file, args, { env });
|
|
81
|
+
}
|
|
82
|
+
function cmdPrintUrl(args) {
|
|
83
|
+
const status = require_status.resolveDevStatus({
|
|
84
|
+
root: args.root,
|
|
85
|
+
mode: args.mode
|
|
86
|
+
});
|
|
87
|
+
if (!status.ok) {
|
|
88
|
+
writeLines(process.stderr, require_studio.formatDevStatus(status));
|
|
89
|
+
return 2;
|
|
90
|
+
}
|
|
91
|
+
process.stdout.write(`${status.databaseUrl}\n`);
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
function cmdStatus(args) {
|
|
95
|
+
const status = require_status.resolveDevStatus({
|
|
96
|
+
root: args.root,
|
|
97
|
+
mode: args.mode
|
|
98
|
+
});
|
|
99
|
+
if (args.json) {
|
|
100
|
+
process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
|
|
101
|
+
return status.ok ? 0 : 2;
|
|
102
|
+
}
|
|
103
|
+
writeLines(process.stdout, require_studio.formatDevStatus(status));
|
|
104
|
+
return status.ok ? 0 : 2;
|
|
105
|
+
}
|
|
106
|
+
async function cmdStudio(args) {
|
|
107
|
+
const prefer = studioPrefer(args);
|
|
108
|
+
const status = require_status.resolveDevStatus({
|
|
109
|
+
root: args.root,
|
|
110
|
+
mode: args.mode
|
|
111
|
+
});
|
|
112
|
+
if (!status.ok) {
|
|
113
|
+
writeLines(process.stderr, require_studio.formatDevStatus(status));
|
|
114
|
+
return 2;
|
|
115
|
+
}
|
|
116
|
+
const studio = require_studio.detectStudio({
|
|
117
|
+
root: status.root,
|
|
118
|
+
cwd: process.cwd(),
|
|
119
|
+
prefer
|
|
120
|
+
});
|
|
121
|
+
if (!studio) {
|
|
122
|
+
process.stderr.write(`${require_lease.CLI_NAME}: no Prisma or Drizzle Studio found (install prisma or drizzle-kit)\n`);
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
process.stdout.write(`${require_lease.CLI_NAME}: opening ${studio.kind} studio (${studio.command} ${studio.args.join(" ")})\n`);
|
|
126
|
+
return require_studio.runStudio({
|
|
127
|
+
databaseUrl: status.databaseUrl,
|
|
128
|
+
studio
|
|
72
129
|
});
|
|
73
130
|
}
|
|
74
131
|
async function main() {
|
|
@@ -108,7 +165,7 @@ async function main() {
|
|
|
108
165
|
root: result.root
|
|
109
166
|
}, null, 2)}\n`);
|
|
110
167
|
else if (!args.printEnv) {
|
|
111
|
-
process.stdout.write(`${
|
|
168
|
+
process.stdout.write(`${require_lease.CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\n`);
|
|
112
169
|
process.stdout.write(`${result.databaseUrl}\n`);
|
|
113
170
|
}
|
|
114
171
|
return 0;
|
|
@@ -135,41 +192,34 @@ async function main() {
|
|
|
135
192
|
mode
|
|
136
193
|
});
|
|
137
194
|
if (result.dropped) {
|
|
138
|
-
process.stdout.write(`${
|
|
195
|
+
process.stdout.write(`${require_lease.CLI_NAME}: disposed ${mode} (${result.databaseName})\n`);
|
|
139
196
|
return 0;
|
|
140
197
|
}
|
|
141
198
|
if (result.reason === "no-lease") {
|
|
142
|
-
process.stdout.write(`${
|
|
199
|
+
process.stdout.write(`${require_lease.CLI_NAME}: nothing to dispose for ${mode} (no lease)\n`);
|
|
143
200
|
return 0;
|
|
144
201
|
}
|
|
145
|
-
process.stderr.write(`${
|
|
202
|
+
process.stderr.write(`${require_lease.CLI_NAME}: could not dispose ${mode}: autopg host unavailable (lease kept for retry)\n`);
|
|
146
203
|
return 1;
|
|
147
204
|
}
|
|
148
205
|
if (args.cmd === "gc") {
|
|
149
206
|
const result = await require_lifecycle.gc();
|
|
150
207
|
if (args.json) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
151
208
|
else {
|
|
152
|
-
process.stdout.write(`${
|
|
209
|
+
process.stdout.write(`${require_lease.CLI_NAME} gc: dropped ${result.dropped.length} database(s)\n`);
|
|
153
210
|
for (const name of result.dropped) process.stdout.write(` ${name}\n`);
|
|
154
211
|
}
|
|
155
212
|
return 0;
|
|
156
213
|
}
|
|
157
|
-
if (args.cmd === "print-url")
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
process.stderr.write(`${require_constants.CLI_NAME}: no ${mode} lease; run \`${require_constants.CLI_NAME} acquire --mode=${mode}\` first\n`);
|
|
162
|
-
return 2;
|
|
163
|
-
}
|
|
164
|
-
process.stdout.write(`${require_lifecycle.urlFromLease(lease)}\n`);
|
|
165
|
-
return 0;
|
|
166
|
-
}
|
|
167
|
-
process.stderr.write(`${require_constants.CLI_NAME}: unknown command ${args.cmd}\n`);
|
|
214
|
+
if (args.cmd === "print-url") return cmdPrintUrl(args);
|
|
215
|
+
if (args.cmd === "status") return cmdStatus(args);
|
|
216
|
+
if (args.cmd === "studio") return await cmdStudio(args);
|
|
217
|
+
process.stderr.write(`${require_lease.CLI_NAME}: unknown command ${args.cmd}\n`);
|
|
168
218
|
printHelp();
|
|
169
219
|
return 64;
|
|
170
220
|
} catch (err) {
|
|
171
221
|
const message = err instanceof Error ? err.message : String(err);
|
|
172
|
-
process.stderr.write(`${
|
|
222
|
+
process.stderr.write(`${require_lease.CLI_NAME}: ${message}\n`);
|
|
173
223
|
return 1;
|
|
174
224
|
}
|
|
175
225
|
}
|
|
@@ -177,7 +227,7 @@ main().then((code) => {
|
|
|
177
227
|
process.exit(code);
|
|
178
228
|
}).catch((err) => {
|
|
179
229
|
const message = err instanceof Error ? err.message : String(err);
|
|
180
|
-
process.stderr.write(`${
|
|
230
|
+
process.stderr.write(`${require_lease.CLI_NAME}: ${message}\n`);
|
|
181
231
|
process.exit(1);
|
|
182
232
|
});
|
|
183
233
|
//#endregion
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["CLI_NAME","acquire","dispose","gc","readLease","resolveWorktreeIdentity","urlFromLease"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { spawn } from \"node:child_process\";\nimport { CLI_NAME } from \"./core/constants.ts\";\nimport { acquire, dispose, gc, urlFromLease } from \"./core/lifecycle.ts\";\nimport { resolveWorktreeIdentity } from \"./core/worktree.ts\";\nimport { readLease } from \"./core/lease.ts\";\nimport type { DbMode } from \"./core/naming.ts\";\n\nfunction printHelp(): void {\n process.stdout.write(`${CLI_NAME}: worktree-isolated local Postgres (via autopg)\n\nUsage:\n ${CLI_NAME} acquire --mode=dev|test [--root <path>] [--force] [--json] [--print-env]\n ${CLI_NAME} run --mode=dev|test [--root <path>] [--force] -- <cmd…>\n ${CLI_NAME} dispose [--mode=dev|test] [--root <path>]\n ${CLI_NAME} gc [--json]\n ${CLI_NAME} print-url [--mode=dev|test] [--root <path>]\n ${CLI_NAME} --help\n\nModes:\n dev Keep DB across restarts (default when --mode omitted)\n test Drop DB on dispose / test teardown\n\nrun:\n Acquire, set DATABASE_URL (+ TEST_DATABASE_URL in test) on the child, exec <cmd…>.\n --force sets CEDAR_PG_FORCE (escape hatch); child env overwrite is always on.\n\nEnv:\n AUTOPG_BIN Path to autopg binary\n CEDAR_PG=0 Disable adapters that auto-acquire\n CEDAR_PG_FORCE=1 Ignore external-URL escape hatch (same as --force)\n`);\n}\n\nfunction parseMode(value: string | undefined): DbMode {\n if (value === \"dev\" || value === \"test\") return value;\n throw new Error(\"--mode must be dev or test\");\n}\n\ntype ParsedArgs = {\n cmd?: string;\n mode?: DbMode;\n root?: string;\n json?: boolean;\n printEnv?: boolean;\n force?: boolean;\n help?: boolean;\n child?: string[];\n};\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const out: ParsedArgs = {};\n const rest = [...argv];\n out.cmd = rest.shift();\n\n const dash = rest.indexOf(\"--\");\n let flagArgs = rest;\n if (dash >= 0) {\n flagArgs = rest.slice(0, dash);\n out.child = rest.slice(dash + 1);\n }\n\n for (let i = 0; i < flagArgs.length; i++) {\n const a = flagArgs[i]!;\n if (a === \"--help\" || a === \"-h\") out.help = true;\n else if (a === \"--json\") out.json = true;\n else if (a === \"--print-env\") out.printEnv = true;\n else if (a === \"--force\") out.force = true;\n else if (a.startsWith(\"--mode=\")) out.mode = parseMode(a.slice(7));\n else if (a === \"--mode\") out.mode = parseMode(flagArgs[++i]);\n else if (a.startsWith(\"--root=\")) out.root = a.slice(7);\n else if (a === \"--root\") out.root = flagArgs[++i];\n else throw new Error(`unknown argument: ${a}`);\n }\n return out;\n}\n\nfunction runChild(command: string[], env: NodeJS.ProcessEnv): Promise<number> {\n const [file, ...args] = command;\n if (!file) {\n throw new Error(\n `run requires a command after -- (e.g. ${CLI_NAME} run --mode=dev -- yarn dev)`,\n );\n }\n return new Promise((resolve, reject) => {\n const child = spawn(file, args, { stdio: \"inherit\", env });\n child.on(\"error\", reject);\n child.on(\"exit\", (code, signal) => {\n resolve(signal ? 1 : (code ?? 1));\n });\n });\n}\n\nasync function main(): Promise<number> {\n const argv = process.argv.slice(2);\n if (argv.length === 0 || argv[0] === \"help\" || argv[0] === \"--help\" || argv[0] === \"-h\") {\n printHelp();\n return 0;\n }\n const args = parseArgs(argv);\n if (args.help) {\n printHelp();\n return 0;\n }\n\n try {\n if (args.cmd === \"acquire\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n if (args.printEnv) {\n process.stdout.write(`DATABASE_URL=${result.databaseUrl}\\n`);\n if (mode === \"test\") {\n process.stdout.write(`TEST_DATABASE_URL=${result.databaseUrl}\\n`);\n }\n }\n if (args.json) {\n process.stdout.write(\n `${JSON.stringify(\n {\n databaseUrl: result.databaseUrl,\n adminUrl: result.adminUrl,\n databaseName: result.databaseName,\n roleName: result.roleName,\n repoSlug: result.repoSlug,\n worktreeSlug: result.worktreeSlug,\n pathHash: result.pathHash,\n mode: result.mode,\n port: result.port,\n root: result.root,\n },\n null,\n 2,\n )}\\n`,\n );\n } else if (!args.printEnv) {\n process.stdout.write(\n `${CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\\n`,\n );\n process.stdout.write(`${result.databaseUrl}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"run\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n const childEnv: NodeJS.ProcessEnv = {\n ...process.env,\n DATABASE_URL: result.databaseUrl,\n };\n if (mode === \"test\") childEnv.TEST_DATABASE_URL = result.databaseUrl;\n return await runChild(args.child ?? [], childEnv);\n }\n\n if (args.cmd === \"dispose\") {\n const mode = args.mode ?? \"test\";\n const result = await dispose({ root: args.root, mode });\n if (result.dropped) {\n process.stdout.write(`${CLI_NAME}: disposed ${mode} (${result.databaseName})\\n`);\n return 0;\n }\n if (result.reason === \"no-lease\") {\n process.stdout.write(`${CLI_NAME}: nothing to dispose for ${mode} (no lease)\\n`);\n return 0;\n }\n process.stderr.write(\n `${CLI_NAME}: could not dispose ${mode}: autopg host unavailable (lease kept for retry)\\n`,\n );\n return 1;\n }\n\n if (args.cmd === \"gc\") {\n const result = await gc();\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n } else {\n process.stdout.write(`${CLI_NAME} gc: dropped ${result.dropped.length} database(s)\\n`);\n for (const name of result.dropped) process.stdout.write(` ${name}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"print-url\") {\n const mode = args.mode ?? \"dev\";\n const identity = resolveWorktreeIdentity(args.root);\n const lease = readLease(identity.root, mode);\n if (!lease) {\n process.stderr.write(\n `${CLI_NAME}: no ${mode} lease; run \\`${CLI_NAME} acquire --mode=${mode}\\` first\\n`,\n );\n return 2;\n }\n process.stdout.write(`${urlFromLease(lease)}\\n`);\n return 0;\n }\n\n process.stderr.write(`${CLI_NAME}: unknown command ${args.cmd}\\n`);\n printHelp();\n return 64;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n return 1;\n }\n}\n\nmain()\n .then((code) => {\n process.exit(code);\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n process.exit(1);\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["CLI_NAME","runAttached","resolveDevStatus","formatDevStatus","detectStudio","runStudio","acquire","dispose","gc"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { CLI_NAME } from \"./core/constants.ts\";\nimport { acquire, dispose, gc } from \"./core/lifecycle.ts\";\nimport { resolveDevStatus } from \"./core/status.ts\";\nimport type { DbMode } from \"./core/naming.ts\";\nimport { runAttached } from \"./adapters/child.ts\";\nimport { formatDevStatus } from \"./adapters/status-format.ts\";\nimport { detectStudio, runStudio, type StudioKind } from \"./adapters/studio.ts\";\n\nfunction printHelp(): void {\n process.stdout.write(`${CLI_NAME}: worktree-isolated local Postgres (via autopg)\n\nUsage:\n ${CLI_NAME} acquire --mode=dev|test [--root <path>] [--force] [--json] [--print-env]\n ${CLI_NAME} run --mode=dev|test [--root <path>] [--force] -- <cmd…>\n ${CLI_NAME} dispose [--mode=dev|test] [--root <path>]\n ${CLI_NAME} gc [--json]\n ${CLI_NAME} print-url [--mode=dev|test] [--root <path>]\n ${CLI_NAME} status [--mode=dev|test] [--root <path>] [--json]\n ${CLI_NAME} studio [--mode=dev|test] [--root <path>] [--prisma|--drizzle]\n ${CLI_NAME} --help\n\nModes:\n dev Keep DB across restarts (default when --mode omitted)\n test Drop DB on dispose / test teardown\n\nrun:\n Acquire, set DATABASE_URL (+ TEST_DATABASE_URL in test) on the child, exec <cmd…>.\n --force sets CEDAR_PG_FORCE (escape hatch); child env overwrite is always on.\n\nstatus / studio:\n Read-only lease inspection (no acquire). studio runs Prisma or Drizzle Kit Studio\n attached (stdio + exit code) with DATABASE_URL from the lease. Detects from cwd\n up to the worktree (auto; --prisma / --drizzle to force).\n\nEnv:\n AUTOPG_BIN Path to autopg binary\n CEDAR_PG=0 Disable adapters that auto-acquire\n CEDAR_PG_FORCE=1 Ignore external-URL escape hatch (same as --force)\n`);\n}\n\nfunction parseMode(value: string | undefined): DbMode {\n if (value === \"dev\" || value === \"test\") return value;\n throw new Error(\"--mode must be dev or test\");\n}\n\ntype ParsedArgs = {\n cmd?: string;\n mode?: DbMode;\n root?: string;\n json?: boolean;\n printEnv?: boolean;\n force?: boolean;\n help?: boolean;\n prisma?: boolean;\n drizzle?: boolean;\n child?: string[];\n};\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const out: ParsedArgs = {};\n const rest = [...argv];\n out.cmd = rest.shift();\n\n const dash = rest.indexOf(\"--\");\n let flagArgs = rest;\n if (dash >= 0) {\n flagArgs = rest.slice(0, dash);\n out.child = rest.slice(dash + 1);\n }\n\n for (let i = 0; i < flagArgs.length; i++) {\n const a = flagArgs[i]!;\n if (a === \"--help\" || a === \"-h\") out.help = true;\n else if (a === \"--json\") out.json = true;\n else if (a === \"--print-env\") out.printEnv = true;\n else if (a === \"--force\") out.force = true;\n else if (a === \"--prisma\") out.prisma = true;\n else if (a === \"--drizzle\") out.drizzle = true;\n else if (a.startsWith(\"--mode=\")) out.mode = parseMode(a.slice(7));\n else if (a === \"--mode\") out.mode = parseMode(flagArgs[++i]);\n else if (a.startsWith(\"--root=\")) out.root = a.slice(7);\n else if (a === \"--root\") out.root = flagArgs[++i];\n else throw new Error(`unknown argument: ${a}`);\n }\n return out;\n}\n\nfunction studioPrefer(args: ParsedArgs): StudioKind | undefined {\n if (args.prisma && args.drizzle) {\n throw new Error(\"pass only one of --prisma or --drizzle\");\n }\n if (args.prisma) return \"prisma\";\n if (args.drizzle) return \"drizzle\";\n return undefined;\n}\n\nfunction writeLines(stream: NodeJS.WriteStream, lines: string[]): void {\n for (const line of lines) stream.write(`${line}\\n`);\n}\n\nfunction runChild(command: string[], env: NodeJS.ProcessEnv): Promise<number> {\n const [file, ...args] = command;\n if (!file) {\n throw new Error(\n `run requires a command after -- (e.g. ${CLI_NAME} run --mode=dev -- yarn dev)`,\n );\n }\n return runAttached(file, args, { env });\n}\n\nfunction cmdPrintUrl(args: ParsedArgs): number {\n const status = resolveDevStatus({ root: args.root, mode: args.mode });\n if (!status.ok) {\n writeLines(process.stderr, formatDevStatus(status));\n return 2;\n }\n process.stdout.write(`${status.databaseUrl}\\n`);\n return 0;\n}\n\nfunction cmdStatus(args: ParsedArgs): number {\n const status = resolveDevStatus({ root: args.root, mode: args.mode });\n if (args.json) {\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return status.ok ? 0 : 2;\n }\n writeLines(process.stdout, formatDevStatus(status));\n return status.ok ? 0 : 2;\n}\n\nasync function cmdStudio(args: ParsedArgs): Promise<number> {\n const prefer = studioPrefer(args);\n const status = resolveDevStatus({ root: args.root, mode: args.mode });\n if (!status.ok) {\n writeLines(process.stderr, formatDevStatus(status));\n return 2;\n }\n const studio = detectStudio({ root: status.root, cwd: process.cwd(), prefer });\n if (!studio) {\n process.stderr.write(\n `${CLI_NAME}: no Prisma or Drizzle Studio found (install prisma or drizzle-kit)\\n`,\n );\n return 1;\n }\n process.stdout.write(\n `${CLI_NAME}: opening ${studio.kind} studio (${studio.command} ${studio.args.join(\" \")})\\n`,\n );\n return runStudio({ databaseUrl: status.databaseUrl, studio });\n}\n\nasync function main(): Promise<number> {\n const argv = process.argv.slice(2);\n if (argv.length === 0 || argv[0] === \"help\" || argv[0] === \"--help\" || argv[0] === \"-h\") {\n printHelp();\n return 0;\n }\n const args = parseArgs(argv);\n if (args.help) {\n printHelp();\n return 0;\n }\n\n try {\n if (args.cmd === \"acquire\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n if (args.printEnv) {\n process.stdout.write(`DATABASE_URL=${result.databaseUrl}\\n`);\n if (mode === \"test\") {\n process.stdout.write(`TEST_DATABASE_URL=${result.databaseUrl}\\n`);\n }\n }\n if (args.json) {\n process.stdout.write(\n `${JSON.stringify(\n {\n databaseUrl: result.databaseUrl,\n adminUrl: result.adminUrl,\n databaseName: result.databaseName,\n roleName: result.roleName,\n repoSlug: result.repoSlug,\n worktreeSlug: result.worktreeSlug,\n pathHash: result.pathHash,\n mode: result.mode,\n port: result.port,\n root: result.root,\n },\n null,\n 2,\n )}\\n`,\n );\n } else if (!args.printEnv) {\n process.stdout.write(\n `${CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\\n`,\n );\n process.stdout.write(`${result.databaseUrl}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"run\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n const childEnv: NodeJS.ProcessEnv = {\n ...process.env,\n DATABASE_URL: result.databaseUrl,\n };\n if (mode === \"test\") childEnv.TEST_DATABASE_URL = result.databaseUrl;\n return await runChild(args.child ?? [], childEnv);\n }\n\n if (args.cmd === \"dispose\") {\n const mode = args.mode ?? \"test\";\n const result = await dispose({ root: args.root, mode });\n if (result.dropped) {\n process.stdout.write(`${CLI_NAME}: disposed ${mode} (${result.databaseName})\\n`);\n return 0;\n }\n if (result.reason === \"no-lease\") {\n process.stdout.write(`${CLI_NAME}: nothing to dispose for ${mode} (no lease)\\n`);\n return 0;\n }\n process.stderr.write(\n `${CLI_NAME}: could not dispose ${mode}: autopg host unavailable (lease kept for retry)\\n`,\n );\n return 1;\n }\n\n if (args.cmd === \"gc\") {\n const result = await gc();\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n } else {\n process.stdout.write(`${CLI_NAME} gc: dropped ${result.dropped.length} database(s)\\n`);\n for (const name of result.dropped) process.stdout.write(` ${name}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"print-url\") {\n return cmdPrintUrl(args);\n }\n\n if (args.cmd === \"status\") {\n return cmdStatus(args);\n }\n\n if (args.cmd === \"studio\") {\n return await cmdStudio(args);\n }\n\n process.stderr.write(`${CLI_NAME}: unknown command ${args.cmd}\\n`);\n printHelp();\n return 64;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n return 1;\n }\n}\n\nmain()\n .then((code) => {\n process.exit(code);\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n process.exit(1);\n });\n"],"mappings":"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"}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { i as gc, r as dispose, t as acquire } from "./lifecycle-BvIx0xqq.mjs";
|
|
3
|
+
import { p as CLI_NAME } from "./lease-DS1SX8U_.mjs";
|
|
4
|
+
import { t as resolveDevStatus } from "./status-Dcnpgnlz.mjs";
|
|
5
|
+
import { a as formatDevStatus, o as runAttached, r as runStudio, t as detectStudio } from "./studio-DIFw1qWC.mjs";
|
|
6
6
|
//#region src/cli.ts
|
|
7
7
|
function printHelp() {
|
|
8
8
|
process.stdout.write(`${CLI_NAME}: worktree-isolated local Postgres (via autopg)
|
|
@@ -13,6 +13,8 @@ Usage:
|
|
|
13
13
|
${CLI_NAME} dispose [--mode=dev|test] [--root <path>]
|
|
14
14
|
${CLI_NAME} gc [--json]
|
|
15
15
|
${CLI_NAME} print-url [--mode=dev|test] [--root <path>]
|
|
16
|
+
${CLI_NAME} status [--mode=dev|test] [--root <path>] [--json]
|
|
17
|
+
${CLI_NAME} studio [--mode=dev|test] [--root <path>] [--prisma|--drizzle]
|
|
16
18
|
${CLI_NAME} --help
|
|
17
19
|
|
|
18
20
|
Modes:
|
|
@@ -23,6 +25,11 @@ run:
|
|
|
23
25
|
Acquire, set DATABASE_URL (+ TEST_DATABASE_URL in test) on the child, exec <cmd…>.
|
|
24
26
|
--force sets CEDAR_PG_FORCE (escape hatch); child env overwrite is always on.
|
|
25
27
|
|
|
28
|
+
status / studio:
|
|
29
|
+
Read-only lease inspection (no acquire). studio runs Prisma or Drizzle Kit Studio
|
|
30
|
+
attached (stdio + exit code) with DATABASE_URL from the lease. Detects from cwd
|
|
31
|
+
up to the worktree (auto; --prisma / --drizzle to force).
|
|
32
|
+
|
|
26
33
|
Env:
|
|
27
34
|
AUTOPG_BIN Path to autopg binary
|
|
28
35
|
CEDAR_PG=0 Disable adapters that auto-acquire
|
|
@@ -49,6 +56,8 @@ function parseArgs(argv) {
|
|
|
49
56
|
else if (a === "--json") out.json = true;
|
|
50
57
|
else if (a === "--print-env") out.printEnv = true;
|
|
51
58
|
else if (a === "--force") out.force = true;
|
|
59
|
+
else if (a === "--prisma") out.prisma = true;
|
|
60
|
+
else if (a === "--drizzle") out.drizzle = true;
|
|
52
61
|
else if (a.startsWith("--mode=")) out.mode = parseMode(a.slice(7));
|
|
53
62
|
else if (a === "--mode") out.mode = parseMode(flagArgs[++i]);
|
|
54
63
|
else if (a.startsWith("--root=")) out.root = a.slice(7);
|
|
@@ -57,18 +66,66 @@ function parseArgs(argv) {
|
|
|
57
66
|
}
|
|
58
67
|
return out;
|
|
59
68
|
}
|
|
69
|
+
function studioPrefer(args) {
|
|
70
|
+
if (args.prisma && args.drizzle) throw new Error("pass only one of --prisma or --drizzle");
|
|
71
|
+
if (args.prisma) return "prisma";
|
|
72
|
+
if (args.drizzle) return "drizzle";
|
|
73
|
+
}
|
|
74
|
+
function writeLines(stream, lines) {
|
|
75
|
+
for (const line of lines) stream.write(`${line}\n`);
|
|
76
|
+
}
|
|
60
77
|
function runChild(command, env) {
|
|
61
78
|
const [file, ...args] = command;
|
|
62
79
|
if (!file) throw new Error(`run requires a command after -- (e.g. ${CLI_NAME} run --mode=dev -- yarn dev)`);
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
return runAttached(file, args, { env });
|
|
81
|
+
}
|
|
82
|
+
function cmdPrintUrl(args) {
|
|
83
|
+
const status = resolveDevStatus({
|
|
84
|
+
root: args.root,
|
|
85
|
+
mode: args.mode
|
|
86
|
+
});
|
|
87
|
+
if (!status.ok) {
|
|
88
|
+
writeLines(process.stderr, formatDevStatus(status));
|
|
89
|
+
return 2;
|
|
90
|
+
}
|
|
91
|
+
process.stdout.write(`${status.databaseUrl}\n`);
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
function cmdStatus(args) {
|
|
95
|
+
const status = resolveDevStatus({
|
|
96
|
+
root: args.root,
|
|
97
|
+
mode: args.mode
|
|
98
|
+
});
|
|
99
|
+
if (args.json) {
|
|
100
|
+
process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
|
|
101
|
+
return status.ok ? 0 : 2;
|
|
102
|
+
}
|
|
103
|
+
writeLines(process.stdout, formatDevStatus(status));
|
|
104
|
+
return status.ok ? 0 : 2;
|
|
105
|
+
}
|
|
106
|
+
async function cmdStudio(args) {
|
|
107
|
+
const prefer = studioPrefer(args);
|
|
108
|
+
const status = resolveDevStatus({
|
|
109
|
+
root: args.root,
|
|
110
|
+
mode: args.mode
|
|
111
|
+
});
|
|
112
|
+
if (!status.ok) {
|
|
113
|
+
writeLines(process.stderr, formatDevStatus(status));
|
|
114
|
+
return 2;
|
|
115
|
+
}
|
|
116
|
+
const studio = detectStudio({
|
|
117
|
+
root: status.root,
|
|
118
|
+
cwd: process.cwd(),
|
|
119
|
+
prefer
|
|
120
|
+
});
|
|
121
|
+
if (!studio) {
|
|
122
|
+
process.stderr.write(`${CLI_NAME}: no Prisma or Drizzle Studio found (install prisma or drizzle-kit)\n`);
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
process.stdout.write(`${CLI_NAME}: opening ${studio.kind} studio (${studio.command} ${studio.args.join(" ")})\n`);
|
|
126
|
+
return runStudio({
|
|
127
|
+
databaseUrl: status.databaseUrl,
|
|
128
|
+
studio
|
|
72
129
|
});
|
|
73
130
|
}
|
|
74
131
|
async function main() {
|
|
@@ -154,16 +211,9 @@ async function main() {
|
|
|
154
211
|
}
|
|
155
212
|
return 0;
|
|
156
213
|
}
|
|
157
|
-
if (args.cmd === "print-url")
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (!lease) {
|
|
161
|
-
process.stderr.write(`${CLI_NAME}: no ${mode} lease; run \`${CLI_NAME} acquire --mode=${mode}\` first\n`);
|
|
162
|
-
return 2;
|
|
163
|
-
}
|
|
164
|
-
process.stdout.write(`${urlFromLease(lease)}\n`);
|
|
165
|
-
return 0;
|
|
166
|
-
}
|
|
214
|
+
if (args.cmd === "print-url") return cmdPrintUrl(args);
|
|
215
|
+
if (args.cmd === "status") return cmdStatus(args);
|
|
216
|
+
if (args.cmd === "studio") return await cmdStudio(args);
|
|
167
217
|
process.stderr.write(`${CLI_NAME}: unknown command ${args.cmd}\n`);
|
|
168
218
|
printHelp();
|
|
169
219
|
return 64;
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { spawn } from \"node:child_process\";\nimport { CLI_NAME } from \"./core/constants.ts\";\nimport { acquire, dispose, gc, urlFromLease } from \"./core/lifecycle.ts\";\nimport { resolveWorktreeIdentity } from \"./core/worktree.ts\";\nimport { readLease } from \"./core/lease.ts\";\nimport type { DbMode } from \"./core/naming.ts\";\n\nfunction printHelp(): void {\n process.stdout.write(`${CLI_NAME}: worktree-isolated local Postgres (via autopg)\n\nUsage:\n ${CLI_NAME} acquire --mode=dev|test [--root <path>] [--force] [--json] [--print-env]\n ${CLI_NAME} run --mode=dev|test [--root <path>] [--force] -- <cmd…>\n ${CLI_NAME} dispose [--mode=dev|test] [--root <path>]\n ${CLI_NAME} gc [--json]\n ${CLI_NAME} print-url [--mode=dev|test] [--root <path>]\n ${CLI_NAME} --help\n\nModes:\n dev Keep DB across restarts (default when --mode omitted)\n test Drop DB on dispose / test teardown\n\nrun:\n Acquire, set DATABASE_URL (+ TEST_DATABASE_URL in test) on the child, exec <cmd…>.\n --force sets CEDAR_PG_FORCE (escape hatch); child env overwrite is always on.\n\nEnv:\n AUTOPG_BIN Path to autopg binary\n CEDAR_PG=0 Disable adapters that auto-acquire\n CEDAR_PG_FORCE=1 Ignore external-URL escape hatch (same as --force)\n`);\n}\n\nfunction parseMode(value: string | undefined): DbMode {\n if (value === \"dev\" || value === \"test\") return value;\n throw new Error(\"--mode must be dev or test\");\n}\n\ntype ParsedArgs = {\n cmd?: string;\n mode?: DbMode;\n root?: string;\n json?: boolean;\n printEnv?: boolean;\n force?: boolean;\n help?: boolean;\n child?: string[];\n};\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const out: ParsedArgs = {};\n const rest = [...argv];\n out.cmd = rest.shift();\n\n const dash = rest.indexOf(\"--\");\n let flagArgs = rest;\n if (dash >= 0) {\n flagArgs = rest.slice(0, dash);\n out.child = rest.slice(dash + 1);\n }\n\n for (let i = 0; i < flagArgs.length; i++) {\n const a = flagArgs[i]!;\n if (a === \"--help\" || a === \"-h\") out.help = true;\n else if (a === \"--json\") out.json = true;\n else if (a === \"--print-env\") out.printEnv = true;\n else if (a === \"--force\") out.force = true;\n else if (a.startsWith(\"--mode=\")) out.mode = parseMode(a.slice(7));\n else if (a === \"--mode\") out.mode = parseMode(flagArgs[++i]);\n else if (a.startsWith(\"--root=\")) out.root = a.slice(7);\n else if (a === \"--root\") out.root = flagArgs[++i];\n else throw new Error(`unknown argument: ${a}`);\n }\n return out;\n}\n\nfunction runChild(command: string[], env: NodeJS.ProcessEnv): Promise<number> {\n const [file, ...args] = command;\n if (!file) {\n throw new Error(\n `run requires a command after -- (e.g. ${CLI_NAME} run --mode=dev -- yarn dev)`,\n );\n }\n return new Promise((resolve, reject) => {\n const child = spawn(file, args, { stdio: \"inherit\", env });\n child.on(\"error\", reject);\n child.on(\"exit\", (code, signal) => {\n resolve(signal ? 1 : (code ?? 1));\n });\n });\n}\n\nasync function main(): Promise<number> {\n const argv = process.argv.slice(2);\n if (argv.length === 0 || argv[0] === \"help\" || argv[0] === \"--help\" || argv[0] === \"-h\") {\n printHelp();\n return 0;\n }\n const args = parseArgs(argv);\n if (args.help) {\n printHelp();\n return 0;\n }\n\n try {\n if (args.cmd === \"acquire\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n if (args.printEnv) {\n process.stdout.write(`DATABASE_URL=${result.databaseUrl}\\n`);\n if (mode === \"test\") {\n process.stdout.write(`TEST_DATABASE_URL=${result.databaseUrl}\\n`);\n }\n }\n if (args.json) {\n process.stdout.write(\n `${JSON.stringify(\n {\n databaseUrl: result.databaseUrl,\n adminUrl: result.adminUrl,\n databaseName: result.databaseName,\n roleName: result.roleName,\n repoSlug: result.repoSlug,\n worktreeSlug: result.worktreeSlug,\n pathHash: result.pathHash,\n mode: result.mode,\n port: result.port,\n root: result.root,\n },\n null,\n 2,\n )}\\n`,\n );\n } else if (!args.printEnv) {\n process.stdout.write(\n `${CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\\n`,\n );\n process.stdout.write(`${result.databaseUrl}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"run\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n const childEnv: NodeJS.ProcessEnv = {\n ...process.env,\n DATABASE_URL: result.databaseUrl,\n };\n if (mode === \"test\") childEnv.TEST_DATABASE_URL = result.databaseUrl;\n return await runChild(args.child ?? [], childEnv);\n }\n\n if (args.cmd === \"dispose\") {\n const mode = args.mode ?? \"test\";\n const result = await dispose({ root: args.root, mode });\n if (result.dropped) {\n process.stdout.write(`${CLI_NAME}: disposed ${mode} (${result.databaseName})\\n`);\n return 0;\n }\n if (result.reason === \"no-lease\") {\n process.stdout.write(`${CLI_NAME}: nothing to dispose for ${mode} (no lease)\\n`);\n return 0;\n }\n process.stderr.write(\n `${CLI_NAME}: could not dispose ${mode}: autopg host unavailable (lease kept for retry)\\n`,\n );\n return 1;\n }\n\n if (args.cmd === \"gc\") {\n const result = await gc();\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n } else {\n process.stdout.write(`${CLI_NAME} gc: dropped ${result.dropped.length} database(s)\\n`);\n for (const name of result.dropped) process.stdout.write(` ${name}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"print-url\") {\n const mode = args.mode ?? \"dev\";\n const identity = resolveWorktreeIdentity(args.root);\n const lease = readLease(identity.root, mode);\n if (!lease) {\n process.stderr.write(\n `${CLI_NAME}: no ${mode} lease; run \\`${CLI_NAME} acquire --mode=${mode}\\` first\\n`,\n );\n return 2;\n }\n process.stdout.write(`${urlFromLease(lease)}\\n`);\n return 0;\n }\n\n process.stderr.write(`${CLI_NAME}: unknown command ${args.cmd}\\n`);\n printHelp();\n return 64;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n return 1;\n }\n}\n\nmain()\n .then((code) => {\n process.exit(code);\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n process.exit(1);\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { CLI_NAME } from \"./core/constants.ts\";\nimport { acquire, dispose, gc } from \"./core/lifecycle.ts\";\nimport { resolveDevStatus } from \"./core/status.ts\";\nimport type { DbMode } from \"./core/naming.ts\";\nimport { runAttached } from \"./adapters/child.ts\";\nimport { formatDevStatus } from \"./adapters/status-format.ts\";\nimport { detectStudio, runStudio, type StudioKind } from \"./adapters/studio.ts\";\n\nfunction printHelp(): void {\n process.stdout.write(`${CLI_NAME}: worktree-isolated local Postgres (via autopg)\n\nUsage:\n ${CLI_NAME} acquire --mode=dev|test [--root <path>] [--force] [--json] [--print-env]\n ${CLI_NAME} run --mode=dev|test [--root <path>] [--force] -- <cmd…>\n ${CLI_NAME} dispose [--mode=dev|test] [--root <path>]\n ${CLI_NAME} gc [--json]\n ${CLI_NAME} print-url [--mode=dev|test] [--root <path>]\n ${CLI_NAME} status [--mode=dev|test] [--root <path>] [--json]\n ${CLI_NAME} studio [--mode=dev|test] [--root <path>] [--prisma|--drizzle]\n ${CLI_NAME} --help\n\nModes:\n dev Keep DB across restarts (default when --mode omitted)\n test Drop DB on dispose / test teardown\n\nrun:\n Acquire, set DATABASE_URL (+ TEST_DATABASE_URL in test) on the child, exec <cmd…>.\n --force sets CEDAR_PG_FORCE (escape hatch); child env overwrite is always on.\n\nstatus / studio:\n Read-only lease inspection (no acquire). studio runs Prisma or Drizzle Kit Studio\n attached (stdio + exit code) with DATABASE_URL from the lease. Detects from cwd\n up to the worktree (auto; --prisma / --drizzle to force).\n\nEnv:\n AUTOPG_BIN Path to autopg binary\n CEDAR_PG=0 Disable adapters that auto-acquire\n CEDAR_PG_FORCE=1 Ignore external-URL escape hatch (same as --force)\n`);\n}\n\nfunction parseMode(value: string | undefined): DbMode {\n if (value === \"dev\" || value === \"test\") return value;\n throw new Error(\"--mode must be dev or test\");\n}\n\ntype ParsedArgs = {\n cmd?: string;\n mode?: DbMode;\n root?: string;\n json?: boolean;\n printEnv?: boolean;\n force?: boolean;\n help?: boolean;\n prisma?: boolean;\n drizzle?: boolean;\n child?: string[];\n};\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const out: ParsedArgs = {};\n const rest = [...argv];\n out.cmd = rest.shift();\n\n const dash = rest.indexOf(\"--\");\n let flagArgs = rest;\n if (dash >= 0) {\n flagArgs = rest.slice(0, dash);\n out.child = rest.slice(dash + 1);\n }\n\n for (let i = 0; i < flagArgs.length; i++) {\n const a = flagArgs[i]!;\n if (a === \"--help\" || a === \"-h\") out.help = true;\n else if (a === \"--json\") out.json = true;\n else if (a === \"--print-env\") out.printEnv = true;\n else if (a === \"--force\") out.force = true;\n else if (a === \"--prisma\") out.prisma = true;\n else if (a === \"--drizzle\") out.drizzle = true;\n else if (a.startsWith(\"--mode=\")) out.mode = parseMode(a.slice(7));\n else if (a === \"--mode\") out.mode = parseMode(flagArgs[++i]);\n else if (a.startsWith(\"--root=\")) out.root = a.slice(7);\n else if (a === \"--root\") out.root = flagArgs[++i];\n else throw new Error(`unknown argument: ${a}`);\n }\n return out;\n}\n\nfunction studioPrefer(args: ParsedArgs): StudioKind | undefined {\n if (args.prisma && args.drizzle) {\n throw new Error(\"pass only one of --prisma or --drizzle\");\n }\n if (args.prisma) return \"prisma\";\n if (args.drizzle) return \"drizzle\";\n return undefined;\n}\n\nfunction writeLines(stream: NodeJS.WriteStream, lines: string[]): void {\n for (const line of lines) stream.write(`${line}\\n`);\n}\n\nfunction runChild(command: string[], env: NodeJS.ProcessEnv): Promise<number> {\n const [file, ...args] = command;\n if (!file) {\n throw new Error(\n `run requires a command after -- (e.g. ${CLI_NAME} run --mode=dev -- yarn dev)`,\n );\n }\n return runAttached(file, args, { env });\n}\n\nfunction cmdPrintUrl(args: ParsedArgs): number {\n const status = resolveDevStatus({ root: args.root, mode: args.mode });\n if (!status.ok) {\n writeLines(process.stderr, formatDevStatus(status));\n return 2;\n }\n process.stdout.write(`${status.databaseUrl}\\n`);\n return 0;\n}\n\nfunction cmdStatus(args: ParsedArgs): number {\n const status = resolveDevStatus({ root: args.root, mode: args.mode });\n if (args.json) {\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return status.ok ? 0 : 2;\n }\n writeLines(process.stdout, formatDevStatus(status));\n return status.ok ? 0 : 2;\n}\n\nasync function cmdStudio(args: ParsedArgs): Promise<number> {\n const prefer = studioPrefer(args);\n const status = resolveDevStatus({ root: args.root, mode: args.mode });\n if (!status.ok) {\n writeLines(process.stderr, formatDevStatus(status));\n return 2;\n }\n const studio = detectStudio({ root: status.root, cwd: process.cwd(), prefer });\n if (!studio) {\n process.stderr.write(\n `${CLI_NAME}: no Prisma or Drizzle Studio found (install prisma or drizzle-kit)\\n`,\n );\n return 1;\n }\n process.stdout.write(\n `${CLI_NAME}: opening ${studio.kind} studio (${studio.command} ${studio.args.join(\" \")})\\n`,\n );\n return runStudio({ databaseUrl: status.databaseUrl, studio });\n}\n\nasync function main(): Promise<number> {\n const argv = process.argv.slice(2);\n if (argv.length === 0 || argv[0] === \"help\" || argv[0] === \"--help\" || argv[0] === \"-h\") {\n printHelp();\n return 0;\n }\n const args = parseArgs(argv);\n if (args.help) {\n printHelp();\n return 0;\n }\n\n try {\n if (args.cmd === \"acquire\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n if (args.printEnv) {\n process.stdout.write(`DATABASE_URL=${result.databaseUrl}\\n`);\n if (mode === \"test\") {\n process.stdout.write(`TEST_DATABASE_URL=${result.databaseUrl}\\n`);\n }\n }\n if (args.json) {\n process.stdout.write(\n `${JSON.stringify(\n {\n databaseUrl: result.databaseUrl,\n adminUrl: result.adminUrl,\n databaseName: result.databaseName,\n roleName: result.roleName,\n repoSlug: result.repoSlug,\n worktreeSlug: result.worktreeSlug,\n pathHash: result.pathHash,\n mode: result.mode,\n port: result.port,\n root: result.root,\n },\n null,\n 2,\n )}\\n`,\n );\n } else if (!args.printEnv) {\n process.stdout.write(\n `${CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\\n`,\n );\n process.stdout.write(`${result.databaseUrl}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"run\") {\n if (args.force) process.env.CEDAR_PG_FORCE = \"1\";\n const mode = args.mode ?? \"dev\";\n const result = await acquire({\n root: args.root,\n mode,\n setEnv: true,\n });\n const childEnv: NodeJS.ProcessEnv = {\n ...process.env,\n DATABASE_URL: result.databaseUrl,\n };\n if (mode === \"test\") childEnv.TEST_DATABASE_URL = result.databaseUrl;\n return await runChild(args.child ?? [], childEnv);\n }\n\n if (args.cmd === \"dispose\") {\n const mode = args.mode ?? \"test\";\n const result = await dispose({ root: args.root, mode });\n if (result.dropped) {\n process.stdout.write(`${CLI_NAME}: disposed ${mode} (${result.databaseName})\\n`);\n return 0;\n }\n if (result.reason === \"no-lease\") {\n process.stdout.write(`${CLI_NAME}: nothing to dispose for ${mode} (no lease)\\n`);\n return 0;\n }\n process.stderr.write(\n `${CLI_NAME}: could not dispose ${mode}: autopg host unavailable (lease kept for retry)\\n`,\n );\n return 1;\n }\n\n if (args.cmd === \"gc\") {\n const result = await gc();\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n } else {\n process.stdout.write(`${CLI_NAME} gc: dropped ${result.dropped.length} database(s)\\n`);\n for (const name of result.dropped) process.stdout.write(` ${name}\\n`);\n }\n return 0;\n }\n\n if (args.cmd === \"print-url\") {\n return cmdPrintUrl(args);\n }\n\n if (args.cmd === \"status\") {\n return cmdStatus(args);\n }\n\n if (args.cmd === \"studio\") {\n return await cmdStudio(args);\n }\n\n process.stderr.write(`${CLI_NAME}: unknown command ${args.cmd}\\n`);\n printHelp();\n return 64;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n return 1;\n }\n}\n\nmain()\n .then((code) => {\n process.exit(code);\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`${CLI_NAME}: ${message}\\n`);\n process.exit(1);\n });\n"],"mappings":"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"}
|
package/dist/dev-env.cjs
CHANGED
package/dist/dev-env.mjs
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_lifecycle = require("./lifecycle-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
2
|
+
const require_lifecycle = require("./lifecycle-BbrvFQvg.cjs");
|
|
3
|
+
const require_lease = require("./lease-WlmOnNDi.cjs");
|
|
4
|
+
const require_template = require("./template-CXMpODzK.cjs");
|
|
5
|
+
const require_load_test_env = require("./load-test-env-Dcgh6YHV.cjs");
|
|
6
|
+
const require_load_dev_env = require("./load-dev-env-Bl6Ddv1U.cjs");
|
|
7
|
+
const require_status = require("./status-4Uz6A3LB.cjs");
|
|
8
8
|
//#region src/adapters/acquire-task.ts
|
|
9
9
|
/** Run acquireIfNeeded, then optional afterAcquire (migrate / db:ready). */
|
|
10
10
|
function createAcquireTask(options) {
|
|
@@ -28,10 +28,10 @@ function createAcquireTask(options) {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
|
-
exports.CLI_NAME =
|
|
31
|
+
exports.CLI_NAME = require_lease.CLI_NAME;
|
|
32
32
|
exports.INSTALL_HINT = require_lifecycle.INSTALL_HINT;
|
|
33
33
|
exports.ROLE_PASSWORD_SCHEME = require_lifecycle.ROLE_PASSWORD_SCHEME;
|
|
34
|
-
exports.STATE_DIRNAME =
|
|
34
|
+
exports.STATE_DIRNAME = require_lease.STATE_DIRNAME;
|
|
35
35
|
exports.acquire = require_lifecycle.acquire;
|
|
36
36
|
exports.acquireIfNeeded = require_lifecycle.acquireIfNeeded;
|
|
37
37
|
exports.applyDatabaseUrlEnv = require_lifecycle.applyDatabaseUrlEnv;
|
|
@@ -58,6 +58,7 @@ exports.readLease = require_lease.readLease;
|
|
|
58
58
|
exports.requireAutopgBin = require_lifecycle.requireAutopgBin;
|
|
59
59
|
exports.resolveAcquireSkip = require_lifecycle.resolveAcquireSkip;
|
|
60
60
|
exports.resolveAutopgBin = require_lifecycle.resolveAutopgBin;
|
|
61
|
+
exports.resolveDevStatus = require_status.resolveDevStatus;
|
|
61
62
|
exports.resolveRoot = require_lease.resolveRoot;
|
|
62
63
|
exports.resolveWorktreeIdentity = require_lease.resolveWorktreeIdentity;
|
|
63
64
|
exports.rolePasswordFor = require_lifecycle.rolePasswordFor;
|
package/dist/index.d.cts
CHANGED
|
@@ -247,6 +247,26 @@ type CreateAcquireTaskOptions = {
|
|
|
247
247
|
/** Run acquireIfNeeded, then optional afterAcquire (migrate / db:ready). */
|
|
248
248
|
declare function createAcquireTask(options: CreateAcquireTaskOptions): () => Promise<void>;
|
|
249
249
|
//#endregion
|
|
250
|
+
//#region src/core/status.d.ts
|
|
251
|
+
type ResolveDevStatusOptions = {
|
|
252
|
+
root?: string;
|
|
253
|
+
mode?: DbMode;
|
|
254
|
+
};
|
|
255
|
+
type DevStatus = {
|
|
256
|
+
ok: true;
|
|
257
|
+
mode: DbMode;
|
|
258
|
+
root: string;
|
|
259
|
+
lease: Lease;
|
|
260
|
+
databaseUrl: string;
|
|
261
|
+
envPath: string;
|
|
262
|
+
} | {
|
|
263
|
+
ok: false;
|
|
264
|
+
mode: DbMode;
|
|
265
|
+
root: string;
|
|
266
|
+
};
|
|
267
|
+
/** Read-only lease snapshot for CLI / Vite panel (no acquire, no host). */
|
|
268
|
+
declare function resolveDevStatus(options?: ResolveDevStatusOptions): DevStatus;
|
|
269
|
+
//#endregion
|
|
250
270
|
//#region src/providers/autopg.d.ts
|
|
251
271
|
type AutopgDiscovery = {
|
|
252
272
|
port: number;
|
|
@@ -259,13 +279,21 @@ declare const ROLE_PASSWORD_SCHEME: "v2";
|
|
|
259
279
|
declare function resolveAutopgBin(): string | null;
|
|
260
280
|
declare function requireAutopgBin(): string;
|
|
261
281
|
/**
|
|
262
|
-
* Parse `autopg status --json`
|
|
282
|
+
* Parse `autopg status --json` → the **registered** port. Throws only when the
|
|
283
|
+
* output is not autopg status JSON.
|
|
284
|
+
*
|
|
285
|
+
* Registration is not liveness: autopg reports a port for a stopped host too,
|
|
286
|
+
* and its `status` string is supervisor-specific (pm2 `online`, systemd-user /
|
|
287
|
+
* launchd differ). Liveness is a TCP accept on the port, proven by the caller —
|
|
288
|
+
* `acquire` does that before it connects.
|
|
263
289
|
*/
|
|
264
290
|
declare function parseHostStatus(json: string): {
|
|
265
291
|
port: number;
|
|
266
292
|
};
|
|
267
293
|
/**
|
|
268
|
-
* Discover
|
|
294
|
+
* Discover the registered autopg host (port + admin URL) via `autopg status --json`.
|
|
295
|
+
* Throws when autopg cannot be queried; does **not** prove a listener — probe TCP
|
|
296
|
+
* (or use `acquire`, which does) before connecting.
|
|
269
297
|
*/
|
|
270
298
|
declare function discoverHost(bin?: string): AutopgDiscovery;
|
|
271
299
|
/**
|
|
@@ -283,5 +311,5 @@ declare function buildDatabaseUrl(opts: {
|
|
|
283
311
|
password?: string;
|
|
284
312
|
}): string;
|
|
285
313
|
//#endregion
|
|
286
|
-
export { type AcquireIfNeededOptions, type AcquireIfNeededResult, type AcquireOptions, type AcquireResult, type AcquireSkip, type AcquireTaskContext, type AutopgDiscovery, CLI_NAME, type CloneFromTemplateIfNeededOptions, type CloneFromTemplateIfNeededResult, type CloneFromTemplateOptions, type CloneResult, type CreateAcquireTaskOptions, type DbMode, type DisposeOptions, type DisposeResult, INSTALL_HINT, type Lease, type LoadDevEnvOptions, type LoadTestEnvOptions, type MarkTemplateOptions, ROLE_PASSWORD_SCHEME, type ResolveAcquireSkipInput, STATE_DIRNAME, type WorktreeIdentity, acquire, acquireIfNeeded, applyDatabaseUrlEnv, buildCloneDatabaseName, buildDatabaseName, buildDatabaseUrl, buildRoleName, cloneFromTemplate, cloneFromTemplateIfNeeded, createAcquireTask, discoverHost, dispose, envFilePath, gc, isCedarPgManagedUrl, isExternalDatabaseEscapeHatch, isOrphanLease, loadDevEnv, loadTestEnv, markTemplate, parseHostStatus, parseLease, readLease, requireAutopgBin, resolveAcquireSkip, resolveAutopgBin, resolveRoot, resolveWorktreeIdentity, rolePasswordFor, urlFromLease };
|
|
314
|
+
export { type AcquireIfNeededOptions, type AcquireIfNeededResult, type AcquireOptions, type AcquireResult, type AcquireSkip, type AcquireTaskContext, type AutopgDiscovery, CLI_NAME, type CloneFromTemplateIfNeededOptions, type CloneFromTemplateIfNeededResult, type CloneFromTemplateOptions, type CloneResult, type CreateAcquireTaskOptions, type DbMode, type DevStatus, type DisposeOptions, type DisposeResult, INSTALL_HINT, type Lease, type LoadDevEnvOptions, type LoadTestEnvOptions, type MarkTemplateOptions, ROLE_PASSWORD_SCHEME, type ResolveAcquireSkipInput, type ResolveDevStatusOptions, STATE_DIRNAME, type WorktreeIdentity, acquire, acquireIfNeeded, applyDatabaseUrlEnv, buildCloneDatabaseName, buildDatabaseName, buildDatabaseUrl, buildRoleName, cloneFromTemplate, cloneFromTemplateIfNeeded, createAcquireTask, discoverHost, dispose, envFilePath, gc, isCedarPgManagedUrl, isExternalDatabaseEscapeHatch, isOrphanLease, loadDevEnv, loadTestEnv, markTemplate, parseHostStatus, parseLease, readLease, requireAutopgBin, resolveAcquireSkip, resolveAutopgBin, resolveDevStatus, resolveRoot, resolveWorktreeIdentity, rolePasswordFor, urlFromLease };
|
|
287
315
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -247,6 +247,26 @@ type CreateAcquireTaskOptions = {
|
|
|
247
247
|
/** Run acquireIfNeeded, then optional afterAcquire (migrate / db:ready). */
|
|
248
248
|
declare function createAcquireTask(options: CreateAcquireTaskOptions): () => Promise<void>;
|
|
249
249
|
//#endregion
|
|
250
|
+
//#region src/core/status.d.ts
|
|
251
|
+
type ResolveDevStatusOptions = {
|
|
252
|
+
root?: string;
|
|
253
|
+
mode?: DbMode;
|
|
254
|
+
};
|
|
255
|
+
type DevStatus = {
|
|
256
|
+
ok: true;
|
|
257
|
+
mode: DbMode;
|
|
258
|
+
root: string;
|
|
259
|
+
lease: Lease;
|
|
260
|
+
databaseUrl: string;
|
|
261
|
+
envPath: string;
|
|
262
|
+
} | {
|
|
263
|
+
ok: false;
|
|
264
|
+
mode: DbMode;
|
|
265
|
+
root: string;
|
|
266
|
+
};
|
|
267
|
+
/** Read-only lease snapshot for CLI / Vite panel (no acquire, no host). */
|
|
268
|
+
declare function resolveDevStatus(options?: ResolveDevStatusOptions): DevStatus;
|
|
269
|
+
//#endregion
|
|
250
270
|
//#region src/providers/autopg.d.ts
|
|
251
271
|
type AutopgDiscovery = {
|
|
252
272
|
port: number;
|
|
@@ -259,13 +279,21 @@ declare const ROLE_PASSWORD_SCHEME: "v2";
|
|
|
259
279
|
declare function resolveAutopgBin(): string | null;
|
|
260
280
|
declare function requireAutopgBin(): string;
|
|
261
281
|
/**
|
|
262
|
-
* Parse `autopg status --json`
|
|
282
|
+
* Parse `autopg status --json` → the **registered** port. Throws only when the
|
|
283
|
+
* output is not autopg status JSON.
|
|
284
|
+
*
|
|
285
|
+
* Registration is not liveness: autopg reports a port for a stopped host too,
|
|
286
|
+
* and its `status` string is supervisor-specific (pm2 `online`, systemd-user /
|
|
287
|
+
* launchd differ). Liveness is a TCP accept on the port, proven by the caller —
|
|
288
|
+
* `acquire` does that before it connects.
|
|
263
289
|
*/
|
|
264
290
|
declare function parseHostStatus(json: string): {
|
|
265
291
|
port: number;
|
|
266
292
|
};
|
|
267
293
|
/**
|
|
268
|
-
* Discover
|
|
294
|
+
* Discover the registered autopg host (port + admin URL) via `autopg status --json`.
|
|
295
|
+
* Throws when autopg cannot be queried; does **not** prove a listener — probe TCP
|
|
296
|
+
* (or use `acquire`, which does) before connecting.
|
|
269
297
|
*/
|
|
270
298
|
declare function discoverHost(bin?: string): AutopgDiscovery;
|
|
271
299
|
/**
|
|
@@ -283,5 +311,5 @@ declare function buildDatabaseUrl(opts: {
|
|
|
283
311
|
password?: string;
|
|
284
312
|
}): string;
|
|
285
313
|
//#endregion
|
|
286
|
-
export { type AcquireIfNeededOptions, type AcquireIfNeededResult, type AcquireOptions, type AcquireResult, type AcquireSkip, type AcquireTaskContext, type AutopgDiscovery, CLI_NAME, type CloneFromTemplateIfNeededOptions, type CloneFromTemplateIfNeededResult, type CloneFromTemplateOptions, type CloneResult, type CreateAcquireTaskOptions, type DbMode, type DisposeOptions, type DisposeResult, INSTALL_HINT, type Lease, type LoadDevEnvOptions, type LoadTestEnvOptions, type MarkTemplateOptions, ROLE_PASSWORD_SCHEME, type ResolveAcquireSkipInput, STATE_DIRNAME, type WorktreeIdentity, acquire, acquireIfNeeded, applyDatabaseUrlEnv, buildCloneDatabaseName, buildDatabaseName, buildDatabaseUrl, buildRoleName, cloneFromTemplate, cloneFromTemplateIfNeeded, createAcquireTask, discoverHost, dispose, envFilePath, gc, isCedarPgManagedUrl, isExternalDatabaseEscapeHatch, isOrphanLease, loadDevEnv, loadTestEnv, markTemplate, parseHostStatus, parseLease, readLease, requireAutopgBin, resolveAcquireSkip, resolveAutopgBin, resolveRoot, resolveWorktreeIdentity, rolePasswordFor, urlFromLease };
|
|
314
|
+
export { type AcquireIfNeededOptions, type AcquireIfNeededResult, type AcquireOptions, type AcquireResult, type AcquireSkip, type AcquireTaskContext, type AutopgDiscovery, CLI_NAME, type CloneFromTemplateIfNeededOptions, type CloneFromTemplateIfNeededResult, type CloneFromTemplateOptions, type CloneResult, type CreateAcquireTaskOptions, type DbMode, type DevStatus, type DisposeOptions, type DisposeResult, INSTALL_HINT, type Lease, type LoadDevEnvOptions, type LoadTestEnvOptions, type MarkTemplateOptions, ROLE_PASSWORD_SCHEME, type ResolveAcquireSkipInput, type ResolveDevStatusOptions, STATE_DIRNAME, type WorktreeIdentity, acquire, acquireIfNeeded, applyDatabaseUrlEnv, buildCloneDatabaseName, buildDatabaseName, buildDatabaseUrl, buildRoleName, cloneFromTemplate, cloneFromTemplateIfNeeded, createAcquireTask, discoverHost, dispose, envFilePath, gc, isCedarPgManagedUrl, isExternalDatabaseEscapeHatch, isOrphanLease, loadDevEnv, loadTestEnv, markTemplate, parseHostStatus, parseLease, readLease, requireAutopgBin, resolveAcquireSkip, resolveAutopgBin, resolveDevStatus, resolveRoot, resolveWorktreeIdentity, rolePasswordFor, urlFromLease };
|
|
287
315
|
//# sourceMappingURL=index.d.mts.map
|