{"version":3,"sources":["../../src/zod/index.ts","../../src/zod/schemas.ts","../../src/core/errors.ts","../../src/core/types.ts","../../src/core/internal.ts","../../src/core/entity-id.ts"],"sourcesContent":["export { entityIdSchema } from \"./schemas.js\";\nexport type { EntityIdSchemaOutput } from \"./schemas.js\";\n","import { z } from \"zod\";\n\nimport { parseEntityId } from \"../core/entity-id.js\";\n\nexport const entityIdSchema = z\n  .string()\n  .transform((value, ctx) => {\n    try {\n      return parseEntityId(value);\n    } catch (err) {\n      ctx.addIssue({\n        code: \"custom\",\n        message: err instanceof Error ? err.message : \"Invalid entity id\",\n      });\n      return z.NEVER;\n    }\n  });\n\nexport type EntityIdSchemaOutput = z.infer<typeof entityIdSchema>;\n","export const ENTITY_ID_PARSE_CODE = \"ENTITY_ID_PARSE\" as const;\n\nexport class EntityIdParseError extends Error {\n  readonly code = ENTITY_ID_PARSE_CODE;\n\n  constructor(message: string) {\n    super(message);\n    this.name = \"EntityIdParseError\";\n  }\n}\n","/** Canonical lowercase UUID string with hyphens (RFC 9562 UUID v7). */\nexport type EntityId = string & { readonly __brand: unique symbol };\n\nexport const ENTITY_ID_VERSION = 7 as const;\n\nexport const MAX_ENTITY_ID_UNIX_MS = 0xffff_ffff_ffff;\n","import { EntityIdParseError } from \"./errors.js\";\nimport type { EntityId } from \"./types.js\";\nimport { ENTITY_ID_VERSION, MAX_ENTITY_ID_UNIX_MS } from \"./types.js\";\n\nconst HYPHENATED =\n  /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\nexport function bytesToCanonicalUuid(bytes: Uint8Array): EntityId {\n  const hex = [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n  const canonical =\n    `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n  return canonical as EntityId;\n}\n\nexport function canonicalUuidToBytes(id: string): Uint8Array {\n  const compact = id.replace(/-/g, \"\").toLowerCase();\n  if (compact.length !== 32 || !/^[0-9a-f]+$/.test(compact)) {\n    throw new EntityIdParseError(\"Entity id must be 32 hex digits (optional hyphens)\");\n  }\n  const bytes = new Uint8Array(16);\n  for (let i = 0; i < 16; i++) {\n    bytes[i] = Number.parseInt(compact.slice(i * 2, i * 2 + 2), 16);\n  }\n  return bytes;\n}\n\nexport function assertEntityIdV7(bytes: Uint8Array): void {\n  const version = (bytes[6]! >> 4) & 0x0f;\n  if (version !== ENTITY_ID_VERSION) {\n    throw new EntityIdParseError(\n      `Entity id must be UUID version ${ENTITY_ID_VERSION}, got version ${version}`,\n    );\n  }\n  const variant = (bytes[8]! >> 6) & 0x03;\n  if (variant !== 0b10) {\n    throw new EntityIdParseError(\"Entity id must use RFC 4122 variant (10xxxxxx)\");\n  }\n}\n\nexport function unixMsFromV7Bytes(bytes: Uint8Array): number {\n  const ms =\n    (BigInt(bytes[0]!) << 40n) |\n    (BigInt(bytes[1]!) << 32n) |\n    (BigInt(bytes[2]!) << 24n) |\n    (BigInt(bytes[3]!) << 16n) |\n    (BigInt(bytes[4]!) << 8n) |\n    BigInt(bytes[5]!);\n  return Number(ms);\n}\n\nexport function generateEntityIdBytes(\n  unixMs: number,\n  random: Uint8Array,\n): Uint8Array {\n  if (!Number.isFinite(unixMs) || unixMs < 0 || unixMs > MAX_ENTITY_ID_UNIX_MS) {\n    throw new EntityIdParseError(\n      `Unix timestamp ms out of range for UUID v7 (0..${MAX_ENTITY_ID_UNIX_MS})`,\n    );\n  }\n  if (random.length < 10) {\n    throw new EntityIdParseError(\"Random bytes must be at least 10 octets\");\n  }\n\n  const ts = BigInt(Math.trunc(unixMs));\n  const bytes = new Uint8Array(16);\n  bytes[0] = Number((ts >> 40n) & 0xffn);\n  bytes[1] = Number((ts >> 32n) & 0xffn);\n  bytes[2] = Number((ts >> 24n) & 0xffn);\n  bytes[3] = Number((ts >> 16n) & 0xffn);\n  bytes[4] = Number((ts >> 8n) & 0xffn);\n  bytes[5] = Number(ts & 0xffn);\n\n  bytes[6] = (random[0]! & 0x0f) | 0x70;\n  bytes[7] = random[1]!;\n  bytes[8] = (random[2]! & 0x3f) | 0x80;\n  bytes[9] = random[3]!;\n  bytes[10] = random[4]!;\n  bytes[11] = random[5]!;\n  bytes[12] = random[6]!;\n  bytes[13] = random[7]!;\n  bytes[14] = random[8]!;\n  bytes[15] = random[9]!;\n\n  return bytes;\n}\n\nexport function isHyphenatedUuidLower(value: string): boolean {\n  return HYPHENATED.test(value);\n}\n","import { EntityIdParseError } from \"./errors.js\";\nimport {\n  assertEntityIdV7,\n  bytesToCanonicalUuid,\n  canonicalUuidToBytes,\n  generateEntityIdBytes,\n  isHyphenatedUuidLower,\n  unixMsFromV7Bytes,\n} from \"./internal.js\";\nimport type { EntityId } from \"./types.js\";\n\nfunction randomOctets(length: number): Uint8Array {\n  const bytes = new Uint8Array(length);\n  crypto.getRandomValues(bytes);\n  return bytes;\n}\n\n/** Default Eristack `idFactory` — UUID v7, not DB serial or `randomUUID`. */\nexport function entityIdFactory(): EntityId {\n  return generateEntityId();\n}\n\nexport function generateEntityId(unixMs: number = Date.now()): EntityId {\n  const rnd = randomOctets(10);\n  const bytes = generateEntityIdBytes(unixMs, rnd);\n  return bytesToCanonicalUuid(bytes);\n}\n\n/** Deterministic generation for tests — same ms + random → same id. */\nexport function generateEntityIdAt(\n  unixMs: number,\n  random: Uint8Array,\n): EntityId {\n  const bytes = generateEntityIdBytes(unixMs, random);\n  return bytesToCanonicalUuid(bytes);\n}\n\nexport function normalizeEntityId(value: string): EntityId {\n  const trimmed = value.trim().toLowerCase();\n  const canonical = trimmed.includes(\"-\")\n    ? trimmed\n    : `${trimmed.slice(0, 8)}-${trimmed.slice(8, 12)}-${trimmed.slice(12, 16)}-${trimmed.slice(16, 20)}-${trimmed.slice(20)}`;\n\n  if (!isHyphenatedUuidLower(canonical)) {\n    throw new EntityIdParseError(\"Entity id must be a lowercase UUID string\");\n  }\n\n  const bytes = canonicalUuidToBytes(canonical);\n  assertEntityIdV7(bytes);\n  return canonical as EntityId;\n}\n\nexport function parseEntityId(value: string): EntityId {\n  return normalizeEntityId(value);\n}\n\nexport function isValidEntityId(value: string): boolean {\n  try {\n    parseEntityId(value);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nexport function entityIdToUnixMs(id: EntityId): number {\n  const bytes = canonicalUuidToBytes(id);\n  assertEntityIdV7(bytes);\n  return unixMsFromV7Bytes(bytes);\n}\n\nexport function entityIdToDate(id: EntityId): Date {\n  return new Date(entityIdToUnixMs(id));\n}\n\n/** Lexicographic compare — matches time order for ids from `generateEntityId`. */\nexport function compareEntityIds(a: EntityId, b: EntityId): number {\n  return a.localeCompare(b);\n}\n\nexport function entityIdEquals(a: string, b: string): boolean {\n  try {\n    return parseEntityId(a) === parseEntityId(b);\n  } catch {\n    return false;\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAAkB;;;ACAX,IAAM,uBAAuB;AAE7B,IAAM,qBAAN,cAAiC,MAAM;AAAA,EACnC,OAAO;AAAA,EAEhB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;ACNO,IAAM,oBAAoB;;;ACCjC,IAAM,aACJ;AASK,SAAS,qBAAqB,IAAwB;AAC3D,QAAM,UAAU,GAAG,QAAQ,MAAM,EAAE,EAAE,YAAY;AACjD,MAAI,QAAQ,WAAW,MAAM,CAAC,cAAc,KAAK,OAAO,GAAG;AACzD,UAAM,IAAI,mBAAmB,oDAAoD;AAAA,EACnF;AACA,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,CAAC,IAAI,OAAO,SAAS,QAAQ,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AAAA,EAChE;AACA,SAAO;AACT;AAEO,SAAS,iBAAiB,OAAyB;AACxD,QAAM,UAAW,MAAM,CAAC,KAAM,IAAK;AACnC,MAAI,YAAY,mBAAmB;AACjC,UAAM,IAAI;AAAA,MACR,kCAAkC,iBAAiB,iBAAiB,OAAO;AAAA,IAC7E;AAAA,EACF;AACA,QAAM,UAAW,MAAM,CAAC,KAAM,IAAK;AACnC,MAAI,YAAY,GAAM;AACpB,UAAM,IAAI,mBAAmB,gDAAgD;AAAA,EAC/E;AACF;AAiDO,SAAS,sBAAsB,OAAwB;AAC5D,SAAO,WAAW,KAAK,KAAK;AAC9B;;;ACnDO,SAAS,kBAAkB,OAAyB;AACzD,QAAM,UAAU,MAAM,KAAK,EAAE,YAAY;AACzC,QAAM,YAAY,QAAQ,SAAS,GAAG,IAClC,UACA,GAAG,QAAQ,MAAM,GAAG,CAAC,CAAC,IAAI,QAAQ,MAAM,GAAG,EAAE,CAAC,IAAI,QAAQ,MAAM,IAAI,EAAE,CAAC,IAAI,QAAQ,MAAM,IAAI,EAAE,CAAC,IAAI,QAAQ,MAAM,EAAE,CAAC;AAEzH,MAAI,CAAC,sBAAsB,SAAS,GAAG;AACrC,UAAM,IAAI,mBAAmB,2CAA2C;AAAA,EAC1E;AAEA,QAAM,QAAQ,qBAAqB,SAAS;AAC5C,mBAAiB,KAAK;AACtB,SAAO;AACT;AAEO,SAAS,cAAc,OAAyB;AACrD,SAAO,kBAAkB,KAAK;AAChC;;;AJlDO,IAAM,iBAAiB,aAC3B,OAAO,EACP,UAAU,CAAC,OAAO,QAAQ;AACzB,MAAI;AACF,WAAO,cAAc,KAAK;AAAA,EAC5B,SAAS,KAAK;AACZ,QAAI,SAAS;AAAA,MACX,MAAM;AAAA,MACN,SAAS,eAAe,QAAQ,IAAI,UAAU;AAAA,IAChD,CAAC;AACD,WAAO,aAAE;AAAA,EACX;AACF,CAAC;","names":[]}