@smonn/ids 0.13.0 → 0.13.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 (30) hide show
  1. package/README.md +20 -40
  2. package/dist/cli.mjs +90 -84
  3. package/dist/cli.mjs.map +1 -1
  4. package/dist/{codec-shell-DvrTDa65.mjs → codec-shell-C2NKQEx2.mjs} +5 -1
  5. package/dist/codec-shell-C2NKQEx2.mjs.map +1 -0
  6. package/dist/{digest-Drnof-l_.mjs → digest-DsGeXfk3.mjs} +3 -3
  7. package/dist/{digest-Drnof-l_.mjs.map → digest-DsGeXfk3.mjs.map} +1 -1
  8. package/dist/digest.mjs +1 -1
  9. package/dist/index.mjs +1 -1
  10. package/dist/{key-material-DsukgnR5.mjs → key-material-DvjACe89.mjs} +2 -2
  11. package/dist/key-material-DvjACe89.mjs.map +1 -0
  12. package/dist/{opaque-D7y5cgzT.mjs → opaque-BW3Uzeeb.mjs} +4 -4
  13. package/dist/{opaque-D7y5cgzT.mjs.map → opaque-BW3Uzeeb.mjs.map} +1 -1
  14. package/dist/opaque.mjs +1 -1
  15. package/dist/{reverse-DrAofYWV.mjs → reverse-BW8g_cln.mjs} +3 -3
  16. package/dist/{reverse-DrAofYWV.mjs.map → reverse-BW8g_cln.mjs.map} +1 -1
  17. package/dist/reverse.mjs +1 -1
  18. package/dist/{rng-Clos6uC0.mjs → rng-BHFxX1Fc.mjs} +2 -2
  19. package/dist/{rng-Clos6uC0.mjs.map → rng-BHFxX1Fc.mjs.map} +1 -1
  20. package/dist/{signed-B2Aa3zMg.mjs → signed-BTz3ZFYE.mjs} +4 -4
  21. package/dist/{signed-B2Aa3zMg.mjs.map → signed-BTz3ZFYE.mjs.map} +1 -1
  22. package/dist/signed.mjs +1 -1
  23. package/dist/{timestamp-YPd58344.mjs → timestamp-CleAIdZI.mjs} +3 -3
  24. package/dist/{timestamp-YPd58344.mjs.map → timestamp-CleAIdZI.mjs.map} +1 -1
  25. package/dist/{wrapped-BjmVzuYc.mjs → wrapped-DPlsv1x-.mjs} +3 -3
  26. package/dist/{wrapped-BjmVzuYc.mjs.map → wrapped-DPlsv1x-.mjs.map} +1 -1
  27. package/dist/wrapped.mjs +1 -1
  28. package/package.json +1 -1
  29. package/dist/codec-shell-DvrTDa65.mjs.map +0 -1
  30. package/dist/key-material-DsukgnR5.mjs.map +0 -1
package/README.md CHANGED
@@ -8,10 +8,7 @@ Public-facing branded IDs for TypeScript apps. Type-safe, sortable, and codec-pl
8
8
  pnpm add @smonn/ids
9
9
  ```
10
10
 
11
- Each ID looks like `usr_01h7b3k9rqxn4cw3p9r8t2sgkw`: a three-letter brand, an
12
- underscore, then 26 Crockford base32 characters of payload. The default
13
- Timestamp codec encodes a 48-bit millisecond Unix timestamp followed by 80
14
- random bits — the same byte layout as a [ULID](https://github.com/ulid/spec).
11
+ Each ID looks like `usr_01h7b3k9rqxn4cw3p9r8t2sgkw`: a three-letter brand, an underscore, then 26 Crockford base32 characters of payload. The default Timestamp codec encodes a 48-bit millisecond Unix timestamp followed by 80 random bits — the same byte layout as a [ULID](https://github.com/ulid/spec).
15
12
 
16
13
  ## Quickstart
17
14
 
@@ -35,29 +32,22 @@ if (r.ok) {
35
32
  }
36
33
  ```
37
34
 
