json-schema-compatibility-checker 1.0.3 → 1.0.5

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.
Files changed (64) hide show
  1. package/dist/chunk-159ezrfm.js +5 -0
  2. package/dist/chunk-159ezrfm.js.map +10 -0
  3. package/dist/chunk-1xda2xvb.js +5 -0
  4. package/dist/{chunk-etwjsbj3.js.map → chunk-1xda2xvb.js.map} +2 -2
  5. package/dist/{chunk-mfe3cw5r.js → chunk-3gazezx2.js} +3 -3
  6. package/dist/{chunk-mfe3cw5r.js.map → chunk-3gazezx2.js.map} +1 -1
  7. package/dist/chunk-7mkqk5qv.js +6 -0
  8. package/dist/chunk-7mkqk5qv.js.map +10 -0
  9. package/dist/{chunk-w1ypc97a.js → chunk-aemw3jv0.js} +3 -3
  10. package/dist/{chunk-w1ypc97a.js.map → chunk-aemw3jv0.js.map} +1 -1
  11. package/dist/{chunk-ayae82am.js → chunk-hrwygqa2.js} +4 -4
  12. package/dist/{chunk-ayae82am.js.map → chunk-hrwygqa2.js.map} +1 -1
  13. package/dist/{chunk-gdf3h8q4.js → chunk-jg89j4nd.js} +3 -3
  14. package/dist/{chunk-gdf3h8q4.js.map → chunk-jg89j4nd.js.map} +1 -1
  15. package/dist/{chunk-ywa6h8q4.js → chunk-kncywgnx.js} +4 -4
  16. package/dist/{chunk-ywa6h8q4.js.map → chunk-kncywgnx.js.map} +1 -1
  17. package/dist/chunk-nkpsq34q.js +5 -0
  18. package/dist/chunk-nkpsq34q.js.map +10 -0
  19. package/dist/chunk-nn3cjjtp.js +5 -0
  20. package/dist/chunk-nn3cjjtp.js.map +10 -0
  21. package/dist/condition-resolver.js +2 -2
  22. package/dist/condition-resolver.js.map +1 -1
  23. package/dist/format-validator.js +2 -2
  24. package/dist/format-validator.js.map +1 -1
  25. package/dist/formatter.d.ts +4 -16
  26. package/dist/formatter.js +2 -2
  27. package/dist/formatter.js.map +1 -1
  28. package/dist/index.d.ts +2 -4
  29. package/dist/index.js +2 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/json-schema-compatibility-checker.d.ts +4 -4
  32. package/dist/json-schema-compatibility-checker.js +2 -2
  33. package/dist/json-schema-compatibility-checker.js.map +1 -1
  34. package/dist/merge-engine.js +2 -2
  35. package/dist/merge-engine.js.map +1 -1
  36. package/dist/normalizer.js +2 -2
  37. package/dist/normalizer.js.map +1 -1
  38. package/dist/pattern-subset.js +2 -2
  39. package/dist/pattern-subset.js.map +1 -1
  40. package/dist/semantic-errors.d.ts +24 -0
  41. package/dist/semantic-errors.js +4 -0
  42. package/dist/{differ.js.map → semantic-errors.js.map} +1 -1
  43. package/dist/subset-checker.d.ts +1 -1
  44. package/dist/subset-checker.js +2 -2
  45. package/dist/subset-checker.js.map +1 -1
  46. package/dist/types.d.ts +9 -14
  47. package/dist/utils.js +2 -2
  48. package/dist/utils.js.map +1 -1
  49. package/package.json +3 -3
  50. package/dist/chunk-8me729r7.js +0 -5
  51. package/dist/chunk-8me729r7.js.map +0 -12
  52. package/dist/chunk-8qenxa2z.js +0 -7
  53. package/dist/chunk-8qenxa2z.js.map +0 -10
  54. package/dist/chunk-etwjsbj3.js +0 -5
  55. package/dist/chunk-jy9206ze.js +0 -5
  56. package/dist/chunk-jy9206ze.js.map +0 -10
  57. package/dist/chunk-k92ftyzf.js +0 -5
  58. package/dist/chunk-k92ftyzf.js.map +0 -10
  59. package/dist/differ.d.ts +0 -14
  60. package/dist/differ.js +0 -4
  61. package/dist/semantic-diff/analyzer.d.ts +0 -25
  62. package/dist/semantic-diff/detectors.d.ts +0 -79
  63. package/dist/semantic-diff/index.d.ts +0 -3
  64. package/dist/semantic-diff/types.d.ts +0 -81
@@ -5,6 +5,6 @@
5
5
  "import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { deepEqual, hasOwn, isPlainObj } from \"./utils\";\n\n// ─── Schema Normalizer ───────────────────────────────────────────────────────\n//\n// Fonctions pures pour normaliser un JSON Schema :\n// - Inférer `type` depuis `const` ou `enum`\n// - Récurser dans toutes les sous-structures (properties, items, anyOf, etc.)\n// - Résoudre la double négation `not.not` → aplatir en contenu direct\n// - Récurser dans `patternProperties` (Point 2)\n// - Récurser dans `dependencies` forme schema (Point 3)\n//\n// Optimisations :\n// - WeakMap cache pour éviter de re-normaliser le même objet\n// - Lazy copy-on-write : ne crée une copie que si des mutations sont nécessaires\n// - Retourne l'original si rien n'a changé (évite les allocations)\n\n// ─── Normalization Cache ─────────────────────────────────────────────────────\n\n/**\n * Cache WeakMap pour les résultats de normalisation.\n * Évite de re-normaliser le même objet schema plusieurs fois.\n * WeakMap permet au GC de collecter les schemas qui ne sont plus référencés.\n */\nconst normalizeCache = new WeakMap<object, JSONSchema7Definition>();\n\n// ─── Type inference ──────────────────────────────────────────────────────────\n\n/**\n * Infère le type JSON Schema d'une valeur JavaScript.\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/** Mots-clés contenant un unique sous-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 * Vérifie si un schema ne contient qu'un seul mot-clé `not` (et aucun\n * autre mot-clé significatif). Utilisé pour la résolution de double négation.\n *\n * Un schema « pur not » est de la forme `{ not: X }` sans aucune autre\n * contrainte. Dans ce cas, `{ not: { not: Y } }` ≡ `Y`.\n *\n * Les mots-clés de métadonnée (`$id`, `$schema`, `$comment`, `title`,\n * `description`, `default`, `examples`, `definitions`, `$defs`) ne sont\n * PAS considérés comme significatifs pour cette détection.\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 * Vérifie si un objet schema ne contient que le mot-clé `not`\n * (plus éventuellement des métadonnées non significatives).\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/** Mots-clés contenant un tableau de sous-schemas */\nconst ARRAY_SCHEMA_KEYWORDS = [\"anyOf\", \"oneOf\", \"allOf\"] as const;\n\n/**\n * Mots-clés contenant un Record<string, JSONSchema7Definition>\n * (chaque valeur est un sous-schema à normaliser récursivement).\n */\nconst PROPERTIES_LIKE_KEYWORDS = [\"properties\", \"patternProperties\"] as const;\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\n/**\n * Normalise un `Record<string, JSONSchema7Definition>` en appliquant\n * `normalize` à chaque valeur.\n * Retourne l'objet original si rien n'a changé (évite les 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 * Infère le `type` depuis `const` si absent.\n * Retourne le type inféré ou undefined si non 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 * Infère le `type` depuis `enum` si absent.\n * Retourne le type inféré (single ou array) ou undefined si non 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 * Normalise un schema : infère `type` depuis `const`/`enum`,\n * et normalise récursivement tous les sous-schemas.\n *\n * Récurse dans :\n * - `properties` et `patternProperties` (Point 2)\n * - `dependencies` forme schema (Point 3) — les valeurs tableau (forme 1)\n * sont laissées intactes\n * - `items` (single ou tuple)\n * - Mots-clés single-schema (`additionalProperties`, `not`, `if`, etc.)\n * - Mots-clés array-of-schema (`anyOf`, `oneOf`, `allOf`)\n *\n * Optimisations :\n * - WeakMap cache : retourne le résultat mis en cache en O(1)\n * - Lazy copy-on-write : ne crée une copie shallow que quand la première\n * mutation est nécessaire, via `ensureCopy()`\n * - Les sous-structures ne sont remplacées que si effectivement changées\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// ── Inférer type depuis const ──\n\tconst typeFromConst = inferTypeFromConst(schema);\n\tif (typeFromConst) {\n\t\tensureCopy().type = typeFromConst;\n\t}\n\n\t// ── Inférer type depuis enum ──\n\tconst typeFromEnum = inferTypeFromEnum(schema);\n\tif (typeFromEnum) {\n\t\tensureCopy().type = typeFromEnum;\n\t}\n\n\t// ── Convertir enum à un seul élément en const ──\n\t// Sémantiquement, { enum: [X] } ≡ { const: X }.\n\t// Cette normalisation garantit que la comparaison structurelle\n\t// (isEqual) ne produit pas de faux négatifs quand un schema utilise\n\t// enum et l'autre utilise const pour la même valeur.\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// Si `const: X` et `enum: [... X ...]` coexistent, `const` est plus\n\t// restrictif → `enum` est redondant. Le merge engine peut produire\n\t// cette combinaison lors de l'intersection const ∩ enum.\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// ── Récurser dans 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// ── Récurser dans dependencies (Point 3) ──\n\t// `dependencies` peut contenir :\n\t// - Forme 1 (property deps) : { foo: [\"bar\", \"baz\"] } → tableau de strings, on skip\n\t// - Forme 2 (schema deps) : { foo: { required: [...] } } → objet schema, on normalise\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// Forme 1 : tableau de strings → laisser tel quel\n\t\t\t\tnewDeps[key] = val;\n\t\t\t} else if (isPlainObj(val)) {\n\t\t\t\t// Forme 2 : sous-schema → normaliser récursivement\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// ── Récurser dans items (tuple ou single) ──\n\tif (schema.items) {\n\t\tif (Array.isArray(schema.items)) {\n\t\t\t// Tuple : normaliser chaque élément\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// ── Récurser dans les mots-clés single-schema ──\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// ── Résoudre la double négation not(not(X)) → X ──\n\t// Après la récursion dans les sous-schemas, `schema.not` est normalisé.\n\t// Si `schema.not` est un objet qui ne contient QUE `not` (un « pur not »),\n\t// alors `{ ...rest, not: { not: X } }` ≡ `{ ...rest, ...X }`.\n\t//\n\t// Logique propositionnelle : ¬¬P ≡ P\n\t//\n\t// On ne résout que le cas « pur » (schema.not n'a que `not` comme clé\n\t// significative) pour éviter les faux-positifs dans les cas complexes.\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// Extraire le contenu de not.not et le fusionner avec le reste du schema\n\t\t\tconst innerSchema = notSchema.not as JSONSchema7;\n\t\t\tconst s = ensureCopy();\n\t\t\t// Retirer `not` du schema courant\n\t\t\tdelete s.not;\n\t\t\t// Fusionner le contenu interne dans le schema courant\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// ── Récurser dans les mots-clés array-of-schema ──\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"
