pinnace 0.0.0 → 0.1.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.
Files changed (83) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +15 -0
  3. package/dist/car/car-build.d.ts +26 -0
  4. package/dist/car/car-build.d.ts.map +1 -0
  5. package/dist/car/car-build.js +113 -0
  6. package/dist/car/car-build.js.map +1 -0
  7. package/dist/ci/ci-emit.d.ts +116 -0
  8. package/dist/ci/ci-emit.d.ts.map +1 -0
  9. package/dist/ci/ci-emit.js +190 -0
  10. package/dist/ci/ci-emit.js.map +1 -0
  11. package/dist/cli/bin.d.ts +3 -0
  12. package/dist/cli/bin.d.ts.map +1 -0
  13. package/dist/cli/bin.js +17 -0
  14. package/dist/cli/bin.js.map +1 -0
  15. package/dist/cli/run.d.ts +78 -0
  16. package/dist/cli/run.d.ts.map +1 -0
  17. package/dist/cli/run.js +506 -0
  18. package/dist/cli/run.js.map +1 -0
  19. package/dist/config/config-resolution.d.ts +186 -0
  20. package/dist/config/config-resolution.d.ts.map +1 -0
  21. package/dist/config/config-resolution.js +137 -0
  22. package/dist/config/config-resolution.js.map +1 -0
  23. package/dist/deploy/deploy.d.ts +121 -0
  24. package/dist/deploy/deploy.d.ts.map +1 -0
  25. package/dist/deploy/deploy.js +150 -0
  26. package/dist/deploy/deploy.js.map +1 -0
  27. package/dist/derive/ipns-key-derivation.d.ts +37 -0
  28. package/dist/derive/ipns-key-derivation.d.ts.map +1 -0
  29. package/dist/derive/ipns-key-derivation.js +130 -0
  30. package/dist/derive/ipns-key-derivation.js.map +1 -0
  31. package/dist/index.d.ts +27 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +29 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/node/node-commands.d.ts +115 -0
  36. package/dist/node/node-commands.d.ts.map +1 -0
  37. package/dist/node/node-commands.js +227 -0
  38. package/dist/node/node-commands.js.map +1 -0
  39. package/dist/provision/cloud-init.d.ts +137 -0
  40. package/dist/provision/cloud-init.d.ts.map +1 -0
  41. package/dist/provision/cloud-init.js +390 -0
  42. package/dist/provision/cloud-init.js.map +1 -0
  43. package/dist/publisher/key-import.d.ts +105 -0
  44. package/dist/publisher/key-import.d.ts.map +1 -0
  45. package/dist/publisher/key-import.js +76 -0
  46. package/dist/publisher/key-import.js.map +1 -0
  47. package/dist/publisher/record-sequence.d.ts +90 -0
  48. package/dist/publisher/record-sequence.d.ts.map +1 -0
  49. package/dist/publisher/record-sequence.js +250 -0
  50. package/dist/publisher/record-sequence.js.map +1 -0
  51. package/dist/rpc/kubo-rpc-client.d.ts +154 -0
  52. package/dist/rpc/kubo-rpc-client.d.ts.map +1 -0
  53. package/dist/rpc/kubo-rpc-client.js +207 -0
  54. package/dist/rpc/kubo-rpc-client.js.map +1 -0
  55. package/dist/rpc/mock-kubo.d.ts +87 -0
  56. package/dist/rpc/mock-kubo.d.ts.map +1 -0
  57. package/dist/rpc/mock-kubo.js +129 -0
  58. package/dist/rpc/mock-kubo.js.map +1 -0
  59. package/dist/site/site-management.d.ts +126 -0
  60. package/dist/site/site-management.d.ts.map +1 -0
  61. package/dist/site/site-management.js +123 -0
  62. package/dist/site/site-management.js.map +1 -0
  63. package/dist/status/status-report.d.ts +145 -0
  64. package/dist/status/status-report.d.ts.map +1 -0
  65. package/dist/status/status-report.js +192 -0
  66. package/dist/status/status-report.js.map +1 -0
  67. package/package.json +45 -2
  68. package/src/car/car-build.ts +135 -0
  69. package/src/ci/ci-emit.ts +284 -0
  70. package/src/cli/bin.ts +20 -0
  71. package/src/cli/run.ts +654 -0
  72. package/src/config/config-resolution.ts +264 -0
  73. package/src/deploy/deploy.ts +250 -0
  74. package/src/derive/ipns-key-derivation.ts +173 -0
  75. package/src/index.ts +146 -0
  76. package/src/node/node-commands.ts +391 -0
  77. package/src/provision/cloud-init.ts +551 -0
  78. package/src/publisher/key-import.ts +141 -0
  79. package/src/publisher/record-sequence.ts +336 -0
  80. package/src/rpc/kubo-rpc-client.ts +281 -0
  81. package/src/rpc/mock-kubo.ts +194 -0
  82. package/src/site/site-management.ts +241 -0
  83. package/src/status/status-report.ts +291 -0