38
- `safeParse` accepts mixed case and the Crockford visual aliases (`o → 0`,
39
- `i → 1`, `l → 1`) and always returns the canonical lowercase form. See the
40
- [Timestamp codec guide](https://ids.smonn.se/codecs/timestamp/) for sorting,
41
- backfills (`generateAt`), range queries, structured errors, Standard Schema, and
42
- JSON Schema.
35
+ `safeParse` accepts mixed case and the Crockford visual aliases (`o → 0`, `i → 1`, `l → 1`) and always returns the canonical lowercase form. See the [Timestamp codec guide](https://ids.smonn.se/codecs/timestamp/) for sorting, backfills (`generateAt`), range queries, structured errors, Standard Schema, and JSON Schema.
43
36
 
44
37
  ## Choosing a codec
45
38
 
46
- All six codecs share the same `<brand>_<26 chars>` wire shape but make different
47
- trade-offs. They are wire-indistinguishable — `safeParse`, `is`, and `parse`
48
- cannot distinguish an Opaque Timestamp ID from a Timestamp ID at runtime.
49
- Cross-codec confusion is undetectable by the library; the consumer is
50
- responsible for routing a given ID to the correct codec for the brand. Codec
51
- choice is therefore a per-brand commitment.
52
-
53
- | Codec | Import | Sort direction | Key required | Timestamp extractable |
54
- | ----------------- | -------------------- | ------------------------- | ------------------ | -------------------------- |
55
- | Timestamp | `@smonn/ids` | Ascending (oldest-first) | No | Always (plaintext) |
56
- | Reverse Timestamp | `@smonn/ids/reverse` | Descending (newest-first) | No | Always (plaintext) |
57
- | Signed Timestamp | `@smonn/ids/signed` | Ascending (oldest-first) | Yes (signing key) | Always (plaintext) |
58
- | Opaque Timestamp | `@smonn/ids/opaque` | None (encrypted) | Yes (AES key) | With key only |
59
- | Wrapped key | `@smonn/ids/wrapped` | None | Yes (wrapping key) | N/A — not timestamp-family |
60
- | Digest | `@smonn/ids/digest` | None | Yes (digest key) | N/A — not timestamp-family |
39
+ All six codecs share the same `<brand>_<26 chars>` wire shape but make different trade-offs. They are wire-indistinguishable — `safeParse`, `is`, and `parse` cannot distinguish an Opaque Timestamp ID from a Timestamp ID at runtime. Cross-codec confusion is undetectable by the library; the consumer is responsible for routing a given ID to the correct codec for the brand. Codec choice is therefore a per-brand commitment.
40
+
41
+ | Codec | Import | Sort direction | Key required | Timestamp extractable |
42
+ | --- | --- | --- | --- | --- |
43
+ | Timestamp | `@smonn/ids` | Ascending (oldest-first) | No | Always (plaintext) |
44
+ | Reverse Timestamp | `@smonn/ids/reverse` | Descending (newest-first) | No | Always (plaintext) |
45
+ | Signed Timestamp | `@smonn/ids/signed` | Ascending (oldest-first) | Yes (signing key) | Always (plaintext) |
46
+ | Opaque Timestamp | `@smonn/ids/opaque` | None (encrypted) | Yes (AES key) | With key only |
47
+ | Wrapped key | `@smonn/ids/wrapped` | None | Yes (wrapping key) | N/A — not timestamp-family |
48
+ | Digest | `@smonn/ids/digest` | None | Yes (digest key) | N/A — not timestamp-family |
49
+
50
+ The Timestamp codec is the default and ships from the root `@smonn/ids` entry — it has no `/timestamp` subpath by design. If you try `import ... from "@smonn/ids/timestamp"` you will get a module-resolution error; use `@smonn/ids` directly. Every other codec uses a named subpath (`/reverse`, `/signed`, `/opaque`, `/wrapped`, `/digest`); this asymmetry is intentional and permanent.
61
51
 
62
52
  - **Newest-first scans** on forward-only KV stores → [Reverse Timestamp](https://ids.smonn.se/codecs/reverse/)
63
53
  - **Tamper-evident share links** verified without a DB lookup → [Signed Timestamp](https://ids.smonn.se/codecs/signed/) (integrity)
@@ -69,35 +59,25 @@ Try them all live in the [playground](https://ids.smonn.se/playground/).
69
59
 
70
60
  ## Integrations
71
61
 
72
- Framework and ORM adapters ship as optional subpath exports (each requires its
73
- own peer dependency):
62
+ Framework and ORM adapters ship as optional subpath exports (each requires its own peer dependency):
74
63
 
75
64
  - **HTTP route params:** [Hono](https://ids.smonn.se/adapters/hono/), [Express](https://ids.smonn.se/adapters/express/), [Fastify](https://ids.smonn.se/adapters/fastify/) — `idParam` middleware; [NestJS](https://ids.smonn.se/adapters/nestjs/) — `ParseIdPipe`
76
65
  - **ORM columns:** [Drizzle](https://ids.smonn.se/adapters/drizzle/) — `idColumn`, [Kysely](https://ids.smonn.se/adapters/kysely/) — `idColumn`, [MikroORM](https://ids.smonn.se/adapters/mikro-orm/) — `idType`, [Prisma](https://ids.smonn.se/adapters/prisma/) — `idField`, [TypeORM](https://ids.smonn.se/adapters/typeorm/) — `idTransformer`
77
66
  - **GraphQL:** [GraphQL](https://ids.smonn.se/adapters/graphql/) — `idScalar` custom scalar
78
67
  - **CLI:** brand-agnostic `inspect` / `generate` / `keygen` — `npx @smonn/ids --help` ([docs](https://ids.smonn.se/cli/))
79
68
 
80
- Every codec also implements [Standard Schema v1](https://standardschema.dev/), so
81
- it slots into Zod, Valibot, ArkType, tRPC, and any validator-aware library.
69
+ Every codec also implements [Standard Schema v1](https://standardschema.dev/), so it slots into Zod, Valibot, ArkType, tRPC, and any validator-aware library.
82
70
 
83
71
  ## What this is **not** for
84
72
 
85
- - **Internal surrogate primary keys.** If nobody outside your service sees the
86
- ID, the brand prefix and lenient parsing are dead weight. Use a `bigint`
87
- sequence.
88
- - **Wire-compatible ULIDs.** The byte layout is ULID-shaped, but the encoding is
89
- lowercase and brand-wrapped. Stock ULID parsers will reject these.
73
+ - **Internal surrogate primary keys.** If nobody outside your service sees the ID, the brand prefix and lenient parsing are dead weight. Use a `bigint` sequence.
74
+ - **Wire-compatible ULIDs.** The byte layout is ULID-shaped, but the encoding is lowercase and brand-wrapped. Stock ULID parsers will reject these.
90
75
  - **Distributed-trace / request-correlation IDs.** Use OpenTelemetry-format IDs.
91
- - **Hiding creation time with the Timestamp codec.** Anyone with one ID at a
92
- known creation time can compute the epoch offset. Use the Opaque Timestamp
93
- codec to hide creation time per-ID.
76
+ - **Hiding creation time with the Timestamp codec.** Anyone with one ID at a known creation time can compute the epoch offset. Use the Opaque Timestamp codec to hide creation time per-ID.
94
77
 
95
78
  ## API surface
96
79
 
97
- Exports from the main `@smonn/ids` entry point only. Codec-specific subpath
98
- exports (`@smonn/ids/reverse`, `@smonn/ids/opaque`, `@smonn/ids/signed`,
99
- `@smonn/ids/wrapped`, `@smonn/ids/digest`) and adapter subpaths are not listed
100
- here.
80
+ Exports from the main `@smonn/ids` entry point only. Codec-specific subpath exports (`@smonn/ids/reverse`, `@smonn/ids/opaque`, `@smonn/ids/signed`, `@smonn/ids/wrapped`, `@smonn/ids/digest`) and adapter subpaths are not listed here.
101
81
 
102
82
  ### Types
103
83
 
package/dist/cli.mjs CHANGED
@@ -1,11 +1,79 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as isIdsError } from "./error-Cp5qYZcv.mjs";
3
- import { t as createTimestampId } from "./timestamp-YPd58344.mjs";
4
- import { i as importOpaqueKey, n as decodeOpaqueKey, r as encodeOpaqueKey, t as createOpaqueTimestampId } from "./opaque-D7y5cgzT.mjs";
5
- import { t as createReverseTimestampId } from "./reverse-DrAofYWV.mjs";
6
- import { i as importSigningKey, n as decodeSigningKey, r as encodeSigningKey, t as createSignedTimestampId } from "./signed-B2Aa3zMg.mjs";
7
- import { i as importWrappingKey, n as decodeWrappingKey, r as encodeWrappingKey, t as createWrappedKeyId } from "./wrapped-BjmVzuYc.mjs";
8
- import { i as importDigestKey, n as decodeDigestKey, r as encodeDigestKey, t as createDigestId } from "./digest-Drnof-l_.mjs";
3
+ import { t as createTimestampId } from "./timestamp-CleAIdZI.mjs";
4
+ import { i as importOpaqueKey, n as decodeOpaqueKey, r as encodeOpaqueKey, t as createOpaqueTimestampId } from "./opaque-BW3Uzeeb.mjs";
5
+ import { t as createReverseTimestampId } from "./reverse-BW8g_cln.mjs";
6
+ import { i as importSigningKey, n as decodeSigningKey, r as encodeSigningKey, t as createSignedTimestampId } from "./signed-BTz3ZFYE.mjs";
7
+ import { i as importWrappingKey, n as decodeWrappingKey, r as encodeWrappingKey, t as createWrappedKeyId } from "./wrapped-DPlsv1x-.mjs";
8
+ import { i as importDigestKey, n as decodeDigestKey, r as encodeDigestKey, t as createDigestId } from "./digest-DsGeXfk3.mjs";
9
+ //#region src/cli/format.ts
10
+ const invalidIdPrefix = "invalid_id: ";
11
+ function formatCliError(err) {
12
+ return isIdsError(err) ? `${err.code}: ${err.message}` : err instanceof Error ? err.message : String(err);
13
+ }
14
+ function formatWrappedInspectOutput(result) {
15
+ const inputLine = describeInputForm(result.input, result.canonical);
16
+ return [
17
+ `brand: ${result.brand}`,
18
+ `lookup-key: ${result.lookupKey.toString()}`,
19
+ `canonical: ${result.canonical}`,
20
+ `input: ${inputLine}`,
21
+ ""
22
+ ].join("\n");
23
+ }
24
+ function formatSignedInspectOutput(result) {
25
+ const relative = formatRelative(result.timestamp.getTime(), result.nowMs);
26
+ const inputLine = describeInputForm(result.input, result.canonical);
27
+ const lines = [`brand: ${result.brand}`, `timestamp: ${result.timestamp.toISOString()} (${relative})`];
28
+ lines.push(`verification: ${result.verification}`);
29
+ lines.push(`canonical: ${result.canonical}`, `input: ${inputLine}`, "");
30
+ return lines.join("\n");
31
+ }
32
+ function formatInspectOutput(result) {
33
+ const relative = formatRelative(result.timestamp.getTime(), result.nowMs);
34
+ const inputLine = describeInputForm(result.input, result.canonical);
35
+ return [
36
+ `brand: ${result.brand}`,
37
+ `timestamp: ${result.timestamp.toISOString()} (${relative})`,
38
+ `canonical: ${result.canonical}`,
39
+ `input: ${inputLine}`,
40
+ ""
41
+ ].join("\n");
42
+ }
43
+ function describeInputForm(input, canonical) {
44
+ if (input === canonical) return "canonical";
45
+ const notes = [];
46
+ if (input !== input.toLowerCase()) notes.push("was uppercase");
47
+ if (/[ilo]/i.test(input.slice(4))) notes.push("used Crockford aliases");
48
+ return `not canonical (${notes.join(" + ")})`;
49
+ }
50
+ const msPerMinute = 60 * 1e3;
51
+ const msPerHour = 60 * msPerMinute;
52
+ const msPerDay = 24 * msPerHour;
53
+ const daysPerMonth = 30.44;
54
+ const monthsPerYear = 12;
55
+ function formatRelative(thenMs, nowMs) {
56
+ const diff = nowMs - thenMs;
57
+ const abs = Math.abs(diff);
58
+ const suffix = diff < 0 ? "from now" : "ago";
59
+ const head = headUnits(abs);
60
+ return head === "" ? "just now" : `${head} ${suffix}`;
61
+ }
62
+ function headUnits(abs) {
63
+ if (abs < 6e4) return "";
64
+ if (abs < 36e5) return unit(Math.round(abs / msPerMinute), "minute");
65
+ if (abs < 864e5) return unit(Math.round(abs / msPerHour), "hour");
66
+ if (abs < 864e5 * daysPerMonth) return unit(Math.round(abs / msPerDay), "day");
67
+ const totalMonths = Math.round(abs / (msPerDay * daysPerMonth));
68
+ if (totalMonths < monthsPerYear) return unit(totalMonths, "month");
69
+ const years = Math.floor(totalMonths / monthsPerYear);
70
+ const months = totalMonths % monthsPerYear;
71
+ return months === 0 ? unit(years, "year") : `${unit(years, "year")} ${unit(months, "month")}`;
72
+ }
73
+ function unit(n, name) {
74
+ return `${n} ${n === 1 ? name : `${name}s`}`;
75
+ }
76
+ //#endregion
9
77
  //#region src/cli/key-io.ts
10
78
  function isLoadKeyError(value) {
11
79
  if (typeof value !== "object" || value === null) return false;
@@ -46,7 +114,7 @@ async function loadKey(opts, format, facet) {
46
114
  } catch (err) {
47
115
  return {
48
116
  kind: "import-failure",
49
- message: err.message
117
+ message: formatCliError(err)
50
118
  };
51
119
  }
52
120
  }
@@ -178,77 +246,10 @@ function isNsError(result) {
178
246
  return result === "--ns requires a value";
179
247
  }
180
248
  //#endregion
181
- //#region src/cli/format.ts
182
- function formatCliError(err) {
183
- return isIdsError(err) ? `${err.code}: ${err.message}` : err instanceof Error ? err.message : String(err);
184
- }
185
- function formatWrappedInspectOutput(result) {
186
- const inputLine = describeInputForm(result.input, result.canonical);
187
- return [
188
- `brand: ${result.brand}`,
189
- `lookup-key: ${result.lookupKey.toString()}`,
190
- `canonical: ${result.canonical}`,
191
- `input: ${inputLine}`,
192
- ""
193
- ].join("\n");
194
- }
195
- function formatSignedInspectOutput(result) {
196
- const relative = formatRelative(result.timestamp.getTime(), result.nowMs);
197
- const inputLine = describeInputForm(result.input, result.canonical);
198
- const lines = [`brand: ${result.brand}`, `timestamp: ${result.timestamp.toISOString()} (${relative})`];
199
- lines.push(`verification: ${result.verification}`);
200
- lines.push(`canonical: ${result.canonical}`, `input: ${inputLine}`, "");
201
- return lines.join("\n");
202
- }
203
- function formatInspectOutput(result) {
204
- const relative = formatRelative(result.timestamp.getTime(), result.nowMs);
205
- const inputLine = describeInputForm(result.input, result.canonical);
206
- return [
207
- `brand: ${result.brand}`,
208
- `timestamp: ${result.timestamp.toISOString()} (${relative})`,
209
- `canonical: ${result.canonical}`,
210
- `input: ${inputLine}`,
211
- ""
212
- ].join("\n");
213
- }
214
- function describeInputForm(input, canonical) {
215
- if (input === canonical) return "canonical";
216
- const notes = [];
217
- if (input !== input.toLowerCase()) notes.push("was uppercase");
218
- if (/[ilo]/i.test(input.slice(4))) notes.push("used Crockford aliases");
219
- return `not canonical (${notes.join(" + ")})`;
220
- }
221
- const msPerMinute = 60 * 1e3;
222
- const msPerHour = 60 * msPerMinute;
223
- const msPerDay = 24 * msPerHour;
224
- const daysPerMonth = 30.44;
225
- const monthsPerYear = 12;
226
- function formatRelative(thenMs, nowMs) {
227
- const diff = nowMs - thenMs;
228
- const abs = Math.abs(diff);
229
- const suffix = diff < 0 ? "from now" : "ago";
230
- const head = headUnits(abs);
231
- return head === "" ? "just now" : `${head} ${suffix}`;
232
- }
233
- function headUnits(abs) {
234
- if (abs < 6e4) return "";
235
- if (abs < 36e5) return unit(Math.round(abs / msPerMinute), "minute");
236
- if (abs < 864e5) return unit(Math.round(abs / msPerHour), "hour");
237
- if (abs < 864e5 * daysPerMonth) return unit(Math.round(abs / msPerDay), "day");
238
- const totalMonths = Math.round(abs / (msPerDay * daysPerMonth));
239
- if (totalMonths < monthsPerYear) return unit(totalMonths, "month");
240
- const years = Math.floor(totalMonths / monthsPerYear);
241
- const months = totalMonths % monthsPerYear;
242
- return months === 0 ? unit(years, "year") : `${unit(years, "year")} ${unit(months, "month")}`;
243
- }
244
- function unit(n, name) {
245
- return `${n} ${n === 1 ? name : `${name}s`}`;
246
- }
247
- //#endregion
248
249
  //#region src/cli/variants.ts
249
250
  function standardValidate(codec, input) {
250
251
  const result = codec["~standard"].validate(input);
251
- if (result.issues) return { issue: result.issues[0].message };
252
+ if (result.issues) return { issue: invalidIdPrefix + result.issues[0].message };
252
253
  return { value: result.value };
253
254
  }
254
255
  const timestampVariant = {
@@ -695,7 +696,7 @@ async function runInspect(args, opts) {
695
696
  }
696
697
  const structValidation = tsCodec["~standard"].validate(input);
697
698
  if (structValidation.issues) {
698
- opts.stderr(structValidation.issues[0].message + "\n");
699
+ opts.stderr(invalidIdPrefix + structValidation.issues[0].message + "\n");
699
700
  return 1;
700
701
  }
701
702
  verifyCanonical = structValidation.value;
@@ -876,15 +877,20 @@ const commands = [
876
877
  }
877
878
  ];
878
879
  async function run(opts) {
879
- const [subcommand, ...rest] = opts.argv;
880
- const command = commands.find((candidate) => candidate.names.includes(subcommand ?? ""));
881
- if (command !== void 0) return command.run(rest, opts);
882
- if (subcommand === void 0 || subcommand === "--help" || subcommand === "-h") {
883
- opts.stdout(usage());
884
- return 0;
880
+ try {
881
+ const [subcommand, ...rest] = opts.argv;
882
+ const command = commands.find((candidate) => candidate.names.includes(subcommand ?? ""));
883
+ if (command !== void 0) return await command.run(rest, opts);
884
+ if (subcommand === void 0 || subcommand === "--help" || subcommand === "-h") {
885
+ opts.stdout(usage());
886
+ return 0;
887
+ }
888
+ opts.stderr(usage());
889
+ return 2;
890
+ } catch (err) {
891
+ opts.stderr(formatCliError(err) + "\n");
892
+ return 1;
885
893
  }
886
- opts.stderr(usage());
887
- return 2;
888
894
  }
889
895
  //#endregion
890
896
  //#region bin/cli.ts
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli/key-io.ts","../src/cli/codec-options.ts","../src/cli/constants.ts","../src/cli/flags.ts","../src/cli/format.ts","../src/cli/variants.ts","../src/cli/dispatch.ts","../src/cli/usage.ts","../src/cli/commands/generate.ts","../src/cli/commands/inspect.ts","../src/cli/commands/keygen.ts","../src/cli/index.ts","../bin/cli.ts"],"sourcesContent":["import type { RunOpts } from \"./types.js\";\n\nexport type KeyFormat = \"hex\" | \"base64url\";\n\nexport type LoadKeyError = { kind: \"missing\" | \"import-failure\"; message: string };\n\nexport function isLoadKeyError(value: unknown): value is LoadKeyError {\n if (typeof value !== \"object\" || value === null) return false;\n const kind = (value as Record<string, unknown>).kind;\n return kind === \"missing\" || kind === \"import-failure\";\n}\n\nexport type KeyFacet<K> = {\n envVar: string;\n formatEnvVar: string;\n // Not yet consumed by any helper here; the keygen-delegation chunk wires it.\n encode: (bytes: Uint8Array, format: KeyFormat) => string;\n decode: (raw: string, format: KeyFormat) => Uint8Array;\n import: (bytes: Uint8Array) => K | Promise<K>;\n};\n\nexport function isKeyFormatError(result: KeyFormat | string): result is string {\n return result !== \"hex\" && result !== \"base64url\";\n}\n\nfunction parseKeyFormatFlag(values: Map<string, string>): KeyFormat | string | undefined {\n const fromFlag = values.get(\"--key-format\");\n if (fromFlag === undefined) return undefined;\n if (fromFlag === \"\") return \"--key-format requires a value\";\n if (fromFlag === \"hex\" || fromFlag === \"base64url\") return fromFlag;\n return `--key-format must be hex or base64url, got '${fromFlag}'`;\n}\n\nexport function parseKeyFormatFromFlag(values: Map<string, string>): KeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag === undefined) return \"hex\";\n return fromFlag;\n}\n\nexport function parseKeyFormat(\n values: Map<string, string>,\n opts: RunOpts,\n facet: Pick<KeyFacet<unknown>, \"formatEnvVar\">,\n): KeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag !== undefined) return fromFlag;\n const env = opts.env ?? process.env;\n const fromEnv = env[facet.formatEnvVar];\n if (fromEnv === undefined || fromEnv === \"\") return \"hex\";\n if (fromEnv === \"hex\" || fromEnv === \"base64url\") return fromEnv;\n return `${facet.formatEnvVar} must be hex or base64url, got '${fromEnv}'`;\n}\n\nexport async function loadKey<K>(\n opts: RunOpts,\n format: KeyFormat,\n facet: Pick<KeyFacet<K>, \"envVar\" | \"decode\" | \"import\">,\n): Promise<K | LoadKeyError> {\n const env = opts.env ?? process.env;\n const raw = env[facet.envVar];\n if (raw === undefined || raw === \"\") {\n return { kind: \"missing\", message: `missing ${facet.envVar} environment variable` };\n }\n try {\n return await facet.import(facet.decode(raw, format));\n } catch (err) {\n return { kind: \"import-failure\", message: (err as Error).message };\n }\n}\n","import type { TimestampOptions } from \"../codecs/timestamp/index.js\";\nimport type { RunOpts } from \"./types.js\";\n\nexport function codecOpts(opts: RunOpts): Partial<TimestampOptions> {\n // CLI invocations are intentionally ephemeral: one codec per run, never\n // retained, so this is not the duplicate-brand warning case.\n const o: Partial<TimestampOptions> = { allowDuplicateBrand: true };\n if (opts.now !== undefined) o.now = opts.now;\n if (opts.rng !== undefined) o.rng = opts.rng;\n return o;\n}\n","export const maxGenerateCount = 10_000;\n","import { maxGenerateCount } from \"./constants.js\";\n\nexport type ParsedFlags = {\n flags: Set<string>;\n values: Map<string, string>;\n positionals: string[];\n errors: string[];\n};\n\nfunction splitFlagToken(arg: string): { flag: string; inlineValue: string | undefined } {\n const eq = arg.indexOf(\"=\");\n if (eq <= 0) return { flag: arg, inlineValue: undefined };\n return { flag: arg.slice(0, eq), inlineValue: arg.slice(eq + 1) };\n}\n\nexport function splitFlags(args: ReadonlyArray<string>, valueFlags: Set<string>): ParsedFlags {\n const flags = new Set<string>();\n const values = new Map<string, string>();\n const positionals: string[] = [];\n const errors: string[] = [];\n const seenFlags = new Set<string>();\n const addFlag = (flag: string) => {\n const canonical = canonicalFlag(flag);\n if (seenFlags.has(canonical)) errors.push(`duplicate flag: ${canonical}`);\n seenFlags.add(canonical);\n flags.add(flag);\n };\n for (let i = 0; i < args.length; i++) {\n const raw = args[i]!;\n const { flag, inlineValue } = splitFlagToken(raw);\n if (valueFlags.has(flag)) {\n if (inlineValue !== undefined) {\n addFlag(flag);\n values.set(flag, inlineValue);\n continue;\n }\n const value = args[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n addFlag(flag);\n values.set(flag, \"\");\n continue;\n }\n addFlag(flag);\n values.set(flag, value);\n i++;\n continue;\n }\n if (flag.startsWith(\"-\")) {\n addFlag(flag);\n if (inlineValue !== undefined) errors.push(`flag does not take a value: ${flag}`);\n continue;\n }\n positionals.push(raw);\n }\n return { flags, values, positionals, errors };\n}\n\nfunction canonicalFlag(flag: string): string {\n if (flag === \"-c\") return \"--count\";\n return flag;\n}\n\nconst knownFlags = new Set([\n \"--opaque\",\n \"--wrapped\",\n \"--reverse\",\n \"--signed\",\n \"--digest\",\n \"--ns\",\n \"--kind\",\n \"--key-format\",\n \"--count\",\n \"-c\",\n \"--bits\",\n]);\n\nexport function unsupportedFlagForCommand(\n command: string,\n flags: Set<string>,\n allowed: Set<string>,\n): string | undefined {\n for (const flag of flags) {\n if (!allowed.has(flag)) {\n return knownFlags.has(flag)\n ? `unsupported flag for ${command}: ${flag}`\n : `unsupported flag: ${flag}`;\n }\n }\n return undefined;\n}\n\nexport function parseCount(values: Map<string, string>): number | string {\n const raw = values.get(\"--count\") ?? values.get(\"-c\");\n if (raw === undefined) return 1;\n if (raw === \"\") return \"--count requires a value\";\n if (!/^[1-9][0-9]*$/.test(raw)) return `--count must be a positive integer, got '${raw}'`;\n const count = Number.parseInt(raw, 10);\n if (!Number.isSafeInteger(count) || count > maxGenerateCount) {\n return `--count must be at most ${maxGenerateCount}, got '${raw}'`;\n }\n return count;\n}\n\nexport function parseBits(values: Map<string, string>): number | string {\n const raw = values.get(\"--bits\");\n if (raw === undefined) return 256;\n if (raw === \"\") return \"--bits requires a value\";\n if (raw === \"128\") return 128;\n if (raw === \"192\") return 192;\n if (raw === \"256\") return 256;\n return `--bits must be 128, 192, or 256, got '${raw}'`;\n}\n\nexport type WrappedKindValue = \"u32\" | \"i32\" | \"u64\" | \"i64\";\n\nexport function parseKind(values: Map<string, string>): WrappedKindValue | string | undefined {\n const raw = values.get(\"--kind\");\n if (raw === undefined) return undefined;\n if (raw === \"\") return \"--kind requires a value\";\n if (raw === \"u32\" || raw === \"i32\" || raw === \"u64\" || raw === \"i64\") return raw;\n return `--kind must be u32, i32, u64, or i64, got '${raw}'`;\n}\n\nexport function isKindError(result: WrappedKindValue | string): result is string {\n return result !== \"u32\" && result !== \"i32\" && result !== \"u64\" && result !== \"i64\";\n}\n\nexport function parseNs(values: Map<string, string>): string | undefined {\n const raw = values.get(\"--ns\");\n if (raw === undefined) return undefined;\n if (raw === \"\") return \"--ns requires a value\";\n return raw;\n}\n\nexport function isNsError(result: string): boolean {\n return result === \"--ns requires a value\";\n}\n","import { isIdsError } from \"../error.js\";\nimport type { Id } from \"../types.js\";\n\ntype InspectOutput = {\n brand: string;\n timestamp: Date;\n canonical: Id<string>;\n input: string;\n nowMs: number;\n};\n\ntype SignedInspectOutput = InspectOutput & {\n verification: \"ok\" | \"failed\" | \"unavailable\";\n};\n\ntype WrappedInspectOutput = {\n brand: string;\n lookupKey: number | bigint;\n canonical: Id<string>;\n input: string;\n};\n\nexport function formatCliError(err: unknown): string {\n return isIdsError(err)\n ? `${err.code}: ${err.message}`\n : err instanceof Error\n ? err.message\n : String(err);\n}\n\nexport function formatWrappedInspectOutput(result: WrappedInspectOutput): string {\n const inputLine = describeInputForm(result.input, result.canonical);\n return [\n `brand: ${result.brand}`,\n `lookup-key: ${result.lookupKey.toString()}`,\n `canonical: ${result.canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\");\n}\n\nexport function formatSignedInspectOutput(result: SignedInspectOutput): string {\n const relative = formatRelative(result.timestamp.getTime(), result.nowMs);\n const inputLine = describeInputForm(result.input, result.canonical);\n const lines = [\n `brand: ${result.brand}`,\n `timestamp: ${result.timestamp.toISOString()} (${relative})`,\n ];\n // \"verification:\" is the spec-mandated key name; the extra chars vs. other labels are intentional.\n lines.push(`verification: ${result.verification}`);\n lines.push(`canonical: ${result.canonical}`, `input: ${inputLine}`, \"\");\n return lines.join(\"\\n\");\n}\n\nexport function formatInspectOutput(result: InspectOutput): string {\n const relative = formatRelative(result.timestamp.getTime(), result.nowMs);\n const inputLine = describeInputForm(result.input, result.canonical);\n return [\n `brand: ${result.brand}`,\n `timestamp: ${result.timestamp.toISOString()} (${relative})`,\n `canonical: ${result.canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction describeInputForm(input: string, canonical: Id<string>): string {\n if (input === canonical) return \"canonical\";\n const notes: string[] = [];\n if (input !== input.toLowerCase()) notes.push(\"was uppercase\");\n if (/[ilo]/i.test(input.slice(4))) notes.push(\"used Crockford aliases\");\n return `not canonical (${notes.join(\" + \")})`;\n}\n\nconst msPerSecond = 1000;\nexport const msPerMinute: number = 60 * msPerSecond;\nexport const msPerHour: number = 60 * msPerMinute;\nexport const msPerDay: number = 24 * msPerHour;\nconst daysPerMonth = 30.44;\nconst monthsPerYear = 12;\n\nfunction formatRelative(thenMs: number, nowMs: number): string {\n const diff = nowMs - thenMs;\n const abs = Math.abs(diff);\n const suffix = diff < 0 ? \"from now\" : \"ago\";\n\n const head = headUnits(abs);\n return head === \"\" ? \"just now\" : `${head} ${suffix}`;\n}\n\nfunction headUnits(abs: number): string {\n if (abs < msPerMinute) return \"\";\n if (abs < msPerHour) return unit(Math.round(abs / msPerMinute), \"minute\");\n if (abs < msPerDay) return unit(Math.round(abs / msPerHour), \"hour\");\n if (abs < msPerDay * daysPerMonth) return unit(Math.round(abs / msPerDay), \"day\");\n\n const totalMonths = Math.round(abs / (msPerDay * daysPerMonth));\n if (totalMonths < monthsPerYear) return unit(totalMonths, \"month\");\n\n const years = Math.floor(totalMonths / monthsPerYear);\n const months = totalMonths % monthsPerYear;\n return months === 0 ? unit(years, \"year\") : `${unit(years, \"year\")} ${unit(months, \"month\")}`;\n}\n\nfunction unit(n: number, name: string): string {\n return `${n} ${n === 1 ? name : `${name}s`}`;\n}\n","import {\n createDigestId,\n decodeDigestKey,\n encodeDigestKey,\n importDigestKey,\n type DigestKey,\n} from \"../codecs/digest/index.js\";\nimport {\n createOpaqueTimestampId,\n decodeOpaqueKey,\n encodeOpaqueKey,\n importOpaqueKey,\n type OpaqueKey,\n} from \"../codecs/opaque/index.js\";\nimport { createReverseTimestampId } from \"../codecs/reverse/index.js\";\nimport {\n createSignedTimestampId,\n decodeSigningKey,\n encodeSigningKey,\n importSigningKey,\n type SigningKey,\n} from \"../codecs/signed/index.js\";\nimport { createTimestampId } from \"../codecs/timestamp/index.js\";\nimport {\n createWrappedKeyId,\n decodeWrappingKey,\n encodeWrappingKey,\n importWrappingKey,\n type WrappingKey,\n} from \"../codecs/wrapped/index.js\";\nimport type { IdCodec } from \"../adapters/adapter-types.js\";\nimport type { SafeVerifyResult } from \"../codecs/signed/index.js\";\nimport type { Id, StandardSchemaProps } from \"../types.js\";\nimport { codecOpts } from \"./codec-options.js\";\nimport { isKindError, isNsError, parseKind, parseNs } from \"./flags.js\";\nimport { formatCliError } from \"./format.js\";\nimport type { KeyFacet } from \"./key-io.js\";\nimport type { RunOpts } from \"./types.js\";\n\ntype InspectCapability =\n | {\n readonly mode: \"readable\";\n readonly note: string;\n validate(codec: IdCodec<string>, input: string): { value: Id<string> } | { issue: string };\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Date;\n }\n | {\n readonly mode: \"keyed-readable\";\n readonly note: string;\n validate(codec: IdCodec<string>, input: string): { value: Id<string> } | { issue: string };\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Promise<Date>;\n }\n | {\n readonly mode: \"unwrap\";\n validate(codec: IdCodec<string>, input: string): { value: Id<string> } | { issue: string };\n unwrap(codec: IdCodec<string>, id: Id<string>): Promise<number | bigint>;\n }\n | {\n readonly mode: \"verify\";\n safeVerify(codec: IdCodec<string>, id: string): Promise<SafeVerifyResult<string>>;\n }\n | { readonly mode: \"unsupported\" };\n\nfunction standardValidate(\n codec: IdCodec<string>,\n input: string,\n): { value: Id<string> } | { issue: string } {\n const result = (codec as unknown as { \"~standard\": StandardSchemaProps<string> })[\n \"~standard\"\n ].validate(input);\n if (result.issues) return { issue: result.issues[0]!.message };\n return { value: result.value! };\n}\n\nexport type Descriptor = {\n flag?: string;\n key?: KeyFacet<unknown>;\n construct: (\n brand: string,\n opts: RunOpts,\n key?: unknown,\n values?: Map<string, string>,\n ) => (IdCodec<string> & { generate?(): string | Promise<string> }) | string;\n inspect: InspectCapability;\n extraFlags?: readonly string[];\n};\n\nexport type GeneratorDescriptor = {\n flag?: string;\n key?: KeyFacet<unknown>;\n construct: (\n brand: string,\n opts: RunOpts,\n key?: unknown,\n values?: Map<string, string>,\n ) => (IdCodec<string> & { generate(): string | Promise<string> }) | string;\n inspect: InspectCapability;\n extraFlags?: readonly string[];\n};\n\nexport type Policy<D extends Descriptor = Descriptor> = {\n default: D;\n selectable: readonly D[];\n intrinsicFlags: readonly string[];\n};\n\nexport type GeneratePolicy = Policy<GeneratorDescriptor>;\n\nexport const timestampVariant: GeneratorDescriptor = {\n inspect: {\n mode: \"readable\",\n note: \"note: timestamp assumes a plaintext Timestamp ID; if this ID was Opaque-encoded, the timestamp is meaningless — re-run with --opaque and the correct IDS_KEY\",\n validate: standardValidate,\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Date {\n return (codec as unknown as { extractTimestamp(id: Id<string>): Date }).extractTimestamp(id);\n },\n },\n construct(brand, opts) {\n try {\n return createTimestampId(brand, codecOpts(opts));\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const opaqueVariant: GeneratorDescriptor = {\n flag: \"--opaque\",\n key: {\n envVar: \"IDS_KEY\",\n formatEnvVar: \"IDS_KEY_FORMAT\",\n encode: encodeOpaqueKey,\n decode: decodeOpaqueKey,\n import: importOpaqueKey,\n },\n inspect: {\n mode: \"keyed-readable\",\n note: \"note: timestamp assumes IDS_KEY matches the key used at generation; a wrong key yields a plausible but incorrect timestamp\",\n validate: standardValidate,\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Promise<Date> {\n return (\n codec as unknown as { extractTimestamp(id: Id<string>): Promise<Date> }\n ).extractTimestamp(id);\n },\n },\n construct(brand, opts, key) {\n try {\n return createOpaqueTimestampId(brand, { key: key as OpaqueKey, ...codecOpts(opts) });\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const reverseVariant: GeneratorDescriptor = {\n flag: \"--reverse\",\n inspect: {\n mode: \"readable\",\n note: \"note: timestamp assumes a plaintext Timestamp ID; if this ID was Opaque-encoded, the timestamp is meaningless — re-run with --opaque and the correct IDS_KEY\",\n validate: standardValidate,\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Date {\n return (codec as unknown as { extractTimestamp(id: Id<string>): Date }).extractTimestamp(id);\n },\n },\n construct(brand, opts) {\n try {\n return createReverseTimestampId(brand, codecOpts(opts));\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const wrappedVariant: Descriptor = {\n flag: \"--wrapped\",\n key: {\n envVar: \"IDS_WRAPPING_KEY\",\n formatEnvVar: \"IDS_WRAPPING_KEY_FORMAT\",\n encode: encodeWrappingKey,\n decode: decodeWrappingKey,\n import: importWrappingKey,\n },\n inspect: {\n mode: \"unwrap\",\n validate: standardValidate,\n unwrap(codec: IdCodec<string>, id: Id<string>): Promise<number | bigint> {\n return (codec as unknown as { unwrap(id: Id<string>): Promise<number | bigint> }).unwrap(id);\n },\n },\n extraFlags: [\"--kind\"],\n construct(brand, _opts, key, values) {\n const kind = parseKind(values ?? new Map());\n if (kind === undefined) return \"--kind is required with --wrapped\";\n if (isKindError(kind)) return kind;\n try {\n return createWrappedKeyId(brand, {\n kind,\n keys: [key as WrappingKey],\n allowDuplicateBrand: true,\n });\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const signedVariant: GeneratorDescriptor = {\n flag: \"--signed\",\n key: {\n envVar: \"IDS_SIGNING_KEY\",\n formatEnvVar: \"IDS_SIGNING_KEY_FORMAT\",\n encode: encodeSigningKey,\n decode: decodeSigningKey,\n import: importSigningKey,\n },\n inspect: {\n mode: \"verify\",\n safeVerify(codec: IdCodec<string>, id: string): Promise<SafeVerifyResult<string>> {\n return (\n codec as unknown as { safeVerify(id: string): Promise<SafeVerifyResult<string>> }\n ).safeVerify(id);\n },\n },\n construct(brand, opts, key) {\n try {\n return createSignedTimestampId(brand, {\n keys: [key as SigningKey],\n ...codecOpts(opts),\n });\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const digestVariant: GeneratorDescriptor = {\n flag: \"--digest\",\n key: {\n envVar: \"IDS_DIGEST_KEY\",\n formatEnvVar: \"IDS_DIGEST_KEY_FORMAT\",\n encode: encodeDigestKey,\n decode: decodeDigestKey,\n import: importDigestKey,\n },\n // Digest is one-way: inspect --digest is unsupported by design, so digestVariant is omitted\n // from inspectPolicy.selectable. \"unsupported\" documents that there is no inspect path.\n inspect: { mode: \"unsupported\" },\n extraFlags: [\"--ns\"],\n construct(brand, opts, key, values) {\n const ns = parseNs(values ?? new Map());\n if (ns === undefined) return \"--ns is required with --digest\";\n if (isNsError(ns)) return ns;\n try {\n const codec = createDigestId(brand, { ns, key: key as DigestKey, allowDuplicateBrand: true });\n return {\n safeParse: (v: unknown) => codec.safeParse(v),\n async generate(): Promise<string> {\n const reader = opts.readStdin ?? (() => Promise.resolve(\"\"));\n const material = await reader();\n return codec.digest(material);\n },\n };\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\n// Determines which flag name appears first in \"cannot use --A and --B together\"\n// messages when two selectable variant flags conflict. Signed always leads;\n// remaining follow registry insertion order (digest, reverse, wrapped, opaque).\nexport const conflictPriorityOrder: readonly Descriptor[] = [\n signedVariant,\n digestVariant,\n reverseVariant,\n wrappedVariant,\n opaqueVariant,\n];\n\nexport const generatePolicy: GeneratePolicy = {\n default: timestampVariant,\n selectable: [opaqueVariant, reverseVariant, signedVariant, digestVariant],\n intrinsicFlags: [\"--count\", \"-c\"],\n};\n\nexport const inspectPolicy: Policy = {\n default: timestampVariant,\n selectable: [reverseVariant, wrappedVariant, opaqueVariant, signedVariant],\n intrinsicFlags: [],\n};\n\nexport const keygenPolicy: Policy = {\n default: opaqueVariant,\n selectable: [wrappedVariant, signedVariant, digestVariant],\n intrinsicFlags: [\"--bits\"],\n};\n","import type { IdCodec } from \"../adapters/adapter-types.js\";\nimport { isKeyFormatError, isLoadKeyError, loadKey, parseKeyFormat } from \"./key-io.js\";\nimport type { RunOpts } from \"./types.js\";\nimport {\n conflictPriorityOrder,\n type Descriptor,\n type GeneratorDescriptor,\n type Policy,\n} from \"./variants.js\";\n\nexport type CodecError = { kind: \"usage\"; message: string } | { kind: \"runtime\"; message: string };\n\nexport function isCodecError(v: unknown): v is CodecError {\n if (typeof v !== \"object\" || v === null) return false;\n const kind = (v as Record<string, unknown>).kind;\n return (kind === \"usage\" || kind === \"runtime\") && \"message\" in v;\n}\n\nexport function deriveAllowedFlags(policy: Policy): Set<string> {\n const flags = new Set<string>(policy.intrinsicFlags);\n let hasKeyed = policy.default.key !== undefined;\n for (const v of policy.selectable) {\n if (v.flag !== undefined) flags.add(v.flag);\n if (v.key !== undefined) hasKeyed = true;\n if (v.extraFlags !== undefined) {\n for (const f of v.extraFlags) flags.add(f);\n }\n }\n if (hasKeyed) flags.add(\"--key-format\");\n return flags;\n}\n\nexport function resolveVariant<D extends Descriptor>(\n policy: Policy<D>,\n flags: Set<string>,\n): D | string {\n const selected = conflictPriorityOrder.filter(\n (v): v is D =>\n policy.selectable.some((d) => d === v) && v.flag !== undefined && flags.has(v.flag),\n );\n if (selected.length === 0) return policy.default;\n if (selected.length === 1) return selected[0]!;\n return `cannot use ${selected[0]!.flag} and ${selected[1]!.flag} together`;\n}\n\nexport async function buildCodec(\n variant: GeneratorDescriptor,\n brand: string,\n values: Map<string, string>,\n opts: RunOpts,\n): Promise<(IdCodec<string> & { generate(): string | Promise<string> }) | CodecError>;\nexport async function buildCodec(\n variant: Descriptor,\n brand: string,\n values: Map<string, string>,\n opts: RunOpts,\n): Promise<IdCodec<string> | CodecError>;\nexport async function buildCodec(\n variant: Descriptor,\n brand: string,\n values: Map<string, string>,\n opts: RunOpts,\n): Promise<(IdCodec<string> & { generate?(): string | Promise<string> }) | CodecError> {\n let key: unknown;\n if (variant.key !== undefined) {\n const format = parseKeyFormat(values, opts, variant.key);\n if (isKeyFormatError(format)) return { kind: \"usage\", message: format };\n const keyResult = await loadKey(opts, format, variant.key);\n if (isLoadKeyError(keyResult)) {\n return {\n kind: keyResult.kind === \"missing\" ? \"usage\" : \"runtime\",\n message: keyResult.message,\n };\n }\n key = keyResult;\n }\n const codecOrError = variant.construct(brand, opts, key, values);\n if (typeof codecOrError === \"string\") {\n return {\n kind: codecOrError.startsWith(\"--\") ? \"usage\" : \"runtime\",\n message: codecOrError,\n };\n }\n return codecOrError;\n}\n","import { maxGenerateCount } from \"./constants.js\";\n\nexport function usageInspect(): string {\n return [\n \"Usage: ids inspect, i <id> [--opaque] [--wrapped --kind u32|i32|u64|i64] [--reverse] [--signed] [--key-format hex|base64url]\",\n \"\",\n \" Decode an ID and print brand, timestamp (or lookup key), and canonical form.\",\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format).\",\n \" --kind is required with --wrapped: u32, i32, u64, or i64.\",\n \" --reverse decodes a Reverse Timestamp ID (newest-first sort order).\",\n \" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" Without IDS_SIGNING_KEY, --signed prints the timestamp only (no verification). With IDS_SIGNING_KEY, prints verification: ok or failed.\",\n \" Note: --digest is not supported for inspect (Digest IDs are one-way; there is no reverse path).\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function usageGenerate(): string {\n return [\n `Usage: ids generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--key-format hex|base64url]`,\n \"\",\n ` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --reverse mints Reverse Timestamp IDs (newest-first sort order).\",\n \" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest mints a deterministic Digest ID from material read on stdin.\",\n \" --ns <ns> is required: the namespace domain separator (non-secret, non-empty).\",\n \" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \" Same material + ns + key always produces the same ID. Digest IDs are one-way.\",\n \" --count N > 1 is rejected: same material always produces the same ID.\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function usageKeygen(): string {\n return [\n \"Usage: ids keygen, k [--wrapped] [--signed] [--digest] [--bits 128|192|256] [--key-format hex|base64url]\",\n \"\",\n \" Emit a random key for importOpaqueKey, importWrappingKey, importSigningKey, or importDigestKey (stdout only).\",\n \" --wrapped emits a wrapping key for importWrappingKey instead (IDS_WRAPPING_KEY).\",\n \" --signed emits a signing key for importSigningKey instead (IDS_SIGNING_KEY; hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest emits a digest key for importDigestKey instead (IDS_DIGEST_KEY; hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function usage(): string {\n return [\n \"Usage: ids <subcommand> [args]\",\n \"\",\n \"Subcommands:\",\n \" inspect, i <id> [--opaque] [--wrapped --kind u32|i32|u64|i64] [--reverse] [--signed] [--key-format hex|base64url]\",\n \" Decode an ID and print brand, timestamp (or lookup key), and canonical form.\",\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format).\",\n \" --kind is required with --wrapped: u32, i32, u64, or i64.\",\n \" --reverse decodes a Reverse Timestamp ID (newest-first sort order).\",\n \" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" Without IDS_SIGNING_KEY, --signed prints the timestamp only (no verification). With IDS_SIGNING_KEY, prints verification: ok or failed.\",\n \" Note: --digest is not supported for inspect (Digest IDs are one-way; there is no reverse path).\",\n \" generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--key-format hex|base64url]\",\n ` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --reverse mints Reverse Timestamp IDs (newest-first sort order).\",\n \" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest mints a deterministic Digest ID from material read on stdin.\",\n \" --ns <ns> is required: the namespace domain separator (non-secret, non-empty).\",\n \" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \" Same material + ns + key always produces the same ID. Digest IDs are one-way.\",\n \" --count N > 1 is rejected: same material always produces the same ID.\",\n \" keygen, k [--wrapped] [--signed] [--digest] [--bits 128|192|256] [--key-format hex|base64url]\",\n \" Emit a random key for importOpaqueKey, importWrappingKey, importSigningKey, or importDigestKey (key on stdout; warning on stderr).\",\n \" Safe handling: redirect stdout to a 0600 file (e.g. ids keygen > key.hex && chmod 0600 key.hex);\",\n \" do not let the key appear in shell history or CI logs. A warning is printed to stderr on every run.\",\n \" --wrapped emits a wrapping key for importWrappingKey instead (IDS_WRAPPING_KEY).\",\n \" --signed emits a signing key for importSigningKey instead (IDS_SIGNING_KEY; hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest emits a digest key for importDigestKey instead (IDS_DIGEST_KEY; hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \"\",\n \"Exit codes:\",\n \" 0 Success\",\n \" 1 Runtime/operational error (codec failure, bad key material, verification failure)\",\n \" 2 Usage/argument error (unknown subcommand, unrecognised flag, bad flag value, missing required arg)\",\n \"\",\n ].join(\"\\n\");\n}\n","import { buildCodec, deriveAllowedFlags, isCodecError, resolveVariant } from \"../dispatch.js\";\nimport { parseCount, splitFlags, unsupportedFlagForCommand } from \"../flags.js\";\nimport type { RunOpts } from \"../types.js\";\nimport { usageGenerate } from \"../usage.js\";\nimport { generatePolicy } from \"../variants.js\";\n\nlet stdinCache: Promise<string> | undefined;\n/* v8 ignore next 12 -- reads from process.stdin; not exercised in unit tests, only in the real binary */\nfunction readProcessStdin(): Promise<string> {\n if (stdinCache === undefined) {\n stdinCache = new Promise<string>((resolve) => {\n const chunks: string[] = [];\n process.stdin.setEncoding(\"utf8\");\n process.stdin.on(\"data\", (chunk: string) => chunks.push(chunk));\n process.stdin.on(\"end\", () => resolve(chunks.join(\"\")));\n process.stdin.resume();\n });\n }\n return stdinCache;\n}\n\nexport async function runGenerate(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n opts.stdout(usageGenerate());\n return 0;\n }\n const allowedFlags = deriveAllowedFlags(generatePolicy);\n const selectorFlags = new Set(\n generatePolicy.selectable.map((v) => v.flag).filter((f): f is string => f !== undefined),\n );\n const valueFlags = new Set([...allowedFlags].filter((f) => !selectorFlags.has(f)));\n const { flags, values, positionals, errors } = splitFlags(args, valueFlags);\n const unsupported = unsupportedFlagForCommand(\"generate\", flags, allowedFlags);\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return 2;\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return 2;\n }\n const extra = positionals[1];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return 2;\n }\n const [brand] = positionals;\n const count = parseCount(values);\n if (typeof count === \"string\") {\n opts.stderr(count + \"\\n\");\n return 2;\n }\n const variant = resolveVariant(generatePolicy, flags);\n if (typeof variant === \"string\") {\n opts.stderr(variant + \"\\n\");\n return 2;\n }\n if (variant.key === undefined && flags.has(\"--key-format\")) {\n opts.stderr(\"--key-format requires --opaque, --signed, or --digest\\n\");\n return 2;\n }\n if (flags.has(\"--digest\") && count > 1) {\n opts.stderr(\n \"--count N > 1 is rejected with --digest: same material always produces the same ID\\n\",\n );\n return 2;\n }\n const optsWithStdin: RunOpts = { ...opts, readStdin: opts.readStdin ?? readProcessStdin };\n const codec = await buildCodec(variant, brand ?? \"\", values, optsWithStdin);\n if (isCodecError(codec)) {\n opts.stderr(codec.message + \"\\n\");\n return codec.kind === \"usage\" ? 2 : 1;\n }\n for (let i = 0; i < count; i++) opts.stdout((await codec.generate()) + \"\\n\");\n return 0;\n}\n","import { createTimestampId, type TimestampCodec } from \"../../codecs/timestamp/index.js\";\nimport type { Id } from \"../../types.js\";\nimport { codecOpts } from \"../codec-options.js\";\nimport { buildCodec, deriveAllowedFlags, isCodecError, resolveVariant } from \"../dispatch.js\";\nimport {\n formatCliError,\n formatInspectOutput,\n formatSignedInspectOutput,\n formatWrappedInspectOutput,\n} from \"../format.js\";\nimport { splitFlags, unsupportedFlagForCommand } from \"../flags.js\";\nimport { isKeyFormatError, parseKeyFormat } from \"../key-io.js\";\nimport type { RunOpts } from \"../types.js\";\nimport { usageInspect } from \"../usage.js\";\nimport { inspectPolicy } from \"../variants.js\";\n\nexport async function runInspect(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n opts.stdout(usageInspect());\n return 0;\n }\n const allowedFlags = deriveAllowedFlags(inspectPolicy);\n const selectorFlags = new Set(\n inspectPolicy.selectable.map((v) => v.flag).filter((f): f is string => f !== undefined),\n );\n const valueFlags = new Set([...allowedFlags].filter((f) => !selectorFlags.has(f)));\n const { flags, values, positionals, errors } = splitFlags(args, valueFlags);\n\n const unsupported = unsupportedFlagForCommand(\"inspect\", flags, allowedFlags);\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return 2;\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return 2;\n }\n const [input] = positionals;\n if (input === undefined) {\n opts.stderr(usageInspect());\n return 2;\n }\n const extra = positionals[1];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return 2;\n }\n\n const variant = resolveVariant(inspectPolicy, flags);\n if (typeof variant === \"string\") {\n opts.stderr(variant + \"\\n\");\n return 2;\n }\n if (variant.key === undefined && flags.has(\"--key-format\")) {\n opts.stderr(\"--key-format requires --opaque, --wrapped, or --signed\\n\");\n return 2;\n }\n\n const brand = input.slice(0, 3).toLowerCase();\n const cap = variant.inspect;\n\n // \"verify\" (--signed) mode: the timestamp is plaintext and must be extractable even when\n // the signing key is unavailable. Structural parse happens before key loading so that:\n // bad key format → stderr only, stdout = \"\" (no timestamp shown)\n // invalid payload → stderr only, stdout = \"\" (no timestamp shown)\n // key missing/malformed → stdout has timestamp + \"verification: unavailable\"\n let verifyTimestamp: Date | undefined;\n let verifyCanonical: Id<string> | undefined;\n let verifyNowMs: number | undefined;\n if (cap.mode === \"verify\") {\n const fmtCheck = parseKeyFormat(values, opts, variant.key!);\n if (isKeyFormatError(fmtCheck)) {\n opts.stderr(fmtCheck + \"\\n\");\n return 2;\n }\n let tsCodec: TimestampCodec<string>;\n try {\n tsCodec = createTimestampId(brand, codecOpts(opts));\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n const structValidation = tsCodec[\"~standard\"].validate(input);\n if (structValidation.issues) {\n opts.stderr(structValidation.issues[0]!.message + \"\\n\");\n return 1;\n }\n verifyCanonical = structValidation.value;\n verifyTimestamp = tsCodec.extractTimestamp(verifyCanonical);\n verifyNowMs = (opts.now ?? Date.now)();\n }\n\n const codecOrError = await buildCodec(variant, brand, values, opts);\n if (isCodecError(codecOrError)) {\n if (cap.mode === \"verify\") {\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyCanonical!,\n input,\n nowMs: verifyNowMs!,\n verification: \"unavailable\",\n }),\n );\n opts.stderr(codecOrError.message + \"\\n\");\n return 1;\n }\n opts.stderr(codecOrError.message + \"\\n\");\n return codecOrError.kind === \"usage\" ? 2 : 1;\n }\n\n // Structural validation for non-verify, non-unsupported cases\n let canonical: Id<string> | undefined;\n if (cap.mode !== \"verify\" && cap.mode !== \"unsupported\") {\n const parsed = cap.validate(codecOrError, input);\n if (\"issue\" in parsed) {\n opts.stderr(parsed.issue + \"\\n\");\n return 1;\n }\n canonical = parsed.value;\n }\n\n // Dispatch on capability mode for output shapes\n switch (cap.mode) {\n case \"readable\": {\n const timestamp = cap.extractTimestamp(codecOrError, canonical!);\n const nowMs = (opts.now ?? Date.now)();\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(formatInspectOutput({ brand, timestamp, canonical: canonical!, input, nowMs }));\n return 0;\n }\n case \"keyed-readable\": {\n const timestamp = await cap.extractTimestamp(codecOrError, canonical!);\n const nowMs = (opts.now ?? Date.now)();\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(formatInspectOutput({ brand, timestamp, canonical: canonical!, input, nowMs }));\n return 0;\n }\n case \"unwrap\": {\n let lookupKey: number | bigint;\n try {\n lookupKey = await cap.unwrap(codecOrError, canonical!);\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n opts.stdout(formatWrappedInspectOutput({ brand, lookupKey, canonical: canonical!, input }));\n return 0;\n }\n case \"verify\": {\n const verifyResult = await cap.safeVerify(codecOrError, input);\n if (!verifyResult.ok) {\n /* v8 ignore next 4 -- defensive: both codecs share the same wire parse so ParseError\n is unreachable after the createTimestampId pre-validation above passes */\n if (verifyResult.error !== \"verification_failed\") {\n opts.stderr(verifyResult.error + \"\\n\");\n return 1;\n }\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyCanonical!,\n input,\n nowMs: verifyNowMs!,\n verification: \"failed\",\n }),\n );\n opts.stderr(\"verification_failed: verification failed\\n\");\n return 1;\n }\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyResult.id,\n input,\n nowMs: verifyNowMs!,\n verification: \"ok\",\n }),\n );\n return 0;\n }\n /* v8 ignore next 5 -- defensive: digestVariant is the only \"unsupported\" variant and it is\n excluded from inspectPolicy.selectable, so resolveVariant can never return it here. The\n branch exists for TypeScript exhaustiveness. */\n case \"unsupported\": {\n opts.stderr(\"unsupported flag for inspect: --digest\\n\");\n return 1;\n }\n }\n}\n","import { deriveAllowedFlags, resolveVariant } from \"../dispatch.js\";\nimport { parseBits, splitFlags, unsupportedFlagForCommand } from \"../flags.js\";\nimport { isKeyFormatError, parseKeyFormatFromFlag } from \"../key-io.js\";\nimport type { RunOpts } from \"../types.js\";\nimport { usageKeygen } from \"../usage.js\";\nimport { keygenPolicy } from \"../variants.js\";\n\nexport async function runKeygen(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n opts.stdout(usageKeygen());\n return Promise.resolve(0);\n }\n const allowedFlags = deriveAllowedFlags(keygenPolicy);\n const variantExtraFlags = new Set(keygenPolicy.selectable.flatMap((v) => v.extraFlags ?? []));\n const { flags, values, positionals, errors } = splitFlags(args, allowedFlags);\n const unsupported = unsupportedFlagForCommand(\n \"keygen\",\n flags,\n new Set([...allowedFlags].filter((f) => !variantExtraFlags.has(f))),\n );\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return Promise.resolve(2);\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return Promise.resolve(2);\n }\n const extra = positionals[0];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return Promise.resolve(2);\n }\n const variant = resolveVariant(keygenPolicy, flags);\n if (typeof variant === \"string\") {\n opts.stderr(variant + \"\\n\");\n return Promise.resolve(2);\n }\n const bits = parseBits(values);\n if (typeof bits === \"string\") {\n opts.stderr(bits + \"\\n\");\n return Promise.resolve(2);\n }\n const format = parseKeyFormatFromFlag(values);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(2);\n }\n /* v8 ignore next 4 -- defensive guard; all keygenPolicy variants have key defined */\n if (variant.key === undefined) {\n opts.stderr(\"internal: keygen policy variant has no key facet\\n\");\n return Promise.resolve(1);\n }\n const bytes = new Uint8Array(bits / 8);\n crypto.getRandomValues(bytes);\n opts.stderr(\n \"Warning: secret key material — redirect to a file (chmod 0600) and avoid shell history.\\n\",\n );\n opts.stdout(variant.key.encode(bytes, format) + \"\\n\");\n return Promise.resolve(0);\n}\n","import { runGenerate } from \"./commands/generate.js\";\nimport { runInspect } from \"./commands/inspect.js\";\nimport { runKeygen } from \"./commands/keygen.js\";\nimport type { CommandHandler, RunOpts } from \"./types.js\";\nimport { usage } from \"./usage.js\";\n\nexport type { RunOpts } from \"./types.js\";\n\ntype Command = {\n names: ReadonlyArray<string>;\n run: CommandHandler;\n};\n\nconst commands: ReadonlyArray<Command> = [\n { names: [\"generate\", \"g\"], run: runGenerate },\n { names: [\"inspect\", \"i\"], run: runInspect },\n { names: [\"keygen\", \"k\"], run: runKeygen },\n];\n\nexport async function run(opts: RunOpts): Promise<number> {\n const [subcommand, ...rest] = opts.argv;\n const command = commands.find((candidate) => candidate.names.includes(subcommand ?? \"\"));\n if (command !== undefined) return command.run(rest, opts);\n if (subcommand === undefined || subcommand === \"--help\" || subcommand === \"-h\") {\n opts.stdout(usage());\n return 0;\n }\n opts.stderr(usage());\n return 2;\n}\n","#!/usr/bin/env node\nimport { run } from \"../src/cli/index.js\";\n\nprocess.exitCode = await run({\n argv: process.argv.slice(2),\n stdout: (s) => process.stdout.write(s),\n stderr: (s) => process.stderr.write(s),\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli/format.ts","../src/cli/key-io.ts","../src/cli/codec-options.ts","../src/cli/constants.ts","../src/cli/flags.ts","../src/cli/variants.ts","../src/cli/dispatch.ts","../src/cli/usage.ts","../src/cli/commands/generate.ts","../src/cli/commands/inspect.ts","../src/cli/commands/keygen.ts","../src/cli/index.ts","../bin/cli.ts"],"sourcesContent":["import { isIdsError } from \"../error.js\";\nimport type { Id } from \"../types.js\";\n\ntype InspectOutput = {\n brand: string;\n timestamp: Date;\n canonical: Id<string>;\n input: string;\n nowMs: number;\n};\n\ntype SignedInspectOutput = InspectOutput & {\n verification: \"ok\" | \"failed\" | \"unavailable\";\n};\n\ntype WrappedInspectOutput = {\n brand: string;\n lookupKey: number | bigint;\n canonical: Id<string>;\n input: string;\n};\n\nexport const invalidIdPrefix = \"invalid_id: \";\n\nexport function formatCliError(err: unknown): string {\n return isIdsError(err)\n ? `${err.code}: ${err.message}`\n : err instanceof Error\n ? err.message\n : String(err);\n}\n\nexport function formatWrappedInspectOutput(result: WrappedInspectOutput): string {\n const inputLine = describeInputForm(result.input, result.canonical);\n return [\n `brand: ${result.brand}`,\n `lookup-key: ${result.lookupKey.toString()}`,\n `canonical: ${result.canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\");\n}\n\nexport function formatSignedInspectOutput(result: SignedInspectOutput): string {\n const relative = formatRelative(result.timestamp.getTime(), result.nowMs);\n const inputLine = describeInputForm(result.input, result.canonical);\n const lines = [\n `brand: ${result.brand}`,\n `timestamp: ${result.timestamp.toISOString()} (${relative})`,\n ];\n // \"verification:\" is the spec-mandated key name; the extra chars vs. other labels are intentional.\n lines.push(`verification: ${result.verification}`);\n lines.push(`canonical: ${result.canonical}`, `input: ${inputLine}`, \"\");\n return lines.join(\"\\n\");\n}\n\nexport function formatInspectOutput(result: InspectOutput): string {\n const relative = formatRelative(result.timestamp.getTime(), result.nowMs);\n const inputLine = describeInputForm(result.input, result.canonical);\n return [\n `brand: ${result.brand}`,\n `timestamp: ${result.timestamp.toISOString()} (${relative})`,\n `canonical: ${result.canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction describeInputForm(input: string, canonical: Id<string>): string {\n if (input === canonical) return \"canonical\";\n const notes: string[] = [];\n if (input !== input.toLowerCase()) notes.push(\"was uppercase\");\n if (/[ilo]/i.test(input.slice(4))) notes.push(\"used Crockford aliases\");\n return `not canonical (${notes.join(\" + \")})`;\n}\n\nconst msPerSecond = 1000;\nexport const msPerMinute: number = 60 * msPerSecond;\nexport const msPerHour: number = 60 * msPerMinute;\nexport const msPerDay: number = 24 * msPerHour;\nconst daysPerMonth = 30.44;\nconst monthsPerYear = 12;\n\nfunction formatRelative(thenMs: number, nowMs: number): string {\n const diff = nowMs - thenMs;\n const abs = Math.abs(diff);\n const suffix = diff < 0 ? \"from now\" : \"ago\";\n\n const head = headUnits(abs);\n return head === \"\" ? \"just now\" : `${head} ${suffix}`;\n}\n\nfunction headUnits(abs: number): string {\n if (abs < msPerMinute) return \"\";\n if (abs < msPerHour) return unit(Math.round(abs / msPerMinute), \"minute\");\n if (abs < msPerDay) return unit(Math.round(abs / msPerHour), \"hour\");\n if (abs < msPerDay * daysPerMonth) return unit(Math.round(abs / msPerDay), \"day\");\n\n const totalMonths = Math.round(abs / (msPerDay * daysPerMonth));\n if (totalMonths < monthsPerYear) return unit(totalMonths, \"month\");\n\n const years = Math.floor(totalMonths / monthsPerYear);\n const months = totalMonths % monthsPerYear;\n return months === 0 ? unit(years, \"year\") : `${unit(years, \"year\")} ${unit(months, \"month\")}`;\n}\n\nfunction unit(n: number, name: string): string {\n return `${n} ${n === 1 ? name : `${name}s`}`;\n}\n","import { formatCliError } from \"./format.js\";\nimport type { RunOpts } from \"./types.js\";\n\nexport type KeyFormat = \"hex\" | \"base64url\";\n\nexport type LoadKeyError = { kind: \"missing\" | \"import-failure\"; message: string };\n\nexport function isLoadKeyError(value: unknown): value is LoadKeyError {\n if (typeof value !== \"object\" || value === null) return false;\n const kind = (value as Record<string, unknown>).kind;\n return kind === \"missing\" || kind === \"import-failure\";\n}\n\nexport type KeyFacet<K> = {\n envVar: string;\n formatEnvVar: string;\n // Not yet consumed by any helper here; the keygen-delegation chunk wires it.\n encode: (bytes: Uint8Array, format: KeyFormat) => string;\n decode: (raw: string, format: KeyFormat) => Uint8Array;\n import: (bytes: Uint8Array) => K | Promise<K>;\n};\n\nexport function isKeyFormatError(result: KeyFormat | string): result is string {\n return result !== \"hex\" && result !== \"base64url\";\n}\n\nfunction parseKeyFormatFlag(values: Map<string, string>): KeyFormat | string | undefined {\n const fromFlag = values.get(\"--key-format\");\n if (fromFlag === undefined) return undefined;\n if (fromFlag === \"\") return \"--key-format requires a value\";\n if (fromFlag === \"hex\" || fromFlag === \"base64url\") return fromFlag;\n return `--key-format must be hex or base64url, got '${fromFlag}'`;\n}\n\nexport function parseKeyFormatFromFlag(values: Map<string, string>): KeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag === undefined) return \"hex\";\n return fromFlag;\n}\n\nexport function parseKeyFormat(\n values: Map<string, string>,\n opts: RunOpts,\n facet: Pick<KeyFacet<unknown>, \"formatEnvVar\">,\n): KeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag !== undefined) return fromFlag;\n const env = opts.env ?? process.env;\n const fromEnv = env[facet.formatEnvVar];\n if (fromEnv === undefined || fromEnv === \"\") return \"hex\";\n if (fromEnv === \"hex\" || fromEnv === \"base64url\") return fromEnv;\n return `${facet.formatEnvVar} must be hex or base64url, got '${fromEnv}'`;\n}\n\nexport async function loadKey<K>(\n opts: RunOpts,\n format: KeyFormat,\n facet: Pick<KeyFacet<K>, \"envVar\" | \"decode\" | \"import\">,\n): Promise<K | LoadKeyError> {\n const env = opts.env ?? process.env;\n const raw = env[facet.envVar];\n if (raw === undefined || raw === \"\") {\n return { kind: \"missing\", message: `missing ${facet.envVar} environment variable` };\n }\n try {\n return await facet.import(facet.decode(raw, format));\n } catch (err) {\n return { kind: \"import-failure\", message: formatCliError(err) };\n }\n}\n","import type { TimestampOptions } from \"../codecs/timestamp/index.js\";\nimport type { RunOpts } from \"./types.js\";\n\nexport function codecOpts(opts: RunOpts): Partial<TimestampOptions> {\n // CLI invocations are intentionally ephemeral: one codec per run, never\n // retained, so this is not the duplicate-brand warning case.\n const o: Partial<TimestampOptions> = { allowDuplicateBrand: true };\n if (opts.now !== undefined) o.now = opts.now;\n if (opts.rng !== undefined) o.rng = opts.rng;\n return o;\n}\n","export const maxGenerateCount = 10_000;\n","import { maxGenerateCount } from \"./constants.js\";\n\nexport type ParsedFlags = {\n flags: Set<string>;\n values: Map<string, string>;\n positionals: string[];\n errors: string[];\n};\n\nfunction splitFlagToken(arg: string): { flag: string; inlineValue: string | undefined } {\n const eq = arg.indexOf(\"=\");\n if (eq <= 0) return { flag: arg, inlineValue: undefined };\n return { flag: arg.slice(0, eq), inlineValue: arg.slice(eq + 1) };\n}\n\nexport function splitFlags(args: ReadonlyArray<string>, valueFlags: Set<string>): ParsedFlags {\n const flags = new Set<string>();\n const values = new Map<string, string>();\n const positionals: string[] = [];\n const errors: string[] = [];\n const seenFlags = new Set<string>();\n const addFlag = (flag: string) => {\n const canonical = canonicalFlag(flag);\n if (seenFlags.has(canonical)) errors.push(`duplicate flag: ${canonical}`);\n seenFlags.add(canonical);\n flags.add(flag);\n };\n for (let i = 0; i < args.length; i++) {\n const raw = args[i]!;\n const { flag, inlineValue } = splitFlagToken(raw);\n if (valueFlags.has(flag)) {\n if (inlineValue !== undefined) {\n addFlag(flag);\n values.set(flag, inlineValue);\n continue;\n }\n const value = args[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n addFlag(flag);\n values.set(flag, \"\");\n continue;\n }\n addFlag(flag);\n values.set(flag, value);\n i++;\n continue;\n }\n if (flag.startsWith(\"-\")) {\n addFlag(flag);\n if (inlineValue !== undefined) errors.push(`flag does not take a value: ${flag}`);\n continue;\n }\n positionals.push(raw);\n }\n return { flags, values, positionals, errors };\n}\n\nfunction canonicalFlag(flag: string): string {\n if (flag === \"-c\") return \"--count\";\n return flag;\n}\n\nconst knownFlags = new Set([\n \"--opaque\",\n \"--wrapped\",\n \"--reverse\",\n \"--signed\",\n \"--digest\",\n \"--ns\",\n \"--kind\",\n \"--key-format\",\n \"--count\",\n \"-c\",\n \"--bits\",\n]);\n\nexport function unsupportedFlagForCommand(\n command: string,\n flags: Set<string>,\n allowed: Set<string>,\n): string | undefined {\n for (const flag of flags) {\n if (!allowed.has(flag)) {\n return knownFlags.has(flag)\n ? `unsupported flag for ${command}: ${flag}`\n : `unsupported flag: ${flag}`;\n }\n }\n return undefined;\n}\n\nexport function parseCount(values: Map<string, string>): number | string {\n const raw = values.get(\"--count\") ?? values.get(\"-c\");\n if (raw === undefined) return 1;\n if (raw === \"\") return \"--count requires a value\";\n if (!/^[1-9][0-9]*$/.test(raw)) return `--count must be a positive integer, got '${raw}'`;\n const count = Number.parseInt(raw, 10);\n if (!Number.isSafeInteger(count) || count > maxGenerateCount) {\n return `--count must be at most ${maxGenerateCount}, got '${raw}'`;\n }\n return count;\n}\n\nexport function parseBits(values: Map<string, string>): number | string {\n const raw = values.get(\"--bits\");\n if (raw === undefined) return 256;\n if (raw === \"\") return \"--bits requires a value\";\n if (raw === \"128\") return 128;\n if (raw === \"192\") return 192;\n if (raw === \"256\") return 256;\n return `--bits must be 128, 192, or 256, got '${raw}'`;\n}\n\nexport type WrappedKindValue = \"u32\" | \"i32\" | \"u64\" | \"i64\";\n\nexport function parseKind(values: Map<string, string>): WrappedKindValue | string | undefined {\n const raw = values.get(\"--kind\");\n if (raw === undefined) return undefined;\n if (raw === \"\") return \"--kind requires a value\";\n if (raw === \"u32\" || raw === \"i32\" || raw === \"u64\" || raw === \"i64\") return raw;\n return `--kind must be u32, i32, u64, or i64, got '${raw}'`;\n}\n\nexport function isKindError(result: WrappedKindValue | string): result is string {\n return result !== \"u32\" && result !== \"i32\" && result !== \"u64\" && result !== \"i64\";\n}\n\nexport function parseNs(values: Map<string, string>): string | undefined {\n const raw = values.get(\"--ns\");\n if (raw === undefined) return undefined;\n if (raw === \"\") return \"--ns requires a value\";\n return raw;\n}\n\nexport function isNsError(result: string): boolean {\n return result === \"--ns requires a value\";\n}\n","import {\n createDigestId,\n decodeDigestKey,\n encodeDigestKey,\n importDigestKey,\n type DigestKey,\n} from \"../codecs/digest/index.js\";\nimport {\n createOpaqueTimestampId,\n decodeOpaqueKey,\n encodeOpaqueKey,\n importOpaqueKey,\n type OpaqueKey,\n} from \"../codecs/opaque/index.js\";\nimport { createReverseTimestampId } from \"../codecs/reverse/index.js\";\nimport {\n createSignedTimestampId,\n decodeSigningKey,\n encodeSigningKey,\n importSigningKey,\n type SigningKey,\n} from \"../codecs/signed/index.js\";\nimport { createTimestampId } from \"../codecs/timestamp/index.js\";\nimport {\n createWrappedKeyId,\n decodeWrappingKey,\n encodeWrappingKey,\n importWrappingKey,\n type WrappingKey,\n} from \"../codecs/wrapped/index.js\";\nimport type { IdCodec } from \"../adapters/adapter-types.js\";\nimport type { SafeVerifyResult } from \"../codecs/signed/index.js\";\nimport type { Id, StandardSchemaProps } from \"../types.js\";\nimport { codecOpts } from \"./codec-options.js\";\nimport { isKindError, isNsError, parseKind, parseNs } from \"./flags.js\";\nimport { formatCliError, invalidIdPrefix } from \"./format.js\";\nimport type { KeyFacet } from \"./key-io.js\";\nimport type { RunOpts } from \"./types.js\";\n\ntype InspectCapability =\n | {\n readonly mode: \"readable\";\n readonly note: string;\n validate(codec: IdCodec<string>, input: string): { value: Id<string> } | { issue: string };\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Date;\n }\n | {\n readonly mode: \"keyed-readable\";\n readonly note: string;\n validate(codec: IdCodec<string>, input: string): { value: Id<string> } | { issue: string };\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Promise<Date>;\n }\n | {\n readonly mode: \"unwrap\";\n validate(codec: IdCodec<string>, input: string): { value: Id<string> } | { issue: string };\n unwrap(codec: IdCodec<string>, id: Id<string>): Promise<number | bigint>;\n }\n | {\n readonly mode: \"verify\";\n safeVerify(codec: IdCodec<string>, id: string): Promise<SafeVerifyResult<string>>;\n }\n | { readonly mode: \"unsupported\" };\n\nfunction standardValidate(\n codec: IdCodec<string>,\n input: string,\n): { value: Id<string> } | { issue: string } {\n const result = (codec as unknown as { \"~standard\": StandardSchemaProps<string> })[\n \"~standard\"\n ].validate(input);\n if (result.issues) return { issue: invalidIdPrefix + result.issues[0]!.message };\n return { value: result.value! };\n}\n\nexport type Descriptor = {\n flag?: string;\n key?: KeyFacet<unknown>;\n construct: (\n brand: string,\n opts: RunOpts,\n key?: unknown,\n values?: Map<string, string>,\n ) => (IdCodec<string> & { generate?(): string | Promise<string> }) | string;\n inspect: InspectCapability;\n extraFlags?: readonly string[];\n};\n\nexport type GeneratorDescriptor = {\n flag?: string;\n key?: KeyFacet<unknown>;\n construct: (\n brand: string,\n opts: RunOpts,\n key?: unknown,\n values?: Map<string, string>,\n ) => (IdCodec<string> & { generate(): string | Promise<string> }) | string;\n inspect: InspectCapability;\n extraFlags?: readonly string[];\n};\n\nexport type Policy<D extends Descriptor = Descriptor> = {\n default: D;\n selectable: readonly D[];\n intrinsicFlags: readonly string[];\n};\n\nexport type GeneratePolicy = Policy<GeneratorDescriptor>;\n\nexport const timestampVariant: GeneratorDescriptor = {\n inspect: {\n mode: \"readable\",\n note: \"note: timestamp assumes a plaintext Timestamp ID; if this ID was Opaque-encoded, the timestamp is meaningless — re-run with --opaque and the correct IDS_KEY\",\n validate: standardValidate,\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Date {\n return (codec as unknown as { extractTimestamp(id: Id<string>): Date }).extractTimestamp(id);\n },\n },\n construct(brand, opts) {\n try {\n return createTimestampId(brand, codecOpts(opts));\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const opaqueVariant: GeneratorDescriptor = {\n flag: \"--opaque\",\n key: {\n envVar: \"IDS_KEY\",\n formatEnvVar: \"IDS_KEY_FORMAT\",\n encode: encodeOpaqueKey,\n decode: decodeOpaqueKey,\n import: importOpaqueKey,\n },\n inspect: {\n mode: \"keyed-readable\",\n note: \"note: timestamp assumes IDS_KEY matches the key used at generation; a wrong key yields a plausible but incorrect timestamp\",\n validate: standardValidate,\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Promise<Date> {\n return (\n codec as unknown as { extractTimestamp(id: Id<string>): Promise<Date> }\n ).extractTimestamp(id);\n },\n },\n construct(brand, opts, key) {\n try {\n return createOpaqueTimestampId(brand, { key: key as OpaqueKey, ...codecOpts(opts) });\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const reverseVariant: GeneratorDescriptor = {\n flag: \"--reverse\",\n inspect: {\n mode: \"readable\",\n note: \"note: timestamp assumes a plaintext Timestamp ID; if this ID was Opaque-encoded, the timestamp is meaningless — re-run with --opaque and the correct IDS_KEY\",\n validate: standardValidate,\n extractTimestamp(codec: IdCodec<string>, id: Id<string>): Date {\n return (codec as unknown as { extractTimestamp(id: Id<string>): Date }).extractTimestamp(id);\n },\n },\n construct(brand, opts) {\n try {\n return createReverseTimestampId(brand, codecOpts(opts));\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const wrappedVariant: Descriptor = {\n flag: \"--wrapped\",\n key: {\n envVar: \"IDS_WRAPPING_KEY\",\n formatEnvVar: \"IDS_WRAPPING_KEY_FORMAT\",\n encode: encodeWrappingKey,\n decode: decodeWrappingKey,\n import: importWrappingKey,\n },\n inspect: {\n mode: \"unwrap\",\n validate: standardValidate,\n unwrap(codec: IdCodec<string>, id: Id<string>): Promise<number | bigint> {\n return (codec as unknown as { unwrap(id: Id<string>): Promise<number | bigint> }).unwrap(id);\n },\n },\n extraFlags: [\"--kind\"],\n construct(brand, _opts, key, values) {\n const kind = parseKind(values ?? new Map());\n if (kind === undefined) return \"--kind is required with --wrapped\";\n if (isKindError(kind)) return kind;\n try {\n return createWrappedKeyId(brand, {\n kind,\n keys: [key as WrappingKey],\n allowDuplicateBrand: true,\n });\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const signedVariant: GeneratorDescriptor = {\n flag: \"--signed\",\n key: {\n envVar: \"IDS_SIGNING_KEY\",\n formatEnvVar: \"IDS_SIGNING_KEY_FORMAT\",\n encode: encodeSigningKey,\n decode: decodeSigningKey,\n import: importSigningKey,\n },\n inspect: {\n mode: \"verify\",\n safeVerify(codec: IdCodec<string>, id: string): Promise<SafeVerifyResult<string>> {\n return (\n codec as unknown as { safeVerify(id: string): Promise<SafeVerifyResult<string>> }\n ).safeVerify(id);\n },\n },\n construct(brand, opts, key) {\n try {\n return createSignedTimestampId(brand, {\n keys: [key as SigningKey],\n ...codecOpts(opts),\n });\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\nexport const digestVariant: GeneratorDescriptor = {\n flag: \"--digest\",\n key: {\n envVar: \"IDS_DIGEST_KEY\",\n formatEnvVar: \"IDS_DIGEST_KEY_FORMAT\",\n encode: encodeDigestKey,\n decode: decodeDigestKey,\n import: importDigestKey,\n },\n // Digest is one-way: inspect --digest is unsupported by design, so digestVariant is omitted\n // from inspectPolicy.selectable. \"unsupported\" documents that there is no inspect path.\n inspect: { mode: \"unsupported\" },\n extraFlags: [\"--ns\"],\n construct(brand, opts, key, values) {\n const ns = parseNs(values ?? new Map());\n if (ns === undefined) return \"--ns is required with --digest\";\n if (isNsError(ns)) return ns;\n try {\n const codec = createDigestId(brand, { ns, key: key as DigestKey, allowDuplicateBrand: true });\n return {\n safeParse: (v: unknown) => codec.safeParse(v),\n async generate(): Promise<string> {\n const reader = opts.readStdin ?? (() => Promise.resolve(\"\"));\n const material = await reader();\n return codec.digest(material);\n },\n };\n } catch (err) {\n return formatCliError(err);\n }\n },\n};\n\n// Determines which flag name appears first in \"cannot use --A and --B together\"\n// messages when two selectable variant flags conflict. Signed always leads;\n// remaining follow registry insertion order (digest, reverse, wrapped, opaque).\nexport const conflictPriorityOrder: readonly Descriptor[] = [\n signedVariant,\n digestVariant,\n reverseVariant,\n wrappedVariant,\n opaqueVariant,\n];\n\nexport const generatePolicy: GeneratePolicy = {\n default: timestampVariant,\n selectable: [opaqueVariant, reverseVariant, signedVariant, digestVariant],\n intrinsicFlags: [\"--count\", \"-c\"],\n};\n\nexport const inspectPolicy: Policy = {\n default: timestampVariant,\n selectable: [reverseVariant, wrappedVariant, opaqueVariant, signedVariant],\n intrinsicFlags: [],\n};\n\nexport const keygenPolicy: Policy = {\n default: opaqueVariant,\n selectable: [wrappedVariant, signedVariant, digestVariant],\n intrinsicFlags: [\"--bits\"],\n};\n","import type { IdCodec } from \"../adapters/adapter-types.js\";\nimport { isKeyFormatError, isLoadKeyError, loadKey, parseKeyFormat } from \"./key-io.js\";\nimport type { RunOpts } from \"./types.js\";\nimport {\n conflictPriorityOrder,\n type Descriptor,\n type GeneratorDescriptor,\n type Policy,\n} from \"./variants.js\";\n\nexport type CodecError = { kind: \"usage\"; message: string } | { kind: \"runtime\"; message: string };\n\nexport function isCodecError(v: unknown): v is CodecError {\n if (typeof v !== \"object\" || v === null) return false;\n const kind = (v as Record<string, unknown>).kind;\n return (kind === \"usage\" || kind === \"runtime\") && \"message\" in v;\n}\n\nexport function deriveAllowedFlags(policy: Policy): Set<string> {\n const flags = new Set<string>(policy.intrinsicFlags);\n let hasKeyed = policy.default.key !== undefined;\n for (const v of policy.selectable) {\n if (v.flag !== undefined) flags.add(v.flag);\n if (v.key !== undefined) hasKeyed = true;\n if (v.extraFlags !== undefined) {\n for (const f of v.extraFlags) flags.add(f);\n }\n }\n if (hasKeyed) flags.add(\"--key-format\");\n return flags;\n}\n\nexport function resolveVariant<D extends Descriptor>(\n policy: Policy<D>,\n flags: Set<string>,\n): D | string {\n const selected = conflictPriorityOrder.filter(\n (v): v is D =>\n policy.selectable.some((d) => d === v) && v.flag !== undefined && flags.has(v.flag),\n );\n if (selected.length === 0) return policy.default;\n if (selected.length === 1) return selected[0]!;\n return `cannot use ${selected[0]!.flag} and ${selected[1]!.flag} together`;\n}\n\nexport async function buildCodec(\n variant: GeneratorDescriptor,\n brand: string,\n values: Map<string, string>,\n opts: RunOpts,\n): Promise<(IdCodec<string> & { generate(): string | Promise<string> }) | CodecError>;\nexport async function buildCodec(\n variant: Descriptor,\n brand: string,\n values: Map<string, string>,\n opts: RunOpts,\n): Promise<IdCodec<string> | CodecError>;\nexport async function buildCodec(\n variant: Descriptor,\n brand: string,\n values: Map<string, string>,\n opts: RunOpts,\n): Promise<(IdCodec<string> & { generate?(): string | Promise<string> }) | CodecError> {\n let key: unknown;\n if (variant.key !== undefined) {\n const format = parseKeyFormat(values, opts, variant.key);\n if (isKeyFormatError(format)) return { kind: \"usage\", message: format };\n const keyResult = await loadKey(opts, format, variant.key);\n if (isLoadKeyError(keyResult)) {\n return {\n kind: keyResult.kind === \"missing\" ? \"usage\" : \"runtime\",\n message: keyResult.message,\n };\n }\n key = keyResult;\n }\n const codecOrError = variant.construct(brand, opts, key, values);\n if (typeof codecOrError === \"string\") {\n return {\n kind: codecOrError.startsWith(\"--\") ? \"usage\" : \"runtime\",\n message: codecOrError,\n };\n }\n return codecOrError;\n}\n","import { maxGenerateCount } from \"./constants.js\";\n\nexport function usageInspect(): string {\n return [\n \"Usage: ids inspect, i <id> [--opaque] [--wrapped --kind u32|i32|u64|i64] [--reverse] [--signed] [--key-format hex|base64url]\",\n \"\",\n \" Decode an ID and print brand, timestamp (or lookup key), and canonical form.\",\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format).\",\n \" --kind is required with --wrapped: u32, i32, u64, or i64.\",\n \" --reverse decodes a Reverse Timestamp ID (newest-first sort order).\",\n \" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" Without IDS_SIGNING_KEY, --signed prints the timestamp only (no verification). With IDS_SIGNING_KEY, prints verification: ok or failed.\",\n \" Note: --digest is not supported for inspect (Digest IDs are one-way; there is no reverse path).\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function usageGenerate(): string {\n return [\n `Usage: ids generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--key-format hex|base64url]`,\n \"\",\n ` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --reverse mints Reverse Timestamp IDs (newest-first sort order).\",\n \" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest mints a deterministic Digest ID from material read on stdin.\",\n \" --ns <ns> is required: the namespace domain separator (non-secret, non-empty).\",\n \" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \" Same material + ns + key always produces the same ID. Digest IDs are one-way.\",\n \" --count N > 1 is rejected: same material always produces the same ID.\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function usageKeygen(): string {\n return [\n \"Usage: ids keygen, k [--wrapped] [--signed] [--digest] [--bits 128|192|256] [--key-format hex|base64url]\",\n \"\",\n \" Emit a random key for importOpaqueKey, importWrappingKey, importSigningKey, or importDigestKey (stdout only).\",\n \" --wrapped emits a wrapping key for importWrappingKey instead (IDS_WRAPPING_KEY).\",\n \" --signed emits a signing key for importSigningKey instead (IDS_SIGNING_KEY; hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest emits a digest key for importDigestKey instead (IDS_DIGEST_KEY; hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function usage(): string {\n return [\n \"Usage: ids <subcommand> [args]\",\n \"\",\n \"Subcommands:\",\n \" inspect, i <id> [--opaque] [--wrapped --kind u32|i32|u64|i64] [--reverse] [--signed] [--key-format hex|base64url]\",\n \" Decode an ID and print brand, timestamp (or lookup key), and canonical form.\",\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format).\",\n \" --kind is required with --wrapped: u32, i32, u64, or i64.\",\n \" --reverse decodes a Reverse Timestamp ID (newest-first sort order).\",\n \" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" Without IDS_SIGNING_KEY, --signed prints the timestamp only (no verification). With IDS_SIGNING_KEY, prints verification: ok or failed.\",\n \" Note: --digest is not supported for inspect (Digest IDs are one-way; there is no reverse path).\",\n \" generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--key-format hex|base64url]\",\n ` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" --reverse mints Reverse Timestamp IDs (newest-first sort order).\",\n \" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest mints a deterministic Digest ID from material read on stdin.\",\n \" --ns <ns> is required: the namespace domain separator (non-secret, non-empty).\",\n \" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \" Same material + ns + key always produces the same ID. Digest IDs are one-way.\",\n \" --count N > 1 is rejected: same material always produces the same ID.\",\n \" keygen, k [--wrapped] [--signed] [--digest] [--bits 128|192|256] [--key-format hex|base64url]\",\n \" Emit a random key for importOpaqueKey, importWrappingKey, importSigningKey, or importDigestKey (key on stdout; warning on stderr).\",\n \" Safe handling: redirect stdout to a 0600 file (e.g. ids keygen > key.hex && chmod 0600 key.hex);\",\n \" do not let the key appear in shell history or CI logs. A warning is printed to stderr on every run.\",\n \" --wrapped emits a wrapping key for importWrappingKey instead (IDS_WRAPPING_KEY).\",\n \" --signed emits a signing key for importSigningKey instead (IDS_SIGNING_KEY; hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).\",\n \" --digest emits a digest key for importDigestKey instead (IDS_DIGEST_KEY; hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).\",\n \"\",\n \"Exit codes:\",\n \" 0 Success\",\n \" 1 Runtime/operational error (codec failure, bad key material, verification failure)\",\n \" 2 Usage/argument error (unknown subcommand, unrecognised flag, bad flag value, missing required arg)\",\n \"\",\n ].join(\"\\n\");\n}\n","import { buildCodec, deriveAllowedFlags, isCodecError, resolveVariant } from \"../dispatch.js\";\nimport { parseCount, splitFlags, unsupportedFlagForCommand } from \"../flags.js\";\nimport type { RunOpts } from \"../types.js\";\nimport { usageGenerate } from \"../usage.js\";\nimport { generatePolicy } from \"../variants.js\";\n\nlet stdinCache: Promise<string> | undefined;\n/* v8 ignore next 12 -- reads from process.stdin; not exercised in unit tests, only in the real binary */\nfunction readProcessStdin(): Promise<string> {\n if (stdinCache === undefined) {\n stdinCache = new Promise<string>((resolve) => {\n const chunks: string[] = [];\n process.stdin.setEncoding(\"utf8\");\n process.stdin.on(\"data\", (chunk: string) => chunks.push(chunk));\n process.stdin.on(\"end\", () => resolve(chunks.join(\"\")));\n process.stdin.resume();\n });\n }\n return stdinCache;\n}\n\nexport async function runGenerate(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n opts.stdout(usageGenerate());\n return 0;\n }\n const allowedFlags = deriveAllowedFlags(generatePolicy);\n const selectorFlags = new Set(\n generatePolicy.selectable.map((v) => v.flag).filter((f): f is string => f !== undefined),\n );\n const valueFlags = new Set([...allowedFlags].filter((f) => !selectorFlags.has(f)));\n const { flags, values, positionals, errors } = splitFlags(args, valueFlags);\n const unsupported = unsupportedFlagForCommand(\"generate\", flags, allowedFlags);\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return 2;\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return 2;\n }\n const extra = positionals[1];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return 2;\n }\n const [brand] = positionals;\n const count = parseCount(values);\n if (typeof count === \"string\") {\n opts.stderr(count + \"\\n\");\n return 2;\n }\n const variant = resolveVariant(generatePolicy, flags);\n if (typeof variant === \"string\") {\n opts.stderr(variant + \"\\n\");\n return 2;\n }\n if (variant.key === undefined && flags.has(\"--key-format\")) {\n opts.stderr(\"--key-format requires --opaque, --signed, or --digest\\n\");\n return 2;\n }\n if (flags.has(\"--digest\") && count > 1) {\n opts.stderr(\n \"--count N > 1 is rejected with --digest: same material always produces the same ID\\n\",\n );\n return 2;\n }\n const optsWithStdin: RunOpts = { ...opts, readStdin: opts.readStdin ?? readProcessStdin };\n const codec = await buildCodec(variant, brand ?? \"\", values, optsWithStdin);\n if (isCodecError(codec)) {\n opts.stderr(codec.message + \"\\n\");\n return codec.kind === \"usage\" ? 2 : 1;\n }\n for (let i = 0; i < count; i++) opts.stdout((await codec.generate()) + \"\\n\");\n return 0;\n}\n","import { createTimestampId, type TimestampCodec } from \"../../codecs/timestamp/index.js\";\nimport type { Id } from \"../../types.js\";\nimport { codecOpts } from \"../codec-options.js\";\nimport { buildCodec, deriveAllowedFlags, isCodecError, resolveVariant } from \"../dispatch.js\";\nimport {\n formatCliError,\n formatInspectOutput,\n formatSignedInspectOutput,\n formatWrappedInspectOutput,\n invalidIdPrefix,\n} from \"../format.js\";\nimport { splitFlags, unsupportedFlagForCommand } from \"../flags.js\";\nimport { isKeyFormatError, parseKeyFormat } from \"../key-io.js\";\nimport type { RunOpts } from \"../types.js\";\nimport { usageInspect } from \"../usage.js\";\nimport { inspectPolicy } from \"../variants.js\";\n\nexport async function runInspect(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n opts.stdout(usageInspect());\n return 0;\n }\n const allowedFlags = deriveAllowedFlags(inspectPolicy);\n const selectorFlags = new Set(\n inspectPolicy.selectable.map((v) => v.flag).filter((f): f is string => f !== undefined),\n );\n const valueFlags = new Set([...allowedFlags].filter((f) => !selectorFlags.has(f)));\n const { flags, values, positionals, errors } = splitFlags(args, valueFlags);\n\n const unsupported = unsupportedFlagForCommand(\"inspect\", flags, allowedFlags);\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return 2;\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return 2;\n }\n const [input] = positionals;\n if (input === undefined) {\n opts.stderr(usageInspect());\n return 2;\n }\n const extra = positionals[1];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return 2;\n }\n\n const variant = resolveVariant(inspectPolicy, flags);\n if (typeof variant === \"string\") {\n opts.stderr(variant + \"\\n\");\n return 2;\n }\n if (variant.key === undefined && flags.has(\"--key-format\")) {\n opts.stderr(\"--key-format requires --opaque, --wrapped, or --signed\\n\");\n return 2;\n }\n\n const brand = input.slice(0, 3).toLowerCase();\n const cap = variant.inspect;\n\n // \"verify\" (--signed) mode: the timestamp is plaintext and must be extractable even when\n // the signing key is unavailable. Structural parse happens before key loading so that:\n // bad key format → stderr only, stdout = \"\" (no timestamp shown)\n // invalid payload → stderr only, stdout = \"\" (no timestamp shown)\n // key missing/malformed → stdout has timestamp + \"verification: unavailable\"\n let verifyTimestamp: Date | undefined;\n let verifyCanonical: Id<string> | undefined;\n let verifyNowMs: number | undefined;\n if (cap.mode === \"verify\") {\n const fmtCheck = parseKeyFormat(values, opts, variant.key!);\n if (isKeyFormatError(fmtCheck)) {\n opts.stderr(fmtCheck + \"\\n\");\n return 2;\n }\n let tsCodec: TimestampCodec<string>;\n try {\n tsCodec = createTimestampId(brand, codecOpts(opts));\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n const structValidation = tsCodec[\"~standard\"].validate(input);\n if (structValidation.issues) {\n opts.stderr(invalidIdPrefix + structValidation.issues[0]!.message + \"\\n\");\n return 1;\n }\n verifyCanonical = structValidation.value;\n verifyTimestamp = tsCodec.extractTimestamp(verifyCanonical);\n verifyNowMs = (opts.now ?? Date.now)();\n }\n\n const codecOrError = await buildCodec(variant, brand, values, opts);\n if (isCodecError(codecOrError)) {\n if (cap.mode === \"verify\") {\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyCanonical!,\n input,\n nowMs: verifyNowMs!,\n verification: \"unavailable\",\n }),\n );\n opts.stderr(codecOrError.message + \"\\n\");\n return 1;\n }\n opts.stderr(codecOrError.message + \"\\n\");\n return codecOrError.kind === \"usage\" ? 2 : 1;\n }\n\n // Structural validation for non-verify, non-unsupported cases\n let canonical: Id<string> | undefined;\n if (cap.mode !== \"verify\" && cap.mode !== \"unsupported\") {\n const parsed = cap.validate(codecOrError, input);\n if (\"issue\" in parsed) {\n opts.stderr(parsed.issue + \"\\n\");\n return 1;\n }\n canonical = parsed.value;\n }\n\n // Dispatch on capability mode for output shapes\n switch (cap.mode) {\n case \"readable\": {\n const timestamp = cap.extractTimestamp(codecOrError, canonical!);\n const nowMs = (opts.now ?? Date.now)();\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(formatInspectOutput({ brand, timestamp, canonical: canonical!, input, nowMs }));\n return 0;\n }\n case \"keyed-readable\": {\n const timestamp = await cap.extractTimestamp(codecOrError, canonical!);\n const nowMs = (opts.now ?? Date.now)();\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(formatInspectOutput({ brand, timestamp, canonical: canonical!, input, nowMs }));\n return 0;\n }\n case \"unwrap\": {\n let lookupKey: number | bigint;\n try {\n lookupKey = await cap.unwrap(codecOrError, canonical!);\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n opts.stdout(formatWrappedInspectOutput({ brand, lookupKey, canonical: canonical!, input }));\n return 0;\n }\n case \"verify\": {\n const verifyResult = await cap.safeVerify(codecOrError, input);\n if (!verifyResult.ok) {\n /* v8 ignore next 4 -- defensive: both codecs share the same wire parse so ParseError\n is unreachable after the createTimestampId pre-validation above passes */\n if (verifyResult.error !== \"verification_failed\") {\n opts.stderr(verifyResult.error + \"\\n\");\n return 1;\n }\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyCanonical!,\n input,\n nowMs: verifyNowMs!,\n verification: \"failed\",\n }),\n );\n opts.stderr(\"verification_failed: verification failed\\n\");\n return 1;\n }\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyResult.id,\n input,\n nowMs: verifyNowMs!,\n verification: \"ok\",\n }),\n );\n return 0;\n }\n /* v8 ignore next 5 -- defensive: digestVariant is the only \"unsupported\" variant and it is\n excluded from inspectPolicy.selectable, so resolveVariant can never return it here. The\n branch exists for TypeScript exhaustiveness. */\n case \"unsupported\": {\n opts.stderr(\"unsupported flag for inspect: --digest\\n\");\n return 1;\n }\n }\n}\n","import { deriveAllowedFlags, resolveVariant } from \"../dispatch.js\";\nimport { parseBits, splitFlags, unsupportedFlagForCommand } from \"../flags.js\";\nimport { isKeyFormatError, parseKeyFormatFromFlag } from \"../key-io.js\";\nimport type { RunOpts } from \"../types.js\";\nimport { usageKeygen } from \"../usage.js\";\nimport { keygenPolicy } from \"../variants.js\";\n\nexport async function runKeygen(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n opts.stdout(usageKeygen());\n return Promise.resolve(0);\n }\n const allowedFlags = deriveAllowedFlags(keygenPolicy);\n const variantExtraFlags = new Set(keygenPolicy.selectable.flatMap((v) => v.extraFlags ?? []));\n const { flags, values, positionals, errors } = splitFlags(args, allowedFlags);\n const unsupported = unsupportedFlagForCommand(\n \"keygen\",\n flags,\n new Set([...allowedFlags].filter((f) => !variantExtraFlags.has(f))),\n );\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return Promise.resolve(2);\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return Promise.resolve(2);\n }\n const extra = positionals[0];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return Promise.resolve(2);\n }\n const variant = resolveVariant(keygenPolicy, flags);\n if (typeof variant === \"string\") {\n opts.stderr(variant + \"\\n\");\n return Promise.resolve(2);\n }\n const bits = parseBits(values);\n if (typeof bits === \"string\") {\n opts.stderr(bits + \"\\n\");\n return Promise.resolve(2);\n }\n const format = parseKeyFormatFromFlag(values);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(2);\n }\n /* v8 ignore next 4 -- defensive guard; all keygenPolicy variants have key defined */\n if (variant.key === undefined) {\n opts.stderr(\"internal: keygen policy variant has no key facet\\n\");\n return Promise.resolve(1);\n }\n const bytes = new Uint8Array(bits / 8);\n crypto.getRandomValues(bytes);\n opts.stderr(\n \"Warning: secret key material — redirect to a file (chmod 0600) and avoid shell history.\\n\",\n );\n opts.stdout(variant.key.encode(bytes, format) + \"\\n\");\n return Promise.resolve(0);\n}\n","import { runGenerate } from \"./commands/generate.js\";\nimport { runInspect } from \"./commands/inspect.js\";\nimport { runKeygen } from \"./commands/keygen.js\";\nimport type { CommandHandler, RunOpts } from \"./types.js\";\nimport { formatCliError } from \"./format.js\";\nimport { usage } from \"./usage.js\";\n\nexport type { RunOpts } from \"./types.js\";\n\ntype Command = {\n names: ReadonlyArray<string>;\n run: CommandHandler;\n};\n\nconst commands: ReadonlyArray<Command> = [\n { names: [\"generate\", \"g\"], run: runGenerate },\n { names: [\"inspect\", \"i\"], run: runInspect },\n { names: [\"keygen\", \"k\"], run: runKeygen },\n];\n\nexport async function run(opts: RunOpts): Promise<number> {\n try {\n const [subcommand, ...rest] = opts.argv;\n const command = commands.find((candidate) => candidate.names.includes(subcommand ?? \"\"));\n if (command !== undefined) return await command.run(rest, opts);\n if (subcommand === undefined || subcommand === \"--help\" || subcommand === \"-h\") {\n opts.stdout(usage());\n return 0;\n }\n opts.stderr(usage());\n return 2;\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n}\n","#!/usr/bin/env node\nimport { run } from \"../src/cli/index.js\";\n\nprocess.exitCode = await run({\n argv: process.argv.slice(2),\n stdout: (s) => process.stdout.write(s),\n stderr: (s) => process.stderr.write(s),\n});\n"],"mappings":"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"}