@cedarjs/pg 0.1.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/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/cli.cjs +139 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +140 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/constants-B7sCf4fg.cjs +41 -0
- package/dist/constants-B7sCf4fg.cjs.map +1 -0
- package/dist/constants-YnHDwShD.mjs +24 -0
- package/dist/constants-YnHDwShD.mjs.map +1 -0
- package/dist/index.cjs +26 -0
- package/dist/index.d.cts +201 -0
- package/dist/index.d.mts +201 -0
- package/dist/index.mjs +2 -0
- package/dist/jest.cjs +28 -0
- package/dist/jest.cjs.map +1 -0
- package/dist/jest.d.cts +14 -0
- package/dist/jest.d.mts +14 -0
- package/dist/jest.mjs +23 -0
- package/dist/jest.mjs.map +1 -0
- package/dist/lifecycle-D10usEjM.cjs +743 -0
- package/dist/lifecycle-D10usEjM.cjs.map +1 -0
- package/dist/lifecycle-PbTXNC2Z.mjs +577 -0
- package/dist/lifecycle-PbTXNC2Z.mjs.map +1 -0
- package/dist/nx.cjs +35 -0
- package/dist/nx.cjs.map +1 -0
- package/dist/nx.d.cts +26 -0
- package/dist/nx.d.mts +26 -0
- package/dist/nx.mjs +34 -0
- package/dist/nx.mjs.map +1 -0
- package/dist/tasks-CW2D0n46.mjs +16 -0
- package/dist/tasks-CW2D0n46.mjs.map +1 -0
- package/dist/tasks-DZ7hMmGJ.cjs +21 -0
- package/dist/tasks-DZ7hMmGJ.cjs.map +1 -0
- package/dist/vite-plus.cjs +65 -0
- package/dist/vite-plus.cjs.map +1 -0
- package/dist/vite-plus.d.cts +51 -0
- package/dist/vite-plus.d.mts +51 -0
- package/dist/vite-plus.mjs +61 -0
- package/dist/vite-plus.mjs.map +1 -0
- package/dist/vitest.cjs +33 -0
- package/dist/vitest.cjs.map +1 -0
- package/dist/vitest.d.cts +17 -0
- package/dist/vitest.d.mts +17 -0
- package/dist/vitest.mjs +28 -0
- package/dist/vitest.mjs.map +1 -0
- package/package.json +96 -0
- package/scripts/postinstall.js +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Simon Crypta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# cedar-pg
|
|
2
|
+
|
|
3
|
+
Worktree-isolated local Postgres for **Vite+**, **Nx**, and **CedarJS** — powered by [autopg](https://github.com/automagik-dev/autopg).
|
|
4
|
+
|
|
5
|
+
Published on npm as **`@cedarjs/pg`**.
|
|
6
|
+
|
|
7
|
+
> **Alpha** (`0.1.0-alpha.0`): APIs may change. Install with the `alpha` dist-tag.
|
|
8
|
+
|
|
9
|
+
## What you get (via autopg)
|
|
10
|
+
|
|
11
|
+
Under the hood you get an **embedded PostgreSQL server with true concurrent connections** — native PostgreSQL 18 (not WASM), real process forking, no connection locks. It just works: **no credentials needed**, **zero config**, and **auto-provisioned databases** on first use. Any client works (`psql`, `node-postgres`, Prisma, Drizzle, TypeORM).
|
|
12
|
+
|
|
13
|
+
### Development & testing
|
|
14
|
+
|
|
15
|
+
| Use case | What you get |
|
|
16
|
+
| ----------------------- | ------------------------------------------ |
|
|
17
|
+
| **Local development** | PostgreSQL without Docker |
|
|
18
|
+
| **Integration testing** | Real PostgreSQL, not mocks |
|
|
19
|
+
| **CI/CD pipelines** | Fresh databases per test run |
|
|
20
|
+
| **E2E testing** | Isolated database for Playwright / Cypress |
|
|
21
|
+
|
|
22
|
+
## What cedar-pg adds
|
|
23
|
+
|
|
24
|
+
**cedar-pg** sits on that autopg host and gives each **git worktree** its own database + role, with readable names, leases, and teardown — so parallel checkouts don’t fight over one shared DB:
|
|
25
|
+
|
|
26
|
+
- **1 database per git worktree** (visible in `\l` as `cpg_…`)
|
|
27
|
+
- **dev** DBs persist across restarts; **test** DBs drop on dispose
|
|
28
|
+
- First-class **Vite+ Task** + **Nx** / Vitest / Jest adapters
|
|
29
|
+
- `postinstall` ensures the pinned `autopg` binary when missing
|
|
30
|
+
|
|
31
|
+
| Layer | Responsibility |
|
|
32
|
+
| ------------ | ------------------------------------------------------------------- |
|
|
33
|
+
| **autopg** | Embedded Postgres host — concurrent, zero-config, auto-provision |
|
|
34
|
+
| **cedar-pg** | Per-worktree `CREATE DATABASE` / role, `DATABASE_URL`, dispose + GC |
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -D @cedarjs/pg@alpha
|
|
40
|
+
# or: pnpm add -D @cedarjs/pg@alpha
|
|
41
|
+
# or: yarn add -D @cedarjs/pg@alpha
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Database names (observability)
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
cpg_<repo>_<worktree>_<mode>_<pathHash8>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
|
|
52
|
+
| Name | Meaning |
|
|
53
|
+
| ----------------------------------- | -------------------------- |
|
|
54
|
+
| `cpg_cedar_cedar_dev_a1b2c3d4` | main `cedar` checkout, dev |
|
|
55
|
+
| `cpg_cedar_feat_auth_test_e5f67890` | worktree `feat-auth`, test |
|
|
56
|
+
|
|
57
|
+
## Prerequisites
|
|
58
|
+
|
|
59
|
+
A running [autopg](https://github.com/automagik-dev/autopg) host (installed automatically by `postinstall`, or manually).
|
|
60
|
+
Both the install script and binary are pinned to a release tag (currently `v3.0.7`); bump the pin in `scripts/postinstall.js` to upgrade:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -fsSL https://raw.githubusercontent.com/automagik-dev/autopg/v3.0.7/install.sh \
|
|
64
|
+
| AUTOPG_VERSION=v3.0.7 bash
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Typical flow: `autopg daemon` (or your usual host install) once per machine → `cedarpg ensure` per worktree → connect with the printed `DATABASE_URL`.
|
|
68
|
+
|
|
69
|
+
## Develop this package (Vite+)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
vp install
|
|
73
|
+
vp check
|
|
74
|
+
vp test
|
|
75
|
+
vp pack # → dist/ (dts + esm + cjs)
|
|
76
|
+
vp run smoke # build → npm-pack tarball → install + resolve exports
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Local consume (without npm)
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# in this repo
|
|
83
|
+
vp pack
|
|
84
|
+
|
|
85
|
+
# in your app / Cedar
|
|
86
|
+
yarn add @cedarjs/pg@file:../cedar-pg
|
|
87
|
+
# or: pnpm pack && yarn add ./cedarjs-pg-0.1.0-alpha.0.tgz
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## CLI
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
cedarpg ensure --mode=dev
|
|
94
|
+
cedarpg ensure --mode=test --print-env
|
|
95
|
+
cedarpg dispose --mode=test
|
|
96
|
+
cedarpg print-url --mode=dev
|
|
97
|
+
cedarpg gc # drop DBs whose worktree root is gone (uses ~/.cedarpg/registry)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Vite+ consumer adapter
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// vite.config.ts
|
|
104
|
+
import { defineConfig } from "vite-plus";
|
|
105
|
+
import { cedarPgTasks } from "@cedarjs/pg/vite-plus";
|
|
106
|
+
|
|
107
|
+
export default defineConfig({
|
|
108
|
+
run: {
|
|
109
|
+
tasks: {
|
|
110
|
+
...cedarPgTasks(),
|
|
111
|
+
test: {
|
|
112
|
+
command: "vp test",
|
|
113
|
+
dependsOn: ["db:ensure-test"],
|
|
114
|
+
env: ["DATABASE_URL", "TEST_DATABASE_URL"],
|
|
115
|
+
},
|
|
116
|
+
dev: {
|
|
117
|
+
command: "vp dev",
|
|
118
|
+
dependsOn: ["db:ensure"],
|
|
119
|
+
env: ["DATABASE_URL"],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Programmatic API
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { ensure, dispose } from "@cedarjs/pg";
|
|
130
|
+
|
|
131
|
+
const { databaseUrl, databaseName, dispose: drop } = await ensure({ mode: "test" });
|
|
132
|
+
// … tests …
|
|
133
|
+
await drop();
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Env
|
|
137
|
+
|
|
138
|
+
| Var | Meaning |
|
|
139
|
+
| ----------------------------- | ------------------------------------------------------------------- |
|
|
140
|
+
| `AUTOPG_BIN` | Path to autopg |
|
|
141
|
+
| `CEDAR_PG=0` | Disable auto-ensure in adapters |
|
|
142
|
+
| `TEST_DATABASE_URL` | Escape hatch — skip ensure for external DBs (not `cpg_*` / `file:`) |
|
|
143
|
+
| `CEDAR_PG_FORCE=1` | Ignore external-URL escape hatch |
|
|
144
|
+
| `CEDAR_PG_REGISTRY_DIR` | Override global lease registry (for `gc`) |
|
|
145
|
+
| `CEDAR_PG_SKIP_POSTINSTALL=1` | Skip autopg install hook |
|
|
146
|
+
| `CEDAR_PG_INSTALL_AUTOPG=1` | Force autopg install in CI |
|
|
147
|
+
|
|
148
|
+
## Alpha caveats
|
|
149
|
+
|
|
150
|
+
- Public API may change before `0.1.0`.
|
|
151
|
+
- End-to-end Postgres flows assume a working local `autopg` host; CI unit tests do not start Postgres.
|
|
152
|
+
- State lives in product-owned `.cedarpg` (worktree + `~/.cedarpg/registry`) — not under autopg's `~/.autopg/`, not a generic `.pg`.
|
|
153
|
+
- Password salt (`cedar-pg\\0`, scheme v1) is an opaque crypto constant; bump the scheme id to change it.
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const require_lifecycle = require("./lifecycle-D10usEjM.cjs");
|
|
3
|
+
const require_constants = require("./constants-B7sCf4fg.cjs");
|
|
4
|
+
//#region src/cli.ts
|
|
5
|
+
function printHelp() {
|
|
6
|
+
process.stdout.write(`${require_constants.CLI_NAME} — worktree-isolated local Postgres (via autopg)
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
${require_constants.CLI_NAME} ensure --mode=dev|test [--root <path>] [--json] [--print-env]
|
|
10
|
+
${require_constants.CLI_NAME} dispose [--mode=dev|test] [--root <path>]
|
|
11
|
+
${require_constants.CLI_NAME} gc [--json]
|
|
12
|
+
${require_constants.CLI_NAME} print-url [--mode=dev|test] [--root <path>]
|
|
13
|
+
${require_constants.CLI_NAME} --help
|
|
14
|
+
|
|
15
|
+
Modes:
|
|
16
|
+
dev Keep DB across restarts (default for ensure if omitted: dev)
|
|
17
|
+
test Drop DB on dispose / test teardown
|
|
18
|
+
|
|
19
|
+
Env:
|
|
20
|
+
AUTOPG_BIN Path to autopg binary
|
|
21
|
+
CEDAR_PG=0 Disable adapters that auto-ensure
|
|
22
|
+
`);
|
|
23
|
+
}
|
|
24
|
+
function parseMode(value) {
|
|
25
|
+
if (value === "dev" || value === "test") return value;
|
|
26
|
+
throw new Error("--mode must be dev or test");
|
|
27
|
+
}
|
|
28
|
+
function parseArgs(argv) {
|
|
29
|
+
const out = {};
|
|
30
|
+
const rest = [...argv];
|
|
31
|
+
out.cmd = rest.shift();
|
|
32
|
+
for (let i = 0; i < rest.length; i++) {
|
|
33
|
+
const a = rest[i];
|
|
34
|
+
if (a === "--help" || a === "-h") out.help = true;
|
|
35
|
+
else if (a === "--json") out.json = true;
|
|
36
|
+
else if (a === "--print-env") out.printEnv = true;
|
|
37
|
+
else if (a.startsWith("--mode=")) out.mode = parseMode(a.slice(7));
|
|
38
|
+
else if (a === "--mode") out.mode = parseMode(rest[++i]);
|
|
39
|
+
else if (a.startsWith("--root=")) out.root = a.slice(7);
|
|
40
|
+
else if (a === "--root") out.root = rest[++i];
|
|
41
|
+
else throw new Error(`unknown argument: ${a}`);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
async function main() {
|
|
46
|
+
const argv = process.argv.slice(2);
|
|
47
|
+
if (argv.length === 0 || argv[0] === "help" || argv[0] === "--help" || argv[0] === "-h") {
|
|
48
|
+
printHelp();
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const args = parseArgs(argv);
|
|
52
|
+
if (args.help) {
|
|
53
|
+
printHelp();
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
if (args.cmd === "ensure") {
|
|
58
|
+
const mode = args.mode ?? "dev";
|
|
59
|
+
const result = await require_lifecycle.ensure({
|
|
60
|
+
root: args.root,
|
|
61
|
+
mode,
|
|
62
|
+
setEnv: true
|
|
63
|
+
});
|
|
64
|
+
if (args.printEnv) {
|
|
65
|
+
process.stdout.write(`DATABASE_URL=${result.databaseUrl}\n`);
|
|
66
|
+
if (mode === "test") process.stdout.write(`TEST_DATABASE_URL=${result.databaseUrl}\n`);
|
|
67
|
+
}
|
|
68
|
+
if (args.json) process.stdout.write(`${JSON.stringify({
|
|
69
|
+
databaseUrl: result.databaseUrl,
|
|
70
|
+
databaseName: result.databaseName,
|
|
71
|
+
roleName: result.roleName,
|
|
72
|
+
repoSlug: result.repoSlug,
|
|
73
|
+
worktreeSlug: result.worktreeSlug,
|
|
74
|
+
pathHash: result.pathHash,
|
|
75
|
+
mode: result.mode,
|
|
76
|
+
port: result.port,
|
|
77
|
+
root: result.root
|
|
78
|
+
}, null, 2)}\n`);
|
|
79
|
+
else if (!args.printEnv) {
|
|
80
|
+
process.stdout.write(`${require_constants.CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\n`);
|
|
81
|
+
process.stdout.write(`${result.databaseUrl}\n`);
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
if (args.cmd === "dispose") {
|
|
86
|
+
const mode = args.mode ?? "test";
|
|
87
|
+
const result = await require_lifecycle.dispose({
|
|
88
|
+
root: args.root,
|
|
89
|
+
mode
|
|
90
|
+
});
|
|
91
|
+
if (result.dropped) {
|
|
92
|
+
process.stdout.write(`${require_constants.CLI_NAME}: disposed ${mode} (${result.databaseName})\n`);
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
if (result.reason === "no-lease") {
|
|
96
|
+
process.stdout.write(`${require_constants.CLI_NAME}: nothing to dispose for ${mode} (no lease)\n`);
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
process.stderr.write(`${require_constants.CLI_NAME}: could not dispose ${mode} — autopg host unavailable (lease kept for retry)\n`);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
if (args.cmd === "gc") {
|
|
103
|
+
const result = await require_lifecycle.gc();
|
|
104
|
+
if (args.json) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
105
|
+
else {
|
|
106
|
+
process.stdout.write(`${require_constants.CLI_NAME} gc: dropped ${result.dropped.length} database(s)\n`);
|
|
107
|
+
for (const name of result.dropped) process.stdout.write(` ${name}\n`);
|
|
108
|
+
}
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
if (args.cmd === "print-url") {
|
|
112
|
+
const mode = args.mode ?? "dev";
|
|
113
|
+
const lease = require_lifecycle.readLease(require_lifecycle.resolveWorktreeIdentity(args.root).root, mode);
|
|
114
|
+
if (!lease) {
|
|
115
|
+
process.stderr.write(`${require_constants.CLI_NAME}: no ${mode} lease — run \`${require_constants.CLI_NAME} ensure --mode=${mode}\` first\n`);
|
|
116
|
+
return 2;
|
|
117
|
+
}
|
|
118
|
+
process.stdout.write(`${require_lifecycle.urlFromLease(lease)}\n`);
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
process.stderr.write(`${require_constants.CLI_NAME}: unknown command ${args.cmd}\n`);
|
|
122
|
+
printHelp();
|
|
123
|
+
return 64;
|
|
124
|
+
} catch (err) {
|
|
125
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
126
|
+
process.stderr.write(`${require_constants.CLI_NAME}: ${message}\n`);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
main().then((code) => {
|
|
131
|
+
process.exit(code);
|
|
132
|
+
}).catch((err) => {
|
|
133
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
134
|
+
process.stderr.write(`${require_constants.CLI_NAME}: ${message}\n`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
|
137
|
+
//#endregion
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=cli.cjs.map
|
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["CLI_NAME","ensure","dispose","gc","readLease","resolveWorktreeIdentity","urlFromLease"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { CLI_NAME } from \"./core/constants.ts\";\nimport { ensure, 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} ensure --mode=dev|test [--root <path>] [--json] [--print-env]\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 for ensure if omitted: dev)\n test Drop DB on dispose / test teardown\n\nEnv:\n AUTOPG_BIN Path to autopg binary\n CEDAR_PG=0 Disable adapters that auto-ensure\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\nfunction parseArgs(argv: string[]) {\n const out: {\n cmd?: string;\n mode?: DbMode;\n root?: string;\n json?: boolean;\n printEnv?: boolean;\n help?: boolean;\n } = {};\n const rest = [...argv];\n out.cmd = rest.shift();\n for (let i = 0; i < rest.length; i++) {\n const a = rest[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.startsWith(\"--mode=\")) out.mode = parseMode(a.slice(7));\n else if (a === \"--mode\") out.mode = parseMode(rest[++i]);\n else if (a.startsWith(\"--root=\")) out.root = a.slice(7);\n else if (a === \"--root\") out.root = rest[++i];\n else throw new Error(`unknown argument: ${a}`);\n }\n return out;\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 === \"ensure\") {\n const mode = args.mode ?? \"dev\";\n const result = await ensure({\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 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 === \"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} ensure --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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"}
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { S as readLease, a as urlFromLease, g as resolveWorktreeIdentity, i as gc, n as ensure, t as dispose } from "./lifecycle-PbTXNC2Z.mjs";
|
|
3
|
+
import { t as CLI_NAME } from "./constants-YnHDwShD.mjs";
|
|
4
|
+
//#region src/cli.ts
|
|
5
|
+
function printHelp() {
|
|
6
|
+
process.stdout.write(`${CLI_NAME} — worktree-isolated local Postgres (via autopg)
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
${CLI_NAME} ensure --mode=dev|test [--root <path>] [--json] [--print-env]
|
|
10
|
+
${CLI_NAME} dispose [--mode=dev|test] [--root <path>]
|
|
11
|
+
${CLI_NAME} gc [--json]
|
|
12
|
+
${CLI_NAME} print-url [--mode=dev|test] [--root <path>]
|
|
13
|
+
${CLI_NAME} --help
|
|
14
|
+
|
|
15
|
+
Modes:
|
|
16
|
+
dev Keep DB across restarts (default for ensure if omitted: dev)
|
|
17
|
+
test Drop DB on dispose / test teardown
|
|
18
|
+
|
|
19
|
+
Env:
|
|
20
|
+
AUTOPG_BIN Path to autopg binary
|
|
21
|
+
CEDAR_PG=0 Disable adapters that auto-ensure
|
|
22
|
+
`);
|
|
23
|
+
}
|
|
24
|
+
function parseMode(value) {
|
|
25
|
+
if (value === "dev" || value === "test") return value;
|
|
26
|
+
throw new Error("--mode must be dev or test");
|
|
27
|
+
}
|
|
28
|
+
function parseArgs(argv) {
|
|
29
|
+
const out = {};
|
|
30
|
+
const rest = [...argv];
|
|
31
|
+
out.cmd = rest.shift();
|
|
32
|
+
for (let i = 0; i < rest.length; i++) {
|
|
33
|
+
const a = rest[i];
|
|
34
|
+
if (a === "--help" || a === "-h") out.help = true;
|
|
35
|
+
else if (a === "--json") out.json = true;
|
|
36
|
+
else if (a === "--print-env") out.printEnv = true;
|
|
37
|
+
else if (a.startsWith("--mode=")) out.mode = parseMode(a.slice(7));
|
|
38
|
+
else if (a === "--mode") out.mode = parseMode(rest[++i]);
|
|
39
|
+
else if (a.startsWith("--root=")) out.root = a.slice(7);
|
|
40
|
+
else if (a === "--root") out.root = rest[++i];
|
|
41
|
+
else throw new Error(`unknown argument: ${a}`);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
async function main() {
|
|
46
|
+
const argv = process.argv.slice(2);
|
|
47
|
+
if (argv.length === 0 || argv[0] === "help" || argv[0] === "--help" || argv[0] === "-h") {
|
|
48
|
+
printHelp();
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const args = parseArgs(argv);
|
|
52
|
+
if (args.help) {
|
|
53
|
+
printHelp();
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
if (args.cmd === "ensure") {
|
|
58
|
+
const mode = args.mode ?? "dev";
|
|
59
|
+
const result = await ensure({
|
|
60
|
+
root: args.root,
|
|
61
|
+
mode,
|
|
62
|
+
setEnv: true
|
|
63
|
+
});
|
|
64
|
+
if (args.printEnv) {
|
|
65
|
+
process.stdout.write(`DATABASE_URL=${result.databaseUrl}\n`);
|
|
66
|
+
if (mode === "test") process.stdout.write(`TEST_DATABASE_URL=${result.databaseUrl}\n`);
|
|
67
|
+
}
|
|
68
|
+
if (args.json) process.stdout.write(`${JSON.stringify({
|
|
69
|
+
databaseUrl: result.databaseUrl,
|
|
70
|
+
databaseName: result.databaseName,
|
|
71
|
+
roleName: result.roleName,
|
|
72
|
+
repoSlug: result.repoSlug,
|
|
73
|
+
worktreeSlug: result.worktreeSlug,
|
|
74
|
+
pathHash: result.pathHash,
|
|
75
|
+
mode: result.mode,
|
|
76
|
+
port: result.port,
|
|
77
|
+
root: result.root
|
|
78
|
+
}, null, 2)}\n`);
|
|
79
|
+
else if (!args.printEnv) {
|
|
80
|
+
process.stdout.write(`${CLI_NAME}: ${result.databaseName} (${result.repoSlug}/${result.worktreeSlug} ${result.mode})\n`);
|
|
81
|
+
process.stdout.write(`${result.databaseUrl}\n`);
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
if (args.cmd === "dispose") {
|
|
86
|
+
const mode = args.mode ?? "test";
|
|
87
|
+
const result = await dispose({
|
|
88
|
+
root: args.root,
|
|
89
|
+
mode
|
|
90
|
+
});
|
|
91
|
+
if (result.dropped) {
|
|
92
|
+
process.stdout.write(`${CLI_NAME}: disposed ${mode} (${result.databaseName})\n`);
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
if (result.reason === "no-lease") {
|
|
96
|
+
process.stdout.write(`${CLI_NAME}: nothing to dispose for ${mode} (no lease)\n`);
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
process.stderr.write(`${CLI_NAME}: could not dispose ${mode} — autopg host unavailable (lease kept for retry)\n`);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
if (args.cmd === "gc") {
|
|
103
|
+
const result = await gc();
|
|
104
|
+
if (args.json) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
105
|
+
else {
|
|
106
|
+
process.stdout.write(`${CLI_NAME} gc: dropped ${result.dropped.length} database(s)\n`);
|
|
107
|
+
for (const name of result.dropped) process.stdout.write(` ${name}\n`);
|
|
108
|
+
}
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
if (args.cmd === "print-url") {
|
|
112
|
+
const mode = args.mode ?? "dev";
|
|
113
|
+
const lease = readLease(resolveWorktreeIdentity(args.root).root, mode);
|
|
114
|
+
if (!lease) {
|
|
115
|
+
process.stderr.write(`${CLI_NAME}: no ${mode} lease — run \`${CLI_NAME} ensure --mode=${mode}\` first\n`);
|
|
116
|
+
return 2;
|
|
117
|
+
}
|
|
118
|
+
process.stdout.write(`${urlFromLease(lease)}\n`);
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
process.stderr.write(`${CLI_NAME}: unknown command ${args.cmd}\n`);
|
|
122
|
+
printHelp();
|
|
123
|
+
return 64;
|
|
124
|
+
} catch (err) {
|
|
125
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
126
|
+
process.stderr.write(`${CLI_NAME}: ${message}\n`);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
main().then((code) => {
|
|
131
|
+
process.exit(code);
|
|
132
|
+
}).catch((err) => {
|
|
133
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
134
|
+
process.stderr.write(`${CLI_NAME}: ${message}\n`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
|
137
|
+
//#endregion
|
|
138
|
+
export {};
|
|
139
|
+
|
|
140
|
+
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { CLI_NAME } from \"./core/constants.ts\";\nimport { ensure, 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} ensure --mode=dev|test [--root <path>] [--json] [--print-env]\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 for ensure if omitted: dev)\n test Drop DB on dispose / test teardown\n\nEnv:\n AUTOPG_BIN Path to autopg binary\n CEDAR_PG=0 Disable adapters that auto-ensure\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\nfunction parseArgs(argv: string[]) {\n const out: {\n cmd?: string;\n mode?: DbMode;\n root?: string;\n json?: boolean;\n printEnv?: boolean;\n help?: boolean;\n } = {};\n const rest = [...argv];\n out.cmd = rest.shift();\n for (let i = 0; i < rest.length; i++) {\n const a = rest[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.startsWith(\"--mode=\")) out.mode = parseMode(a.slice(7));\n else if (a === \"--mode\") out.mode = parseMode(rest[++i]);\n else if (a.startsWith(\"--root=\")) out.root = a.slice(7);\n else if (a === \"--root\") out.root = rest[++i];\n else throw new Error(`unknown argument: ${a}`);\n }\n return out;\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 === \"ensure\") {\n const mode = args.mode ?? \"dev\";\n const result = await ensure({\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 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 === \"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} ensure --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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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/core/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* Product identity vs frozen crypto.
|
|
4
|
+
*
|
|
5
|
+
* State dirs follow the CLI name (`.cedarpg`) — product-owned, not nested under
|
|
6
|
+
* autopg's `~/.autopg/` (host owns that) and not a generic `.pg` (collision-prone).
|
|
7
|
+
* Password salt is an opaque crypto constant; bump ROLE_PASSWORD_SCHEME to change it.
|
|
8
|
+
*/
|
|
9
|
+
/** User-facing CLI binary (`package.json` bin) and log prefix */
|
|
10
|
+
const CLI_NAME = "cedarpg";
|
|
11
|
+
/**
|
|
12
|
+
* Worktree-local state dir and home-registry parent (`~/.cedarpg/registry`).
|
|
13
|
+
* Frozen for lease/gc discovery after first alpha consumers appear.
|
|
14
|
+
*/
|
|
15
|
+
const STATE_DIRNAME = ".cedarpg";
|
|
16
|
+
/**
|
|
17
|
+
* Password scheme v1 salt prefix: sha256(`${PASSWORD_SALT_PREFIX}\0` + databaseName).
|
|
18
|
+
* Opaque — independent of STATE_DIRNAME / CLI_NAME. Bump ROLE_PASSWORD_SCHEME to change.
|
|
19
|
+
*/
|
|
20
|
+
const PASSWORD_SALT_PREFIX = "cedar-pg";
|
|
21
|
+
//#endregion
|
|
22
|
+
Object.defineProperty(exports, "CLI_NAME", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function() {
|
|
25
|
+
return CLI_NAME;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports, "PASSWORD_SALT_PREFIX", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function() {
|
|
31
|
+
return PASSWORD_SALT_PREFIX;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(exports, "STATE_DIRNAME", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function() {
|
|
37
|
+
return STATE_DIRNAME;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=constants-B7sCf4fg.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants-B7sCf4fg.cjs","names":[],"sources":["../src/core/constants.ts"],"sourcesContent":["/**\n * Product identity vs frozen crypto.\n *\n * State dirs follow the CLI name (`.cedarpg`) — product-owned, not nested under\n * autopg's `~/.autopg/` (host owns that) and not a generic `.pg` (collision-prone).\n * Password salt is an opaque crypto constant; bump ROLE_PASSWORD_SCHEME to change it.\n */\n\n/** User-facing CLI binary (`package.json` bin) and log prefix */\nexport const CLI_NAME = \"cedarpg\";\n\n/**\n * Worktree-local state dir and home-registry parent (`~/.cedarpg/registry`).\n * Frozen for lease/gc discovery after first alpha consumers appear.\n */\nexport const STATE_DIRNAME = \".cedarpg\";\n\n/**\n * Password scheme v1 salt prefix: sha256(`${PASSWORD_SALT_PREFIX}\\0` + databaseName).\n * Opaque — independent of STATE_DIRNAME / CLI_NAME. Bump ROLE_PASSWORD_SCHEME to change.\n */\nexport const PASSWORD_SALT_PREFIX = \"cedar-pg\";\n"],"mappings":";;;;;;;;;AASA,MAAa,WAAW;;;;;AAMxB,MAAa,gBAAgB;;;;;AAM7B,MAAa,uBAAuB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/core/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* Product identity vs frozen crypto.
|
|
4
|
+
*
|
|
5
|
+
* State dirs follow the CLI name (`.cedarpg`) — product-owned, not nested under
|
|
6
|
+
* autopg's `~/.autopg/` (host owns that) and not a generic `.pg` (collision-prone).
|
|
7
|
+
* Password salt is an opaque crypto constant; bump ROLE_PASSWORD_SCHEME to change it.
|
|
8
|
+
*/
|
|
9
|
+
/** User-facing CLI binary (`package.json` bin) and log prefix */
|
|
10
|
+
const CLI_NAME = "cedarpg";
|
|
11
|
+
/**
|
|
12
|
+
* Worktree-local state dir and home-registry parent (`~/.cedarpg/registry`).
|
|
13
|
+
* Frozen for lease/gc discovery after first alpha consumers appear.
|
|
14
|
+
*/
|
|
15
|
+
const STATE_DIRNAME = ".cedarpg";
|
|
16
|
+
/**
|
|
17
|
+
* Password scheme v1 salt prefix: sha256(`${PASSWORD_SALT_PREFIX}\0` + databaseName).
|
|
18
|
+
* Opaque — independent of STATE_DIRNAME / CLI_NAME. Bump ROLE_PASSWORD_SCHEME to change.
|
|
19
|
+
*/
|
|
20
|
+
const PASSWORD_SALT_PREFIX = "cedar-pg";
|
|
21
|
+
//#endregion
|
|
22
|
+
export { PASSWORD_SALT_PREFIX as n, STATE_DIRNAME as r, CLI_NAME as t };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=constants-YnHDwShD.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants-YnHDwShD.mjs","names":[],"sources":["../src/core/constants.ts"],"sourcesContent":["/**\n * Product identity vs frozen crypto.\n *\n * State dirs follow the CLI name (`.cedarpg`) — product-owned, not nested under\n * autopg's `~/.autopg/` (host owns that) and not a generic `.pg` (collision-prone).\n * Password salt is an opaque crypto constant; bump ROLE_PASSWORD_SCHEME to change it.\n */\n\n/** User-facing CLI binary (`package.json` bin) and log prefix */\nexport const CLI_NAME = \"cedarpg\";\n\n/**\n * Worktree-local state dir and home-registry parent (`~/.cedarpg/registry`).\n * Frozen for lease/gc discovery after first alpha consumers appear.\n */\nexport const STATE_DIRNAME = \".cedarpg\";\n\n/**\n * Password scheme v1 salt prefix: sha256(`${PASSWORD_SALT_PREFIX}\\0` + databaseName).\n * Opaque — independent of STATE_DIRNAME / CLI_NAME. Bump ROLE_PASSWORD_SCHEME to change.\n */\nexport const PASSWORD_SALT_PREFIX = \"cedar-pg\";\n"],"mappings":";;;;;;;;;AASA,MAAa,WAAW;;;;;AAMxB,MAAa,gBAAgB;;;;;AAM7B,MAAa,uBAAuB"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_lifecycle = require("./lifecycle-D10usEjM.cjs");
|
|
3
|
+
exports.INSTALL_HINT = require_lifecycle.INSTALL_HINT;
|
|
4
|
+
exports.ROLE_PASSWORD_SCHEME = require_lifecycle.ROLE_PASSWORD_SCHEME;
|
|
5
|
+
exports.buildDatabaseName = require_lifecycle.buildDatabaseName;
|
|
6
|
+
exports.buildDatabaseUrl = require_lifecycle.buildDatabaseUrl;
|
|
7
|
+
exports.buildRoleName = require_lifecycle.buildRoleName;
|
|
8
|
+
exports.discoverHost = require_lifecycle.discoverHost;
|
|
9
|
+
exports.dispose = require_lifecycle.dispose;
|
|
10
|
+
exports.ensure = require_lifecycle.ensure;
|
|
11
|
+
exports.ensureHostRunning = require_lifecycle.ensureHostRunning;
|
|
12
|
+
exports.ensureIfNeeded = require_lifecycle.ensureIfNeeded;
|
|
13
|
+
exports.gc = require_lifecycle.gc;
|
|
14
|
+
exports.isCedarPgManagedUrl = require_lifecycle.isCedarPgManagedUrl;
|
|
15
|
+
exports.isExternalDatabaseEscapeHatch = require_lifecycle.isExternalDatabaseEscapeHatch;
|
|
16
|
+
exports.isOrphanLease = require_lifecycle.isOrphanLease;
|
|
17
|
+
exports.parseHostStatus = require_lifecycle.parseHostStatus;
|
|
18
|
+
exports.parseLease = require_lifecycle.parseLease;
|
|
19
|
+
exports.readLease = require_lifecycle.readLease;
|
|
20
|
+
exports.requireAutopgBin = require_lifecycle.requireAutopgBin;
|
|
21
|
+
exports.resolveAutopgBin = require_lifecycle.resolveAutopgBin;
|
|
22
|
+
exports.resolveEnsureSkip = require_lifecycle.resolveEnsureSkip;
|
|
23
|
+
exports.resolveRoot = require_lifecycle.resolveRoot;
|
|
24
|
+
exports.resolveWorktreeIdentity = require_lifecycle.resolveWorktreeIdentity;
|
|
25
|
+
exports.rolePasswordFor = require_lifecycle.rolePasswordFor;
|
|
26
|
+
exports.urlFromLease = require_lifecycle.urlFromLease;
|