db-drifter-cli 0.3.0 → 0.3.1

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.
Files changed (3) hide show
  1. package/README.md +41 -10
  2. package/package.json +1 -1
  3. package/src/index.js +24 -21
package/README.md CHANGED
@@ -18,7 +18,7 @@ node cli/src/index.js --help
18
18
  ```sh
19
19
  dbd auth # browser sign-in; auto-selects your workspace (prompts if you have several)
20
20
 
21
- dbd use staging # pick the source database (auto if the workspace has just one)
21
+ dbd use staging # pick the source DB (auto if the workspace has just one)
22
22
 
23
23
  dbd branch pr-42 # create an isolated, writable database and print its DSN
24
24
  # postgresql://you@wire.db-drifter.com/ws1.staging.pr-42?sslmode=require
@@ -28,17 +28,17 @@ dbd branch rm pr-42 # throw it away
28
28
  ```
29
29
 
30
30
  `dbd auth` auto-selects your workspace when you have one (and prompts a
31
- radio list when you have several), then remembers a single source database.
32
- `dbd branch <name>` creates an isolated overlay on that source and prints its
31
+ radio list when you have several), then remembers a single source DB.
32
+ `dbd branch <name>` creates an isolated overlay on that source DB and prints its
33
33
  connection string — hand it straight to your app, tests or an agent. Run
34
- `dbd add-source <name> <url>` first if you're an admin connecting a database.
34
+ `dbd add-source-db <name> <url>` first if you're an admin connecting a database.
35
35
 
36
36
  ```sh
37
37
  dbd conn staging # the `main` branch DSN
38
38
  dbd conn staging --branch pr-42
39
39
  dbd sql staging "select count(*) from orders"
40
40
  dbd branch ls
41
- dbd use staging # default source database for `dbd branch`
41
+ dbd use staging # default source DB for `dbd branch`
42
42
  ```
43
43
 
44
44
  ## All commands
@@ -46,12 +46,12 @@ dbd use staging # default source database for `dbd br
46
46
  ```
47
47
  auth [--username U] [--password P] [--token T] log in (device flow by default)
48
48
  logout | whoami
49
- use <source-db> set the default source database
49
+ use <source-db> set the default source DB
50
50
 
51
- add-source <name> <url> connect a source database (admin)
51
+ add-source-db <name> <url> connect a source DB (admin)
52
52
  source-db ls | add <name> <url> | rm <name> | reset <name>
53
53
 
54
- branch <name> [--source S] [--ttl-days N] create a branch, print its DSN
54
+ branch <name> [--source-db S] [--ttl-days N] create a branch, print its DSN
55
55
  branch ls | rm <name>
56
56
 
57
57
  conn <source-db> [--branch <name>] print a connection string
@@ -95,6 +95,37 @@ as `DATABASE_URL`, and deletes it on PR close. Ephemeral branches also carry a
95
95
  TTL; the server's nightly cleanup removes expired branches and drops their
96
96
  overlays.
97
97
 
98
- The token can create/delete branches (scope `branch`) but not add source
99
- databases (scope `admin`) — CI can provision its own database without being able
98
+ The token can create/delete branches (scope `branch`) but not add source DBs (scope `admin`) — CI can provision its own database without being able
100
99
  to widen access.
100
+
101
+ ## Releasing
102
+
103
+ The package lives in `cli/` and is published as **`db-drifter-cli`** (it installs
104
+ the `dbd` command). Publishing needs your npm 2FA:
105
+
106
+ ```sh
107
+ cd cli
108
+ npm version patch # or minor / major — bumps package.json + tags
109
+ npm publish --otp=<6-digit code>
110
+ git push --follow-tags
111
+ ```
112
+
113
+ `publishConfig` pins the public registry and `access: public`, so no extra flags
114
+ are needed. After publishing, `latest` follows the highest version — check with:
115
+
116
+ ```sh
117
+ npm view db-drifter-cli dist-tags
118
+ ```
119
+
120
+ Sanity-check the tarball before releasing (it should include `src/index.js`):
121
+
122
+ ```sh
123
+ npm pack --dry-run
124
+ ```
125
+
126
+ If you ever need to publish from a repo checkout before npm has it:
127
+
128
+ ```sh
129
+ npm i -g ./cli # installs `dbd` from the local folder
130
+ node ./cli/src/index.js --help
131
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "db-drifter-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "db_drifter command-line client — connect a source database, create isolated branches, print connection strings.",
5
5
  "type": "module",
6
6
  "bin": { "dbd": "src/index.js" },
package/src/index.js CHANGED
@@ -12,7 +12,7 @@ import { homedir } from "node:os";
12
12
  import { dirname, join } from "node:path";
13
13
 
14
14
  const DEFAULT_API = "https://app.db-drifter.com";