@@ -0,0 +1,506 @@
1
+ /**
2
+ * The CLI dispatch surface, separated from the executable shebang entry
3
+ * (bin.ts) so it is unit-testable without spawning a process. It is a THIN
4
+ * wrapper: it parses/validates args, resolves config (arg > env > file), calls
5
+ * the core, and formats the result. ALL behaviour lives in the core (CONTEXT.md
6
+ * `core vs cli`); nothing here re-implements domain logic.
7
+ *
8
+ * The client-facing verbs (provision, deploy, install-ci, status, derive) and
9
+ * the config/env layer dispatch through an injectable {@link RunContext} seam:
10
+ * - {@link RunContext.deps} are the core functions each verb calls (defaults to
11
+ * the real core; tests inject stubs to assert dispatch + resolved args),
12
+ * - {@link RunContext.env} + {@link RunContext.loadConfigFile} are the env and
13
+ * `pinnace.json` layers (defaults read the real `process.env` + file; tests
14
+ * inject in-memory values so the operator's real environment/config is never
15
+ * read or mutated — mirroring the `NodeCommandOps` injectable-ops pattern in
16
+ * node-commands and the explicit-`env` resolver in config-resolution).
17
+ *
18
+ * The on-box `pinnace node <verb>` and the `pinnace site <verb>` namespaces are
19
+ * validated here for surface coherence (one CLI), but their full dispatch is
20
+ * wired by their own tasks (node-agent-commands, site-management).
21
+ */
22
+ import { readFileSync } from 'node:fs';
23
+ import { name } from '../index.js';
24
+ import { NODE_VERBS } from '../node/node-commands.js';
25
+ import { SITE_VERBS } from '../site/site-management.js';
26
+ import { KuboRpcClient } from '../rpc/kubo-rpc-client.js';
27
+ import { provision as coreProvision, } from '../provision/cloud-init.js';
28
+ import { deploy as coreDeploy, } from '../deploy/deploy.js';
29
+ import { emitCi as coreEmitCi, } from '../ci/ci-emit.js';
30
+ import { statusReport as coreStatusReport, } from '../status/status-report.js';
31
+ import { deriveIpnsId as coreDeriveIpnsId, } from '../derive/ipns-key-derivation.js';
32
+ import { resolveConfig, resolveMasterSecret, resolveHostToken, MissingHostTokenError, } from '../config/config-resolution.js';
33
+ /** The real core, used when a caller does not inject stubs. */
34
+ const DEFAULT_DEPS = {
35
+ provision: coreProvision,
36
+ deploy: coreDeploy,
37
+ emitCi: coreEmitCi,
38
+ statusReport: coreStatusReport,
39
+ deriveIpnsId: coreDeriveIpnsId,
40
+ };
41
+ /**
42
+ * Load a config file.
43
+ *
44
+ * With NO explicit path (`--config` absent), read `./pinnace.json` if present;
45
+ * its ABSENCE (or an unreadable/invalid default file) stays a benign empty
46
+ * config, because a config file is optional.
47
+ *
48
+ * With an EXPLICIT `path` (the operator typed `--config <path>`), the file MUST
49
+ * exist and parse: a missing / unreadable / invalid-JSON named path THROWS
50
+ * (naming the path) so the caller fails loud rather than silently emptying the
51
+ * config — an operator who named a file has claimed it exists.
52
+ */
53
+ function defaultLoadConfigFile(path) {
54
+ if (path === undefined) {
55
+ try {
56
+ return JSON.parse(readFileSync('pinnace.json', 'utf8'));
57
+ }
58
+ catch {
59
+ return {};
60
+ }
61
+ }
62
+ let raw;
63
+ try {
64
+ raw = readFileSync(path, 'utf8');
65
+ }
66
+ catch (cause) {
67
+ throw new ConfigLoadError(path, 'read', cause);
68
+ }
69
+ try {
70
+ return JSON.parse(raw);
71
+ }
72
+ catch (cause) {
73
+ throw new ConfigLoadError(path, 'parse', cause);
74
+ }
75
+ }
76
+ /**
77
+ * An explicitly-named `--config <path>` could not be read or parsed. Names the
78
+ * path so `run()` can emit a loud, operator-actionable error (exit 1) instead
79
+ * of silently resolving to an empty config.
80
+ */
81
+ export class ConfigLoadError extends Error {
82
+ path;
83
+ kind;
84
+ constructor(path, kind, cause) {
85
+ const detail = kind === 'read' ? 'read' : 'parse';
86
+ super(`failed to ${detail} config file '${path}'`, { cause });
87
+ this.path = path;
88
+ this.kind = kind;
89
+ this.name = 'ConfigLoadError';
90
+ }
91
+ }
92
+ /**
93
+ * Fill in the run context defaults (real env/file/core/console) once, loading
94
+ * the config from `configPath` (the operator's explicit `--config`, or
95
+ * `undefined` for the `./pinnace.json` default) through the loader seam.
96
+ */
97
+ function resolveContext(context, configPath) {
98
+ return {
99
+ env: context.env ?? process.env,
100
+ file: (context.loadConfigFile ?? defaultLoadConfigFile)(configPath),
101
+ deps: context.deps ?? DEFAULT_DEPS,
102
+ out: context.out ?? ((line) => console.log(line)),
103
+ err: context.err ?? ((line) => console.error(line)),
104
+ };
105
+ }
106
+ /**
107
+ * Dispatch a pinnace CLI invocation. Returns the process exit code.
108
+ *
109
+ * Routes the client verbs (provision/deploy/install-ci/status/derive), the
110
+ * on-box `node` namespace, and the `site` namespace. A missing command is a
111
+ * benign no-op (exit 0); an UNKNOWN command is loud (exit 1) so the surface is
112
+ * an explicit allow-list, not a silent catch-all.
113
+ *
114
+ * A GLOBAL `--config <path>` flag may appear BEFORE the command; it is consumed
115
+ * here (stripped from the per-verb argv) and threaded into config loading via
116
+ * the {@link RunContext.loadConfigFile} seam. With no `--config`, the default
117
+ * `./pinnace.json` is read and its absence is benign; an explicitly-named path
118
+ * that is missing/unreadable/invalid JSON fails loud (names the path, exit 1).
119
+ */
120
+ export async function run(argv, context = {}) {
121
+ const { configPath, rest: postGlobal } = takeConfigFlag(argv);
122
+ const err = context.err ?? ((line) => console.error(line));
123
+ let rc;
124
+ try {
125
+ rc = resolveContext(context, configPath);
126
+ }
127
+ catch (cause) {
128
+ // A loud, path-named failure only ever comes from an EXPLICIT --config;
129
+ // the default loader swallows an absent ./pinnace.json into an empty config.
130
+ if (cause instanceof ConfigLoadError) {
131
+ err(`${name()}: ${cause.message}`);
132
+ return 1;
133
+ }
134
+ throw cause;
135
+ }
136
+ const [command, ...rest] = postGlobal;
137
+ if (command === undefined) {
138
+ rc.out(`${name()}: no command given`);
139
+ return 0;
140
+ }
141
+ if (command === 'version' || command === '--version' || command === '-v') {
142
+ rc.out(name());
143
+ return 0;
144
+ }
145
+ if (command === 'node') {
146
+ return runNodeCli(rest, rc);
147
+ }
148
+ if (command === 'site') {
149
+ return runSiteCli(rest, rc);
150
+ }
151
+ if (command === 'provision') {
152
+ return runProvision(rest, rc);
153
+ }
154
+ if (command === 'deploy') {
155
+ return runDeploy(rest, rc);
156
+ }
157
+ if (command === 'install-ci') {
158
+ return runInstallCi(rest, rc);
159
+ }
160
+ if (command === 'status') {
161
+ return runStatus(rest, rc);
162
+ }
163
+ if (command === 'derive' || command === 'ipns-id') {
164
+ return runDerive(rest, rc);
165
+ }
166
+ rc.err(`${name()}: unknown command '${command}'`);
167
+ return 1;
168
+ }
169
+ // ---------------------------------------------------------------------------
170
+ // Minimal arg parsing (flags + positionals). Kept tiny + local: the CLI is a
171
+ // parse/format layer, so a full arg-parsing dependency would be over-weight.
172
+ // ---------------------------------------------------------------------------
173
+ /**
174
+ * Split the GLOBAL `--config <path>` flag off the front of the argv.
175
+ *
176
+ * `--config` is a global (not a per-verb) flag: it may precede the command and
177
+ * MUST be stripped before the argv reaches a verb parser, or a per-verb parser
178
+ * would mis-read `--config`/its path as one of its own flags/positionals. This
179
+ * scans the WHOLE argv (so `--config` before the command is found) and removes
180
+ * the flag and its value, returning the chosen path (`undefined` if absent).
181
+ * Only the last `--config` wins if repeated. A trailing `--config` with no
182
+ * value yields an empty path, which the loader then fails loud on.
183
+ */
184
+ function takeConfigFlag(argv) {
185
+ const rest = [];
186
+ let configPath;
187
+ for (let i = 0; i < argv.length; i++) {
188
+ if (argv[i] === '--config') {
189
+ const next = argv[i + 1];
190
+ configPath = next !== undefined && !next.startsWith('--') ? next : '';
191
+ if (next !== undefined && !next.startsWith('--'))
192
+ i++;
193
+ continue;
194
+ }
195
+ rest.push(argv[i]);
196
+ }
197
+ return { configPath, rest };
198
+ }
199
+ /**
200
+ * Parse `--flag value` pairs and positionals. Flags are long-form only
201
+ * (`--host hetzner`); a `--flag` at the end with no value is treated as `''`.
202
+ * Positionals are everything that is not a flag or a flag value.
203
+ */
204
+ function parseArgs(argv) {
205
+ const flags = {};
206
+ const positionals = [];
207
+ for (let i = 0; i < argv.length; i++) {
208
+ const token = argv[i];
209
+ if (token.startsWith('--')) {
210
+ const key = token.slice(2);
211
+ const next = argv[i + 1];
212
+ if (next !== undefined && !next.startsWith('--')) {
213
+ flags[key] = next;
214
+ i++;
215
+ }
216
+ else {
217
+ flags[key] = '';
218
+ }
219
+ }
220
+ else {
221
+ positionals.push(token);
222
+ }
223
+ }
224
+ return { flags, positionals };
225
+ }
226
+ // ---------------------------------------------------------------------------
227
+ // Client verbs — each: parse/validate -> resolve config -> call core -> format.
228
+ // ---------------------------------------------------------------------------
229
+ /**
230
+ * `provision --host <h> --api-domain <d> --acme-email <e> --bearer-token <t>
231
+ * --role <r> [...]` -> core {@link ClientDeps.provision}. Purely arg-driven
232
+ * (provisioning inputs are per-box and not stored in `pinnace.json`); prints the
233
+ * generated cloud-init to stdout.
234
+ */
235
+ function runProvision(argv, rc) {
236
+ const { flags } = parseArgs(argv);
237
+ const host = flags['host'];
238
+ const apiDomain = flags['api-domain'];
239
+ const acmeEmail = flags['acme-email'];
240
+ const bearerToken = flags['bearer-token'];
241
+ const role = flags['role'];
242
+ const missing = missingFlags({
243
+ host,
244
+ 'api-domain': apiDomain,
245
+ 'acme-email': acmeEmail,
246
+ 'bearer-token': bearerToken,
247
+ role,
248
+ });
249
+ if (missing.length > 0) {
250
+ rc.err(`pinnace provision: missing required flag(s): ${missing.join(', ')}`);
251
+ return 1;
252
+ }
253
+ if (role !== 'publisher' && role !== 'replica') {
254
+ rc.err(`pinnace provision: --role must be 'publisher' or 'replica'`);
255
+ return 1;
256
+ }
257
+ const input = {
258
+ host: host,
259
+ apiDomain,
260
+ acmeEmail,
261
+ bearerToken,
262
+ role: role,
263
+ };
264
+ if (flags['dashboard-domain'])
265
+ input.dashboardDomain = flags['dashboard-domain'];
266
+ if (flags['publisher-endpoint'])
267
+ input.publisherEndpoint = flags['publisher-endpoint'];
268
+ const result = rc.deps.provision(input);
269
+ rc.out(result.cloudInit.contents);
270
+ return 0;
271
+ }
272
+ /**
273
+ * `deploy [--mode <m>] <dir> <id>` -> core {@link ClientDeps.deploy}. Resolves
274
+ * every configured host into a {@link DeployTarget} (each host's OWN token
275
+ * resolved env-only, LAZILY, via {@link resolveHostToken} — CLI > env, no file),
276
+ * and the site's `mode` from the matching `pinnace.json` site entry (overridable
277
+ * with `--mode`). A host with no resolvable token FAILS LOUD naming its exact
278
+ * env var. Prints the resulting CID / per-node breakdown.
279
+ */
280
+ async function runDeploy(argv, rc) {
281
+ const { flags, positionals } = parseArgs(argv);
282
+ const [dir, siteId] = positionals;
283
+ if (!dir || !siteId) {
284
+ rc.err('pinnace deploy: usage: pinnace deploy [--mode ipfs|ipns] <dir> <id>');
285
+ return 1;
286
+ }
287
+ const cli = cliOverridesFromFlags(flags);
288
+ const cfg = resolveConfig({ file: rc.file, env: rc.env, cli });
289
+ // The site's mode: --mode arg > matching site entry (config precedence).
290
+ const siteEntry = cfg.sites.find((s) => s.id === siteId);
291
+ const mode = flags['mode'] ?? siteEntry?.mode;
292
+ if (mode !== 'ipfs' && mode !== 'ipns') {
293
+ rc.err(`pinnace deploy: mode for '${siteId}' is unset or invalid; pass --mode ipfs|ipns or add the site to pinnace.json`);
294
+ return 1;
295
+ }
296
+ if (cfg.hosts.length === 0) {
297
+ rc.err('pinnace deploy: no hosts configured (add hosts to pinnace.json)');
298
+ return 1;
299
+ }
300
+ // Resolve each host's token env-only (LAZY: only the hosts this deploy uses).
301
+ // A missing token is a loud named error, never a silent "" / downstream 401.
302
+ let targets;
303
+ try {
304
+ targets = cfg.hosts.map((h) => ({
305
+ baseUrl: h.endpoint,
306
+ token: resolveHostToken({ hostName: h.name, env: rc.env, cli }),
307
+ role: h.role,
308
+ }));
309
+ }
310
+ catch (error) {
311
+ if (error instanceof MissingHostTokenError) {
312
+ rc.err(`pinnace deploy: ${error.message}`);
313
+ return 1;
314
+ }
315
+ throw error;
316
+ }
317
+ const input = { sourceDir: dir, id: siteId, mode, targets };
318
+ const result = await rc.deps.deploy(input);
319
+ rc.out(`cid: ${result.cid}`);
320
+ for (const ok of result.ok) {
321
+ rc.out(` ok ${ok.baseUrl}${ok.published && ok.ipns ? ` (ipns ${ok.ipns})` : ''}`);
322
+ }
323
+ for (const failure of result.failed) {
324
+ rc.err(` FAIL ${failure.baseUrl}: ${failure.error.message}`);
325
+ }
326
+ return result.success ? 0 : 1;
327
+ }
328
+ /**
329
+ * `install-ci --system <s> --build-command <c> --output-dir <d> [--branch <b>]
330
+ * [--node-version <v>]` -> core {@link ClientDeps.emitCi}. Prints the workflow
331
+ * path/contents and reports the secrets/vars the operator must set.
332
+ */
333
+ function runInstallCi(argv, rc) {
334
+ const { flags } = parseArgs(argv);
335
+ const system = flags['system'];
336
+ const buildCommand = flags['build-command'];
337
+ const outputDir = flags['output-dir'];
338
+ const missing = missingFlags({
339
+ system,
340
+ 'build-command': buildCommand,
341
+ 'output-dir': outputDir,
342
+ });
343
+ if (missing.length > 0) {
344
+ rc.err(`pinnace install-ci: missing required flag(s): ${missing.join(', ')}`);
345
+ return 1;
346
+ }
347
+ const input = {
348
+ system: system,
349
+ buildCommand,
350
+ outputDir,
351
+ };
352
+ if (flags['branch'])
353
+ input.branch = flags['branch'];
354
+ if (flags['node-version'])
355
+ input.nodeVersion = flags['node-version'];
356
+ const emitted = rc.deps.emitCi(input);
357
+ rc.out(`workflow: ${emitted.workflow.path}`);
358
+ rc.out(emitted.workflow.contents);
359
+ if (emitted.secrets.length > 0) {
360
+ rc.out('Required secrets (Settings -> Secrets):');
361
+ for (const s of emitted.secrets)
362
+ rc.out(` ${s.name} — ${s.description}`);
363
+ }
364
+ if (emitted.vars.length > 0) {
365
+ rc.out('Required variables (Settings -> Variables):');
366
+ for (const v of emitted.vars)
367
+ rc.out(` ${v.name} — ${v.description}`);
368
+ }
369
+ return 0;
370
+ }
371
+ /**
372
+ * `status` -> core {@link ClientDeps.statusReport}, once per configured host
373
+ * (each node reports its OWN sites). Builds each node's Kubo client from the
374
+ * resolved endpoint + token and prints the per-site report.
375
+ */
376
+ async function runStatus(argv, rc) {
377
+ const { flags } = parseArgs(argv);
378
+ const cli = cliOverridesFromFlags(flags);
379
+ const cfg = resolveConfig({ file: rc.file, env: rc.env, cli });
380
+ if (cfg.hosts.length === 0) {
381
+ rc.err('pinnace status: no hosts configured (add hosts to pinnace.json)');
382
+ return 1;
383
+ }
384
+ for (const host of cfg.hosts) {
385
+ let token;
386
+ try {
387
+ // Env-only token, resolved LAZILY per host actually used (see deploy).
388
+ token = resolveHostToken({ hostName: host.name, env: rc.env, cli });
389
+ }
390
+ catch (error) {
391
+ if (error instanceof MissingHostTokenError) {
392
+ rc.err(`pinnace status: ${error.message}`);
393
+ return 1;
394
+ }
395
+ throw error;
396
+ }
397
+ const client = new KuboRpcClient({ baseUrl: host.endpoint, token });
398
+ const report = await rc.deps.statusReport({ client });
399
+ rc.out(`${host.name} (${host.endpoint}) peer ${report.peerId}`);
400
+ for (const site of report.sites) {
401
+ rc.out(` ${site.id}: cid ${site.cid}${site.ipns ? ` ipns ${site.ipns}` : ''} announced=${site.announced} gatewayServes=${site.gatewayServes}`);
402
+ }
403
+ }
404
+ return 0;
405
+ }
406
+ /**
407
+ * `derive <id>` (a.k.a. `ipns-id`) -> core {@link ClientDeps.deriveIpnsId}.
408
+ * Prints the site's `k51...` IPNS id from the master + the site's single `id`
409
+ * (the KDF input), with NO deploy (user story 22). The master is env-ONLY (via
410
+ * {@link resolveMasterSecret}); the `id` is either the positional argument
411
+ * verbatim or, if it names a `pinnace.json` site entry, that entry's `id` (they
412
+ * are the same value — one identifier). Fails loudly if the master is unset.
413
+ */
414
+ function runDerive(argv, rc) {
415
+ const { positionals } = parseArgs(argv);
416
+ const [siteId] = positionals;
417
+ if (!siteId) {
418
+ rc.err('pinnace derive: usage: pinnace derive <id>');
419
+ return 1;
420
+ }
421
+ const master = resolveMasterSecret({ env: rc.env });
422
+ if (!master) {
423
+ rc.err('pinnace derive: master secret not set — export PINNACE_MASTER (env-only; never read from pinnace.json)');
424
+ return 1;
425
+ }
426
+ // The single `id` IS the KDF input. The positional is the id directly; a
427
+ // matching site entry carries the same value (no separate keyId to look up).
428
+ const cfg = resolveConfig({ file: rc.file, env: rc.env, cli: {} });
429
+ const id = cfg.sites.find((s) => s.id === siteId)?.id ?? siteId;
430
+ const printed = rc.deps.deriveIpnsId({ master, keyId: id });
431
+ rc.out(printed);
432
+ return 0;
433
+ }
434
+ // ---------------------------------------------------------------------------
435
+ // Shared helpers.
436
+ // ---------------------------------------------------------------------------
437
+ /** Return the keys whose value is falsy (missing required flags), in order. */
438
+ function missingFlags(required) {
439
+ return Object.entries(required)
440
+ .filter(([, value]) => !value)
441
+ .map(([key]) => `--${key}`);
442
+ }
443
+ /**
444
+ * Build the {@link CliOverrides} the config resolver understands from parsed
445
+ * flags. `--gateways a,b` overrides the gateway list; per-host token/endpoint
446
+ * overrides use the `--host-token.<name>` / `--host-endpoint.<name>` form.
447
+ */
448
+ function cliOverridesFromFlags(flags) {
449
+ const cli = {};
450
+ const hostToken = {};
451
+ const hostEndpoint = {};
452
+ for (const [key, value] of Object.entries(flags)) {
453
+ if (key.startsWith('host-token.'))
454
+ hostToken[key.slice('host-token.'.length)] = value;
455
+ else if (key.startsWith('host-endpoint.'))
456
+ hostEndpoint[key.slice('host-endpoint.'.length)] = value;
457
+ }
458
+ if (Object.keys(hostToken).length > 0)
459
+ cli.hostToken = hostToken;
460
+ if (Object.keys(hostEndpoint).length > 0)
461
+ cli.hostEndpoint = hostEndpoint;
462
+ if (flags['gateways'])
463
+ cli.gateways = flags['gateways']
464
+ .split(',')
465
+ .map((s) => s.trim())
466
+ .filter(Boolean);
467
+ return cli;
468
+ }
469
+ /**
470
+ * Parse `pinnace site <verb>` and validate the verb. The full context (Kubo
471
+ * client from config-resolution, the site name / CID args) is assembled by the
472
+ * CLI wiring in the site-management task; this thin router validates the verb
473
+ * belongs to the `site` namespace. The three verbs (list/remove/add) are
474
+ * implemented in `../site/site-management.ts`.
475
+ */
476
+ function runSiteCli(argv, rc) {
477
+ const [verb] = argv;
478
+ if (!verb) {
479
+ rc.err(`pinnace site: expected a verb (${SITE_VERBS.join(', ')})`);
480
+ return 1;
481
+ }
482
+ if (!SITE_VERBS.includes(verb)) {
483
+ rc.err(`pinnace site: unknown verb '${verb}'; expected one of ${SITE_VERBS.join(', ')}`);
484
+ return 1;
485
+ }
486
+ return 0;
487
+ }
488
+ /**
489
+ * Parse `pinnace node <verb>` and validate the verb. The full on-box context
490
+ * (local Kubo client, role, on-box paths) is assembled by the cloud-init /
491
+ * config-resolution wiring in the node-agent-commands task; this thin router
492
+ * only validates the verb belongs to the `node` namespace.
493
+ */
494
+ function runNodeCli(argv, rc) {
495
+ const [verb] = argv;
496
+ if (!verb) {
497
+ rc.err(`pinnace node: expected a verb (${NODE_VERBS.join(', ')})`);
498
+ return 1;
499
+ }
500
+ if (!NODE_VERBS.includes(verb)) {
501
+ rc.err(`pinnace node: unknown verb '${verb}'; expected one of ${NODE_VERBS.join(', ')}`);
502
+ return 1;
503
+ }
504
+ return 0;
505
+ }
506
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}