6
6
  ],
7
7
  "mappings": "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",
8
- "debugId": "22F563921815E14364756E2164756E21",
8
+ "debugId": "DCEC1645C649CA3B64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,5 @@
1
+ import{b as U,c as V,d as Y,e as Z,f as _}from"./chunk-159ezrfm.js";import{i as Q}from"./chunk-hrwygqa2.js";import{j as W}from"./chunk-7mkqk5qv.js";import{k as X}from"./chunk-1xda2xvb.js";import{r as J}from"./chunk-kncywgnx.js";import{u as K}from"./chunk-aemw3jv0.js";class F{engine;constructor(){this.engine=new X}isSubset(j,x){if(j===x)return!0;if(K(j,x))return!0;let w=J(j),G=J(x);if(w!==j&&G!==x&&K(w,G))return!0;if(w!==G&&K(w,G))return!0;let{branches:H}=U(w);if(H.length>1||H[0]!==w)return H.every((L)=>V(L,G,this.engine));return V(w,G,this.engine)}check(j,x){if(j===x)return{isSubset:!0,merged:j,errors:[]};if(K(j,x))return{isSubset:!0,merged:j,errors:[]};let w=J(j),G=J(x);if(K(w,G))return{isSubset:!0,merged:w,errors:[]};let{branches:H,type:L}=U(w),{branches:N,type:$}=U(G);if(H.length>1||H[0]!==w)return Y(H,G,this.engine,L);if(N.length>1||N[0]!==G)return Z(w,N,this.engine,$);return _(w,G,this.engine)}canConnect(j,x){return{...this.check(j,x),direction:"sourceOutput ⊆ targetInput"}}isEqual(j,x){return this.engine.isEqual(J(j),J(x))}intersect(j,x){if(j===x||K(j,x))return J(j);let w=J(j),G=J(x);if(K(w,G))return w;let H=this.engine.merge(w,G);if(H===null)return null;if(K(H,w)||K(H,G))return H;return J(H)}resolveConditions(j,x){return Q(j,x,this.engine)}checkResolved(j,x,w,G){let H=Q(j,w,this.engine),L=Q(x,G??w,this.engine);return{...this.check(H.resolved,L.resolved),resolvedSub:H,resolvedSup:L}}normalize(j){return J(j)}formatResult(j,x){return W(j,x)}}
2
+ export{F as a};
3
+
4
+ //# debugId=91D94EC67E2F2AAF64756E2164756E21
5
+ //# sourceMappingURL=chunk-nkpsq34q.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/json-schema-compatibility-checker.ts"],
4
+ "sourcesContent": [
5
+ "import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { resolveConditions } from \"./condition-resolver\";\nimport { formatResult } from \"./formatter\";\nimport { MergeEngine } from \"./merge-engine\";\nimport { normalize } from \"./normalizer\";\nimport {\n\tarePatternsEquivalent,\n\tisPatternSubset,\n\tisTrivialPattern,\n} from \"./pattern-subset\";\nimport type { BranchResult, BranchType } from \"./subset-checker\";\nimport {\n\tcheckAtomic,\n\tcheckBranchedSub,\n\tcheckBranchedSup,\n\tgetBranchesTyped,\n\tisAtomicSubsetOf,\n} from \"./subset-checker\";\nimport type {\n\tConnectionResult,\n\tResolvedConditionResult,\n\tSchemaError,\n\tSubsetResult,\n} from \"./types\";\nimport { deepEqual } from \"./utils\";\n\n// ─── Re-exports ──────────────────────────────────────────────────────────────\n\nexport type {\n\tSchemaError,\n\tSubsetResult,\n\tConnectionResult,\n\tResolvedConditionResult,\n\tBranchType,\n\tBranchResult,\n};\n\nexport {\n\tnormalize,\n\tresolveConditions,\n\tformatResult,\n\tMergeEngine,\n\tisPatternSubset,\n\tarePatternsEquivalent,\n\tisTrivialPattern,\n};\n\n// ─── Main Class ──────────────────────────────────────────────────────────────\n//\n// Façade légère qui orchestre les sous-modules pour vérifier la compatibilité\n// entre JSON Schemas (Draft-07).\n//\n// Principe mathématique :\n// A ⊆ B ⟺ A ∩ B ≡ A\n//\n// En JSON Schema :\n// - A ∩ B = allOf([A, B]) résolu via merge\n// - ≡ = comparaison structurelle\n//\n// @example\n// ```ts\n// const checker = new JsonSchemaCompatibilityChecker();\n//\n// checker.isSubset(strict, loose); // true\n// checker.check(loose, strict); // { isSubset: false, diffs: [...] }\n// checker.canConnect(nodeA.output, nodeB.input); // ConnectionResult\n// ```\n\nexport class JsonSchemaCompatibilityChecker {\n\tprivate readonly engine: MergeEngine;\n\n\tconstructor() {\n\t\tthis.engine = new MergeEngine();\n\t}\n\n\t// ── Subset check (boolean) ─────────────────────────────────────────────\n\n\t/**\n\t * Vérifie si `sub ⊆ sup`.\n\t * Toute valeur valide pour sub est-elle aussi valide pour sup ?\n\t *\n\t * Point 6 — Utilise `getBranchesTyped` pour distinguer `anyOf` de `oneOf`\n\t * en interne, bien que le résultat boolean ne reflète pas la distinction.\n\t */\n\tisSubset(sub: JSONSchema7Definition, sup: JSONSchema7Definition): boolean {\n\t\t// ── Identity short-circuit ──\n\t\t// If sub and sup are the same reference, sub ⊆ sup is trivially true.\n\t\t// This avoids the entire normalize + merge + compare pipeline.\n\t\tif (sub === sup) return true;\n\n\t\t// ── Pre-normalize structural equality ──\n\t\t// If sub and sup are structurally identical before normalization,\n\t\t// they represent the same schema → sub ⊆ sup trivially.\n\t\t// This avoids the WeakMap overhead of normalize() for common cases\n\t\t// like {} ⊆ {} or identical schema objects with different references.\n\t\tif (deepEqual(sub, sup)) return true;\n\n\t\tconst nSub = normalize(sub);\n\t\tconst nSup = normalize(sup);\n\n\t\t// ── Post-normalize structural identity ──\n\t\t// After normalization, schemas that were syntactically different\n\t\t// but semantically equivalent become structurally equal\n\t\t// (e.g. {const:1} vs {const:1, type:\"integer\"}).\n\t\tif (nSub !== sub && nSup !== sup && deepEqual(nSub, nSup)) return true;\n\t\tif (nSub !== nSup && deepEqual(nSub, nSup)) return true;\n\n\t\tconst { branches: subBranches } = getBranchesTyped(nSub);\n\n\t\tif (subBranches.length > 1 || subBranches[0] !== nSub) {\n\t\t\treturn subBranches.every((branch) =>\n\t\t\t\tisAtomicSubsetOf(branch, nSup, this.engine),\n\t\t\t);\n\t\t}\n\n\t\treturn isAtomicSubsetOf(nSub, nSup, this.engine);\n\t}\n\n\t// ── Subset check (detailed) ────────────────────────────────────────────\n\n\t/**\n\t * Vérifie `sub ⊆ sup` et retourne un diagnostic complet\n\t * avec des erreurs sémantiques lisibles.\n\t *\n\t * Point 6 — Utilise `getBranchesTyped` pour distinguer `anyOf` de `oneOf`\n\t * dans les paths d'erreur.\n\t */\n\tcheck(sub: JSONSchema7Definition, sup: JSONSchema7Definition): SubsetResult {\n\t\t// ── Identity short-circuit ──\n\t\t// Same reference → no errors, no merge needed.\n\t\tif (sub === sup) {\n\t\t\treturn { isSubset: true, merged: sub, errors: [] };\n\t\t}\n\n\t\t// ── Pre-normalize structural equality ──\n\t\t// Avoids WeakMap overhead for identical schemas ({} ⊆ {}, etc.).\n\t\tif (deepEqual(sub, sup)) {\n\t\t\treturn { isSubset: true, merged: sub, errors: [] };\n\t\t}\n\n\t\tconst nSub = normalize(sub);\n\t\tconst nSup = normalize(sup);\n\n\t\t// ── Post-normalize structural identity ──\n\t\t// Catches semantically equivalent schemas after normalization.\n\t\tif (deepEqual(nSub, nSup)) {\n\t\t\treturn { isSubset: true, merged: nSub, errors: [] };\n\t\t}\n\n\t\tconst { branches: subBranches, type: subBranchType } =\n\t\t\tgetBranchesTyped(nSub);\n\t\tconst { branches: supBranches, type: supBranchType } =\n\t\t\tgetBranchesTyped(nSup);\n\n\t\t// anyOf/oneOf dans sub\n\t\tif (subBranches.length > 1 || subBranches[0] !== nSub) {\n\t\t\treturn checkBranchedSub(subBranches, nSup, this.engine, subBranchType);\n\t\t}\n\n\t\t// anyOf/oneOf dans sup uniquement\n\t\tif (supBranches.length > 1 || supBranches[0] !== nSup) {\n\t\t\treturn checkBranchedSup(nSub, supBranches, this.engine, supBranchType);\n\t\t}\n\n\t\t// Cas standard\n\t\treturn checkAtomic(nSub, nSup, this.engine);\n\t}\n\n\t// ── Connection check ───────────────────────────────────────────────────\n\n\t/**\n\t * Vérifie si la sortie d'un nœud source peut alimenter l'entrée d'un nœud cible.\n\t *\n\t * Sémantique : `sourceOutput ⊆ targetInput`\n\t * → Toute donnée produite par source sera acceptée par target.\n\t */\n\tcanConnect(\n\t\tsourceOutput: JSONSchema7Definition,\n\t\ttargetInput: JSONSchema7Definition,\n\t): ConnectionResult {\n\t\tconst result = this.check(sourceOutput, targetInput);\n\t\treturn { ...result, direction: \"sourceOutput ⊆ targetInput\" };\n\t}\n\n\t// ── Equality ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Vérifie l'égalité structurelle entre deux schemas.\n\t */\n\tisEqual(a: JSONSchema7Definition, b: JSONSchema7Definition): boolean {\n\t\treturn this.engine.isEqual(normalize(a), normalize(b));\n\t}\n\n\t// ── Intersection ───────────────────────────────────────────────────────\n\n\t/**\n\t * Calcule l'intersection de deux schemas (allOf merge).\n\t * Retourne null si les schemas sont incompatibles.\n\t *\n\t * Le résultat est normalisé pour éliminer les artefacts structurels\n\t * du merge (ex: `enum` redondant quand `const` est présent).\n\t */\n\tintersect(\n\t\ta: JSONSchema7Definition,\n\t\tb: JSONSchema7Definition,\n\t): JSONSchema7Definition | null {\n\t\t// ── Identity short-circuit ──\n\t\t// If a and b are the same reference or structurally equal,\n\t\t// intersection is just normalize(a) — skip the merge entirely.\n\t\tif (a === b || deepEqual(a, b)) return normalize(a);\n\n\t\tconst nA = normalize(a);\n\t\tconst nB = normalize(b);\n\n\t\t// ── Post-normalize identity ──\n\t\tif (deepEqual(nA, nB)) return nA;\n\n\t\tconst merged = this.engine.merge(nA, nB);\n\t\tif (merged === null) return null;\n\t\t// Fast path: if merge result equals one of the normalized inputs,\n\t\t// it's already normalized — skip redundant normalize call.\n\t\tif (deepEqual(merged, nA) || deepEqual(merged, nB)) return merged;\n\t\treturn normalize(merged);\n\t}\n\n\t// ── Condition resolution ───────────────────────────────────────────────\n\n\t/**\n\t * Résout les `if/then/else` d'un schema en évaluant le `if` contre\n\t * des données partielles (discriminants).\n\t */\n\tresolveConditions(\n\t\tschema: JSONSchema7,\n\t\tdata: Record<string, unknown>,\n\t): ResolvedConditionResult {\n\t\treturn resolveConditions(schema, data, this.engine);\n\t}\n\n\t// ── Resolved check ────────────────────────────────────────────────────\n\n\t/**\n\t * Raccourci : résout les conditions des deux schemas puis vérifie sub ⊆ sup.\n\t *\n\t * Utile quand le superset contient des if/then/else et que tu connais\n\t * les valeurs discriminantes que le subset va produire.\n\t */\n\tcheckResolved(\n\t\tsub: JSONSchema7,\n\t\tsup: JSONSchema7,\n\t\tsubData: Record<string, unknown>,\n\t\tsupData?: Record<string, unknown>,\n\t): SubsetResult & {\n\t\tresolvedSub: ResolvedConditionResult;\n\t\tresolvedSup: ResolvedConditionResult;\n\t} {\n\t\tconst resolvedSub = resolveConditions(sub, subData, this.engine);\n\t\tconst resolvedSup = resolveConditions(sup, supData ?? subData, this.engine);\n\t\tconst result = this.check(resolvedSub.resolved, resolvedSup.resolved);\n\n\t\treturn { ...result, resolvedSub, resolvedSup };\n\t}\n\n\t// ── Normalization ──────────────────────────────────────────────────────\n\n\t/**\n\t * Normalise un schema : infère `type` depuis `const`/`enum`,\n\t * et normalise récursivement tous les sous-schemas.\n\t */\n\tnormalize(def: JSONSchema7Definition): JSONSchema7Definition {\n\t\treturn normalize(def);\n\t}\n\n\t// ── Formatting ─────────────────────────────────────────────────────────\n\n\t/**\n\t * Formate un SubsetResult en chaîne lisible (utile pour logs/debug).\n\t */\n\tformatResult(label: string, result: SubsetResult): string {\n\t\treturn formatResult(label, result);\n\t}\n}\n"
6
+ ],
7
+ "mappings": "0SAoEO,AAAM,LAA+B,LAC1B,CAEjB,KAAW,EAAG,CACb,KAAK,OAAS,IAAI,EAYnB,QAAQ,CAAC,EAA4B,EAAqC,CAIzE,GAAI,IAAQ,EAAK,MAAO,GAOxB,GAAI,EAAU,EAAK,CAAG,EAAG,MAAO,GAEhC,IAAM,EAAO,EAAU,CAAG,EACpB,EAAO,EAAU,CAAG,EAM1B,GAAI,IAAS,GAAO,IAAS,GAAO,EAAU,EAAM,CAAI,EAAG,MAAO,GAClE,GAAI,IAAS,GAAQ,EAAU,EAAM,CAAI,EAAG,MAAO,GAEnD,IAAQ,SAAU,GAAgB,EAAiB,CAAI,EAEvD,GAAI,EAAY,OAAS,GAAK,EAAY,KAAO,EAChD,OAAO,EAAY,MAAM,CAAC,IACzB,EAAiB,EAAQ,EAAM,KAAK,MAAM,CAC3C,EAGD,OAAO,EAAiB,EAAM,EAAM,KAAK,MAAM,EAYhD,KAAK,CAAC,EAA4B,EAA0C,CAG3E,GAAI,IAAQ,EACX,MAAO,CAAE,SAAU,GAAM,OAAQ,EAAK,OAAQ,CAAC,CAAE,EAKlD,GAAI,EAAU,EAAK,CAAG,EACrB,MAAO,CAAE,SAAU,GAAM,OAAQ,EAAK,OAAQ,CAAC,CAAE,EAGlD,IAAM,EAAO,EAAU,CAAG,EACpB,EAAO,EAAU,CAAG,EAI1B,GAAI,EAAU,EAAM,CAAI,EACvB,MAAO,CAAE,SAAU,GAAM,OAAQ,EAAM,OAAQ,CAAC,CAAE,EAGnD,IAAQ,SAAU,EAAa,KAAM,GACpC,EAAiB,CAAI,GACd,SAAU,EAAa,KAAM,GACpC,EAAiB,CAAI,EAGtB,GAAI,EAAY,OAAS,GAAK,EAAY,KAAO,EAChD,OAAO,EAAiB,EAAa,EAAM,KAAK,OAAQ,CAAa,EAItE,GAAI,EAAY,OAAS,GAAK,EAAY,KAAO,EAChD,OAAO,EAAiB,EAAM,EAAa,KAAK,OAAQ,CAAa,EAItE,OAAO,EAAY,EAAM,EAAM,KAAK,MAAM,EAW3C,UAAU,CACT,EACA,EACmB,CAEnB,MAAO,IADQ,KAAK,MAAM,EAAc,CAAW,EAC/B,UAAW,4BAA4B,EAQ5D,OAAO,CAAC,EAA0B,EAAmC,CACpE,OAAO,KAAK,OAAO,QAAQ,EAAU,CAAC,EAAG,EAAU,CAAC,CAAC,EAYtD,SAAS,CACR,EACA,EAC+B,CAI/B,GAAI,IAAM,GAAK,EAAU,EAAG,CAAC,EAAG,OAAO,EAAU,CAAC,EAElD,IAAM,EAAK,EAAU,CAAC,EAChB,EAAK,EAAU,CAAC,EAGtB,GAAI,EAAU,EAAI,CAAE,EAAG,OAAO,EAE9B,IAAM,EAAS,KAAK,OAAO,MAAM,EAAI,CAAE,EACvC,GAAI,IAAW,KAAM,OAAO,KAG5B,GAAI,EAAU,EAAQ,CAAE,GAAK,EAAU,EAAQ,CAAE,EAAG,OAAO,EAC3D,OAAO,EAAU,CAAM,EASxB,iBAAiB,CAChB,EACA,EAC0B,CAC1B,OAAO,EAAkB,EAAQ,EAAM,KAAK,MAAM,EAWnD,aAAa,CACZ,EACA,EACA,EACA,EAIC,CACD,IAAM,EAAc,EAAkB,EAAK,EAAS,KAAK,MAAM,EACzD,EAAc,EAAkB,EAAK,GAAW,EAAS,KAAK,MAAM,EAG1E,MAAO,IAFQ,KAAK,MAAM,EAAY,SAAU,EAAY,QAAQ,EAEhD,cAAa,aAAY,EAS9C,SAAS,CAAC,EAAmD,CAC5D,OAAO,EAAU,CAAG,EAQrB,YAAY,CAAC,EAAe,EAA8B,CACzD,OAAO,EAAa,EAAO,CAAM,EAEnC",
8
+ "debugId": "91D94EC67E2F2AAF64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,5 @@
1
+ import{s as N,t as R}from"./chunk-aemw3jv0.js";function I(z){let G=z.map((H)=>typeof H==="string"?H:JSON.stringify(H));if(G.length===0)return"never";if(G.length===1)return G[0];if(G.length===2)return`${G[0]} or ${G[1]}`;let Q=G.pop();return`${G.join(", ")}, or ${Q}`}function Y(z){if(z===void 0)return"undefined";if(typeof z==="boolean")return z?"any":"never";let G=z;if(R(G,"const")){let H=G.const;return typeof H==="string"?H:JSON.stringify(H)}if(Array.isArray(G.enum))return I(G.enum);let Q=G.anyOf??G.oneOf;if(Array.isArray(Q)&&Q.length>0)return Q.map((W)=>Y(W)).join(" | ");if(G.type==="array"){if(G.items!==void 0&&typeof G.items!=="boolean"){let H=G.items,W=H.anyOf??H.oneOf;if(Array.isArray(W)&&W.length>0)return W.map((_)=>`${Y(_)}[]`).join(" | ");if(Array.isArray(H.type))return H.type.map((_)=>`${_}[]`).join(" | ");return`${Y(H)}[]`}return"array"}if(typeof G.type==="string")return G.type;if(Array.isArray(G.type))return G.type.join(" | ");if(R(G,"not")&&!G.type&&!N(G.properties)&&G.items===void 0&&!Array.isArray(G.enum)&&!R(G,"const"))return`not ${Y(G.not)}`;if(N(G.properties))return"object";if(G.items!==void 0)return"array";return"unknown"}function d(z,G){if(!z)return G;return`${z}.${G}`}function h(z){if(!z)return"[]";return`${z}[]`}function D(z){if(N(z.properties))return z.properties;return null}function P(z){if(Array.isArray(z.required))return z.required;return[]}function j(z){if(z.type!==void 0)return z.type;if(R(z,"const")){let G=z.const;if(G===null)return"null";if(Array.isArray(G))return"array";return typeof G}if(N(z.properties))return"object";if(z.items!==void 0)return"array";return}function t(z,G){if(z===void 0)return!1;if(typeof z==="string"){if(G==="number"&&z==="integer")return!0;if(G==="integer"&&z==="number")return!0;return z===G}return z.includes(G)}function b(z,G){if(G===void 0)return!0;if(z===void 0)return!0;if(typeof z==="string"&&typeof G==="string"){if(z===G)return!0;if(z==="integer"&&G==="number")return!0;return!1}if(typeof z==="string"&&Array.isArray(G))return G.some((Q)=>Q===z||z==="integer"&&Q==="number");if(Array.isArray(z)&&typeof G==="string")return z.every((Q)=>Q===G||Q==="integer"&&G==="number");if(Array.isArray(z)&&Array.isArray(G))return z.every((Q)=>G.some((H)=>H===Q||Q==="integer"&&H==="number"));return!0}function U(z,G){if(G===void 0)return`${z}: not set`;if(typeof G==="boolean")return`${z}: ${G}`;if(typeof G==="number"||typeof G==="string")return`${z}: ${G}`;return`${z}: ${JSON.stringify(G)}`}function w(z,G,Q,H,W){if(G!==void 0){if(z===void 0||z<G)W.push({key:H||"$root",expected:U(Q,G),received:U(Q,z)})}}function g(z,G,Q,H,W){if(G!==void 0){if(z===void 0||z>G)W.push({key:H||"$root",expected:U(Q,G),received:U(Q,z)})}}function u(z,G,Q,H){if(w(z.minimum,G.minimum,"minimum",Q,H),g(z.maximum,G.maximum,"maximum",Q,H),w(z.exclusiveMinimum,G.exclusiveMinimum,"exclusiveMinimum",Q,H),g(z.exclusiveMaximum,G.exclusiveMaximum,"exclusiveMaximum",Q,H),G.multipleOf!==void 0){if(z.multipleOf===void 0)H.push({key:Q||"$root",expected:U("multipleOf",G.multipleOf),received:U("multipleOf",z.multipleOf)});else if(z.multipleOf!==G.multipleOf){if(z.multipleOf%G.multipleOf!==0)H.push({key:Q||"$root",expected:U("multipleOf",G.multipleOf),received:U("multipleOf",z.multipleOf)})}}}function r(z,G,Q,H){if(w(z.minLength,G.minLength,"minLength",Q,H),g(z.maxLength,G.maxLength,"maxLength",Q,H),G.pattern!==void 0){if(z.pattern===void 0)H.push({key:Q||"$root",expected:U("pattern",G.pattern),received:"no pattern constraint"});else if(z.pattern!==G.pattern)H.push({key:Q||"$root",expected:U("pattern",G.pattern),received:U("pattern",z.pattern)})}if(G.format!==void 0&&z.format!==G.format)if(z.format===void 0)H.push({key:Q||"$root",expected:U("format",G.format),received:"no format constraint"});else H.push({key:Q||"$root",expected:U("format",G.format),received:U("format",z.format)})}function v(z,G,Q,H){if(G.additionalProperties!==void 0){if(G.additionalProperties===!1){if(z.additionalProperties===void 0||z.additionalProperties===!0)H.push({key:Q||"$root",expected:"additionalProperties: false",received:"additional properties allowed"});else if(typeof z.additionalProperties==="object"&&z.additionalProperties!==null)H.push({key:Q||"$root",expected:"additionalProperties: false",received:"additionalProperties: schema"})}else if(typeof G.additionalProperties==="object"&&G.additionalProperties!==null){if(z.additionalProperties===void 0||z.additionalProperties===!0)H.push({key:Q||"$root",expected:`additionalProperties: ${Y(G.additionalProperties)}`,received:"additional properties allowed"});else if(typeof z.additionalProperties==="object"&&z.additionalProperties!==null){let W=Q?`${Q}.<additionalProperties>`:"<additionalProperties>",X=B(z.additionalProperties,G.additionalProperties,W);H.push(...X)}}}if(w(z.minProperties,G.minProperties,"minProperties",Q,H),g(z.maxProperties,G.maxProperties,"maxProperties",Q,H),G.propertyNames!==void 0)if(z.propertyNames===void 0)H.push({key:Q||"$root",expected:`propertyNames: ${Y(G.propertyNames)}`,received:"no propertyNames constraint"});else{let W=B(z.propertyNames,G.propertyNames,Q?`${Q}.<propertyNames>`:"<propertyNames>");H.push(...W)}if(N(G.dependencies)){let W=G.dependencies,X=N(z.dependencies)?z.dependencies:null;for(let Z of Object.keys(W)){let _=W[Z],$=X?.[Z];if($===void 0)if(Array.isArray(_))H.push({key:Q||"$root",expected:`dependency: ${Z} requires ${_.join(", ")}`,received:`no dependency for ${Z}`});else H.push({key:Q||"$root",expected:`dependency: ${Z} requires schema`,received:`no dependency for ${Z}`});else if(Array.isArray(_)&&Array.isArray($)){if(_.filter((A)=>!$.includes(A)).length>0)H.push({key:Q||"$root",expected:`dependency: ${Z} requires ${_.join(", ")}`,received:`dependency: ${Z} requires ${$.join(", ")}`})}else if(!Array.isArray(_)&&!Array.isArray($)){let x=Q?`${Q}.<dependency:${Z}>`:`<dependency:${Z}>`,A=B($,_,x);H.push(...A)}else H.push({key:Q||"$root",expected:Array.isArray(_)?`dependency: ${Z} requires ${_.join(", ")}`:`dependency: ${Z} requires schema`,received:Array.isArray($)?`dependency: ${Z} requires ${$.join(", ")}`:`dependency: ${Z} requires schema`})}}if(N(G.patternProperties)){let W=G.patternProperties,X=N(z.patternProperties)?z.patternProperties:null;for(let Z of Object.keys(W)){let _=W[Z];if(_===void 0)continue;let $=X?.[Z],x=Q?`${Q}.<patternProperties:${Z}>`:`<patternProperties:${Z}>`;if($===void 0)H.push({key:x,expected:Y(_),received:"no constraint for this pattern"});else{let A=B($,_,x);H.push(...A)}}}}function l(z,G,Q,H){if(w(z.minItems,G.minItems,"minItems",Q,H),g(z.maxItems,G.maxItems,"maxItems",Q,H),G.uniqueItems===!0&&z.uniqueItems!==!0)H.push({key:Q||"$root",expected:"uniqueItems: true",received:U("uniqueItems",z.uniqueItems??!1)});if(G.contains!==void 0)if(z.contains===void 0)H.push({key:Q||"$root",expected:`contains: ${Y(G.contains)}`,received:"no contains constraint"});else{let W=Q?`${Q}.<contains>`:"<contains>",X=B(z.contains,G.contains,W);H.push(...X)}}function f(z){if(z===void 0)return!1;if(typeof z==="string")return z==="number"||z==="integer";return z.some((G)=>G==="number"||G==="integer")}function T(z){if(z===void 0)return!1;if(typeof z==="string")return z==="string";return z.includes("string")}function V(z){if(z===void 0)return!1;if(typeof z==="string")return z==="object";return z.includes("object")}function i(z){if(z===void 0)return!1;if(typeof z==="string")return z==="array";return z.includes("array")}function y(z){return z.minimum!==void 0||z.maximum!==void 0||z.exclusiveMinimum!==void 0||z.exclusiveMaximum!==void 0||z.multipleOf!==void 0}function S(z){return z.minLength!==void 0||z.maxLength!==void 0||z.pattern!==void 0||z.format!==void 0}function n(z){return z.minProperties!==void 0||z.maxProperties!==void 0||z.propertyNames!==void 0||z.additionalProperties!==void 0||N(z.patternProperties)||N(z.dependencies)}function o(z){return z.minItems!==void 0||z.maxItems!==void 0||z.uniqueItems!==void 0||z.contains!==void 0}function B(z,G,Q=""){if(typeof G==="boolean"){if(G===!1)return[{key:Q||"$root",expected:"never",received:Y(z)}];return[]}if(typeof z==="boolean"){if(z===!0)return[{key:Q||"$root",expected:Y(G),received:"any"}];return[]}let H=z,W=G,X=[];if(R(W,"not")&&N(W.not)&&typeof W.not!=="boolean"){let F=W.not,J=Y(F);if(!R(H,"not"))X.push({key:Q||"$root",expected:`not ${J}`,received:Y(H)});else if(N(H.not)&&typeof H.not!=="boolean"){let L=H.not;if(!K(L,F))X.push({key:Q||"$root",expected:`not ${J}`,received:`not ${Y(L)}`})}}let Z=j(H),_=j(W),$=W.anyOf??W.oneOf;if(Array.isArray($)&&$.length>0&&!W.type)return a(H,$,Q);let x=H.anyOf??H.oneOf;if(Array.isArray(x)&&x.length>0&&!H.type){let F=[];for(let J of x){let L=B(J,G,Q);F.push(...L)}return F}let A=D(W),c=D(H);if(A!==null||V(_)){if(Z!==void 0&&!t(Z,"object"))return X.push({key:Q||"$root",expected:Y(W),received:Y(H)}),X;if(A!==null){let F=P(W),J=P(H);for(let L of Object.keys(A)){let M=d(Q,L),q=A[L],k=c?.[L];if(q===void 0)continue;let E=F.includes(L);if(k===void 0){if(E)X.push({key:M,expected:Y(q),received:"undefined"});continue}if(E&&!J.includes(L)){X.push({key:M,expected:"not optional",received:"optional"});continue}let m=p(k,q,M);X.push(...m)}}return v(H,W,Q,X),X}if((_==="array"||W.items!==void 0)&&(Z==="array"||H.items!==void 0)){if(W.items!==void 0&&typeof W.items!=="boolean")if(H.items!==void 0&&typeof H.items!=="boolean"){if(Array.isArray(W.items)&&Array.isArray(H.items)){let F=Math.max(W.items.length,H.items.length);for(let J=0;J<F;J++){let L=W.items[J],M=H.items[J],q=d(Q,`[${J}]`);if(L!==void 0&&M===void 0)X.push({key:q,expected:Y(L),received:"undefined"});else if(L!==void 0&&M!==void 0)X.push(...B(M,L,q))}}else if(!Array.isArray(W.items)&&!Array.isArray(H.items)){let F=h(Q),J=B(H.items,W.items,F);X.push(...J)}}else X.push({key:Q||"$root",expected:Y(W),received:Y(H)});return l(H,W,Q,X),X}if(Z!==void 0&&_!==void 0){if(!b(Z,_))return X.push({key:Q||"$root",expected:Y(W),received:Y(H)}),X}if(Array.isArray(W.enum)){if(Array.isArray(H.enum)){if(H.enum.filter((J)=>!W.enum?.some((L)=>K(J,L))).length>0)X.push({key:Q||"$root",expected:I(W.enum),received:I(H.enum)})}else if(R(H,"const")){if(!W.enum.some((J)=>K(J,H.const)))X.push({key:Q||"$root",expected:I(W.enum),received:Y(H)})}else X.push({key:Q||"$root",expected:I(W.enum),received:Y(H)});return X}if(R(W,"const")&&R(H,"const")){if(!K(W.const,H.const))X.push({key:Q||"$root",expected:Y(W),received:Y(H)});return X}if(f(Z)||f(_)||y(W)||y(H))u(H,W,Q,X);if(T(Z)||T(_)||S(W)||S(H))r(H,W,Q,X);if(V(Z)||V(_)||n(W)||n(H))v(H,W,Q,X);if(i(Z)||i(_)||o(W)||o(H))l(H,W,Q,X);if(X.length>0)return X;let C=Y(W),O=Y(H);if(C!==O)X.push({key:Q||"$root",expected:C,received:O});return X}function p(z,G,Q){if(typeof z==="boolean"||typeof G==="boolean"){if(z!==G)return[{key:Q,expected:Y(G),received:Y(z)}];return[]}let H=z,W=G,X=j(H),Z=j(W);if(Array.isArray(W.enum)){if(Array.isArray(H.enum)){if(H.enum.filter(($)=>!W.enum?.some((x)=>K($,x))).length>0)return[{key:Q,expected:I(W.enum),received:I(H.enum)}];return[]}if(R(H,"const")){if(!W.enum.some(($)=>K($,H.const)))return[{key:Q,expected:I(W.enum),received:Y(H)}];return[]}return[{key:Q,expected:I(W.enum),received:Y(H)}]}if(R(W,"const")&&R(H,"const")){if(!K(W.const,H.const))return[{key:Q,expected:Y(W),received:Y(H)}];return[]}if(X!==void 0&&Z!==void 0){if(!b(X,Z))return[{key:Q,expected:Y(W),received:Y(H)}]}return B(z,G,Q)}function a(z,G,Q){let H=null;for(let W of G){let X=B(z,W,Q);if(X.length===0)return[];if(H===null||X.length<H.length)H=X}return H??[{key:Q||"$root",expected:Y({anyOf:G}),received:Y(z)}]}function K(z,G){if(z===G)return!0;if(z===null||G===null)return!1;if(typeof z!==typeof G)return!1;if(typeof z==="object"){if(Array.isArray(z)){if(!Array.isArray(G))return!1;if(z.length!==G.length)return!1;for(let X=0;X<z.length;X++)if(!K(z[X],G[X]))return!1;return!0}if(Array.isArray(G))return!1;let Q=z,H=G,W=Object.keys(Q);if(W.length!==Object.keys(H).length)return!1;for(let X of W)if(!K(Q[X],H[X]))return!1;return!0}return!1}
2
+ export{Y as g,B as h};
3
+
4
+ //# debugId=0C862C8CE299289A64756E2164756E21
5
+ //# sourceMappingURL=chunk-nn3cjjtp.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/semantic-errors.ts"],
4
+ "sourcesContent": [
5
+ "import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport type { SchemaError } from \"./types\";\nimport { hasOwn, isPlainObj } from \"./utils\";\n\n// ─── Semantic Error Generator ────────────────────────────────────────────────\n//\n// Génère des erreurs sémantiques lisibles en comparant directement deux schemas.\n//\n// Contrairement au differ structurel (qui comparait sub vs merged), ce module\n// compare directement sub (source/received) et sup (target/expected) pour\n// produire des messages d'erreur orientés métier.\n//\n// Les chemins de propriétés sont normalisés :\n// - `accountId` (propriété top-level)\n// - `user.name` (propriété imbriquée)\n// - `users[].name` (propriété dans les items d'un tableau)\n//\n// Convention :\n// - `expected` = ce que le schema cible (sup) attend\n// - `received` = ce que le schema source (sub) fournit\n\n// ─── Type Formatting ─────────────────────────────────────────────────────────\n\n/**\n * Formate les valeurs d'un enum en chaîne lisible.\n *\n * Exemples :\n * - 1 valeur : `\"123\"`\n * - 2 valeurs : `\"123 or salut\"`\n * - 3 valeurs : `\"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 * Formate un schema en représentation de type lisible.\n *\n * Exemples :\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\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 * Construit un chemin de propriété normalisé.\n * - Racine + clé → `\"accountId\"`\n * - Parent + clé → `\"user.name\"`\n * - Parent[] + clé → `\"users[].name\"`\n */\nfunction joinPath(parent: string, key: string): string {\n\tif (!parent) return key;\n\treturn `${parent}.${key}`;\n}\n\n/**\n * Ajoute le suffixe `[]` pour indiquer qu'on entre dans les items d'un array.\n */\nfunction arrayPath(parent: string): string {\n\tif (!parent) return \"[]\";\n\treturn `${parent}[]`;\n}\n\n// ─── Schema Accessors ────────────────────────────────────────────────────────\n\n/**\n * Extrait les propriétés d'un schema de manière sûre.\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 * Extrait les champs required d'un schema de manière sûre.\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 * Détermine le type effectif d'un schema (string ou tableau de 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 * Vérifie si un type (string) est inclus dans un type ou un tableau de 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 * Vérifie si deux types sont compatibles.\n * Un type est compatible si le type de sub est inclus dans le type de sup.\n */\nfunction typesAreCompatible(\n\tsubType: string | string[] | undefined,\n\tsupType: string | string[] | undefined,\n): boolean {\n\tif (supType === undefined) return true; // sup accepte tout\n\tif (subType === undefined) return true; // sub indéterminé, on ne peut pas conclure\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 * Formate une valeur de contrainte en string lisible.\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 * Compare une contrainte numérique \"minimum-like\" (sub.X doit être >= sup.X pour sub ⊆ sup).\n * Exemples : 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 * Compare une contrainte numérique \"maximum-like\" (sub.X doit être <= sup.X pour sub ⊆ sup).\n * Exemples : 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 * Compare les contraintes numériques entre sub et 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 * Compare les contraintes de string entre sub et 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 * Compare les contraintes d'objet (hors properties/required) entre sub et 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 interdit les propriétés additionnelles\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 les autorise → 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 * Compare les contraintes d'array (hors items) entre sub et 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 * Détecte si un schema a un type numérique.\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 * Détecte si un schema a un type string.\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 * Détecte si un schema a un type object.\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 * Détecte si un schema a un type array.\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 * Compare deux schemas et produit des erreurs sémantiques.\n *\n * @param sub Le schema source (ce qui est produit / received)\n * @param sup Le schema cible (ce qui est attendu / expected)\n * @param path Le chemin normalisé courant\n * @returns Liste d'erreurs sémantiques\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 (!deepEqualPrimitive(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) => deepEqualPrimitive(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\tdeepEqualPrimitive(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 (!deepEqualPrimitive(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 * Compare deux schemas de propriété et produit des erreurs.\n * Gère la récursion dans les objets imbriqués et les tableaux.\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) => deepEqualPrimitive(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\tdeepEqualPrimitive(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 (!deepEqualPrimitive(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 * Quand sup a des branches (anyOf/oneOf), tente de trouver la branche\n * la plus proche et génère les erreurs contre celle-ci.\n *\n * Stratégie : calculer les erreurs pour chaque branche et retourner\n * celles de la branche avec le moins d'erreurs (meilleur 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\n// ─── Primitive Deep Equal ────────────────────────────────────────────────────\n\n/**\n * Comparaison d'égalité profonde pour des valeurs JSON primitives et tableaux.\n * Utilisé pour la comparaison d'enums et de consts.\n */\nfunction deepEqualPrimitive(a: unknown, b: unknown): boolean {\n\tif (a === b) return true;\n\tif (a === null || b === null) return false;\n\tif (typeof a !== typeof b) return false;\n\tif (typeof a === \"object\") {\n\t\tif (Array.isArray(a)) {\n\t\t\tif (!Array.isArray(b)) return false;\n\t\t\tif (a.length !== b.length) return false;\n\t\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\t\tif (!deepEqualPrimitive(a[i], b[i])) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tif (Array.isArray(b)) return false;\n\t\tconst aObj = a as Record<string, unknown>;\n\t\tconst bObj = b as Record<string, unknown>;\n\t\tconst aKeys = Object.keys(aObj);\n\t\tif (aKeys.length !== Object.keys(bObj).length) return false;\n\t\tfor (const key of aKeys) {\n\t\t\tif (!deepEqualPrimitive(aObj[key], bObj[key])) return false;\n\t\t}\n\t\treturn true;\n\t}\n\treturn false;\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "0C862C8CE299289A64756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,4 +1,4 @@
1
- import{l as a}from"./chunk-ayae82am.js";import"./chunk-gdf3h8q4.js";import"./chunk-ywa6h8q4.js";import"./chunk-w1ypc97a.js";export{a as resolveConditions};
1
+ import{i as a}from"./chunk-hrwygqa2.js";import"./chunk-jg89j4nd.js";import"./chunk-kncywgnx.js";import"./chunk-aemw3jv0.js";export{a as resolveConditions};
2
2
 
3
- //# debugId=97768507FF79B49E64756E2164756E21
3
+ //# debugId=52E0950EB026BD4B64756E2164756E21
4
4
  //# sourceMappingURL=condition-resolver.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "97768507FF79B49E64756E2164756E21",
7
+ "debugId": "52E0950EB026BD4B64756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -1,4 +1,4 @@
1
- import{q as a,r as b,s as c,t as d,u as e}from"./chunk-gdf3h8q4.js";export{d as validateFormat,c as isKnownFormat,e as isFormatSubset,a as KNOWN_FORMATS,b as FORMAT_SUPERSETS};
1
+ import{l as a,m as b,n as c,o as d,p as e}from"./chunk-jg89j4nd.js";export{d as validateFormat,c as isKnownFormat,e as isFormatSubset,a as KNOWN_FORMATS,b as FORMAT_SUPERSETS};
2
2
 
3
- //# debugId=B906A1D671DC9C0E64756E2164756E21
3
+ //# debugId=CF43D00A548DC60A64756E2164756E21
4
4
  //# sourceMappingURL=format-validator.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "B906A1D671DC9C0E64756E2164756E21",
7
+ "debugId": "CF43D00A548DC60A64756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -1,14 +1,10 @@
1
- import type { SemanticDiff } from "./semantic-diff/types";
2
1
  import type { SubsetResult } from "./types";
3
2
  /**
4
3
  * Formate un SubsetResult en chaîne lisible (utile pour logs/debug).
5
4
  *
6
- * Affiche les diffs sémantiques en priorité (si disponibles),
7
- * avec un fallback sur les diffs structurelles.
8
- *
9
5
  * @param label Label descriptif du check (ex: "strict ⊆ loose")
10
6
  * @param result Le résultat du check à formater
11
- * @returns Chaîne multi-lignes formatée avec icônes et diffs
7
+ * @returns Chaîne multi-lignes formatée avec icônes et erreurs
12
8
  *
13
9
  * @example
14
10
  * ```
@@ -18,17 +14,9 @@ import type { SubsetResult } from "./types";
18
14
  * @example
19
15
  * ```
20
16
  * ❌ loose ⊆ strict: false
21
- * Diffs:
22
- * 🔴 [missing-required-property] Target requires property 'meetingId' (string) which source does not provide
17
+ * Errors:
18
+ * accountId: expected string, received undefined
19
+ * ✗ meetingId: expected not optional, received optional
23
20
  * ```
24
21
  */
25
22
  export declare function formatResult(label: string, result: SubsetResult): string;
26
- /**
27
- * Formate uniquement les diffs sémantiques en chaîne lisible.
28
- *
29
- * Utile quand on veut afficher les diagnostics sans le résultat global.
30
- *
31
- * @param diffs Les diffs sémantiques à formater
32
- * @returns Chaîne multi-lignes, ou chaîne vide si pas de diffs
33
- */
34
- export declare function formatSemanticDiffs(diffs: SemanticDiff[]): string;
package/dist/formatter.js CHANGED
@@ -1,4 +1,4 @@
1
- import{n as a,o as b}from"./chunk-8qenxa2z.js";export{b as formatSemanticDiffs,a as formatResult};
1
+ import{j as a}from"./chunk-7mkqk5qv.js";export{a as formatResult};
2
2
 
3
- //# debugId=8FA4D81514C1E38064756E2164756E21
3
+ //# debugId=CD87B10804FCC3EC64756E2164756E21
4
4
  //# sourceMappingURL=formatter.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "8FA4D81514C1E38064756E2164756E21",
7
+ "debugId": "CD87B10804FCC3EC64756E2164756E21",
8
8
  "names": []
9
9
  }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,5 @@