15
- const VERSION = "0.3.0";
15
+ const VERSION = "0.3.1";
16
16
 
17
17
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
18
18
 
@@ -137,7 +137,7 @@ async function workspaceDetail(api, ws) {
137
137
  async function findSourceDb(api, ws, name) {
138
138
  const v = await workspaceDetail(api, ws);
139
139
  const found = (v?.source_dbs ?? []).find((s) => s.name === name);
140
- if (!found) throw new Error(`source database "${name}" not found`);
140
+ if (!found) throw new Error(`source DB "${name}" not found`);
141
141
  return found;
142
142
  }
143
143
 
@@ -148,15 +148,15 @@ async function resolveSourceDb(cfg, api, ws, explicit) {
148
148
  const v = await workspaceDetail(api, ws);
149
149
  const names = (v?.source_dbs ?? []).map((s) => s.name);
150
150
  if (names.length === 1) return names[0];
151
- if (names.length === 0) throw new Error("no source database yet; run `dbd add-source <name> <url>`");
151
+ if (names.length === 0) throw new Error("no source DB yet; run `dbd add-source-db <name> <url>`");
152
152
  const sds = v.source_dbs;
153
- const picked = await chooseRadio("Select a source database:", sds, (s) => s.name);
153
+ const picked = await chooseRadio("Select a source DB:", sds, (s) => s.name);
154
154
  if (picked) {
155
155
  cfg.source_db = picked.name;
156
156
  saveConfig(cfg);
157
157
  return picked.name;
158
158
  }
159
- throw new Error(`which source database? pass --source <name> (available: ${names.join(", ")})`);
159
+ throw new Error(`which source DB? pass --source-db <name> (available: ${names.join(", ")})`);
160
160
  }
161
161
 
162
162
  async function connFor(api, ws, sourceDb, branch) {
@@ -169,6 +169,9 @@ async function connFor(api, ws, sourceDb, branch) {
169
169
 
170
170
  const enc = (s) => encodeURIComponent(s);
171
171
 
172
+ /** The source DB flag: `--source-db` (with `--source` accepted for back-compat). */
173
+ const sourceFlag = (args) => str(args.flags["source-db"]) ?? sourceFlag(args);
174
+
172
175
  // ---------------------------------------------------------------------------
173
176
  // Args
174
177
  // ---------------------------------------------------------------------------
@@ -293,7 +296,7 @@ async function chooseRadio(question, items, label) {
293
296
 
294
297
  /**
295
298
  * After login, pick a workspace (auto if there is only one, otherwise prompt)
296
- * and remember a single source database when the workspace has exactly one.
299
+ * and remember a single source DB when the workspace has exactly one.
297
300
  */
298
301
  async function settleContext(cfg, api) {
299
302
  try {
@@ -321,7 +324,7 @@ async function settleContext(cfg, api) {
321
324
  if (sds.length === 1) {
322
325
  cfg.source_db = sds[0].name;
323
326
  saveConfig(cfg);
324
- console.log(`using source database "${sds[0].name}"`);
327
+ console.log(`using source DB "${sds[0].name}"`);
325
328
  }
326
329
  } catch {
327
330
  /* best effort — never fail a login over this */
@@ -410,7 +413,7 @@ async function cmdWorkspace(cfg, args) {
410
413
  throw new Error("usage: dbd workspace ls | use <id>");
411
414
  }
412
415
 
413
- /** `dbd source-db …` and the `dbd add-source` / `dbd use` aliases. */
416
+ /** `dbd source-db …` and the `dbd add-source-db` / `dbd use` aliases. */
414
417
  async function cmdSourceDb(cfg, args, verb) {
415
418
  const api = apiFor(cfg);
416
419
  const ws = await resolveWorkspace(cfg, api);
@@ -425,19 +428,19 @@ async function cmdSourceDb(cfg, args, verb) {
425
428
  return;
426
429
  }
427
430
  if (sub === "add") {
428
- // `dbd add-source <name> <url>` or `dbd source-db add <name> <url>`
431
+ // `dbd add-source-db <name> <url>` or `dbd source-db add <name> <url>`
429
432
  const name = verb ? args.pos[0] : args.pos[1];
430
433
  const url = verb ? args.pos[1] : args.pos[2];
431
434
  await api.post(`/api/workspaces/${ws}/source-dbs`, { name, url });
432
435
  cfg.source_db = name;
433
436
  saveConfig(cfg);
434
- console.log(`source database "${name}" added (with a \`main\` branch)`);
437
+ console.log(`source DB "${name}" added (with a \`main\` branch)`);
435
438
  return;
436
439
  }
437
440
  if (sub === "rm") {
438
441
  const name = verb ? args.pos[0] : args.pos[1];
439
442
  await api.del(`/api/workspaces/${ws}/source-dbs/${enc(name)}`);
440
- console.log(`source database "${name}" deleted`);
443
+ console.log(`source DB "${name}" deleted`);
441
444
  return;
442
445
  }
443
446
  if (sub === "reset") {
@@ -449,7 +452,7 @@ async function cmdSourceDb(cfg, args, verb) {
449
452
  throw new Error("usage: dbd source-db ls | add <name> <url> | rm <name> | reset <name>");
450
453
  }
451
454
 
452
- /** `dbd use <source-db>` — set the default source database. */
455
+ /** `dbd use <source-db>` — set the default source DB. */
453
456
  async function cmdUse(cfg, args) {
454
457
  const api = apiFor(cfg);
455
458
  const ws = await resolveWorkspace(cfg, api);
@@ -458,14 +461,14 @@ async function cmdUse(cfg, args) {
458
461
  const sds = (await workspaceDetail(api, ws))?.source_dbs ?? [];
459
462
  if (sds.length === 1) name = sds[0].name;
460
463
  else if (sds.length > 1) {
461
- name = (await chooseRadio("Select a source database:", sds, (s) => s.name))?.name;
464
+ name = (await chooseRadio("Select a source DB:", sds, (s) => s.name))?.name;
462
465
  }
463
466
  }
464
467
  if (!name) throw new Error("usage: dbd use <source-db>");
465
468
  await findSourceDb(api, ws, name); // validate
466
469
  cfg.source_db = name;
467
470
  saveConfig(cfg);
468
- console.log(`current source database: ${name}`);
471
+ console.log(`current source DB: ${name}`);
469
472
  }
470
473
 
471
474
  async function cmdBranch(cfg, args) {
@@ -475,7 +478,7 @@ async function cmdBranch(cfg, args) {
475
478
 
476
479
  // `dbd branch ls`
477
480
  if (sub === "ls") {
478
- const src = await resolveSourceDb(cfg, api, ws, str(args.flags.source));
481
+ const src = await resolveSourceDb(cfg, api, ws, sourceFlag(args));
479
482
  const sd = await findSourceDb(api, ws, src);
480
483
  for (const b of sd.branches ?? []) {
481
484
  console.log(
@@ -486,7 +489,7 @@ async function cmdBranch(cfg, args) {
486
489
  }
487
490
  // `dbd branch rm <name>`
488
491
  if (sub === "rm") {
489
- const src = await resolveSourceDb(cfg, api, ws, str(args.flags.source));
492
+ const src = await resolveSourceDb(cfg, api, ws, sourceFlag(args));
490
493
  await api.del(`/api/workspaces/${ws}/source-dbs/${enc(src)}/branches/${enc(args.pos[1])}`);
491
494
  console.log(`branch "${args.pos[1]}" deleted`);
492
495
  return;
@@ -495,7 +498,7 @@ async function cmdBranch(cfg, args) {
495
498
  const explicitCreate = sub === "create";
496
499
  const name = explicitCreate ? args.pos[1] : args.pos[0];
497
500
  if (!name) throw new Error("usage: dbd branch <name> (or: dbd branch ls | rm <name>)");
498
- const src = await resolveSourceDb(cfg, api, ws, str(args.flags.source));
501
+ const src = await resolveSourceDb(cfg, api, ws, sourceFlag(args));
499
502
  const body = { name };
500
503
  const ttl = num(args.flags["ttl-days"]);
501
504
  if (ttl !== undefined) body.ttl_days = ttl;
@@ -560,12 +563,12 @@ Usage: dbd [--api-url <url>] <command> [args]
560
563
 
561
564
  auth [--username U] [--password P] [--token T] log in (device flow by default)
562
565
  whoami
563
- use <source-db> set the default source database
566
+ use <source-db> set the default source DB
564
567
 
565
- add-source <name> <url> connect a source database (admin)
568
+ add-source-db <name> <url> connect a source DB (admin)
566
569
  source-db ls | add <name> <url> | rm <name> | reset <name>
567
570
 
568
- branch <name> [--source S] [--ttl-days N] create a branch, print its DSN
571
+ branch <name> [--source-db S] [--ttl-days N] create a branch, print its DSN
569
572
  branch ls | rm <name>
570
573
 
571
574
  conn <source-db> [--branch <name>] print a connection string
@@ -613,11 +616,11 @@ async function main() {
613
616
  case "workspace":
614
617
  await cmdWorkspace(cfg, rest);
615
618
  break;
619
+ case "add-source-db":
616
620
  case "add-source":
617
621
  await cmdSourceDb(cfg, rest, "add");
618
622
  break;
619
623
  case "source-db":
620
- case "source":
621
624
  await cmdSourceDb(cfg, rest);
622
625
  break;
623
626
  case "branch":