@smonn/ids 0.15.0 → 1.0.0-rc.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.
- package/README.md +3 -3
- package/dist/{adapter-types-7wWdELSh.mjs → adapter-types-CjzFNDcJ.mjs} +7 -2
- package/dist/adapter-types-CjzFNDcJ.mjs.map +1 -0
- package/dist/cli.mjs +30 -22
- package/dist/cli.mjs.map +1 -1
- package/dist/drizzle.d.mts +202 -3
- package/dist/drizzle.d.mts.map +1 -1
- package/dist/drizzle.mjs +245 -5
- package/dist/drizzle.mjs.map +1 -1
- package/dist/express.d.mts +44 -2
- package/dist/express.d.mts.map +1 -1
- package/dist/express.mjs +60 -2
- package/dist/express.mjs.map +1 -1
- package/dist/fastify.d.mts +49 -2
- package/dist/fastify.d.mts.map +1 -1
- package/dist/fastify.mjs +61 -2
- package/dist/fastify.mjs.map +1 -1
- package/dist/hono.d.mts +44 -2
- package/dist/hono.d.mts.map +1 -1
- package/dist/hono.mjs +54 -2
- package/dist/hono.mjs.map +1 -1
- package/dist/kysely.d.mts +103 -2
- package/dist/kysely.d.mts.map +1 -1
- package/dist/kysely.mjs +105 -2
- package/dist/kysely.mjs.map +1 -1
- package/dist/mikro-orm.d.mts +81 -3
- package/dist/mikro-orm.d.mts.map +1 -1
- package/dist/mikro-orm.mjs +86 -4
- package/dist/mikro-orm.mjs.map +1 -1
- package/dist/nestjs.mjs +1 -1
- package/dist/{opaque-COAcIIY4.mjs → opaque-Dle3CmSE.mjs} +18 -10
- package/dist/opaque-Dle3CmSE.mjs.map +1 -0
- package/dist/opaque.d.mts +16 -10
- package/dist/opaque.d.mts.map +1 -1
- package/dist/opaque.mjs +1 -1
- package/dist/prisma.d.mts +135 -3
- package/dist/prisma.d.mts.map +1 -1
- package/dist/prisma.mjs +141 -3
- package/dist/prisma.mjs.map +1 -1
- package/dist/typeorm.d.mts +84 -1
- package/dist/typeorm.d.mts.map +1 -1
- package/dist/typeorm.mjs +87 -2
- package/dist/typeorm.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/adapter-types-7wWdELSh.mjs.map +0 -1
- package/dist/opaque-COAcIIY4.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ All six codecs share the same `<brand>_<26 chars>` wire shape but make different
|
|
|
43
43
|
| Timestamp | `@smonn/ids` | Ascending (oldest-first) | No | Always (plaintext) |
|
|
44
44
|
| Reverse Timestamp | `@smonn/ids/reverse` | Descending (newest-first) | No | Always (plaintext) |
|
|
45
45
|
| Signed Timestamp | `@smonn/ids/signed` | Ascending (oldest-first) | Yes (signing key) | Always (plaintext) |
|
|
46
|
-
| Opaque Timestamp | `@smonn/ids/opaque` | None (encrypted) | Yes (
|
|
46
|
+
| Opaque Timestamp | `@smonn/ids/opaque` | None (encrypted) | Yes (key material) | With key only |
|
|
47
47
|
| Wrapped key | `@smonn/ids/wrapped` | None | Yes (wrapping key) | N/A — not timestamp-family |
|
|
48
48
|
| Digest | `@smonn/ids/digest` | None | Yes (digest key) | N/A — not timestamp-family |
|
|
49
49
|
|
|
@@ -61,8 +61,8 @@ Try them all live in the [playground](https://ids.smonn.se/playground/).
|
|
|
61
61
|
|
|
62
62
|
Framework and ORM adapters ship as optional subpath exports (each requires its own peer dependency):
|
|
63
63
|
|
|
64
|
-
- **HTTP
|
|
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`
|
|
64
|
+
- **HTTP params:** [Hono](https://ids.smonn.se/adapters/hono/), [Express](https://ids.smonn.se/adapters/express/), [Fastify](https://ids.smonn.se/adapters/fastify/) — `idParam`, `idQuery` middleware; [NestJS](https://ids.smonn.se/adapters/nestjs/) — `ParseIdPipe`
|
|
65
|
+
- **ORM columns:** [Drizzle](https://ids.smonn.se/adapters/drizzle/) — `idColumn`, `idColumnMysql`, `idColumnSqlite`, `nullableIdColumn`, [Kysely](https://ids.smonn.se/adapters/kysely/) — `idPlugin` / `idColumn`, `nullableIdColumn`, [MikroORM](https://ids.smonn.se/adapters/mikro-orm/) — `idType`, `nullableIdType`, `idField`, [Prisma](https://ids.smonn.se/adapters/prisma/) — `idField`, `nullableIdField`, [TypeORM](https://ids.smonn.se/adapters/typeorm/) — `idTransformer`, `nullableIdTransformer`
|
|
66
66
|
- **GraphQL:** [GraphQL](https://ids.smonn.se/adapters/graphql/) — `idScalar` custom scalar
|
|
67
67
|
- **CLI:** brand-agnostic `inspect` / `generate` / `keygen` — `npx @smonn/ids --help` ([docs](https://ids.smonn.se/cli/))
|
|
68
68
|
|
|
@@ -6,6 +6,11 @@ function readIdColumn(codec, value) {
|
|
|
6
6
|
if (!result.ok) throw new IdsError("invalid_id", `invalid ID from database: ${result.error}`, { cause: result.error });
|
|
7
7
|
return result.id;
|
|
8
8
|
}
|
|
9
|
+
/** Like {@link readIdColumn} but returns `null` when `value` is `null` or `undefined`. Delegates to `readIdColumn` for all other values. */
|
|
10
|
+
function readIdColumnNullable(codec, value) {
|
|
11
|
+
if (value === null || value === void 0) return null;
|
|
12
|
+
return readIdColumn(codec, value);
|
|
13
|
+
}
|
|
9
14
|
/**
|
|
10
15
|
* Maps a `ParseError` to `{ reason, status }` for web adapter failure handling.
|
|
11
16
|
*
|
|
@@ -22,6 +27,6 @@ function resolveIdParamFailure(error, options) {
|
|
|
22
27
|
};
|
|
23
28
|
}
|
|
24
29
|
//#endregion
|
|
25
|
-
export {
|
|
30
|
+
export { readIdColumnNullable as n, resolveIdParamFailure as r, readIdColumn as t };
|
|
26
31
|
|
|
27
|
-
//# sourceMappingURL=adapter-types-
|
|
32
|
+
//# sourceMappingURL=adapter-types-CjzFNDcJ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-types-CjzFNDcJ.mjs","names":[],"sources":["../src/adapters/adapter-types.ts"],"sourcesContent":["import { IdsError } from \"../error.js\";\nimport type { Id, ParseError, ParseResult } from \"../types.js\";\n\n/** Discriminated failure value passed to `onError` and emitted to the framework's error handler. */\nexport type IdParamFailure =\n | { readonly reason: \"brand_mismatch\"; readonly status: number }\n | { readonly reason: \"malformed\"; readonly status: number };\n\n/** Minimum structural type required by web and ORM adapters. Any codec variant satisfies this — all expose `safeParse`. Adapters only ever call `safeParse` — never key-dependent methods like `extractTimestamp`, `wrap`, or `unwrap`. */\nexport type IdCodec<Brand extends string> = {\n safeParse(value: unknown): ParseResult<Brand>;\n};\n\n/** Re-exported from ORM adapter subpaths (`@smonn/ids/drizzle`, `@smonn/ids/prisma`, `@smonn/ids/kysely`) under the public name; structurally identical to {@link IdCodec}. */\nexport type IdColumnCodec<Brand extends string> = IdCodec<Brand>;\n\n/** Parses `value` as `Id<Brand>` via `codec.safeParse`; throws `IdsError(\"invalid_id\")` on failure. Shared read helper for ORM adapters. */\nexport function readIdColumn<Brand extends string>(\n codec: IdCodec<Brand>,\n value: unknown,\n): Id<Brand> {\n const result = codec.safeParse(value);\n if (!result.ok) {\n throw new IdsError(\"invalid_id\", `invalid ID from database: ${result.error}`, {\n cause: result.error,\n });\n }\n return result.id;\n}\n\n/** Like {@link readIdColumn} but returns `null` when `value` is `null` or `undefined`. Delegates to `readIdColumn` for all other values. */\nexport function readIdColumnNullable<Brand extends string>(\n codec: IdCodec<Brand>,\n value: unknown,\n): Id<Brand> | null {\n if (value === null || value === undefined) {\n return null;\n }\n return readIdColumn(codec, value);\n}\n\n/**\n * Maps a `ParseError` to `{ reason, status }` for web adapter failure handling.\n *\n * - `invalid_prefix` → `brand_mismatch` / default 404\n * - anything else → `malformed` / default 400\n * - `options.status[reason]` overrides the default for that reason\n */\nexport function resolveIdParamFailure(\n error: ParseError,\n options?: { status?: { brand_mismatch?: number; malformed?: number } },\n): IdParamFailure {\n const reason = error === \"invalid_prefix\" ? (\"brand_mismatch\" as const) : (\"malformed\" as const);\n const defaultStatus = reason === \"brand_mismatch\" ? 404 : 400;\n const status = options?.status?.[reason] ?? defaultStatus;\n return { reason, status };\n}\n"],"mappings":";;;AAiBA,SAAgB,aACd,OACA,OACW;CACX,MAAM,SAAS,MAAM,UAAU,KAAK;CACpC,IAAI,CAAC,OAAO,IACV,MAAM,IAAI,SAAS,cAAc,6BAA6B,OAAO,SAAS,EAC5E,OAAO,OAAO,MAChB,CAAC;CAEH,OAAO,OAAO;AAChB;;AAGA,SAAgB,qBACd,OACA,OACkB;CAClB,IAAI,UAAU,QAAQ,UAAU,KAAA,GAC9B,OAAO;CAET,OAAO,aAAa,OAAO,KAAK;AAClC;;;;;;;;AASA,SAAgB,sBACd,OACA,SACgB;CAChB,MAAM,SAAS,UAAU,mBAAoB,mBAA8B;CAC3E,MAAM,gBAAgB,WAAW,mBAAmB,MAAM;CAE1D,OAAO;EAAE;EAAQ,QADF,SAAS,SAAS,WAAW;CACpB;AAC1B"}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as isIdsError } from "./error-Cp5qYZcv.mjs";
|
|
3
3
|
import { t as createTimestampId } from "./timestamp-RXXwHfHO.mjs";
|
|
4
|
-
import { i as importOpaqueKey, n as decodeOpaqueKey, r as encodeOpaqueKey, t as createOpaqueTimestampId } from "./opaque-
|
|
4
|
+
import { i as importOpaqueKey, n as decodeOpaqueKey, r as encodeOpaqueKey, t as createOpaqueTimestampId } from "./opaque-Dle3CmSE.mjs";
|
|
5
5
|
import { t as createReverseTimestampId } from "./reverse-CT-El3hi.mjs";
|
|
6
6
|
import { i as importSigningKey, n as decodeSigningKey, r as encodeSigningKey, t as createSignedTimestampId } from "./signed-Dkdteu1y.mjs";
|
|
7
7
|
import { i as importWrappingKey, n as decodeWrappingKey, r as encodeWrappingKey, t as createWrappedKeyId } from "./wrapped-Oj2hC1vB.mjs";
|
|
@@ -97,19 +97,27 @@ function parseKeyFormatFromFlag(values) {
|
|
|
97
97
|
if (fromFlag === void 0) return "hex";
|
|
98
98
|
return fromFlag;
|
|
99
99
|
}
|
|
100
|
+
const PRIMARY_KEY_VAR = "IDS_KEY";
|
|
101
|
+
const PRIMARY_FORMAT_VAR = "IDS_KEY_FORMAT";
|
|
100
102
|
function parseKeyFormat(values, opts, facet) {
|
|
101
103
|
const fromFlag = parseKeyFormatFlag(values);
|
|
102
104
|
if (fromFlag !== void 0) return fromFlag;
|
|
103
|
-
const
|
|
105
|
+
const env = opts.env ?? process.env;
|
|
106
|
+
const specificRaw = env[facet.envVar];
|
|
107
|
+
const activeFormatVar = specificRaw !== void 0 && specificRaw !== "" ? facet.formatEnvVar : PRIMARY_FORMAT_VAR;
|
|
108
|
+
const fromEnv = env[activeFormatVar];
|
|
104
109
|
if (fromEnv === void 0 || fromEnv === "") return "hex";
|
|
105
110
|
if (fromEnv === "hex" || fromEnv === "base64url") return fromEnv;
|
|
106
|
-
return `${
|
|
111
|
+
return `${activeFormatVar} must be hex or base64url, got '${fromEnv}'`;
|
|
107
112
|
}
|
|
108
113
|
async function loadKey(opts, format, facet) {
|
|
109
|
-
const
|
|
114
|
+
const env = opts.env ?? process.env;
|
|
115
|
+
const specificRaw = env[facet.envVar];
|
|
116
|
+
const specificSet = specificRaw !== void 0 && specificRaw !== "";
|
|
117
|
+
const raw = specificSet ? specificRaw : env[PRIMARY_KEY_VAR];
|
|
110
118
|
if (raw === void 0 || raw === "") return {
|
|
111
119
|
kind: "missing",
|
|
112
|
-
message: `missing ${facet.envVar} environment variable`
|
|
120
|
+
message: `missing ${!specificSet && facet.envVar !== PRIMARY_KEY_VAR ? `${facet.envVar} or ${PRIMARY_KEY_VAR}` : facet.envVar} environment variable`
|
|
113
121
|
};
|
|
114
122
|
try {
|
|
115
123
|
return await facet.import(facet.decode(raw, format));
|
|
@@ -260,7 +268,7 @@ function standardValidate(codec, input) {
|
|
|
260
268
|
const timestampVariant = {
|
|
261
269
|
inspect: {
|
|
262
270
|
mode: "readable",
|
|
263
|
-
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",
|
|
271
|
+
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_OPAQUE_KEY or IDS_KEY",
|
|
264
272
|
validate: standardValidate,
|
|
265
273
|
extractTimestamp(codec, id) {
|
|
266
274
|
return codec.extractTimestamp(id);
|
|
@@ -277,15 +285,15 @@ const timestampVariant = {
|
|
|
277
285
|
const opaqueVariant = {
|
|
278
286
|
flag: "--opaque",
|
|
279
287
|
key: {
|
|
280
|
-
envVar: "
|
|
281
|
-
formatEnvVar: "
|
|
288
|
+
envVar: "IDS_OPAQUE_KEY",
|
|
289
|
+
formatEnvVar: "IDS_OPAQUE_KEY_FORMAT",
|
|
282
290
|
encode: encodeOpaqueKey,
|
|
283
291
|
decode: decodeOpaqueKey,
|
|
284
292
|
import: importOpaqueKey
|
|
285
293
|
},
|
|
286
294
|
inspect: {
|
|
287
295
|
mode: "keyed-readable",
|
|
288
|
-
note: "note: timestamp assumes IDS_KEY matches the key used at generation; a wrong key yields a plausible but incorrect timestamp",
|
|
296
|
+
note: "note: timestamp assumes IDS_OPAQUE_KEY or IDS_KEY matches the key used at generation; a wrong key yields a plausible but incorrect timestamp",
|
|
289
297
|
validate: standardValidate,
|
|
290
298
|
extractTimestamp(codec, id) {
|
|
291
299
|
return codec.extractTimestamp(id);
|
|
@@ -306,7 +314,7 @@ const reverseVariant = {
|
|
|
306
314
|
flag: "--reverse",
|
|
307
315
|
inspect: {
|
|
308
316
|
mode: "readable",
|
|
309
|
-
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",
|
|
317
|
+
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_OPAQUE_KEY or IDS_KEY",
|
|
310
318
|
validate: standardValidate,
|
|
311
319
|
extractTimestamp(codec, id) {
|
|
312
320
|
return codec.extractTimestamp(id);
|
|
@@ -506,11 +514,11 @@ function usageInspect() {
|
|
|
506
514
|
" ids inspect --from-uuid <uuid> --brand <brand>",
|
|
507
515
|
"",
|
|
508
516
|
" Decode an ID and print brand, timestamp (or lookup key), canonical form, and UUID.",
|
|
509
|
-
" --opaque reads the
|
|
510
|
-
" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format).",
|
|
517
|
+
" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.",
|
|
518
|
+
" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_WRAPPING_KEY is unset.",
|
|
511
519
|
" --kind is required with --wrapped: u32, i32, u64, or i64.",
|
|
512
520
|
" --reverse decodes a Reverse Timestamp ID (newest-first sort order).",
|
|
513
|
-
" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).",
|
|
521
|
+
" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.",
|
|
514
522
|
" Without IDS_SIGNING_KEY, --signed prints the timestamp only (no verification). With IDS_SIGNING_KEY, prints verification: ok or failed.",
|
|
515
523
|
" Note: --digest is not supported for inspect (Digest IDs are one-way; there is no reverse path).",
|
|
516
524
|
" --from-uuid <uuid> converts a UUID back to a canonical Id<Brand>. Requires --brand <brand>.",
|
|
@@ -523,12 +531,12 @@ function usageGenerate() {
|
|
|
523
531
|
`Usage: ids generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--uuid] [--key-format hex|base64url]`,
|
|
524
532
|
"",
|
|
525
533
|
` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,
|
|
526
|
-
" --opaque reads the
|
|
534
|
+
" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.",
|
|
527
535
|
" --reverse mints Reverse Timestamp IDs (newest-first sort order).",
|
|
528
|
-
" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).",
|
|
536
|
+
" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.",
|
|
529
537
|
" --digest mints a deterministic Digest ID from material read on stdin.",
|
|
530
538
|
" --ns <ns> is required: the namespace domain separator (non-secret, non-empty).",
|
|
531
|
-
" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).",
|
|
539
|
+
" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_DIGEST_KEY is unset.",
|
|
532
540
|
" Same material + ns + key always produces the same ID. Digest IDs are one-way.",
|
|
533
541
|
" --count N > 1 is rejected: same material always produces the same ID.",
|
|
534
542
|
" --uuid emits the raw UUID form of each generated ID instead of the canonical ID.",
|
|
@@ -554,23 +562,23 @@ function usage() {
|
|
|
554
562
|
" inspect, i <id> [--opaque] [--wrapped --kind u32|i32|u64|i64] [--reverse] [--signed] [--key-format hex|base64url]",
|
|
555
563
|
" inspect, i --from-uuid <uuid> --brand <brand>",
|
|
556
564
|
" Decode an ID and print brand, timestamp (or lookup key), canonical form, and UUID.",
|
|
557
|
-
" --opaque reads the
|
|
558
|
-
" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format).",
|
|
565
|
+
" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.",
|
|
566
|
+
" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_WRAPPING_KEY is unset.",
|
|
559
567
|
" --kind is required with --wrapped: u32, i32, u64, or i64.",
|
|
560
568
|
" --reverse decodes a Reverse Timestamp ID (newest-first sort order).",
|
|
561
|
-
" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).",
|
|
569
|
+
" --signed decodes a Signed Timestamp ID; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.",
|
|
562
570
|
" Without IDS_SIGNING_KEY, --signed prints the timestamp only (no verification). With IDS_SIGNING_KEY, prints verification: ok or failed.",
|
|
563
571
|
" Note: --digest is not supported for inspect (Digest IDs are one-way; there is no reverse path).",
|
|
564
572
|
" --from-uuid <uuid> converts a UUID back to a canonical Id<Brand>. Requires --brand <brand>.",
|
|
565
573
|
" --brand <brand> specifies the entity type brand for --from-uuid (e.g. usr).",
|
|
566
574
|
" generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--uuid] [--key-format hex|base64url]",
|
|
567
575
|
` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,
|
|
568
|
-
" --opaque reads the
|
|
576
|
+
" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.",
|
|
569
577
|
" --reverse mints Reverse Timestamp IDs (newest-first sort order).",
|
|
570
|
-
" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format).",
|
|
578
|
+
" --signed mints Signed Timestamp IDs; reads signing key from IDS_SIGNING_KEY (hex by default; IDS_SIGNING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.",
|
|
571
579
|
" --digest mints a deterministic Digest ID from material read on stdin.",
|
|
572
580
|
" --ns <ns> is required: the namespace domain separator (non-secret, non-empty).",
|
|
573
|
-
" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format).",
|
|
581
|
+
" Reads the digest key from IDS_DIGEST_KEY (hex by default; IDS_DIGEST_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_DIGEST_KEY is unset.",
|
|
574
582
|
" Same material + ns + key always produces the same ID. Digest IDs are one-way.",
|
|
575
583
|
" --count N > 1 is rejected: same material always produces the same ID.",
|
|
576
584
|
" --uuid emits the raw UUID form of each generated ID instead of the canonical ID.",
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 uuid: 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 uuid: 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 `uuid: ${result.uuid}`,\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(\n `canonical: ${result.canonical}`,\n `uuid: ${result.uuid}`,\n `input: ${inputLine}`,\n \"\",\n );\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 `uuid: ${result.uuid}`,\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 \"--uuid\",\n \"--from-uuid\",\n \"--brand\",\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 toUUID: (id: string) => codec.toUUID(id as Id<typeof brand>),\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\", \"--uuid\"],\n};\n\nexport const inspectPolicy: Policy = {\n default: timestampVariant,\n selectable: [reverseVariant, wrappedVariant, opaqueVariant, signedVariant],\n intrinsicFlags: [\"--from-uuid\", \"--brand\"],\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 \" ids inspect --from-uuid <uuid> --brand <brand>\",\n \"\",\n \" Decode an ID and print brand, timestamp (or lookup key), canonical form, and UUID.\",\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 \" --from-uuid <uuid> converts a UUID back to a canonical Id<Brand>. Requires --brand <brand>.\",\n \" --brand <brand> specifies the entity type brand for --from-uuid (e.g. usr).\",\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>] [--uuid] [--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 \" --uuid emits the raw UUID form of each generated ID instead of the canonical 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 \" inspect, i --from-uuid <uuid> --brand <brand>\",\n \" Decode an ID and print brand, timestamp (or lookup key), canonical form, and UUID.\",\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 \" --from-uuid <uuid> converts a UUID back to a canonical Id<Brand>. Requires --brand <brand>.\",\n \" --brand <brand> specifies the entity type brand for --from-uuid (e.g. usr).\",\n \" generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--uuid] [--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 \" --uuid emits the raw UUID form of each generated ID instead of the canonical 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 const emitUuid = flags.has(\"--uuid\");\n for (let i = 0; i < count; i++) {\n const id = await codec.generate();\n if (emitUuid) {\n // BuildCodecResult does not expose toUUID in its type; cast required because every codec variant implements the method (ADR-0024)\n const uuid = (codec as unknown as { toUUID(id: string): string }).toUUID(id);\n opts.stdout(uuid + \"\\n\");\n } else {\n opts.stdout(id + \"\\n\");\n }\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\n // --from-uuid path: convert a UUID to a canonical Id<Brand>\n const fromUuidValue = values.get(\"--from-uuid\");\n if (fromUuidValue !== undefined) {\n if (fromUuidValue === \"\") {\n opts.stderr(\"--from-uuid requires a value\\n\");\n return 2;\n }\n const brandValue = values.get(\"--brand\");\n if (brandValue === undefined || brandValue === \"\") {\n opts.stderr(\"--from-uuid requires --brand\\n\");\n return 2;\n }\n let tsCodec: TimestampCodec<string>;\n try {\n tsCodec = createTimestampId(brandValue, codecOpts(opts));\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n const result = tsCodec.safeFromUUID(fromUuidValue);\n if (!result.ok) {\n opts.stderr(\"invalid_uuid: not a valid RFC 9562 UUID\\n\");\n return 1;\n }\n opts.stdout(result.id + \"\\n\");\n return 0;\n }\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 let verifyTsCodec: TimestampCodec<string> | 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 verifyTsCodec = tsCodec;\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 const uuid = verifyTsCodec!.toUUID(verifyCanonical!);\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyCanonical!,\n uuid,\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 // Helper to call toUUID on any codec via unsafe cast\n function codecToUUID(id: Id<string>): string {\n return (codecOrError as unknown as { toUUID(id: Id<string>): string }).toUUID(id);\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 const uuid = codecToUUID(canonical!);\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(\n formatInspectOutput({ brand, timestamp, canonical: canonical!, uuid, input, nowMs }),\n );\n return 0;\n }\n case \"keyed-readable\": {\n const timestamp = await cap.extractTimestamp(codecOrError, canonical!);\n const nowMs = (opts.now ?? Date.now)();\n const uuid = codecToUUID(canonical!);\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(\n formatInspectOutput({ brand, timestamp, canonical: canonical!, uuid, input, nowMs }),\n );\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 const uuid = codecToUUID(canonical!);\n opts.stdout(\n formatWrappedInspectOutput({ brand, lookupKey, canonical: canonical!, uuid, input }),\n );\n return 0;\n }\n case \"verify\": {\n const uuid = verifyTsCodec!.toUUID(verifyCanonical!);\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 uuid,\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 uuid,\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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"}
|
|
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 uuid: 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 uuid: 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 `uuid: ${result.uuid}`,\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(\n `canonical: ${result.canonical}`,\n `uuid: ${result.uuid}`,\n `input: ${inputLine}`,\n \"\",\n );\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 `uuid: ${result.uuid}`,\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\nconst PRIMARY_KEY_VAR = \"IDS_KEY\";\nconst PRIMARY_FORMAT_VAR = \"IDS_KEY_FORMAT\";\n\nexport function parseKeyFormat(\n values: Map<string, string>,\n opts: RunOpts,\n facet: Pick<KeyFacet<unknown>, \"envVar\" | \"formatEnvVar\">,\n): KeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag !== undefined) return fromFlag;\n const env = opts.env ?? process.env;\n // format must travel with its paired key var, never cross-paired\n const specificRaw = env[facet.envVar];\n const specificSet = specificRaw !== undefined && specificRaw !== \"\";\n const activeFormatVar = specificSet ? facet.formatEnvVar : PRIMARY_FORMAT_VAR;\n const fromEnv = env[activeFormatVar];\n if (fromEnv === undefined || fromEnv === \"\") return \"hex\";\n if (fromEnv === \"hex\" || fromEnv === \"base64url\") return fromEnv;\n return `${activeFormatVar} 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 specificRaw = env[facet.envVar];\n const specificSet = specificRaw !== undefined && specificRaw !== \"\";\n const raw = specificSet ? specificRaw : env[PRIMARY_KEY_VAR];\n if (raw === undefined || raw === \"\") {\n const varDesc =\n !specificSet && facet.envVar !== PRIMARY_KEY_VAR\n ? `${facet.envVar} or ${PRIMARY_KEY_VAR}`\n : facet.envVar;\n return { kind: \"missing\", message: `missing ${varDesc} 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 \"--uuid\",\n \"--from-uuid\",\n \"--brand\",\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_OPAQUE_KEY or 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_OPAQUE_KEY\",\n formatEnvVar: \"IDS_OPAQUE_KEY_FORMAT\",\n encode: encodeOpaqueKey,\n decode: decodeOpaqueKey,\n import: importOpaqueKey,\n },\n inspect: {\n mode: \"keyed-readable\",\n note: \"note: timestamp assumes IDS_OPAQUE_KEY or 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_OPAQUE_KEY or 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 toUUID: (id: string) => codec.toUUID(id as Id<typeof brand>),\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\", \"--uuid\"],\n};\n\nexport const inspectPolicy: Policy = {\n default: timestampVariant,\n selectable: [reverseVariant, wrappedVariant, opaqueVariant, signedVariant],\n intrinsicFlags: [\"--from-uuid\", \"--brand\"],\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 \" ids inspect --from-uuid <uuid> --brand <brand>\",\n \"\",\n \" Decode an ID and print brand, timestamp (or lookup key), canonical form, and UUID.\",\n \" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.\",\n \" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_WRAPPING_KEY is unset.\",\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); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.\",\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 \" --from-uuid <uuid> converts a UUID back to a canonical Id<Brand>. Requires --brand <brand>.\",\n \" --brand <brand> specifies the entity type brand for --from-uuid (e.g. usr).\",\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>] [--uuid] [--key-format hex|base64url]`,\n \"\",\n ` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,\n \" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.\",\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); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.\",\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); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_DIGEST_KEY is unset.\",\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 \" --uuid emits the raw UUID form of each generated ID instead of the canonical 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 \" inspect, i --from-uuid <uuid> --brand <brand>\",\n \" Decode an ID and print brand, timestamp (or lookup key), canonical form, and UUID.\",\n \" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.\",\n \" --wrapped reads the wrapping key from IDS_WRAPPING_KEY (hex by default; IDS_WRAPPING_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_WRAPPING_KEY is unset.\",\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); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.\",\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 \" --from-uuid <uuid> converts a UUID back to a canonical Id<Brand>. Requires --brand <brand>.\",\n \" --brand <brand> specifies the entity type brand for --from-uuid (e.g. usr).\",\n \" generate, g <brand> [--count, -c N] [--opaque] [--reverse] [--signed] [--digest --ns <ns>] [--uuid] [--key-format hex|base64url]\",\n ` Mint 1..${maxGenerateCount} canonical IDs for the given brand.`,\n \" --opaque reads the Opaque key from IDS_OPAQUE_KEY (hex by default; IDS_OPAQUE_KEY_FORMAT or --key-format); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_OPAQUE_KEY is unset.\",\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); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_SIGNING_KEY is unset.\",\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); falls back to IDS_KEY / IDS_KEY_FORMAT when IDS_DIGEST_KEY is unset.\",\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 \" --uuid emits the raw UUID form of each generated ID instead of the canonical 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 const emitUuid = flags.has(\"--uuid\");\n for (let i = 0; i < count; i++) {\n const id = await codec.generate();\n if (emitUuid) {\n // BuildCodecResult does not expose toUUID in its type; cast required because every codec variant implements the method (ADR-0024)\n const uuid = (codec as unknown as { toUUID(id: string): string }).toUUID(id);\n opts.stdout(uuid + \"\\n\");\n } else {\n opts.stdout(id + \"\\n\");\n }\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\n // --from-uuid path: convert a UUID to a canonical Id<Brand>\n const fromUuidValue = values.get(\"--from-uuid\");\n if (fromUuidValue !== undefined) {\n if (fromUuidValue === \"\") {\n opts.stderr(\"--from-uuid requires a value\\n\");\n return 2;\n }\n const brandValue = values.get(\"--brand\");\n if (brandValue === undefined || brandValue === \"\") {\n opts.stderr(\"--from-uuid requires --brand\\n\");\n return 2;\n }\n let tsCodec: TimestampCodec<string>;\n try {\n tsCodec = createTimestampId(brandValue, codecOpts(opts));\n } catch (err) {\n opts.stderr(formatCliError(err) + \"\\n\");\n return 1;\n }\n const result = tsCodec.safeFromUUID(fromUuidValue);\n if (!result.ok) {\n opts.stderr(\"invalid_uuid: not a valid RFC 9562 UUID\\n\");\n return 1;\n }\n opts.stdout(result.id + \"\\n\");\n return 0;\n }\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 let verifyTsCodec: TimestampCodec<string> | 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 verifyTsCodec = tsCodec;\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 const uuid = verifyTsCodec!.toUUID(verifyCanonical!);\n opts.stdout(\n formatSignedInspectOutput({\n brand,\n timestamp: verifyTimestamp!,\n canonical: verifyCanonical!,\n uuid,\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 // Helper to call toUUID on any codec via unsafe cast\n function codecToUUID(id: Id<string>): string {\n return (codecOrError as unknown as { toUUID(id: Id<string>): string }).toUUID(id);\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 const uuid = codecToUUID(canonical!);\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(\n formatInspectOutput({ brand, timestamp, canonical: canonical!, uuid, input, nowMs }),\n );\n return 0;\n }\n case \"keyed-readable\": {\n const timestamp = await cap.extractTimestamp(codecOrError, canonical!);\n const nowMs = (opts.now ?? Date.now)();\n const uuid = codecToUUID(canonical!);\n opts.stderr(cap.note + \"\\n\");\n opts.stdout(\n formatInspectOutput({ brand, timestamp, canonical: canonical!, uuid, input, nowMs }),\n );\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 const uuid = codecToUUID(canonical!);\n opts.stdout(\n formatWrappedInspectOutput({ brand, lookupKey, canonical: canonical!, uuid, input }),\n );\n return 0;\n }\n case \"verify\": {\n const uuid = verifyTsCodec!.toUUID(verifyCanonical!);\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 uuid,\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 uuid,\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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"}
|