1
- export { formatSemanticDiffs } from "./formatter";
2
1
  export { JsonSchemaCompatibilityChecker } from "./json-schema-compatibility-checker";
3
2
  export { MergeEngine } from "./merge-engine";
4
3
  export { arePatternsEquivalent, isPatternSubset, isTrivialPattern, } from "./pattern-subset";
5
- export type { SemanticDiff, SemanticDiffType } from "./semantic-diff";
6
- export { computeSemanticDiffs } from "./semantic-diff";
7
- export type { ConnectionResult, ResolvedConditionResult, SchemaDiff, SubsetResult, } from "./types";
4
+ export { formatSchemaType } from "./semantic-errors";
5
+ export type { ConnectionResult, ResolvedConditionResult, SchemaError, SubsetResult, } from "./types";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as B}from"./chunk-jy9206ze.js";import{b as A}from"./chunk-8me729r7.js";import{i as w,j as x,k as z}from"./chunk-mfe3cw5r.js";import"./chunk-ayae82am.js";import"./chunk-k92ftyzf.js";import{o as q}from"./chunk-8qenxa2z.js";import{p as v}from"./chunk-etwjsbj3.js";import"./chunk-gdf3h8q4.js";import"./chunk-ywa6h8q4.js";import"./chunk-w1ypc97a.js";export{z as isTrivialPattern,w as isPatternSubset,q as formatSemanticDiffs,A as computeSemanticDiffs,x as arePatternsEquivalent,v as MergeEngine,B as JsonSchemaCompatibilityChecker};
1
+ import{a as x}from"./chunk-nkpsq34q.js";import"./chunk-159ezrfm.js";import{g as w}from"./chunk-nn3cjjtp.js";import"./chunk-hrwygqa2.js";import"./chunk-7mkqk5qv.js";import{k as d}from"./chunk-1xda2xvb.js";import"./chunk-jg89j4nd.js";import"./chunk-kncywgnx.js";import"./chunk-aemw3jv0.js";import{A as q,B as v,z as f}from"./chunk-3gazezx2.js";export{v as isTrivialPattern,f as isPatternSubset,w as formatSchemaType,q as arePatternsEquivalent,d as MergeEngine,x as JsonSchemaCompatibilityChecker};
2
2
 
