@smonn/ids 0.3.3 → 0.3.4
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/dist/cli.mjs +90 -9
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -31,13 +31,31 @@ function usage() {
|
|
|
31
31
|
].join("\n");
|
|
32
32
|
}
|
|
33
33
|
function runInspect(args, opts) {
|
|
34
|
-
const { flags, values, positionals } = splitFlags(args);
|
|
34
|
+
const { flags, values, positionals, errors } = splitFlags(args);
|
|
35
|
+
const unsupported = unsupportedFlagForCommand("inspect", flags, new Set(["--opaque", "--key-format"]));
|
|
36
|
+
if (unsupported !== void 0) {
|
|
37
|
+
opts.stderr(unsupported + "\n");
|
|
38
|
+
return Promise.resolve(1);
|
|
39
|
+
}
|
|
40
|
+
if (errors[0] !== void 0) {
|
|
41
|
+
opts.stderr(errors[0] + "\n");
|
|
42
|
+
return Promise.resolve(1);
|
|
43
|
+
}
|
|
35
44
|
const [input] = positionals;
|
|
36
45
|
if (input === void 0) {
|
|
37
46
|
opts.stderr(usage());
|
|
38
47
|
return Promise.resolve(1);
|
|
39
48
|
}
|
|
49
|
+
const extra = positionals[1];
|
|
50
|
+
if (extra !== void 0) {
|
|
51
|
+
opts.stderr(`unexpected argument: ${extra}\n`);
|
|
52
|
+
return Promise.resolve(1);
|
|
53
|
+
}
|
|
40
54
|
const opaque = flags.has("--opaque");
|
|
55
|
+
if (!opaque && flags.has("--key-format")) {
|
|
56
|
+
opts.stderr("--key-format requires --opaque\n");
|
|
57
|
+
return Promise.resolve(1);
|
|
58
|
+
}
|
|
41
59
|
const brand = input.slice(0, 3).toLowerCase();
|
|
42
60
|
if (opaque) {
|
|
43
61
|
const format = parseOpaqueKeyFormat(values, opts);
|
|
@@ -143,14 +161,38 @@ function unit(n, name) {
|
|
|
143
161
|
return `${n} ${n === 1 ? name : `${name}s`}`;
|
|
144
162
|
}
|
|
145
163
|
function runGenerate(args, opts) {
|
|
146
|
-
const { flags, values, positionals } = splitFlags(args);
|
|
164
|
+
const { flags, values, positionals, errors } = splitFlags(args);
|
|
165
|
+
const unsupported = unsupportedFlagForCommand("generate", flags, new Set([
|
|
166
|
+
"--count",
|
|
167
|
+
"-c",
|
|
168
|
+
"--opaque",
|
|
169
|
+
"--key-format"
|
|
170
|
+
]));
|
|
171
|
+
if (unsupported !== void 0) {
|
|
172
|
+
opts.stderr(unsupported + "\n");
|
|
173
|
+
return Promise.resolve(1);
|
|
174
|
+
}
|
|
175
|
+
if (errors[0] !== void 0) {
|
|
176
|
+
opts.stderr(errors[0] + "\n");
|
|
177
|
+
return Promise.resolve(1);
|
|
178
|
+
}
|
|
179
|
+
const extra = positionals[1];
|
|
180
|
+
if (extra !== void 0) {
|
|
181
|
+
opts.stderr(`unexpected argument: ${extra}\n`);
|
|
182
|
+
return Promise.resolve(1);
|
|
183
|
+
}
|
|
147
184
|
const [brand] = positionals;
|
|
148
185
|
const count = parseCount(values);
|
|
149
186
|
if (typeof count === "string") {
|
|
150
187
|
opts.stderr(count + "\n");
|
|
151
188
|
return Promise.resolve(1);
|
|
152
189
|
}
|
|
153
|
-
|
|
190
|
+
const opaque = flags.has("--opaque");
|
|
191
|
+
if (!opaque && flags.has("--key-format")) {
|
|
192
|
+
opts.stderr("--key-format requires --opaque\n");
|
|
193
|
+
return Promise.resolve(1);
|
|
194
|
+
}
|
|
195
|
+
if (opaque) {
|
|
154
196
|
const format = parseOpaqueKeyFormat(values, opts);
|
|
155
197
|
if (isKeyFormatError(format)) {
|
|
156
198
|
opts.stderr(format + "\n");
|
|
@@ -188,7 +230,21 @@ async function runOpaqueGenerate(brand, count, format, opts) {
|
|
|
188
230
|
return 0;
|
|
189
231
|
}
|
|
190
232
|
function runKeygen(args, opts) {
|
|
191
|
-
const { values } = splitFlags(args);
|
|
233
|
+
const { flags, values, positionals, errors } = splitFlags(args);
|
|
234
|
+
const unsupported = unsupportedFlagForCommand("keygen", flags, new Set(["--bits", "--key-format"]));
|
|
235
|
+
if (unsupported !== void 0) {
|
|
236
|
+
opts.stderr(unsupported + "\n");
|
|
237
|
+
return Promise.resolve(1);
|
|
238
|
+
}
|
|
239
|
+
if (errors[0] !== void 0) {
|
|
240
|
+
opts.stderr(errors[0] + "\n");
|
|
241
|
+
return Promise.resolve(1);
|
|
242
|
+
}
|
|
243
|
+
const extra = positionals[0];
|
|
244
|
+
if (extra !== void 0) {
|
|
245
|
+
opts.stderr(`unexpected argument: ${extra}\n`);
|
|
246
|
+
return Promise.resolve(1);
|
|
247
|
+
}
|
|
192
248
|
const bits = parseBits(values);
|
|
193
249
|
if (typeof bits === "string") {
|
|
194
250
|
opts.stderr(bits + "\n");
|
|
@@ -267,37 +323,47 @@ function splitFlags(args) {
|
|
|
267
323
|
const flags = /* @__PURE__ */ new Set();
|
|
268
324
|
const values = /* @__PURE__ */ new Map();
|
|
269
325
|
const positionals = [];
|
|
326
|
+
const errors = [];
|
|
327
|
+
const seenFlags = /* @__PURE__ */ new Set();
|
|
270
328
|
const valueFlags = new Set([
|
|
271
329
|
"--count",
|
|
272
330
|
"-c",
|
|
273
331
|
"--bits",
|
|
274
332
|
"--key-format"
|
|
275
333
|
]);
|
|
334
|
+
const addFlag = (flag) => {
|
|
335
|
+
const canonical = canonicalFlag(flag);
|
|
336
|
+
if (seenFlags.has(canonical)) errors.push(`duplicate flag: ${canonical}`);
|
|
337
|
+
seenFlags.add(canonical);
|
|
338
|
+
flags.add(flag);
|
|
339
|
+
};
|
|
276
340
|
for (let i = 0; i < args.length; i++) {
|
|
277
341
|
const raw = args[i];
|
|
278
342
|
const { flag, inlineValue } = splitFlagToken(raw);
|
|
279
343
|
if (flag === "--opaque") {
|
|
280
|
-
|
|
344
|
+
addFlag(flag);
|
|
345
|
+
if (inlineValue !== void 0) errors.push("flag does not take a value: --opaque");
|
|
281
346
|
continue;
|
|
282
347
|
}
|
|
283
348
|
if (valueFlags.has(flag)) {
|
|
284
349
|
if (inlineValue !== void 0) {
|
|
285
|
-
|
|
350
|
+
addFlag(flag);
|
|
286
351
|
values.set(flag, inlineValue);
|
|
287
352
|
continue;
|
|
288
353
|
}
|
|
289
354
|
const value = args[i + 1];
|
|
290
355
|
if (value === void 0 || value.startsWith("-")) {
|
|
356
|
+
addFlag(flag);
|
|
291
357
|
values.set(flag, "");
|
|
292
358
|
continue;
|
|
293
359
|
}
|
|
294
|
-
|
|
360
|
+
addFlag(flag);
|
|
295
361
|
values.set(flag, value);
|
|
296
362
|
i++;
|
|
297
363
|
continue;
|
|
298
364
|
}
|
|
299
365
|
if (flag.startsWith("-")) {
|
|
300
|
-
|
|
366
|
+
addFlag(flag);
|
|
301
367
|
continue;
|
|
302
368
|
}
|
|
303
369
|
positionals.push(raw);
|
|
@@ -305,9 +371,24 @@ function splitFlags(args) {
|
|
|
305
371
|
return {
|
|
306
372
|
flags,
|
|
307
373
|
values,
|
|
308
|
-
positionals
|
|
374
|
+
positionals,
|
|
375
|
+
errors
|
|
309
376
|
};
|
|
310
377
|
}
|
|
378
|
+
function canonicalFlag(flag) {
|
|
379
|
+
if (flag === "-c") return "--count";
|
|
380
|
+
return flag;
|
|
381
|
+
}
|
|
382
|
+
const knownFlags = new Set([
|
|
383
|
+
"--opaque",
|
|
384
|
+
"--key-format",
|
|
385
|
+
"--count",
|
|
386
|
+
"-c",
|
|
387
|
+
"--bits"
|
|
388
|
+
]);
|
|
389
|
+
function unsupportedFlagForCommand(command, flags, allowed) {
|
|
390
|
+
for (const flag of flags) if (!allowed.has(flag)) return knownFlags.has(flag) ? `unsupported flag for ${command}: ${flag}` : `unsupported flag: ${flag}`;
|
|
391
|
+
}
|
|
311
392
|
function codecOpts(opts) {
|
|
312
393
|
const o = { allowDuplicateBrand: true };
|
|
313
394
|
if (opts.now !== void 0) o.now = opts.now;
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts","../bin/cli.ts"],"sourcesContent":["import { createId, type Options } from \"./id.js\";\nimport {\n createOpaqueId,\n decodeOpaqueKey,\n encodeOpaqueKey,\n importOpaqueKey,\n type OpaqueKeyFormat,\n} from \"./opaque.js\";\nimport type { Id } from \"./types.js\";\n\nexport type RunOpts = {\n argv: ReadonlyArray<string>;\n stdout: (chunk: string) => void;\n stderr: (chunk: string) => void;\n now?: Options[\"now\"];\n rng?: Options[\"rng\"];\n /** Defaults to `process.env`. Injected in tests for `IDS_KEY`. */\n env?: Readonly<Record<string, string | undefined>>;\n};\n\nexport async function run(opts: RunOpts): Promise<number> {\n const [subcommand, ...rest] = opts.argv;\n if (subcommand === \"generate\" || subcommand === \"g\") return runGenerate(rest, opts);\n if (subcommand === \"inspect\" || subcommand === \"i\") return runInspect(rest, opts);\n if (subcommand === \"keygen\" || subcommand === \"k\") return runKeygen(rest, opts);\n if (subcommand === undefined || subcommand === \"--help\" || subcommand === \"-h\") {\n opts.stdout(usage());\n return 0;\n }\n opts.stderr(usage());\n return 1;\n}\n\nfunction usage(): string {\n return [\n \"Usage: ids <subcommand> [args]\",\n \"\",\n \"Subcommands:\",\n \" inspect, i <id> [--opaque] [--key-format hex|base64url]\",\n \" Decode an ID and print brand, timestamp, and canonical form.\",\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" generate, g <brand> [--count, -c N] [--opaque] [--key-format hex|base64url]\",\n \" Mint one or more 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 \" keygen, k [--bits 128|192|256] [--key-format hex|base64url]\",\n \" Emit a random AES key for importOpaqueKey (stdout only).\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction runInspect(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n const { flags, values, positionals } = splitFlags(args);\n const [input] = positionals;\n if (input === undefined) {\n opts.stderr(usage());\n return Promise.resolve(1);\n }\n const opaque = flags.has(\"--opaque\");\n const brand = input.slice(0, 3).toLowerCase();\n if (opaque) {\n const format = parseOpaqueKeyFormat(values, opts);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(1);\n }\n return runOpaqueInspect(brand, input, format, opts);\n }\n let codec;\n try {\n codec = createId(brand, codecOpts(opts));\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return Promise.resolve(1);\n }\n const validation = codec[\"~standard\"].validate(input);\n if (validation.issues) {\n opts.stderr(validation.issues[0]!.message + \"\\n\");\n return Promise.resolve(1);\n }\n const canonical = validation.value;\n const timestamp = codec.extractTimestamp(canonical);\n const nowMs = (opts.now ?? Date.now)();\n const relative = formatRelative(timestamp.getTime(), nowMs);\n const inputLine = describeInputForm(input, canonical);\n opts.stdout(\n [\n `brand: ${brand}`,\n `timestamp: ${timestamp.toISOString()} (${relative})`,\n `canonical: ${canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\"),\n );\n return Promise.resolve(0);\n}\n\nasync function runOpaqueInspect(\n brand: string,\n input: string,\n format: OpaqueKeyFormat,\n opts: RunOpts,\n): Promise<number> {\n const keyResult = await loadOpaqueKey(opts, format);\n if (typeof keyResult === \"string\") {\n opts.stderr(keyResult + \"\\n\");\n return 1;\n }\n let codec;\n try {\n codec = createOpaqueId(brand, { key: keyResult, ...codecOpts(opts) });\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return 1;\n }\n const validation = codec[\"~standard\"].validate(input);\n if (validation.issues) {\n opts.stderr(validation.issues[0]!.message + \"\\n\");\n return 1;\n }\n const canonical = validation.value;\n const timestamp = await codec.extractTimestamp(canonical);\n const nowMs = (opts.now ?? Date.now)();\n const relative = formatRelative(timestamp.getTime(), nowMs);\n const inputLine = describeInputForm(input, canonical);\n opts.stderr(\n \"note: timestamp assumes IDS_KEY matches the key used at generation; a wrong key yields a plausible but incorrect timestamp\\n\",\n );\n opts.stdout(\n [\n `brand: ${brand}`,\n `timestamp: ${timestamp.toISOString()} (${relative})`,\n `canonical: ${canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\"),\n );\n return 0;\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;\nconst msPerMinute = 60 * msPerSecond;\nconst msPerHour = 60 * msPerMinute;\nconst msPerDay = 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\nfunction runGenerate(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n const { flags, values, positionals } = splitFlags(args);\n const [brand] = positionals;\n const count = parseCount(values);\n if (typeof count === \"string\") {\n opts.stderr(count + \"\\n\");\n return Promise.resolve(1);\n }\n const opaque = flags.has(\"--opaque\");\n if (opaque) {\n const format = parseOpaqueKeyFormat(values, opts);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(1);\n }\n return runOpaqueGenerate(brand ?? \"\", count, format, opts);\n }\n let codec;\n try {\n codec = createId(brand ?? \"\", codecOpts(opts));\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return Promise.resolve(1);\n }\n for (let i = 0; i < count; i++) opts.stdout(codec.generate() + \"\\n\");\n return Promise.resolve(0);\n}\n\nasync function runOpaqueGenerate(\n brand: string,\n count: number,\n format: OpaqueKeyFormat,\n opts: RunOpts,\n): Promise<number> {\n const keyResult = await loadOpaqueKey(opts, format);\n if (typeof keyResult === \"string\") {\n opts.stderr(keyResult + \"\\n\");\n return 1;\n }\n let codec;\n try {\n codec = createOpaqueId(brand, { key: keyResult, ...codecOpts(opts) });\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return 1;\n }\n for (let i = 0; i < count; i++) opts.stdout((await codec.generate()) + \"\\n\");\n return 0;\n}\n\nfunction runKeygen(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n const { values } = splitFlags(args);\n const bits = parseBits(values);\n if (typeof bits === \"string\") {\n opts.stderr(bits + \"\\n\");\n return Promise.resolve(1);\n }\n const format = parseKeygenFormat(values);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(1);\n }\n const bytes = new Uint8Array(bits / 8);\n crypto.getRandomValues(bytes);\n opts.stdout(encodeOpaqueKey(bytes, format) + \"\\n\");\n return Promise.resolve(0);\n}\n\nasync function loadOpaqueKey(opts: RunOpts, format: OpaqueKeyFormat): Promise<CryptoKey | string> {\n const env = opts.env ?? process.env;\n const raw = env.IDS_KEY;\n if (raw === undefined || raw === \"\") return \"missing IDS_KEY environment variable\";\n try {\n return importOpaqueKey(decodeOpaqueKey(raw, format));\n } catch (err) {\n return (err as Error).message;\n }\n}\n\nfunction 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 return Number(raw);\n}\n\nfunction 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\nfunction isKeyFormatError(result: OpaqueKeyFormat | string): result is string {\n return result !== \"hex\" && result !== \"base64url\";\n}\n\nfunction parseKeyFormatFlag(values: Map<string, string>): OpaqueKeyFormat | 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\nfunction parseKeygenFormat(values: Map<string, string>): OpaqueKeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag === undefined) return \"hex\";\n return fromFlag;\n}\n\nfunction parseOpaqueKeyFormat(\n values: Map<string, string>,\n opts: RunOpts,\n): OpaqueKeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag !== undefined) return fromFlag;\n const env = opts.env ?? process.env;\n const fromEnv = env.IDS_KEY_FORMAT;\n if (fromEnv === undefined || fromEnv === \"\") return \"hex\";\n if (fromEnv === \"hex\" || fromEnv === \"base64url\") return fromEnv;\n return `IDS_KEY_FORMAT must be hex or base64url, got '${fromEnv}'`;\n}\n\ntype ParsedFlags = {\n flags: Set<string>;\n values: Map<string, string>;\n positionals: 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\nfunction splitFlags(args: ReadonlyArray<string>): ParsedFlags {\n const flags = new Set<string>();\n const values = new Map<string, string>();\n const positionals: string[] = [];\n const valueFlags = new Set([\"--count\", \"-c\", \"--bits\", \"--key-format\"]);\n for (let i = 0; i < args.length; i++) {\n const raw = args[i]!;\n const { flag, inlineValue } = splitFlagToken(raw);\n if (flag === \"--opaque\") {\n flags.add(flag);\n continue;\n }\n if (valueFlags.has(flag)) {\n if (inlineValue !== undefined) {\n flags.add(flag);\n values.set(flag, inlineValue);\n continue;\n }\n const value = args[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n values.set(flag, \"\");\n continue;\n }\n flags.add(flag);\n values.set(flag, value);\n i++;\n continue;\n }\n if (flag.startsWith(\"-\")) {\n flags.add(flag);\n continue;\n }\n positionals.push(raw);\n }\n return { flags, values, positionals };\n}\n\nfunction codecOpts(opts: RunOpts): Partial<Options> {\n // CLI invocations are intentionally ephemeral — one codec per run, never\n // retained — so a repeated `createId(brand)` here is not the bundling/import\n // bug that the duplicate-brand warning is designed to catch.\n const o: Partial<Options> = { 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","#!/usr/bin/env node\nimport { run } from \"../src/cli.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.ts","../bin/cli.ts"],"sourcesContent":["import { createId, type Options } from \"./id.js\";\nimport {\n createOpaqueId,\n decodeOpaqueKey,\n encodeOpaqueKey,\n importOpaqueKey,\n type OpaqueKeyFormat,\n} from \"./opaque.js\";\nimport type { Id } from \"./types.js\";\n\nexport type RunOpts = {\n argv: ReadonlyArray<string>;\n stdout: (chunk: string) => void;\n stderr: (chunk: string) => void;\n now?: Options[\"now\"];\n rng?: Options[\"rng\"];\n /** Defaults to `process.env`. Injected in tests for `IDS_KEY`. */\n env?: Readonly<Record<string, string | undefined>>;\n};\n\nexport async function run(opts: RunOpts): Promise<number> {\n const [subcommand, ...rest] = opts.argv;\n if (subcommand === \"generate\" || subcommand === \"g\") return runGenerate(rest, opts);\n if (subcommand === \"inspect\" || subcommand === \"i\") return runInspect(rest, opts);\n if (subcommand === \"keygen\" || subcommand === \"k\") return runKeygen(rest, opts);\n if (subcommand === undefined || subcommand === \"--help\" || subcommand === \"-h\") {\n opts.stdout(usage());\n return 0;\n }\n opts.stderr(usage());\n return 1;\n}\n\nfunction usage(): string {\n return [\n \"Usage: ids <subcommand> [args]\",\n \"\",\n \"Subcommands:\",\n \" inspect, i <id> [--opaque] [--key-format hex|base64url]\",\n \" Decode an ID and print brand, timestamp, and canonical form.\",\n \" --opaque reads the AES key from IDS_KEY (hex by default; IDS_KEY_FORMAT or --key-format).\",\n \" generate, g <brand> [--count, -c N] [--opaque] [--key-format hex|base64url]\",\n \" Mint one or more 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 \" keygen, k [--bits 128|192|256] [--key-format hex|base64url]\",\n \" Emit a random AES key for importOpaqueKey (stdout only).\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction runInspect(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n const { flags, values, positionals, errors } = splitFlags(args);\n const unsupported = unsupportedFlagForCommand(\n \"inspect\",\n flags,\n new Set([\"--opaque\", \"--key-format\"]),\n );\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return Promise.resolve(1);\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return Promise.resolve(1);\n }\n const [input] = positionals;\n if (input === undefined) {\n opts.stderr(usage());\n return Promise.resolve(1);\n }\n const extra = positionals[1];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return Promise.resolve(1);\n }\n const opaque = flags.has(\"--opaque\");\n if (!opaque && flags.has(\"--key-format\")) {\n opts.stderr(\"--key-format requires --opaque\\n\");\n return Promise.resolve(1);\n }\n const brand = input.slice(0, 3).toLowerCase();\n if (opaque) {\n const format = parseOpaqueKeyFormat(values, opts);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(1);\n }\n return runOpaqueInspect(brand, input, format, opts);\n }\n let codec;\n try {\n codec = createId(brand, codecOpts(opts));\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return Promise.resolve(1);\n }\n const validation = codec[\"~standard\"].validate(input);\n if (validation.issues) {\n opts.stderr(validation.issues[0]!.message + \"\\n\");\n return Promise.resolve(1);\n }\n const canonical = validation.value;\n const timestamp = codec.extractTimestamp(canonical);\n const nowMs = (opts.now ?? Date.now)();\n const relative = formatRelative(timestamp.getTime(), nowMs);\n const inputLine = describeInputForm(input, canonical);\n opts.stdout(\n [\n `brand: ${brand}`,\n `timestamp: ${timestamp.toISOString()} (${relative})`,\n `canonical: ${canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\"),\n );\n return Promise.resolve(0);\n}\n\nasync function runOpaqueInspect(\n brand: string,\n input: string,\n format: OpaqueKeyFormat,\n opts: RunOpts,\n): Promise<number> {\n const keyResult = await loadOpaqueKey(opts, format);\n if (typeof keyResult === \"string\") {\n opts.stderr(keyResult + \"\\n\");\n return 1;\n }\n let codec;\n try {\n codec = createOpaqueId(brand, { key: keyResult, ...codecOpts(opts) });\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return 1;\n }\n const validation = codec[\"~standard\"].validate(input);\n if (validation.issues) {\n opts.stderr(validation.issues[0]!.message + \"\\n\");\n return 1;\n }\n const canonical = validation.value;\n const timestamp = await codec.extractTimestamp(canonical);\n const nowMs = (opts.now ?? Date.now)();\n const relative = formatRelative(timestamp.getTime(), nowMs);\n const inputLine = describeInputForm(input, canonical);\n opts.stderr(\n \"note: timestamp assumes IDS_KEY matches the key used at generation; a wrong key yields a plausible but incorrect timestamp\\n\",\n );\n opts.stdout(\n [\n `brand: ${brand}`,\n `timestamp: ${timestamp.toISOString()} (${relative})`,\n `canonical: ${canonical}`,\n `input: ${inputLine}`,\n \"\",\n ].join(\"\\n\"),\n );\n return 0;\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;\nconst msPerMinute = 60 * msPerSecond;\nconst msPerHour = 60 * msPerMinute;\nconst msPerDay = 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\nfunction runGenerate(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n const { flags, values, positionals, errors } = splitFlags(args);\n const unsupported = unsupportedFlagForCommand(\n \"generate\",\n flags,\n new Set([\"--count\", \"-c\", \"--opaque\", \"--key-format\"]),\n );\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return Promise.resolve(1);\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return Promise.resolve(1);\n }\n const extra = positionals[1];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return Promise.resolve(1);\n }\n const [brand] = positionals;\n const count = parseCount(values);\n if (typeof count === \"string\") {\n opts.stderr(count + \"\\n\");\n return Promise.resolve(1);\n }\n const opaque = flags.has(\"--opaque\");\n if (!opaque && flags.has(\"--key-format\")) {\n opts.stderr(\"--key-format requires --opaque\\n\");\n return Promise.resolve(1);\n }\n if (opaque) {\n const format = parseOpaqueKeyFormat(values, opts);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(1);\n }\n return runOpaqueGenerate(brand ?? \"\", count, format, opts);\n }\n let codec;\n try {\n codec = createId(brand ?? \"\", codecOpts(opts));\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return Promise.resolve(1);\n }\n for (let i = 0; i < count; i++) opts.stdout(codec.generate() + \"\\n\");\n return Promise.resolve(0);\n}\n\nasync function runOpaqueGenerate(\n brand: string,\n count: number,\n format: OpaqueKeyFormat,\n opts: RunOpts,\n): Promise<number> {\n const keyResult = await loadOpaqueKey(opts, format);\n if (typeof keyResult === \"string\") {\n opts.stderr(keyResult + \"\\n\");\n return 1;\n }\n let codec;\n try {\n codec = createOpaqueId(brand, { key: keyResult, ...codecOpts(opts) });\n } catch (err) {\n opts.stderr((err as Error).message + \"\\n\");\n return 1;\n }\n for (let i = 0; i < count; i++) opts.stdout((await codec.generate()) + \"\\n\");\n return 0;\n}\n\nfunction runKeygen(args: ReadonlyArray<string>, opts: RunOpts): Promise<number> {\n const { flags, values, positionals, errors } = splitFlags(args);\n const unsupported = unsupportedFlagForCommand(\n \"keygen\",\n flags,\n new Set([\"--bits\", \"--key-format\"]),\n );\n if (unsupported !== undefined) {\n opts.stderr(unsupported + \"\\n\");\n return Promise.resolve(1);\n }\n if (errors[0] !== undefined) {\n opts.stderr(errors[0] + \"\\n\");\n return Promise.resolve(1);\n }\n const extra = positionals[0];\n if (extra !== undefined) {\n opts.stderr(`unexpected argument: ${extra}\\n`);\n return Promise.resolve(1);\n }\n const bits = parseBits(values);\n if (typeof bits === \"string\") {\n opts.stderr(bits + \"\\n\");\n return Promise.resolve(1);\n }\n const format = parseKeygenFormat(values);\n if (isKeyFormatError(format)) {\n opts.stderr(format + \"\\n\");\n return Promise.resolve(1);\n }\n const bytes = new Uint8Array(bits / 8);\n crypto.getRandomValues(bytes);\n opts.stdout(encodeOpaqueKey(bytes, format) + \"\\n\");\n return Promise.resolve(0);\n}\n\nasync function loadOpaqueKey(opts: RunOpts, format: OpaqueKeyFormat): Promise<CryptoKey | string> {\n const env = opts.env ?? process.env;\n const raw = env.IDS_KEY;\n if (raw === undefined || raw === \"\") return \"missing IDS_KEY environment variable\";\n try {\n return importOpaqueKey(decodeOpaqueKey(raw, format));\n } catch (err) {\n return (err as Error).message;\n }\n}\n\nfunction 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 return Number(raw);\n}\n\nfunction 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\nfunction isKeyFormatError(result: OpaqueKeyFormat | string): result is string {\n return result !== \"hex\" && result !== \"base64url\";\n}\n\nfunction parseKeyFormatFlag(values: Map<string, string>): OpaqueKeyFormat | 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\nfunction parseKeygenFormat(values: Map<string, string>): OpaqueKeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag === undefined) return \"hex\";\n return fromFlag;\n}\n\nfunction parseOpaqueKeyFormat(\n values: Map<string, string>,\n opts: RunOpts,\n): OpaqueKeyFormat | string {\n const fromFlag = parseKeyFormatFlag(values);\n if (fromFlag !== undefined) return fromFlag;\n const env = opts.env ?? process.env;\n const fromEnv = env.IDS_KEY_FORMAT;\n if (fromEnv === undefined || fromEnv === \"\") return \"hex\";\n if (fromEnv === \"hex\" || fromEnv === \"base64url\") return fromEnv;\n return `IDS_KEY_FORMAT must be hex or base64url, got '${fromEnv}'`;\n}\n\ntype 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\nfunction splitFlags(args: ReadonlyArray<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 valueFlags = new Set([\"--count\", \"-c\", \"--bits\", \"--key-format\"]);\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 (flag === \"--opaque\") {\n addFlag(flag);\n if (inlineValue !== undefined) errors.push(\"flag does not take a value: --opaque\");\n continue;\n }\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 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([\"--opaque\", \"--key-format\", \"--count\", \"-c\", \"--bits\"]);\n\nfunction 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\nfunction codecOpts(opts: RunOpts): Partial<Options> {\n // CLI invocations are intentionally ephemeral — one codec per run, never\n // retained — so a repeated `createId(brand)` here is not the bundling/import\n // bug that the duplicate-brand warning is designed to catch.\n const o: Partial<Options> = { 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","#!/usr/bin/env node\nimport { run } from \"../src/cli.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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"}
|