json-schema-compatibility-checker 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-8me729r7.js +5 -0
- package/dist/chunk-8me729r7.js.map +12 -0
- package/dist/chunk-8qenxa2z.js +7 -0
- package/dist/chunk-8qenxa2z.js.map +10 -0
- package/dist/{chunk-pyrx217p.js → chunk-ayae82am.js} +4 -4
- package/dist/{chunk-pyrx217p.js.map → chunk-ayae82am.js.map} +1 -1
- package/dist/chunk-etwjsbj3.js +5 -0
- package/dist/{chunk-yg81ax5m.js.map → chunk-etwjsbj3.js.map} +2 -2
- package/dist/{chunk-07z7fc5q.js → chunk-gdf3h8q4.js} +3 -3
- package/dist/{chunk-07z7fc5q.js.map → chunk-gdf3h8q4.js.map} +1 -1
- package/dist/chunk-jy9206ze.js +5 -0
- package/dist/chunk-jy9206ze.js.map +10 -0
- package/dist/chunk-k92ftyzf.js +5 -0
- package/dist/chunk-k92ftyzf.js.map +10 -0
- package/dist/{chunk-q7kq4fgq.js → chunk-mfe3cw5r.js} +3 -3
- package/dist/{chunk-q7kq4fgq.js.map → chunk-mfe3cw5r.js.map} +1 -1
- package/dist/{chunk-jkdzdb3r.js → chunk-w1ypc97a.js} +3 -3
- package/dist/{chunk-jkdzdb3r.js.map → chunk-w1ypc97a.js.map} +1 -1
- package/dist/{chunk-yqhv3py7.js → chunk-ywa6h8q4.js} +4 -4
- package/dist/{chunk-yqhv3py7.js.map → chunk-ywa6h8q4.js.map} +1 -1
- package/dist/condition-resolver.js +2 -2
- package/dist/condition-resolver.js.map +1 -1
- package/dist/differ.js +2 -2
- package/dist/differ.js.map +1 -1
- package/dist/format-validator.js +2 -2
- package/dist/format-validator.js.map +1 -1
- package/dist/formatter.d.ts +14 -2
- package/dist/formatter.js +2 -2
- package/dist/formatter.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/json-schema-compatibility-checker.js +2 -2
- package/dist/json-schema-compatibility-checker.js.map +1 -1
- package/dist/merge-engine.js +2 -2
- package/dist/merge-engine.js.map +1 -1
- package/dist/normalizer.js +2 -2
- package/dist/normalizer.js.map +1 -1
- package/dist/pattern-subset.js +2 -2
- package/dist/pattern-subset.js.map +1 -1
- package/dist/semantic-diff/analyzer.d.ts +25 -0
- package/dist/semantic-diff/detectors.d.ts +79 -0
- package/dist/semantic-diff/index.d.ts +3 -0
- package/dist/semantic-diff/types.d.ts +81 -0
- package/dist/subset-checker.js +2 -2
- package/dist/subset-checker.js.map +1 -1
- package/dist/types.d.ts +6 -3
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/package.json +48 -48
- package/dist/chunk-2ddbnbyq.js +0 -5
- package/dist/chunk-2ddbnbyq.js.map +0 -10
- package/dist/chunk-b55zsn5n.js +0 -5
- package/dist/chunk-b55zsn5n.js.map +0 -10
- package/dist/chunk-jybaxgmh.js +0 -5
- package/dist/chunk-jybaxgmh.js.map +0 -10
- package/dist/chunk-y8c2z1m3.js +0 -6
- package/dist/chunk-y8c2z1m3.js.map +0 -10
- package/dist/chunk-yg81ax5m.js +0 -5
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"import {\n\tisEmail,\n\tisFQDN,\n\tisIP,\n\tisISO8601,\n\tisURL,\n\tisUUID,\n} from \"class-validator\";\n\n// ─── Format Validator ─────────────────────────────────────────────────────────\n//\n// Valide les valeurs contre les formats JSON Schema Draft-07 en utilisant\n// les fonctions utilitaires de `class-validator`.\n//\n// ⚠️ Ce module ne gère PAS la relation format ⊆ type.\n// Cette relation est déjà correctement gérée par l'approche merge :\n// - { format: \"email\" } ⊆ { type: \"string\" } → true (merge ne change rien)\n// - { type: \"string\" } ⊄ { format: \"email\" } → false (merge ajoute format)\n//\n// Ce module gère UNIQUEMENT :\n// 1. La validation d'une valeur runtime contre un format (evaluateCondition)\n// 2. La compatibilité entre deux formats différents (format-vs-format)\n//\n// Expose :\n// - `validateFormat(value, format)` → validation runtime d'une valeur\n// - `isFormatSubset(sub, sup)` → compatibilité statique format-vs-format\n// - `isKnownFormat(format)` → vérifie si le format est supporté\n// - `FORMAT_SUPERSETS` → hiérarchie d'inclusion entre formats\n\n// ─── Regex patterns ──────────────────────────────────────────────────────────\n\n/** Regex pour le format `time` (HH:MM:SS avec offset optionnel) */\nconst TIME_REGEX = /^\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})?$/;\n\n/** Regex pour le format `date` (YYYY-MM-DD strict) */\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** Regex pour le format `json-pointer` (RFC 6901) */\nconst JSON_POINTER_REGEX = /^(\\/([^~/]|~[01])*)*$/;\n\n/** Regex pour le format `relative-json-pointer` (extension Draft-07) */\nconst RELATIVE_JSON_POINTER_REGEX = /^\\d+(#|(\\/([^~/]|~[01])*)*)$/;\n\n/** Regex pour le format `uri-template` (RFC 6570 — vérification basique) */\nconst _URI_TEMPLATE_REGEX = /\\{[^}]+\\}/;\n\n// ─── Known formats ──────────────────────────────────────────────────────────\n\n/** Formats reconnus par le validateur */\nexport const KNOWN_FORMATS: ReadonlySet<string> = new Set([\n\t\"date-time\",\n\t\"date\",\n\t\"time\",\n\t\"email\",\n\t\"idn-email\",\n\t\"hostname\",\n\t\"idn-hostname\",\n\t\"ipv4\",\n\t\"ipv6\",\n\t\"uri\",\n\t\"uri-reference\",\n\t\"iri\",\n\t\"iri-reference\",\n\t\"uri-template\",\n\t\"uuid\",\n\t\"json-pointer\",\n\t\"relative-json-pointer\",\n\t\"regex\",\n]);\n\n// ─── Format hierarchy ────────────────────────────────────────────────────────\n\n/**\n * Hiérarchie d'inclusion ENTRE FORMATS (pas format-vs-type).\n *\n * `FORMAT_SUPERSETS[format]` = liste des formats qui sont des sur-ensembles\n * de `format` (i.e., toute valeur valide pour `format` est aussi valide\n * pour chacun des sur-ensembles).\n *\n * Cette hiérarchie ne concerne QUE les comparaisons format-vs-format.\n * La relation format ⊆ type (ex: email ⊆ string) est gérée nativement\n * par le merge engine et n'a pas besoin d'être modélisée ici.\n *\n * En pratique, la plupart des formats sont **incomparables** (pas de relation d'inclusion).\n * Seule l'identité (même format) et les quelques relations ci-dessous sont garanties.\n */\nexport const FORMAT_SUPERSETS: Record<string, string[]> = {\n\temail: [\"idn-email\"], // email ⊆ idn-email (toute email ASCII est une idn-email)\n\thostname: [\"idn-hostname\"], // hostname ⊆ idn-hostname\n\turi: [\"iri\"], // uri ⊆ iri (toute URI est une IRI)\n\t\"uri-reference\": [\"iri-reference\"], // uri-reference ⊆ iri-reference\n};\n\n// ─── Format validators (internal) ───────────────────────────────────────────\n\n/**\n * Map interne des fonctions de validation par format.\n *\n * Chaque entrée associe un format Draft-07 à une fonction qui prend\n * une valeur `string` et retourne `boolean`.\n *\n * Utilise les fonctions standalone de `class-validator` quand disponibles,\n * sinon des regex ou des heuristiques.\n */\nconst FORMAT_VALIDATORS: Record<string, (value: string) => boolean> = {\n\t/** ISO 8601 date-time (ex: \"2023-01-15T10:30:00Z\") */\n\t\"date-time\": (value: string): boolean => {\n\t\treturn isISO8601(value, { strict: true });\n\t},\n\n\t/** Date complète (ex: \"2023-01-15\") */\n\tdate: (value: string): boolean => {\n\t\tif (!DATE_REGEX.test(value)) return false;\n\t\t// Vérifier que la date est valide (pas de 2023-02-30)\n\t\tconst d = new Date(`${value}T00:00:00Z`);\n\t\treturn !Number.isNaN(d.getTime()) && value === d.toISOString().slice(0, 10);\n\t},\n\n\t/** Heure complète (ex: \"10:30:00\") */\n\ttime: (value: string): boolean => {\n\t\treturn TIME_REGEX.test(value);\n\t},\n\n\t/** Adresse email (RFC 5321) */\n\temail: (value: string): boolean => {\n\t\treturn isEmail(value);\n\t},\n\n\t/** Adresse email internationalisée (approximation via isEmail) */\n\t\"idn-email\": (value: string): boolean => {\n\t\treturn isEmail(value);\n\t},\n\n\t/** Nom d'hôte (RFC 1123) */\n\thostname: (value: string): boolean => {\n\t\treturn isFQDN(value, { require_tld: false });\n\t},\n\n\t/** Nom d'hôte internationalisé (approximation via isFQDN) */\n\t\"idn-hostname\": (value: string): boolean => {\n\t\treturn isFQDN(value, { require_tld: false });\n\t},\n\n\t/** Adresse IPv4 (ex: \"192.168.1.1\") */\n\tipv4: (value: string): boolean => {\n\t\treturn isIP(value, 4);\n\t},\n\n\t/** Adresse IPv6 (ex: \"::1\") */\n\tipv6: (value: string): boolean => {\n\t\treturn isIP(value, 6);\n\t},\n\n\t/** URI absolue (RFC 3986) */\n\turi: (value: string): boolean => {\n\t\treturn isURL(value, { require_protocol: true });\n\t},\n\n\t/** Référence URI (absolue ou relative — approximation via isURL) */\n\t\"uri-reference\": (value: string): boolean => {\n\t\t// Une uri-reference peut être relative, isURL est une approximation\n\t\treturn isURL(value, { require_protocol: false });\n\t},\n\n\t/** IRI (RFC 3987 — approximation via isURL) */\n\tiri: (value: string): boolean => {\n\t\treturn isURL(value, { require_protocol: true });\n\t},\n\n\t/** Référence IRI (approximation via isURL) */\n\t\"iri-reference\": (value: string): boolean => {\n\t\treturn isURL(value, { require_protocol: false });\n\t},\n\n\t/** Template URI (RFC 6570 — vérification basique) */\n\t\"uri-template\": (value: string): boolean => {\n\t\t// Un uri-template valide peut contenir des expressions entre accolades\n\t\t// ou être une URI simple sans template expressions.\n\t\t// On vérifie juste que les accolades sont bien formées.\n\t\tlet inBrace = false;\n\t\tfor (const ch of value) {\n\t\t\tif (ch === \"{\") {\n\t\t\t\tif (inBrace) return false; // Accolades imbriquées\n\t\t\t\tinBrace = true;\n\t\t\t} else if (ch === \"}\") {\n\t\t\t\tif (!inBrace) return false; // Accolade fermante sans ouvrante\n\t\t\t\tinBrace = false;\n\t\t\t}\n\t\t}\n\t\treturn !inBrace; // Pas d'accolade non fermée\n\t},\n\n\t/** UUID (RFC 4122) */\n\tuuid: (value: string): boolean => {\n\t\treturn isUUID(value);\n\t},\n\n\t/** JSON Pointer (RFC 6901) */\n\t\"json-pointer\": (value: string): boolean => {\n\t\t// Chaîne vide est un json-pointer valide (pointe vers la racine)\n\t\tif (value === \"\") return true;\n\t\treturn JSON_POINTER_REGEX.test(value);\n\t},\n\n\t/** Relative JSON Pointer (extension Draft-07) */\n\t\"relative-json-pointer\": (value: string): boolean => {\n\t\treturn RELATIVE_JSON_POINTER_REGEX.test(value);\n\t},\n\n\t/** Expression régulière ECMA-262 */\n\tregex: (value: string): boolean => {\n\t\ttry {\n\t\t\tnew RegExp(value);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t},\n};\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Vérifie si le format est connu/supporté.\n *\n * @param format Le nom du format à vérifier\n * @returns `true` si le format est dans la liste des formats reconnus\n */\nexport function isKnownFormat(format: string): boolean {\n\treturn KNOWN_FORMATS.has(format);\n}\n\n/**\n * Valide une valeur contre un format JSON Schema Draft-07.\n *\n * Retourne `true` si la valeur est valide pour le format,\n * `false` si elle ne l'est pas, `null` si le format est inconnu.\n *\n * Ne valide que les strings — pour les non-strings, retourne `true`\n * (le format ne s'applique qu'aux strings en Draft-07).\n *\n * @param value La valeur à valider\n * @param format Le format JSON Schema Draft-07 à vérifier\n * @returns `true` si valide, `false` si invalide, `null` si format inconnu\n *\n * @example\n * ```ts\n * validateFormat(\"test@example.com\", \"email\"); // true\n * validateFormat(\"not-an-email\", \"email\"); // false\n * validateFormat(42, \"email\"); // true (non-string → skip)\n * validateFormat(\"foo\", \"unknown-format\"); // null (format inconnu)\n * ```\n */\nexport function validateFormat(value: unknown, format: string): boolean | null {\n\t// Le format ne s'applique qu'aux strings en Draft-07\n\tif (typeof value !== \"string\") return true;\n\n\tconst validator = FORMAT_VALIDATORS[format];\n\tif (!validator) return null; // Format inconnu → indéterminé\n\n\treturn validator(value);\n}\n\n/**\n * Vérifie si le format `sub` est un sous-ensemble du format `sup`.\n *\n * ⚠️ Cette fonction compare UNIQUEMENT deux formats entre eux.\n * Elle ne gère PAS la relation format ⊆ type (ex: email ⊆ string),\n * qui est déjà correctement gérée par le merge engine.\n *\n * `sub ⊆ sup` signifie : toute valeur valide pour `sub` est aussi valide pour `sup`.\n *\n * Retourne `true` si `sub ⊆ sup`, `false` si incompatible, `null` si indéterminé.\n *\n * Cas gérés :\n * - Identité : `sub === sup` → `true`\n * - Hiérarchie : `sup` est dans `FORMAT_SUPERSETS[sub]` → `true`\n * - Hiérarchie inverse : `sub` est dans `FORMAT_SUPERSETS[sup]` → `null`\n * (le subset est un sur-ensemble du superset → indéterminé, pas un conflit\n * car certaines valeurs valides pour sub pourraient aussi être valides pour sup)\n * - Formats différents sans relation connue → `null` (indéterminé)\n *\n * @param subFormat Le format du schema sub\n * @param supFormat Le format du schema sup\n * @returns `true` si sub ⊆ sup, `null` si indéterminé\n *\n * @example\n * ```ts\n * isFormatSubset(\"email\", \"email\"); // true (identité)\n * isFormatSubset(\"email\", \"idn-email\"); // true (email ⊆ idn-email)\n * isFormatSubset(\"email\", \"ipv4\"); // null (incomparable)\n * isFormatSubset(\"idn-email\", \"email\"); // null (sur-ensemble, pas sous-ensemble)\n * ```\n */\nexport function isFormatSubset(\n\tsubFormat: string,\n\tsupFormat: string,\n): boolean | null {\n\t// Identité : même format → toujours un sous-ensemble\n\tif (subFormat === supFormat) return true;\n\n\t// Hiérarchie : vérifier si sup est un sur-ensemble connu de sub\n\tconst supersets = FORMAT_SUPERSETS[subFormat];\n\tif (supersets?.includes(supFormat)) {\n\t\treturn true;\n\t}\n\n\t// Formats différents sans relation connue → indéterminé\n\t// On ne retourne PAS false ici car on ne peut pas affirmer l'incompatibilité\n\t// entre deux formats quelconques sans les connaître parfaitement.\n\t// Le merge engine (via hasFormatConflict) se charge de détecter les conflits\n\t// quand les deux schemas ont un format et qu'aucune relation n'est connue.\n\treturn null;\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "AAAA,kBACC,YACA,UACA,eACA,WACA,YACA,wBA0BD,IAAM,EAAa,kDAGb,EAAa,sBAGb,EAAqB,wBAGrB,EAA8B,+BAQ7B,IAAM,EAAqC,IAAI,IAAI,CACzD,YACA,OACA,OACA,QACA,YACA,WACA,eACA,OACA,OACA,MACA,gBACA,MACA,gBACA,eACA,OACA,eACA,wBACA,OACD,CAAC,EAkBY,EAA6C,CACzD,MAAO,CAAC,WAAW,EACnB,SAAU,CAAC,cAAc,EACzB,IAAK,CAAC,KAAK,EACX,gBAAiB,CAAC,eAAe,CAClC,EAaM,EAAgE,CAErE,YAAa,CAAC,IAA2B,CACxC,OAAO,EAAU,EAAO,CAAE,OAAQ,EAAK,CAAC,GAIzC,KAAM,CAAC,IAA2B,CACjC,GAAI,CAAC,EAAW,KAAK,CAAK,EAAG,MAAO,GAEpC,IAAM,EAAI,IAAI,KAAK,GAAG,aAAiB,EACvC,MAAO,CAAC,OAAO,MAAM,EAAE,QAAQ,CAAC,GAAK,IAAU,EAAE,YAAY,EAAE,MAAM,EAAG,EAAE,GAI3E,KAAM,CAAC,IAA2B,CACjC,OAAO,EAAW,KAAK,CAAK,GAI7B,MAAO,CAAC,IAA2B,CAClC,OAAO,EAAQ,CAAK,GAIrB,YAAa,CAAC,IAA2B,CACxC,OAAO,EAAQ,CAAK,GAIrB,SAAU,CAAC,IAA2B,CACrC,OAAO,EAAO,EAAO,CAAE,YAAa,EAAM,CAAC,GAI5C,eAAgB,CAAC,IAA2B,CAC3C,OAAO,EAAO,EAAO,CAAE,YAAa,EAAM,CAAC,GAI5C,KAAM,CAAC,IAA2B,CACjC,OAAO,EAAK,EAAO,CAAC,GAIrB,KAAM,CAAC,IAA2B,CACjC,OAAO,EAAK,EAAO,CAAC,GAIrB,IAAK,CAAC,IAA2B,CAChC,OAAO,EAAM,EAAO,CAAE,iBAAkB,EAAK,CAAC,GAI/C,gBAAiB,CAAC,IAA2B,CAE5C,OAAO,EAAM,EAAO,CAAE,iBAAkB,EAAM,CAAC,GAIhD,IAAK,CAAC,IAA2B,CAChC,OAAO,EAAM,EAAO,CAAE,iBAAkB,EAAK,CAAC,GAI/C,gBAAiB,CAAC,IAA2B,CAC5C,OAAO,EAAM,EAAO,CAAE,iBAAkB,EAAM,CAAC,GAIhD,eAAgB,CAAC,IAA2B,CAI3C,IAAI,EAAU,GACd,QAAW,KAAM,EAChB,GAAI,IAAO,IAAK,CACf,GAAI,EAAS,MAAO,GACpB,EAAU,GACJ,QAAI,IAAO,IAAK,CACtB,GAAI,CAAC,EAAS,MAAO,GACrB,EAAU,GAGZ,MAAO,CAAC,GAIT,KAAM,CAAC,IAA2B,CACjC,OAAO,EAAO,CAAK,GAIpB,eAAgB,CAAC,IAA2B,CAE3C,GAAI,IAAU,GAAI,MAAO,GACzB,OAAO,EAAmB,KAAK,CAAK,GAIrC,wBAAyB,CAAC,IAA2B,CACpD,OAAO,EAA4B,KAAK,CAAK,GAI9C,MAAO,CAAC,IAA2B,CAClC,GAAI,CAEH,OADA,IAAI,OAAO,CAAK,EACT,GACN,KAAM,CACP,MAAO,IAGV,EAUO,SAAS,CAAa,CAAC,EAAyB,CACtD,OAAO,EAAc,IAAI,CAAM,EAwBzB,SAAS,CAAc,CAAC,EAAgB,EAAgC,CAE9E,GAAI,OAAO,IAAU,SAAU,MAAO,GAEtC,IAAM,EAAY,EAAkB,GACpC,GAAI,CAAC,EAAW,OAAO,KAEvB,OAAO,EAAU,CAAK,EAkChB,SAAS,CAAc,CAC7B,EACA,EACiB,CAEjB,GAAI,IAAc,EAAW,MAAO,GAIpC,GADkB,EAAiB,IACpB,SAAS,CAAS,EAChC,MAAO,GAQR,OAAO",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "84623DE4C3DA393664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{c as U,d as V,e as Y,f as Z,g as _}from"./chunk-8me729r7.js";import{l as Q}from"./chunk-ayae82am.js";import{n as W}from"./chunk-8qenxa2z.js";import{p as X}from"./chunk-etwjsbj3.js";import{w as J}from"./chunk-ywa6h8q4.js";import{z as K}from"./chunk-w1ypc97a.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,diffs:[],semanticDiffs:[]};if(K(j,x))return{isSubset:!0,merged:j,diffs:[],semanticDiffs:[]};let w=J(j),G=J(x);if(K(w,G))return{isSubset:!0,merged:w,diffs:[],semanticDiffs:[]};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=F7539F5812EBB21364756E2164756E21
|
|
5
|
+
//# sourceMappingURL=chunk-jy9206ze.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\tSchemaDiff,\n\tSubsetResult,\n} from \"./types\";\nimport { deepEqual } from \"./utils\";\n\n// ─── Re-exports ──────────────────────────────────────────────────────────────\n\nexport type {\n\tSchemaDiff,\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 les diffs structurels.\n\t *\n\t * Point 6 — Utilise `getBranchesTyped` pour distinguer `anyOf` de `oneOf`\n\t * dans les paths de diff (ex: `anyOf[0]` vs `oneOf[0]`).\n\t */\n\tcheck(sub: JSONSchema7Definition, sup: JSONSchema7Definition): SubsetResult {\n\t\t// ── Identity short-circuit ──\n\t\t// Same reference → no diffs, no merge needed.\n\t\tif (sub === sup) {\n\t\t\treturn { isSubset: true, merged: sub, diffs: [], semanticDiffs: [] };\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, diffs: [], semanticDiffs: [] };\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, diffs: [], semanticDiffs: [] };\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,MAAO,CAAC,EAAG,cAAe,CAAC,CAAE,EAKpE,GAAI,EAAU,EAAK,CAAG,EACrB,MAAO,CAAE,SAAU,GAAM,OAAQ,EAAK,MAAO,CAAC,EAAG,cAAe,CAAC,CAAE,EAGpE,IAAM,EAAO,EAAU,CAAG,EACpB,EAAO,EAAU,CAAG,EAI1B,GAAI,EAAU,EAAM,CAAI,EACvB,MAAO,CAAE,SAAU,GAAM,OAAQ,EAAM,MAAO,CAAC,EAAG,cAAe,CAAC,CAAE,EAGrE,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": "F7539F5812EBB21364756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{B as W,x as M,z as Q}from"./chunk-w1ypc97a.js";var $=new Set(["items","additionalProperties","additionalItems","contains","propertyNames","not","if","then","else"]),C=new Set(["properties","patternProperties","dependencies"]);function T(z,A,F){return $.has(z)&&M(A)&&M(F)}function U(z,A,F){return C.has(z)&&M(A)&&M(F)}function X(z,A,F){if(typeof z==="boolean"||typeof A==="boolean"){if(z!==A)return[{path:F||"$",type:"changed",sourceValue:z,mergedValue:A}];return[]}let N=W(Object.keys(z),Object.keys(A)),H=[];for(let x of N){let G=F?`${F}.${x}`:x,w=z[x],v=A[x];if(w===void 0&&v!==void 0){H.push({path:G,type:"added",sourceValue:void 0,mergedValue:v});continue}if(w!==void 0&&v===void 0){H.push({path:G,type:"removed",sourceValue:w,mergedValue:void 0});continue}if(w!==void 0&&v!==void 0&&!Q(w,v)){if(T(x,w,v)){let B=X(w,v,G);for(let J of B)H.push(J);continue}if(U(x,w,v)){let B=q(w,v,G,x);for(let J of B)H.push(J);continue}H.push({path:G,type:"changed",sourceValue:w,mergedValue:v})}}return H}function q(z,A,F,N){let H=W(Object.keys(z),Object.keys(A)),x=[];for(let G of H){let w=`${F}.${G}`,v=z[G],B=A[G];if(v===void 0&&B!==void 0){x.push({path:w,type:"added",sourceValue:void 0,mergedValue:B});continue}if(v!==void 0&&B===void 0){x.push({path:w,type:"removed",sourceValue:v,mergedValue:void 0});continue}if(v!==void 0&&B!==void 0){if(N==="dependencies"&&(Array.isArray(v)||Array.isArray(B))){if(!Q(v,B))x.push({path:w,type:"changed",sourceValue:v,mergedValue:B});continue}let J=X(v,B,w);for(let Z of J)x.push(Z)}}return x}
|
|
2
|
+
export{X as m};
|
|
3
|
+
|
|
4
|
+
//# debugId=DE69788D2095718464756E2164756E21
|
|
5
|
+
//# sourceMappingURL=chunk-k92ftyzf.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/differ.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport type { SchemaDiff } from \"./types\";\nimport { deepEqual, isPlainObj, unionStrings } from \"./utils\";\n\n// ─── Schema Differ ───────────────────────────────────────────────────────────\n//\n// Calcul des différences structurelles entre un schema original et son\n// intersection (merged). Utilisé pour produire des diagnostics lisibles\n// quand sub ⊄ sup.\n//\n// Utilise des méthodes natives JS pour des performances optimales.\n\n// ─── Recursive diff keys ─────────────────────────────────────────────────────\n\n/** Mots-clés dont la valeur est un sous-schema unique (récursion possible) */\nconst RECURSIVE_KEYS: ReadonlySet<string> = new Set([\n\t\"items\",\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]);\n\n/**\n * Mots-clés dont la valeur est un `Record<string, JSONSchema7Definition>`.\n * Chaque propriété est un sous-schema → récursion au niveau des clés.\n *\n * `dependencies` est inclus ici avec une gestion spéciale (forme tableau\n * vs forme schema) dans `computePropertyDiffs`.\n *\n * Point 3 — dependencies ajouté ici (avec gestion spéciale forme tableau).\n */\nconst PROPERTIES_LIKE_KEYS: ReadonlySet<string> = new Set([\n\t\"properties\",\n\t\"patternProperties\",\n\t\"dependencies\",\n]);\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\n/**\n * Vérifie si on peut récurser dans un mot-clé single-schema :\n * la clé doit être dans RECURSIVE_KEYS et les deux valeurs doivent être\n * des objets (pas des tableaux, pas null).\n */\nfunction canRecurseInto(\n\tkey: string,\n\torigVal: unknown,\n\tmergedVal: unknown,\n): boolean {\n\treturn (\n\t\tRECURSIVE_KEYS.has(key) && isPlainObj(origVal) && isPlainObj(mergedVal)\n\t);\n}\n\n/**\n * Vérifie si un mot-clé est un objet de propriétés récursable.\n *\n * Utilise `_.includes` sur le Set pour une vérification concise.\n */\nfunction isPropertiesLikeObject(\n\tkey: string,\n\torigVal: unknown,\n\tmergedVal: unknown,\n): boolean {\n\treturn (\n\t\tPROPERTIES_LIKE_KEYS.has(key) &&\n\t\tisPlainObj(origVal) &&\n\t\tisPlainObj(mergedVal)\n\t);\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Compare un schema original avec sa version mergée et retourne la liste\n * des différences structurelles.\n *\n * @param original Le schema sub tel qu'il était avant le merge\n * @param merged Le schema résultant de l'intersection allOf(sub, sup)\n * @param path Chemin JSON-path courant (vide à la racine)\n *\n * Point 9 — Utilise `deepEqual` au lieu de `JSON.stringify` pour comparer\n * les valeurs, ce qui élimine la dépendance à l'ordre des clés.\n */\nexport function computeDiffs(\n\toriginal: JSONSchema7Definition,\n\tmerged: JSONSchema7Definition,\n\tpath: string,\n): SchemaDiff[] {\n\t// Cas boolean schemas\n\tif (typeof original === \"boolean\" || typeof merged === \"boolean\") {\n\t\tif (original !== merged) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: path || \"$\",\n\t\t\t\t\ttype: \"changed\",\n\t\t\t\t\tsourceValue: original,\n\t\t\t\t\tmergedValue: merged,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t}\n\n\t// Collecter toutes les clés des deux schemas\n\tconst allKeys = unionStrings(\n\t\tObject.keys(original),\n\t\tObject.keys(merged),\n\t) as (keyof JSONSchema7)[];\n\n\tconst result: SchemaDiff[] = [];\n\tfor (const key of allKeys) {\n\t\tconst currentPath = path ? `${path}.${key}` : key;\n\t\tconst origVal = original[key];\n\t\tconst mergedVal = merged[key];\n\n\t\t// Clé ajoutée par le merge\n\t\tif (origVal === undefined && mergedVal !== undefined) {\n\t\t\tresult.push({\n\t\t\t\tpath: currentPath,\n\t\t\t\ttype: \"added\",\n\t\t\t\tsourceValue: undefined,\n\t\t\t\tmergedValue: mergedVal,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Clé supprimée par le merge\n\t\tif (origVal !== undefined && mergedVal === undefined) {\n\t\t\tresult.push({\n\t\t\t\tpath: currentPath,\n\t\t\t\ttype: \"removed\",\n\t\t\t\tsourceValue: origVal,\n\t\t\t\tmergedValue: undefined,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Les deux sont définies — vérifier si elles diffèrent\n\t\t// Point 9 : deepEqual pour une comparaison profonde indépendante de l'ordre des clés\n\t\tif (\n\t\t\torigVal !== undefined &&\n\t\t\tmergedVal !== undefined &&\n\t\t\t!deepEqual(origVal, mergedVal)\n\t\t) {\n\t\t\t// Récurser dans les sous-schemas uniques\n\t\t\tif (canRecurseInto(key, origVal, mergedVal)) {\n\t\t\t\tconst sub = computeDiffs(\n\t\t\t\t\torigVal as JSONSchema7Definition,\n\t\t\t\t\tmergedVal as JSONSchema7Definition,\n\t\t\t\t\tcurrentPath,\n\t\t\t\t);\n\t\t\t\tfor (const d of sub) result.push(d);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Récurser dans les objets de propriétés (properties, patternProperties, dependencies)\n\t\t\tif (isPropertiesLikeObject(key, origVal, mergedVal)) {\n\t\t\t\tconst sub = computePropertyDiffs(\n\t\t\t\t\torigVal as Record<string, JSONSchema7Definition>,\n\t\t\t\t\tmergedVal as Record<string, JSONSchema7Definition>,\n\t\t\t\t\tcurrentPath,\n\t\t\t\t\tkey,\n\t\t\t\t);\n\t\t\t\tfor (const d of sub) result.push(d);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Valeur scalaire ou structure non-récursable\n\t\t\tresult.push({\n\t\t\t\tpath: currentPath,\n\t\t\t\ttype: \"changed\",\n\t\t\t\tsourceValue: origVal,\n\t\t\t\tmergedValue: mergedVal,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// ─── Property-level diffs ────────────────────────────────────────────────────\n\n/**\n * Calcule les diffs au niveau des propriétés d'un objet `properties`,\n * `patternProperties`, ou `dependencies`.\n *\n * Pour `dependencies` (Point 3), gère les deux formes :\n * - Forme 1 (tableau de strings) : comparaison directe via `deepEqual`\n * - Forme 2 (sous-schema) : récursion via `computeDiffs`\n *\n * Fusionne les clés des deux côtés et produit un tableau aplati de diffs.\n */\nfunction computePropertyDiffs(\n\toriginal: Record<string, JSONSchema7Definition | string[]>,\n\tmerged: Record<string, JSONSchema7Definition | string[]>,\n\tbasePath: string,\n\tparentKey: string,\n): SchemaDiff[] {\n\tconst allPropKeys = unionStrings(Object.keys(original), Object.keys(merged));\n\n\tconst result: SchemaDiff[] = [];\n\tfor (const key of allPropKeys) {\n\t\tconst currentPath = `${basePath}.${key}`;\n\t\tconst origVal = original[key];\n\t\tconst mergedVal = merged[key];\n\n\t\tif (origVal === undefined && mergedVal !== undefined) {\n\t\t\tresult.push({\n\t\t\t\tpath: currentPath,\n\t\t\t\ttype: \"added\",\n\t\t\t\tsourceValue: undefined,\n\t\t\t\tmergedValue: mergedVal,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (origVal !== undefined && mergedVal === undefined) {\n\t\t\tresult.push({\n\t\t\t\tpath: currentPath,\n\t\t\t\ttype: \"removed\",\n\t\t\t\tsourceValue: origVal,\n\t\t\t\tmergedValue: undefined,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (origVal !== undefined && mergedVal !== undefined) {\n\t\t\t// Pour `dependencies`, les valeurs peuvent être des tableaux de strings (forme 1)\n\t\t\t// On ne récurse que si les deux valeurs sont des objets (sous-schemas)\n\t\t\tif (\n\t\t\t\tparentKey === \"dependencies\" &&\n\t\t\t\t(Array.isArray(origVal) || Array.isArray(mergedVal))\n\t\t\t) {\n\t\t\t\t// Comparaison directe pour les tableaux de strings\n\t\t\t\tif (!deepEqual(origVal, mergedVal)) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\tpath: currentPath,\n\t\t\t\t\t\ttype: \"changed\",\n\t\t\t\t\t\tsourceValue: origVal,\n\t\t\t\t\t\tmergedValue: mergedVal,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Récursion standard pour les sous-schemas\n\t\t\tconst sub = computeDiffs(\n\t\t\t\torigVal as JSONSchema7Definition,\n\t\t\t\tmergedVal as JSONSchema7Definition,\n\t\t\t\tcurrentPath,\n\t\t\t);\n\t\t\tfor (const d of sub) result.push(d);\n\t\t}\n\t}\n\n\treturn result;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "sDAeA,IAAM,EAAsC,IAAI,IAAI,CACnD,QACA,uBACA,kBACA,WACA,gBACA,MACA,KACA,OACA,MACD,CAAC,EAWK,EAA4C,IAAI,IAAI,CACzD,aACA,oBACA,cACD,CAAC,EASD,SAAS,CAAc,CACtB,EACA,EACA,EACU,CACV,OACC,EAAe,IAAI,CAAG,GAAK,EAAW,CAAO,GAAK,EAAW,CAAS,EASxE,SAAS,CAAsB,CAC9B,EACA,EACA,EACU,CACV,OACC,EAAqB,IAAI,CAAG,GAC5B,EAAW,CAAO,GAClB,EAAW,CAAS,EAiBf,SAAS,CAAY,CAC3B,EACA,EACA,EACe,CAEf,GAAI,OAAO,IAAa,WAAa,OAAO,IAAW,UAAW,CACjE,GAAI,IAAa,EAChB,MAAO,CACN,CACC,KAAM,GAAQ,IACd,KAAM,UACN,YAAa,EACb,YAAa,CACd,CACD,EAED,MAAO,CAAC,EAIT,IAAM,EAAU,EACf,OAAO,KAAK,CAAQ,EACpB,OAAO,KAAK,CAAM,CACnB,EAEM,EAAuB,CAAC,EAC9B,QAAW,KAAO,EAAS,CAC1B,IAAM,EAAc,EAAO,GAAG,KAAQ,IAAQ,EACxC,EAAU,EAAS,GACnB,EAAY,EAAO,GAGzB,GAAI,IAAY,QAAa,IAAc,OAAW,CACrD,EAAO,KAAK,CACX,KAAM,EACN,KAAM,QACN,YAAa,OACb,YAAa,CACd,CAAC,EACD,SAID,GAAI,IAAY,QAAa,IAAc,OAAW,CACrD,EAAO,KAAK,CACX,KAAM,EACN,KAAM,UACN,YAAa,EACb,YAAa,MACd,CAAC,EACD,SAKD,GACC,IAAY,QACZ,IAAc,QACd,CAAC,EAAU,EAAS,CAAS,EAC5B,CAED,GAAI,EAAe,EAAK,EAAS,CAAS,EAAG,CAC5C,IAAM,EAAM,EACX,EACA,EACA,CACD,EACA,QAAW,KAAK,EAAK,EAAO,KAAK,CAAC,EAClC,SAID,GAAI,EAAuB,EAAK,EAAS,CAAS,EAAG,CACpD,IAAM,EAAM,EACX,EACA,EACA,EACA,CACD,EACA,QAAW,KAAK,EAAK,EAAO,KAAK,CAAC,EAClC,SAID,EAAO,KAAK,CACX,KAAM,EACN,KAAM,UACN,YAAa,EACb,YAAa,CACd,CAAC,GAIH,OAAO,EAeR,SAAS,CAAoB,CAC5B,EACA,EACA,EACA,EACe,CACf,IAAM,EAAc,EAAa,OAAO,KAAK,CAAQ,EAAG,OAAO,KAAK,CAAM,CAAC,EAErE,EAAuB,CAAC,EAC9B,QAAW,KAAO,EAAa,CAC9B,IAAM,EAAc,GAAG,KAAY,IAC7B,EAAU,EAAS,GACnB,EAAY,EAAO,GAEzB,GAAI,IAAY,QAAa,IAAc,OAAW,CACrD,EAAO,KAAK,CACX,KAAM,EACN,KAAM,QACN,YAAa,OACb,YAAa,CACd,CAAC,EACD,SAGD,GAAI,IAAY,QAAa,IAAc,OAAW,CACrD,EAAO,KAAK,CACX,KAAM,EACN,KAAM,UACN,YAAa,EACb,YAAa,MACd,CAAC,EACD,SAGD,GAAI,IAAY,QAAa,IAAc,OAAW,CAGrD,GACC,IAAc,iBACb,MAAM,QAAQ,CAAO,GAAK,MAAM,QAAQ,CAAS,GACjD,CAED,GAAI,CAAC,EAAU,EAAS,CAAS,EAChC,EAAO,KAAK,CACX,KAAM,EACN,KAAM,UACN,YAAa,EACb,YAAa,CACd,CAAC,EAEF,SAID,IAAM,EAAM,EACX,EACA,EACA,CACD,EACA,QAAW,KAAK,EAAK,EAAO,KAAK,CAAC,GAIpC,OAAO",
|
|
8
|
+
"debugId": "DE69788D2095718464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import k from"randexp";var V=200,q=100,K=20,Y=new Map,w=new Map,H=new Map;function _(){Y.clear(),w.clear(),H.clear()}var I=new Set([".*",".+","^.*$","^.+$","^.*",".*$","^.+",".+$","(?:.*)","(?:.+)"]);function y(J){let z=H.get(J);if(z!==void 0)return z;try{let Q=new k(J);return Q.max=K,H.set(J,Q),Q}catch{return H.set(J,null),null}}function B(J){let z=w.get(J);if(z!==void 0)return z;try{let Q=new RegExp(J);return w.set(J,Q),Q}catch{return w.set(J,null),null}}function L(J){let z=J.trim();if(z===""||I.has(z))return!0;if(z==="^(.*)$"||z==="^(.+)$")return!0;return!1}function U(J,z){if(L(z))return!0;return null}function O(J,z,Q=V){if(J===z)return!0;let W=`${J}\x00${z}\x00${Q}`,Z=Y.get(W);if(Z!==void 0)return Z;let F=U(J,z);if(F!==null)return Y.set(W,F),F;let $=B(z);if($===null)return Y.set(W,null),null;let f=y(J);if(f===null)return Y.set(W,null),null;let D=new Set,X=0,G=0,M=Q*3;while(X<Q&&G<M){G++;let j=f.gen();if(typeof j!=="string"||j.length>q)continue;if(D.has(j))continue;if(D.add(j),X++,!$.test(j))return Y.set(W,!1),!1}if(X===0)return Y.set(W,null),null;return Y.set(W,!0),!0}function R(J,z,Q=V){if(J===z)return!0;let W=O(J,z,Q);if(W===null)return null;if(W===!1)return!1;let Z=O(z,J,Q);if(Z===null)return null;return Z}function v(J){let z=J.trim();if(z==="")return!0;return I.has(z)}
|
|
2
|
-
export{_ as
|
|
2
|
+
export{_ as h,O as i,R as j,v as k};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
5
|
-
//# sourceMappingURL=chunk-
|
|
4
|
+
//# debugId=8A1D1F55B4FF298064756E2164756E21
|
|
5
|
+
//# sourceMappingURL=chunk-mfe3cw5r.js.map
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"import RandExp from \"randexp\";\n\n// ─── Pattern Subset Checker ──────────────────────────────────────────────────\n//\n// Vérifie si un pattern regex est un sous-ensemble d'un autre pattern regex\n// via une approche par échantillonnage (sampling).\n//\n// Principe :\n// L(A) ⊆ L(B) ⟺ ∀s ∈ L(A), s ∈ L(B)\n//\n// On ne peut pas prouver ça formellement pour des regex ECMA-262 arbitraires\n// (le problème est PSPACE-complet pour les regex pures, et indécidable avec\n// les extensions comme les backreferences).\n//\n// Approche pragmatique :\n// 1. Générer N strings aléatoires matchant le pattern sub (via `randexp`)\n// 2. Vérifier que CHAQUE string matche aussi le pattern sup\n// 3. Si toutes matchent → retourner `true` (confiance haute)\n// 4. Si au moins une ne matche pas → retourner `false` (certain)\n// 5. Si la génération échoue → retourner `null` (indéterminé)\n//\n// Limites :\n// - Faux positifs possibles (mais très improbables avec N suffisant)\n// - Ne gère pas les regex avec backreferences complexes\n// - `randexp` peut générer des strings biaisées (pas uniformément distribuées)\n//\n// Pour mitiger les faux positifs, on utilise :\n// - Un nombre d'échantillons élevé (200 par défaut)\n// - Plusieurs seeds pour diversifier la génération\n// - Un fallback `null` en cas de doute\n\n// ─── Configuration ───────────────────────────────────────────────────────────\n\n/** Nombre d'échantillons générés par défaut */\nconst DEFAULT_SAMPLE_COUNT = 200;\n\n/** Longueur maximale des strings générées par randexp */\nconst MAX_GENERATED_LENGTH = 100;\n\n/** Nombre maximal de répétitions pour les quantificateurs unbounded (*, +, {n,}) */\nconst MAX_REPETITION = 20;\n\n// ─── Result Cache ────────────────────────────────────────────────────────────\n\n/**\n * Cache des résultats de isPatternSubset pour éviter de recalculer\n * les mêmes comparaisons. La clé est `${subPattern}\\0${supPattern}\\0${sampleCount}`.\n */\nconst subsetCache = new Map<string, boolean | null>();\n\n/**\n * Cache des résultats de compilation RegExp pour éviter les recompilations.\n */\nconst regexCache = new Map<string, RegExp | null>();\n\n/**\n * Cache des générateurs RandExp pour éviter les re-créations.\n */\nconst generatorCache = new Map<string, RandExp | null>();\n\n/**\n * Vide les caches internes. Utile pour les tests ou la gestion mémoire.\n */\nexport function clearPatternCaches(): void {\n\tsubsetCache.clear();\n\tregexCache.clear();\n\tgeneratorCache.clear();\n}\n\n// ─── Trivial pattern detection (module-level constants) ──────────────────────\n\n/**\n * Patterns universels connus — matchent toute string (ou presque).\n * Défini au niveau du module pour éviter de recréer le Set à chaque appel.\n */\nconst UNIVERSAL_PATTERNS: ReadonlySet<string> = new Set([\n\t\".*\",\n\t\".+\",\n\t\"^.*$\",\n\t\"^.+$\",\n\t\"^.*\",\n\t\".*$\",\n\t\"^.+\",\n\t\".+$\",\n\t\"(?:.*)\",\n\t\"(?:.+)\",\n]);\n\n/**\n * Patterns anchored universal — variantes fréquentes qui matchent tout.\n * Utilisé pour la détection rapide de superset universels.\n */\nconst _ANCHORED_UNIVERSAL_REGEX =\n\t/^\\^?\\(?:\\.\\*\\)?\\$?$|^\\^?\\.\\*\\$?$|^\\^?\\.\\+\\$?$/;\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\n/**\n * Crée un générateur RandExp configuré pour un pattern donné (avec cache).\n *\n * @param pattern Le pattern regex source\n * @returns L'instance RandExp configurée, ou null si le pattern est invalide\n */\nfunction createGenerator(pattern: string): RandExp | null {\n\tconst cached = generatorCache.get(pattern);\n\tif (cached !== undefined) return cached;\n\n\ttry {\n\t\tconst randexp = new RandExp(pattern);\n\t\trandexp.max = MAX_REPETITION;\n\t\tgeneratorCache.set(pattern, randexp);\n\t\treturn randexp;\n\t} catch {\n\t\tgeneratorCache.set(pattern, null);\n\t\treturn null;\n\t}\n}\n\n/**\n * Compile un pattern en RegExp avec gestion d'erreur et cache.\n *\n * @param pattern Le pattern regex à compiler\n * @returns L'objet RegExp compilé, ou null si invalide\n */\nfunction compileRegex(pattern: string): RegExp | null {\n\tconst cached = regexCache.get(pattern);\n\tif (cached !== undefined) return cached;\n\n\ttry {\n\t\tconst regex = new RegExp(pattern);\n\t\tregexCache.set(pattern, regex);\n\t\treturn regex;\n\t} catch {\n\t\tregexCache.set(pattern, null);\n\t\treturn null;\n\t}\n}\n\n/**\n * Vérifie si un pattern est un superset universel (matche tout).\n * Utilisé pour court-circuiter le sampling quand sup matche tout.\n */\nfunction isUniversalSuperset(pattern: string): boolean {\n\tconst trimmed = pattern.trim();\n\tif (trimmed === \"\" || UNIVERSAL_PATTERNS.has(trimmed)) return true;\n\n\t// Vérifier des variantes avec anchors optionnels\n\t// Ex: \"^(.*)$\", \"^(.+)$\" etc.\n\tif (trimmed === \"^(.*)$\" || trimmed === \"^(.+)$\") return true;\n\n\treturn false;\n}\n\n/**\n * Vérifie si subPattern est un sous-string littéral de supPattern\n * ou si le sup est clairement plus large (heuristiques rapides).\n * Retourne true si sub ⊆ sup est garanti, false sinon.\n */\nfunction quickSubsetCheck(\n\t_subPattern: string,\n\tsupPattern: string,\n): boolean | null {\n\t// Si sup est universel → tout est un sous-ensemble\n\tif (isUniversalSuperset(supPattern)) return true;\n\n\t// Si sub est un pattern littéral exact (anchored string sans métacaractères)\n\t// et que sup contient une classe de caractères ou quantificateur qui l'englobe,\n\t// on ne peut pas le déterminer facilement → null\n\treturn null;\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Vérifie si le langage du pattern `sub` est un sous-ensemble du langage\n * du pattern `sup` via échantillonnage.\n *\n * `sub ⊆ sup` signifie : toute string matchant `sub` matche aussi `sup`.\n *\n * Contrat ternaire :\n * - `true` → toutes les strings échantillonnées de sub matchent sup\n * (confiance haute, pas une preuve formelle)\n * - `false` → au moins une string de sub ne matche PAS sup\n * (certain — c'est un contre-exemple concret)\n * - `null` → impossible de déterminer (pattern invalide, génération échouée)\n *\n * @param subPattern Le pattern regex du schema sub\n * @param supPattern Le pattern regex du schema sup\n * @param sampleCount Nombre d'échantillons (défaut: 200)\n * @returns `true`, `false`, ou `null`\n *\n * @example\n * ```ts\n * isPatternSubset(\"^[a-z]{3}$\", \"^[a-z]+$\"); // true — 3 lettres ⊆ 1+ lettres\n * isPatternSubset(\"^[a-z]+$\", \"^[0-9]+$\"); // false — lettres ⊄ chiffres\n * isPatternSubset(\"^[a-z]+$\", \"^[a-z]{3}$\"); // false — \"ab\" matche sub mais pas sup\n * isPatternSubset(\"invalid[\", \"^[a-z]+$\"); // null — pattern invalide\n * ```\n */\nexport function isPatternSubset(\n\tsubPattern: string,\n\tsupPattern: string,\n\tsampleCount: number = DEFAULT_SAMPLE_COUNT,\n): boolean | null {\n\t// ── Identité : même pattern → toujours subset ──\n\tif (subPattern === supPattern) return true;\n\n\t// ── Cache lookup ──\n\tconst cacheKey = `${subPattern}\\0${supPattern}\\0${sampleCount}`;\n\tconst cached = subsetCache.get(cacheKey);\n\tif (cached !== undefined) return cached;\n\n\t// ── Quick checks avant le sampling ──\n\tconst quick = quickSubsetCheck(subPattern, supPattern);\n\tif (quick !== null) {\n\t\tsubsetCache.set(cacheKey, quick);\n\t\treturn quick;\n\t}\n\n\t// ── Compiler le pattern sup ──\n\tconst supRegex = compileRegex(supPattern);\n\tif (supRegex === null) {\n\t\tsubsetCache.set(cacheKey, null);\n\t\treturn null;\n\t}\n\n\t// ── Créer le générateur pour sub ──\n\tconst generator = createGenerator(subPattern);\n\tif (generator === null) {\n\t\tsubsetCache.set(cacheKey, null);\n\t\treturn null;\n\t}\n\n\t// ── Générer et vérifier les échantillons paresseusement ──\n\t// Au lieu de générer tous les échantillons d'abord puis les vérifier,\n\t// on génère et vérifie un par un pour permettre un arrêt précoce\n\t// dès qu'un contre-exemple est trouvé.\n\tconst seen = new Set<string>();\n\tlet validSamples = 0;\n\tlet attempts = 0;\n\tconst maxAttempts = sampleCount * 3; // Éviter les boucles infinies\n\n\twhile (validSamples < sampleCount && attempts < maxAttempts) {\n\t\tattempts++;\n\t\tconst sample = generator.gen();\n\n\t\t// Valider que l'échantillon est utilisable\n\t\tif (typeof sample !== \"string\" || sample.length > MAX_GENERATED_LENGTH) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Dédupliquer les échantillons\n\t\tif (seen.has(sample)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(sample);\n\t\tvalidSamples++;\n\n\t\t// ── Vérification immédiate contre sup ──\n\t\t// Arrêt précoce dès qu'un contre-exemple est trouvé\n\t\tif (!supRegex.test(sample)) {\n\t\t\t// Contre-exemple trouvé → sub ⊄ sup (certain)\n\t\t\tsubsetCache.set(cacheKey, false);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Si aucun échantillon n'a pu être généré → indéterminé\n\tif (validSamples === 0) {\n\t\tsubsetCache.set(cacheKey, null);\n\t\treturn null;\n\t}\n\n\t// Tous les échantillons matchent → sub ⊆ sup (confiance haute)\n\tsubsetCache.set(cacheKey, true);\n\treturn true;\n}\n\n/**\n * Vérifie si deux patterns sont équivalents (acceptent le même langage)\n * via échantillonnage bidirectionnel.\n *\n * `A ≡ B` signifie : `A ⊆ B` ET `B ⊆ A`.\n *\n * @param patternA Premier pattern regex\n * @param patternB Second pattern regex\n * @param sampleCount Nombre d'échantillons par direction (défaut: 200)\n * @returns `true`, `false`, ou `null`\n */\nexport function arePatternsEquivalent(\n\tpatternA: string,\n\tpatternB: string,\n\tsampleCount: number = DEFAULT_SAMPLE_COUNT,\n): boolean | null {\n\tif (patternA === patternB) return true;\n\n\tconst aSubB = isPatternSubset(patternA, patternB, sampleCount);\n\tif (aSubB === null) return null;\n\tif (aSubB === false) return false;\n\n\tconst bSubA = isPatternSubset(patternB, patternA, sampleCount);\n\tif (bSubA === null) return null;\n\n\treturn bSubA;\n}\n\n/**\n * Vérifie si un pattern est \"trivially universal\" — i.e., il matche\n * toute string (ou presque). Utile pour détecter les patterns qui\n * n'ajoutent aucune contrainte réelle.\n *\n * Patterns détectés comme universels :\n * - `.*`\n * - `.+` (matche tout sauf la string vide)\n * - `^.*$`\n * - `^.+$`\n * - Patterns vides ou whitespace\n *\n * @param pattern Le pattern à vérifier\n * @returns `true` si le pattern est trivial/universel\n */\nexport function isTrivialPattern(pattern: string): boolean {\n\tconst trimmed = pattern.trim();\n\tif (trimmed === \"\") return true;\n\n\treturn UNIVERSAL_PATTERNS.has(trimmed);\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "8A1D1F55B4FF298064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function X(w){return typeof w==="object"&&w!==null&&!Array.isArray(w)}function Y(w,B){return Object.hasOwn(w,B)}function R(w,B){if(w===B)return!0;if(w===null||B===null)return!1;if(typeof w!==typeof B)return!1;if(typeof w==="object"){if(Array.isArray(w)){if(!Array.isArray(B))return!1;let C=w.length;if(C!==B.length)return!1;for(let G=0;G<C;G++)if(!R(w[G],B[G]))return!1;return!0}if(Array.isArray(B))return!1;let M=w,H=B,I=Object.keys(M),F=Object.keys(H);if(I.length!==F.length)return!1;for(let C of I)if(!(C in H)||!R(M[C],H[C]))return!1;return!0}return!1}function Z(w,B){if(B.length<=2){let F=B[0],C=B[1],G=F!==void 0&&F in w,P=C!==void 0&&C in w;if(!G&&!P)return w;let U={};for(let Q of Object.keys(w))if(Q!==F&&Q!==C)U[Q]=w[Q];return U}let M=new Set(B),H=!1;for(let F of B)if(F in w){H=!0;break}if(!H)return w;let I={};for(let F of Object.keys(w))if(!M.has(F))I[F]=w[F];return I}function _(w,B){let M=w.length,H=B.length;if(H===0)return w;if(M===0)return B;if(M+H<=8){let C=w.slice();for(let G=0;G<H;G++){let P=B[G];if(P!==void 0&&!C.includes(P))C.push(P)}return C.length===M?w:C}let I=new Set(w),F=I.size;for(let C=0;C<H;C++){let G=B[C];if(G!==void 0)I.add(G)}if(I.size===F&&F===M)return w;return Array.from(I)}function $(w,B){return R(w,B)}
|
|
2
|
-
export{X as
|
|
2
|
+
export{X as x,Y as y,R as z,Z as A,_ as B,$ as C};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
5
|
-
//# sourceMappingURL=chunk-
|
|
4
|
+
//# debugId=2E06072FE3BC442664756E2164756E21
|
|
5
|
+
//# sourceMappingURL=chunk-w1ypc97a.js.map
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"import type { JSONSchema7Definition } from \"json-schema\";\n\n// ─── Shared Utilities ────────────────────────────────────────────────────────\n//\n// Fonctions utilitaires natives partagées entre tous les modules.\n// Centralisées ici pour éviter la duplication et permettre à V8\n// d'optimiser une seule instance de chaque fonction hot-path.\n\n/**\n * Vérifie si une valeur est un plain object (pas null, pas un array).\n */\nexport function isPlainObj(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Vérifie si un objet possède une propriété propre.\n */\nexport function hasOwn(obj: object, key: string): boolean {\n\treturn Object.hasOwn(obj, key);\n}\n\n/**\n * Compare deux valeurs en profondeur (deep equality).\n *\n * Optimisations :\n * - Reference equality short-circuit (a === b)\n * - Length checks avant l'itération (arrays et objects)\n * - Pas de support pour Date, RegExp, Map, Set (pas nécessaire pour JSON Schema)\n */\nexport function deepEqual(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\n\tif (typeof a === \"object\") {\n\t\tif (Array.isArray(a)) {\n\t\t\tif (!Array.isArray(b)) return false;\n\t\t\tconst len = a.length;\n\t\t\tif (len !== b.length) return false;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tif (!deepEqual(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\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\tconst bKeys = Object.keys(bObj);\n\t\tif (aKeys.length !== bKeys.length) return false;\n\t\tfor (const key of aKeys) {\n\t\t\tif (!(key in bObj) || !deepEqual(aObj[key], bObj[key])) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Crée une copie d'un objet sans les clés spécifiées.\n *\n * Optimisé pour le cas courant (1-2 clés à omettre) :\n * - Utilise un Set uniquement si > 2 clés\n * - Itère une seule fois sur l'objet source\n * - Retourne l'original si aucune clé à omettre n'est présente dans l'objet\n */\nexport function omitKeys<T extends Record<string, unknown>>(\n\tobj: T,\n\tkeysToOmit: string[],\n): T {\n\t// Fast path: check if any key to omit actually exists in the object\n\tif (keysToOmit.length <= 2) {\n\t\tconst k0 = keysToOmit[0];\n\t\tconst k1 = keysToOmit[1];\n\t\tconst has0 = k0 !== undefined && k0 in obj;\n\t\tconst has1 = k1 !== undefined && k1 in obj;\n\t\tif (!has0 && !has1) return obj;\n\n\t\tconst result: Record<string, unknown> = {};\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tif (key !== k0 && key !== k1) {\n\t\t\t\tresult[key] = obj[key];\n\t\t\t}\n\t\t}\n\t\treturn result as T;\n\t}\n\n\tconst omitSet = new Set(keysToOmit);\n\n\t// Check if any key to omit exists\n\tlet hasAny = false;\n\tfor (const key of keysToOmit) {\n\t\tif (key in obj) {\n\t\t\thasAny = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!hasAny) return obj;\n\n\tconst result: Record<string, unknown> = {};\n\tfor (const key of Object.keys(obj)) {\n\t\tif (!omitSet.has(key)) {\n\t\t\tresult[key] = obj[key];\n\t\t}\n\t}\n\treturn result as T;\n}\n\n/**\n * Fusionne deux tableaux de strings en éliminant les doublons.\n * Retourne un tableau avec les éléments uniques des deux sources.\n *\n * Optimisé avec fast paths pour les cas courants :\n * - Si b est vide → retourne a directement\n * - Si a est vide → retourne b directement\n * - Pour les petits tableaux (≤ 8 éléments total), utilise\n * une boucle avec includes au lieu de créer un Set\n */\nexport function unionStrings(a: string[], b: string[]): string[] {\n\tconst aLen = a.length;\n\tconst bLen = b.length;\n\n\t// Fast paths for empty arrays\n\tif (bLen === 0) return a;\n\tif (aLen === 0) return b;\n\n\t// Fast path for small arrays: avoid Set allocation overhead\n\tif (aLen + bLen <= 8) {\n\t\tconst result = a.slice();\n\t\tfor (let i = 0; i < bLen; i++) {\n\t\t\tconst item = b[i];\n\t\t\tif (item !== undefined && !result.includes(item)) {\n\t\t\t\tresult.push(item);\n\t\t\t}\n\t\t}\n\t\t// If nothing was added from b (all items already in a), return a\n\t\treturn result.length === aLen ? a : result;\n\t}\n\n\t// General case: use Set for larger arrays\n\tconst set = new Set(a);\n\tconst initialSize = set.size;\n\tfor (let i = 0; i < bLen; i++) {\n\t\tconst item = b[i];\n\t\tif (item !== undefined) set.add(item);\n\t}\n\n\t// If nothing new was added, return a directly\n\tif (set.size === initialSize && initialSize === aLen) return a;\n\n\treturn Array.from(set);\n}\n\n/**\n * Vérifie l'égalité structurelle entre deux JSONSchema7Definition.\n * Wrapper typé autour de deepEqual pour les schemas.\n */\nexport function schemaDeepEqual(\n\ta: JSONSchema7Definition,\n\tb: JSONSchema7Definition,\n): boolean {\n\treturn deepEqual(a, b);\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "AAWO,SAAS,CAAU,CAAC,EAAkD,CAC5E,OAAO,OAAO,IAAU,UAAY,IAAU,MAAQ,CAAC,MAAM,QAAQ,CAAK,EAMpE,SAAS,CAAM,CAAC,EAAa,EAAsB,CACzD,OAAO,OAAO,OAAO,EAAK,CAAG,EAWvB,SAAS,CAAS,CAAC,EAAY,EAAqB,CAC1D,GAAI,IAAM,EAAG,MAAO,GACpB,GAAI,IAAM,MAAQ,IAAM,KAAM,MAAO,GACrC,GAAI,OAAO,IAAM,OAAO,EAAG,MAAO,GAElC,GAAI,OAAO,IAAM,SAAU,CAC1B,GAAI,MAAM,QAAQ,CAAC,EAAG,CACrB,GAAI,CAAC,MAAM,QAAQ,CAAC,EAAG,MAAO,GAC9B,IAAM,EAAM,EAAE,OACd,GAAI,IAAQ,EAAE,OAAQ,MAAO,GAC7B,QAAS,EAAI,EAAG,EAAI,EAAK,IACxB,GAAI,CAAC,EAAU,EAAE,GAAI,EAAE,EAAE,EAAG,MAAO,GAEpC,MAAO,GAER,GAAI,MAAM,QAAQ,CAAC,EAAG,MAAO,GAE7B,IAAM,EAAO,EACP,EAAO,EACP,EAAQ,OAAO,KAAK,CAAI,EACxB,EAAQ,OAAO,KAAK,CAAI,EAC9B,GAAI,EAAM,SAAW,EAAM,OAAQ,MAAO,GAC1C,QAAW,KAAO,EACjB,GAAI,EAAE,KAAO,IAAS,CAAC,EAAU,EAAK,GAAM,EAAK,EAAI,EAAG,MAAO,GAEhE,MAAO,GAGR,MAAO,GAWD,SAAS,CAA2C,CAC1D,EACA,EACI,CAEJ,GAAI,EAAW,QAAU,EAAG,CAC3B,IAAM,EAAK,EAAW,GAChB,EAAK,EAAW,GAChB,EAAO,IAAO,QAAa,KAAM,EACjC,EAAO,IAAO,QAAa,KAAM,EACvC,GAAI,CAAC,GAAQ,CAAC,EAAM,OAAO,EAE3B,IAAM,EAAkC,CAAC,EACzC,QAAW,KAAO,OAAO,KAAK,CAAG,EAChC,GAAI,IAAQ,GAAM,IAAQ,EACzB,EAAO,GAAO,EAAI,GAGpB,OAAO,EAGR,IAAM,EAAU,IAAI,IAAI,CAAU,EAG9B,EAAS,GACb,QAAW,KAAO,EACjB,GAAI,KAAO,EAAK,CACf,EAAS,GACT,MAGF,GAAI,CAAC,EAAQ,OAAO,EAEpB,IAAM,EAAkC,CAAC,EACzC,QAAW,KAAO,OAAO,KAAK,CAAG,EAChC,GAAI,CAAC,EAAQ,IAAI,CAAG,EACnB,EAAO,GAAO,EAAI,GAGpB,OAAO,EAaD,SAAS,CAAY,CAAC,EAAa,EAAuB,CAChE,IAAM,EAAO,EAAE,OACT,EAAO,EAAE,OAGf,GAAI,IAAS,EAAG,OAAO,EACvB,GAAI,IAAS,EAAG,OAAO,EAGvB,GAAI,EAAO,GAAQ,EAAG,CACrB,IAAM,EAAS,EAAE,MAAM,EACvB,QAAS,EAAI,EAAG,EAAI,EAAM,IAAK,CAC9B,IAAM,EAAO,EAAE,GACf,GAAI,IAAS,QAAa,CAAC,EAAO,SAAS,CAAI,EAC9C,EAAO,KAAK,CAAI,EAIlB,OAAO,EAAO,SAAW,EAAO,EAAI,EAIrC,IAAM,EAAM,IAAI,IAAI,CAAC,EACf,EAAc,EAAI,KACxB,QAAS,EAAI,EAAG,EAAI,EAAM,IAAK,CAC9B,IAAM,EAAO,EAAE,GACf,GAAI,IAAS,OAAW,EAAI,IAAI,CAAI,EAIrC,GAAI,EAAI,OAAS,GAAe,IAAgB,EAAM,OAAO,EAE7D,OAAO,MAAM,KAAK,CAAG,EAOf,SAAS,CAAe,CAC9B,EACA,EACU,CACV,OAAO,EAAU,EAAG,CAAC",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "2E06072FE3BC442664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{
|
|
2
|
-
export{T as
|
|
1
|
+
import{x as N,y as W,z as F}from"./chunk-w1ypc97a.js";var j=new WeakMap;function T(J){if(J===null)return"null";switch(typeof J){case"string":return"string";case"number":return Number.isInteger(J)?"integer":"number";case"boolean":return"boolean";case"object":return Array.isArray(J)?"array":"object";default:return}}var _=["additionalProperties","additionalItems","contains","propertyNames","not","if","then","else"],R=new Set(["$id","$schema","$comment","title","description","default","examples","definitions","$defs"]);function A(J){return Object.keys(J).every((x)=>x==="not"||R.has(x))}var D=["anyOf","oneOf","allOf"],K=["properties","patternProperties"];function P(J){let Z=Object.keys(J),x=!1;for(let Q=0;Q<Z.length;Q++){let G=Z[Q];if(G===void 0)continue;let I=J[G];if(M(I)!==I){x=!0;break}}if(!x)return J;let L={};for(let Q=0;Q<Z.length;Q++){let G=Z[Q];if(G===void 0)continue;L[G]=M(J[G])}return L}function w(J){if(!W(J,"const")||J.type!==void 0)return;let Z=T(J.const);return Z?Z:void 0}function E(J){if(!Array.isArray(J.enum)||J.type!==void 0)return;let Z=new Set;for(let Q of J.enum){let G=T(Q);if(G)Z.add(G)}let x=Z.size;if(x===0)return;let L=Array.from(Z);if(x===1)return L[0];return L}function M(J){if(typeof J==="boolean")return J;let Z=j.get(J);if(Z!==void 0)return Z;let x=J,L=!1;function Q(){if(!L)x={...J},L=!0;return x}let G=w(x);if(G)Q().type=G;let I=E(x);if(I)Q().type=I;if(Array.isArray(x.enum)&&x.enum.length===1&&!W(x,"const")){let B=Q();B.const=x.enum[0],delete B.enum}if(W(x,"const")&&Array.isArray(x.enum)){if(x.enum.some((B)=>F(B,x.const)))delete Q().enum}for(let B of K){let U=x[B];if(N(U)){let V=P(U);if(V!==U)Q()[B]=V}}if(N(x.dependencies)){let B=x.dependencies,U=Object.keys(B),V=!1,$={};for(let q=0;q<U.length;q++){let X=U[q];if(X===void 0)continue;let H=B[X];if(H===void 0)continue;if(Array.isArray(H))$[X]=H;else if(N(H)){let Y=M(H);if($[X]=Y,Y!==H)V=!0}else $[X]=H}if(V)Q().dependencies=$}if(x.items){if(Array.isArray(x.items)){let B=x.items,U=!1,V=Array(B.length);for(let $=0;$<B.length;$++){let q=B[$];if(q===void 0)continue;let X=M(q);if(V[$]=X,X!==q)U=!0}if(U)Q().items=V}else if(N(x.items)){let B=M(x.items);if(B!==x.items)Q().items=B}}for(let B of _){let U=x[B];if(U!==void 0&&typeof U!=="boolean"){let V=M(U);if(V!==U)Q()[B]=V}}if(W(x,"not")&&N(x.not)&&typeof x.not!=="boolean"){let B=x.not;if(W(B,"not")&&A(B)&&N(B.not)&&typeof B.not!=="boolean"){let U=B.not,V=Q();delete V.not;let $=Object.keys(U);for(let q=0;q<$.length;q++){let X=$[q];if(X===void 0)continue;V[X]=U[X]}}}for(let B of D){let U=x[B];if(Array.isArray(U)){let V=U,$=!1,q=Array(V.length);for(let X=0;X<V.length;X++){let H=V[X];if(H===void 0)continue;let Y=M(H);if(q[X]=Y,Y!==H)$=!0}if($)Q()[B]=q}}let b=L?x:J;return j.set(J,b),b}
|
|
2
|
+
export{T as v,M as w};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
5
|
-
//# sourceMappingURL=chunk-
|
|
4
|
+
//# debugId=22F563921815E14364756E2164756E21
|
|
5
|
+
//# sourceMappingURL=chunk-ywa6h8q4.js.map
|
|
@@ -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": "
|
|
8
|
+
"debugId": "22F563921815E14364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
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};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=97768507FF79B49E64756E2164756E21
|
|
4
4
|
//# sourceMappingURL=condition-resolver.js.map
|
package/dist/differ.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{m as a}from"./chunk-k92ftyzf.js";import"./chunk-w1ypc97a.js";export{a as computeDiffs};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=3AA728193DF7D13364756E2164756E21
|
|
4
4
|
//# sourceMappingURL=differ.js.map
|
package/dist/differ.js.map
CHANGED
package/dist/format-validator.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
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};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=B906A1D671DC9C0E64756E2164756E21
|
|
4
4
|
//# sourceMappingURL=format-validator.js.map
|
package/dist/formatter.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import type { SemanticDiff } from "./semantic-diff/types";
|
|
1
2
|
import type { SubsetResult } from "./types";
|
|
2
3
|
/**
|
|
3
4
|
* Formate un SubsetResult en chaîne lisible (utile pour logs/debug).
|
|
4
5
|
*
|
|
6
|
+
* Affiche les diffs sémantiques en priorité (si disponibles),
|
|
7
|
+
* avec un fallback sur les diffs structurelles.
|
|
8
|
+
*
|
|
5
9
|
* @param label Label descriptif du check (ex: "strict ⊆ loose")
|
|
6
10
|
* @param result Le résultat du check à formater
|
|
7
11
|
* @returns Chaîne multi-lignes formatée avec icônes et diffs
|
|
@@ -15,8 +19,16 @@ import type { SubsetResult } from "./types";
|
|
|
15
19
|
* ```
|
|
16
20
|
* ❌ loose ⊆ strict: false
|
|
17
21
|
* Diffs:
|
|
18
|
-
*
|
|
19
|
-
* + properties.age: {"type":"number"}
|
|
22
|
+
* 🔴 [missing-required-property] Target requires property 'meetingId' (string) which source does not provide
|
|
20
23
|
* ```
|
|
21
24
|
*/
|
|
22
25
|
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{
|
|
1
|
+
import{n as a,o as b}from"./chunk-8qenxa2z.js";export{b as formatSemanticDiffs,a as formatResult};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=8FA4D81514C1E38064756E2164756E21
|
|
4
4
|
//# sourceMappingURL=formatter.js.map
|
package/dist/formatter.js.map
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export { formatSemanticDiffs } from "./formatter";
|
|
1
2
|
export { JsonSchemaCompatibilityChecker } from "./json-schema-compatibility-checker";
|
|
2
3
|
export { MergeEngine } from "./merge-engine";
|
|
3
4
|
export { arePatternsEquivalent, isPatternSubset, isTrivialPattern, } from "./pattern-subset";
|
|
5
|
+
export type { SemanticDiff, SemanticDiffType } from "./semantic-diff";
|
|
6
|
+
export { computeSemanticDiffs } from "./semantic-diff";
|
|
4
7
|
export type { ConnectionResult, ResolvedConditionResult, SchemaDiff, SubsetResult, } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as
|
|
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};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=302300B8000AAAE564756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as h}from"./chunk-
|
|
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};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=027205FF920F7D0864756E2164756E21
|
|
4
4
|
//# sourceMappingURL=json-schema-compatibility-checker.js.map
|
package/dist/merge-engine.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{p as a}from"./chunk-etwjsbj3.js";import"./chunk-gdf3h8q4.js";import"./chunk-w1ypc97a.js";export{a as MergeEngine};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=4B6A36C3676677B164756E2164756E21
|
|
4
4
|
//# sourceMappingURL=merge-engine.js.map
|
package/dist/merge-engine.js.map
CHANGED
package/dist/normalizer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{v as a,w as b}from"./chunk-ywa6h8q4.js";import"./chunk-w1ypc97a.js";export{b as normalize,a as inferType};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=5721562EAFC36DF764756E2164756E21
|
|
4
4
|
//# sourceMappingURL=normalizer.js.map
|
package/dist/normalizer.js.map
CHANGED
package/dist/pattern-subset.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
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};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=9CE3C9594A63700F64756E2164756E21
|
|
4
4
|
//# sourceMappingURL=pattern-subset.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { JSONSchema7Definition } from "json-schema";
|
|
2
|
+
import type { SchemaDiff } from "../types";
|
|
3
|
+
import type { SemanticDiff } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Transforme les diffs structurelles en diffs sémantiques.
|
|
6
|
+
*
|
|
7
|
+
* @param sub Le schema source (sourceOutput)
|
|
8
|
+
* @param sup Le schema target (targetInput)
|
|
9
|
+
* @param structuralDiffs Les diffs brutes produites par `computeDiffs`
|
|
10
|
+
* @returns Tableau de SemanticDiff lisibles et actionnables
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const semanticDiffs = computeSemanticDiffs(sourceSchema, targetSchema, rawDiffs);
|
|
15
|
+
* // [
|
|
16
|
+
* // {
|
|
17
|
+
* // type: 'missing-required-property',
|
|
18
|
+
* // path: 'properties.meetingId',
|
|
19
|
+
* // message: "Target requires property 'meetingId' (string) which source does not provide",
|
|
20
|
+
* // details: { property: 'meetingId', targetSchema: { type: 'string' } }
|
|
21
|
+
* // }
|
|
22
|
+
* // ]
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeSemanticDiffs(sub: JSONSchema7Definition, sup: JSONSchema7Definition, structuralDiffs: SchemaDiff[]): SemanticDiff[];
|