3
- //# debugId=302300B8000AAAE564756E2164756E21
3
+ //# debugId=FB47493934D7B79964756E2164756E21
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "302300B8000AAAE564756E2164756E21",
7
+ "debugId": "FB47493934D7B79964756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -5,8 +5,8 @@ import { MergeEngine } from "./merge-engine";
5
5
  import { normalize } from "./normalizer";
6
6
  import { arePatternsEquivalent, isPatternSubset, isTrivialPattern } from "./pattern-subset";
7
7
  import type { BranchResult, BranchType } from "./subset-checker";
8
- import type { ConnectionResult, ResolvedConditionResult, SchemaDiff, SubsetResult } from "./types";
9
- export type { SchemaDiff, SubsetResult, ConnectionResult, ResolvedConditionResult, BranchType, BranchResult, };
8
+ import type { ConnectionResult, ResolvedConditionResult, SchemaError, SubsetResult } from "./types";
9
+ export type { SchemaError, SubsetResult, ConnectionResult, ResolvedConditionResult, BranchType, BranchResult, };
10
10
  export { normalize, resolveConditions, formatResult, MergeEngine, isPatternSubset, arePatternsEquivalent, isTrivialPattern, };
11
11
  export declare class JsonSchemaCompatibilityChecker {
12
12
  private readonly engine;
@@ -21,10 +21,10 @@ export declare class JsonSchemaCompatibilityChecker {
21
21
  isSubset(sub: JSONSchema7Definition, sup: JSONSchema7Definition): boolean;
22
22
  /**
23
23
  * Vérifie `sub ⊆ sup` et retourne un diagnostic complet
24
- * avec les diffs structurels.
24
+ * avec des erreurs sémantiques lisibles.
25
25
  *
26
26
  * Point 6 — Utilise `getBranchesTyped` pour distinguer `anyOf` de `oneOf`
27
- * dans les paths de diff (ex: `anyOf[0]` vs `oneOf[0]`).
27
+ * dans les paths d'erreur.
28
28
  */
29
29
  check(sub: JSONSchema7Definition, sup: JSONSchema7Definition): SubsetResult;
30
30
  /**
@@ -1,4 +1,4 @@
1
- import{a as h}from"./chunk-jy9206ze.js";import"./chunk-8me729r7.js";import{i as e,j as f,k as g}from"./chunk-mfe3cw5r.js";import{l as b}from"./chunk-ayae82am.js";import"./chunk-k92ftyzf.js";import{n as c}from"./chunk-8qenxa2z.js";import{p as d}from"./chunk-etwjsbj3.js";import"./chunk-gdf3h8q4.js";import{w as a}from"./chunk-ywa6h8q4.js";import"./chunk-w1ypc97a.js";export{b as resolveConditions,a as normalize,g as isTrivialPattern,e as isPatternSubset,c as formatResult,f as arePatternsEquivalent,d as MergeEngine,h as JsonSchemaCompatibilityChecker};
1
+ import{a as h}from"./chunk-nkpsq34q.js";import"./chunk-159ezrfm.js";import"./chunk-nn3cjjtp.js";import{i as b}from"./chunk-hrwygqa2.js";import{j as c}from"./chunk-7mkqk5qv.js";import{k as d}from"./chunk-1xda2xvb.js";import"./chunk-jg89j4nd.js";import{r as a}from"./chunk-kncywgnx.js";import"./chunk-aemw3jv0.js";import{A as f,B as g,z as e}from"./chunk-3gazezx2.js";export{b as resolveConditions,a as normalize,g as isTrivialPattern,e as isPatternSubset,c as formatResult,f as arePatternsEquivalent,d as MergeEngine,h as JsonSchemaCompatibilityChecker};
2
2
 
3
- //# debugId=027205FF920F7D0864756E2164756E21
3
+ //# debugId=C1AE5C9302E872FE64756E2164756E21
4
4
  //# sourceMappingURL=json-schema-compatibility-checker.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "027205FF920F7D0864756E2164756E21",
7
+ "debugId": "C1AE5C9302E872FE64756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -1,4 +1,4 @@
1
- import{p as a}from"./chunk-etwjsbj3.js";import"./chunk-gdf3h8q4.js";import"./chunk-w1ypc97a.js";export{a as MergeEngine};
1
+ import{k as a}from"./chunk-1xda2xvb.js";import"./chunk-jg89j4nd.js";import"./chunk-aemw3jv0.js";export{a as MergeEngine};
2
2
 
3
- //# debugId=4B6A36C3676677B164756E2164756E21
3
+ //# debugId=C16B5F221BFFE39664756E2164756E21
4
4
  //# sourceMappingURL=merge-engine.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "4B6A36C3676677B164756E2164756E21",
7
+ "debugId": "C16B5F221BFFE39664756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -1,4 +1,4 @@
1
- import{v as a,w as b}from"./chunk-ywa6h8q4.js";import"./chunk-w1ypc97a.js";export{b as normalize,a as inferType};
1
+ import{q as a,r as b}from"./chunk-kncywgnx.js";import"./chunk-aemw3jv0.js";export{b as normalize,a as inferType};
2
2
 
3
- //# debugId=5721562EAFC36DF764756E2164756E21
3
+ //# debugId=E9B1B1D4D87AB9FF64756E2164756E21
4
4
  //# sourceMappingURL=normalizer.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "5721562EAFC36DF764756E2164756E21",
7
+ "debugId": "E9B1B1D4D87AB9FF64756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -1,4 +1,4 @@
1
- import{h as a,i as b,j as c,k as d}from"./chunk-mfe3cw5r.js";export{d as isTrivialPattern,b as isPatternSubset,a as clearPatternCaches,c as arePatternsEquivalent};
1
+ import{A as c,B as d,y as a,z as b}from"./chunk-3gazezx2.js";export{d as isTrivialPattern,b as isPatternSubset,a as clearPatternCaches,c as arePatternsEquivalent};
2
2
 
3
- //# debugId=9CE3C9594A63700F64756E2164756E21
3
+ //# debugId=C8C679EA9730E87D64756E2164756E21
4
4
  //# sourceMappingURL=pattern-subset.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "9CE3C9594A63700F64756E2164756E21",
7
+ "debugId": "C8C679EA9730E87D64756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -0,0 +1,24 @@
1
+ import type { JSONSchema7Definition } from "json-schema";
2
+ import type { SchemaError } from "./types";
3
+ /**
4
+ * Formate un schema en représentation de type lisible.
5
+ *
6
+ * Exemples :
7
+ * - `{ type: "string" }` → `"string"`
8
+ * - `{ type: "array", items: { type: "string" } }` → `"string[]"`
9
+ * - `{ type: "array", items: { type: ["string","number"] }` → `"string[] | number[]"`
10
+ * - `{ enum: [1, 2, 3] }` → `"1, 2, or 3"`
11
+ * - `{ const: "hello" }` → `"hello"`
12
+ * - `{ anyOf: [{type:"string"},{type:"number"}] }` → `"string | number"`
13
+ * - `undefined` → `"undefined"`
14
+ */
15
+ export declare function formatSchemaType(def: JSONSchema7Definition | undefined): string;
16
+ /**
17
+ * Compare deux schemas et produit des erreurs sémantiques.
18
+ *
19
+ * @param sub Le schema source (ce qui est produit / received)
20
+ * @param sup Le schema cible (ce qui est attendu / expected)
21
+ * @param path Le chemin normalisé courant
22
+ * @returns Liste d'erreurs sémantiques
23
+ */
24
+ export declare function computeSemanticErrors(sub: JSONSchema7Definition, sup: JSONSchema7Definition, path?: string): SchemaError[];
@@ -0,0 +1,4 @@
1
+ import{g as a,h as b}from"./chunk-nn3cjjtp.js";import"./chunk-aemw3jv0.js";export{a as formatSchemaType,b as computeSemanticErrors};
2
+
3
+ //# debugId=88292B457FF8BF8F64756E2164756E21
4
+ //# sourceMappingURL=semantic-errors.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "3AA728193DF7D13364756E2164756E21",
7
+ "debugId": "88292B457FF8BF8F64756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -70,7 +70,7 @@ export declare function checkBranchedSub(subBranches: JSONSchema7Definition[], s
70
70
  *
71
71
  * Utilise `_.some` pour trouver la première branche compatible.
72
72
  */
73
- export declare function checkBranchedSup(sub: JSONSchema7Definition, supBranches: JSONSchema7Definition[], engine: MergeEngine, branchType?: BranchType): SubsetResult;
73
+ export declare function checkBranchedSup(sub: JSONSchema7Definition, supBranches: JSONSchema7Definition[], engine: MergeEngine, _branchType?: BranchType): SubsetResult;
74
74
  /**
75
75
  * Vérifie `sub ⊆ sup` pour deux schemas atomiques (sans anyOf/oneOf).
76
76
  * Utilise `mergeOrThrow` pour capturer les erreurs d'incompatibilité.
@@ -1,4 +1,4 @@
1
- import{c as a,d as b,e as c,f as d,g as e}from"./chunk-8me729r7.js";import"./chunk-mfe3cw5r.js";import"./chunk-k92ftyzf.js";import"./chunk-gdf3h8q4.js";import"./chunk-ywa6h8q4.js";import"./chunk-w1ypc97a.js";export{b as isAtomicSubsetOf,a as getBranchesTyped,d as checkBranchedSup,c as checkBranchedSub,e as checkAtomic};
1
+ import{b as a,c as b,d as c,e as d,f as e}from"./chunk-159ezrfm.js";import"./chunk-nn3cjjtp.js";import"./chunk-jg89j4nd.js";import"./chunk-kncywgnx.js";import"./chunk-aemw3jv0.js";import"./chunk-3gazezx2.js";export{b as isAtomicSubsetOf,a as getBranchesTyped,d as checkBranchedSup,c as checkBranchedSub,e as checkAtomic};
2
2
 
3
- //# debugId=EBA7C5BEF7728E5A64756E2164756E21
3
+ //# debugId=F9684ED9F9ECB1E264756E2164756E21
4
4
  //# sourceMappingURL=subset-checker.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "EBA7C5BEF7728E5A64756E2164756E21",
7
+ "debugId": "F9684ED9F9ECB1E264756E2164756E21",
8
8
  "names": []
9
9
  }