json-schema-compatibility-checker 1.1.2 → 1.1.3

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/normalizer.ts"],"sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { deepEqual, hasOwn, isPlainObj } from \"./utils.ts\";\n\n// ─── Schema Normalizer ───────────────────────────────────────────────────────\n//\n// Pure functions to normalize a JSON Schema:\n// - Infer `type` from `const` or `enum`\n// - Recurse into all sub-structures (properties, items, anyOf, etc.)\n// - Resolve double negation `not.not` → flatten to direct content\n// - Recurse into `patternProperties` (Point 2)\n// - Recurse into `dependencies` schema form (Point 3)\n//\n// Optimizations:\n// - WeakMap cache to avoid re-normalizing the same object\n// - Lazy copy-on-write: only creates a copy when mutations are needed\n// - Returns the original if nothing changed (avoids allocations)\n\n// ─── Normalization Cache ─────────────────────────────────────────────────────\n\n/**\n * WeakMap cache for normalization results.\n * Avoids re-normalizing the same schema object multiple times.\n * WeakMap allows the GC to collect schemas that are no longer referenced.\n */\nconst normalizeCache = new WeakMap<object, JSONSchema7Definition>();\n\n// ─── Type inference ──────────────────────────────────────────────────────────\n\n/**\n * Infers the JSON Schema type from a JavaScript value.\n */\nexport function inferType(value: unknown): string | undefined {\n\tif (value === null) return \"null\";\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\t\treturn Number.isInteger(value) ? \"integer\" : \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"object\":\n\t\t\treturn Array.isArray(value) ? \"array\" : \"object\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n// ─── Sub-schema keywords ─────────────────────────────────────────────────────\n\n/** Keywords containing a single sub-schema */\nconst SINGLE_SCHEMA_KEYWORDS = [\n\t\"additionalProperties\",\n\t\"additionalItems\",\n\t\"contains\",\n\t\"propertyNames\",\n\t\"not\",\n\t\"if\",\n\t\"then\",\n\t\"else\",\n] as const;\n\n/**\n * Checks whether a schema contains only the `not` keyword (and no other\n * significant keyword). Used for double negation resolution.\n *\n * A \"pure not\" schema has the form `{ not: X }` without any other constraint.\n * In that case, `{ not: { not: Y } }` ≡ `Y`.\n *\n * Metadata keywords (`$id`, `$schema`, `$comment`, `title`, `description`,\n * `default`, `examples`, `definitions`, `$defs`) are NOT considered\n * significant for this detection.\n */\nconst METADATA_KEYWORDS = new Set([\n\t\"$id\",\n\t\"$schema\",\n\t\"$comment\",\n\t\"title\",\n\t\"description\",\n\t\"default\",\n\t\"examples\",\n\t\"definitions\",\n\t\"$defs\",\n]);\n\n/**\n * Checks whether a schema object contains only the `not` keyword\n * (plus optionally non-significant metadata).\n */\nfunction isPureNotSchema(schema: JSONSchema7): boolean {\n\tconst schemaKeys = Object.keys(schema);\n\treturn schemaKeys.every((k) => k === \"not\" || METADATA_KEYWORDS.has(k));\n}\n\n/** Keywords containing an array of sub-schemas */\nconst ARRAY_SCHEMA_KEYWORDS = [\"anyOf\", \"oneOf\", \"allOf\"] as const;\n\n/**\n * Keywords containing a Record<string, JSONSchema7Definition>\n * (each value is a sub-schema to normalize recursively).\n */\nconst PROPERTIES_LIKE_KEYWORDS = [\"properties\", \"patternProperties\"] as const;\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\n/**\n * Normalizes a `Record<string, JSONSchema7Definition>` by applying\n * `normalize` to each value.\n * Returns the original object if nothing changed (avoids allocations).\n */\nfunction normalizePropertiesMap(\n\tprops: Record<string, JSONSchema7Definition>,\n): Record<string, JSONSchema7Definition> {\n\tconst keys = Object.keys(props);\n\tlet changed = false;\n\n\t// First pass: detect if anything changes (sub-schemas get cached)\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tconst key = keys[i];\n\t\tif (key === undefined) continue;\n\t\tconst original = props[key];\n\t\tconst normalized = normalize(original as JSONSchema7Definition);\n\t\tif (normalized !== original) {\n\t\t\tchanged = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!changed) return props;\n\n\t// Build result only when something changed (sub normalize calls hit cache)\n\tconst result: Record<string, JSONSchema7Definition> = {};\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tconst key = keys[i];\n\t\tif (key === undefined) continue;\n\t\tresult[key] = normalize(props[key] as JSONSchema7Definition);\n\t}\n\n\treturn result;\n}\n\n/**\n * Infers `type` from `const` if absent.\n * Returns the inferred type or undefined if not applicable.\n */\nfunction inferTypeFromConst(\n\tschema: JSONSchema7,\n): JSONSchema7[\"type\"] | undefined {\n\tif (!hasOwn(schema, \"const\") || schema.type !== undefined) return undefined;\n\tconst t = inferType(schema.const);\n\treturn t ? (t as JSONSchema7[\"type\"]) : undefined;\n}\n\n/**\n * Infers `type` from `enum` if absent.\n * Returns the inferred type (single or array) or undefined if not applicable.\n */\nfunction inferTypeFromEnum(\n\tschema: JSONSchema7,\n): JSONSchema7[\"type\"] | undefined {\n\tif (!Array.isArray(schema.enum) || schema.type !== undefined)\n\t\treturn undefined;\n\n\tconst typesSet = new Set<string>();\n\tfor (const v of schema.enum) {\n\t\tconst t = inferType(v);\n\t\tif (t) typesSet.add(t);\n\t}\n\n\tconst count = typesSet.size;\n\tif (count === 0) return undefined;\n\n\tconst types = Array.from(typesSet);\n\tif (count === 1) return types[0] as JSONSchema7[\"type\"];\n\treturn types as JSONSchema7[\"type\"];\n}\n\n// ─── Normalization ───────────────────────────────────────────────────────────\n\n/**\n * Normalizes a schema: infers `type` from `const`/`enum`,\n * and recursively normalizes all sub-schemas.\n *\n * Recurses into:\n * - `properties` and `patternProperties` (Point 2)\n * - `dependencies` schema form (Point 3) — array values (form 1)\n * are left unchanged\n * - `items` (single or tuple)\n * - Single-schema keywords (`additionalProperties`, `not`, `if`, etc.)\n * - Array-of-schema keywords (`anyOf`, `oneOf`, `allOf`)\n *\n * Optimizations:\n * - WeakMap cache: returns the cached result in O(1)\n * - Lazy copy-on-write: only creates a shallow copy when the first\n * mutation is needed, via `ensureCopy()`\n * - Sub-structures are only replaced if actually changed\n */\nexport function normalize(def: JSONSchema7Definition): JSONSchema7Definition {\n\tif (typeof def === \"boolean\") return def;\n\n\t// ── Cache lookup (O(1) fast path) ──\n\tconst cached = normalizeCache.get(def);\n\tif (cached !== undefined) return cached;\n\n\t// ── Lazy copy-on-write ──\n\t// We delay creating a shallow copy until the first actual mutation.\n\t// `schema` starts as `def` and only becomes a copy when `ensureCopy()` is called.\n\tlet schema = def as JSONSchema7 & Record<string, unknown>;\n\tlet copied = false;\n\n\tfunction ensureCopy(): JSONSchema7 & Record<string, unknown> {\n\t\tif (!copied) {\n\t\t\tschema = { ...(def as JSONSchema7) } as JSONSchema7 &\n\t\t\t\tRecord<string, unknown>;\n\t\t\tcopied = true;\n\t\t}\n\t\treturn schema;\n\t}\n\n\t// ── Infer type from const ──\n\tconst typeFromConst = inferTypeFromConst(schema);\n\tif (typeFromConst) {\n\t\tensureCopy().type = typeFromConst;\n\t}\n\n\t// ── Infer type from enum ──\n\tconst typeFromEnum = inferTypeFromEnum(schema);\n\tif (typeFromEnum) {\n\t\tensureCopy().type = typeFromEnum;\n\t}\n\n\t// ── Convert single-element enum to const ──\n\t// Semantically, { enum: [X] } ≡ { const: X }.\n\t// This normalization ensures that structural comparison (isEqual) does not\n\t// produce false negatives when one schema uses enum and the other uses\n\t// const for the same value.\n\tif (\n\t\tArray.isArray(schema.enum) &&\n\t\tschema.enum.length === 1 &&\n\t\t!hasOwn(schema, \"const\")\n\t) {\n\t\tconst s = ensureCopy();\n\t\ts.const = schema.enum[0];\n\t\tdelete s.enum;\n\t}\n\n\t// ── Strip redundant enum when const is present ──\n\t// If `const: X` and `enum: [... X ...]` coexist, `const` is more\n\t// restrictive → `enum` is redundant. The merge engine can produce\n\t// this combination during the const ∩ enum intersection.\n\tif (hasOwn(schema, \"const\") && Array.isArray(schema.enum)) {\n\t\tif (schema.enum.some((v) => deepEqual(v, schema.const))) {\n\t\t\tdelete ensureCopy().enum;\n\t\t}\n\t}\n\n\t// ── Normalize constraints to array form ──\n\t// The `constraints` custom keyword accepts `Constraint | Constraint[]`.\n\t// Canonicalize to always be an array so that deepEqual comparisons\n\t// in the subset checker work correctly.\n\tif (\n\t\thasOwn(schema, \"constraints\") &&\n\t\tschema.constraints !== undefined &&\n\t\t!Array.isArray(schema.constraints)\n\t) {\n\t\tensureCopy().constraints = [schema.constraints];\n\t}\n\n\t// ── Recurse into properties & patternProperties (Point 2) ──\n\tfor (const keyword of PROPERTIES_LIKE_KEYWORDS) {\n\t\tconst val = schema[keyword];\n\t\tif (isPlainObj(val)) {\n\t\t\tconst normalized = normalizePropertiesMap(\n\t\t\t\tval as Record<string, JSONSchema7Definition>,\n\t\t\t);\n\t\t\tif (normalized !== val) {\n\t\t\t\tensureCopy()[keyword] = normalized as JSONSchema7[\"properties\"];\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into dependencies (Point 3) ──\n\t// `dependencies` can contain:\n\t// - Form 1 (property deps): { foo: [\"bar\", \"baz\"] } → string array, skip\n\t// - Form 2 (schema deps): { foo: { required: [...] } } → schema object, normalize\n\tif (isPlainObj(schema.dependencies)) {\n\t\tconst deps = schema.dependencies as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\t\tconst depsKeys = Object.keys(deps);\n\t\tlet depsChanged = false;\n\t\tconst newDeps: Record<string, JSONSchema7Definition | string[]> = {};\n\n\t\tfor (let i = 0; i < depsKeys.length; i++) {\n\t\t\tconst key = depsKeys[i];\n\t\t\tif (key === undefined) continue;\n\t\t\tconst val = deps[key];\n\t\t\tif (val === undefined) continue;\n\t\t\tif (Array.isArray(val)) {\n\t\t\t\t// Form 1: string array → leave as-is\n\t\t\t\tnewDeps[key] = val;\n\t\t\t} else if (isPlainObj(val)) {\n\t\t\t\t// Form 2: sub-schema → normalize recursively\n\t\t\t\tconst normalized = normalize(val as JSONSchema7Definition);\n\t\t\t\tnewDeps[key] = normalized;\n\t\t\t\tif (normalized !== val) depsChanged = true;\n\t\t\t} else {\n\t\t\t\tnewDeps[key] = val as JSONSchema7Definition;\n\t\t\t}\n\t\t}\n\n\t\tif (depsChanged) {\n\t\t\tensureCopy().dependencies = newDeps;\n\t\t}\n\t}\n\n\t// ── Recurse into items (tuple or single) ──\n\tif (schema.items) {\n\t\tif (Array.isArray(schema.items)) {\n\t\t\t// Tuple: normalize each element\n\t\t\tconst items = schema.items as JSONSchema7Definition[];\n\t\t\tlet itemsChanged = false;\n\t\t\tconst newItems: JSONSchema7Definition[] = new Array(items.length);\n\n\t\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\t\tconst original = items[i];\n\t\t\t\tif (original === undefined) continue;\n\t\t\t\tconst normalized = normalize(original);\n\t\t\t\tnewItems[i] = normalized;\n\t\t\t\tif (normalized !== original) itemsChanged = true;\n\t\t\t}\n\n\t\t\tif (itemsChanged) {\n\t\t\t\tensureCopy().items = newItems;\n\t\t\t}\n\t\t} else if (isPlainObj(schema.items)) {\n\t\t\t// Single items schema\n\t\t\tconst normalized = normalize(schema.items as JSONSchema7Definition);\n\t\t\tif (normalized !== schema.items) {\n\t\t\t\tensureCopy().items = normalized;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into single-schema keywords ──\n\tfor (const key of SINGLE_SCHEMA_KEYWORDS) {\n\t\tconst val = schema[key];\n\t\tif (val !== undefined && typeof val !== \"boolean\") {\n\t\t\tconst normalized = normalize(val as JSONSchema7Definition);\n\t\t\tif (normalized !== val) {\n\t\t\t\t(ensureCopy() as Record<string, JSONSchema7Definition>)[key] =\n\t\t\t\t\tnormalized;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Resolve double negation not(not(X)) → X ──\n\t// After recursing into sub-schemas, `schema.not` is normalized.\n\t// If `schema.not` is an object that only contains `not` (a \"pure not\"),\n\t// then `{ ...rest, not: { not: X } }` ≡ `{ ...rest, ...X }`.\n\t//\n\t// Propositional logic: ¬¬P ≡ P\n\t//\n\t// We only resolve the \"pure\" case (schema.not has only `not` as a\n\t// significant key) to avoid false positives in complex cases.\n\tif (\n\t\thasOwn(schema, \"not\") &&\n\t\tisPlainObj(schema.not) &&\n\t\ttypeof schema.not !== \"boolean\"\n\t) {\n\t\tconst notSchema = schema.not as JSONSchema7;\n\t\tif (\n\t\t\thasOwn(notSchema, \"not\") &&\n\t\t\tisPureNotSchema(notSchema) &&\n\t\t\tisPlainObj(notSchema.not) &&\n\t\t\ttypeof notSchema.not !== \"boolean\"\n\t\t) {\n\t\t\t// Extract the content of not.not and merge it into the rest of the schema\n\t\t\tconst innerSchema = notSchema.not as JSONSchema7;\n\t\t\tconst s = ensureCopy();\n\t\t\t// Remove `not` from the current schema\n\t\t\tdelete s.not;\n\t\t\t// Merge the inner content into the current schema\n\t\t\tconst innerKeys = Object.keys(innerSchema);\n\t\t\tfor (let i = 0; i < innerKeys.length; i++) {\n\t\t\t\tconst ik = innerKeys[i];\n\t\t\t\tif (ik === undefined) continue;\n\t\t\t\t(s as Record<string, unknown>)[ik] = (\n\t\t\t\t\tinnerSchema as Record<string, unknown>\n\t\t\t\t)[ik];\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into array-of-schema keywords ──\n\tfor (const key of ARRAY_SCHEMA_KEYWORDS) {\n\t\tconst val = schema[key];\n\t\tif (Array.isArray(val)) {\n\t\t\tconst arr = val as JSONSchema7Definition[];\n\t\t\tlet arrChanged = false;\n\t\t\tconst newArr: JSONSchema7Definition[] = new Array(arr.length);\n\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst original = arr[i];\n\t\t\t\tif (original === undefined) continue;\n\t\t\t\tconst normalized = normalize(original);\n\t\t\t\tnewArr[i] = normalized;\n\t\t\t\tif (normalized !== original) arrChanged = true;\n\t\t\t}\n\n\t\t\tif (arrChanged) {\n\t\t\t\tensureCopy()[key] = newArr;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Determine result ──\n\t// If nothing changed (copied === false), return the original def.\n\t// Otherwise, return the mutated copy.\n\tconst result = (copied ? schema : def) as JSONSchema7Definition;\n\n\t// ── Cache the result ──\n\tnormalizeCache.set(def, result);\n\n\treturn result;\n}\n"],"names":["deepEqual","hasOwn","isPlainObj","normalizeCache","WeakMap","inferType","value","Number","isInteger","Array","isArray","undefined","SINGLE_SCHEMA_KEYWORDS","METADATA_KEYWORDS","Set","isPureNotSchema","schema","schemaKeys","Object","keys","every","k","has","ARRAY_SCHEMA_KEYWORDS","PROPERTIES_LIKE_KEYWORDS","normalizePropertiesMap","props","changed","i","length","key","original","normalized","normalize","result","inferTypeFromConst","type","t","const","inferTypeFromEnum","enum","typesSet","v","add","count","size","types","from","def","cached","get","copied","ensureCopy","typeFromConst","typeFromEnum","s","some","constraints","keyword","val","dependencies","deps","depsKeys","depsChanged","newDeps","items","itemsChanged","newItems","not","notSchema","innerSchema","innerKeys","ik","arr","arrChanged","newArr","set"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/normalizer.ts"],"sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { deepEqual, hasOwn, isPlainObj } from \"./utils.ts\";\n\n// ─── Schema Normalizer ───────────────────────────────────────────────────────\n//\n// Pure functions to normalize a JSON Schema:\n// - Infer `type` from `const` or `enum`\n// - Recurse into all sub-structures (properties, items, anyOf, etc.)\n// - Resolve double negation `not.not` → flatten to direct content\n// - Recurse into `patternProperties` (Point 2)\n// - Recurse into `dependencies` schema form (Point 3)\n//\n// Optimizations:\n// - WeakMap cache to avoid re-normalizing the same object\n// - Lazy copy-on-write: only creates a copy when mutations are needed\n// - Returns the original if nothing changed (avoids allocations)\n\n// ─── Normalization Cache ─────────────────────────────────────────────────────\n\n/**\n * WeakMap cache for normalization results.\n * Avoids re-normalizing the same schema object multiple times.\n * WeakMap allows the GC to collect schemas that are no longer referenced.\n */\nconst normalizeCache = new WeakMap<object, JSONSchema7Definition>();\n\n// ─── Type inference ──────────────────────────────────────────────────────────\n\n/**\n * Infers the JSON Schema type from a JavaScript value.\n */\nexport function inferType(value: unknown): string | undefined {\n\tif (value === null) return \"null\";\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\t\treturn Number.isInteger(value) ? \"integer\" : \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"object\":\n\t\t\treturn Array.isArray(value) ? \"array\" : \"object\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n// ─── Sub-schema keywords ─────────────────────────────────────────────────────\n\n/** Keywords containing a single sub-schema */\nconst SINGLE_SCHEMA_KEYWORDS = [\n\t\"additionalProperties\",\n\t\"additionalItems\",\n\t\"contains\",\n\t\"propertyNames\",\n\t\"not\",\n\t\"if\",\n\t\"then\",\n\t\"else\",\n] as const;\n\n/**\n * Checks whether a schema contains only the `not` keyword (and no other\n * significant keyword). Used for double negation resolution.\n *\n * A \"pure not\" schema has the form `{ not: X }` without any other constraint.\n * In that case, `{ not: { not: Y } }` ≡ `Y`.\n *\n * Metadata keywords (`$id`, `$schema`, `$comment`, `title`, `description`,\n * `default`, `examples`, `definitions`, `$defs`) are NOT considered\n * significant for this detection.\n */\nconst METADATA_KEYWORDS = new Set([\n\t\"$id\",\n\t\"$schema\",\n\t\"$comment\",\n\t\"title\",\n\t\"description\",\n\t\"default\",\n\t\"examples\",\n\t\"definitions\",\n\t\"$defs\",\n]);\n\n/**\n * Checks whether a schema object contains only the `not` keyword\n * (plus optionally non-significant metadata).\n */\nfunction isPureNotSchema(schema: JSONSchema7): boolean {\n\tconst schemaKeys = Object.keys(schema);\n\treturn schemaKeys.every((k) => k === \"not\" || METADATA_KEYWORDS.has(k));\n}\n\n/** Keywords containing an array of sub-schemas */\nconst ARRAY_SCHEMA_KEYWORDS = [\"anyOf\", \"oneOf\", \"allOf\"] as const;\n\n/**\n * Keywords containing a Record<string, JSONSchema7Definition>\n * (each value is a sub-schema to normalize recursively).\n */\nconst PROPERTIES_LIKE_KEYWORDS = [\"properties\", \"patternProperties\"] as const;\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\n/**\n * Normalizes a `Record<string, JSONSchema7Definition>` by applying\n * `normalize` to each value.\n * Returns the original object if nothing changed (avoids allocations).\n */\nfunction normalizePropertiesMap(\n\tprops: Record<string, JSONSchema7Definition>,\n): Record<string, JSONSchema7Definition> {\n\tconst keys = Object.keys(props);\n\tlet changed = false;\n\n\t// First pass: detect if anything changes (sub-schemas get cached)\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tconst key = keys[i];\n\t\tif (key === undefined) continue;\n\t\tconst original = props[key];\n\t\tconst normalized = normalize(original as JSONSchema7Definition);\n\t\tif (normalized !== original) {\n\t\t\tchanged = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!changed) return props;\n\n\t// Build result only when something changed (sub normalize calls hit cache)\n\tconst result: Record<string, JSONSchema7Definition> = {};\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tconst key = keys[i];\n\t\tif (key === undefined) continue;\n\t\tresult[key] = normalize(props[key] as JSONSchema7Definition);\n\t}\n\n\treturn result;\n}\n\n/**\n * Infers `type` from `const` if absent.\n * Returns the inferred type or undefined if not applicable.\n */\nfunction inferTypeFromConst(\n\tschema: JSONSchema7,\n): JSONSchema7[\"type\"] | undefined {\n\tif (!hasOwn(schema, \"const\") || schema.type !== undefined) return undefined;\n\tconst t = inferType(schema.const);\n\treturn t ? (t as JSONSchema7[\"type\"]) : undefined;\n}\n\n/**\n * Infers `type` from `enum` if absent.\n * Returns the inferred type (single or array) or undefined if not applicable.\n */\nfunction inferTypeFromEnum(\n\tschema: JSONSchema7,\n): JSONSchema7[\"type\"] | undefined {\n\tif (!Array.isArray(schema.enum) || schema.type !== undefined)\n\t\treturn undefined;\n\n\tconst typesSet = new Set<string>();\n\tfor (const v of schema.enum) {\n\t\tconst t = inferType(v);\n\t\tif (t) typesSet.add(t);\n\t}\n\n\tconst count = typesSet.size;\n\tif (count === 0) return undefined;\n\n\tconst types = Array.from(typesSet);\n\tif (count === 1) return types[0] as JSONSchema7[\"type\"];\n\treturn types as JSONSchema7[\"type\"];\n}\n\n// ─── Normalization ───────────────────────────────────────────────────────────\n\n/**\n * Normalizes a schema: infers `type` from `const`/`enum`,\n * and recursively normalizes all sub-schemas.\n *\n * Recurses into:\n * - `properties` and `patternProperties` (Point 2)\n * - `dependencies` schema form (Point 3) — array values (form 1)\n * are left unchanged\n * - `items` (single or tuple)\n * - Single-schema keywords (`additionalProperties`, `not`, `if`, etc.)\n * - Array-of-schema keywords (`anyOf`, `oneOf`, `allOf`)\n *\n * Optimizations:\n * - WeakMap cache: returns the cached result in O(1)\n * - Lazy copy-on-write: only creates a shallow copy when the first\n * mutation is needed, via `ensureCopy()`\n * - Sub-structures are only replaced if actually changed\n */\nexport function normalize(def: JSONSchema7Definition): JSONSchema7Definition {\n\tif (typeof def === \"boolean\") return def;\n\n\t// ── Cache lookup (O(1) fast path) ──\n\tconst cached = normalizeCache.get(def);\n\tif (cached !== undefined) return cached;\n\n\t// ── Lazy copy-on-write ──\n\t// We delay creating a shallow copy until the first actual mutation.\n\t// `schema` starts as `def` and only becomes a copy when `ensureCopy()` is called.\n\tlet schema = def as JSONSchema7 & Record<string, unknown>;\n\tlet copied = false;\n\n\tfunction ensureCopy(): JSONSchema7 & Record<string, unknown> {\n\t\tif (!copied) {\n\t\t\tschema = { ...(def as JSONSchema7) } as JSONSchema7 &\n\t\t\t\tRecord<string, unknown>;\n\t\t\tcopied = true;\n\t\t}\n\t\treturn schema;\n\t}\n\n\t// ── Infer type from const ──\n\tconst typeFromConst = inferTypeFromConst(schema);\n\tif (typeFromConst) {\n\t\tensureCopy().type = typeFromConst;\n\t}\n\n\t// ── Infer type from enum ──\n\tconst typeFromEnum = inferTypeFromEnum(schema);\n\tif (typeFromEnum) {\n\t\tensureCopy().type = typeFromEnum;\n\t}\n\n\t// ── Convert single-element enum to const ──\n\t// Semantically, { enum: [X] } ≡ { const: X }.\n\t// This normalization ensures that structural comparison (isEqual) does not\n\t// produce false negatives when one schema uses enum and the other uses\n\t// const for the same value.\n\tif (\n\t\tArray.isArray(schema.enum) &&\n\t\tschema.enum.length === 1 &&\n\t\t!hasOwn(schema, \"const\")\n\t) {\n\t\tconst s = ensureCopy();\n\t\ts.const = schema.enum[0];\n\t\tdelete s.enum;\n\t}\n\n\t// ── Strip redundant enum when const is present ──\n\t// If `const: X` and `enum: [... X ...]` coexist, `const` is more\n\t// restrictive → `enum` is redundant. The merge engine can produce\n\t// this combination during the const ∩ enum intersection.\n\tif (hasOwn(schema, \"const\") && Array.isArray(schema.enum)) {\n\t\tif (schema.enum.some((v) => deepEqual(v, schema.const))) {\n\t\t\tdelete ensureCopy().enum;\n\t\t}\n\t}\n\n\t// ── Strip constraints from the static path ──\n\t// The `constraints` keyword is a runtime-only concept: it represents\n\t// custom validators (e.g. \"IsUuid\", \"NotFoundConstraint\") that can only\n\t// be evaluated against concrete data. Including them in the normalized\n\t// schema would cause false negatives in the structural subset check\n\t// (e.g. `{ type: \"string\" }` would fail to be recognized as a subset of\n\t// `{ type: \"string\", constraints: [\"X\"] }` because the merge adds the\n\t// constraint to the result, making merged ≠ sub).\n\t//\n\t// Stripping here is safe: the runtime validation path\n\t// (`validateSchemaConstraints`) receives the original resolved/narrowed\n\t// schemas that have NOT been through `normalize()`, so constraints are\n\t// still available for runtime evaluation.\n\tif (hasOwn(schema, \"constraints\") && schema.constraints !== undefined) {\n\t\tconst s = ensureCopy();\n\t\tdelete s.constraints;\n\t}\n\n\t// ── Recurse into properties & patternProperties (Point 2) ──\n\tfor (const keyword of PROPERTIES_LIKE_KEYWORDS) {\n\t\tconst val = schema[keyword];\n\t\tif (isPlainObj(val)) {\n\t\t\tconst normalized = normalizePropertiesMap(\n\t\t\t\tval as Record<string, JSONSchema7Definition>,\n\t\t\t);\n\t\t\tif (normalized !== val) {\n\t\t\t\tensureCopy()[keyword] = normalized as JSONSchema7[\"properties\"];\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into dependencies (Point 3) ──\n\t// `dependencies` can contain:\n\t// - Form 1 (property deps): { foo: [\"bar\", \"baz\"] } → string array, skip\n\t// - Form 2 (schema deps): { foo: { required: [...] } } → schema object, normalize\n\tif (isPlainObj(schema.dependencies)) {\n\t\tconst deps = schema.dependencies as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\t\tconst depsKeys = Object.keys(deps);\n\t\tlet depsChanged = false;\n\t\tconst newDeps: Record<string, JSONSchema7Definition | string[]> = {};\n\n\t\tfor (let i = 0; i < depsKeys.length; i++) {\n\t\t\tconst key = depsKeys[i];\n\t\t\tif (key === undefined) continue;\n\t\t\tconst val = deps[key];\n\t\t\tif (val === undefined) continue;\n\t\t\tif (Array.isArray(val)) {\n\t\t\t\t// Form 1: string array → leave as-is\n\t\t\t\tnewDeps[key] = val;\n\t\t\t} else if (isPlainObj(val)) {\n\t\t\t\t// Form 2: sub-schema → normalize recursively\n\t\t\t\tconst normalized = normalize(val as JSONSchema7Definition);\n\t\t\t\tnewDeps[key] = normalized;\n\t\t\t\tif (normalized !== val) depsChanged = true;\n\t\t\t} else {\n\t\t\t\tnewDeps[key] = val as JSONSchema7Definition;\n\t\t\t}\n\t\t}\n\n\t\tif (depsChanged) {\n\t\t\tensureCopy().dependencies = newDeps;\n\t\t}\n\t}\n\n\t// ── Recurse into items (tuple or single) ──\n\tif (schema.items) {\n\t\tif (Array.isArray(schema.items)) {\n\t\t\t// Tuple: normalize each element\n\t\t\tconst items = schema.items as JSONSchema7Definition[];\n\t\t\tlet itemsChanged = false;\n\t\t\tconst newItems: JSONSchema7Definition[] = new Array(items.length);\n\n\t\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\t\tconst original = items[i];\n\t\t\t\tif (original === undefined) continue;\n\t\t\t\tconst normalized = normalize(original);\n\t\t\t\tnewItems[i] = normalized;\n\t\t\t\tif (normalized !== original) itemsChanged = true;\n\t\t\t}\n\n\t\t\tif (itemsChanged) {\n\t\t\t\tensureCopy().items = newItems;\n\t\t\t}\n\t\t} else if (isPlainObj(schema.items)) {\n\t\t\t// Single items schema\n\t\t\tconst normalized = normalize(schema.items as JSONSchema7Definition);\n\t\t\tif (normalized !== schema.items) {\n\t\t\t\tensureCopy().items = normalized;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into single-schema keywords ──\n\tfor (const key of SINGLE_SCHEMA_KEYWORDS) {\n\t\tconst val = schema[key];\n\t\tif (val !== undefined && typeof val !== \"boolean\") {\n\t\t\tconst normalized = normalize(val as JSONSchema7Definition);\n\t\t\tif (normalized !== val) {\n\t\t\t\t(ensureCopy() as Record<string, JSONSchema7Definition>)[key] =\n\t\t\t\t\tnormalized;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Resolve double negation not(not(X)) → X ──\n\t// After recursing into sub-schemas, `schema.not` is normalized.\n\t// If `schema.not` is an object that only contains `not` (a \"pure not\"),\n\t// then `{ ...rest, not: { not: X } }` ≡ `{ ...rest, ...X }`.\n\t//\n\t// Propositional logic: ¬¬P ≡ P\n\t//\n\t// We only resolve the \"pure\" case (schema.not has only `not` as a\n\t// significant key) to avoid false positives in complex cases.\n\tif (\n\t\thasOwn(schema, \"not\") &&\n\t\tisPlainObj(schema.not) &&\n\t\ttypeof schema.not !== \"boolean\"\n\t) {\n\t\tconst notSchema = schema.not as JSONSchema7;\n\t\tif (\n\t\t\thasOwn(notSchema, \"not\") &&\n\t\t\tisPureNotSchema(notSchema) &&\n\t\t\tisPlainObj(notSchema.not) &&\n\t\t\ttypeof notSchema.not !== \"boolean\"\n\t\t) {\n\t\t\t// Extract the content of not.not and merge it into the rest of the schema\n\t\t\tconst innerSchema = notSchema.not as JSONSchema7;\n\t\t\tconst s = ensureCopy();\n\t\t\t// Remove `not` from the current schema\n\t\t\tdelete s.not;\n\t\t\t// Merge the inner content into the current schema\n\t\t\tconst innerKeys = Object.keys(innerSchema);\n\t\t\tfor (let i = 0; i < innerKeys.length; i++) {\n\t\t\t\tconst ik = innerKeys[i];\n\t\t\t\tif (ik === undefined) continue;\n\t\t\t\t(s as Record<string, unknown>)[ik] = (\n\t\t\t\t\tinnerSchema as Record<string, unknown>\n\t\t\t\t)[ik];\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into array-of-schema keywords ──\n\tfor (const key of ARRAY_SCHEMA_KEYWORDS) {\n\t\tconst val = schema[key];\n\t\tif (Array.isArray(val)) {\n\t\t\tconst arr = val as JSONSchema7Definition[];\n\t\t\tlet arrChanged = false;\n\t\t\tconst newArr: JSONSchema7Definition[] = new Array(arr.length);\n\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst original = arr[i];\n\t\t\t\tif (original === undefined) continue;\n\t\t\t\tconst normalized = normalize(original);\n\t\t\t\tnewArr[i] = normalized;\n\t\t\t\tif (normalized !== original) arrChanged = true;\n\t\t\t}\n\n\t\t\tif (arrChanged) {\n\t\t\t\tensureCopy()[key] = newArr;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Determine result ──\n\t// If nothing changed (copied === false), return the original def.\n\t// Otherwise, return the mutated copy.\n\tconst result = (copied ? schema : def) as JSONSchema7Definition;\n\n\t// ── Cache the result ──\n\tnormalizeCache.set(def, result);\n\n\treturn result;\n}\n"],"names":["deepEqual","hasOwn","isPlainObj","normalizeCache","WeakMap","inferType","value","Number","isInteger","Array","isArray","undefined","SINGLE_SCHEMA_KEYWORDS","METADATA_KEYWORDS","Set","isPureNotSchema","schema","schemaKeys","Object","keys","every","k","has","ARRAY_SCHEMA_KEYWORDS","PROPERTIES_LIKE_KEYWORDS","normalizePropertiesMap","props","changed","i","length","key","original","normalized","normalize","result","inferTypeFromConst","type","t","const","inferTypeFromEnum","enum","typesSet","v","add","count","size","types","from","def","cached","get","copied","ensureCopy","typeFromConst","typeFromEnum","s","some","constraints","keyword","val","dependencies","deps","depsKeys","depsChanged","newDeps","items","itemsChanged","newItems","not","notSchema","innerSchema","innerKeys","ik","arr","arrChanged","newArr","set"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{deepEqual,hasOwn,isPlainObj}from"./utils.js";function formatEnumValues(values){const parts=values.map(v=>typeof v==="string"?v:JSON.stringify(v));if(parts.length===0)return"never";if(parts.length===1)return parts[0];if(parts.length===2)return`${parts[0]} or ${parts[1]}`;const last=parts.pop();return`${parts.join(", ")}, or ${last}`}export function formatSchemaType(def){const base=formatSchemaTypeInternal(def);if(def===undefined||typeof def==="boolean")return base;return base+formatConstraintsSuffix(def)}function formatConstraintsSuffix(schema){const constraints=schema.constraints;if(constraints===undefined)return"";const arr=Array.isArray(constraints)?constraints:[constraints];if(arr.length===0)return"";return` [${arr.map(formatCustomConstraint).join(", ")}]`}function formatSchemaTypeInternal(def){if(def===undefined)return"undefined";if(typeof def==="boolean")return def?"any":"never";const schema=def;if(hasOwn(schema,"const")){const v=schema.const;return typeof v==="string"?v:JSON.stringify(v)}if(Array.isArray(schema.enum)){return formatEnumValues(schema.enum)}const branches=schema.anyOf??schema.oneOf;if(Array.isArray(branches)&&branches.length>0){const parts=branches.map(b=>formatSchemaType(b));return parts.join(" | ")}if(schema.type==="array"){if(schema.items!==undefined&&typeof schema.items!=="boolean"){const itemSchema=schema.items;const itemBranches=itemSchema.anyOf??itemSchema.oneOf;if(Array.isArray(itemBranches)&&itemBranches.length>0){const parts=itemBranches.map(b=>`${formatSchemaType(b)}[]`);return parts.join(" | ")}if(Array.isArray(itemSchema.type)){const parts=itemSchema.type.map(t=>`${t}[]`);return parts.join(" | ")}const itemType=formatSchemaType(itemSchema);return`${itemType}[]`}return"array"}if(typeof schema.type==="string"){return schema.type}if(Array.isArray(schema.type)){return schema.type.join(" | ")}if(hasOwn(schema,"not")&&!schema.type&&!isPlainObj(schema.properties)&&schema.items===undefined&&!Array.isArray(schema.enum)&&!hasOwn(schema,"const")){return`not ${formatSchemaType(schema.not)}`}if(isPlainObj(schema.properties))return"object";if(schema.items!==undefined)return"array";return"unknown"}function joinPath(parent,key){if(!parent)return key;return`${parent}.${key}`}function arrayPath(parent){if(!parent)return"[]";return`${parent}[]`}function getProperties(schema){if(isPlainObj(schema.properties)){return schema.properties}return null}function getRequired(schema){if(Array.isArray(schema.required)){return schema.required}return[]}function getEffectiveType(schema){if(schema.type!==undefined)return schema.type;if(hasOwn(schema,"const")){const v=schema.const;if(v===null)return"null";if(Array.isArray(v))return"array";return typeof v}if(isPlainObj(schema.properties))return"object";if(schema.items!==undefined)return"array";return undefined}function typeIncludes(schemaType,target){if(schemaType===undefined)return false;if(typeof schemaType==="string"){if(target==="number"&&schemaType==="integer")return true;if(target==="integer"&&schemaType==="number")return true;return schemaType===target}return schemaType.includes(target)}function typesAreCompatible(subType,supType){if(supType===undefined)return true;if(subType===undefined)return true;if(typeof subType==="string"&&typeof supType==="string"){if(subType===supType)return true;if(subType==="integer"&&supType==="number")return true;return false}if(typeof subType==="string"&&Array.isArray(supType)){return supType.some(t=>t===subType||subType==="integer"&&t==="number")}if(Array.isArray(subType)&&typeof supType==="string"){return subType.every(t=>t===supType||t==="integer"&&supType==="number")}if(Array.isArray(subType)&&Array.isArray(supType)){return subType.every(st=>supType.some(supt=>supt===st||st==="integer"&&supt==="number"))}return true}function formatCustomConstraint(c){if(typeof c==="string")return c;if(c.params&&Object.keys(c.params).length>0){return`${c.name}(${JSON.stringify(c.params)})`}return c.name}function formatCustomConstraintList(cs){return cs.map(formatCustomConstraint).join(", ")}function checkCustomConstraints(sub,sup,path,errors){const supConstraints=sup.constraints;const subConstraints=sub.constraints;if(supConstraints===undefined)return;const supArr=Array.isArray(supConstraints)?supConstraints:[supConstraints];const subArr=subConstraints===undefined?[]:Array.isArray(subConstraints)?subConstraints:[subConstraints];for(const supC of supArr){const found=subArr.some(subC=>deepEqual(subC,supC));if(!found){errors.push({key:path||"$root",expected:`constraint: ${formatCustomConstraint(supC)}`,received:subArr.length>0?`constraints: ${formatCustomConstraintList(subArr)}`:"no constraints"})}}}function fmtConstraint(name,value){if(value===undefined)return`${name}: not set`;if(typeof value==="boolean")return`${name}: ${value}`;if(typeof value==="number"||typeof value==="string")return`${name}: ${value}`;return`${name}: ${JSON.stringify(value)}`}function checkMinConstraint(subVal,supVal,name,path,errors){if(supVal!==undefined){if(subVal===undefined||subVal<supVal){errors.push({key:path||"$root",expected:fmtConstraint(name,supVal),received:fmtConstraint(name,subVal)})}}}function checkMaxConstraint(subVal,supVal,name,path,errors){if(supVal!==undefined){if(subVal===undefined||subVal>supVal){errors.push({key:path||"$root",expected:fmtConstraint(name,supVal),received:fmtConstraint(name,subVal)})}}}function checkNumericConstraints(sub,sup,path,errors){checkMinConstraint(sub.minimum,sup.minimum,"minimum",path,errors);checkMaxConstraint(sub.maximum,sup.maximum,"maximum",path,errors);checkMinConstraint(sub.exclusiveMinimum,sup.exclusiveMinimum,"exclusiveMinimum",path,errors);checkMaxConstraint(sub.exclusiveMaximum,sup.exclusiveMaximum,"exclusiveMaximum",path,errors);if(sup.multipleOf!==undefined){if(sub.multipleOf===undefined){errors.push({key:path||"$root",expected:fmtConstraint("multipleOf",sup.multipleOf),received:fmtConstraint("multipleOf",sub.multipleOf)})}else if(sub.multipleOf!==sup.multipleOf){if(sub.multipleOf%sup.multipleOf!==0){errors.push({key:path||"$root",expected:fmtConstraint("multipleOf",sup.multipleOf),received:fmtConstraint("multipleOf",sub.multipleOf)})}}}}function checkStringConstraints(sub,sup,path,errors){checkMinConstraint(sub.minLength,sup.minLength,"minLength",path,errors);checkMaxConstraint(sub.maxLength,sup.maxLength,"maxLength",path,errors);if(sup.pattern!==undefined){if(sub.pattern===undefined){errors.push({key:path||"$root",expected:fmtConstraint("pattern",sup.pattern),received:"no pattern constraint"})}else if(sub.pattern!==sup.pattern){errors.push({key:path||"$root",expected:fmtConstraint("pattern",sup.pattern),received:fmtConstraint("pattern",sub.pattern)})}}if(sup.format!==undefined&&sub.format!==sup.format){if(sub.format===undefined){errors.push({key:path||"$root",expected:fmtConstraint("format",sup.format),received:"no format constraint"})}else{errors.push({key:path||"$root",expected:fmtConstraint("format",sup.format),received:fmtConstraint("format",sub.format)})}}}function checkObjectConstraints(sub,sup,path,errors){if(sup.additionalProperties!==undefined){if(sup.additionalProperties===false){if(sub.additionalProperties===undefined||sub.additionalProperties===true){errors.push({key:path||"$root",expected:"additionalProperties: false",received:"additional properties allowed"})}else if(typeof sub.additionalProperties==="object"&&sub.additionalProperties!==null){errors.push({key:path||"$root",expected:"additionalProperties: false",received:"additionalProperties: schema"})}}else if(typeof sup.additionalProperties==="object"&&sup.additionalProperties!==null){if(sub.additionalProperties===undefined||sub.additionalProperties===true){errors.push({key:path||"$root",expected:`additionalProperties: ${formatSchemaType(sup.additionalProperties)}`,received:"additional properties allowed"})}else if(typeof sub.additionalProperties==="object"&&sub.additionalProperties!==null){const apPath=path?`${path}.<additionalProperties>`:"<additionalProperties>";const apErrors=computeSemanticErrors(sub.additionalProperties,sup.additionalProperties,apPath);errors.push(...apErrors)}}}checkMinConstraint(sub.minProperties,sup.minProperties,"minProperties",path,errors);checkMaxConstraint(sub.maxProperties,sup.maxProperties,"maxProperties",path,errors);if(sup.propertyNames!==undefined){if(sub.propertyNames===undefined){errors.push({key:path||"$root",expected:`propertyNames: ${formatSchemaType(sup.propertyNames)}`,received:"no propertyNames constraint"})}else{const pnErrors=computeSemanticErrors(sub.propertyNames,sup.propertyNames,path?`${path}.<propertyNames>`:"<propertyNames>");errors.push(...pnErrors)}}if(isPlainObj(sup.dependencies)){const supDeps=sup.dependencies;const subDeps=isPlainObj(sub.dependencies)?sub.dependencies:null;for(const key of Object.keys(supDeps)){const supDep=supDeps[key];const subDep=subDeps?.[key];if(subDep===undefined){if(Array.isArray(supDep)){errors.push({key:path||"$root",expected:`dependency: ${key} requires ${supDep.join(", ")}`,received:`no dependency for ${key}`})}else{errors.push({key:path||"$root",expected:`dependency: ${key} requires schema`,received:`no dependency for ${key}`})}}else if(Array.isArray(supDep)&&Array.isArray(subDep)){const missing=supDep.filter(d=>!subDep.includes(d));if(missing.length>0){errors.push({key:path||"$root",expected:`dependency: ${key} requires ${supDep.join(", ")}`,received:`dependency: ${key} requires ${subDep.join(", ")}`})}}else if(!Array.isArray(supDep)&&!Array.isArray(subDep)){const depPath=path?`${path}.<dependency:${key}>`:`<dependency:${key}>`;const depErrors=computeSemanticErrors(subDep,supDep,depPath);errors.push(...depErrors)}else{errors.push({key:path||"$root",expected:Array.isArray(supDep)?`dependency: ${key} requires ${supDep.join(", ")}`:`dependency: ${key} requires schema`,received:Array.isArray(subDep)?`dependency: ${key} requires ${subDep.join(", ")}`:`dependency: ${key} requires schema`})}}}if(isPlainObj(sup.patternProperties)){const supPP=sup.patternProperties;const subPP=isPlainObj(sub.patternProperties)?sub.patternProperties:null;for(const pattern of Object.keys(supPP)){const supPropDef=supPP[pattern];if(supPropDef===undefined)continue;const subPropDef=subPP?.[pattern];const ppPath=path?`${path}.<patternProperties:${pattern}>`:`<patternProperties:${pattern}>`;if(subPropDef===undefined){errors.push({key:ppPath,expected:formatSchemaType(supPropDef),received:"no constraint for this pattern"})}else{const ppErrors=computeSemanticErrors(subPropDef,supPropDef,ppPath);errors.push(...ppErrors)}}}}function checkArrayConstraints(sub,sup,path,errors){checkMinConstraint(sub.minItems,sup.minItems,"minItems",path,errors);checkMaxConstraint(sub.maxItems,sup.maxItems,"maxItems",path,errors);if(sup.uniqueItems===true&&sub.uniqueItems!==true){errors.push({key:path||"$root",expected:"uniqueItems: true",received:fmtConstraint("uniqueItems",sub.uniqueItems??false)})}if(sup.contains!==undefined){if(sub.contains===undefined){errors.push({key:path||"$root",expected:`contains: ${formatSchemaType(sup.contains)}`,received:"no contains constraint"})}else{const containsPath=path?`${path}.<contains>`:"<contains>";const containsErrors=computeSemanticErrors(sub.contains,sup.contains,containsPath);errors.push(...containsErrors)}}}function isNumericType(t){if(t===undefined)return false;if(typeof t==="string")return t==="number"||t==="integer";return t.some(v=>v==="number"||v==="integer")}function isStringType(t){if(t===undefined)return false;if(typeof t==="string")return t==="string";return t.includes("string")}function isObjectType(t){if(t===undefined)return false;if(typeof t==="string")return t==="object";return t.includes("object")}function isArrayType(t){if(t===undefined)return false;if(typeof t==="string")return t==="array";return t.includes("array")}function hasNumericKeywords(s){return s.minimum!==undefined||s.maximum!==undefined||s.exclusiveMinimum!==undefined||s.exclusiveMaximum!==undefined||s.multipleOf!==undefined}function hasStringKeywords(s){return s.minLength!==undefined||s.maxLength!==undefined||s.pattern!==undefined||s.format!==undefined}function hasObjectKeywords(s){return s.minProperties!==undefined||s.maxProperties!==undefined||s.propertyNames!==undefined||s.additionalProperties!==undefined||isPlainObj(s.patternProperties)||isPlainObj(s.dependencies)}function hasArrayKeywords(s){return s.minItems!==undefined||s.maxItems!==undefined||s.uniqueItems!==undefined||s.contains!==undefined}export function computeSemanticErrors(sub,sup,path=""){if(typeof sup==="boolean"){if(sup===false){return[{key:path||"$root",expected:"never",received:formatSchemaType(sub)}]}return[]}if(typeof sub==="boolean"){if(sub===true){return[{key:path||"$root",expected:formatSchemaType(sup),received:"any"}]}return[]}const subSchema=sub;const supSchema=sup;const errors=[];if(hasOwn(supSchema,"not")&&isPlainObj(supSchema.not)&&typeof supSchema.not!=="boolean"){const notSchema=supSchema.not;const notFormatted=formatSchemaType(notSchema);if(!hasOwn(subSchema,"not")){errors.push({key:path||"$root",expected:`not ${notFormatted}`,received:formatSchemaType(subSchema)})}else if(isPlainObj(subSchema.not)&&typeof subSchema.not!=="boolean"){const subNotSchema=subSchema.not;if(!deepEqual(subNotSchema,notSchema)){errors.push({key:path||"$root",expected:`not ${notFormatted}`,received:`not ${formatSchemaType(subNotSchema)}`})}}}const subType=getEffectiveType(subSchema);const supType=getEffectiveType(supSchema);const supBranches=supSchema.anyOf??supSchema.oneOf;if(Array.isArray(supBranches)&&supBranches.length>0&&!supSchema.type){return computeErrorsAgainstBranches(subSchema,supBranches,path)}const subBranches=subSchema.anyOf??subSchema.oneOf;if(Array.isArray(subBranches)&&subBranches.length>0&&!subSchema.type){const branchErrors=[];for(const branch of subBranches){const errs=computeSemanticErrors(branch,sup,path);branchErrors.push(...errs)}return branchErrors}const supProps=getProperties(supSchema);const subProps=getProperties(subSchema);if(supProps!==null||isObjectType(supType)){if(subType!==undefined&&!typeIncludes(subType,"object")){errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)});return errors}if(supProps!==null){const supRequired=getRequired(supSchema);const subRequired=getRequired(subSchema);for(const key of Object.keys(supProps)){const propPath=joinPath(path,key);const supPropDef=supProps[key];const subPropDef=subProps?.[key];if(supPropDef===undefined)continue;const isRequiredInSup=supRequired.includes(key);if(subPropDef===undefined){if(isRequiredInSup){errors.push({key:propPath,expected:formatSchemaType(supPropDef),received:"undefined"})}continue}if(isRequiredInSup&&!subRequired.includes(key)){errors.push({key:propPath,expected:"not optional",received:"optional"});continue}const propErrors=comparePropertySchemas(subPropDef,supPropDef,propPath);errors.push(...propErrors)}}checkCustomConstraints(subSchema,supSchema,path,errors);checkObjectConstraints(subSchema,supSchema,path,errors);return errors}if((supType==="array"||supSchema.items!==undefined)&&(subType==="array"||subSchema.items!==undefined)){if(supSchema.items!==undefined&&typeof supSchema.items!=="boolean"){if(subSchema.items!==undefined&&typeof subSchema.items!=="boolean"){if(Array.isArray(supSchema.items)&&Array.isArray(subSchema.items)){const maxLen=Math.max(supSchema.items.length,subSchema.items.length);for(let i=0;i<maxLen;i++){const supItem=supSchema.items[i];const subItem=subSchema.items[i];const itemPath=joinPath(path,`[${i}]`);if(supItem!==undefined&&subItem===undefined){errors.push({key:itemPath,expected:formatSchemaType(supItem),received:"undefined"})}else if(supItem!==undefined&&subItem!==undefined){errors.push(...computeSemanticErrors(subItem,supItem,itemPath))}}}else if(!Array.isArray(supSchema.items)&&!Array.isArray(subSchema.items)){const itemPath=arrayPath(path);const itemErrors=computeSemanticErrors(subSchema.items,supSchema.items,itemPath);errors.push(...itemErrors)}}else{errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)})}}checkCustomConstraints(subSchema,supSchema,path,errors);checkArrayConstraints(subSchema,supSchema,path,errors);return errors}if(subType!==undefined&&supType!==undefined){if(!typesAreCompatible(subType,supType)){errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)});return errors}}if(Array.isArray(supSchema.enum)){if(Array.isArray(subSchema.enum)){const subExtra=subSchema.enum.filter(v=>!supSchema.enum?.some(sv=>deepEqual(v,sv)));if(subExtra.length>0){errors.push({key:path||"$root",expected:formatEnumValues(supSchema.enum),received:formatEnumValues(subSchema.enum)})}}else if(hasOwn(subSchema,"const")){const constInEnum=supSchema.enum.some(v=>deepEqual(v,subSchema.const));if(!constInEnum){errors.push({key:path||"$root",expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)})}}else{errors.push({key:path||"$root",expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)})}return errors}if(hasOwn(supSchema,"const")&&hasOwn(subSchema,"const")){if(!deepEqual(supSchema.const,subSchema.const)){errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)})}return errors}checkCustomConstraints(subSchema,supSchema,path,errors);if(isNumericType(subType)||isNumericType(supType)||hasNumericKeywords(supSchema)||hasNumericKeywords(subSchema)){checkNumericConstraints(subSchema,supSchema,path,errors)}if(isStringType(subType)||isStringType(supType)||hasStringKeywords(supSchema)||hasStringKeywords(subSchema)){checkStringConstraints(subSchema,supSchema,path,errors)}if(isObjectType(subType)||isObjectType(supType)||hasObjectKeywords(supSchema)||hasObjectKeywords(subSchema)){checkObjectConstraints(subSchema,supSchema,path,errors)}if(isArrayType(subType)||isArrayType(supType)||hasArrayKeywords(supSchema)||hasArrayKeywords(subSchema)){checkArrayConstraints(subSchema,supSchema,path,errors)}if(errors.length>0){return errors}const expectedStr=formatSchemaType(supSchema);const receivedStr=formatSchemaType(subSchema);if(expectedStr!==receivedStr){errors.push({key:path||"$root",expected:expectedStr,received:receivedStr})}return errors}function comparePropertySchemas(subDef,supDef,path){if(typeof subDef==="boolean"||typeof supDef==="boolean"){if(subDef!==supDef){return[{key:path,expected:formatSchemaType(supDef),received:formatSchemaType(subDef)}]}return[]}const subSchema=subDef;const supSchema=supDef;const subType=getEffectiveType(subSchema);const supType=getEffectiveType(supSchema);if(Array.isArray(supSchema.enum)){if(Array.isArray(subSchema.enum)){const subExtra=subSchema.enum.filter(v=>!supSchema.enum?.some(sv=>deepEqual(v,sv)));if(subExtra.length>0){return[{key:path,expected:formatEnumValues(supSchema.enum),received:formatEnumValues(subSchema.enum)}]}return[]}if(hasOwn(subSchema,"const")){const constInEnum=supSchema.enum.some(v=>deepEqual(v,subSchema.const));if(!constInEnum){return[{key:path,expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)}]}return[]}return[{key:path,expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)}]}if(hasOwn(supSchema,"const")&&hasOwn(subSchema,"const")){if(!deepEqual(supSchema.const,subSchema.const)){return[{key:path,expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)}]}return[]}if(subType!==undefined&&supType!==undefined){if(!typesAreCompatible(subType,supType)){return[{key:path,expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)}]}}return computeSemanticErrors(subDef,supDef,path)}function computeErrorsAgainstBranches(sub,branches,path){let bestErrors=null;for(const branch of branches){const errors=computeSemanticErrors(sub,branch,path);if(errors.length===0)return[];if(bestErrors===null||errors.length<bestErrors.length){bestErrors=errors}}return bestErrors??[{key:path||"$root",expected:formatSchemaType({anyOf:branches}),received:formatSchemaType(sub)}]}
1
+ import{deepEqual,hasOwn,isPlainObj}from"./utils.js";function formatEnumValues(values){const parts=values.map(v=>typeof v==="string"?v:JSON.stringify(v));if(parts.length===0)return"never";if(parts.length===1)return parts[0];if(parts.length===2)return`${parts[0]} or ${parts[1]}`;const last=parts.pop();return`${parts.join(", ")}, or ${last}`}export function formatSchemaType(def){return formatSchemaTypeInternal(def)}function formatSchemaTypeInternal(def){if(def===undefined)return"undefined";if(typeof def==="boolean")return def?"any":"never";const schema=def;if(hasOwn(schema,"const")){const v=schema.const;return typeof v==="string"?v:JSON.stringify(v)}if(Array.isArray(schema.enum)){return formatEnumValues(schema.enum)}const branches=schema.anyOf??schema.oneOf;if(Array.isArray(branches)&&branches.length>0){const parts=branches.map(b=>formatSchemaType(b));return parts.join(" | ")}if(schema.type==="array"){if(schema.items!==undefined&&typeof schema.items!=="boolean"){const itemSchema=schema.items;const itemBranches=itemSchema.anyOf??itemSchema.oneOf;if(Array.isArray(itemBranches)&&itemBranches.length>0){const parts=itemBranches.map(b=>`${formatSchemaType(b)}[]`);return parts.join(" | ")}if(Array.isArray(itemSchema.type)){const parts=itemSchema.type.map(t=>`${t}[]`);return parts.join(" | ")}const itemType=formatSchemaType(itemSchema);return`${itemType}[]`}return"array"}if(typeof schema.type==="string"){return schema.type}if(Array.isArray(schema.type)){return schema.type.join(" | ")}if(hasOwn(schema,"not")&&!schema.type&&!isPlainObj(schema.properties)&&schema.items===undefined&&!Array.isArray(schema.enum)&&!hasOwn(schema,"const")){return`not ${formatSchemaType(schema.not)}`}if(isPlainObj(schema.properties))return"object";if(schema.items!==undefined)return"array";return"unknown"}function joinPath(parent,key){if(!parent)return key;return`${parent}.${key}`}function arrayPath(parent){if(!parent)return"[]";return`${parent}[]`}function getProperties(schema){if(isPlainObj(schema.properties)){return schema.properties}return null}function getRequired(schema){if(Array.isArray(schema.required)){return schema.required}return[]}function getEffectiveType(schema){if(schema.type!==undefined)return schema.type;if(hasOwn(schema,"const")){const v=schema.const;if(v===null)return"null";if(Array.isArray(v))return"array";return typeof v}if(isPlainObj(schema.properties))return"object";if(schema.items!==undefined)return"array";return undefined}function typeIncludes(schemaType,target){if(schemaType===undefined)return false;if(typeof schemaType==="string"){if(target==="number"&&schemaType==="integer")return true;if(target==="integer"&&schemaType==="number")return true;return schemaType===target}return schemaType.includes(target)}function typesAreCompatible(subType,supType){if(supType===undefined)return true;if(subType===undefined)return true;if(typeof subType==="string"&&typeof supType==="string"){if(subType===supType)return true;if(subType==="integer"&&supType==="number")return true;return false}if(typeof subType==="string"&&Array.isArray(supType)){return supType.some(t=>t===subType||subType==="integer"&&t==="number")}if(Array.isArray(subType)&&typeof supType==="string"){return subType.every(t=>t===supType||t==="integer"&&supType==="number")}if(Array.isArray(subType)&&Array.isArray(supType)){return subType.every(st=>supType.some(supt=>supt===st||st==="integer"&&supt==="number"))}return true}function fmtConstraint(name,value){if(value===undefined)return`${name}: not set`;if(typeof value==="boolean")return`${name}: ${value}`;if(typeof value==="number"||typeof value==="string")return`${name}: ${value}`;return`${name}: ${JSON.stringify(value)}`}function checkMinConstraint(subVal,supVal,name,path,errors){if(supVal!==undefined){if(subVal===undefined||subVal<supVal){errors.push({key:path||"$root",expected:fmtConstraint(name,supVal),received:fmtConstraint(name,subVal)})}}}function checkMaxConstraint(subVal,supVal,name,path,errors){if(supVal!==undefined){if(subVal===undefined||subVal>supVal){errors.push({key:path||"$root",expected:fmtConstraint(name,supVal),received:fmtConstraint(name,subVal)})}}}function checkNumericConstraints(sub,sup,path,errors){checkMinConstraint(sub.minimum,sup.minimum,"minimum",path,errors);checkMaxConstraint(sub.maximum,sup.maximum,"maximum",path,errors);checkMinConstraint(sub.exclusiveMinimum,sup.exclusiveMinimum,"exclusiveMinimum",path,errors);checkMaxConstraint(sub.exclusiveMaximum,sup.exclusiveMaximum,"exclusiveMaximum",path,errors);if(sup.multipleOf!==undefined){if(sub.multipleOf===undefined){errors.push({key:path||"$root",expected:fmtConstraint("multipleOf",sup.multipleOf),received:fmtConstraint("multipleOf",sub.multipleOf)})}else if(sub.multipleOf!==sup.multipleOf){if(sub.multipleOf%sup.multipleOf!==0){errors.push({key:path||"$root",expected:fmtConstraint("multipleOf",sup.multipleOf),received:fmtConstraint("multipleOf",sub.multipleOf)})}}}}function checkStringConstraints(sub,sup,path,errors){checkMinConstraint(sub.minLength,sup.minLength,"minLength",path,errors);checkMaxConstraint(sub.maxLength,sup.maxLength,"maxLength",path,errors);if(sup.pattern!==undefined){if(sub.pattern===undefined){errors.push({key:path||"$root",expected:fmtConstraint("pattern",sup.pattern),received:"no pattern constraint"})}else if(sub.pattern!==sup.pattern){errors.push({key:path||"$root",expected:fmtConstraint("pattern",sup.pattern),received:fmtConstraint("pattern",sub.pattern)})}}if(sup.format!==undefined&&sub.format!==sup.format){if(sub.format===undefined){errors.push({key:path||"$root",expected:fmtConstraint("format",sup.format),received:"no format constraint"})}else{errors.push({key:path||"$root",expected:fmtConstraint("format",sup.format),received:fmtConstraint("format",sub.format)})}}}function checkObjectConstraints(sub,sup,path,errors){if(sup.additionalProperties!==undefined){if(sup.additionalProperties===false){if(sub.additionalProperties===undefined||sub.additionalProperties===true){errors.push({key:path||"$root",expected:"additionalProperties: false",received:"additional properties allowed"})}else if(typeof sub.additionalProperties==="object"&&sub.additionalProperties!==null){errors.push({key:path||"$root",expected:"additionalProperties: false",received:"additionalProperties: schema"})}}else if(typeof sup.additionalProperties==="object"&&sup.additionalProperties!==null){if(sub.additionalProperties===undefined||sub.additionalProperties===true){errors.push({key:path||"$root",expected:`additionalProperties: ${formatSchemaType(sup.additionalProperties)}`,received:"additional properties allowed"})}else if(typeof sub.additionalProperties==="object"&&sub.additionalProperties!==null){const apPath=path?`${path}.<additionalProperties>`:"<additionalProperties>";const apErrors=computeSemanticErrors(sub.additionalProperties,sup.additionalProperties,apPath);errors.push(...apErrors)}}}checkMinConstraint(sub.minProperties,sup.minProperties,"minProperties",path,errors);checkMaxConstraint(sub.maxProperties,sup.maxProperties,"maxProperties",path,errors);if(sup.propertyNames!==undefined){if(sub.propertyNames===undefined){errors.push({key:path||"$root",expected:`propertyNames: ${formatSchemaType(sup.propertyNames)}`,received:"no propertyNames constraint"})}else{const pnErrors=computeSemanticErrors(sub.propertyNames,sup.propertyNames,path?`${path}.<propertyNames>`:"<propertyNames>");errors.push(...pnErrors)}}if(isPlainObj(sup.dependencies)){const supDeps=sup.dependencies;const subDeps=isPlainObj(sub.dependencies)?sub.dependencies:null;for(const key of Object.keys(supDeps)){const supDep=supDeps[key];const subDep=subDeps?.[key];if(subDep===undefined){if(Array.isArray(supDep)){errors.push({key:path||"$root",expected:`dependency: ${key} requires ${supDep.join(", ")}`,received:`no dependency for ${key}`})}else{errors.push({key:path||"$root",expected:`dependency: ${key} requires schema`,received:`no dependency for ${key}`})}}else if(Array.isArray(supDep)&&Array.isArray(subDep)){const missing=supDep.filter(d=>!subDep.includes(d));if(missing.length>0){errors.push({key:path||"$root",expected:`dependency: ${key} requires ${supDep.join(", ")}`,received:`dependency: ${key} requires ${subDep.join(", ")}`})}}else if(!Array.isArray(supDep)&&!Array.isArray(subDep)){const depPath=path?`${path}.<dependency:${key}>`:`<dependency:${key}>`;const depErrors=computeSemanticErrors(subDep,supDep,depPath);errors.push(...depErrors)}else{errors.push({key:path||"$root",expected:Array.isArray(supDep)?`dependency: ${key} requires ${supDep.join(", ")}`:`dependency: ${key} requires schema`,received:Array.isArray(subDep)?`dependency: ${key} requires ${subDep.join(", ")}`:`dependency: ${key} requires schema`})}}}if(isPlainObj(sup.patternProperties)){const supPP=sup.patternProperties;const subPP=isPlainObj(sub.patternProperties)?sub.patternProperties:null;for(const pattern of Object.keys(supPP)){const supPropDef=supPP[pattern];if(supPropDef===undefined)continue;const subPropDef=subPP?.[pattern];const ppPath=path?`${path}.<patternProperties:${pattern}>`:`<patternProperties:${pattern}>`;if(subPropDef===undefined){errors.push({key:ppPath,expected:formatSchemaType(supPropDef),received:"no constraint for this pattern"})}else{const ppErrors=computeSemanticErrors(subPropDef,supPropDef,ppPath);errors.push(...ppErrors)}}}}function checkArrayConstraints(sub,sup,path,errors){checkMinConstraint(sub.minItems,sup.minItems,"minItems",path,errors);checkMaxConstraint(sub.maxItems,sup.maxItems,"maxItems",path,errors);if(sup.uniqueItems===true&&sub.uniqueItems!==true){errors.push({key:path||"$root",expected:"uniqueItems: true",received:fmtConstraint("uniqueItems",sub.uniqueItems??false)})}if(sup.contains!==undefined){if(sub.contains===undefined){errors.push({key:path||"$root",expected:`contains: ${formatSchemaType(sup.contains)}`,received:"no contains constraint"})}else{const containsPath=path?`${path}.<contains>`:"<contains>";const containsErrors=computeSemanticErrors(sub.contains,sup.contains,containsPath);errors.push(...containsErrors)}}}function isNumericType(t){if(t===undefined)return false;if(typeof t==="string")return t==="number"||t==="integer";return t.some(v=>v==="number"||v==="integer")}function isStringType(t){if(t===undefined)return false;if(typeof t==="string")return t==="string";return t.includes("string")}function isObjectType(t){if(t===undefined)return false;if(typeof t==="string")return t==="object";return t.includes("object")}function isArrayType(t){if(t===undefined)return false;if(typeof t==="string")return t==="array";return t.includes("array")}function hasNumericKeywords(s){return s.minimum!==undefined||s.maximum!==undefined||s.exclusiveMinimum!==undefined||s.exclusiveMaximum!==undefined||s.multipleOf!==undefined}function hasStringKeywords(s){return s.minLength!==undefined||s.maxLength!==undefined||s.pattern!==undefined||s.format!==undefined}function hasObjectKeywords(s){return s.minProperties!==undefined||s.maxProperties!==undefined||s.propertyNames!==undefined||s.additionalProperties!==undefined||isPlainObj(s.patternProperties)||isPlainObj(s.dependencies)}function hasArrayKeywords(s){return s.minItems!==undefined||s.maxItems!==undefined||s.uniqueItems!==undefined||s.contains!==undefined}export function computeSemanticErrors(sub,sup,path=""){if(typeof sup==="boolean"){if(sup===false){return[{key:path||"$root",expected:"never",received:formatSchemaType(sub)}]}return[]}if(typeof sub==="boolean"){if(sub===true){return[{key:path||"$root",expected:formatSchemaType(sup),received:"any"}]}return[]}const subSchema=sub;const supSchema=sup;const errors=[];if(hasOwn(supSchema,"not")&&isPlainObj(supSchema.not)&&typeof supSchema.not!=="boolean"){const notSchema=supSchema.not;const notFormatted=formatSchemaType(notSchema);if(!hasOwn(subSchema,"not")){errors.push({key:path||"$root",expected:`not ${notFormatted}`,received:formatSchemaType(subSchema)})}else if(isPlainObj(subSchema.not)&&typeof subSchema.not!=="boolean"){const subNotSchema=subSchema.not;if(!deepEqual(subNotSchema,notSchema)){errors.push({key:path||"$root",expected:`not ${notFormatted}`,received:`not ${formatSchemaType(subNotSchema)}`})}}}const subType=getEffectiveType(subSchema);const supType=getEffectiveType(supSchema);const supBranches=supSchema.anyOf??supSchema.oneOf;if(Array.isArray(supBranches)&&supBranches.length>0&&!supSchema.type){return computeErrorsAgainstBranches(subSchema,supBranches,path)}const subBranches=subSchema.anyOf??subSchema.oneOf;if(Array.isArray(subBranches)&&subBranches.length>0&&!subSchema.type){const branchErrors=[];for(const branch of subBranches){const errs=computeSemanticErrors(branch,sup,path);branchErrors.push(...errs)}return branchErrors}const supProps=getProperties(supSchema);const subProps=getProperties(subSchema);if(supProps!==null||isObjectType(supType)){if(subType!==undefined&&!typeIncludes(subType,"object")){errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)});return errors}if(supProps!==null){const supRequired=getRequired(supSchema);const subRequired=getRequired(subSchema);for(const key of Object.keys(supProps)){const propPath=joinPath(path,key);const supPropDef=supProps[key];const subPropDef=subProps?.[key];if(supPropDef===undefined)continue;const isRequiredInSup=supRequired.includes(key);if(subPropDef===undefined){if(isRequiredInSup){errors.push({key:propPath,expected:formatSchemaType(supPropDef),received:"undefined"})}continue}if(isRequiredInSup&&!subRequired.includes(key)){errors.push({key:propPath,expected:"not optional",received:"optional"});continue}const propErrors=comparePropertySchemas(subPropDef,supPropDef,propPath);errors.push(...propErrors)}}checkObjectConstraints(subSchema,supSchema,path,errors);return errors}if((supType==="array"||supSchema.items!==undefined)&&(subType==="array"||subSchema.items!==undefined)){if(supSchema.items!==undefined&&typeof supSchema.items!=="boolean"){if(subSchema.items!==undefined&&typeof subSchema.items!=="boolean"){if(Array.isArray(supSchema.items)&&Array.isArray(subSchema.items)){const maxLen=Math.max(supSchema.items.length,subSchema.items.length);for(let i=0;i<maxLen;i++){const supItem=supSchema.items[i];const subItem=subSchema.items[i];const itemPath=joinPath(path,`[${i}]`);if(supItem!==undefined&&subItem===undefined){errors.push({key:itemPath,expected:formatSchemaType(supItem),received:"undefined"})}else if(supItem!==undefined&&subItem!==undefined){errors.push(...computeSemanticErrors(subItem,supItem,itemPath))}}}else if(!Array.isArray(supSchema.items)&&!Array.isArray(subSchema.items)){const itemPath=arrayPath(path);const itemErrors=computeSemanticErrors(subSchema.items,supSchema.items,itemPath);errors.push(...itemErrors)}}else{errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)})}}checkArrayConstraints(subSchema,supSchema,path,errors);return errors}if(subType!==undefined&&supType!==undefined){if(!typesAreCompatible(subType,supType)){errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)});return errors}}if(Array.isArray(supSchema.enum)){if(Array.isArray(subSchema.enum)){const subExtra=subSchema.enum.filter(v=>!supSchema.enum?.some(sv=>deepEqual(v,sv)));if(subExtra.length>0){errors.push({key:path||"$root",expected:formatEnumValues(supSchema.enum),received:formatEnumValues(subSchema.enum)})}}else if(hasOwn(subSchema,"const")){const constInEnum=supSchema.enum.some(v=>deepEqual(v,subSchema.const));if(!constInEnum){errors.push({key:path||"$root",expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)})}}else{errors.push({key:path||"$root",expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)})}return errors}if(hasOwn(supSchema,"const")&&hasOwn(subSchema,"const")){if(!deepEqual(supSchema.const,subSchema.const)){errors.push({key:path||"$root",expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)})}return errors}if(isNumericType(subType)||isNumericType(supType)||hasNumericKeywords(supSchema)||hasNumericKeywords(subSchema)){checkNumericConstraints(subSchema,supSchema,path,errors)}if(isStringType(subType)||isStringType(supType)||hasStringKeywords(supSchema)||hasStringKeywords(subSchema)){checkStringConstraints(subSchema,supSchema,path,errors)}if(isObjectType(subType)||isObjectType(supType)||hasObjectKeywords(supSchema)||hasObjectKeywords(subSchema)){checkObjectConstraints(subSchema,supSchema,path,errors)}if(isArrayType(subType)||isArrayType(supType)||hasArrayKeywords(supSchema)||hasArrayKeywords(subSchema)){checkArrayConstraints(subSchema,supSchema,path,errors)}if(errors.length>0){return errors}const expectedStr=formatSchemaType(supSchema);const receivedStr=formatSchemaType(subSchema);if(expectedStr!==receivedStr){errors.push({key:path||"$root",expected:expectedStr,received:receivedStr})}return errors}function comparePropertySchemas(subDef,supDef,path){if(typeof subDef==="boolean"||typeof supDef==="boolean"){if(subDef!==supDef){return[{key:path,expected:formatSchemaType(supDef),received:formatSchemaType(subDef)}]}return[]}const subSchema=subDef;const supSchema=supDef;const subType=getEffectiveType(subSchema);const supType=getEffectiveType(supSchema);if(Array.isArray(supSchema.enum)){if(Array.isArray(subSchema.enum)){const subExtra=subSchema.enum.filter(v=>!supSchema.enum?.some(sv=>deepEqual(v,sv)));if(subExtra.length>0){return[{key:path,expected:formatEnumValues(supSchema.enum),received:formatEnumValues(subSchema.enum)}]}return[]}if(hasOwn(subSchema,"const")){const constInEnum=supSchema.enum.some(v=>deepEqual(v,subSchema.const));if(!constInEnum){return[{key:path,expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)}]}return[]}return[{key:path,expected:formatEnumValues(supSchema.enum),received:formatSchemaType(subSchema)}]}if(hasOwn(supSchema,"const")&&hasOwn(subSchema,"const")){if(!deepEqual(supSchema.const,subSchema.const)){return[{key:path,expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)}]}return[]}if(subType!==undefined&&supType!==undefined){if(!typesAreCompatible(subType,supType)){return[{key:path,expected:formatSchemaType(supSchema),received:formatSchemaType(subSchema)}]}}return computeSemanticErrors(subDef,supDef,path)}function computeErrorsAgainstBranches(sub,branches,path){let bestErrors=null;for(const branch of branches){const errors=computeSemanticErrors(sub,branch,path);if(errors.length===0)return[];if(bestErrors===null||errors.length<bestErrors.length){bestErrors=errors}}return bestErrors??[{key:path||"$root",expected:formatSchemaType({anyOf:branches}),received:formatSchemaType(sub)}]}
2
2
  //# sourceMappingURL=semantic-errors.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/semantic-errors.ts"],"sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport type { Constraint, SchemaError } from \"./types.ts\";\nimport { deepEqual, hasOwn, isPlainObj } from \"./utils.ts\";\n\n// ─── Semantic Error Generator ────────────────────────────────────────────────\n//\n// Generates human-readable semantic errors by directly comparing two schemas.\n//\n// Unlike a structural differ (which would compare sub vs merged), this module\n// directly compares sub (source/received) and sup (target/expected) to produce\n// business-oriented error messages.\n//\n// Property paths are normalized:\n// - `accountId` (top-level property)\n// - `user.name` (nested property)\n// - `users[].name` (property inside array items)\n//\n// Convention:\n// - `expected` = what the target schema (sup) expects\n// - `received` = what the source schema (sub) provides\n\n// ─── Type Formatting ─────────────────────────────────────────────────────────\n\n/**\n * Formats enum values into a readable string.\n *\n * Examples:\n * - 1 value : `\"123\"`\n * - 2 values : `\"123 or hello\"`\n * - 3 values : `\"10, 20, or 30\"`\n */\nfunction formatEnumValues(values: unknown[]): string {\n\tconst parts = values.map((v) =>\n\t\ttypeof v === \"string\" ? v : JSON.stringify(v),\n\t);\n\tif (parts.length === 0) return \"never\";\n\tif (parts.length === 1) return parts[0] as string;\n\tif (parts.length === 2) return `${parts[0]} or ${parts[1]}`;\n\tconst last = parts.pop();\n\treturn `${parts.join(\", \")}, or ${last}`;\n}\n\n/**\n * Formats a schema into a readable type representation.\n *\n * Examples:\n * - `{ type: \"string\" }` → `\"string\"`\n * - `{ type: \"array\", items: { type: \"string\" } }` → `\"string[]\"`\n * - `{ type: \"array\", items: { type: [\"string\",\"number\"] }` → `\"string[] | number[]\"`\n * - `{ enum: [1, 2, 3] }` → `\"1, 2, or 3\"`\n * - `{ const: \"hello\" }` → `\"hello\"`\n * - `{ anyOf: [{type:\"string\"},{type:\"number\"}] }` → `\"string | number\"`\n * - `undefined` → `\"undefined\"`\n */\nexport function formatSchemaType(\n\tdef: JSONSchema7Definition | undefined,\n): string {\n\tconst base = formatSchemaTypeInternal(def);\n\tif (def === undefined || typeof def === \"boolean\") return base;\n\treturn base + formatConstraintsSuffix(def as JSONSchema7);\n}\n\n/**\n * Formats the constraints suffix for a schema type description.\n * Returns an empty string if there are no constraints.\n *\n * @example\n * formatConstraintsSuffix({ type: \"string\", constraints: [\"IsUuid\", \"BelongsToScope\"] })\n * // → \" [IsUuid, BelongsToScope]\"\n *\n * formatConstraintsSuffix({ type: \"string\" })\n * // → \"\"\n */\nfunction formatConstraintsSuffix(schema: JSONSchema7): string {\n\tconst constraints = schema.constraints;\n\tif (constraints === undefined) return \"\";\n\n\tconst arr = Array.isArray(constraints) ? constraints : [constraints];\n\tif (arr.length === 0) return \"\";\n\n\treturn ` [${arr.map(formatCustomConstraint).join(\", \")}]`;\n}\n\nfunction formatSchemaTypeInternal(\n\tdef: JSONSchema7Definition | undefined,\n): string {\n\tif (def === undefined) return \"undefined\";\n\tif (typeof def === \"boolean\") return def ? \"any\" : \"never\";\n\n\tconst schema = def as JSONSchema7;\n\n\t// ── Const ──\n\tif (hasOwn(schema, \"const\")) {\n\t\tconst v = schema.const;\n\t\treturn typeof v === \"string\" ? v : JSON.stringify(v);\n\t}\n\n\t// ── Enum ──\n\tif (Array.isArray(schema.enum)) {\n\t\treturn formatEnumValues(schema.enum);\n\t}\n\n\t// ── anyOf / oneOf (union types) ──\n\tconst branches = schema.anyOf ?? schema.oneOf;\n\tif (Array.isArray(branches) && branches.length > 0) {\n\t\tconst parts = branches.map((b) => formatSchemaType(b));\n\t\treturn parts.join(\" | \");\n\t}\n\n\t// ── Array type ──\n\tif (schema.type === \"array\") {\n\t\tif (schema.items !== undefined && typeof schema.items !== \"boolean\") {\n\t\t\tconst itemSchema = schema.items as JSONSchema7;\n\n\t\t\t// Items with anyOf/oneOf → \"string[] | number[]\"\n\t\t\tconst itemBranches = itemSchema.anyOf ?? itemSchema.oneOf;\n\t\t\tif (Array.isArray(itemBranches) && itemBranches.length > 0) {\n\t\t\t\tconst parts = itemBranches.map((b) => `${formatSchemaType(b)}[]`);\n\t\t\t\treturn parts.join(\" | \");\n\t\t\t}\n\n\t\t\t// Items with multiple types → \"string[] | number[]\"\n\t\t\tif (Array.isArray(itemSchema.type)) {\n\t\t\t\tconst parts = itemSchema.type.map((t) => `${t}[]`);\n\t\t\t\treturn parts.join(\" | \");\n\t\t\t}\n\n\t\t\tconst itemType = formatSchemaType(itemSchema);\n\t\t\treturn `${itemType}[]`;\n\t\t}\n\t\t// items is boolean true or missing\n\t\treturn \"array\";\n\t}\n\n\t// ── Simple type ──\n\tif (typeof schema.type === \"string\") {\n\t\treturn schema.type;\n\t}\n\n\t// ── Multiple types (type: [\"string\", \"number\"]) ──\n\tif (Array.isArray(schema.type)) {\n\t\treturn schema.type.join(\" | \");\n\t}\n\n\t// ── not (pure-not schema, no other significant keywords) ──\n\tif (\n\t\thasOwn(schema, \"not\") &&\n\t\t!schema.type &&\n\t\t!isPlainObj(schema.properties) &&\n\t\tschema.items === undefined &&\n\t\t!Array.isArray(schema.enum) &&\n\t\t!hasOwn(schema, \"const\")\n\t) {\n\t\treturn `not ${formatSchemaType(schema.not as JSONSchema7Definition)}`;\n\t}\n\n\t// ── Fallback ──\n\t// Schema without explicit type — try to infer from structure\n\tif (isPlainObj(schema.properties)) return \"object\";\n\tif (schema.items !== undefined) return \"array\";\n\n\treturn \"unknown\";\n}\n\n// ─── Path Helpers ────────────────────────────────────────────────────────────\n\n/**\n * Builds a normalized property path.\n * - Root + key → `\"accountId\"`\n * - Parent + key → `\"user.name\"`\n * - Parent[] + key → `\"users[].name\"`\n */\nfunction joinPath(parent: string, key: string): string {\n\tif (!parent) return key;\n\treturn `${parent}.${key}`;\n}\n\n/**\n * Appends the `[]` suffix to indicate entering array items.\n */\nfunction arrayPath(parent: string): string {\n\tif (!parent) return \"[]\";\n\treturn `${parent}[]`;\n}\n\n// ─── Schema Accessors ────────────────────────────────────────────────────────\n\n/**\n * Safely extracts the properties from a schema.\n */\nfunction getProperties(\n\tschema: JSONSchema7,\n): Record<string, JSONSchema7Definition> | null {\n\tif (isPlainObj(schema.properties)) {\n\t\treturn schema.properties as Record<string, JSONSchema7Definition>;\n\t}\n\treturn null;\n}\n\n/**\n * Safely extracts the required fields from a schema.\n */\nfunction getRequired(schema: JSONSchema7): string[] {\n\tif (Array.isArray(schema.required)) {\n\t\treturn schema.required as string[];\n\t}\n\treturn [];\n}\n\n/**\n * Determines the effective type of a schema (string or array of types).\n */\nfunction getEffectiveType(schema: JSONSchema7): string | string[] | undefined {\n\tif (schema.type !== undefined) return schema.type as string | string[];\n\n\t// Infer from const\n\tif (hasOwn(schema, \"const\")) {\n\t\tconst v = schema.const;\n\t\tif (v === null) return \"null\";\n\t\tif (Array.isArray(v)) return \"array\";\n\t\treturn typeof v;\n\t}\n\n\t// Infer from properties\n\tif (isPlainObj(schema.properties)) return \"object\";\n\n\t// Infer from items\n\tif (schema.items !== undefined) return \"array\";\n\n\treturn undefined;\n}\n\n/**\n * Checks whether a type (string) is included in a type or array of types.\n */\nfunction typeIncludes(\n\tschemaType: string | string[] | undefined,\n\ttarget: string,\n): boolean {\n\tif (schemaType === undefined) return false;\n\tif (typeof schemaType === \"string\") {\n\t\t// integer is a subset of number\n\t\tif (target === \"number\" && schemaType === \"integer\") return true;\n\t\tif (target === \"integer\" && schemaType === \"number\") return true;\n\t\treturn schemaType === target;\n\t}\n\treturn schemaType.includes(target);\n}\n\n/**\n * Checks whether two types are compatible.\n * A type is compatible if the sub type is included in the sup type.\n */\nfunction typesAreCompatible(\n\tsubType: string | string[] | undefined,\n\tsupType: string | string[] | undefined,\n): boolean {\n\tif (supType === undefined) return true; // sup accepts anything\n\tif (subType === undefined) return true; // sub is undetermined, cannot conclude\n\n\tif (typeof subType === \"string\" && typeof supType === \"string\") {\n\t\tif (subType === supType) return true;\n\t\t// integer ⊆ number\n\t\tif (subType === \"integer\" && supType === \"number\") return true;\n\t\treturn false;\n\t}\n\n\tif (typeof subType === \"string\" && Array.isArray(supType)) {\n\t\treturn supType.some(\n\t\t\t(t) => t === subType || (subType === \"integer\" && t === \"number\"),\n\t\t);\n\t}\n\n\tif (Array.isArray(subType) && typeof supType === \"string\") {\n\t\treturn subType.every(\n\t\t\t(t) => t === supType || (t === \"integer\" && supType === \"number\"),\n\t\t);\n\t}\n\n\tif (Array.isArray(subType) && Array.isArray(supType)) {\n\t\treturn subType.every((st) =>\n\t\t\tsupType.some(\n\t\t\t\t(supt) => supt === st || (st === \"integer\" && supt === \"number\"),\n\t\t\t),\n\t\t);\n\t}\n\n\treturn true;\n}\n\n// ─── Custom Constraint Helpers ───────────────────────────────────────────────\n\n/**\n * Formats a custom constraint into a readable string.\n * @example formatCustomConstraint(\"IsUuid\") → \"IsUuid\"\n * @example formatCustomConstraint({ name: \"MinAge\", params: { min: 21 } }) → 'MinAge({\"min\":21})'\n * @example formatCustomConstraint({ name: \"IsCustom\" }) → \"IsCustom\"\n */\nfunction formatCustomConstraint(c: Constraint): string {\n\tif (typeof c === \"string\") return c;\n\tif (c.params && Object.keys(c.params).length > 0) {\n\t\treturn `${c.name}(${JSON.stringify(c.params)})`;\n\t}\n\treturn c.name;\n}\n\n/**\n * Formats a list of custom constraints into a readable string.\n */\nfunction formatCustomConstraintList(cs: Constraint[]): string {\n\treturn cs.map(formatCustomConstraint).join(\", \");\n}\n\n/**\n * Compares custom constraints between sub and sup.\n *\n * For sub ⊆ sup, every constraint in sup must have an exact match\n * (by deep equality) in sub. Missing constraints are reported as errors.\n */\nfunction checkCustomConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tconst supConstraints = sup.constraints;\n\tconst subConstraints = sub.constraints;\n\n\t// If sup has no constraints, nothing to check\n\tif (supConstraints === undefined) return;\n\n\tconst supArr = Array.isArray(supConstraints)\n\t\t? supConstraints\n\t\t: [supConstraints];\n\tconst subArr =\n\t\tsubConstraints === undefined\n\t\t\t? []\n\t\t\t: Array.isArray(subConstraints)\n\t\t\t\t? subConstraints\n\t\t\t\t: [subConstraints];\n\n\t// Find constraints in sup that are missing from sub\n\tfor (const supC of supArr) {\n\t\tconst found = subArr.some((subC) => deepEqual(subC, supC));\n\t\tif (!found) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `constraint: ${formatCustomConstraint(supC)}`,\n\t\t\t\treceived:\n\t\t\t\t\tsubArr.length > 0\n\t\t\t\t\t\t? `constraints: ${formatCustomConstraintList(subArr)}`\n\t\t\t\t\t\t: \"no constraints\",\n\t\t\t});\n\t\t}\n\t}\n}\n\n// ─── Constraint Helpers ──────────────────────────────────────────────────────\n\n/**\n * Formats a constraint value into a readable string.\n */\nfunction fmtConstraint(name: string, value: unknown): string {\n\tif (value === undefined) return `${name}: not set`;\n\tif (typeof value === \"boolean\") return `${name}: ${value}`;\n\tif (typeof value === \"number\" || typeof value === \"string\")\n\t\treturn `${name}: ${value}`;\n\treturn `${name}: ${JSON.stringify(value)}`;\n}\n\n/**\n * Compares a \"minimum-like\" numeric constraint (sub.X must be >= sup.X for sub ⊆ sup).\n * Examples: minimum, exclusiveMinimum, minLength, minItems, minProperties\n */\nfunction checkMinConstraint(\n\tsubVal: number | undefined,\n\tsupVal: number | undefined,\n\tname: string,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tif (supVal !== undefined) {\n\t\tif (subVal === undefined || subVal < supVal) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(name, supVal),\n\t\t\t\treceived: fmtConstraint(name, subVal),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Compares a \"maximum-like\" numeric constraint (sub.X must be <= sup.X for sub ⊆ sup).\n * Examples: maximum, exclusiveMaximum, maxLength, maxItems, maxProperties\n */\nfunction checkMaxConstraint(\n\tsubVal: number | undefined,\n\tsupVal: number | undefined,\n\tname: string,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tif (supVal !== undefined) {\n\t\tif (subVal === undefined || subVal > supVal) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(name, supVal),\n\t\t\t\treceived: fmtConstraint(name, subVal),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Compares numeric constraints between sub and sup.\n */\nfunction checkNumericConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tcheckMinConstraint(sub.minimum, sup.minimum, \"minimum\", path, errors);\n\tcheckMaxConstraint(sub.maximum, sup.maximum, \"maximum\", path, errors);\n\tcheckMinConstraint(\n\t\tsub.exclusiveMinimum as number | undefined,\n\t\tsup.exclusiveMinimum as number | undefined,\n\t\t\"exclusiveMinimum\",\n\t\tpath,\n\t\terrors,\n\t);\n\tcheckMaxConstraint(\n\t\tsub.exclusiveMaximum as number | undefined,\n\t\tsup.exclusiveMaximum as number | undefined,\n\t\t\"exclusiveMaximum\",\n\t\tpath,\n\t\terrors,\n\t);\n\n\tif (sup.multipleOf !== undefined) {\n\t\tif (sub.multipleOf === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"multipleOf\", sup.multipleOf),\n\t\t\t\treceived: fmtConstraint(\"multipleOf\", sub.multipleOf),\n\t\t\t});\n\t\t} else if (sub.multipleOf !== sup.multipleOf) {\n\t\t\t// sub.multipleOf must be a multiple of sup.multipleOf for sub ⊆ sup\n\t\t\tif (sub.multipleOf % sup.multipleOf !== 0) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: fmtConstraint(\"multipleOf\", sup.multipleOf),\n\t\t\t\t\treceived: fmtConstraint(\"multipleOf\", sub.multipleOf),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Compares string constraints between sub and sup.\n */\nfunction checkStringConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tcheckMinConstraint(sub.minLength, sup.minLength, \"minLength\", path, errors);\n\tcheckMaxConstraint(sub.maxLength, sup.maxLength, \"maxLength\", path, errors);\n\n\t// ── Pattern ──\n\tif (sup.pattern !== undefined) {\n\t\tif (sub.pattern === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"pattern\", sup.pattern),\n\t\t\t\treceived: \"no pattern constraint\",\n\t\t\t});\n\t\t} else if (sub.pattern !== sup.pattern) {\n\t\t\t// Different patterns — we can't statically determine subset relationship\n\t\t\t// without sampling, so report it as a potential mismatch.\n\t\t\t// The subset checker may have already stripped equivalent patterns,\n\t\t\t// so if we get here, they're genuinely different.\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"pattern\", sup.pattern),\n\t\t\t\treceived: fmtConstraint(\"pattern\", sub.pattern),\n\t\t\t});\n\t\t}\n\t}\n\n\t// ── Format ──\n\tif (sup.format !== undefined && sub.format !== sup.format) {\n\t\tif (sub.format === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"format\", sup.format),\n\t\t\t\treceived: \"no format constraint\",\n\t\t\t});\n\t\t} else {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"format\", sup.format),\n\t\t\t\treceived: fmtConstraint(\"format\", sub.format),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Compares object constraints (excluding properties/required) between sub and sup.\n */\nfunction checkObjectConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\t// ── additionalProperties ──\n\tif (sup.additionalProperties !== undefined) {\n\t\tif (sup.additionalProperties === false) {\n\t\t\t// sup forbids additional properties\n\t\t\tif (\n\t\t\t\tsub.additionalProperties === undefined ||\n\t\t\t\tsub.additionalProperties === true\n\t\t\t) {\n\t\t\t\t// sub allows them → incompatible\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: \"additionalProperties: false\",\n\t\t\t\t\treceived: \"additional properties allowed\",\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\ttypeof sub.additionalProperties === \"object\" &&\n\t\t\t\tsub.additionalProperties !== null\n\t\t\t) {\n\t\t\t\t// sub has a schema for additional properties → still allows them\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: \"additionalProperties: false\",\n\t\t\t\t\treceived: \"additionalProperties: schema\",\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (\n\t\t\ttypeof sup.additionalProperties === \"object\" &&\n\t\t\tsup.additionalProperties !== null\n\t\t) {\n\t\t\t// sup has a schema for additionalProperties\n\t\t\tif (\n\t\t\t\tsub.additionalProperties === undefined ||\n\t\t\t\tsub.additionalProperties === true\n\t\t\t) {\n\t\t\t\t// sub allows anything → more permissive\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: `additionalProperties: ${formatSchemaType(sup.additionalProperties as JSONSchema7Definition)}`,\n\t\t\t\t\treceived: \"additional properties allowed\",\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\ttypeof sub.additionalProperties === \"object\" &&\n\t\t\t\tsub.additionalProperties !== null\n\t\t\t) {\n\t\t\t\t// Both have schema-form additionalProperties — recurse\n\t\t\t\tconst apPath = path\n\t\t\t\t\t? `${path}.<additionalProperties>`\n\t\t\t\t\t: \"<additionalProperties>\";\n\t\t\t\tconst apErrors = computeSemanticErrors(\n\t\t\t\t\tsub.additionalProperties as JSONSchema7Definition,\n\t\t\t\t\tsup.additionalProperties as JSONSchema7Definition,\n\t\t\t\t\tapPath,\n\t\t\t\t);\n\t\t\t\terrors.push(...apErrors);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── minProperties / maxProperties ──\n\tcheckMinConstraint(\n\t\tsub.minProperties,\n\t\tsup.minProperties,\n\t\t\"minProperties\",\n\t\tpath,\n\t\terrors,\n\t);\n\tcheckMaxConstraint(\n\t\tsub.maxProperties,\n\t\tsup.maxProperties,\n\t\t\"maxProperties\",\n\t\tpath,\n\t\terrors,\n\t);\n\n\t// ── propertyNames ──\n\tif (sup.propertyNames !== undefined) {\n\t\tif (sub.propertyNames === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `propertyNames: ${formatSchemaType(sup.propertyNames)}`,\n\t\t\t\treceived: \"no propertyNames constraint\",\n\t\t\t});\n\t\t} else {\n\t\t\t// Both have propertyNames — recurse\n\t\t\tconst pnErrors = computeSemanticErrors(\n\t\t\t\tsub.propertyNames as JSONSchema7Definition,\n\t\t\t\tsup.propertyNames as JSONSchema7Definition,\n\t\t\t\tpath ? `${path}.<propertyNames>` : \"<propertyNames>\",\n\t\t\t);\n\t\t\terrors.push(...pnErrors);\n\t\t}\n\t}\n\n\t// ── dependencies ──\n\tif (isPlainObj(sup.dependencies)) {\n\t\tconst supDeps = sup.dependencies as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\t\tconst subDeps = isPlainObj(sub.dependencies)\n\t\t\t? (sub.dependencies as Record<string, JSONSchema7Definition | string[]>)\n\t\t\t: null;\n\n\t\tfor (const key of Object.keys(supDeps)) {\n\t\t\tconst supDep = supDeps[key];\n\t\t\tconst subDep = subDeps?.[key];\n\n\t\t\tif (subDep === undefined) {\n\t\t\t\t// sup requires a dependency that sub doesn't have\n\t\t\t\tif (Array.isArray(supDep)) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\t\texpected: `dependency: ${key} requires ${supDep.join(\", \")}`,\n\t\t\t\t\t\treceived: `no dependency for ${key}`,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\t\texpected: `dependency: ${key} requires schema`,\n\t\t\t\t\t\treceived: `no dependency for ${key}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (Array.isArray(supDep) && Array.isArray(subDep)) {\n\t\t\t\t// Both are array form — check if sub includes all required props from sup\n\t\t\t\tconst missing = supDep.filter((d) => !subDep.includes(d));\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\t\texpected: `dependency: ${key} requires ${supDep.join(\", \")}`,\n\t\t\t\t\t\treceived: `dependency: ${key} requires ${subDep.join(\", \")}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (!Array.isArray(supDep) && !Array.isArray(subDep)) {\n\t\t\t\t// Both are schema form — recurse\n\t\t\t\tconst depPath = path\n\t\t\t\t\t? `${path}.<dependency:${key}>`\n\t\t\t\t\t: `<dependency:${key}>`;\n\t\t\t\tconst depErrors = computeSemanticErrors(\n\t\t\t\t\tsubDep as JSONSchema7Definition,\n\t\t\t\t\tsupDep as JSONSchema7Definition,\n\t\t\t\t\tdepPath,\n\t\t\t\t);\n\t\t\t\terrors.push(...depErrors);\n\t\t\t} else {\n\t\t\t\t// Mixed forms (one array, one schema) — report mismatch\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: Array.isArray(supDep)\n\t\t\t\t\t\t? `dependency: ${key} requires ${supDep.join(\", \")}`\n\t\t\t\t\t\t: `dependency: ${key} requires schema`,\n\t\t\t\t\treceived: Array.isArray(subDep)\n\t\t\t\t\t\t? `dependency: ${key} requires ${subDep.join(\", \")}`\n\t\t\t\t\t\t: `dependency: ${key} requires schema`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── patternProperties ──\n\tif (isPlainObj(sup.patternProperties)) {\n\t\tconst supPP = sup.patternProperties as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition\n\t\t>;\n\t\tconst subPP = isPlainObj(sub.patternProperties)\n\t\t\t? (sub.patternProperties as Record<string, JSONSchema7Definition>)\n\t\t\t: null;\n\n\t\tfor (const pattern of Object.keys(supPP)) {\n\t\t\tconst supPropDef = supPP[pattern];\n\t\t\tif (supPropDef === undefined) continue;\n\n\t\t\tconst subPropDef = subPP?.[pattern];\n\t\t\tconst ppPath = path\n\t\t\t\t? `${path}.<patternProperties:${pattern}>`\n\t\t\t\t: `<patternProperties:${pattern}>`;\n\n\t\t\tif (subPropDef === undefined) {\n\t\t\t\t// sub doesn't constrain this pattern at all — more permissive\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: ppPath,\n\t\t\t\t\texpected: formatSchemaType(supPropDef),\n\t\t\t\t\treceived: \"no constraint for this pattern\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Both define the same pattern — recurse\n\t\t\t\tconst ppErrors = computeSemanticErrors(subPropDef, supPropDef, ppPath);\n\t\t\t\terrors.push(...ppErrors);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Compares array constraints (excluding items) between sub and sup.\n */\nfunction checkArrayConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tcheckMinConstraint(sub.minItems, sup.minItems, \"minItems\", path, errors);\n\tcheckMaxConstraint(sub.maxItems, sup.maxItems, \"maxItems\", path, errors);\n\n\t// ── uniqueItems ──\n\tif (sup.uniqueItems === true && sub.uniqueItems !== true) {\n\t\terrors.push({\n\t\t\tkey: path || \"$root\",\n\t\t\texpected: \"uniqueItems: true\",\n\t\t\treceived: fmtConstraint(\"uniqueItems\", sub.uniqueItems ?? false),\n\t\t});\n\t}\n\n\t// ── contains ──\n\tif (sup.contains !== undefined) {\n\t\tif (sub.contains === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `contains: ${formatSchemaType(sup.contains as JSONSchema7Definition)}`,\n\t\t\t\treceived: \"no contains constraint\",\n\t\t\t});\n\t\t} else {\n\t\t\t// Both have contains — recurse to compare the contained schemas\n\t\t\tconst containsPath = path ? `${path}.<contains>` : \"<contains>\";\n\t\t\tconst containsErrors = computeSemanticErrors(\n\t\t\t\tsub.contains as JSONSchema7Definition,\n\t\t\t\tsup.contains as JSONSchema7Definition,\n\t\t\t\tcontainsPath,\n\t\t\t);\n\t\t\terrors.push(...containsErrors);\n\t\t}\n\t}\n}\n\n/**\n * Detects whether a schema has a numeric type.\n */\nfunction isNumericType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"number\" || t === \"integer\";\n\treturn t.some((v) => v === \"number\" || v === \"integer\");\n}\n\n/**\n * Detects whether a schema has a string type.\n */\nfunction isStringType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"string\";\n\treturn t.includes(\"string\");\n}\n\n/**\n * Detects whether a schema has an object type.\n */\nfunction isObjectType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"object\";\n\treturn t.includes(\"object\");\n}\n\n/**\n * Detects whether a schema has an array type.\n */\nfunction isArrayType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"array\";\n\treturn t.includes(\"array\");\n}\n\n// ─── Keyword-based implicit type detection ───────────────────────────────────\n//\n// propertyNames schemas (e.g. { minLength: 1 }) don't always carry an explicit\n// `type`, yet their keywords unambiguously imply a type family. These helpers\n// let us trigger the right constraint checks even when `getEffectiveType`\n// returns `undefined`.\n\nfunction hasNumericKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minimum !== undefined ||\n\t\ts.maximum !== undefined ||\n\t\ts.exclusiveMinimum !== undefined ||\n\t\ts.exclusiveMaximum !== undefined ||\n\t\ts.multipleOf !== undefined\n\t);\n}\n\nfunction hasStringKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minLength !== undefined ||\n\t\ts.maxLength !== undefined ||\n\t\ts.pattern !== undefined ||\n\t\ts.format !== undefined\n\t);\n}\n\nfunction hasObjectKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minProperties !== undefined ||\n\t\ts.maxProperties !== undefined ||\n\t\ts.propertyNames !== undefined ||\n\t\ts.additionalProperties !== undefined ||\n\t\tisPlainObj(s.patternProperties) ||\n\t\tisPlainObj(s.dependencies)\n\t);\n}\n\nfunction hasArrayKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minItems !== undefined ||\n\t\ts.maxItems !== undefined ||\n\t\ts.uniqueItems !== undefined ||\n\t\ts.contains !== undefined\n\t);\n}\n\n// ─── Core Comparison ─────────────────────────────────────────────────────────\n\n/**\n * Compares two schemas and produces semantic errors.\n *\n * @param sub The source schema (what is produced / received)\n * @param sup The target schema (what is expected)\n * @param path The current normalized path\n * @returns List of semantic errors\n */\nexport function computeSemanticErrors(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tpath = \"\",\n): SchemaError[] {\n\t// ── Boolean schemas ──\n\tif (typeof sup === \"boolean\") {\n\t\tif (sup === false) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: \"never\",\n\t\t\t\t\treceived: formatSchemaType(sub),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn []; // sup = true accepts everything\n\t}\n\tif (typeof sub === \"boolean\") {\n\t\tif (sub === true) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatSchemaType(sup),\n\t\t\t\t\treceived: \"any\",\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn []; // sub = false produces nothing, trivially subset\n\t}\n\n\tconst subSchema = sub as JSONSchema7;\n\tconst supSchema = sup as JSONSchema7;\n\n\tconst errors: SchemaError[] = [];\n\n\t// ── Handle `not` keyword ──\n\t// Check sup.not: sub must not satisfy the not-schema for sub ⊆ sup.\n\t// Check sub.not: if sub has a not that sup doesn't, sub is more constrained (OK).\n\t// if sup has a not that sub doesn't, sub may be too permissive.\n\tif (\n\t\thasOwn(supSchema, \"not\") &&\n\t\tisPlainObj(supSchema.not) &&\n\t\ttypeof supSchema.not !== \"boolean\"\n\t) {\n\t\tconst notSchema = supSchema.not as JSONSchema7;\n\t\tconst notFormatted = formatSchemaType(notSchema);\n\n\t\tif (!hasOwn(subSchema, \"not\")) {\n\t\t\t// sup excludes something, sub doesn't → sub is more permissive\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `not ${notFormatted}`,\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t} else if (\n\t\t\tisPlainObj(subSchema.not) &&\n\t\t\ttypeof subSchema.not !== \"boolean\"\n\t\t) {\n\t\t\t// Both have not — compare the not schemas\n\t\t\t// For sub ⊆ sup, sub.not must be at least as broad as sup.not\n\t\t\t// (i.e. sub excludes at least as much). We report if they differ.\n\t\t\tconst subNotSchema = subSchema.not as JSONSchema7;\n\t\t\tif (!deepEqual(subNotSchema, notSchema)) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: `not ${notFormatted}`,\n\t\t\t\t\treceived: `not ${formatSchemaType(subNotSchema)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Get effective types ──\n\tconst subType = getEffectiveType(subSchema);\n\tconst supType = getEffectiveType(supSchema);\n\n\t// ── Handle anyOf/oneOf in sup ──\n\t// If sup has branches, try to find the best matching one for error reporting\n\tconst supBranches = supSchema.anyOf ?? supSchema.oneOf;\n\tif (Array.isArray(supBranches) && supBranches.length > 0 && !supSchema.type) {\n\t\treturn computeErrorsAgainstBranches(subSchema, supBranches, path);\n\t}\n\n\t// ── Handle anyOf/oneOf in sub ──\n\tconst subBranches = subSchema.anyOf ?? subSchema.oneOf;\n\tif (Array.isArray(subBranches) && subBranches.length > 0 && !subSchema.type) {\n\t\tconst branchErrors: SchemaError[] = [];\n\t\tfor (const branch of subBranches) {\n\t\t\tconst errs = computeSemanticErrors(branch, sup, path);\n\t\t\tbranchErrors.push(...errs);\n\t\t}\n\t\treturn branchErrors;\n\t}\n\n\t// ── Both are object types → compare properties + object constraints ──\n\tconst supProps = getProperties(supSchema);\n\tconst subProps = getProperties(subSchema);\n\n\tif (supProps !== null || isObjectType(supType)) {\n\t\t// sup is an object schema\n\t\tif (subType !== undefined && !typeIncludes(subType, \"object\")) {\n\t\t\t// sub is not an object at all\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t\treturn errors;\n\t\t}\n\n\t\tif (supProps !== null) {\n\t\t\tconst supRequired = getRequired(supSchema);\n\t\t\tconst subRequired = getRequired(subSchema);\n\n\t\t\tfor (const key of Object.keys(supProps)) {\n\t\t\t\tconst propPath = joinPath(path, key);\n\t\t\t\tconst supPropDef = supProps[key];\n\t\t\t\tconst subPropDef = subProps?.[key];\n\n\t\t\t\tif (supPropDef === undefined) continue;\n\n\t\t\t\tconst isRequiredInSup = supRequired.includes(key);\n\n\t\t\t\t// ── Missing property (required in sup, absent in sub) ──\n\t\t\t\tif (subPropDef === undefined) {\n\t\t\t\t\tif (isRequiredInSup) {\n\t\t\t\t\t\terrors.push({\n\t\t\t\t\t\t\tkey: propPath,\n\t\t\t\t\t\t\texpected: formatSchemaType(supPropDef),\n\t\t\t\t\t\t\treceived: \"undefined\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// ── Optionality mismatch (required in sup, optional in sub) ──\n\t\t\t\tif (isRequiredInSup && !subRequired.includes(key)) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: propPath,\n\t\t\t\t\t\texpected: \"not optional\",\n\t\t\t\t\t\treceived: \"optional\",\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// ── Recurse into the property schemas ──\n\t\t\t\tconst propErrors = comparePropertySchemas(\n\t\t\t\t\tsubPropDef,\n\t\t\t\t\tsupPropDef,\n\t\t\t\t\tpropPath,\n\t\t\t\t);\n\t\t\t\terrors.push(...propErrors);\n\t\t\t}\n\t\t}\n\n\t\t// ── Custom constraints ──\n\t\tcheckCustomConstraints(subSchema, supSchema, path, errors);\n\n\t\t// ── Object-level constraints ──\n\t\tcheckObjectConstraints(subSchema, supSchema, path, errors);\n\n\t\treturn errors;\n\t}\n\n\t// ── Both are array types → compare items + array constraints ──\n\tif (\n\t\t(supType === \"array\" || supSchema.items !== undefined) &&\n\t\t(subType === \"array\" || subSchema.items !== undefined)\n\t) {\n\t\t// Check items compatibility\n\t\tif (supSchema.items !== undefined && typeof supSchema.items !== \"boolean\") {\n\t\t\tif (\n\t\t\t\tsubSchema.items !== undefined &&\n\t\t\t\ttypeof subSchema.items !== \"boolean\"\n\t\t\t) {\n\t\t\t\t// Both have items schemas — recurse\n\t\t\t\tif (Array.isArray(supSchema.items) && Array.isArray(subSchema.items)) {\n\t\t\t\t\t// Tuple comparison\n\t\t\t\t\tconst maxLen = Math.max(\n\t\t\t\t\t\tsupSchema.items.length,\n\t\t\t\t\t\tsubSchema.items.length,\n\t\t\t\t\t);\n\t\t\t\t\tfor (let i = 0; i < maxLen; i++) {\n\t\t\t\t\t\tconst supItem = supSchema.items[i];\n\t\t\t\t\t\tconst subItem = subSchema.items[i];\n\t\t\t\t\t\tconst itemPath = joinPath(path, `[${i}]`);\n\t\t\t\t\t\tif (supItem !== undefined && subItem === undefined) {\n\t\t\t\t\t\t\terrors.push({\n\t\t\t\t\t\t\t\tkey: itemPath,\n\t\t\t\t\t\t\t\texpected: formatSchemaType(supItem),\n\t\t\t\t\t\t\t\treceived: \"undefined\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (supItem !== undefined && subItem !== undefined) {\n\t\t\t\t\t\t\terrors.push(...computeSemanticErrors(subItem, supItem, itemPath));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (\n\t\t\t\t\t!Array.isArray(supSchema.items) &&\n\t\t\t\t\t!Array.isArray(subSchema.items)\n\t\t\t\t) {\n\t\t\t\t\t// Single items schema — recurse with [] path\n\t\t\t\t\tconst itemPath = arrayPath(path);\n\t\t\t\t\tconst itemErrors = computeSemanticErrors(\n\t\t\t\t\t\tsubSchema.items as JSONSchema7Definition,\n\t\t\t\t\t\tsupSchema.items as JSONSchema7Definition,\n\t\t\t\t\t\titemPath,\n\t\t\t\t\t);\n\t\t\t\t\terrors.push(...itemErrors);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// sup has items schema but sub doesn't\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// ── Custom constraints ──\n\t\tcheckCustomConstraints(subSchema, supSchema, path, errors);\n\n\t\t// ── Array-level constraints ──\n\t\tcheckArrayConstraints(subSchema, supSchema, path, errors);\n\n\t\treturn errors;\n\t}\n\n\t// ── Type mismatch at current level ──\n\tif (subType !== undefined && supType !== undefined) {\n\t\tif (!typesAreCompatible(subType, supType)) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t\treturn errors;\n\t\t}\n\t}\n\n\t// ── Enum comparison ──\n\tif (Array.isArray(supSchema.enum)) {\n\t\tif (Array.isArray(subSchema.enum)) {\n\t\t\t// Both have enums — check if sub.enum ⊆ sup.enum\n\t\t\tconst subExtra = subSchema.enum.filter(\n\t\t\t\t(v) => !supSchema.enum?.some((sv) => deepEqual(v, sv)),\n\t\t\t);\n\t\t\tif (subExtra.length > 0) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\treceived: formatEnumValues(subSchema.enum),\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (hasOwn(subSchema, \"const\")) {\n\t\t\t// sub has const, sup has enum — check inclusion\n\t\t\tconst constInEnum = supSchema.enum.some((v) =>\n\t\t\t\tdeepEqual(v, subSchema.const),\n\t\t\t);\n\t\t\tif (!constInEnum) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// sup has enum but sub is a plain type (no enum restriction)\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t}\n\t\treturn errors;\n\t}\n\n\t// ── Const comparison ──\n\tif (hasOwn(supSchema, \"const\") && hasOwn(subSchema, \"const\")) {\n\t\tif (!deepEqual(supSchema.const, subSchema.const)) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t}\n\t\treturn errors;\n\t}\n\n\t// ── Same-type constraint comparison ──\n\t// Types are compatible (or unspecified), now check individual keywords.\n\n\t// ── Custom constraints (applies to all types) ──\n\tcheckCustomConstraints(subSchema, supSchema, path, errors);\n\n\tif (\n\t\tisNumericType(subType) ||\n\t\tisNumericType(supType) ||\n\t\thasNumericKeywords(supSchema) ||\n\t\thasNumericKeywords(subSchema)\n\t) {\n\t\tcheckNumericConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\tif (\n\t\tisStringType(subType) ||\n\t\tisStringType(supType) ||\n\t\thasStringKeywords(supSchema) ||\n\t\thasStringKeywords(subSchema)\n\t) {\n\t\tcheckStringConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\t// Object-level constraints when sup doesn't have explicit properties\n\t// but still has object constraints (e.g., just { type: \"object\", minProperties: 3 })\n\tif (\n\t\tisObjectType(subType) ||\n\t\tisObjectType(supType) ||\n\t\thasObjectKeywords(supSchema) ||\n\t\thasObjectKeywords(subSchema)\n\t) {\n\t\tcheckObjectConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\t// Array-level constraints when sup doesn't have explicit items\n\t// but still has array constraints (e.g., just { type: \"array\", minItems: 2 })\n\tif (\n\t\tisArrayType(subType) ||\n\t\tisArrayType(supType) ||\n\t\thasArrayKeywords(supSchema) ||\n\t\thasArrayKeywords(subSchema)\n\t) {\n\t\tcheckArrayConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\tif (errors.length > 0) {\n\t\treturn errors;\n\t}\n\n\t// ── Fallback: generic incompatibility ──\n\t// If we get here, there's an incompatibility we couldn't pinpoint precisely.\n\t// Produce a root-level error with the formatted types.\n\tconst expectedStr = formatSchemaType(supSchema);\n\tconst receivedStr = formatSchemaType(subSchema);\n\tif (expectedStr !== receivedStr) {\n\t\terrors.push({\n\t\t\tkey: path || \"$root\",\n\t\t\texpected: expectedStr,\n\t\t\treceived: receivedStr,\n\t\t});\n\t}\n\n\treturn errors;\n}\n\n// ─── Property Schema Comparison ──────────────────────────────────────────────\n\n/**\n * Compares two property schemas and produces errors.\n * Handles recursion into nested objects and arrays.\n */\nfunction comparePropertySchemas(\n\tsubDef: JSONSchema7Definition,\n\tsupDef: JSONSchema7Definition,\n\tpath: string,\n): SchemaError[] {\n\tif (typeof subDef === \"boolean\" || typeof supDef === \"boolean\") {\n\t\tif (subDef !== supDef) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path,\n\t\t\t\t\texpected: formatSchemaType(supDef),\n\t\t\t\t\treceived: formatSchemaType(subDef),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t}\n\n\tconst subSchema = subDef as JSONSchema7;\n\tconst supSchema = supDef as JSONSchema7;\n\n\tconst subType = getEffectiveType(subSchema);\n\tconst supType = getEffectiveType(supSchema);\n\n\t// ── Enum comparison (before type check, as enums can cross types) ──\n\tif (Array.isArray(supSchema.enum)) {\n\t\tif (Array.isArray(subSchema.enum)) {\n\t\t\tconst subExtra = subSchema.enum.filter(\n\t\t\t\t(v) => !supSchema.enum?.some((sv) => deepEqual(v, sv)),\n\t\t\t);\n\t\t\tif (subExtra.length > 0) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: path,\n\t\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\t\treceived: formatEnumValues(subSchema.enum),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\tif (hasOwn(subSchema, \"const\")) {\n\t\t\tconst constInEnum = supSchema.enum.some((v) =>\n\t\t\t\tdeepEqual(v, subSchema.const),\n\t\t\t);\n\t\t\tif (!constInEnum) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: path,\n\t\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\t// sup has enum, sub is a plain type\n\t\treturn [\n\t\t\t{\n\t\t\t\tkey: path,\n\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t},\n\t\t];\n\t}\n\n\t// ── Const comparison ──\n\tif (hasOwn(supSchema, \"const\") && hasOwn(subSchema, \"const\")) {\n\t\tif (!deepEqual(supSchema.const, subSchema.const)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path,\n\t\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t}\n\n\t// ── Type mismatch ──\n\tif (subType !== undefined && supType !== undefined) {\n\t\tif (!typesAreCompatible(subType, supType)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path,\n\t\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t}\n\n\t// ── If same types, recurse deeper ──\n\treturn computeSemanticErrors(subDef, supDef, path);\n}\n\n// ─── Branch Error Computation ────────────────────────────────────────────────\n\n/**\n * When sup has branches (anyOf/oneOf), attempts to find the closest\n * matching branch and generates errors against it.\n *\n * Strategy: compute errors for each branch and return those from the\n * branch with the fewest errors (best match).\n */\nfunction computeErrorsAgainstBranches(\n\tsub: JSONSchema7,\n\tbranches: JSONSchema7Definition[],\n\tpath: string,\n): SchemaError[] {\n\tlet bestErrors: SchemaError[] | null = null;\n\n\tfor (const branch of branches) {\n\t\tconst errors = computeSemanticErrors(sub, branch, path);\n\t\tif (errors.length === 0) return [];\n\t\tif (bestErrors === null || errors.length < bestErrors.length) {\n\t\t\tbestErrors = errors;\n\t\t}\n\t}\n\n\treturn (\n\t\tbestErrors ?? [\n\t\t\t{\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType({ anyOf: branches } as JSONSchema7),\n\t\t\t\treceived: formatSchemaType(sub),\n\t\t\t},\n\t\t]\n\t);\n}\n"],"names":["deepEqual","hasOwn","isPlainObj","formatEnumValues","values","parts","map","v","JSON","stringify","length","last","pop","join","formatSchemaType","def","base","formatSchemaTypeInternal","undefined","formatConstraintsSuffix","schema","constraints","arr","Array","isArray","formatCustomConstraint","const","enum","branches","anyOf","oneOf","b","type","items","itemSchema","itemBranches","t","itemType","properties","not","joinPath","parent","key","arrayPath","getProperties","getRequired","required","getEffectiveType","typeIncludes","schemaType","target","includes","typesAreCompatible","subType","supType","some","every","st","supt","c","params","Object","keys","name","formatCustomConstraintList","cs","checkCustomConstraints","sub","sup","path","errors","supConstraints","subConstraints","supArr","subArr","supC","found","subC","push","expected","received","fmtConstraint","value","checkMinConstraint","subVal","supVal","checkMaxConstraint","checkNumericConstraints","minimum","maximum","exclusiveMinimum","exclusiveMaximum","multipleOf","checkStringConstraints","minLength","maxLength","pattern","format","checkObjectConstraints","additionalProperties","apPath","apErrors","computeSemanticErrors","minProperties","maxProperties","propertyNames","pnErrors","dependencies","supDeps","subDeps","supDep","subDep","missing","filter","d","depPath","depErrors","patternProperties","supPP","subPP","supPropDef","subPropDef","ppPath","ppErrors","checkArrayConstraints","minItems","maxItems","uniqueItems","contains","containsPath","containsErrors","isNumericType","isStringType","isObjectType","isArrayType","hasNumericKeywords","s","hasStringKeywords","hasObjectKeywords","hasArrayKeywords","subSchema","supSchema","notSchema","notFormatted","subNotSchema","supBranches","computeErrorsAgainstBranches","subBranches","branchErrors","branch","errs","supProps","subProps","supRequired","subRequired","propPath","isRequiredInSup","propErrors","comparePropertySchemas","maxLen","Math","max","i","supItem","subItem","itemPath","itemErrors","subExtra","sv","constInEnum","expectedStr","receivedStr","subDef","supDef","bestErrors"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/semantic-errors.ts"],"sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport type { SchemaError } from \"./types.ts\";\nimport { deepEqual, hasOwn, isPlainObj } from \"./utils.ts\";\n\n// ─── Semantic Error Generator ────────────────────────────────────────────────\n//\n// Generates human-readable semantic errors by directly comparing two schemas.\n//\n// Unlike a structural differ (which would compare sub vs merged), this module\n// directly compares sub (source/received) and sup (target/expected) to produce\n// business-oriented error messages.\n//\n// Property paths are normalized:\n// - `accountId` (top-level property)\n// - `user.name` (nested property)\n// - `users[].name` (property inside array items)\n//\n// Convention:\n// - `expected` = what the target schema (sup) expects\n// - `received` = what the source schema (sub) provides\n\n// ─── Type Formatting ─────────────────────────────────────────────────────────\n\n/**\n * Formats enum values into a readable string.\n *\n * Examples:\n * - 1 value : `\"123\"`\n * - 2 values : `\"123 or hello\"`\n * - 3 values : `\"10, 20, or 30\"`\n */\nfunction formatEnumValues(values: unknown[]): string {\n\tconst parts = values.map((v) =>\n\t\ttypeof v === \"string\" ? v : JSON.stringify(v),\n\t);\n\tif (parts.length === 0) return \"never\";\n\tif (parts.length === 1) return parts[0] as string;\n\tif (parts.length === 2) return `${parts[0]} or ${parts[1]}`;\n\tconst last = parts.pop();\n\treturn `${parts.join(\", \")}, or ${last}`;\n}\n\n/**\n * Formats a schema into a readable type representation.\n *\n * Examples:\n * - `{ type: \"string\" }` → `\"string\"`\n * - `{ type: \"array\", items: { type: \"string\" } }` → `\"string[]\"`\n * - `{ type: \"array\", items: { type: [\"string\",\"number\"] }` → `\"string[] | number[]\"`\n * - `{ enum: [1, 2, 3] }` → `\"1, 2, or 3\"`\n * - `{ const: \"hello\" }` → `\"hello\"`\n * - `{ anyOf: [{type:\"string\"},{type:\"number\"}] }` → `\"string | number\"`\n * - `undefined` → `\"undefined\"`\n */\nexport function formatSchemaType(\n\tdef: JSONSchema7Definition | undefined,\n): string {\n\treturn formatSchemaTypeInternal(def);\n}\n\nfunction formatSchemaTypeInternal(\n\tdef: JSONSchema7Definition | undefined,\n): string {\n\tif (def === undefined) return \"undefined\";\n\tif (typeof def === \"boolean\") return def ? \"any\" : \"never\";\n\n\tconst schema = def as JSONSchema7;\n\n\t// ── Const ──\n\tif (hasOwn(schema, \"const\")) {\n\t\tconst v = schema.const;\n\t\treturn typeof v === \"string\" ? v : JSON.stringify(v);\n\t}\n\n\t// ── Enum ──\n\tif (Array.isArray(schema.enum)) {\n\t\treturn formatEnumValues(schema.enum);\n\t}\n\n\t// ── anyOf / oneOf (union types) ──\n\tconst branches = schema.anyOf ?? schema.oneOf;\n\tif (Array.isArray(branches) && branches.length > 0) {\n\t\tconst parts = branches.map((b) => formatSchemaType(b));\n\t\treturn parts.join(\" | \");\n\t}\n\n\t// ── Array type ──\n\tif (schema.type === \"array\") {\n\t\tif (schema.items !== undefined && typeof schema.items !== \"boolean\") {\n\t\t\tconst itemSchema = schema.items as JSONSchema7;\n\n\t\t\t// Items with anyOf/oneOf → \"string[] | number[]\"\n\t\t\tconst itemBranches = itemSchema.anyOf ?? itemSchema.oneOf;\n\t\t\tif (Array.isArray(itemBranches) && itemBranches.length > 0) {\n\t\t\t\tconst parts = itemBranches.map((b) => `${formatSchemaType(b)}[]`);\n\t\t\t\treturn parts.join(\" | \");\n\t\t\t}\n\n\t\t\t// Items with multiple types → \"string[] | number[]\"\n\t\t\tif (Array.isArray(itemSchema.type)) {\n\t\t\t\tconst parts = itemSchema.type.map((t) => `${t}[]`);\n\t\t\t\treturn parts.join(\" | \");\n\t\t\t}\n\n\t\t\tconst itemType = formatSchemaType(itemSchema);\n\t\t\treturn `${itemType}[]`;\n\t\t}\n\t\t// items is boolean true or missing\n\t\treturn \"array\";\n\t}\n\n\t// ── Simple type ──\n\tif (typeof schema.type === \"string\") {\n\t\treturn schema.type;\n\t}\n\n\t// ── Multiple types (type: [\"string\", \"number\"]) ──\n\tif (Array.isArray(schema.type)) {\n\t\treturn schema.type.join(\" | \");\n\t}\n\n\t// ── not (pure-not schema, no other significant keywords) ──\n\tif (\n\t\thasOwn(schema, \"not\") &&\n\t\t!schema.type &&\n\t\t!isPlainObj(schema.properties) &&\n\t\tschema.items === undefined &&\n\t\t!Array.isArray(schema.enum) &&\n\t\t!hasOwn(schema, \"const\")\n\t) {\n\t\treturn `not ${formatSchemaType(schema.not as JSONSchema7Definition)}`;\n\t}\n\n\t// ── Fallback ──\n\t// Schema without explicit type — try to infer from structure\n\tif (isPlainObj(schema.properties)) return \"object\";\n\tif (schema.items !== undefined) return \"array\";\n\n\treturn \"unknown\";\n}\n\n// ─── Path Helpers ────────────────────────────────────────────────────────────\n\n/**\n * Builds a normalized property path.\n * - Root + key → `\"accountId\"`\n * - Parent + key → `\"user.name\"`\n * - Parent[] + key → `\"users[].name\"`\n */\nfunction joinPath(parent: string, key: string): string {\n\tif (!parent) return key;\n\treturn `${parent}.${key}`;\n}\n\n/**\n * Appends the `[]` suffix to indicate entering array items.\n */\nfunction arrayPath(parent: string): string {\n\tif (!parent) return \"[]\";\n\treturn `${parent}[]`;\n}\n\n// ─── Schema Accessors ────────────────────────────────────────────────────────\n\n/**\n * Safely extracts the properties from a schema.\n */\nfunction getProperties(\n\tschema: JSONSchema7,\n): Record<string, JSONSchema7Definition> | null {\n\tif (isPlainObj(schema.properties)) {\n\t\treturn schema.properties as Record<string, JSONSchema7Definition>;\n\t}\n\treturn null;\n}\n\n/**\n * Safely extracts the required fields from a schema.\n */\nfunction getRequired(schema: JSONSchema7): string[] {\n\tif (Array.isArray(schema.required)) {\n\t\treturn schema.required as string[];\n\t}\n\treturn [];\n}\n\n/**\n * Determines the effective type of a schema (string or array of types).\n */\nfunction getEffectiveType(schema: JSONSchema7): string | string[] | undefined {\n\tif (schema.type !== undefined) return schema.type as string | string[];\n\n\t// Infer from const\n\tif (hasOwn(schema, \"const\")) {\n\t\tconst v = schema.const;\n\t\tif (v === null) return \"null\";\n\t\tif (Array.isArray(v)) return \"array\";\n\t\treturn typeof v;\n\t}\n\n\t// Infer from properties\n\tif (isPlainObj(schema.properties)) return \"object\";\n\n\t// Infer from items\n\tif (schema.items !== undefined) return \"array\";\n\n\treturn undefined;\n}\n\n/**\n * Checks whether a type (string) is included in a type or array of types.\n */\nfunction typeIncludes(\n\tschemaType: string | string[] | undefined,\n\ttarget: string,\n): boolean {\n\tif (schemaType === undefined) return false;\n\tif (typeof schemaType === \"string\") {\n\t\t// integer is a subset of number\n\t\tif (target === \"number\" && schemaType === \"integer\") return true;\n\t\tif (target === \"integer\" && schemaType === \"number\") return true;\n\t\treturn schemaType === target;\n\t}\n\treturn schemaType.includes(target);\n}\n\n/**\n * Checks whether two types are compatible.\n * A type is compatible if the sub type is included in the sup type.\n */\nfunction typesAreCompatible(\n\tsubType: string | string[] | undefined,\n\tsupType: string | string[] | undefined,\n): boolean {\n\tif (supType === undefined) return true; // sup accepts anything\n\tif (subType === undefined) return true; // sub is undetermined, cannot conclude\n\n\tif (typeof subType === \"string\" && typeof supType === \"string\") {\n\t\tif (subType === supType) return true;\n\t\t// integer ⊆ number\n\t\tif (subType === \"integer\" && supType === \"number\") return true;\n\t\treturn false;\n\t}\n\n\tif (typeof subType === \"string\" && Array.isArray(supType)) {\n\t\treturn supType.some(\n\t\t\t(t) => t === subType || (subType === \"integer\" && t === \"number\"),\n\t\t);\n\t}\n\n\tif (Array.isArray(subType) && typeof supType === \"string\") {\n\t\treturn subType.every(\n\t\t\t(t) => t === supType || (t === \"integer\" && supType === \"number\"),\n\t\t);\n\t}\n\n\tif (Array.isArray(subType) && Array.isArray(supType)) {\n\t\treturn subType.every((st) =>\n\t\t\tsupType.some(\n\t\t\t\t(supt) => supt === st || (st === \"integer\" && supt === \"number\"),\n\t\t\t),\n\t\t);\n\t}\n\n\treturn true;\n}\n\n// ─── Constraint Helpers ──────────────────────────────────────────────────────\n\n/**\n * Formats a constraint value into a readable string.\n */\nfunction fmtConstraint(name: string, value: unknown): string {\n\tif (value === undefined) return `${name}: not set`;\n\tif (typeof value === \"boolean\") return `${name}: ${value}`;\n\tif (typeof value === \"number\" || typeof value === \"string\")\n\t\treturn `${name}: ${value}`;\n\treturn `${name}: ${JSON.stringify(value)}`;\n}\n\n/**\n * Compares a \"minimum-like\" numeric constraint (sub.X must be >= sup.X for sub ⊆ sup).\n * Examples: minimum, exclusiveMinimum, minLength, minItems, minProperties\n */\nfunction checkMinConstraint(\n\tsubVal: number | undefined,\n\tsupVal: number | undefined,\n\tname: string,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tif (supVal !== undefined) {\n\t\tif (subVal === undefined || subVal < supVal) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(name, supVal),\n\t\t\t\treceived: fmtConstraint(name, subVal),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Compares a \"maximum-like\" numeric constraint (sub.X must be <= sup.X for sub ⊆ sup).\n * Examples: maximum, exclusiveMaximum, maxLength, maxItems, maxProperties\n */\nfunction checkMaxConstraint(\n\tsubVal: number | undefined,\n\tsupVal: number | undefined,\n\tname: string,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tif (supVal !== undefined) {\n\t\tif (subVal === undefined || subVal > supVal) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(name, supVal),\n\t\t\t\treceived: fmtConstraint(name, subVal),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Compares numeric constraints between sub and sup.\n */\nfunction checkNumericConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tcheckMinConstraint(sub.minimum, sup.minimum, \"minimum\", path, errors);\n\tcheckMaxConstraint(sub.maximum, sup.maximum, \"maximum\", path, errors);\n\tcheckMinConstraint(\n\t\tsub.exclusiveMinimum as number | undefined,\n\t\tsup.exclusiveMinimum as number | undefined,\n\t\t\"exclusiveMinimum\",\n\t\tpath,\n\t\terrors,\n\t);\n\tcheckMaxConstraint(\n\t\tsub.exclusiveMaximum as number | undefined,\n\t\tsup.exclusiveMaximum as number | undefined,\n\t\t\"exclusiveMaximum\",\n\t\tpath,\n\t\terrors,\n\t);\n\n\tif (sup.multipleOf !== undefined) {\n\t\tif (sub.multipleOf === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"multipleOf\", sup.multipleOf),\n\t\t\t\treceived: fmtConstraint(\"multipleOf\", sub.multipleOf),\n\t\t\t});\n\t\t} else if (sub.multipleOf !== sup.multipleOf) {\n\t\t\t// sub.multipleOf must be a multiple of sup.multipleOf for sub ⊆ sup\n\t\t\tif (sub.multipleOf % sup.multipleOf !== 0) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: fmtConstraint(\"multipleOf\", sup.multipleOf),\n\t\t\t\t\treceived: fmtConstraint(\"multipleOf\", sub.multipleOf),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Compares string constraints between sub and sup.\n */\nfunction checkStringConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tcheckMinConstraint(sub.minLength, sup.minLength, \"minLength\", path, errors);\n\tcheckMaxConstraint(sub.maxLength, sup.maxLength, \"maxLength\", path, errors);\n\n\t// ── Pattern ──\n\tif (sup.pattern !== undefined) {\n\t\tif (sub.pattern === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"pattern\", sup.pattern),\n\t\t\t\treceived: \"no pattern constraint\",\n\t\t\t});\n\t\t} else if (sub.pattern !== sup.pattern) {\n\t\t\t// Different patterns — we can't statically determine subset relationship\n\t\t\t// without sampling, so report it as a potential mismatch.\n\t\t\t// The subset checker may have already stripped equivalent patterns,\n\t\t\t// so if we get here, they're genuinely different.\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"pattern\", sup.pattern),\n\t\t\t\treceived: fmtConstraint(\"pattern\", sub.pattern),\n\t\t\t});\n\t\t}\n\t}\n\n\t// ── Format ──\n\tif (sup.format !== undefined && sub.format !== sup.format) {\n\t\tif (sub.format === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"format\", sup.format),\n\t\t\t\treceived: \"no format constraint\",\n\t\t\t});\n\t\t} else {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: fmtConstraint(\"format\", sup.format),\n\t\t\t\treceived: fmtConstraint(\"format\", sub.format),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Compares object constraints (excluding properties/required) between sub and sup.\n */\nfunction checkObjectConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\t// ── additionalProperties ──\n\tif (sup.additionalProperties !== undefined) {\n\t\tif (sup.additionalProperties === false) {\n\t\t\t// sup forbids additional properties\n\t\t\tif (\n\t\t\t\tsub.additionalProperties === undefined ||\n\t\t\t\tsub.additionalProperties === true\n\t\t\t) {\n\t\t\t\t// sub allows them → incompatible\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: \"additionalProperties: false\",\n\t\t\t\t\treceived: \"additional properties allowed\",\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\ttypeof sub.additionalProperties === \"object\" &&\n\t\t\t\tsub.additionalProperties !== null\n\t\t\t) {\n\t\t\t\t// sub has a schema for additional properties → still allows them\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: \"additionalProperties: false\",\n\t\t\t\t\treceived: \"additionalProperties: schema\",\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (\n\t\t\ttypeof sup.additionalProperties === \"object\" &&\n\t\t\tsup.additionalProperties !== null\n\t\t) {\n\t\t\t// sup has a schema for additionalProperties\n\t\t\tif (\n\t\t\t\tsub.additionalProperties === undefined ||\n\t\t\t\tsub.additionalProperties === true\n\t\t\t) {\n\t\t\t\t// sub allows anything → more permissive\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: `additionalProperties: ${formatSchemaType(sup.additionalProperties as JSONSchema7Definition)}`,\n\t\t\t\t\treceived: \"additional properties allowed\",\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\ttypeof sub.additionalProperties === \"object\" &&\n\t\t\t\tsub.additionalProperties !== null\n\t\t\t) {\n\t\t\t\t// Both have schema-form additionalProperties — recurse\n\t\t\t\tconst apPath = path\n\t\t\t\t\t? `${path}.<additionalProperties>`\n\t\t\t\t\t: \"<additionalProperties>\";\n\t\t\t\tconst apErrors = computeSemanticErrors(\n\t\t\t\t\tsub.additionalProperties as JSONSchema7Definition,\n\t\t\t\t\tsup.additionalProperties as JSONSchema7Definition,\n\t\t\t\t\tapPath,\n\t\t\t\t);\n\t\t\t\terrors.push(...apErrors);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── minProperties / maxProperties ──\n\tcheckMinConstraint(\n\t\tsub.minProperties,\n\t\tsup.minProperties,\n\t\t\"minProperties\",\n\t\tpath,\n\t\terrors,\n\t);\n\tcheckMaxConstraint(\n\t\tsub.maxProperties,\n\t\tsup.maxProperties,\n\t\t\"maxProperties\",\n\t\tpath,\n\t\terrors,\n\t);\n\n\t// ── propertyNames ──\n\tif (sup.propertyNames !== undefined) {\n\t\tif (sub.propertyNames === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `propertyNames: ${formatSchemaType(sup.propertyNames)}`,\n\t\t\t\treceived: \"no propertyNames constraint\",\n\t\t\t});\n\t\t} else {\n\t\t\t// Both have propertyNames — recurse\n\t\t\tconst pnErrors = computeSemanticErrors(\n\t\t\t\tsub.propertyNames as JSONSchema7Definition,\n\t\t\t\tsup.propertyNames as JSONSchema7Definition,\n\t\t\t\tpath ? `${path}.<propertyNames>` : \"<propertyNames>\",\n\t\t\t);\n\t\t\terrors.push(...pnErrors);\n\t\t}\n\t}\n\n\t// ── dependencies ──\n\tif (isPlainObj(sup.dependencies)) {\n\t\tconst supDeps = sup.dependencies as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\t\tconst subDeps = isPlainObj(sub.dependencies)\n\t\t\t? (sub.dependencies as Record<string, JSONSchema7Definition | string[]>)\n\t\t\t: null;\n\n\t\tfor (const key of Object.keys(supDeps)) {\n\t\t\tconst supDep = supDeps[key];\n\t\t\tconst subDep = subDeps?.[key];\n\n\t\t\tif (subDep === undefined) {\n\t\t\t\t// sup requires a dependency that sub doesn't have\n\t\t\t\tif (Array.isArray(supDep)) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\t\texpected: `dependency: ${key} requires ${supDep.join(\", \")}`,\n\t\t\t\t\t\treceived: `no dependency for ${key}`,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\t\texpected: `dependency: ${key} requires schema`,\n\t\t\t\t\t\treceived: `no dependency for ${key}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (Array.isArray(supDep) && Array.isArray(subDep)) {\n\t\t\t\t// Both are array form — check if sub includes all required props from sup\n\t\t\t\tconst missing = supDep.filter((d) => !subDep.includes(d));\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\t\texpected: `dependency: ${key} requires ${supDep.join(\", \")}`,\n\t\t\t\t\t\treceived: `dependency: ${key} requires ${subDep.join(\", \")}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (!Array.isArray(supDep) && !Array.isArray(subDep)) {\n\t\t\t\t// Both are schema form — recurse\n\t\t\t\tconst depPath = path\n\t\t\t\t\t? `${path}.<dependency:${key}>`\n\t\t\t\t\t: `<dependency:${key}>`;\n\t\t\t\tconst depErrors = computeSemanticErrors(\n\t\t\t\t\tsubDep as JSONSchema7Definition,\n\t\t\t\t\tsupDep as JSONSchema7Definition,\n\t\t\t\t\tdepPath,\n\t\t\t\t);\n\t\t\t\terrors.push(...depErrors);\n\t\t\t} else {\n\t\t\t\t// Mixed forms (one array, one schema) — report mismatch\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: Array.isArray(supDep)\n\t\t\t\t\t\t? `dependency: ${key} requires ${supDep.join(\", \")}`\n\t\t\t\t\t\t: `dependency: ${key} requires schema`,\n\t\t\t\t\treceived: Array.isArray(subDep)\n\t\t\t\t\t\t? `dependency: ${key} requires ${subDep.join(\", \")}`\n\t\t\t\t\t\t: `dependency: ${key} requires schema`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── patternProperties ──\n\tif (isPlainObj(sup.patternProperties)) {\n\t\tconst supPP = sup.patternProperties as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition\n\t\t>;\n\t\tconst subPP = isPlainObj(sub.patternProperties)\n\t\t\t? (sub.patternProperties as Record<string, JSONSchema7Definition>)\n\t\t\t: null;\n\n\t\tfor (const pattern of Object.keys(supPP)) {\n\t\t\tconst supPropDef = supPP[pattern];\n\t\t\tif (supPropDef === undefined) continue;\n\n\t\t\tconst subPropDef = subPP?.[pattern];\n\t\t\tconst ppPath = path\n\t\t\t\t? `${path}.<patternProperties:${pattern}>`\n\t\t\t\t: `<patternProperties:${pattern}>`;\n\n\t\t\tif (subPropDef === undefined) {\n\t\t\t\t// sub doesn't constrain this pattern at all — more permissive\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: ppPath,\n\t\t\t\t\texpected: formatSchemaType(supPropDef),\n\t\t\t\t\treceived: \"no constraint for this pattern\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Both define the same pattern — recurse\n\t\t\t\tconst ppErrors = computeSemanticErrors(subPropDef, supPropDef, ppPath);\n\t\t\t\terrors.push(...ppErrors);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Compares array constraints (excluding items) between sub and sup.\n */\nfunction checkArrayConstraints(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tpath: string,\n\terrors: SchemaError[],\n): void {\n\tcheckMinConstraint(sub.minItems, sup.minItems, \"minItems\", path, errors);\n\tcheckMaxConstraint(sub.maxItems, sup.maxItems, \"maxItems\", path, errors);\n\n\t// ── uniqueItems ──\n\tif (sup.uniqueItems === true && sub.uniqueItems !== true) {\n\t\terrors.push({\n\t\t\tkey: path || \"$root\",\n\t\t\texpected: \"uniqueItems: true\",\n\t\t\treceived: fmtConstraint(\"uniqueItems\", sub.uniqueItems ?? false),\n\t\t});\n\t}\n\n\t// ── contains ──\n\tif (sup.contains !== undefined) {\n\t\tif (sub.contains === undefined) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `contains: ${formatSchemaType(sup.contains as JSONSchema7Definition)}`,\n\t\t\t\treceived: \"no contains constraint\",\n\t\t\t});\n\t\t} else {\n\t\t\t// Both have contains — recurse to compare the contained schemas\n\t\t\tconst containsPath = path ? `${path}.<contains>` : \"<contains>\";\n\t\t\tconst containsErrors = computeSemanticErrors(\n\t\t\t\tsub.contains as JSONSchema7Definition,\n\t\t\t\tsup.contains as JSONSchema7Definition,\n\t\t\t\tcontainsPath,\n\t\t\t);\n\t\t\terrors.push(...containsErrors);\n\t\t}\n\t}\n}\n\n/**\n * Detects whether a schema has a numeric type.\n */\nfunction isNumericType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"number\" || t === \"integer\";\n\treturn t.some((v) => v === \"number\" || v === \"integer\");\n}\n\n/**\n * Detects whether a schema has a string type.\n */\nfunction isStringType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"string\";\n\treturn t.includes(\"string\");\n}\n\n/**\n * Detects whether a schema has an object type.\n */\nfunction isObjectType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"object\";\n\treturn t.includes(\"object\");\n}\n\n/**\n * Detects whether a schema has an array type.\n */\nfunction isArrayType(t: string | string[] | undefined): boolean {\n\tif (t === undefined) return false;\n\tif (typeof t === \"string\") return t === \"array\";\n\treturn t.includes(\"array\");\n}\n\n// ─── Keyword-based implicit type detection ───────────────────────────────────\n//\n// propertyNames schemas (e.g. { minLength: 1 }) don't always carry an explicit\n// `type`, yet their keywords unambiguously imply a type family. These helpers\n// let us trigger the right constraint checks even when `getEffectiveType`\n// returns `undefined`.\n\nfunction hasNumericKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minimum !== undefined ||\n\t\ts.maximum !== undefined ||\n\t\ts.exclusiveMinimum !== undefined ||\n\t\ts.exclusiveMaximum !== undefined ||\n\t\ts.multipleOf !== undefined\n\t);\n}\n\nfunction hasStringKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minLength !== undefined ||\n\t\ts.maxLength !== undefined ||\n\t\ts.pattern !== undefined ||\n\t\ts.format !== undefined\n\t);\n}\n\nfunction hasObjectKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minProperties !== undefined ||\n\t\ts.maxProperties !== undefined ||\n\t\ts.propertyNames !== undefined ||\n\t\ts.additionalProperties !== undefined ||\n\t\tisPlainObj(s.patternProperties) ||\n\t\tisPlainObj(s.dependencies)\n\t);\n}\n\nfunction hasArrayKeywords(s: JSONSchema7): boolean {\n\treturn (\n\t\ts.minItems !== undefined ||\n\t\ts.maxItems !== undefined ||\n\t\ts.uniqueItems !== undefined ||\n\t\ts.contains !== undefined\n\t);\n}\n\n// ─── Core Comparison ─────────────────────────────────────────────────────────\n\n/**\n * Compares two schemas and produces semantic errors.\n *\n * @param sub The source schema (what is produced / received)\n * @param sup The target schema (what is expected)\n * @param path The current normalized path\n * @returns List of semantic errors\n */\nexport function computeSemanticErrors(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tpath = \"\",\n): SchemaError[] {\n\t// ── Boolean schemas ──\n\tif (typeof sup === \"boolean\") {\n\t\tif (sup === false) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: \"never\",\n\t\t\t\t\treceived: formatSchemaType(sub),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn []; // sup = true accepts everything\n\t}\n\tif (typeof sub === \"boolean\") {\n\t\tif (sub === true) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatSchemaType(sup),\n\t\t\t\t\treceived: \"any\",\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn []; // sub = false produces nothing, trivially subset\n\t}\n\n\tconst subSchema = sub as JSONSchema7;\n\tconst supSchema = sup as JSONSchema7;\n\n\tconst errors: SchemaError[] = [];\n\n\t// ── Handle `not` keyword ──\n\t// Check sup.not: sub must not satisfy the not-schema for sub ⊆ sup.\n\t// Check sub.not: if sub has a not that sup doesn't, sub is more constrained (OK).\n\t// if sup has a not that sub doesn't, sub may be too permissive.\n\tif (\n\t\thasOwn(supSchema, \"not\") &&\n\t\tisPlainObj(supSchema.not) &&\n\t\ttypeof supSchema.not !== \"boolean\"\n\t) {\n\t\tconst notSchema = supSchema.not as JSONSchema7;\n\t\tconst notFormatted = formatSchemaType(notSchema);\n\n\t\tif (!hasOwn(subSchema, \"not\")) {\n\t\t\t// sup excludes something, sub doesn't → sub is more permissive\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: `not ${notFormatted}`,\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t} else if (\n\t\t\tisPlainObj(subSchema.not) &&\n\t\t\ttypeof subSchema.not !== \"boolean\"\n\t\t) {\n\t\t\t// Both have not — compare the not schemas\n\t\t\t// For sub ⊆ sup, sub.not must be at least as broad as sup.not\n\t\t\t// (i.e. sub excludes at least as much). We report if they differ.\n\t\t\tconst subNotSchema = subSchema.not as JSONSchema7;\n\t\t\tif (!deepEqual(subNotSchema, notSchema)) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: `not ${notFormatted}`,\n\t\t\t\t\treceived: `not ${formatSchemaType(subNotSchema)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Get effective types ──\n\tconst subType = getEffectiveType(subSchema);\n\tconst supType = getEffectiveType(supSchema);\n\n\t// ── Handle anyOf/oneOf in sup ──\n\t// If sup has branches, try to find the best matching one for error reporting\n\tconst supBranches = supSchema.anyOf ?? supSchema.oneOf;\n\tif (Array.isArray(supBranches) && supBranches.length > 0 && !supSchema.type) {\n\t\treturn computeErrorsAgainstBranches(subSchema, supBranches, path);\n\t}\n\n\t// ── Handle anyOf/oneOf in sub ──\n\tconst subBranches = subSchema.anyOf ?? subSchema.oneOf;\n\tif (Array.isArray(subBranches) && subBranches.length > 0 && !subSchema.type) {\n\t\tconst branchErrors: SchemaError[] = [];\n\t\tfor (const branch of subBranches) {\n\t\t\tconst errs = computeSemanticErrors(branch, sup, path);\n\t\t\tbranchErrors.push(...errs);\n\t\t}\n\t\treturn branchErrors;\n\t}\n\n\t// ── Both are object types → compare properties + object constraints ──\n\tconst supProps = getProperties(supSchema);\n\tconst subProps = getProperties(subSchema);\n\n\tif (supProps !== null || isObjectType(supType)) {\n\t\t// sup is an object schema\n\t\tif (subType !== undefined && !typeIncludes(subType, \"object\")) {\n\t\t\t// sub is not an object at all\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t\treturn errors;\n\t\t}\n\n\t\tif (supProps !== null) {\n\t\t\tconst supRequired = getRequired(supSchema);\n\t\t\tconst subRequired = getRequired(subSchema);\n\n\t\t\tfor (const key of Object.keys(supProps)) {\n\t\t\t\tconst propPath = joinPath(path, key);\n\t\t\t\tconst supPropDef = supProps[key];\n\t\t\t\tconst subPropDef = subProps?.[key];\n\n\t\t\t\tif (supPropDef === undefined) continue;\n\n\t\t\t\tconst isRequiredInSup = supRequired.includes(key);\n\n\t\t\t\t// ── Missing property (required in sup, absent in sub) ──\n\t\t\t\tif (subPropDef === undefined) {\n\t\t\t\t\tif (isRequiredInSup) {\n\t\t\t\t\t\terrors.push({\n\t\t\t\t\t\t\tkey: propPath,\n\t\t\t\t\t\t\texpected: formatSchemaType(supPropDef),\n\t\t\t\t\t\t\treceived: \"undefined\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// ── Optionality mismatch (required in sup, optional in sub) ──\n\t\t\t\tif (isRequiredInSup && !subRequired.includes(key)) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tkey: propPath,\n\t\t\t\t\t\texpected: \"not optional\",\n\t\t\t\t\t\treceived: \"optional\",\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// ── Recurse into the property schemas ──\n\t\t\t\tconst propErrors = comparePropertySchemas(\n\t\t\t\t\tsubPropDef,\n\t\t\t\t\tsupPropDef,\n\t\t\t\t\tpropPath,\n\t\t\t\t);\n\t\t\t\terrors.push(...propErrors);\n\t\t\t}\n\t\t}\n\n\t\t// ── Object-level constraints ──\n\t\tcheckObjectConstraints(subSchema, supSchema, path, errors);\n\n\t\treturn errors;\n\t}\n\n\t// ── Both are array types → compare items + array constraints ──\n\tif (\n\t\t(supType === \"array\" || supSchema.items !== undefined) &&\n\t\t(subType === \"array\" || subSchema.items !== undefined)\n\t) {\n\t\t// Check items compatibility\n\t\tif (supSchema.items !== undefined && typeof supSchema.items !== \"boolean\") {\n\t\t\tif (\n\t\t\t\tsubSchema.items !== undefined &&\n\t\t\t\ttypeof subSchema.items !== \"boolean\"\n\t\t\t) {\n\t\t\t\t// Both have items schemas — recurse\n\t\t\t\tif (Array.isArray(supSchema.items) && Array.isArray(subSchema.items)) {\n\t\t\t\t\t// Tuple comparison\n\t\t\t\t\tconst maxLen = Math.max(\n\t\t\t\t\t\tsupSchema.items.length,\n\t\t\t\t\t\tsubSchema.items.length,\n\t\t\t\t\t);\n\t\t\t\t\tfor (let i = 0; i < maxLen; i++) {\n\t\t\t\t\t\tconst supItem = supSchema.items[i];\n\t\t\t\t\t\tconst subItem = subSchema.items[i];\n\t\t\t\t\t\tconst itemPath = joinPath(path, `[${i}]`);\n\t\t\t\t\t\tif (supItem !== undefined && subItem === undefined) {\n\t\t\t\t\t\t\terrors.push({\n\t\t\t\t\t\t\t\tkey: itemPath,\n\t\t\t\t\t\t\t\texpected: formatSchemaType(supItem),\n\t\t\t\t\t\t\t\treceived: \"undefined\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (supItem !== undefined && subItem !== undefined) {\n\t\t\t\t\t\t\terrors.push(...computeSemanticErrors(subItem, supItem, itemPath));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (\n\t\t\t\t\t!Array.isArray(supSchema.items) &&\n\t\t\t\t\t!Array.isArray(subSchema.items)\n\t\t\t\t) {\n\t\t\t\t\t// Single items schema — recurse with [] path\n\t\t\t\t\tconst itemPath = arrayPath(path);\n\t\t\t\t\tconst itemErrors = computeSemanticErrors(\n\t\t\t\t\t\tsubSchema.items as JSONSchema7Definition,\n\t\t\t\t\t\tsupSchema.items as JSONSchema7Definition,\n\t\t\t\t\t\titemPath,\n\t\t\t\t\t);\n\t\t\t\t\terrors.push(...itemErrors);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// sup has items schema but sub doesn't\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// ── Array-level constraints ──\n\t\tcheckArrayConstraints(subSchema, supSchema, path, errors);\n\n\t\treturn errors;\n\t}\n\n\t// ── Type mismatch at current level ──\n\tif (subType !== undefined && supType !== undefined) {\n\t\tif (!typesAreCompatible(subType, supType)) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t\treturn errors;\n\t\t}\n\t}\n\n\t// ── Enum comparison ──\n\tif (Array.isArray(supSchema.enum)) {\n\t\tif (Array.isArray(subSchema.enum)) {\n\t\t\t// Both have enums — check if sub.enum ⊆ sup.enum\n\t\t\tconst subExtra = subSchema.enum.filter(\n\t\t\t\t(v) => !supSchema.enum?.some((sv) => deepEqual(v, sv)),\n\t\t\t);\n\t\t\tif (subExtra.length > 0) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\treceived: formatEnumValues(subSchema.enum),\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (hasOwn(subSchema, \"const\")) {\n\t\t\t// sub has const, sup has enum — check inclusion\n\t\t\tconst constInEnum = supSchema.enum.some((v) =>\n\t\t\t\tdeepEqual(v, subSchema.const),\n\t\t\t);\n\t\t\tif (!constInEnum) {\n\t\t\t\terrors.push({\n\t\t\t\t\tkey: path || \"$root\",\n\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// sup has enum but sub is a plain type (no enum restriction)\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t}\n\t\treturn errors;\n\t}\n\n\t// ── Const comparison ──\n\tif (hasOwn(supSchema, \"const\") && hasOwn(subSchema, \"const\")) {\n\t\tif (!deepEqual(supSchema.const, subSchema.const)) {\n\t\t\terrors.push({\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t});\n\t\t}\n\t\treturn errors;\n\t}\n\n\t// ── Same-type constraint comparison ──\n\t// Types are compatible (or unspecified), now check individual keywords.\n\n\tif (\n\t\tisNumericType(subType) ||\n\t\tisNumericType(supType) ||\n\t\thasNumericKeywords(supSchema) ||\n\t\thasNumericKeywords(subSchema)\n\t) {\n\t\tcheckNumericConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\tif (\n\t\tisStringType(subType) ||\n\t\tisStringType(supType) ||\n\t\thasStringKeywords(supSchema) ||\n\t\thasStringKeywords(subSchema)\n\t) {\n\t\tcheckStringConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\t// Object-level constraints when sup doesn't have explicit properties\n\t// but still has object constraints (e.g., just { type: \"object\", minProperties: 3 })\n\tif (\n\t\tisObjectType(subType) ||\n\t\tisObjectType(supType) ||\n\t\thasObjectKeywords(supSchema) ||\n\t\thasObjectKeywords(subSchema)\n\t) {\n\t\tcheckObjectConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\t// Array-level constraints when sup doesn't have explicit items\n\t// but still has array constraints (e.g., just { type: \"array\", minItems: 2 })\n\tif (\n\t\tisArrayType(subType) ||\n\t\tisArrayType(supType) ||\n\t\thasArrayKeywords(supSchema) ||\n\t\thasArrayKeywords(subSchema)\n\t) {\n\t\tcheckArrayConstraints(subSchema, supSchema, path, errors);\n\t}\n\n\tif (errors.length > 0) {\n\t\treturn errors;\n\t}\n\n\t// ── Fallback: generic incompatibility ──\n\t// If we get here, there's an incompatibility we couldn't pinpoint precisely.\n\t// Produce a root-level error with the formatted types.\n\tconst expectedStr = formatSchemaType(supSchema);\n\tconst receivedStr = formatSchemaType(subSchema);\n\tif (expectedStr !== receivedStr) {\n\t\terrors.push({\n\t\t\tkey: path || \"$root\",\n\t\t\texpected: expectedStr,\n\t\t\treceived: receivedStr,\n\t\t});\n\t}\n\n\treturn errors;\n}\n\n// ─── Property Schema Comparison ──────────────────────────────────────────────\n\n/**\n * Compares two property schemas and produces errors.\n * Handles recursion into nested objects and arrays.\n */\nfunction comparePropertySchemas(\n\tsubDef: JSONSchema7Definition,\n\tsupDef: JSONSchema7Definition,\n\tpath: string,\n): SchemaError[] {\n\tif (typeof subDef === \"boolean\" || typeof supDef === \"boolean\") {\n\t\tif (subDef !== supDef) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path,\n\t\t\t\t\texpected: formatSchemaType(supDef),\n\t\t\t\t\treceived: formatSchemaType(subDef),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t}\n\n\tconst subSchema = subDef as JSONSchema7;\n\tconst supSchema = supDef as JSONSchema7;\n\n\tconst subType = getEffectiveType(subSchema);\n\tconst supType = getEffectiveType(supSchema);\n\n\t// ── Enum comparison (before type check, as enums can cross types) ──\n\tif (Array.isArray(supSchema.enum)) {\n\t\tif (Array.isArray(subSchema.enum)) {\n\t\t\tconst subExtra = subSchema.enum.filter(\n\t\t\t\t(v) => !supSchema.enum?.some((sv) => deepEqual(v, sv)),\n\t\t\t);\n\t\t\tif (subExtra.length > 0) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: path,\n\t\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\t\treceived: formatEnumValues(subSchema.enum),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\tif (hasOwn(subSchema, \"const\")) {\n\t\t\tconst constInEnum = supSchema.enum.some((v) =>\n\t\t\t\tdeepEqual(v, subSchema.const),\n\t\t\t);\n\t\t\tif (!constInEnum) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: path,\n\t\t\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\t// sup has enum, sub is a plain type\n\t\treturn [\n\t\t\t{\n\t\t\t\tkey: path,\n\t\t\t\texpected: formatEnumValues(supSchema.enum),\n\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t},\n\t\t];\n\t}\n\n\t// ── Const comparison ──\n\tif (hasOwn(supSchema, \"const\") && hasOwn(subSchema, \"const\")) {\n\t\tif (!deepEqual(supSchema.const, subSchema.const)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path,\n\t\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t}\n\n\t// ── Type mismatch ──\n\tif (subType !== undefined && supType !== undefined) {\n\t\tif (!typesAreCompatible(subType, supType)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: path,\n\t\t\t\t\texpected: formatSchemaType(supSchema),\n\t\t\t\t\treceived: formatSchemaType(subSchema),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t}\n\n\t// ── If same types, recurse deeper ──\n\treturn computeSemanticErrors(subDef, supDef, path);\n}\n\n// ─── Branch Error Computation ────────────────────────────────────────────────\n\n/**\n * When sup has branches (anyOf/oneOf), attempts to find the closest\n * matching branch and generates errors against it.\n *\n * Strategy: compute errors for each branch and return those from the\n * branch with the fewest errors (best match).\n */\nfunction computeErrorsAgainstBranches(\n\tsub: JSONSchema7,\n\tbranches: JSONSchema7Definition[],\n\tpath: string,\n): SchemaError[] {\n\tlet bestErrors: SchemaError[] | null = null;\n\n\tfor (const branch of branches) {\n\t\tconst errors = computeSemanticErrors(sub, branch, path);\n\t\tif (errors.length === 0) return [];\n\t\tif (bestErrors === null || errors.length < bestErrors.length) {\n\t\t\tbestErrors = errors;\n\t\t}\n\t}\n\n\treturn (\n\t\tbestErrors ?? [\n\t\t\t{\n\t\t\t\tkey: path || \"$root\",\n\t\t\t\texpected: formatSchemaType({ anyOf: branches } as JSONSchema7),\n\t\t\t\treceived: formatSchemaType(sub),\n\t\t\t},\n\t\t]\n\t);\n}\n"],"names":["deepEqual","hasOwn","isPlainObj","formatEnumValues","values","parts","map","v","JSON","stringify","length","last","pop","join","formatSchemaType","def","formatSchemaTypeInternal","undefined","schema","const","Array","isArray","enum","branches","anyOf","oneOf","b","type","items","itemSchema","itemBranches","t","itemType","properties","not","joinPath","parent","key","arrayPath","getProperties","getRequired","required","getEffectiveType","typeIncludes","schemaType","target","includes","typesAreCompatible","subType","supType","some","every","st","supt","fmtConstraint","name","value","checkMinConstraint","subVal","supVal","path","errors","push","expected","received","checkMaxConstraint","checkNumericConstraints","sub","sup","minimum","maximum","exclusiveMinimum","exclusiveMaximum","multipleOf","checkStringConstraints","minLength","maxLength","pattern","format","checkObjectConstraints","additionalProperties","apPath","apErrors","computeSemanticErrors","minProperties","maxProperties","propertyNames","pnErrors","dependencies","supDeps","subDeps","Object","keys","supDep","subDep","missing","filter","d","depPath","depErrors","patternProperties","supPP","subPP","supPropDef","subPropDef","ppPath","ppErrors","checkArrayConstraints","minItems","maxItems","uniqueItems","contains","containsPath","containsErrors","isNumericType","isStringType","isObjectType","isArrayType","hasNumericKeywords","s","hasStringKeywords","hasObjectKeywords","hasArrayKeywords","subSchema","supSchema","notSchema","notFormatted","subNotSchema","supBranches","computeErrorsAgainstBranches","subBranches","branchErrors","branch","errs","supProps","subProps","supRequired","subRequired","propPath","isRequiredInSup","propErrors","comparePropertySchemas","maxLen","Math","max","i","supItem","subItem","itemPath","itemErrors","subExtra","sv","constInEnum","expectedStr","receivedStr","subDef","supDef","bestErrors"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-schema-compatibility-checker",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "license": "MIT",
5
5
  "description": "A tool to check compatibility between two JSON Schemas.",
6
6
  "author": {