@flametrench/ids 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ declare class InvalidTypeError extends Error {
14
14
  }
15
15
 
16
16
  /**
17
- * Registered type prefixes for Flametrench v0.1.
17
+ * Registered type prefixes for Flametrench.
18
18
  *
19
19
  * Keep this map synchronized with the Flametrench specification's
20
20
  * reserved prefix registry at:
@@ -33,6 +33,11 @@ declare const TYPES: {
33
33
  readonly tup: "authorization_tuple";
34
34
  readonly mfa: "mfa_factor";
35
35
  readonly shr: "share_token";
36
+ readonly pat: "personal_access_token";
37
+ readonly aud: "audit_event";
38
+ readonly file: "file_metadata";
39
+ readonly flag: "feature_flag";
40
+ readonly not: "notification";
36
41
  };
37
42
  type IdType = keyof typeof TYPES;
38
43
  /**
package/dist/index.js CHANGED
@@ -27,7 +27,14 @@ var TYPES = {
27
27
  // v0.2 — Proposed (ADR 0008)
28
28
  mfa: "mfa_factor",
29
29
  // v0.2 — Proposed (ADR 0012)
30
- shr: "share_token"
30
+ shr: "share_token",
31
+ // v0.3 — Proposed (ADR 0016)
32
+ pat: "personal_access_token",
33
+ // v0.4 — Proposed (ADR 0019/0020/0021/0022)
34
+ aud: "audit_event",
35
+ file: "file_metadata",
36
+ flag: "feature_flag",
37
+ not: "notification"
31
38
  };
32
39
  var HEX_PAYLOAD_LENGTH = 32;
33
40
  var HEX_PATTERN = /^[0-9a-f]{32}$/;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts"],"sourcesContent":["// Copyright 2026 NDC Digital, LLC\n// SPDX-License-Identifier: Apache-2.0\n\nimport { v7 as uuidv7, validate as uuidValidate } from \"uuid\";\nimport { InvalidIdError, InvalidTypeError } from \"./errors.js\";\n\nexport { InvalidIdError, InvalidTypeError };\n\n/**\n * Registered type prefixes for Flametrench v0.1.\n *\n * Keep this map synchronized with the Flametrench specification's\n * reserved prefix registry at:\n * https://github.com/flametrench/spec/blob/main/docs/ids.md\n *\n * Parallel implementations (Laravel, future SDKs) must use the same\n * prefixes and semantics.\n */\nexport const TYPES = {\n usr: \"user\",\n org: \"organization\",\n mem: \"membership\",\n inv: \"invitation\",\n ses: \"session\",\n cred: \"credential\",\n tup: \"authorization_tuple\",\n // v0.2 — Proposed (ADR 0008)\n mfa: \"mfa_factor\",\n // v0.2 — Proposed (ADR 0012)\n shr: \"share_token\",\n} as const satisfies Record<string, string>;\n\nexport type IdType = keyof typeof TYPES;\n\n/**\n * The shape returned by {@link decode}.\n */\nexport interface DecodedId {\n type: IdType;\n uuid: string;\n}\n\nconst HEX_PAYLOAD_LENGTH = 32;\nconst HEX_PATTERN = /^[0-9a-f]{32}$/;\nconst VERSION_NIBBLE_PATTERN = /^[1-8]$/;\n\n/**\n * Encode a type and UUID into Flametrench wire format.\n *\n * @example\n * encode(\"usr\", \"0190f2a8-1b3c-7abc-8123-456789abcdef\")\n * // → \"usr_0190f2a81b3c7abc8123456789abcdef\"\n *\n * @throws {InvalidTypeError} If the type prefix is not registered.\n * @throws {InvalidIdError} If the UUID is not a valid UUID.\n */\nexport function encode(type: string, uuid: string): string {\n assertType(type);\n\n if (!uuidValidate(uuid)) {\n throw new InvalidIdError(`Value is not a valid UUID: ${uuid}`);\n }\n\n const hex = uuid.replaceAll(\"-\", \"\").toLowerCase();\n return `${type}_${hex}`;\n}\n\n/**\n * Decode a Flametrench wire-format ID into its type and canonical UUID.\n *\n * @example\n * decode(\"usr_0190f2a81b3c7abc8123456789abcdef\")\n * // → { type: \"usr\", uuid: \"0190f2a8-1b3c-7abc-8123-456789abcdef\" }\n *\n * @throws {InvalidIdError} If the ID is malformed.\n * @throws {InvalidTypeError} If the type prefix is not registered.\n */\nexport function decode(id: string): DecodedId {\n const separator = id.indexOf(\"_\");\n if (separator === -1) {\n throw new InvalidIdError(`ID missing type separator: ${id}`);\n }\n\n const type = id.slice(0, separator);\n const hex = id.slice(separator + 1);\n\n assertType(type);\n\n if (hex.length !== HEX_PAYLOAD_LENGTH || !HEX_PATTERN.test(hex)) {\n throw new InvalidIdError(\n `ID payload is not 32 lowercase hex characters: ${id}`,\n );\n }\n\n // Version nibble (13th hex char) must be 1-8. This rejects the Nil UUID\n // (v0) and Max UUID (v15/f), which the `uuid` package's validate() accepts\n // but are not meaningful identifiers.\n if (!VERSION_NIBBLE_PATTERN.test(hex[12]!)) {\n throw new InvalidIdError(`ID payload is not a valid UUID: ${id}`);\n }\n\n const canonical = [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32),\n ].join(\"-\");\n\n return { type, uuid: canonical };\n}\n\n/**\n * Decode a Flametrench wire-format ID without checking the registered-type set.\n *\n * Use this for backend storage adapters that need to convert wire-format\n * object IDs to canonical UUIDs without knowing the application's\n * domain types in advance — e.g., when an authz tuple has\n * `objectType: \"proj\"` and `objectId: \"proj_0190f2a8...\"`.\n *\n * Validates wire-format shape (separator, 32-char lowercase hex, version\n * nibble 1–8). Does NOT consult `TYPES`. See spec/docs/ids.md.\n *\n * @throws {InvalidIdError} If the ID's structure is malformed. Never\n * throws `InvalidTypeError`.\n */\nexport function decodeAny(id: string): { type: string; uuid: string } {\n const separator = id.indexOf(\"_\");\n if (separator === -1) {\n throw new InvalidIdError(`ID missing type separator: ${id}`);\n }\n\n const type = id.slice(0, separator);\n const hex = id.slice(separator + 1);\n\n if (type.length === 0) {\n throw new InvalidIdError(`ID has empty type prefix: ${id}`);\n }\n\n if (hex.length !== HEX_PAYLOAD_LENGTH || !HEX_PATTERN.test(hex)) {\n throw new InvalidIdError(\n `ID payload is not 32 lowercase hex characters: ${id}`,\n );\n }\n\n if (!VERSION_NIBBLE_PATTERN.test(hex[12]!)) {\n throw new InvalidIdError(`ID payload is not a valid UUID: ${id}`);\n }\n\n const canonical = [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32),\n ].join(\"-\");\n\n return { type, uuid: canonical };\n}\n\n/**\n * Check whether a string is a valid Flametrench wire-format ID.\n *\n * Optionally asserts that the ID is of a specific type.\n *\n * @example\n * isValid(\"usr_0190f2a81b3c7abc8123456789abcdef\") // true\n * isValid(\"usr_0190f2a81b3c7abc8123456789abcdef\", \"org\") // false\n */\nexport function isValid(id: string, expectedType?: IdType): boolean {\n try {\n const decoded = decode(id);\n if (expectedType !== undefined && decoded.type !== expectedType) {\n return false;\n }\n return true;\n } catch (error) {\n if (error instanceof InvalidIdError || error instanceof InvalidTypeError) {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * Extract the type prefix from a wire-format ID.\n *\n * @throws {InvalidIdError} If the ID is malformed.\n * @throws {InvalidTypeError} If the type prefix is not registered.\n */\nexport function typeOf(id: string): IdType {\n return decode(id).type;\n}\n\n/**\n * Generate a fresh wire-format ID of the given type.\n *\n * Uses UUIDv7 so generated IDs are sortable by creation time.\n *\n * @example\n * generate(\"usr\")\n * // → \"usr_0190f2a81b3c7abc8123456789abcdef\"\n *\n * @throws {InvalidTypeError} If the type prefix is not registered.\n */\nexport function generate(type: IdType): string {\n assertType(type);\n return encode(type, uuidv7());\n}\n\n/**\n * Type guard narrowing `unknown` to a valid Flametrench ID string.\n *\n * Useful at API boundaries where incoming values need validation.\n */\nexport function isId(value: unknown, expectedType?: IdType): value is string {\n return typeof value === \"string\" && isValid(value, expectedType);\n}\n\n/**\n * Predicate counterpart to {@link decodeAny}. Returns true for any\n * well-formed wire-format ID regardless of registry membership.\n *\n * Use this when validating input from external systems that may\n * legitimately reference application-defined object types.\n */\nexport function isValidShape(id: string): boolean {\n try {\n decodeAny(id);\n return true;\n } catch (error) {\n if (error instanceof InvalidIdError) {\n return false;\n }\n throw error;\n }\n}\n\nfunction assertType(type: string): asserts type is IdType {\n if (!Object.hasOwn(TYPES, type)) {\n const registered = Object.keys(TYPES).join(\", \");\n throw new InvalidTypeError(\n `Unregistered type prefix: '${type}'. Registered prefixes: ${registered}.`,\n );\n }\n}\n","// Copyright 2026 NDC Digital, LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Thrown when an ID string is malformed or cannot be parsed as a\n * Flametrench wire-format identifier.\n */\nexport class InvalidIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidIdError\";\n }\n}\n\n/**\n * Thrown when an ID uses a type prefix that is not in the registered\n * type prefix set.\n */\nexport class InvalidTypeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidTypeError\";\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts"],"sourcesContent":["// Copyright 2026 NDC Digital, LLC\n// SPDX-License-Identifier: Apache-2.0\n\nimport { v7 as uuidv7, validate as uuidValidate } from \"uuid\";\nimport { InvalidIdError, InvalidTypeError } from \"./errors.js\";\n\nexport { InvalidIdError, InvalidTypeError };\n\n/**\n * Registered type prefixes for Flametrench.\n *\n * Keep this map synchronized with the Flametrench specification's\n * reserved prefix registry at:\n * https://github.com/flametrench/spec/blob/main/docs/ids.md\n *\n * Parallel implementations (Laravel, future SDKs) must use the same\n * prefixes and semantics.\n */\nexport const TYPES = {\n usr: \"user\",\n org: \"organization\",\n mem: \"membership\",\n inv: \"invitation\",\n ses: \"session\",\n cred: \"credential\",\n tup: \"authorization_tuple\",\n // v0.2 — Proposed (ADR 0008)\n mfa: \"mfa_factor\",\n // v0.2 — Proposed (ADR 0012)\n shr: \"share_token\",\n // v0.3 — Proposed (ADR 0016)\n pat: \"personal_access_token\",\n // v0.4 — Proposed (ADR 0019/0020/0021/0022)\n aud: \"audit_event\",\n file: \"file_metadata\",\n flag: \"feature_flag\",\n not: \"notification\",\n} as const satisfies Record<string, string>;\n\nexport type IdType = keyof typeof TYPES;\n\n/**\n * The shape returned by {@link decode}.\n */\nexport interface DecodedId {\n type: IdType;\n uuid: string;\n}\n\nconst HEX_PAYLOAD_LENGTH = 32;\nconst HEX_PATTERN = /^[0-9a-f]{32}$/;\nconst VERSION_NIBBLE_PATTERN = /^[1-8]$/;\n\n/**\n * Encode a type and UUID into Flametrench wire format.\n *\n * @example\n * encode(\"usr\", \"0190f2a8-1b3c-7abc-8123-456789abcdef\")\n * // → \"usr_0190f2a81b3c7abc8123456789abcdef\"\n *\n * @throws {InvalidTypeError} If the type prefix is not registered.\n * @throws {InvalidIdError} If the UUID is not a valid UUID.\n */\nexport function encode(type: string, uuid: string): string {\n assertType(type);\n\n if (!uuidValidate(uuid)) {\n throw new InvalidIdError(`Value is not a valid UUID: ${uuid}`);\n }\n\n const hex = uuid.replaceAll(\"-\", \"\").toLowerCase();\n return `${type}_${hex}`;\n}\n\n/**\n * Decode a Flametrench wire-format ID into its type and canonical UUID.\n *\n * @example\n * decode(\"usr_0190f2a81b3c7abc8123456789abcdef\")\n * // → { type: \"usr\", uuid: \"0190f2a8-1b3c-7abc-8123-456789abcdef\" }\n *\n * @throws {InvalidIdError} If the ID is malformed.\n * @throws {InvalidTypeError} If the type prefix is not registered.\n */\nexport function decode(id: string): DecodedId {\n const separator = id.indexOf(\"_\");\n if (separator === -1) {\n throw new InvalidIdError(`ID missing type separator: ${id}`);\n }\n\n const type = id.slice(0, separator);\n const hex = id.slice(separator + 1);\n\n assertType(type);\n\n if (hex.length !== HEX_PAYLOAD_LENGTH || !HEX_PATTERN.test(hex)) {\n throw new InvalidIdError(\n `ID payload is not 32 lowercase hex characters: ${id}`,\n );\n }\n\n // Version nibble (13th hex char) must be 1-8. This rejects the Nil UUID\n // (v0) and Max UUID (v15/f), which the `uuid` package's validate() accepts\n // but are not meaningful identifiers.\n if (!VERSION_NIBBLE_PATTERN.test(hex[12]!)) {\n throw new InvalidIdError(`ID payload is not a valid UUID: ${id}`);\n }\n\n const canonical = [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32),\n ].join(\"-\");\n\n return { type, uuid: canonical };\n}\n\n/**\n * Decode a Flametrench wire-format ID without checking the registered-type set.\n *\n * Use this for backend storage adapters that need to convert wire-format\n * object IDs to canonical UUIDs without knowing the application's\n * domain types in advance — e.g., when an authz tuple has\n * `objectType: \"proj\"` and `objectId: \"proj_0190f2a8...\"`.\n *\n * Validates wire-format shape (separator, 32-char lowercase hex, version\n * nibble 1–8). Does NOT consult `TYPES`. See spec/docs/ids.md.\n *\n * @throws {InvalidIdError} If the ID's structure is malformed. Never\n * throws `InvalidTypeError`.\n */\nexport function decodeAny(id: string): { type: string; uuid: string } {\n const separator = id.indexOf(\"_\");\n if (separator === -1) {\n throw new InvalidIdError(`ID missing type separator: ${id}`);\n }\n\n const type = id.slice(0, separator);\n const hex = id.slice(separator + 1);\n\n if (type.length === 0) {\n throw new InvalidIdError(`ID has empty type prefix: ${id}`);\n }\n\n if (hex.length !== HEX_PAYLOAD_LENGTH || !HEX_PATTERN.test(hex)) {\n throw new InvalidIdError(\n `ID payload is not 32 lowercase hex characters: ${id}`,\n );\n }\n\n if (!VERSION_NIBBLE_PATTERN.test(hex[12]!)) {\n throw new InvalidIdError(`ID payload is not a valid UUID: ${id}`);\n }\n\n const canonical = [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20, 32),\n ].join(\"-\");\n\n return { type, uuid: canonical };\n}\n\n/**\n * Check whether a string is a valid Flametrench wire-format ID.\n *\n * Optionally asserts that the ID is of a specific type.\n *\n * @example\n * isValid(\"usr_0190f2a81b3c7abc8123456789abcdef\") // true\n * isValid(\"usr_0190f2a81b3c7abc8123456789abcdef\", \"org\") // false\n */\nexport function isValid(id: string, expectedType?: IdType): boolean {\n try {\n const decoded = decode(id);\n if (expectedType !== undefined && decoded.type !== expectedType) {\n return false;\n }\n return true;\n } catch (error) {\n if (error instanceof InvalidIdError || error instanceof InvalidTypeError) {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * Extract the type prefix from a wire-format ID.\n *\n * @throws {InvalidIdError} If the ID is malformed.\n * @throws {InvalidTypeError} If the type prefix is not registered.\n */\nexport function typeOf(id: string): IdType {\n return decode(id).type;\n}\n\n/**\n * Generate a fresh wire-format ID of the given type.\n *\n * Uses UUIDv7 so generated IDs are sortable by creation time.\n *\n * @example\n * generate(\"usr\")\n * // → \"usr_0190f2a81b3c7abc8123456789abcdef\"\n *\n * @throws {InvalidTypeError} If the type prefix is not registered.\n */\nexport function generate(type: IdType): string {\n assertType(type);\n return encode(type, uuidv7());\n}\n\n/**\n * Type guard narrowing `unknown` to a valid Flametrench ID string.\n *\n * Useful at API boundaries where incoming values need validation.\n */\nexport function isId(value: unknown, expectedType?: IdType): value is string {\n return typeof value === \"string\" && isValid(value, expectedType);\n}\n\n/**\n * Predicate counterpart to {@link decodeAny}. Returns true for any\n * well-formed wire-format ID regardless of registry membership.\n *\n * Use this when validating input from external systems that may\n * legitimately reference application-defined object types.\n */\nexport function isValidShape(id: string): boolean {\n try {\n decodeAny(id);\n return true;\n } catch (error) {\n if (error instanceof InvalidIdError) {\n return false;\n }\n throw error;\n }\n}\n\nfunction assertType(type: string): asserts type is IdType {\n if (!Object.hasOwn(TYPES, type)) {\n const registered = Object.keys(TYPES).join(\", \");\n throw new InvalidTypeError(\n `Unregistered type prefix: '${type}'. Registered prefixes: ${registered}.`,\n );\n }\n}\n","// Copyright 2026 NDC Digital, LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Thrown when an ID string is malformed or cannot be parsed as a\n * Flametrench wire-format identifier.\n */\nexport class InvalidIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidIdError\";\n }\n}\n\n/**\n * Thrown when an ID uses a type prefix that is not in the registered\n * type prefix set.\n */\nexport class InvalidTypeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidTypeError\";\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flametrench/ids",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Prefixed wire-format IDs for Flametrench. UUIDv7 storage, self-describing public identifiers.",
5
5
  "license": "Apache-2.0",
6
6
  "author": {