{"version":3,"sources":["../src/store/reserved-keys.ts","../src/core/json-value.ts"],"names":["z","isPlainObject","ConfigurationError","createDataKeyedBag"],"mappings":"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","file":"chunk-JLSXOBLQ.cjs","sourcesContent":["/**\n * Reserved Keys for Store Entities\n *\n * Structural keys that cannot be overwritten by user-defined properties.\n * Shared across row-mappers, subgraph projection, and schema validation.\n */\nimport { z } from \"zod\";\n\nimport type { KindEntity } from \"../core/types\";\nimport { ConfigurationError } from \"../errors\";\nimport { createDataKeyedBag, isPlainObject } from \"../utils/object\";\n\nexport const RESERVED_NODE_KEYS: ReadonlySet<string> = new Set([\n  \"id\",\n  \"kind\",\n  \"meta\",\n]);\n\nexport const RESERVED_EDGE_KEYS: ReadonlySet<string> = new Set([\n  \"id\",\n  \"kind\",\n  \"meta\",\n  \"fromKind\",\n  \"fromId\",\n  \"toKind\",\n  \"toId\",\n]);\n\nconst PROTOTYPE_POLLUTION_KEYS: ReadonlySet<string> = new Set([\n  \"__proto__\",\n  \"constructor\",\n  \"prototype\",\n]);\n\n/**\n * The property name the SCHEMA LAYER cannot carry, and the single owner of that\n * question — every authoring path asks here rather than re-spelling the literal.\n *\n * Zod accepts `__proto__` in a shape but drops it from every parse result, and\n * reports success even when the field is required, so a value written to such a\n * field is silently lost. A declaration naming it is therefore refused rather\n * than accepted as a field the storage layer can never honor.\n *\n * TWO authoring paths ask, and they stay separate walkers by necessity — one\n * traverses Zod schemas (`defineNode` / `defineEdge`, below), the other JSON\n * property descriptors (`validateGraphExtension`, in\n * ./../graph-extension/validation.ts) — but the VERDICT and the reason they give\n * for it are shared from here, because a name unstorable on one path is\n * unstorable on the other: both compile to the same `z.object(...)`.\n */\nconst UNSTORABLE_PROPERTY_NAME = \"__proto__\";\n\n/**\n * The shared explanation both authoring paths give when they refuse\n * {@link UNSTORABLE_PROPERTY_NAME}, so the two refusals read as one rule.\n */\nexport const UNSTORABLE_PROPERTY_NAME_REASON =\n  \"schema validation cannot carry it\";\n\n/** See {@link UNSTORABLE_PROPERTY_NAME}. */\nexport function isUnstorablePropertyName(name: string): boolean {\n  return name === UNSTORABLE_PROPERTY_NAME;\n}\n\n/**\n * Renders a nested property path for a refusal message: object field names\n * joined by `.`, with the wrappers between them (optional, array, union, …)\n * contributing no segment because they name nothing.\n */\nfunction formatSchemaPath(segments: readonly string[]): string {\n  return segments.join(\".\");\n}\n\n/** How a refusal names a location that is the schema itself, not a field. */\nconst SCHEMA_ROOT_PATH_LABEL = \"(schema root)\";\n\n/**\n * Every schema reachable one step down from `value` — a schema, an array of\n * them, or a plain object holding them.\n *\n * Deliberately STRUCTURAL rather than a per-Zod-type enumeration: every\n * composite (`array`, `record`, `map`, `set`, `tuple`, `union`, `intersection`,\n * `pipe`) and every wrapper (`optional`, `nullable`, `default`, `prefault`,\n * `catch`, `readonly`, `nonoptional`, `promise`) stores its inner schemas as\n * ordinary values of the public {@link z.ZodType.def} record, so one walk covers\n * all of them — including any Zod adds later. An enumeration would silently\n * stop covering the type it forgot, which is precisely how this defect class\n * survived a depth-0-only fix.\n */\nfunction collectNestedSchemas(value: unknown, found: z.ZodType[]): void {\n  if (value instanceof z.ZodType) {\n    found.push(value);\n    return;\n  }\n  if (Array.isArray(value)) {\n    for (const item of value) collectNestedSchemas(item, found);\n    return;\n  }\n  if (isPlainObject(value)) {\n    for (const nested of Object.values(value)) {\n      collectNestedSchemas(nested, found);\n    }\n  }\n}\n\n/** A `z.lazy` whose getter could not run, and where in the schema it sits. */\ntype UnresolvableLazy = Readonly<{ path: string; cause: unknown }>;\n\n/** What one walk of a schema found. */\ntype SchemaFindings = Readonly<{\n  unstorable: string[];\n  unresolvableLazy: UnresolvableLazy[];\n}>;\n\n/**\n * The inner schema of a `z.lazy`, or the reason its getter could not run.\n *\n * `z.lazy` is the one shape the structural walk cannot see — its inner schema\n * hangs off a `getter` FUNCTION rather than a `def` value — so it is unwrapped\n * through the public `unwrap()`, which RUNS that getter. Running it is the only\n * way to inspect what it wraps, and the `visited` set in the caller makes the\n * resulting recursion safe for a self-referential schema.\n *\n * The failure is REPORTED rather than swallowed, and that is the whole contract\n * of this function. `unwrap()` throws when the getter names a binding still in\n * its temporal dead zone — a mutually recursive pair whose second `z.object`\n * const is declared AFTER the `defineNode` call that walks the first. Returning\n * `undefined` there made the walk fail OPEN: the subtree was never judged, and\n * because a definition is validated exactly once, it was never judged later\n * either — so a nested `__proto__` under that subtree was accepted at\n * definition time and then silently dropped by every parse, which is the exact\n * defect this validation exists to prevent. A branch that cannot be looked at\n * is refused, not waved through.\n */\nfunction resolveLazySchema(schema: z.ZodLazy<z.core.SomeType>):\n  | Readonly<{ resolved: true; inner: unknown }>\n  | Readonly<{\n      resolved: false;\n      cause: unknown;\n    }> {\n  try {\n    return { resolved: true, inner: schema.unwrap() };\n  } catch (error) {\n    return { resolved: false, cause: error };\n  }\n}\n\n/**\n * The schemas nested directly inside `schema`, recording an unrunnable `z.lazy`\n * getter in `findings` instead of quietly yielding nothing for it.\n */\nfunction nestedSchemasOf(\n  schema: z.ZodType,\n  path: readonly string[],\n  findings: SchemaFindings,\n): readonly z.ZodType[] {\n  const found: z.ZodType[] = [];\n  if (schema instanceof z.ZodLazy) {\n    const resolution = resolveLazySchema(schema);\n    if (!resolution.resolved) {\n      findings.unresolvableLazy.push({\n        path: formatSchemaPath(path),\n        cause: resolution.cause,\n      });\n      return found;\n    }\n    collectNestedSchemas(resolution.inner, found);\n    return found;\n  }\n  collectNestedSchemas(Object.values(schema.def), found);\n  return found;\n}\n\n/**\n * Collects the path of every property named {@link UNSTORABLE_PROPERTY_NAME}\n * anywhere in `schema`, at any depth and behind any wrapper — and the path of\n * every `z.lazy` that stopped the walk from getting there.\n *\n * `visited` both terminates recursive schemas and keeps a schema reused under\n * several fields from being re-walked; a name is reported once, which is enough\n * to refuse the definition.\n */\nfunction collectSchemaFindings(\n  schema: z.ZodType,\n  path: readonly string[],\n  visited: Set<z.ZodType>,\n  findings: SchemaFindings,\n): void {\n  if (visited.has(schema)) return;\n  visited.add(schema);\n\n  if (schema instanceof z.ZodObject) {\n    // A ZodObject is the only schema that NAMES anything, so its fields are\n    // walked here, by name, rather than through the structural pass below.\n    for (const [propertyName, field] of Object.entries(schema.shape)) {\n      const fieldPath = [...path, propertyName];\n      if (isUnstorablePropertyName(propertyName)) {\n        findings.unstorable.push(formatSchemaPath(fieldPath));\n      }\n      if (field instanceof z.ZodType) {\n        collectSchemaFindings(field, fieldPath, visited, findings);\n      }\n    }\n  }\n\n  // Runs for a ZodObject too, so its `catchall` is covered; the shape schemas it\n  // re-reaches are already in `visited` and cost one set lookup each.\n  for (const nested of nestedSchemasOf(schema, path, findings)) {\n    collectSchemaFindings(nested, path, visited, findings);\n  }\n}\n\n/**\n * Properties starting with `$` are reserved for TypeGraph-owned accessors\n * on the query-builder node/edge proxies (today: `$fulltext`). Reserving\n * the whole prefix — not just the currently-used names — keeps future\n * accessors (e.g. `$vector`, `$json`) from colliding with user fields.\n */\nconst RESERVED_PROPERTY_PREFIX = \"$\";\n\n/**\n * True if a user-defined field name is reserved by TypeGraph's accessor\n * namespace. `defineNode` / `defineEdge` call this against schema keys so\n * the collision fails fast at graph-definition time rather than silently\n * at query time.\n */\nfunction isReservedPropertyName(name: string): boolean {\n  return name.startsWith(RESERVED_PROPERTY_PREFIX);\n}\n\n/**\n * Validates that a node or edge schema does not use any reserved property\n * name. Covers the unstorable name (at ANY depth), the structural keys (`id`,\n * `kind`, etc.) and the `$`-prefix accessor namespace. Throws a single\n * `ConfigurationError` per conflict class so the user sees all collisions in\n * one pass.\n *\n * A FOURTH class is refused here, and it is about the verdict rather than about\n * a name: a `z.lazy` whose getter cannot run yet. The walk must be able to see\n * the whole schema to answer at all, this is the only moment it ever runs, and\n * a branch it could not enter is a branch nothing will ever check. Refusing is\n * the fail-CLOSED reading of \"cannot judge\"; returning a clean verdict for a\n * subtree that was never looked at is the fail-open one.\n *\n * Takes the SCHEMA rather than its top-level key list: the unstorable-name\n * check is recursive, and a caller that could only hand over `Object.keys(\n * schema.shape)` could not express that.\n *\n * The structural and `$`-prefix classes stay top-level-only, and that is a\n * decision rather than an omission: both are about names TypeGraph itself\n * occupies on the node/edge OBJECT it hands back (`id`, `kind`, `meta`,\n * `$fulltext`), and nothing is projected onto a nested object, so a nested\n * field may legitimately be called `id`. Only unstorability is a property of\n * the schema layer at every depth.\n */\nexport function assertSchemaKeysAreFree(\n  entityKind: \"Node\" | \"Edge\",\n  name: string,\n  schema: z.ZodObject<z.ZodRawShape>,\n  reservedStructuralKeys: ReadonlySet<string>,\n): void {\n  // A field named `__proto__` is UNSTORABLE, not merely reserved: Zod accepts\n  // it in a shape but drops it from every parse result — and reports success\n  // even when the field is required — so a write to it is silently lost.\n  //\n  // `validateGraphExtension` already refuses exactly this declaration for a\n  // kind authored as a JSON document (`RESERVED_PROPERTY_NAME`), AT ANY DEPTH.\n  // Checking only the top-level shape here left the two authoring paths\n  // disagreeing again one level down: `z.object({ payload: z.object({\n  // [\"__proto__\"]: z.string() }) })` was accepted, and the nested write was\n  // dropped at parse exactly as the top-level one had been.\n  //\n  // Reachable only through a COMPUTED key — `z.object({ __proto__: … })`\n  // written literally sets the shape object's prototype instead of creating\n  // the entry — but `z.object({ [\"__proto__\"]: z.string() })` yields a shape\n  // whose `Object.keys` really does contain it.\n  const findings: SchemaFindings = { unstorable: [], unresolvableLazy: [] };\n  collectSchemaFindings(schema, [], new Set(), findings);\n\n  // Refused FIRST, because it is the reason the rest of the verdict may be\n  // incomplete: an unrunnable `z.lazy` getter hides everything beneath it, and\n  // a definition is validated exactly once, so \"judge it later\" is not on\n  // offer. See `resolveLazySchema`.\n  if (findings.unresolvableLazy.length > 0) {\n    const label = entityKind.toLowerCase();\n    const locations = findings.unresolvableLazy.map((lazy) =>\n      lazy.path === \"\" ? SCHEMA_ROOT_PATH_LABEL : lazy.path,\n    );\n    throw new ConfigurationError(\n      `${entityKind} \"${name}\" schema contains a z.lazy() whose schema is not available yet at ${label}-definition time: ${locations.join(\", \")}`,\n      {\n        [`${label}Type`]: name,\n        conflicts: locations,\n      },\n      {\n        cause: findings.unresolvableLazy[0]?.cause,\n        suggestion:\n          `Declare every schema the lazy getter references BEFORE this ` +\n          `define${entityKind} call — a mutually recursive pair works when ` +\n          `both z.object() consts are initialized first, and the getters then ` +\n          `resolve. TypeGraph must read through the whole schema at definition ` +\n          `time to refuse property names it cannot store, and a getter that ` +\n          `throws leaves that subtree unchecked forever.`,\n      },\n    );\n  }\n\n  const unstorableConflicts = findings.unstorable;\n  if (unstorableConflicts.length > 0) {\n    const label = entityKind.toLowerCase();\n    throw new ConfigurationError(\n      `${entityKind} \"${name}\" schema declares a property named \"${UNSTORABLE_PROPERTY_NAME}\", which ${UNSTORABLE_PROPERTY_NAME_REASON}: ${unstorableConflicts.join(\", \")}`,\n      {\n        [`${label}Type`]: name,\n        conflicts: unstorableConflicts,\n      },\n      {\n        suggestion: `Rename the property at ${unstorableConflicts.join(\", \")}. Zod drops \"${UNSTORABLE_PROPERTY_NAME}\" from every parse result, so a value written to it would be silently lost.`,\n      },\n    );\n  }\n\n  const keys = Object.keys(schema.shape);\n  const structuralConflicts = keys.filter((key) =>\n    reservedStructuralKeys.has(key),\n  );\n  if (structuralConflicts.length > 0) {\n    const label = entityKind.toLowerCase();\n    throw new ConfigurationError(\n      `${entityKind} \"${name}\" schema contains reserved property names: ${structuralConflicts.join(\", \")}`,\n      {\n        [`${label}Type`]: name,\n        conflicts: structuralConflicts,\n        reservedKeys: [...reservedStructuralKeys],\n      },\n      {\n        suggestion: `Rename the conflicting properties. Reserved names (${[...reservedStructuralKeys].join(\", \")}) are added automatically to all ${label}s.`,\n      },\n    );\n  }\n\n  const prefixConflicts = keys.filter((key) => isReservedPropertyName(key));\n  if (prefixConflicts.length > 0) {\n    const label = entityKind.toLowerCase();\n    throw new ConfigurationError(\n      `${entityKind} \"${name}\" schema uses the reserved \"${RESERVED_PROPERTY_PREFIX}\" prefix on: ${prefixConflicts.join(\", \")}`,\n      {\n        [`${label}Type`]: name,\n        conflicts: prefixConflicts,\n        reservedPrefix: RESERVED_PROPERTY_PREFIX,\n      },\n      {\n        suggestion: `Property names starting with \"${RESERVED_PROPERTY_PREFIX}\" are reserved for TypeGraph accessors (e.g. $fulltext). Rename each field.`,\n      },\n    );\n  }\n}\n\n/**\n * Validates that a projection field name is safe to assign onto a result object.\n * Rejects reserved structural keys and prototype-pollution vectors.\n *\n * @throws ConfigurationError if the field is reserved or dangerous\n */\nexport function validateProjectionField(\n  field: string,\n  entityType: KindEntity,\n  kind: string,\n): void {\n  const reserved =\n    entityType === \"node\" ? RESERVED_NODE_KEYS : RESERVED_EDGE_KEYS;\n\n  if (reserved.has(field)) {\n    throw new ConfigurationError(\n      `Projection field \"${field}\" on ${entityType} kind \"${kind}\" conflicts with a reserved structural key`,\n      { field, kind, entityType, reservedKeys: [...reserved] },\n      {\n        suggestion: `Remove \"${field}\" from the projection. Structural fields (${[...reserved].join(\", \")}) are included automatically when relevant.`,\n      },\n    );\n  }\n\n  if (PROTOTYPE_POLLUTION_KEYS.has(field)) {\n    throw new ConfigurationError(\n      `Projection field \"${field}\" on ${entityType} kind \"${kind}\" is not allowed`,\n      { field, kind, entityType },\n      {\n        suggestion: `\"${field}\" cannot be used as a projection field name.`,\n      },\n    );\n  }\n}\n\n/**\n * Filters out reserved keys from a props object to prevent runtime collisions.\n */\nexport function filterReservedKeys(\n  props: Record<string, unknown>,\n  reservedKeys: ReadonlySet<string>,\n): Record<string, unknown> {\n  // Props keys are DATA (a trusted import writes a caller's bag verbatim, and\n  // `JSON.parse` yields `__proto__` as an own key), so the accumulator must be\n  // null-prototype — a `{}` literal would answer `filtered[\"__proto__\"] = v`\n  // with the prototype setter and silently drop the value.\n  const filtered = createDataKeyedBag<unknown>();\n  for (const [key, value] of Object.entries(props)) {\n    if (!reservedKeys.has(key)) {\n      filtered[key] = value;\n    }\n  }\n  return filtered;\n}\n","/**\n * Runtime validation for JSON-serializable values.\n *\n * Used at definition-time boundaries (e.g., `defineNode`/`defineEdge` annotations)\n * to reject values that would silently break `JSON.stringify` round-trips or\n * throw at hash time. Catches accidental violations from untyped JS callers\n * and `as any` escape hatches that bypass the `JsonValue` type.\n */\nimport { ConfigurationError } from \"../errors\";\nimport { createDataKeyedBag, isPlainObject } from \"../utils/object\";\nimport {\n  type GraphAnnotations,\n  type JsonValue,\n  type KindAnnotations,\n} from \"./types\";\n\n/**\n * Asserts that `value` is JSON-serializable.\n *\n * Throws `ConfigurationError` with a dotted path identifying the offending\n * field. Rejects `bigint`, `function`, `symbol`, `undefined`, and class\n * instances such as `Date`, `Map`, `Set`, regex literals, and Buffers — all\n * of which either throw or silently coerce under `JSON.stringify`.\n *\n * @param value - The value to validate\n * @param rootLabel - Label for the root of the value (e.g., `\"annotations\"`)\n *   used as the prefix of the error path\n * @param ownerKind - Human-readable owner identifier for the error message\n *   (e.g., `'Node \"Person\"'`)\n */\nexport function assertJsonValue(\n  value: unknown,\n  rootLabel: string,\n  ownerKind: string,\n): void {\n  walk(value, rootLabel, ownerKind);\n}\n\n/** Validates the object-shaped JSON contract shared by graph annotations. */\nexport function assertGraphAnnotations(\n  value: unknown,\n  ownerLabel: string,\n): asserts value is GraphAnnotations {\n  if (!isPlainObject(value)) {\n    throw new ConfigurationError(\n      `${ownerLabel} annotations must be a plain JSON object.`,\n      {\n        path: \"annotations\",\n        valueKind: Array.isArray(value) ? \"array\" : typeof value,\n      },\n      {\n        suggestion:\n          \"Use an object whose values are strings, numbers, booleans, null, arrays, or plain objects.\",\n      },\n    );\n  }\n  assertJsonValue(value, \"annotations\", ownerLabel);\n}\n\n/**\n * Copies graph annotations into framework-owned recursively frozen JSON.\n * Callers retain an independently mutable authoring object; schema hashing\n * and introspection retain the immutable snapshot accepted at the boundary.\n */\nexport function cloneAndFreezeGraphAnnotations(\n  annotations: GraphAnnotations,\n): GraphAnnotations {\n  return cloneAndFreezeJsonValue(annotations) as GraphAnnotations;\n}\n\n/**\n * Merges graph annotations by key. A supplied key replaces its complete prior\n * value; nested objects are deliberately not deep-merged.\n */\nexport function mergeGraphAnnotations(\n  existing: GraphAnnotations | undefined,\n  next: GraphAnnotations | undefined,\n): GraphAnnotations | undefined {\n  if (existing === undefined && next === undefined) return undefined;\n  return cloneAndFreezeGraphAnnotations({ ...existing, ...next });\n}\n\n/** Canonical omission rule shared by serialization and introspection. */\nexport function canonicalAnnotations<\n  T extends GraphAnnotations | KindAnnotations,\n>(annotations: T | undefined): T | undefined {\n  if (annotations === undefined || Object.keys(annotations).length === 0) {\n    return undefined;\n  }\n  return annotations;\n}\n\nfunction cloneAndFreezeJsonValue(value: JsonValue): JsonValue {\n  if (value === null || typeof value !== \"object\") return value;\n  if (Array.isArray(value)) {\n    const values = value as readonly JsonValue[];\n    return Object.freeze(values.map((entry) => cloneAndFreezeJsonValue(entry)));\n  }\n  const cloned = createDataKeyedBag<JsonValue>();\n  for (const [key, nested] of Object.entries(value)) {\n    cloned[key] = cloneAndFreezeJsonValue(nested);\n  }\n  return Object.freeze({ ...cloned });\n}\n\nfunction walk(value: unknown, path: string, ownerKind: string): void {\n  if (value === null) return;\n  const valueType = typeof value;\n  if (valueType === \"number\") {\n    // NaN/Infinity/-Infinity are not JSON values; JSON.stringify silently\n    // coerces them to `null`, which would change the canonical hash input\n    // without the consumer noticing.\n    if (!Number.isFinite(value)) {\n      throwInvalid(path, describeNonFinite(value as number), ownerKind);\n    }\n    return;\n  }\n  if (valueType === \"string\" || valueType === \"boolean\") return;\n  if (\n    valueType === \"bigint\" ||\n    valueType === \"function\" ||\n    valueType === \"symbol\" ||\n    valueType === \"undefined\"\n  ) {\n    throwInvalid(path, valueType, ownerKind);\n  }\n  if (Array.isArray(value)) {\n    for (const [index, element] of value.entries()) {\n      walk(element, `${path}[${index}]`, ownerKind);\n    }\n    return;\n  }\n  if (!isPlainObject(value)) {\n    throwInvalid(path, describeNonPlain(value), ownerKind);\n  }\n  for (const [key, nested] of Object.entries(value)) {\n    walk(nested, `${path}.${key}`, ownerKind);\n  }\n}\n\nfunction describeNonFinite(value: number): string {\n  if (Number.isNaN(value)) return \"NaN\";\n  if (value === Number.POSITIVE_INFINITY) return \"Infinity\";\n  if (value === Number.NEGATIVE_INFINITY) return \"-Infinity\";\n  return \"non-finite number\";\n}\n\nfunction describeNonPlain(value: unknown): string {\n  const constructorName = (value as { constructor?: { name?: unknown } } | null)\n    ?.constructor?.name;\n  if (typeof constructorName === \"string\" && constructorName.length > 0) {\n    return `${constructorName} instance`;\n  }\n  return \"non-plain object\";\n}\n\nfunction throwInvalid(path: string, kind: string, ownerKind: string): never {\n  throw new ConfigurationError(\n    `${ownerKind} ${path} contains a non-JSON value (${kind}). Annotations must be JSON-serializable.`,\n    { path, valueKind: kind },\n    {\n      suggestion:\n        \"Use only strings, numbers, booleans, null, arrays, and plain objects in annotations.\",\n    },\n  );\n}\n"]}