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.
Files changed (59) hide show
  1. package/dist/chunk-8me729r7.js +5 -0
  2. package/dist/chunk-8me729r7.js.map +12 -0
  3. package/dist/chunk-8qenxa2z.js +7 -0
  4. package/dist/chunk-8qenxa2z.js.map +10 -0
  5. package/dist/{chunk-pyrx217p.js → chunk-ayae82am.js} +4 -4
  6. package/dist/{chunk-pyrx217p.js.map → chunk-ayae82am.js.map} +1 -1
  7. package/dist/chunk-etwjsbj3.js +5 -0
  8. package/dist/{chunk-yg81ax5m.js.map → chunk-etwjsbj3.js.map} +2 -2
  9. package/dist/{chunk-07z7fc5q.js → chunk-gdf3h8q4.js} +3 -3
  10. package/dist/{chunk-07z7fc5q.js.map → chunk-gdf3h8q4.js.map} +1 -1
  11. package/dist/chunk-jy9206ze.js +5 -0
  12. package/dist/chunk-jy9206ze.js.map +10 -0
  13. package/dist/chunk-k92ftyzf.js +5 -0
  14. package/dist/chunk-k92ftyzf.js.map +10 -0
  15. package/dist/{chunk-q7kq4fgq.js → chunk-mfe3cw5r.js} +3 -3
  16. package/dist/{chunk-q7kq4fgq.js.map → chunk-mfe3cw5r.js.map} +1 -1
  17. package/dist/{chunk-jkdzdb3r.js → chunk-w1ypc97a.js} +3 -3
  18. package/dist/{chunk-jkdzdb3r.js.map → chunk-w1ypc97a.js.map} +1 -1
  19. package/dist/{chunk-yqhv3py7.js → chunk-ywa6h8q4.js} +4 -4
  20. package/dist/{chunk-yqhv3py7.js.map → chunk-ywa6h8q4.js.map} +1 -1
  21. package/dist/condition-resolver.js +2 -2
  22. package/dist/condition-resolver.js.map +1 -1
  23. package/dist/differ.js +2 -2
  24. package/dist/differ.js.map +1 -1
  25. package/dist/format-validator.js +2 -2
  26. package/dist/format-validator.js.map +1 -1
  27. package/dist/formatter.d.ts +14 -2
  28. package/dist/formatter.js +2 -2
  29. package/dist/formatter.js.map +1 -1
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.js +2 -2
  32. package/dist/index.js.map +1 -1
  33. package/dist/json-schema-compatibility-checker.js +2 -2
  34. package/dist/json-schema-compatibility-checker.js.map +1 -1
  35. package/dist/merge-engine.js +2 -2
  36. package/dist/merge-engine.js.map +1 -1
  37. package/dist/normalizer.js +2 -2
  38. package/dist/normalizer.js.map +1 -1
  39. package/dist/pattern-subset.js +2 -2
  40. package/dist/pattern-subset.js.map +1 -1
  41. package/dist/semantic-diff/analyzer.d.ts +25 -0
  42. package/dist/semantic-diff/detectors.d.ts +79 -0
  43. package/dist/semantic-diff/index.d.ts +3 -0
  44. package/dist/semantic-diff/types.d.ts +81 -0
  45. package/dist/subset-checker.js +2 -2
  46. package/dist/subset-checker.js.map +1 -1
  47. package/dist/types.d.ts +6 -3
  48. package/dist/utils.js +2 -2
  49. package/dist/utils.js.map +1 -1
  50. package/package.json +48 -48
  51. package/dist/chunk-2ddbnbyq.js +0 -5
  52. package/dist/chunk-2ddbnbyq.js.map +0 -10
  53. package/dist/chunk-b55zsn5n.js +0 -5
  54. package/dist/chunk-b55zsn5n.js.map +0 -10
  55. package/dist/chunk-jybaxgmh.js +0 -5
  56. package/dist/chunk-jybaxgmh.js.map +0 -10
  57. package/dist/chunk-y8c2z1m3.js +0 -6
  58. package/dist/chunk-y8c2z1m3.js.map +0 -10
  59. package/dist/chunk-yg81ax5m.js +0 -5
@@ -0,0 +1,5 @@
1
+ import{i as k}from"./chunk-mfe3cw5r.js";import{m as a}from"./chunk-k92ftyzf.js";import{u as o}from"./chunk-gdf3h8q4.js";import{w as v}from"./chunk-ywa6h8q4.js";import{A as M,x as F,y as I,z as V}from"./chunk-w1ypc97a.js";function K(G){if(Array.isArray(G))return G.join(" | ");if(G===void 0||G===null)return"any";return String(G)}function p(G){if(typeof G==="boolean")return G?"any":"never";if(typeof G!=="object"||G===null)return"unknown";let $=G;if($.const!==void 0)return`const(${JSON.stringify($.const)})`;if($.enum)return`enum(${JSON.stringify($.enum)})`;if($.type)return K($.type);return"object"}function P(G,$,x,Q){let H=[],Z=G.properties||{},J=$.properties||{},W=new Set($.required||[]);for(let U=0;U<x.length;U++){if(Q.has(U))continue;let X=x[U];if(X===void 0)continue;let j=X.path.match(/^properties\.([^.]+)$/);if(!j)continue;let _=j[1];if(_===void 0)continue;if(X.type==="added"&&W.has(_)&&!(_ in Z)){let Y=J[_];H.push({type:"missing-required-property",path:`properties.${_}`,message:`Target requires property '${_}' (${p(Y)}) which source does not provide`,details:{property:_,targetSchema:Y??null}}),Q.add(U)}}if(H.length>0)for(let U=0;U<x.length;U++){if(Q.has(U))continue;let X=x[U];if(X===void 0)continue;if(X.path==="required"&&X.type==="changed"){Q.add(U);break}}return H}function y(G,$,x,Q){let H=[],Z=new Set(G.required||[]),J=new Set($.required||[]),W=G.properties||{};for(let U of J){if(Z.has(U))continue;if(U in W)H.push({type:"property-not-guaranteed",path:`properties.${U}`,message:`Property '${U}' is optional in source but required by target`,details:{property:U}})}if(H.length>0)for(let U=0;U<x.length;U++){if(Q.has(U))continue;let X=x[U];if(X===void 0)continue;if(X.path==="required"&&X.type==="changed"){Q.add(U);break}}return H}function l(G,$,x,Q){let H=[];if($.additionalProperties!==!1)return H;let Z=$.properties||{};for(let J=0;J<x.length;J++){if(Q.has(J))continue;let W=x[J];if(W===void 0)continue;let U=W.path.match(/^properties\.([^.]+)$/);if(!U)continue;let X=U[1];if(X===void 0)continue;if(W.type==="removed"&&!(X in Z))H.push({type:"property-not-allowed",path:`properties.${X}`,message:`Source provides property '${X}' which target does not allow`,details:{property:X}}),Q.add(J)}return H}function h(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.type!=="changed"&&J.type!=="added")continue;let W=J.path==="type",U=J.path.match(/^properties\.([^.]+)\.type$/);if(!W&&!U)continue;let X=U?U[1]??null:null,j=X?`properties.${X}`:"",_=X?g(G,X):G.type,Y=X?g($,X):$.type,L=N(_),A=N(Y),z=L.filter((R)=>A.includes(R));if(z.length===0)H.push({type:"type-mismatch",path:j||"type",message:X?`Property '${X}': source produces '${K(_)}' but target expects '${K(Y)}'`:`Source produces '${K(_)}' but target expects '${K(Y)}'`,details:{...X?{property:X}:{},sourceType:_,targetType:Y}});else if(z.length<L.length){let R=L.filter((E)=>!A.includes(E));H.push({type:"type-too-wide",path:j||"type",message:X?`Property '${X}': source can produce '${K(_)}' but target only accepts '${K(Y)}'`:`Source can produce '${K(_)}' but target only accepts '${K(Y)}'`,details:{...X?{property:X}:{},sourceType:_,targetType:Y,extraTypes:R}})}else H.push({type:"type-mismatch",path:j||"type",message:X?`Property '${X}': type changed from '${K(J.sourceValue)}' to '${K(J.mergedValue)}'`:`Type changed from '${K(J.sourceValue)}' to '${K(J.mergedValue)}'`,details:{...X?{property:X}:{},sourceType:J.sourceValue,targetType:J.mergedValue}});Q.add(Z)}return H}function g(G,$){let x=G.properties?.[$];if(typeof x==="object"&&x!==null&&!Array.isArray(x))return x.type;return}function N(G){if(G===void 0)return[];if(Array.isArray(G))return G;return[G]}function m(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.type!=="changed"&&J.type!=="added")continue;let W=J.path==="enum",U=J.path.match(/^properties\.([^.]+)\.enum$/);if(!W&&!U)continue;let X=U?U[1]??null:null,j=X?`properties.${X}`:"",_=X?q(G,X,"enum"):G.enum,Y=X?q($,X,"enum"):$.enum,L=Array.isArray(_)?_:[],A=Array.isArray(Y)?Y:[],z=new Set(A.map((E)=>JSON.stringify(E))),R=L.filter((E)=>!z.has(JSON.stringify(E)));H.push({type:"enum-not-subset",path:j||"enum",message:X?`Property '${X}': source allows ${JSON.stringify(R)} which target does not accept`:`Source allows ${JSON.stringify(R)} which target does not accept`,details:{...X?{property:X}:{},sourceValues:_,targetValues:Y,extraValues:R}}),Q.add(Z)}return H}function c(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.type!=="changed"&&J.type!=="added")continue;let W=J.path==="const",U=J.path.match(/^properties\.([^.]+)\.const$/);if(!W&&!U)continue;let X=U?U[1]??null:null,j=X?`properties.${X}`:"",_=X?q(G,X,"const"):G.const,Y=X?q($,X,"const"):$.const;H.push({type:"const-mismatch",path:j||"const",message:X?`Property '${X}': source produces ${JSON.stringify(_)} but target expects ${JSON.stringify(Y)}`:`Source produces ${JSON.stringify(_)} but target expects ${JSON.stringify(Y)}`,details:{...X?{property:X}:{},sourceConst:_,targetConst:Y}}),Q.add(Z)}return H}var T=new Map([["minimum","minimum value"],["maximum","maximum value"],["exclusiveMinimum","exclusive minimum"],["exclusiveMaximum","exclusive maximum"],["multipleOf","multipleOf"],["minLength","minimum length"],["maxLength","maximum length"],["minItems","minimum items"],["maxItems","maximum items"],["minProperties","minimum properties"],["maxProperties","maximum properties"],["uniqueItems","uniqueItems"]]);function d(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.type!=="changed"&&J.type!=="added")continue;let W=null,U=null;if(T.has(J.path))W=J.path;if(!W){let z=J.path.match(/^properties\.([^.]+)\.(.+)$/);if(z?.[2]&&T.has(z[2]))U=z[1]??null,W=z[2]}if(!W)continue;let X=T.get(W)??W,j=U?`properties.${U}`:"",_=U?q(G,U,W):G[W],Y=U?q($,U,W):$[W],L=_!==void 0?String(_):"none",A=Y!==void 0?String(Y):"none";H.push({type:"constraint-too-loose",path:j||W,message:U?`Property '${U}': source allows ${X}=${L} but target requires ${X}=${A}`:`Source allows ${X}=${L} but target requires ${X}=${A}`,details:{...U?{property:U}:{},constraint:W,sourceValue:_??null,targetValue:Y??null}}),Q.add(Z)}return H}function i(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.path!=="additionalProperties")continue;let W=G.additionalProperties!==!1,U=$.additionalProperties!==!1;H.push({type:"additional-properties-conflict",path:"additionalProperties",message:W&&!U?"Source allows additional properties but target forbids them":`additionalProperties changed from ${JSON.stringify(J.sourceValue)} to ${JSON.stringify(J.mergedValue)}`,details:{sourceAllows:W,targetAllows:U}}),Q.add(Z)}return H}function n(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(!J.path.startsWith("items"))continue;let W=J.path==="items"?"":J.path.slice(6),U=W?` (${W})`:"";H.push({type:"incompatible-items",path:J.path,message:`Array items${U}: ${D(J)}`,details:{reason:D(J),subPath:W||null}}),Q.add(Z)}return H}function b(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.type!=="changed"&&J.type!=="added")continue;let W=J.path==="format",U=J.path.match(/^properties\.([^.]+)\.format$/);if(!W&&!U)continue;let X=U?U[1]??null:null,j=X?`properties.${X}`:"",_=X?q(G,X,"format"):G.format,Y=X?q($,X,"format"):$.format,L=_??"none",A=Y??"none";H.push({type:"format-mismatch",path:j||"format",message:X?`Property '${X}': source format is '${L}' but target requires '${A}'`:`Source format is '${L}' but target requires '${A}'`,details:{...X?{property:X}:{},sourceFormat:_??null,targetFormat:Y??null}}),Q.add(Z)}return H}function f(G,$,x,Q){let H=[];for(let Z=0;Z<x.length;Z++){if(Q.has(Z))continue;let J=x[Z];if(J===void 0)continue;if(J.type!=="changed"&&J.type!=="added")continue;let W=J.path==="pattern",U=J.path.match(/^properties\.([^.]+)\.pattern$/);if(!W&&!U)continue;let X=U?U[1]??null:null,j=X?`properties.${X}`:"",_=X?q(G,X,"pattern"):G.pattern,Y=X?q($,X,"pattern"):$.pattern,L=_??"none",A=Y??"none";H.push({type:"pattern-not-subset",path:j||"pattern",message:X?`Property '${X}': source pattern '${L}' is not a subset of target pattern '${A}'`:`Source pattern '${L}' is not a subset of target pattern '${A}'`,details:{...X?{property:X}:{},sourcePattern:_??null,targetPattern:Y??null}}),Q.add(Z)}return H}function w(G){return{type:"schema-incompatible",path:G.path,message:D(G),details:{reason:D(G),structuralType:G.type,sourceValue:G.sourceValue,mergedValue:G.mergedValue}}}function q(G,$,x){let Q=G.properties?.[$];if(typeof Q==="object"&&Q!==null&&!Array.isArray(Q))return Q[x];return}function D(G){switch(G.type){case"added":return`'${G.path}' added with value ${JSON.stringify(G.mergedValue)}`;case"removed":return`'${G.path}' was removed (was ${JSON.stringify(G.sourceValue)})`;default:return`'${G.path}' changed from ${JSON.stringify(G.sourceValue)} to ${JSON.stringify(G.mergedValue)}`}}var r=[P,y,l,h,m,c,d,i,n,b,f];function B(G,$,x){if(x.length===0)return[];if(typeof G==="boolean"||typeof $==="boolean")return u(G,$,x);let Q=[],H=new Set;for(let Z of r){let J=Z(G,$,x,H);for(let W of J)Q.push(W)}return s(x,H,Q),Q}function u(G,$,x){if(G===!1)return[{type:"schema-incompatible",path:"$",message:"Source schema rejects all values (false schema)",details:{reason:"source is false schema"}}];if($===!1)return[{type:"schema-incompatible",path:"$",message:"Target schema rejects all values (false schema)",details:{reason:"target is false schema"}}];return x.map(w)}function s(G,$,x){for(let Q=0;Q<G.length;Q++){if($.has(Q))continue;let H=G[Q];if(H===void 0)continue;x.push(w(H))}}var e={branches:[!0],type:"none"},GG={branches:[!1],type:"none"},t=new WeakMap;function JG(G){if(typeof G==="boolean")return G?e:GG;if(I(G,"anyOf")&&Array.isArray(G.anyOf))return{branches:G.anyOf,type:"anyOf"};if(I(G,"oneOf")&&Array.isArray(G.oneOf))return{branches:G.oneOf,type:"oneOf"};let $=t.get(G);if($===void 0)$={branches:[G],type:"none"},t.set(G,$);return $}function C(G,$){if(typeof G==="boolean"||typeof $==="boolean")return null;if(I($,"not")&&F($.not)){let x=$.not;if(F(x.properties)&&Array.isArray(x.required)){let{properties:Q,required:H}=x;if(F(G.properties)){let Z=G.properties,J=Array.isArray(G.required)?G.required:[],W=Object.keys(Q);if(W.some((j)=>{let _=Q[j];if(typeof _==="boolean")return!1;let Y=_;if(H.includes(j)&&!J.includes(j)&&!I(Z,j))return!0;if(!I(Z,j))return!1;let L=Z[j];if(typeof L==="boolean")return!1;let A=L;if(I(Y,"const")&&I(A,"const")){if(!V(Y.const,A.const))return!0}if(I(Y,"enum")&&Array.isArray(Y.enum)){if(I(A,"const")){if(!Y.enum.some((R)=>V(R,A.const)))return!0}if(I(A,"enum")&&Array.isArray(A.enum)){if(A.enum.every((R)=>!Y.enum?.some((E)=>V(R,E))))return!0}}return!1}))return!0;if(W.every((j)=>{let _=Q[j];if(typeof _==="boolean")return!0;let Y=_;if(H.includes(j)&&!J.includes(j))return!1;if(!I(Z,j))return!1;let L=Z[j];if(typeof L==="boolean")return!0;let A=L;if(I(Y,"const")&&I(A,"const"))return V(Y.const,A.const);if(I(Y,"enum")&&Array.isArray(Y.enum)){if(I(A,"const"))return Y.enum.some((z)=>V(z,A.const));if(I(A,"enum")&&Array.isArray(A.enum))return A.enum.every((z)=>Y.enum?.some((R)=>V(z,R)))}return!1}))return!1}}if(I(x,"const")&&I(G,"const")){let Q=x.const,H=G.const;if(V(H,Q))return!1;return!0}if(I(x,"enum")&&Array.isArray(x.enum)&&I(G,"enum")&&Array.isArray(G.enum)){if(G.enum.every((H)=>!x.enum?.some((Z)=>V(H,Z))))return!0}if(I(x,"type")&&I(G,"type")){let Q=x.type,H=G.type;if(typeof Q==="string"&&typeof H==="string"){if(!I(x,"const")&&!I(x,"enum")&&!F(x.properties)){if(H===Q)return!1;return!0}}if(Array.isArray(Q)&&typeof H==="string"){if(Q.includes(H))return!1;return!0}}if(I(x,"anyOf")&&Array.isArray(x.anyOf)){let Q=x.anyOf;if(Q.every((J)=>{if(typeof J==="boolean")return!J;return C(G,{not:J})===!0}))return!0;if(Q.some((J)=>{if(typeof J==="boolean")return J;return C(G,{not:J})===!1}))return!1}if(I(x,"oneOf")&&Array.isArray(x.oneOf)){let Q=x.oneOf;if(Q.every((J)=>{if(typeof J==="boolean")return!J;return C(G,{not:J})===!0}))return!0;if(Q.some((J)=>{if(typeof J==="boolean")return J;return C(G,{not:J})===!1}))return!1}if(I(x,"format")&&I(G,"format")){let Q=G.format,H=x.format;if(Q===H)return!1;return!0}}if(I(G,"not")&&I($,"not")){if(V(G.not,$.not))return!0}return null}function S(G,$,x=!0){if(typeof $==="boolean"||typeof G==="boolean")return $;let Q=$;if(x&&I(Q,"not"))Q=M(Q,["not"]);if(F(Q.properties)&&F(G.properties)){let H=G.properties,Z=Q.properties,J;for(let W of Object.keys(Z)){let U=Z[W],X=H[W];if(U!==void 0&&X!==void 0&&typeof U!=="boolean"&&typeof X!=="boolean"&&I(U,"not")){if(C(X,U)===!0){if(!J)J={...Z};J[W]=M(U,["not"])}}}if(J)Q={...Q,properties:J}}return Q}function O(G,$){if(typeof G==="boolean"||typeof $==="boolean")return $;let x=$,Q=x,H=!1;function Z(){if(!H)Q={...x},H=!0;return Q}if(I(Q,"pattern")&&I(G,"pattern")&&Q.pattern!==G.pattern){if(k(G.pattern,Q.pattern)===!0)Q=M(Z(),["pattern"]),H=!0}if(F(Q.properties)&&F(G.properties)){let J=G.properties,W=Q.properties,U=!1,X;for(let j of Object.keys(W)){let _=W[j],Y=J[j];if(_!==void 0&&Y!==void 0&&typeof _!=="boolean"&&typeof Y!=="boolean"&&I(_,"pattern")&&I(Y,"pattern")&&_.pattern!==Y.pattern){if(k(Y.pattern,_.pattern)===!0){if(!X)X={...W};X[j]=M(_,["pattern"]),U=!0}}}if(U&&X)Z().properties=X}if(F(Q.items)&&typeof Q.items!=="boolean"&&F(G.items)&&typeof G.items!=="boolean"){let J=G.items,W=Q.items;if(I(W,"pattern")&&I(J,"pattern")&&W.pattern!==J.pattern){if(k(J.pattern,W.pattern)===!0)Z().items=M(W,["pattern"])}}return Q}function QG(G,$,x){let{branches:Q}=JG($);if(Q.length===1&&Q[0]===$){let H=C(G,$);if(H===!1)return!1;if(typeof G!=="boolean"&&typeof $!=="boolean"&&I(G,"format")&&I($,"format")&&G.format!==$.format){if(o(G.format,$.format)!==!0)return!1}if(typeof G!=="boolean"&&typeof $!=="boolean"&&I(G,"pattern")&&I($,"pattern")&&G.pattern!==$.pattern){if(k(G.pattern,$.pattern)===!1)return!1}let Z=$;if(typeof $!=="boolean"){if(H===!0){if(Z=S(G,$,!0),typeof Z!=="boolean"&&Object.keys(Z).length===0)return!0}else Z=S(G,$,!1);Z=O(G,Z)}let J=x.merge(G,Z);if(J===null)return!1;if(V(J,G))return!0;let W=v(J);return V(W,G)||x.isEqual(W,G)}return Q.some((H)=>{let Z=C(G,H);if(Z===!1)return!1;if(typeof G!=="boolean"&&typeof H!=="boolean"&&I(G,"pattern")&&I(H,"pattern")&&G.pattern!==H.pattern){if(k(G.pattern,H.pattern)===!1)return!1}let J=H;if(typeof H!=="boolean"){if(Z===!0){if(J=S(G,H,!0),typeof J!=="boolean"&&Object.keys(J).length===0)return!0}else J=S(G,H,!1);J=O(G,J)}let W=x.merge(G,J);if(W===null)return!1;if(V(W,G))return!0;let U=v(W);return V(U,G)||x.isEqual(U,G)})}function AG(G,$,x,Q="anyOf"){let H=[],Z=!0,J=Q==="none"?"anyOf":Q;for(let U=0;U<G.length;U++){let X=G[U];if(X===void 0)continue;if(!QG(X,$,x))Z=!1,H.push({path:`${J}[${U}]`,type:"changed",sourceValue:X,mergedValue:"Branch not accepted by superset"})}let W=Z?[]:B(G[0]??!0,$,H);return{isSubset:Z,merged:Z?Q==="oneOf"?{oneOf:G}:{anyOf:G}:null,diffs:H,semanticDiffs:W}}function LG(G,$,x,Q="anyOf"){for(let J of $){let W=J;if(typeof G!=="boolean"&&typeof J!=="boolean")W=O(G,J);let U=x.merge(G,W);if(U!==null){if(V(U,G))return{isSubset:!0,merged:U,diffs:[],semanticDiffs:[]};let X=v(U);if(V(X,G)||x.isEqual(X,G))return{isSubset:!0,merged:U,diffs:[],semanticDiffs:[]}}}let Z=[{path:"$",type:"changed",sourceValue:G,mergedValue:`No branch in superset's ${Q==="none"?"anyOf":Q} accepts this schema`}];return{isSubset:!1,merged:null,diffs:Z,semanticDiffs:B(G,Q==="oneOf"?{oneOf:$}:{anyOf:$},Z)}}function VG(G,$,x){let Q=$;if(typeof G!=="boolean"&&typeof $!=="boolean")Q=O(G,$);try{let H=x.mergeOrThrow(G,Q);if(V(H,G))return{isSubset:!0,merged:H,diffs:[],semanticDiffs:[]};let Z=v(H);if(V(Z,G)||x.isEqual(Z,G))return{isSubset:!0,merged:Z,diffs:[],semanticDiffs:[]};let J=a(G,Z,""),W=B(G,Q,J);return{isSubset:!1,merged:Z,diffs:J,semanticDiffs:W}}catch(H){let Z=[{path:"$",type:"changed",sourceValue:G,mergedValue:`Incompatible: ${H instanceof Error?H.message:String(H)}`}];return{isSubset:!1,merged:null,diffs:Z,semanticDiffs:B(G,Q,Z)}}}
2
+ export{B as b,JG as c,QG as d,AG as e,LG as f,VG as g};
3
+
4
+ //# debugId=189EA8740626810064756E2164756E21
5
+ //# sourceMappingURL=chunk-8me729r7.js.map
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/semantic-diff/detectors.ts", "../src/semantic-diff/analyzer.ts", "../src/subset-checker.ts"],
4
+ "sourcesContent": [
5
+ "import type { JSONSchema7 } from \"json-schema\";\nimport type { SchemaDiff } from \"../types\";\nimport type { SemanticDiff } from \"./types\";\n\n// ─── Semantic Diff Detectors ─────────────────────────────────────────────────\n//\n// Fonctions de détection par catégorie d'incompatibilité.\n// Chaque détecteur analyse les diffs structurels et les schemas originaux\n// pour produire des SemanticDiff lisibles et actionnables.\n//\n// Organisation :\n// 1. Property detectors — missing, optional, not-allowed\n// 2. Type detectors — mismatch, too-wide\n// 3. Value detectors — enum, const\n// 4. Constraint detectors — min/max/length/items/etc.\n// 5. Structure detectors — additionalProperties, items\n// 6. Format detectors — format, pattern\n// 7. Fallback — schema-incompatible (catch-all)\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/** Formate un type JSON Schema pour l'affichage (string, array → \"string | number\") */\nexport function formatType(type: unknown): string {\n\tif (Array.isArray(type)) {\n\t\treturn type.join(\" | \");\n\t}\n\tif (type === undefined || type === null) {\n\t\treturn \"any\";\n\t}\n\treturn String(type);\n}\n\n/**\n * Extrait le type lisible d'un sous-schema pour les messages.\n * Gère les cas const, enum, type, et boolean schemas.\n */\nfunction extractTypeLabel(schema: unknown): string {\n\tif (typeof schema === \"boolean\") {\n\t\treturn schema ? \"any\" : \"never\";\n\t}\n\tif (typeof schema !== \"object\" || schema === null) {\n\t\treturn \"unknown\";\n\t}\n\tconst s = schema as JSONSchema7;\n\tif (s.const !== undefined) {\n\t\treturn `const(${JSON.stringify(s.const)})`;\n\t}\n\tif (s.enum) {\n\t\treturn `enum(${JSON.stringify(s.enum)})`;\n\t}\n\tif (s.type) {\n\t\treturn formatType(s.type);\n\t}\n\treturn \"object\";\n}\n\n// ─── 1. Property Detectors ──────────────────────────────────────────────────\n\n/**\n * Détecte les propriétés requises par le target que le source ne fournit pas.\n *\n * Condition : la propriété est dans `sup.required` mais n'existe pas\n * dans `sub.properties`.\n *\n * Regroupe les diffs structurels `properties.X added` + `required changed`\n * en un seul diagnostic.\n */\nexport function detectMissingRequiredProperties(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tconst subProps = sub.properties || {};\n\tconst supProps = sup.properties || {};\n\tconst supRequired = new Set(sup.required || []);\n\n\t// Chercher les propriétés ajoutées par le merge qui sont requises par le target\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\n\t\tconst match = diff.path.match(/^properties\\.([^.]+)$/);\n\t\tif (!match) continue;\n\n\t\tconst propName = match[1];\n\t\tif (propName === undefined) continue;\n\n\t\t// Propriété ajoutée par le merge ET requise par le target ET absente du source\n\t\tif (\n\t\t\tdiff.type === \"added\" &&\n\t\t\tsupRequired.has(propName) &&\n\t\t\t!(propName in subProps)\n\t\t) {\n\t\t\tconst targetSchema = supProps[propName];\n\t\t\tresult.push({\n\t\t\t\ttype: \"missing-required-property\",\n\t\t\t\tpath: `properties.${propName}`,\n\t\t\t\tmessage: `Target requires property '${propName}' (${extractTypeLabel(targetSchema)}) which source does not provide`,\n\t\t\t\tdetails: {\n\t\t\t\t\tproperty: propName,\n\t\t\t\t\ttargetSchema: targetSchema ?? null,\n\t\t\t\t},\n\t\t\t});\n\t\t\tconsumed.add(i);\n\t\t}\n\t}\n\n\t// Si on a trouvé des missing-required, consommer aussi le diff `required`\n\tif (result.length > 0) {\n\t\tfor (let i = 0; i < diffs.length; i++) {\n\t\t\tif (consumed.has(i)) continue;\n\t\t\tconst diff = diffs[i];\n\t\t\tif (diff === undefined) continue;\n\t\t\tif (diff.path === \"required\" && diff.type === \"changed\") {\n\t\t\t\tconsumed.add(i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Détecte les propriétés optionnelles dans le source mais requises par le target.\n *\n * Condition : la propriété existe dans `sub.properties` (mais pas dans\n * `sub.required`), et elle est dans `sup.required`.\n *\n * Ne se déclenche que si la propriété n'a pas déjà été détectée comme\n * `missing-required-property`.\n */\nexport function detectPropertiesNotGuaranteed(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tconst subRequired = new Set(sub.required || []);\n\tconst supRequired = new Set(sup.required || []);\n\tconst subProps = sub.properties || {};\n\n\t// Compare les schemas directement plutôt que de chercher le diff `required`.\n\t// Le diff `required` peut déjà avoir été consommé par `detectMissingRequiredProperties`,\n\t// mais l'incompatibilité d'optionalité reste valide et doit être détectée.\n\n\t// Pour chaque propriété requise par le target mais pas par le source\n\tfor (const propName of supRequired) {\n\t\tif (subRequired.has(propName)) continue;\n\n\t\t// La propriété existe dans le source mais est optionnelle\n\t\tif (propName in subProps) {\n\t\t\tresult.push({\n\t\t\t\ttype: \"property-not-guaranteed\",\n\t\t\t\tpath: `properties.${propName}`,\n\t\t\t\tmessage: `Property '${propName}' is optional in source but required by target`,\n\t\t\t\tdetails: {\n\t\t\t\t\tproperty: propName,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\t// Consommer le diff `required` s'il est encore disponible\n\tif (result.length > 0) {\n\t\tfor (let i = 0; i < diffs.length; i++) {\n\t\t\tif (consumed.has(i)) continue;\n\t\t\tconst diff = diffs[i];\n\t\t\tif (diff === undefined) continue;\n\t\t\tif (diff.path === \"required\" && diff.type === \"changed\") {\n\t\t\t\tconsumed.add(i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Détecte les propriétés fournies par le source que le target interdit.\n *\n * Condition : la propriété existe dans `sub.properties` mais pas dans\n * `sup.properties`, et `sup.additionalProperties === false`.\n */\nexport function detectPropertiesNotAllowed(\n\t_sub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tif (sup.additionalProperties !== false) return result;\n\n\tconst supProps = sup.properties || {};\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\n\t\tconst match = diff.path.match(/^properties\\.([^.]+)$/);\n\t\tif (!match) continue;\n\n\t\tconst propName = match[1];\n\t\tif (propName === undefined) continue;\n\n\t\t// Propriété retirée par le merge (source l'a, target l'interdit)\n\t\tif (diff.type === \"removed\" && !(propName in supProps)) {\n\t\t\tresult.push({\n\t\t\t\ttype: \"property-not-allowed\",\n\t\t\t\tpath: `properties.${propName}`,\n\t\t\t\tmessage: `Source provides property '${propName}' which target does not allow`,\n\t\t\t\tdetails: {\n\t\t\t\t\tproperty: propName,\n\t\t\t\t},\n\t\t\t});\n\t\t\tconsumed.add(i);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// ─── 2. Type Detectors ──────────────────────────────────────────────────────\n\n/**\n * Détecte les incompatibilités de type sur les propriétés ou à la racine.\n *\n * Distingue deux cas :\n * - `type-mismatch` : types complètement différents (string vs number)\n * - `type-too-wide` : source est un superset du target (string|number vs string)\n */\nexport function detectTypeDiffs(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\t\tif (diff.type !== \"changed\" && diff.type !== \"added\") continue;\n\n\t\t// Match root \"type\" or \"properties.X.type\"\n\t\tconst rootTypeMatch = diff.path === \"type\";\n\t\tconst propTypeMatch = diff.path.match(/^properties\\.([^.]+)\\.type$/);\n\n\t\tif (!rootTypeMatch && !propTypeMatch) continue;\n\n\t\tconst propName = propTypeMatch ? (propTypeMatch[1] ?? null) : null;\n\t\tconst basePath = propName ? `properties.${propName}` : \"\";\n\n\t\t// Récupérer les types source et target depuis les schemas originaux\n\t\tconst sourceType = propName ? getPropertyType(sub, propName) : sub.type;\n\t\tconst targetType = propName ? getPropertyType(sup, propName) : sup.type;\n\n\t\tconst sourceTypes = normalizeTypeToArray(sourceType);\n\t\tconst targetTypes = normalizeTypeToArray(targetType);\n\n\t\t// Vérifier si c'est un type-too-wide (source ⊃ target) ou un mismatch total\n\t\tconst overlap = sourceTypes.filter((t) => targetTypes.includes(t));\n\n\t\tif (overlap.length === 0) {\n\t\t\t// Aucun type en commun → mismatch total\n\t\t\tresult.push({\n\t\t\t\ttype: \"type-mismatch\",\n\t\t\t\tpath: basePath || \"type\",\n\t\t\t\tmessage: propName\n\t\t\t\t\t? `Property '${propName}': source produces '${formatType(sourceType)}' but target expects '${formatType(targetType)}'`\n\t\t\t\t\t: `Source produces '${formatType(sourceType)}' but target expects '${formatType(targetType)}'`,\n\t\t\t\tdetails: {\n\t\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\t\tsourceType,\n\t\t\t\t\ttargetType,\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (overlap.length < sourceTypes.length) {\n\t\t\t// Overlap partiel → source trop large\n\t\t\tconst extraTypes = sourceTypes.filter((t) => !targetTypes.includes(t));\n\t\t\tresult.push({\n\t\t\t\ttype: \"type-too-wide\",\n\t\t\t\tpath: basePath || \"type\",\n\t\t\t\tmessage: propName\n\t\t\t\t\t? `Property '${propName}': source can produce '${formatType(sourceType)}' but target only accepts '${formatType(targetType)}'`\n\t\t\t\t\t: `Source can produce '${formatType(sourceType)}' but target only accepts '${formatType(targetType)}'`,\n\t\t\t\tdetails: {\n\t\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\t\tsourceType,\n\t\t\t\t\ttargetType,\n\t\t\t\t\textraTypes,\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\t// Même types mais le diff existe (cas edge, ne devrait pas arriver souvent)\n\t\t\tresult.push({\n\t\t\t\ttype: \"type-mismatch\",\n\t\t\t\tpath: basePath || \"type\",\n\t\t\t\tmessage: propName\n\t\t\t\t\t? `Property '${propName}': type changed from '${formatType(diff.sourceValue)}' to '${formatType(diff.mergedValue)}'`\n\t\t\t\t\t: `Type changed from '${formatType(diff.sourceValue)}' to '${formatType(diff.mergedValue)}'`,\n\t\t\t\tdetails: {\n\t\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\t\tsourceType: diff.sourceValue,\n\t\t\t\t\ttargetType: diff.mergedValue,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n/** Extrait le type d'une propriété d'un schema */\nfunction getPropertyType(\n\tschema: JSONSchema7,\n\tpropName: string,\n): JSONSchema7[\"type\"] | undefined {\n\tconst prop = schema.properties?.[propName];\n\tif (typeof prop === \"object\" && prop !== null && !Array.isArray(prop)) {\n\t\treturn prop.type;\n\t}\n\treturn undefined;\n}\n\n/** Normalise un type en tableau (pour faciliter les comparaisons) */\nfunction normalizeTypeToArray(type: JSONSchema7[\"type\"] | undefined): string[] {\n\tif (type === undefined) return [];\n\tif (Array.isArray(type)) return type;\n\treturn [type];\n}\n\n// ─── 3. Value Detectors ─────────────────────────────────────────────────────\n\n/**\n * Détecte les incompatibilités d'enum : source autorise des valeurs\n * que target n'accepte pas.\n */\nexport function detectEnumDiffs(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\t\tif (diff.type !== \"changed\" && diff.type !== \"added\") continue;\n\n\t\tconst rootEnumMatch = diff.path === \"enum\";\n\t\tconst propEnumMatch = diff.path.match(/^properties\\.([^.]+)\\.enum$/);\n\n\t\tif (!rootEnumMatch && !propEnumMatch) continue;\n\n\t\tconst propName = propEnumMatch ? (propEnumMatch[1] ?? null) : null;\n\t\tconst basePath = propName ? `properties.${propName}` : \"\";\n\n\t\tconst sourceValues = propName\n\t\t\t? getPropertyKeyword(sub, propName, \"enum\")\n\t\t\t: sub.enum;\n\t\tconst targetValues = propName\n\t\t\t? getPropertyKeyword(sup, propName, \"enum\")\n\t\t\t: sup.enum;\n\n\t\tconst sourceArr = Array.isArray(sourceValues) ? sourceValues : [];\n\t\tconst targetArr = Array.isArray(targetValues) ? targetValues : [];\n\t\tconst targetSet = new Set(targetArr.map((v) => JSON.stringify(v)));\n\t\tconst extraValues = sourceArr.filter(\n\t\t\t(v) => !targetSet.has(JSON.stringify(v)),\n\t\t);\n\n\t\tresult.push({\n\t\t\ttype: \"enum-not-subset\",\n\t\t\tpath: basePath || \"enum\",\n\t\t\tmessage: propName\n\t\t\t\t? `Property '${propName}': source allows ${JSON.stringify(extraValues)} which target does not accept`\n\t\t\t\t: `Source allows ${JSON.stringify(extraValues)} which target does not accept`,\n\t\t\tdetails: {\n\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\tsourceValues,\n\t\t\t\ttargetValues,\n\t\t\t\textraValues,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n/**\n * Détecte les incompatibilités de const : valeurs const différentes.\n */\nexport function detectConstDiffs(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\t\tif (diff.type !== \"changed\" && diff.type !== \"added\") continue;\n\n\t\tconst rootConstMatch = diff.path === \"const\";\n\t\tconst propConstMatch = diff.path.match(/^properties\\.([^.]+)\\.const$/);\n\n\t\tif (!rootConstMatch && !propConstMatch) continue;\n\n\t\tconst propName = propConstMatch ? (propConstMatch[1] ?? null) : null;\n\t\tconst basePath = propName ? `properties.${propName}` : \"\";\n\n\t\tconst sourceConst = propName\n\t\t\t? getPropertyKeyword(sub, propName, \"const\")\n\t\t\t: sub.const;\n\t\tconst targetConst = propName\n\t\t\t? getPropertyKeyword(sup, propName, \"const\")\n\t\t\t: sup.const;\n\n\t\tresult.push({\n\t\t\ttype: \"const-mismatch\",\n\t\t\tpath: basePath || \"const\",\n\t\t\tmessage: propName\n\t\t\t\t? `Property '${propName}': source produces ${JSON.stringify(sourceConst)} but target expects ${JSON.stringify(targetConst)}`\n\t\t\t\t: `Source produces ${JSON.stringify(sourceConst)} but target expects ${JSON.stringify(targetConst)}`,\n\t\t\tdetails: {\n\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\tsourceConst,\n\t\t\t\ttargetConst,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n// ─── 4. Constraint Detectors ────────────────────────────────────────────────\n\n/**\n * Mots-clés de contraintes numériques / string / array / object.\n * Chaque entrée indique le keyword et une description lisible.\n */\nconst CONSTRAINT_KEYWORDS: ReadonlyMap<string, string> = new Map([\n\t[\"minimum\", \"minimum value\"],\n\t[\"maximum\", \"maximum value\"],\n\t[\"exclusiveMinimum\", \"exclusive minimum\"],\n\t[\"exclusiveMaximum\", \"exclusive maximum\"],\n\t[\"multipleOf\", \"multipleOf\"],\n\t[\"minLength\", \"minimum length\"],\n\t[\"maxLength\", \"maximum length\"],\n\t[\"minItems\", \"minimum items\"],\n\t[\"maxItems\", \"maximum items\"],\n\t[\"minProperties\", \"minimum properties\"],\n\t[\"maxProperties\", \"maximum properties\"],\n\t[\"uniqueItems\", \"uniqueItems\"],\n]);\n\n/**\n * Détecte les contraintes du target plus strictes que celles du source.\n *\n * Couvre : minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf,\n * minLength, maxLength, minItems, maxItems, minProperties, maxProperties.\n */\nexport function detectConstraintDiffs(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\t\tif (diff.type !== \"changed\" && diff.type !== \"added\") continue;\n\n\t\t// Match root constraint or properties.X.constraint\n\t\tlet keyword: string | null = null;\n\t\tlet propName: string | null = null;\n\n\t\t// Root level: \"minLength\", \"maximum\", etc.\n\t\tif (CONSTRAINT_KEYWORDS.has(diff.path)) {\n\t\t\tkeyword = diff.path;\n\t\t}\n\n\t\t// Property level: \"properties.X.minLength\", etc.\n\t\tif (!keyword) {\n\t\t\tconst propMatch = diff.path.match(/^properties\\.([^.]+)\\.(.+)$/);\n\t\t\tif (propMatch?.[2] && CONSTRAINT_KEYWORDS.has(propMatch[2])) {\n\t\t\t\tpropName = propMatch[1] ?? null;\n\t\t\t\tkeyword = propMatch[2];\n\t\t\t}\n\t\t}\n\n\t\tif (!keyword) continue;\n\n\t\tconst label = CONSTRAINT_KEYWORDS.get(keyword) ?? keyword;\n\t\tconst basePath = propName ? `properties.${propName}` : \"\";\n\n\t\tconst sourceValue = propName\n\t\t\t? getPropertyKeyword(sub, propName, keyword)\n\t\t\t: (sub as Record<string, unknown>)[keyword];\n\t\tconst targetValue = propName\n\t\t\t? getPropertyKeyword(sup, propName, keyword)\n\t\t\t: (sup as Record<string, unknown>)[keyword];\n\n\t\tconst sourceLabel =\n\t\t\tsourceValue !== undefined ? String(sourceValue) : \"none\";\n\t\tconst targetLabel =\n\t\t\ttargetValue !== undefined ? String(targetValue) : \"none\";\n\n\t\tresult.push({\n\t\t\ttype: \"constraint-too-loose\",\n\t\t\tpath: basePath || keyword,\n\t\t\tmessage: propName\n\t\t\t\t? `Property '${propName}': source allows ${label}=${sourceLabel} but target requires ${label}=${targetLabel}`\n\t\t\t\t: `Source allows ${label}=${sourceLabel} but target requires ${label}=${targetLabel}`,\n\t\t\tdetails: {\n\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\tconstraint: keyword,\n\t\t\t\tsourceValue: sourceValue ?? null,\n\t\t\t\ttargetValue: targetValue ?? null,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n// ─── 5. Structure Detectors ─────────────────────────────────────────────────\n\n/**\n * Détecte les conflits d'additionalProperties :\n * source autorise des propriétés supplémentaires, target les interdit.\n */\nexport function detectAdditionalPropertiesConflict(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\n\t\tif (diff.path !== \"additionalProperties\") continue;\n\n\t\tconst sourceAllows = sub.additionalProperties !== false;\n\t\tconst targetAllows = sup.additionalProperties !== false;\n\n\t\tresult.push({\n\t\t\ttype: \"additional-properties-conflict\",\n\t\t\tpath: \"additionalProperties\",\n\t\t\tmessage:\n\t\t\t\tsourceAllows && !targetAllows\n\t\t\t\t\t? \"Source allows additional properties but target forbids them\"\n\t\t\t\t\t: `additionalProperties changed from ${JSON.stringify(diff.sourceValue)} to ${JSON.stringify(diff.mergedValue)}`,\n\t\t\tdetails: {\n\t\t\t\tsourceAllows,\n\t\t\t\ttargetAllows,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n/**\n * Détecte les incompatibilités de schema d'items (arrays).\n */\nexport function detectItemsDiffs(\n\t_sub: JSONSchema7,\n\t_sup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\n\t\t// Match \"items\" or \"items.something\"\n\t\tif (!diff.path.startsWith(\"items\")) continue;\n\n\t\t// Construire un message selon le sous-path\n\t\tconst subPath = diff.path === \"items\" ? \"\" : diff.path.slice(6); // remove \"items.\"\n\t\tconst detail = subPath ? ` (${subPath})` : \"\";\n\n\t\tresult.push({\n\t\t\ttype: \"incompatible-items\",\n\t\t\tpath: diff.path,\n\t\t\tmessage: `Array items${detail}: ${describeChange(diff)}`,\n\t\t\tdetails: {\n\t\t\t\treason: describeChange(diff),\n\t\t\t\tsubPath: subPath || null,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n// ─── 6. Format Detectors ────────────────────────────────────────────────────\n\n/**\n * Détecte les incompatibilités de format (email, uri, date-time, etc.).\n */\nexport function detectFormatDiffs(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\t\tif (diff.type !== \"changed\" && diff.type !== \"added\") continue;\n\n\t\tconst rootFormatMatch = diff.path === \"format\";\n\t\tconst propFormatMatch = diff.path.match(/^properties\\.([^.]+)\\.format$/);\n\n\t\tif (!rootFormatMatch && !propFormatMatch) continue;\n\n\t\tconst propName = propFormatMatch ? (propFormatMatch[1] ?? null) : null;\n\t\tconst basePath = propName ? `properties.${propName}` : \"\";\n\n\t\tconst sourceFormat = propName\n\t\t\t? getPropertyKeyword(sub, propName, \"format\")\n\t\t\t: sub.format;\n\t\tconst targetFormat = propName\n\t\t\t? getPropertyKeyword(sup, propName, \"format\")\n\t\t\t: sup.format;\n\n\t\tconst sourceLabel = sourceFormat ?? \"none\";\n\t\tconst targetLabel = targetFormat ?? \"none\";\n\n\t\tresult.push({\n\t\t\ttype: \"format-mismatch\",\n\t\t\tpath: basePath || \"format\",\n\t\t\tmessage: propName\n\t\t\t\t? `Property '${propName}': source format is '${sourceLabel}' but target requires '${targetLabel}'`\n\t\t\t\t: `Source format is '${sourceLabel}' but target requires '${targetLabel}'`,\n\t\t\tdetails: {\n\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\tsourceFormat: sourceFormat ?? null,\n\t\t\t\ttargetFormat: targetFormat ?? null,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n/**\n * Détecte les incompatibilités de pattern regex.\n */\nexport function detectPatternDiffs(\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n): SemanticDiff[] {\n\tconst result: SemanticDiff[] = [];\n\n\tfor (let i = 0; i < diffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = diffs[i];\n\t\tif (diff === undefined) continue;\n\t\tif (diff.type !== \"changed\" && diff.type !== \"added\") continue;\n\n\t\tconst rootPatternMatch = diff.path === \"pattern\";\n\t\tconst propPatternMatch = diff.path.match(/^properties\\.([^.]+)\\.pattern$/);\n\n\t\tif (!rootPatternMatch && !propPatternMatch) continue;\n\n\t\tconst propName = propPatternMatch ? (propPatternMatch[1] ?? null) : null;\n\t\tconst basePath = propName ? `properties.${propName}` : \"\";\n\n\t\tconst sourcePattern = propName\n\t\t\t? getPropertyKeyword(sub, propName, \"pattern\")\n\t\t\t: sub.pattern;\n\t\tconst targetPattern = propName\n\t\t\t? getPropertyKeyword(sup, propName, \"pattern\")\n\t\t\t: sup.pattern;\n\n\t\tconst sourceLabel = sourcePattern ?? \"none\";\n\t\tconst targetLabel = targetPattern ?? \"none\";\n\n\t\tresult.push({\n\t\t\ttype: \"pattern-not-subset\",\n\t\t\tpath: basePath || \"pattern\",\n\t\t\tmessage: propName\n\t\t\t\t? `Property '${propName}': source pattern '${sourceLabel}' is not a subset of target pattern '${targetLabel}'`\n\t\t\t\t: `Source pattern '${sourceLabel}' is not a subset of target pattern '${targetLabel}'`,\n\t\t\tdetails: {\n\t\t\t\t...(propName ? { property: propName } : {}),\n\t\t\t\tsourcePattern: sourcePattern ?? null,\n\t\t\t\ttargetPattern: targetPattern ?? null,\n\t\t\t},\n\t\t});\n\t\tconsumed.add(i);\n\t}\n\n\treturn result;\n}\n\n// ─── 7. Fallback ─────────────────────────────────────────────────────────────\n\n/**\n * Convertit les diffs structurels non consommés en `schema-incompatible`.\n *\n * C'est le catch-all pour les cas non couverts par les détecteurs spécifiques.\n */\nexport function createFallbackDiff(diff: SchemaDiff): SemanticDiff {\n\treturn {\n\t\ttype: \"schema-incompatible\",\n\t\tpath: diff.path,\n\t\tmessage: describeChange(diff),\n\t\tdetails: {\n\t\t\treason: describeChange(diff),\n\t\t\tstructuralType: diff.type,\n\t\t\tsourceValue: diff.sourceValue,\n\t\t\tmergedValue: diff.mergedValue,\n\t\t},\n\t};\n}\n\n// ─── Shared Helpers ──────────────────────────────────────────────────────────\n\n/**\n * Extrait la valeur d'un mot-clé d'un sous-schema de propriété.\n *\n * @param schema Le schema parent\n * @param propName Le nom de la propriété\n * @param keyword Le mot-clé à extraire (type, enum, format, etc.)\n */\nfunction getPropertyKeyword(\n\tschema: JSONSchema7,\n\tpropName: string,\n\tkeyword: string,\n): unknown {\n\tconst prop = schema.properties?.[propName];\n\tif (typeof prop === \"object\" && prop !== null && !Array.isArray(prop)) {\n\t\treturn (prop as Record<string, unknown>)[keyword];\n\t}\n\treturn undefined;\n}\n\n/**\n * Décrit un changement structurel en phrase lisible.\n * Utilisé pour les messages des détecteurs et du fallback.\n */\nfunction describeChange(diff: SchemaDiff): string {\n\tswitch (diff.type) {\n\t\tcase \"added\":\n\t\t\treturn `'${diff.path}' added with value ${JSON.stringify(diff.mergedValue)}`;\n\t\tcase \"removed\":\n\t\t\treturn `'${diff.path}' was removed (was ${JSON.stringify(diff.sourceValue)})`;\n\t\tdefault:\n\t\t\treturn `'${diff.path}' changed from ${JSON.stringify(diff.sourceValue)} to ${JSON.stringify(diff.mergedValue)}`;\n\t}\n}\n",
6
+ "import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport type { SchemaDiff } from \"../types\";\nimport {\n\tcreateFallbackDiff,\n\tdetectAdditionalPropertiesConflict,\n\tdetectConstDiffs,\n\tdetectConstraintDiffs,\n\tdetectEnumDiffs,\n\tdetectFormatDiffs,\n\tdetectItemsDiffs,\n\tdetectMissingRequiredProperties,\n\tdetectPatternDiffs,\n\tdetectPropertiesNotAllowed,\n\tdetectPropertiesNotGuaranteed,\n\tdetectTypeDiffs,\n} from \"./detectors\";\nimport type { SemanticDiff } from \"./types\";\n\n// ─── Semantic Diff Analyzer ──────────────────────────────────────────────────\n//\n// Orchestrateur principal qui transforme des diffs structurelles brutes\n// (original vs merged) en diffs sémantiques lisibles et actionnables.\n//\n// Architecture :\n// 1. Les détecteurs s'exécutent dans un ordre précis (priorité décroissante)\n// 2. Chaque détecteur marque les diffs structurelles qu'il a \"consommées\"\n// 3. Les diffs non consommées tombent dans le fallback `schema-incompatible`\n//\n// L'ordre des détecteurs est important :\n// - Les property detectors passent en premier pour regrouper les diffs\n// `properties.X added` + `required changed` en un seul diagnostic\n// - Les type/value/constraint detectors traitent les diffs restantes\n// - Le fallback attrape tout ce qui n'a pas été classifié\n\n// ─── Detector pipeline ───────────────────────────────────────────────────────\n\n/**\n * Pipeline de détecteurs, exécutés dans l'ordre.\n *\n * Chaque détecteur reçoit :\n * - sub : le schema source (original)\n * - sup : le schema target\n * - diffs : toutes les diffs structurelles\n * - consumed : Set d'indices des diffs déjà traitées\n *\n * Et retourne un tableau de SemanticDiff.\n *\n * L'ordre est crucial :\n * 1. Property-level (regroupe required + property diffs)\n * 2. Type-level\n * 3. Value-level (enum, const)\n * 4. Constraint-level (min/max/length/items/etc.)\n * 5. Structure-level (additionalProperties, items)\n * 6. Format-level (format, pattern)\n */\ntype DetectorFn = (\n\tsub: JSONSchema7,\n\tsup: JSONSchema7,\n\tdiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n) => SemanticDiff[];\n\nconst DETECTOR_PIPELINE: readonly DetectorFn[] = [\n\t// Phase 1 — Property detectors (order matters: missing before not-guaranteed)\n\tdetectMissingRequiredProperties,\n\tdetectPropertiesNotGuaranteed,\n\tdetectPropertiesNotAllowed,\n\n\t// Phase 2 — Type detectors\n\tdetectTypeDiffs,\n\n\t// Phase 3 — Value detectors\n\tdetectEnumDiffs,\n\tdetectConstDiffs,\n\n\t// Phase 4 — Constraint detectors\n\tdetectConstraintDiffs,\n\n\t// Phase 5 — Structure detectors\n\tdetectAdditionalPropertiesConflict,\n\tdetectItemsDiffs,\n\n\t// Phase 6 — Format detectors\n\tdetectFormatDiffs,\n\tdetectPatternDiffs,\n];\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Transforme les diffs structurelles en diffs sémantiques.\n *\n * @param sub Le schema source (sourceOutput)\n * @param sup Le schema target (targetInput)\n * @param structuralDiffs Les diffs brutes produites par `computeDiffs`\n * @returns Tableau de SemanticDiff lisibles et actionnables\n *\n * @example\n * ```ts\n * const semanticDiffs = computeSemanticDiffs(sourceSchema, targetSchema, rawDiffs);\n * // [\n * // {\n * // type: 'missing-required-property',\n * // path: 'properties.meetingId',\n * // message: \"Target requires property 'meetingId' (string) which source does not provide\",\n * // details: { property: 'meetingId', targetSchema: { type: 'string' } }\n * // }\n * // ]\n * ```\n */\nexport function computeSemanticDiffs(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tstructuralDiffs: SchemaDiff[],\n): SemanticDiff[] {\n\t// Pas de diffs structurelles → pas de diffs sémantiques\n\tif (structuralDiffs.length === 0) return [];\n\n\t// Boolean schemas : pas assez de structure pour détecter des patterns\n\t// → fallback direct\n\tif (typeof sub === \"boolean\" || typeof sup === \"boolean\") {\n\t\treturn handleBooleanSchemas(sub, sup, structuralDiffs);\n\t}\n\n\tconst result: SemanticDiff[] = [];\n\tconst consumed = new Set<number>();\n\n\t// Exécuter chaque détecteur dans l'ordre du pipeline\n\tfor (const detector of DETECTOR_PIPELINE) {\n\t\tconst detected = detector(sub, sup, structuralDiffs, consumed);\n\t\tfor (const diff of detected) {\n\t\t\tresult.push(diff);\n\t\t}\n\t}\n\n\t// Phase finale — Fallback pour les diffs non consommées\n\tcollectUnconsumedDiffs(structuralDiffs, consumed, result);\n\n\treturn result;\n}\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\n/**\n * Gère les boolean schemas (true/false).\n *\n * `true` = accepte tout, `false` = rejette tout.\n * Pas assez de structure pour les détecteurs spécifiques,\n * donc on produit un `schema-incompatible` générique.\n */\nfunction handleBooleanSchemas(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tstructuralDiffs: SchemaDiff[],\n): SemanticDiff[] {\n\tif (sub === false) {\n\t\treturn [\n\t\t\t{\n\t\t\t\ttype: \"schema-incompatible\",\n\t\t\t\tpath: \"$\",\n\t\t\t\tmessage: \"Source schema rejects all values (false schema)\",\n\t\t\t\tdetails: { reason: \"source is false schema\" },\n\t\t\t},\n\t\t];\n\t}\n\n\tif (sup === false) {\n\t\treturn [\n\t\t\t{\n\t\t\t\ttype: \"schema-incompatible\",\n\t\t\t\tpath: \"$\",\n\t\t\t\tmessage: \"Target schema rejects all values (false schema)\",\n\t\t\t\tdetails: { reason: \"target is false schema\" },\n\t\t\t},\n\t\t];\n\t}\n\n\t// sub === true et sup est un objet, ou vice versa\n\t// Le diff structurel devrait décrire le problème\n\treturn structuralDiffs.map(createFallbackDiff);\n}\n\n/**\n * Collecte les diffs structurelles non consommées par aucun détecteur\n * et les convertit en `schema-incompatible` (fallback).\n *\n * Garantit qu'aucune diff structurelle n'est silencieusement ignorée.\n */\nfunction collectUnconsumedDiffs(\n\tstructuralDiffs: SchemaDiff[],\n\tconsumed: Set<number>,\n\tresult: SemanticDiff[],\n): void {\n\tfor (let i = 0; i < structuralDiffs.length; i++) {\n\t\tif (consumed.has(i)) continue;\n\t\tconst diff = structuralDiffs[i];\n\t\tif (diff === undefined) continue;\n\t\tresult.push(createFallbackDiff(diff));\n\t}\n}\n",
7
+ "import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { computeDiffs } from \"./differ\";\nimport { isFormatSubset } from \"./format-validator\";\nimport type { MergeEngine } from \"./merge-engine\";\nimport { normalize } from \"./normalizer\";\nimport { isPatternSubset } from \"./pattern-subset\";\nimport { computeSemanticDiffs } from \"./semantic-diff\";\nimport type { SchemaDiff, SubsetResult } from \"./types\";\nimport { deepEqual, hasOwn, isPlainObj, omitKeys } from \"./utils\";\n\n// ─── Subset Checker ──────────────────────────────────────────────────────────\n//\n// Logique de vérification sub ⊆ sup via l'approche :\n// A ⊆ B ⟺ A ∩ B ≡ A\n//\n// Gère les cas :\n// - Schemas atomiques (pas de anyOf/oneOf)\n// - anyOf/oneOf dans sub → chaque branche doit être acceptée par sup\n// - anyOf/oneOf dans sup → au moins une branche doit accepter sub\n// - Point 6 : Distinction anyOf / oneOf dans les messages de diff\n// - Point 7 : Raisonnement étendu sur `not` (evaluateNot)\n// - not.type, not.const, not.enum (existants)\n// - not avec properties+required (1.1)\n// - not avec anyOf/oneOf (1.2)\n// - not dans sub (1.3)\n// - not.format (format-vs-format)\n//\n// Utilise des helpers natifs partagés depuis `./utils` pour des performances\n// optimales (deepEqual, hasOwn, isPlainObj, omitKeys).\n\n// ─── Branch type ─────────────────────────────────────────────────────────────\n\n/**\n * Type de branchement détecté dans un schema.\n *\n * Point 6 — Distingue `anyOf` de `oneOf` pour produire des messages\n * de diff plus précis. `\"none\"` indique un schema atomique (pas de branches).\n *\n * Note : la sémantique d'exclusivité de `oneOf` n'est pas vérifiée\n * (ce serait un problème NP-hard en général). Le checker traite `oneOf`\n * comme `anyOf` pour le subset checking, ce qui est correct pour le cas\n * `sub ⊆ sup` mais peut produire des faux-positifs si les branches\n * du sub se chevauchent.\n */\nexport type BranchType = \"anyOf\" | \"oneOf\" | \"none\";\n\nexport interface BranchResult {\n\t/** Les branches extraites du schema */\n\tbranches: JSONSchema7Definition[];\n\t/** Le type de branchement détecté */\n\ttype: BranchType;\n}\n\n// ─── Branch extraction ───────────────────────────────────────────────────────\n\n// Pre-allocated singleton results for boolean schemas to avoid per-call allocations.\n// These are safe because the branches arrays are never mutated after creation.\nconst BRANCH_TRUE: BranchResult = { branches: [true], type: \"none\" };\nconst BRANCH_FALSE: BranchResult = { branches: [false], type: \"none\" };\n\n/**\n * WeakMap cache for atomic (no anyOf/oneOf) schema branch results.\n * Avoids allocating `{ branches: [def], type: \"none\" }` on every call\n * for the same schema object. Since normalized schemas are cached and\n * return the same reference, this cache hits frequently.\n */\nconst atomicBranchCache = new WeakMap<object, BranchResult>();\n\n/**\n * Extrait les branches d'un schema et le type de branchement.\n *\n * Retourne les éléments de `anyOf`/`oneOf` s'ils existent, sinon retourne\n * le schema lui-même dans un tableau avec type `\"none\"`.\n *\n * Point 6 — Distingue `anyOf` de `oneOf` dans les paths de diff.\n *\n * Optimisation : réutilise des objets pré-alloués pour les cas boolean\n * (true/false) et un WeakMap cache pour les schemas atomiques afin\n * d'éviter les allocations sur ces chemins fréquents.\n */\nexport function getBranchesTyped(def: JSONSchema7Definition): BranchResult {\n\tif (typeof def === \"boolean\") {\n\t\treturn def ? BRANCH_TRUE : BRANCH_FALSE;\n\t}\n\tif (hasOwn(def, \"anyOf\") && Array.isArray(def.anyOf)) {\n\t\treturn { branches: def.anyOf, type: \"anyOf\" };\n\t}\n\tif (hasOwn(def, \"oneOf\") && Array.isArray(def.oneOf)) {\n\t\treturn { branches: def.oneOf, type: \"oneOf\" };\n\t}\n\t// Cache atomic results per schema object to avoid repeated allocations.\n\tlet cached = atomicBranchCache.get(def);\n\tif (cached === undefined) {\n\t\tcached = { branches: [def], type: \"none\" };\n\t\tatomicBranchCache.set(def, cached);\n\t}\n\treturn cached;\n}\n\n// ─── `not` reasoning (Point 7 — étendu) ─────────────────────────────────────\n\n/**\n * Raisonnement étendu sur `not` pour les cas courants.\n *\n * Point 7 — Vérifie la compatibilité quand `sup` et/ou `sub` contiennent `not` :\n *\n * **Cas existants (not dans sup) :**\n * - `not.type` : type exclu vs type de sub\n * - `not.const` : const exclu vs const de sub\n * - `not.enum` : valeurs exclues vs enum de sub\n *\n * **Cas ajoutés :**\n * - 1.1 — `not` avec `properties` + `required` : vérifier que les propriétés\n * de sub sont incompatibles avec celles du `not` (const/enum différents)\n * - 1.2 — `not` avec `anyOf`/`oneOf` : `not(anyOf([A,B]))` ≡ `allOf([not(A), not(B)])`,\n * donc sub doit être incompatible avec CHAQUE branche\n * - 1.3 — `not` dans `sub` (pas seulement dans `sup`) : un sub avec `not`\n * accepte un ensemble trop large pour être un sous-ensemble d'un sup concret\n * - `not.format` : format-vs-format via `isFormatSubset`\n *\n * Contrat ternaire conservateur :\n * - `true` → compatible (certain)\n * - `false` → incompatible (certain)\n * - `null` → indéterminé (laisser le merge engine décider)\n *\n * En cas de doute → `null`. Ne JAMAIS retourner `true` sans certitude.\n *\n * Utilise `_.has`, `_.get`, `_.isEqual`, `_.includes`, `_.every`, `_.some`,\n * `_.keys`, `_.isPlainObject`, `_.isArray` pour des vérifications concises.\n */\nfunction evaluateNot(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n): boolean | null {\n\tif (typeof sub === \"boolean\" || typeof sup === \"boolean\") return null;\n\n\t// ── 1.3 — `not` dans sub (pas dans sup) ──\n\t// Un `not` dans sub est une restriction supplémentaire : il exclut des\n\t// valeurs de l'ensemble accepté par sub, ce qui le rend potentiellement\n\t// plus petit — donc plus susceptible d'être ⊆ sup, pas moins.\n\t// On laisse le merge engine décider : allOf(sub, sup) préservera le `not`\n\t// de sub, et la comparaison merged ≡ sub donnera le bon résultat.\n\t// Exception : si les deux ont `not`, on traite l'identité plus bas.\n\n\t// Vérifier `not` dans sup\n\tif (hasOwn(sup, \"not\") && isPlainObj(sup.not)) {\n\t\tconst notSchema = sup.not as JSONSchema7;\n\n\t\t// ── 1.1 — Cas not avec properties + required ──\n\t\t// IMPORTANT : ce check est placé AVANT le check not.type car quand\n\t\t// le not a à la fois `type` et `properties`, le check not.type seul\n\t\t// produirait un faux négatif (ex: sub type=object et not type=object\n\t\t// retournerait false, mais les properties pourraient être incompatibles\n\t\t// ce qui rendrait sub compatible avec le not).\n\t\t// Si not contient des properties avec const/enum et required,\n\t\t// vérifier que les propriétés de sub sont incompatibles avec celles du not.\n\t\tif (isPlainObj(notSchema.properties) && Array.isArray(notSchema.required)) {\n\t\t\tconst notProps = notSchema.properties as Record<\n\t\t\t\tstring,\n\t\t\t\tJSONSchema7Definition\n\t\t\t>;\n\t\t\tconst notRequired = notSchema.required as string[];\n\n\t\t\t// sub doit avoir des properties pour qu'on puisse comparer\n\t\t\tif (isPlainObj(sub.properties)) {\n\t\t\t\tconst subProps = sub.properties as Record<\n\t\t\t\t\tstring,\n\t\t\t\t\tJSONSchema7Definition\n\t\t\t\t>;\n\t\t\t\tconst subRequired = Array.isArray(sub.required)\n\t\t\t\t\t? (sub.required as string[])\n\t\t\t\t\t: [];\n\t\t\t\tconst notPropKeys = Object.keys(notProps);\n\n\t\t\t\t// Pour que sub soit compatible avec not(schema),\n\t\t\t\t// il suffit qu'au moins UNE propriété du not soit incompatible avec sub.\n\t\t\t\t// Cela signifie que sub ne peut jamais valider le schema inside not.\n\t\t\t\tconst hasIncompatibleProp = notPropKeys.some((key) => {\n\t\t\t\t\tconst notPropDef = notProps[key];\n\t\t\t\t\tif (typeof notPropDef === \"boolean\") return false;\n\t\t\t\t\tconst notProp = notPropDef as JSONSchema7;\n\n\t\t\t\t\t// Si la propriété est required dans not mais PAS dans sub.required\n\t\t\t\t\t// et qu'elle n'existe pas dans sub.properties → sub peut ne pas\n\t\t\t\t\t// avoir cette propriété → le not schema ne matcherait pas → compatible\n\t\t\t\t\tif (\n\t\t\t\t\t\tnotRequired.includes(key) &&\n\t\t\t\t\t\t!subRequired.includes(key) &&\n\t\t\t\t\t\t!hasOwn(subProps, key)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn true; // Propriété absente de sub → not ne matche pas\n\t\t\t\t\t}\n\n\t\t\t\t\t// Comparer les const/enum de la propriété\n\t\t\t\t\tif (!hasOwn(subProps, key)) return false;\n\t\t\t\t\tconst subPropDef = subProps[key];\n\t\t\t\t\tif (typeof subPropDef === \"boolean\") return false;\n\t\t\t\t\tconst subProp = subPropDef as JSONSchema7;\n\n\t\t\t\t\t// not.prop a un const, sub.prop a un const différent → incompatible pour cette prop\n\t\t\t\t\tif (hasOwn(notProp, \"const\") && hasOwn(subProp, \"const\")) {\n\t\t\t\t\t\tif (!deepEqual(notProp.const, subProp.const)) {\n\t\t\t\t\t\t\treturn true; // Consts différents → sub ne matche pas le not\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// not.prop a un enum, sub.prop a un const ou enum dont aucune valeur\n\t\t\t\t\t// n'est dans not.enum → incompatible pour cette prop\n\t\t\t\t\tif (hasOwn(notProp, \"enum\") && Array.isArray(notProp.enum)) {\n\t\t\t\t\t\tif (hasOwn(subProp, \"const\")) {\n\t\t\t\t\t\t\tconst inNotEnum = notProp.enum.some((v) =>\n\t\t\t\t\t\t\t\tdeepEqual(v, subProp.const),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (!inNotEnum) return true; // sub.const absent du not.enum\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (hasOwn(subProp, \"enum\") && Array.isArray(subProp.enum)) {\n\t\t\t\t\t\t\tconst noneInNotEnum = subProp.enum.every(\n\t\t\t\t\t\t\t\t(v) => !notProp.enum?.some((nv) => deepEqual(v, nv)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (noneInNotEnum) return true; // Aucune valeur de sub.enum dans not.enum\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t});\n\n\t\t\t\tif (hasIncompatibleProp) return true;\n\n\t\t\t\t// Vérification inverse : si TOUTES les propriétés du not matchent sub\n\t\t\t\t// exactement (même const, sub a les required du not), alors sub VIOLE le not\n\t\t\t\tconst allPropsMatch = notPropKeys.every((key) => {\n\t\t\t\t\tconst notPropDef = notProps[key];\n\t\t\t\t\tif (typeof notPropDef === \"boolean\") return true;\n\t\t\t\t\tconst notProp = notPropDef as JSONSchema7;\n\n\t\t\t\t\t// La propriété doit être dans sub.required si elle est dans not.required\n\t\t\t\t\tif (notRequired.includes(key) && !subRequired.includes(key))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!hasOwn(subProps, key)) return false;\n\t\t\t\t\tconst subPropDef = subProps[key];\n\t\t\t\t\tif (typeof subPropDef === \"boolean\") return true;\n\t\t\t\t\tconst subProp = subPropDef as JSONSchema7;\n\n\t\t\t\t\t// Vérifier const match\n\t\t\t\t\tif (hasOwn(notProp, \"const\") && hasOwn(subProp, \"const\")) {\n\t\t\t\t\t\treturn deepEqual(notProp.const, subProp.const);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Vérifier enum inclusion\n\t\t\t\t\tif (hasOwn(notProp, \"enum\") && Array.isArray(notProp.enum)) {\n\t\t\t\t\t\tif (hasOwn(subProp, \"const\")) {\n\t\t\t\t\t\t\treturn notProp.enum.some((v) => deepEqual(v, subProp.const));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (hasOwn(subProp, \"enum\") && Array.isArray(subProp.enum)) {\n\t\t\t\t\t\t\t// Toutes les valeurs de sub.enum sont dans not.enum\n\t\t\t\t\t\t\treturn subProp.enum.every((v) =>\n\t\t\t\t\t\t\t\tnotProp.enum?.some((nv) => deepEqual(v, nv)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false; // Indéterminé pour cette propriété\n\t\t\t\t});\n\n\t\t\t\tif (allPropsMatch) return false; // sub matche exactement le not → incompatible\n\t\t\t}\n\t\t}\n\n\t\t// ── Cas not.const ──\n\t\t// IMPORTANT : ce check est placé AVANT not.type car quand le not a\n\t\t// à la fois `type` et `const`, le check not.type seul produirait un\n\t\t// faux négatif (ex: sub type=string const=\"active\" et not type=string\n\t\t// const=\"deleted\" → le type check retournerait false car même type,\n\t\t// alors que les consts sont différents → compatible).\n\t\tif (hasOwn(notSchema, \"const\") && hasOwn(sub, \"const\")) {\n\t\t\tconst notConst = notSchema.const;\n\t\t\tconst subConst = sub.const;\n\t\t\tif (deepEqual(subConst, notConst)) return false;\n\t\t\treturn true;\n\t\t}\n\n\t\t// ── Cas not.enum ──\n\t\t// Aussi placé AVANT not.type pour la même raison.\n\t\tif (\n\t\t\thasOwn(notSchema, \"enum\") &&\n\t\t\tArray.isArray(notSchema.enum) &&\n\t\t\thasOwn(sub, \"enum\") &&\n\t\t\tArray.isArray(sub.enum)\n\t\t) {\n\t\t\t// Toutes les valeurs de sub.enum doivent être absentes de not.enum\n\t\t\tconst allExcluded = sub.enum.every(\n\t\t\t\t(val) => !notSchema.enum?.some((notVal) => deepEqual(val, notVal)),\n\t\t\t);\n\t\t\tif (allExcluded) return true;\n\t\t\t// Certaines valeurs de sub sont dans not.enum → pas automatiquement faux,\n\t\t\t// le merge engine peut encore gérer\n\t\t}\n\n\t\t// ── Cas not.type ──\n\t\t// Placé APRÈS not.const, not.enum et properties+required pour ne pas\n\t\t// court-circuiter les cas où le not a des contraintes plus spécifiques.\n\t\t// Le check type seul est un fallback pour les not schemas simples\n\t\t// (ex: { not: { type: \"string\" } }).\n\t\tif (hasOwn(notSchema, \"type\") && hasOwn(sub, \"type\")) {\n\t\t\tconst notType = notSchema.type;\n\t\t\tconst subType = sub.type;\n\n\t\t\t// Si les deux sont des strings simples\n\t\t\tif (typeof notType === \"string\" && typeof subType === \"string\") {\n\t\t\t\t// Ne retourner que si le not n'a PAS de contraintes plus spécifiques\n\t\t\t\t// (const, enum, properties) qui auraient dû être traitées plus haut\n\t\t\t\tif (\n\t\t\t\t\t!hasOwn(notSchema, \"const\") &&\n\t\t\t\t\t!hasOwn(notSchema, \"enum\") &&\n\t\t\t\t\t!isPlainObj(notSchema.properties)\n\t\t\t\t) {\n\t\t\t\t\tif (subType === notType) return false; // Incompatible : sub est exactement le type exclu\n\t\t\t\t\treturn true; // Compatible : sub est un type différent du type exclu\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Si notType est un tableau, sub.type doit ne pas être dedans\n\t\t\tif (Array.isArray(notType) && typeof subType === \"string\") {\n\t\t\t\tif (notType.includes(subType)) return false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// ── 1.2 — Cas not avec anyOf / oneOf ──\n\t\t// not(anyOf([A, B])) ≡ allOf([not(A), not(B)])\n\t\t// Pour que sub ⊆ not(anyOf(...)), sub doit être incompatible avec CHAQUE branche.\n\t\tif (hasOwn(notSchema, \"anyOf\") && Array.isArray(notSchema.anyOf)) {\n\t\t\tconst branches = notSchema.anyOf as JSONSchema7Definition[];\n\t\t\t// Pour chaque branche du not.anyOf, vérifier que sub est incompatible\n\t\t\tconst allIncompatible = branches.every((branch) => {\n\t\t\t\tif (typeof branch === \"boolean\") return !branch; // not(true) = rien, not(false) = tout\n\t\t\t\t// Créer un sup virtuel { not: branch } et vérifier récursivement\n\t\t\t\tconst result = evaluateNot(sub, { not: branch });\n\t\t\t\t// result = true → sub est compatible avec not(branch) → sub ⊄ branch → OK\n\t\t\t\t// result = false → sub est incompatible avec not(branch) → sub ⊆ branch → pas OK\n\t\t\t\t// result = null → indéterminé\n\t\t\t\treturn result === true;\n\t\t\t});\n\t\t\tif (allIncompatible) return true;\n\n\t\t\t// Vérifier si au moins une branche accepte sub → incompatible avec not(anyOf)\n\t\t\tconst anyBranchMatches = branches.some((branch) => {\n\t\t\t\tif (typeof branch === \"boolean\") return branch;\n\t\t\t\tconst result = evaluateNot(sub, { not: branch });\n\t\t\t\treturn result === false; // sub est incompatible avec not(branch) → sub ⊆ branch\n\t\t\t});\n\t\t\tif (anyBranchMatches) return false;\n\t\t}\n\n\t\t// Même logique pour oneOf (dans le contexte du not, traité comme anyOf)\n\t\tif (hasOwn(notSchema, \"oneOf\") && Array.isArray(notSchema.oneOf)) {\n\t\t\tconst branches = notSchema.oneOf as JSONSchema7Definition[];\n\t\t\tconst allIncompatible = branches.every((branch) => {\n\t\t\t\tif (typeof branch === \"boolean\") return !branch;\n\t\t\t\tconst result = evaluateNot(sub, { not: branch });\n\t\t\t\treturn result === true;\n\t\t\t});\n\t\t\tif (allIncompatible) return true;\n\n\t\t\tconst anyBranchMatches = branches.some((branch) => {\n\t\t\t\tif (typeof branch === \"boolean\") return branch;\n\t\t\t\tconst result = evaluateNot(sub, { not: branch });\n\t\t\t\treturn result === false;\n\t\t\t});\n\t\t\tif (anyBranchMatches) return false;\n\t\t}\n\n\t\t// ── Cas not.format (format-vs-format uniquement) ──\n\t\t// Si not a un format et sub aussi, vérifier la compatibilité\n\t\tif (hasOwn(notSchema, \"format\") && hasOwn(sub, \"format\")) {\n\t\t\tconst subFormat = sub.format as string;\n\t\t\tconst notFormat = notSchema.format as string;\n\t\t\tif (subFormat === notFormat) return false; // Incompatible : sub a exactement le format exclu\n\t\t\t// Formats différents → compatible (approximation conservatrice)\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Vérifier `not` dans sub ET dans sup (identité : { not: X } ⊆ { not: X })\n\tif (hasOwn(sub, \"not\") && hasOwn(sup, \"not\")) {\n\t\tif (deepEqual(sub.not, sup.not)) return true;\n\t}\n\n\treturn null; // Pas d'avis → laisser le merge engine décider\n}\n\n// ─── Not stripping helper ────────────────────────────────────────────────────\n\n/**\n * Retire le mot-clé `not` d'un schema pour permettre un merge propre\n * quand `evaluateNot` a déjà confirmé la compatibilité.\n *\n * Gère aussi le `not` imbriqué dans les `properties` : si une propriété\n * de `sup` a un `not` qui est compatible avec la propriété correspondante\n * de `sub`, on le retire également.\n *\n * Retourne le schema nettoyé, ou `null` si le schema est vide après retrait.\n *\n * Utilise `_.omit`, `_.has`, `_.keys`, `_.isEmpty`, `_.isPlainObject`.\n */\nfunction stripNotFromSup(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tstripTopLevel: boolean = true,\n): JSONSchema7Definition {\n\tif (typeof sup === \"boolean\" || typeof sub === \"boolean\") return sup;\n\n\tlet result = sup as JSONSchema7;\n\n\t// ── Retirer le `not` de niveau supérieur (seulement si confirmé) ──\n\tif (stripTopLevel && hasOwn(result, \"not\")) {\n\t\tresult = omitKeys(result as unknown as Record<string, unknown>, [\n\t\t\t\"not\",\n\t\t]) as JSONSchema7;\n\t}\n\n\t// ── Retirer les `not` dans les propriétés communes ──\n\t// Si sup.properties[key] a un `not` et que evaluateNot(sub.prop, sup.prop)\n\t// confirme la compatibilité, on retire le `not` de cette propriété aussi.\n\tif (\n\t\tisPlainObj(result.properties) &&\n\t\tisPlainObj((sub as JSONSchema7).properties)\n\t) {\n\t\tconst subProps = (sub as JSONSchema7).properties as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition\n\t\t>;\n\t\tconst supProps = result.properties as Record<string, JSONSchema7Definition>;\n\t\tlet newProps: Record<string, JSONSchema7Definition> | undefined;\n\n\t\tfor (const key of Object.keys(supProps)) {\n\t\t\tconst supPropDef = supProps[key];\n\t\t\tconst subPropDef = subProps[key];\n\t\t\tif (\n\t\t\t\tsupPropDef !== undefined &&\n\t\t\t\tsubPropDef !== undefined &&\n\t\t\t\ttypeof supPropDef !== \"boolean\" &&\n\t\t\t\ttypeof subPropDef !== \"boolean\" &&\n\t\t\t\thasOwn(supPropDef, \"not\")\n\t\t\t) {\n\t\t\t\t// Vérifier la compatibilité du not au niveau de la propriété\n\t\t\t\tconst propNotResult = evaluateNot(subPropDef, supPropDef);\n\t\t\t\tif (propNotResult === true) {\n\t\t\t\t\t// Lazy allocate newProps only on first modification\n\t\t\t\t\tif (!newProps) newProps = { ...supProps };\n\t\t\t\t\tnewProps[key] = omitKeys(\n\t\t\t\t\t\tsupPropDef as unknown as Record<string, unknown>,\n\t\t\t\t\t\t[\"not\"],\n\t\t\t\t\t) as JSONSchema7Definition;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (newProps) {\n\t\t\tresult = { ...result, properties: newProps };\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// ─── Pattern stripping helper ────────────────────────────────────────────────\n\n/**\n * Retire le `pattern` de `sup` quand `isPatternSubset` a confirmé que\n * sub.pattern ⊆ sup.pattern par échantillonnage.\n *\n * Fonctionne comme `stripNotFromSup` : on retire la contrainte de sup\n * qui est déjà satisfaite par sub, pour éviter que le merge engine\n * produise un pattern combiné (lookahead conjunction) structurellement\n * différent du pattern de sub, ce qui causerait un faux négatif.\n *\n * Récurse dans les `properties` pour traiter les patterns imbriqués.\n *\n * @param sub Le schema sub (utilisé pour extraire les patterns à comparer)\n * @param sup Le schema sup dont on retire les patterns confirmés\n * @returns Le schema sup nettoyé\n */\nfunction stripPatternFromSup(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n): JSONSchema7Definition {\n\tif (typeof sub === \"boolean\" || typeof sup === \"boolean\") return sup;\n\n\tconst supObj: JSONSchema7 = sup;\n\n\t// Lazy copy-on-write: only create a copy when the first mutation is needed.\n\tlet result: JSONSchema7 = supObj;\n\tlet copied = false;\n\n\tfunction ensureCopy(): JSONSchema7 {\n\t\tif (!copied) {\n\t\t\tresult = { ...supObj };\n\t\t\tcopied = true;\n\t\t}\n\t\treturn result;\n\t}\n\n\t// ── Top-level pattern ──\n\tif (\n\t\thasOwn(result, \"pattern\") &&\n\t\thasOwn(sub, \"pattern\") &&\n\t\tresult.pattern !== (sub as JSONSchema7).pattern\n\t) {\n\t\tconst patResult = isPatternSubset(\n\t\t\t(sub as JSONSchema7).pattern as string,\n\t\t\tresult.pattern as string,\n\t\t);\n\t\tif (patResult === true) {\n\t\t\tresult = omitKeys(ensureCopy() as unknown as Record<string, unknown>, [\n\t\t\t\t\"pattern\",\n\t\t\t]) as JSONSchema7;\n\t\t\tcopied = true;\n\t\t}\n\t}\n\n\t// ── Patterns dans les propriétés communes ──\n\tif (\n\t\tisPlainObj(result.properties) &&\n\t\tisPlainObj((sub as JSONSchema7).properties)\n\t) {\n\t\tconst subProps = (sub as JSONSchema7).properties as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition\n\t\t>;\n\t\tconst supProps = result.properties as Record<string, JSONSchema7Definition>;\n\t\tlet propsModified = false;\n\t\tlet newProps: Record<string, JSONSchema7Definition> | undefined;\n\n\t\tfor (const key of Object.keys(supProps)) {\n\t\t\tconst supPropDef = supProps[key];\n\t\t\tconst subPropDef = subProps[key];\n\t\t\tif (\n\t\t\t\tsupPropDef !== undefined &&\n\t\t\t\tsubPropDef !== undefined &&\n\t\t\t\ttypeof supPropDef !== \"boolean\" &&\n\t\t\t\ttypeof subPropDef !== \"boolean\" &&\n\t\t\t\thasOwn(supPropDef, \"pattern\") &&\n\t\t\t\thasOwn(subPropDef, \"pattern\") &&\n\t\t\t\tsupPropDef.pattern !== subPropDef.pattern\n\t\t\t) {\n\t\t\t\tconst propPatResult = isPatternSubset(\n\t\t\t\t\t(subPropDef as JSONSchema7).pattern as string,\n\t\t\t\t\t(supPropDef as JSONSchema7).pattern as string,\n\t\t\t\t);\n\t\t\t\tif (propPatResult === true) {\n\t\t\t\t\tif (!newProps) newProps = { ...supProps };\n\t\t\t\t\tnewProps[key] = omitKeys(\n\t\t\t\t\t\tsupPropDef as unknown as Record<string, unknown>,\n\t\t\t\t\t\t[\"pattern\"],\n\t\t\t\t\t) as JSONSchema7Definition;\n\t\t\t\t\tpropsModified = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (propsModified && newProps) {\n\t\t\tensureCopy().properties = newProps;\n\t\t}\n\t}\n\n\t// ── Pattern dans items (single schema) ──\n\tif (\n\t\tisPlainObj(result.items) &&\n\t\ttypeof result.items !== \"boolean\" &&\n\t\tisPlainObj((sub as JSONSchema7).items) &&\n\t\ttypeof (sub as JSONSchema7).items !== \"boolean\"\n\t) {\n\t\tconst subItems = (sub as JSONSchema7).items as JSONSchema7;\n\t\tconst supItems = result.items as JSONSchema7;\n\t\tif (\n\t\t\thasOwn(supItems, \"pattern\") &&\n\t\t\thasOwn(subItems, \"pattern\") &&\n\t\t\tsupItems.pattern !== subItems.pattern\n\t\t) {\n\t\t\tconst itemsPatResult = isPatternSubset(\n\t\t\t\tsubItems.pattern as string,\n\t\t\t\tsupItems.pattern as string,\n\t\t\t);\n\t\t\tif (itemsPatResult === true) {\n\t\t\t\tensureCopy().items = omitKeys(\n\t\t\t\t\tsupItems as unknown as Record<string, unknown>,\n\t\t\t\t\t[\"pattern\"],\n\t\t\t\t) as JSONSchema7Definition;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// ─── Atomic subset check ─────────────────────────────────────────────────────\n\n/**\n * Vérifie si `sub ⊆ sup` pour deux schemas sans anyOf/oneOf (ou avec\n * anyOf/oneOf uniquement côté sup).\n *\n * Point 7 — Intègre un pré-check `not` étendu (`evaluateNot`) avant le merge.\n *\n * Quand `evaluateNot` confirme la compatibilité (`true`), on retire le `not`\n * de `sup` avant le merge pour éviter que le merge engine ajoute une contrainte\n * `not` que `sub` n'a pas (ce qui ferait échouer `isEqual(merged, sub)`).\n *\n * Pattern pre-check — Quand les deux schemas ont des patterns différents,\n * vérifie l'inclusion par échantillonnage via `isPatternSubset`. Si confirmé,\n * retire le pattern de sup avant le merge (même stratégie que pour `not`).\n *\n * Principe : merge(sub, sup) ≡ sub → sub est un sous-ensemble de sup.\n *\n * Utilise `_.some`, `_.has`, `_.omit`, `_.keys`, `_.isEmpty` pour la logique.\n */\nexport function isAtomicSubsetOf(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tengine: MergeEngine,\n): boolean {\n\tconst { branches: supBranches } = getBranchesTyped(sup);\n\n\t// Schema simple → merge direct\n\tif (supBranches.length === 1 && supBranches[0] === sup) {\n\t\t// Point 7 : pré-check `not` étendu\n\t\tconst notResult = evaluateNot(sub, sup);\n\t\tif (notResult === false) return false;\n\n\t\t// ── Format pre-check ──\n\t\t// Si les deux schemas ont un `format` différent, vérifier que\n\t\t// sub.format ⊆ sup.format. Sinon, sub ne peut pas être ⊆ sup.\n\t\t// Cela complète hasFormatConflict (qui gère le merge) en gérant\n\t\t// la direction du subset check que le merge ne peut pas résoudre.\n\t\tif (\n\t\t\ttypeof sub !== \"boolean\" &&\n\t\t\ttypeof sup !== \"boolean\" &&\n\t\t\thasOwn(sub, \"format\") &&\n\t\t\thasOwn(sup, \"format\") &&\n\t\t\tsub.format !== sup.format\n\t\t) {\n\t\t\tconst fmtResult = isFormatSubset(\n\t\t\t\tsub.format as string,\n\t\t\t\tsup.format as string,\n\t\t\t);\n\t\t\tif (fmtResult !== true) return false;\n\t\t}\n\n\t\t// ── Pattern pre-check ──\n\t\t// Si les deux schemas ont des patterns différents, vérifier l'inclusion\n\t\t// par échantillonnage. Si sub.pattern ⊄ sup.pattern (contre-exemple trouvé),\n\t\t// on retourne false immédiatement. Sinon, on pourra retirer le pattern\n\t\t// de sup pour éviter le faux négatif structurel du merge.\n\t\tif (\n\t\t\ttypeof sub !== \"boolean\" &&\n\t\t\ttypeof sup !== \"boolean\" &&\n\t\t\thasOwn(sub, \"pattern\") &&\n\t\t\thasOwn(sup, \"pattern\") &&\n\t\t\tsub.pattern !== sup.pattern\n\t\t) {\n\t\t\tconst patResult = isPatternSubset(\n\t\t\t\tsub.pattern as string,\n\t\t\t\tsup.pattern as string,\n\t\t\t);\n\t\t\tif (patResult === false) return false;\n\t\t}\n\n\t\t// Retirer `not` de sup (top-level et/ou dans les properties)\n\t\t// quand evaluateNot confirme la compatibilité au niveau correspondant.\n\t\t// Cela évite que le merge engine ajoute une contrainte `not` que sub n'a pas\n\t\t// (ce qui ferait merged ≠ sub et produirait un faux négatif).\n\t\tlet effectiveSup = sup;\n\t\tif (typeof sup !== \"boolean\") {\n\t\t\t// Si top-level not est confirmé compatible → retirer le not top-level\n\t\t\tif (notResult === true) {\n\t\t\t\teffectiveSup = stripNotFromSup(sub, sup, true);\n\t\t\t\t// Si sup n'avait QUE `not` → sub est compatible (le not est résolu)\n\t\t\t\tif (\n\t\t\t\t\ttypeof effectiveSup !== \"boolean\" &&\n\t\t\t\t\tObject.keys(effectiveSup).length === 0\n\t\t\t\t) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Même si le top-level not n'est pas confirmé (null), on tente\n\t\t\t\t// de retirer les `not` dans les properties individuelles\n\t\t\t\t// sans toucher au `not` top-level\n\t\t\t\teffectiveSup = stripNotFromSup(sub, sup, false);\n\t\t\t}\n\n\t\t\t// Retirer les patterns de sup confirmés par échantillonnage.\n\t\t\t// Même stratégie que pour `not` : on retire la contrainte déjà\n\t\t\t// satisfaite par sub pour éviter que le merge produise un pattern\n\t\t\t// combiné (lookahead conjunction) structurellement ≠ sub.\n\t\t\teffectiveSup = stripPatternFromSup(sub, effectiveSup);\n\t\t}\n\n\t\tconst merged = engine.merge(sub, effectiveSup);\n\t\tif (merged === null) return false;\n\t\t// Fast path: if merged is already structurally equal to sub,\n\t\t// skip normalize entirely. This is the common case when sub ⊆ sup\n\t\t// (A ∩ B = A), saving O(n) normalize traversal on wide schemas.\n\t\tif (deepEqual(merged, sub)) return true;\n\t\t// Slow path: normalize to eliminate merge artifacts (e.g. redundant\n\t\t// enum when const is present), then compare.\n\t\tconst normalizedMerged = normalize(merged);\n\t\treturn (\n\t\t\tdeepEqual(normalizedMerged, sub) || engine.isEqual(normalizedMerged, sub)\n\t\t);\n\t}\n\n\t// anyOf/oneOf dans sup → au moins une branche doit accepter sub\n\treturn supBranches.some((branch) => {\n\t\t// Point 7 : pré-check `not` étendu par branche\n\t\tconst notResult = evaluateNot(sub, branch);\n\t\tif (notResult === false) return false;\n\n\t\t// ── Pattern pre-check par branche ──\n\t\tif (\n\t\t\ttypeof sub !== \"boolean\" &&\n\t\t\ttypeof branch !== \"boolean\" &&\n\t\t\thasOwn(sub, \"pattern\") &&\n\t\t\thasOwn(branch, \"pattern\") &&\n\t\t\tsub.pattern !== branch.pattern\n\t\t) {\n\t\t\tconst patResult = isPatternSubset(\n\t\t\t\tsub.pattern as string,\n\t\t\t\tbranch.pattern as string,\n\t\t\t);\n\t\t\tif (patResult === false) return false;\n\t\t}\n\n\t\t// Même logique de strip pour les branches\n\t\tlet effectiveBranch = branch;\n\t\tif (typeof branch !== \"boolean\") {\n\t\t\tif (notResult === true) {\n\t\t\t\teffectiveBranch = stripNotFromSup(sub, branch, true);\n\t\t\t\tif (\n\t\t\t\t\ttypeof effectiveBranch !== \"boolean\" &&\n\t\t\t\t\tObject.keys(effectiveBranch).length === 0\n\t\t\t\t) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\teffectiveBranch = stripNotFromSup(sub, branch, false);\n\t\t\t}\n\n\t\t\t// Strip patterns confirmés par échantillonnage\n\t\t\teffectiveBranch = stripPatternFromSup(sub, effectiveBranch);\n\t\t}\n\n\t\tconst merged = engine.merge(sub, effectiveBranch);\n\t\tif (merged === null) return false;\n\t\t// Fast path: skip normalize if merged already equals sub\n\t\tif (deepEqual(merged, sub)) return true;\n\t\tconst normalizedBranch = normalize(merged);\n\t\treturn (\n\t\t\tdeepEqual(normalizedBranch, sub) || engine.isEqual(normalizedBranch, sub)\n\t\t);\n\t});\n}\n\n// ─── Full subset check (with diffs) ─────────────────────────────────────────\n\n/**\n * Vérifie `sub ⊆ sup` pour un sub qui a des branches (anyOf/oneOf).\n * Chaque branche de sub doit être acceptée par sup.\n *\n * Point 6 — Utilise `getBranchesTyped` pour distinguer `anyOf[i]` de\n * `oneOf[i]` dans les paths de diff.\n *\n * Utilise `_.every` / `_.flatMap` / `_.map` pour une itération idiomatique.\n */\nexport function checkBranchedSub(\n\tsubBranches: JSONSchema7Definition[],\n\tsup: JSONSchema7Definition,\n\tengine: MergeEngine,\n\tbranchType: BranchType = \"anyOf\",\n): SubsetResult {\n\tconst allDiffs: SchemaDiff[] = [];\n\tlet allSubset = true;\n\n\t// Point 6 : utilise le type de branche réel pour le path\n\tconst branchLabel = branchType === \"none\" ? \"anyOf\" : branchType;\n\n\tfor (let i = 0; i < subBranches.length; i++) {\n\t\tconst branch = subBranches[i];\n\t\tif (branch === undefined) continue;\n\t\tif (!isAtomicSubsetOf(branch, sup, engine)) {\n\t\t\tallSubset = false;\n\t\t\tallDiffs.push({\n\t\t\t\tpath: `${branchLabel}[${i}]`,\n\t\t\t\ttype: \"changed\",\n\t\t\t\tsourceValue: branch,\n\t\t\t\tmergedValue: \"Branch not accepted by superset\",\n\t\t\t});\n\t\t}\n\t}\n\n\tconst semanticDiffs = allSubset\n\t\t? []\n\t\t: computeSemanticDiffs(subBranches[0] ?? true, sup, allDiffs);\n\n\treturn {\n\t\tisSubset: allSubset,\n\t\tmerged: allSubset\n\t\t\t? branchType === \"oneOf\"\n\t\t\t\t? { oneOf: subBranches }\n\t\t\t\t: { anyOf: subBranches }\n\t\t\t: null,\n\t\tdiffs: allDiffs,\n\t\tsemanticDiffs,\n\t};\n}\n\n/**\n * Vérifie `sub ⊆ sup` pour un sup qui a des branches (anyOf/oneOf).\n * Au moins une branche de sup doit accepter sub.\n *\n * Point 6 — Utilise le type de branche de sup pour des messages plus précis.\n *\n * Utilise `_.some` pour trouver la première branche compatible.\n */\nexport function checkBranchedSup(\n\tsub: JSONSchema7Definition,\n\tsupBranches: JSONSchema7Definition[],\n\tengine: MergeEngine,\n\tbranchType: BranchType = \"anyOf\",\n): SubsetResult {\n\tfor (const branch of supBranches) {\n\t\t// Strip patterns confirmés par échantillonnage avant le merge\n\t\tlet effectiveBranch = branch;\n\t\tif (typeof sub !== \"boolean\" && typeof branch !== \"boolean\") {\n\t\t\teffectiveBranch = stripPatternFromSup(sub, branch);\n\t\t}\n\t\tconst merged = engine.merge(sub, effectiveBranch);\n\t\tif (merged !== null) {\n\t\t\t// Fast path: skip normalize if merged already equals sub\n\t\t\tif (deepEqual(merged, sub)) {\n\t\t\t\treturn { isSubset: true, merged, diffs: [], semanticDiffs: [] };\n\t\t\t}\n\t\t\tconst normalizedMerged = normalize(merged);\n\t\t\tif (\n\t\t\t\tdeepEqual(normalizedMerged, sub) ||\n\t\t\t\tengine.isEqual(normalizedMerged, sub)\n\t\t\t) {\n\t\t\t\treturn { isSubset: true, merged, diffs: [], semanticDiffs: [] };\n\t\t\t}\n\t\t}\n\t}\n\n\t// Point 6 : message précis selon le type de branche\n\tconst branchLabel = branchType === \"none\" ? \"anyOf\" : branchType;\n\n\tconst fallbackDiffs: SchemaDiff[] = [\n\t\t{\n\t\t\tpath: \"$\",\n\t\t\ttype: \"changed\",\n\t\t\tsourceValue: sub,\n\t\t\tmergedValue: `No branch in superset's ${branchLabel} accepts this schema`,\n\t\t},\n\t];\n\n\treturn {\n\t\tisSubset: false,\n\t\tmerged: null,\n\t\tdiffs: fallbackDiffs,\n\t\tsemanticDiffs: computeSemanticDiffs(\n\t\t\tsub,\n\t\t\tbranchType === \"oneOf\" ? { oneOf: supBranches } : { anyOf: supBranches },\n\t\t\tfallbackDiffs,\n\t\t),\n\t};\n}\n\n/**\n * Vérifie `sub ⊆ sup` pour deux schemas atomiques (sans anyOf/oneOf).\n * Utilise `mergeOrThrow` pour capturer les erreurs d'incompatibilité.\n *\n * Utilise `deepEqual` pour la comparaison structurelle (avec short-circuit\n * par référence et comptage de clés).\n */\nexport function checkAtomic(\n\tsub: JSONSchema7Definition,\n\tsup: JSONSchema7Definition,\n\tengine: MergeEngine,\n): SubsetResult {\n\t// Strip patterns confirmés par échantillonnage avant le merge,\n\t// même stratégie que dans isAtomicSubsetOf pour éviter les faux négatifs\n\t// structurels causés par la conjonction de patterns en lookahead.\n\tlet effectiveSup = sup;\n\tif (typeof sub !== \"boolean\" && typeof sup !== \"boolean\") {\n\t\teffectiveSup = stripPatternFromSup(sub, sup);\n\t}\n\n\ttry {\n\t\tconst merged = engine.mergeOrThrow(sub, effectiveSup);\n\n\t\t// Fast path: skip normalize if merged already equals sub\n\t\tif (deepEqual(merged, sub)) {\n\t\t\treturn { isSubset: true, merged, diffs: [], semanticDiffs: [] };\n\t\t}\n\n\t\tconst normalizedMerged = normalize(merged);\n\n\t\tif (\n\t\t\tdeepEqual(normalizedMerged, sub) ||\n\t\t\tengine.isEqual(normalizedMerged, sub)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tisSubset: true,\n\t\t\t\tmerged: normalizedMerged,\n\t\t\t\tdiffs: [],\n\t\t\t\tsemanticDiffs: [],\n\t\t\t};\n\t\t}\n\n\t\tconst diffs = computeDiffs(sub, normalizedMerged, \"\");\n\t\tconst semanticDiffs = computeSemanticDiffs(sub, effectiveSup, diffs);\n\t\treturn { isSubset: false, merged: normalizedMerged, diffs, semanticDiffs };\n\t} catch (e) {\n\t\tconst diffs: SchemaDiff[] = [\n\t\t\t{\n\t\t\t\tpath: \"$\",\n\t\t\t\ttype: \"changed\",\n\t\t\t\tsourceValue: sub,\n\t\t\t\tmergedValue: `Incompatible: ${e instanceof Error ? e.message : String(e)}`,\n\t\t\t},\n\t\t];\n\t\treturn {\n\t\t\tisSubset: false,\n\t\t\tmerged: null,\n\t\t\tdiffs,\n\t\t\tsemanticDiffs: computeSemanticDiffs(sub, effectiveSup, diffs),\n\t\t};\n\t}\n}\n"
8
+ ],
9
+ "mappings": "qPAsBO,GAAS,LAAU,LAAC,JAAuB,CACjD,GAAI,MAAM,QAAQ,CAAI,EACrB,OAAO,EAAK,KAAK,KAAK,EAEvB,GAAI,IAAS,QAAa,IAAS,KAClC,MAAO,MAER,OAAO,OAAO,CAAI,EAOnB,SAAS,CAAgB,CAAC,EAAyB,CAClD,GAAI,OAAO,IAAW,UACrB,OAAO,EAAS,MAAQ,QAEzB,GAAI,OAAO,IAAW,UAAY,IAAW,KAC5C,MAAO,UAER,IAAM,EAAI,EACV,GAAI,EAAE,QAAU,OACf,MAAO,SAAS,KAAK,UAAU,EAAE,KAAK,KAEvC,GAAI,EAAE,KACL,MAAO,QAAQ,KAAK,UAAU,EAAE,IAAI,KAErC,GAAI,EAAE,KACL,OAAO,EAAW,EAAE,IAAI,EAEzB,MAAO,SAcD,SAAS,CAA+B,CAC9C,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAE1B,EAAW,EAAI,YAAc,CAAC,EAC9B,EAAW,EAAI,YAAc,CAAC,EAC9B,EAAc,IAAI,IAAI,EAAI,UAAY,CAAC,CAAC,EAG9C,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SAExB,IAAM,EAAQ,EAAK,KAAK,MAAM,uBAAuB,EACrD,GAAI,CAAC,EAAO,SAEZ,IAAM,EAAW,EAAM,GACvB,GAAI,IAAa,OAAW,SAG5B,GACC,EAAK,OAAS,SACd,EAAY,IAAI,CAAQ,GACxB,EAAE,KAAY,GACb,CACD,IAAM,EAAe,EAAS,GAC9B,EAAO,KAAK,CACX,KAAM,4BACN,KAAM,cAAc,IACpB,QAAS,6BAA6B,OAAc,EAAiB,CAAY,mCACjF,QAAS,CACR,SAAU,EACV,aAAc,GAAgB,IAC/B,CACD,CAAC,EACD,EAAS,IAAI,CAAC,GAKhB,GAAI,EAAO,OAAS,EACnB,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,YAAc,EAAK,OAAS,UAAW,CACxD,EAAS,IAAI,CAAC,EACd,OAKH,OAAO,EAYD,SAAS,CAA6B,CAC5C,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAE1B,EAAc,IAAI,IAAI,EAAI,UAAY,CAAC,CAAC,EACxC,EAAc,IAAI,IAAI,EAAI,UAAY,CAAC,CAAC,EACxC,EAAW,EAAI,YAAc,CAAC,EAOpC,QAAW,KAAY,EAAa,CACnC,GAAI,EAAY,IAAI,CAAQ,EAAG,SAG/B,GAAI,KAAY,EACf,EAAO,KAAK,CACX,KAAM,0BACN,KAAM,cAAc,IACpB,QAAS,aAAa,kDACtB,QAAS,CACR,SAAU,CACX,CACD,CAAC,EAKH,GAAI,EAAO,OAAS,EACnB,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,YAAc,EAAK,OAAS,UAAW,CACxD,EAAS,IAAI,CAAC,EACd,OAKH,OAAO,EASD,SAAS,CAA0B,CACzC,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,GAAI,EAAI,uBAAyB,GAAO,OAAO,EAE/C,IAAM,EAAW,EAAI,YAAc,CAAC,EAEpC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SAExB,IAAM,EAAQ,EAAK,KAAK,MAAM,uBAAuB,EACrD,GAAI,CAAC,EAAO,SAEZ,IAAM,EAAW,EAAM,GACvB,GAAI,IAAa,OAAW,SAG5B,GAAI,EAAK,OAAS,WAAa,EAAE,KAAY,GAC5C,EAAO,KAAK,CACX,KAAM,uBACN,KAAM,cAAc,IACpB,QAAS,6BAA6B,iCACtC,QAAS,CACR,SAAU,CACX,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAIhB,OAAO,EAYD,SAAS,CAAe,CAC9B,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,WAAa,EAAK,OAAS,QAAS,SAGtD,IAAM,EAAgB,EAAK,OAAS,OAC9B,EAAgB,EAAK,KAAK,MAAM,6BAA6B,EAEnE,GAAI,CAAC,GAAiB,CAAC,EAAe,SAEtC,IAAM,EAAW,EAAiB,EAAc,IAAM,KAAQ,KACxD,EAAW,EAAW,cAAc,IAAa,GAGjD,EAAa,EAAW,EAAgB,EAAK,CAAQ,EAAI,EAAI,KAC7D,EAAa,EAAW,EAAgB,EAAK,CAAQ,EAAI,EAAI,KAE7D,EAAc,EAAqB,CAAU,EAC7C,EAAc,EAAqB,CAAU,EAG7C,EAAU,EAAY,OAAO,CAAC,IAAM,EAAY,SAAS,CAAC,CAAC,EAEjE,GAAI,EAAQ,SAAW,EAEtB,EAAO,KAAK,CACX,KAAM,gBACN,KAAM,GAAY,OAClB,QAAS,EACN,aAAa,wBAA+B,EAAW,CAAU,0BAA0B,EAAW,CAAU,KAChH,oBAAoB,EAAW,CAAU,0BAA0B,EAAW,CAAU,KAC3F,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,aACA,YACD,CACD,CAAC,EACK,QAAI,EAAQ,OAAS,EAAY,OAAQ,CAE/C,IAAM,EAAa,EAAY,OAAO,CAAC,IAAM,CAAC,EAAY,SAAS,CAAC,CAAC,EACrE,EAAO,KAAK,CACX,KAAM,gBACN,KAAM,GAAY,OAClB,QAAS,EACN,aAAa,2BAAkC,EAAW,CAAU,+BAA+B,EAAW,CAAU,KACxH,uBAAuB,EAAW,CAAU,+BAA+B,EAAW,CAAU,KACnG,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,aACA,aACA,YACD,CACD,CAAC,EAGD,OAAO,KAAK,CACX,KAAM,gBACN,KAAM,GAAY,OAClB,QAAS,EACN,aAAa,0BAAiC,EAAW,EAAK,WAAW,UAAU,EAAW,EAAK,WAAW,KAC9G,sBAAsB,EAAW,EAAK,WAAW,UAAU,EAAW,EAAK,WAAW,KACzF,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,WAAY,EAAK,YACjB,WAAY,EAAK,WAClB,CACD,CAAC,EAGF,EAAS,IAAI,CAAC,EAGf,OAAO,EAIR,SAAS,CAAe,CACvB,EACA,EACkC,CAClC,IAAM,EAAO,EAAO,aAAa,GACjC,GAAI,OAAO,IAAS,UAAY,IAAS,MAAQ,CAAC,MAAM,QAAQ,CAAI,EACnE,OAAO,EAAK,KAEb,OAID,SAAS,CAAoB,CAAC,EAAiD,CAC9E,GAAI,IAAS,OAAW,MAAO,CAAC,EAChC,GAAI,MAAM,QAAQ,CAAI,EAAG,OAAO,EAChC,MAAO,CAAC,CAAI,EASN,SAAS,CAAe,CAC9B,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,WAAa,EAAK,OAAS,QAAS,SAEtD,IAAM,EAAgB,EAAK,OAAS,OAC9B,EAAgB,EAAK,KAAK,MAAM,6BAA6B,EAEnE,GAAI,CAAC,GAAiB,CAAC,EAAe,SAEtC,IAAM,EAAW,EAAiB,EAAc,IAAM,KAAQ,KACxD,EAAW,EAAW,cAAc,IAAa,GAEjD,EAAe,EAClB,EAAmB,EAAK,EAAU,MAAM,EACxC,EAAI,KACD,EAAe,EAClB,EAAmB,EAAK,EAAU,MAAM,EACxC,EAAI,KAED,EAAY,MAAM,QAAQ,CAAY,EAAI,EAAe,CAAC,EAC1D,EAAY,MAAM,QAAQ,CAAY,EAAI,EAAe,CAAC,EAC1D,EAAY,IAAI,IAAI,EAAU,IAAI,CAAC,IAAM,KAAK,UAAU,CAAC,CAAC,CAAC,EAC3D,EAAc,EAAU,OAC7B,CAAC,IAAM,CAAC,EAAU,IAAI,KAAK,UAAU,CAAC,CAAC,CACxC,EAEA,EAAO,KAAK,CACX,KAAM,kBACN,KAAM,GAAY,OAClB,QAAS,EACN,aAAa,qBAA4B,KAAK,UAAU,CAAW,iCACnE,iBAAiB,KAAK,UAAU,CAAW,iCAC9C,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,eACA,eACA,aACD,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EAMD,SAAS,CAAgB,CAC/B,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,WAAa,EAAK,OAAS,QAAS,SAEtD,IAAM,EAAiB,EAAK,OAAS,QAC/B,EAAiB,EAAK,KAAK,MAAM,8BAA8B,EAErE,GAAI,CAAC,GAAkB,CAAC,EAAgB,SAExC,IAAM,EAAW,EAAkB,EAAe,IAAM,KAAQ,KAC1D,EAAW,EAAW,cAAc,IAAa,GAEjD,EAAc,EACjB,EAAmB,EAAK,EAAU,OAAO,EACzC,EAAI,MACD,EAAc,EACjB,EAAmB,EAAK,EAAU,OAAO,EACzC,EAAI,MAEP,EAAO,KAAK,CACX,KAAM,iBACN,KAAM,GAAY,QAClB,QAAS,EACN,aAAa,uBAA8B,KAAK,UAAU,CAAW,wBAAwB,KAAK,UAAU,CAAW,IACvH,mBAAmB,KAAK,UAAU,CAAW,wBAAwB,KAAK,UAAU,CAAW,IAClG,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,cACA,aACD,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EASR,IAAM,EAAmD,IAAI,IAAI,CAChE,CAAC,UAAW,eAAe,EAC3B,CAAC,UAAW,eAAe,EAC3B,CAAC,mBAAoB,mBAAmB,EACxC,CAAC,mBAAoB,mBAAmB,EACxC,CAAC,aAAc,YAAY,EAC3B,CAAC,YAAa,gBAAgB,EAC9B,CAAC,YAAa,gBAAgB,EAC9B,CAAC,WAAY,eAAe,EAC5B,CAAC,WAAY,eAAe,EAC5B,CAAC,gBAAiB,oBAAoB,EACtC,CAAC,gBAAiB,oBAAoB,EACtC,CAAC,cAAe,aAAa,CAC9B,CAAC,EAQM,SAAS,CAAqB,CACpC,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,WAAa,EAAK,OAAS,QAAS,SAGtD,IAAI,EAAyB,KACzB,EAA0B,KAG9B,GAAI,EAAoB,IAAI,EAAK,IAAI,EACpC,EAAU,EAAK,KAIhB,GAAI,CAAC,EAAS,CACb,IAAM,EAAY,EAAK,KAAK,MAAM,6BAA6B,EAC/D,GAAI,IAAY,IAAM,EAAoB,IAAI,EAAU,EAAE,EACzD,EAAW,EAAU,IAAM,KAC3B,EAAU,EAAU,GAItB,GAAI,CAAC,EAAS,SAEd,IAAM,EAAQ,EAAoB,IAAI,CAAO,GAAK,EAC5C,EAAW,EAAW,cAAc,IAAa,GAEjD,EAAc,EACjB,EAAmB,EAAK,EAAU,CAAO,EACxC,EAAgC,GAC9B,EAAc,EACjB,EAAmB,EAAK,EAAU,CAAO,EACxC,EAAgC,GAE9B,EACL,IAAgB,OAAY,OAAO,CAAW,EAAI,OAC7C,EACL,IAAgB,OAAY,OAAO,CAAW,EAAI,OAEnD,EAAO,KAAK,CACX,KAAM,uBACN,KAAM,GAAY,EAClB,QAAS,EACN,aAAa,qBAA4B,KAAS,yBAAmC,KAAS,IAC9F,iBAAiB,KAAS,yBAAmC,KAAS,IACzE,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,WAAY,EACZ,YAAa,GAAe,KAC5B,YAAa,GAAe,IAC7B,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EASD,SAAS,CAAkC,CACjD,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SAExB,GAAI,EAAK,OAAS,uBAAwB,SAE1C,IAAM,EAAe,EAAI,uBAAyB,GAC5C,EAAe,EAAI,uBAAyB,GAElD,EAAO,KAAK,CACX,KAAM,iCACN,KAAM,uBACN,QACC,GAAgB,CAAC,EACd,8DACA,qCAAqC,KAAK,UAAU,EAAK,WAAW,QAAQ,KAAK,UAAU,EAAK,WAAW,IAC/G,QAAS,CACR,eACA,cACD,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EAMD,SAAS,CAAgB,CAC/B,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SAGxB,GAAI,CAAC,EAAK,KAAK,WAAW,OAAO,EAAG,SAGpC,IAAM,EAAU,EAAK,OAAS,QAAU,GAAK,EAAK,KAAK,MAAM,CAAC,EACxD,EAAS,EAAU,KAAK,KAAa,GAE3C,EAAO,KAAK,CACX,KAAM,qBACN,KAAM,EAAK,KACX,QAAS,cAAc,MAAW,EAAe,CAAI,IACrD,QAAS,CACR,OAAQ,EAAe,CAAI,EAC3B,QAAS,GAAW,IACrB,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EAQD,SAAS,CAAiB,CAChC,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,WAAa,EAAK,OAAS,QAAS,SAEtD,IAAM,EAAkB,EAAK,OAAS,SAChC,EAAkB,EAAK,KAAK,MAAM,+BAA+B,EAEvE,GAAI,CAAC,GAAmB,CAAC,EAAiB,SAE1C,IAAM,EAAW,EAAmB,EAAgB,IAAM,KAAQ,KAC5D,EAAW,EAAW,cAAc,IAAa,GAEjD,EAAe,EAClB,EAAmB,EAAK,EAAU,QAAQ,EAC1C,EAAI,OACD,EAAe,EAClB,EAAmB,EAAK,EAAU,QAAQ,EAC1C,EAAI,OAED,EAAc,GAAgB,OAC9B,EAAc,GAAgB,OAEpC,EAAO,KAAK,CACX,KAAM,kBACN,KAAM,GAAY,SAClB,QAAS,EACN,aAAa,yBAAgC,2BAAqC,KAClF,qBAAqB,2BAAqC,KAC7D,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,aAAc,GAAgB,KAC9B,aAAc,GAAgB,IAC/B,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EAMD,SAAS,CAAkB,CACjC,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAyB,CAAC,EAEhC,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAM,GACnB,GAAI,IAAS,OAAW,SACxB,GAAI,EAAK,OAAS,WAAa,EAAK,OAAS,QAAS,SAEtD,IAAM,EAAmB,EAAK,OAAS,UACjC,EAAmB,EAAK,KAAK,MAAM,gCAAgC,EAEzE,GAAI,CAAC,GAAoB,CAAC,EAAkB,SAE5C,IAAM,EAAW,EAAoB,EAAiB,IAAM,KAAQ,KAC9D,EAAW,EAAW,cAAc,IAAa,GAEjD,EAAgB,EACnB,EAAmB,EAAK,EAAU,SAAS,EAC3C,EAAI,QACD,EAAgB,EACnB,EAAmB,EAAK,EAAU,SAAS,EAC3C,EAAI,QAED,EAAc,GAAiB,OAC/B,EAAc,GAAiB,OAErC,EAAO,KAAK,CACX,KAAM,qBACN,KAAM,GAAY,UAClB,QAAS,EACN,aAAa,uBAA8B,yCAAmD,KAC9F,mBAAmB,yCAAmD,KACzE,QAAS,IACJ,EAAW,CAAE,SAAU,CAAS,EAAI,CAAC,EACzC,cAAe,GAAiB,KAChC,cAAe,GAAiB,IACjC,CACD,CAAC,EACD,EAAS,IAAI,CAAC,EAGf,OAAO,EAUD,SAAS,CAAkB,CAAC,EAAgC,CAClE,MAAO,CACN,KAAM,sBACN,KAAM,EAAK,KACX,QAAS,EAAe,CAAI,EAC5B,QAAS,CACR,OAAQ,EAAe,CAAI,EAC3B,eAAgB,EAAK,KACrB,YAAa,EAAK,YAClB,YAAa,EAAK,WACnB,CACD,EAYD,SAAS,CAAkB,CAC1B,EACA,EACA,EACU,CACV,IAAM,EAAO,EAAO,aAAa,GACjC,GAAI,OAAO,IAAS,UAAY,IAAS,MAAQ,CAAC,MAAM,QAAQ,CAAI,EACnE,OAAQ,EAAiC,GAE1C,OAOD,SAAS,CAAc,CAAC,EAA0B,CACjD,OAAQ,EAAK,UACP,QACJ,MAAO,IAAI,EAAK,0BAA0B,KAAK,UAAU,EAAK,WAAW,QACrE,UACJ,MAAO,IAAI,EAAK,0BAA0B,KAAK,UAAU,EAAK,WAAW,aAEzE,MAAO,IAAI,EAAK,sBAAsB,KAAK,UAAU,EAAK,WAAW,QAAQ,KAAK,UAAU,EAAK,WAAW,KCztB/G,IAAM,EAA2C,CAEhD,EACA,EACA,EAGA,EAGA,EACA,EAGA,EAGA,EACA,EAGA,EACA,CACD,EAyBO,SAAS,CAAoB,CACnC,EACA,EACA,EACiB,CAEjB,GAAI,EAAgB,SAAW,EAAG,MAAO,CAAC,EAI1C,GAAI,OAAO,IAAQ,WAAa,OAAO,IAAQ,UAC9C,OAAO,EAAqB,EAAK,EAAK,CAAe,EAGtD,IAAM,EAAyB,CAAC,EAC1B,EAAW,IAAI,IAGrB,QAAW,KAAY,EAAmB,CACzC,IAAM,EAAW,EAAS,EAAK,EAAK,EAAiB,CAAQ,EAC7D,QAAW,KAAQ,EAClB,EAAO,KAAK,CAAI,EAOlB,OAFA,EAAuB,EAAiB,EAAU,CAAM,EAEjD,EAYR,SAAS,CAAoB,CAC5B,EACA,EACA,EACiB,CACjB,GAAI,IAAQ,GACX,MAAO,CACN,CACC,KAAM,sBACN,KAAM,IACN,QAAS,kDACT,QAAS,CAAE,OAAQ,wBAAyB,CAC7C,CACD,EAGD,GAAI,IAAQ,GACX,MAAO,CACN,CACC,KAAM,sBACN,KAAM,IACN,QAAS,kDACT,QAAS,CAAE,OAAQ,wBAAyB,CAC7C,CACD,EAKD,OAAO,EAAgB,IAAI,CAAkB,EAS9C,SAAS,CAAsB,CAC9B,EACA,EACA,EACO,CACP,QAAS,EAAI,EAAG,EAAI,EAAgB,OAAQ,IAAK,CAChD,GAAI,EAAS,IAAI,CAAC,EAAG,SACrB,IAAM,EAAO,EAAgB,GAC7B,GAAI,IAAS,OAAW,SACxB,EAAO,KAAK,EAAmB,CAAI,CAAC,GC5ItC,IAAM,EAA4B,CAAE,SAAU,CAAC,EAAI,EAAG,KAAM,MAAO,EAC7D,GAA6B,CAAE,SAAU,CAAC,EAAK,EAAG,KAAM,MAAO,EAQ/D,EAAoB,IAAI,QAcvB,SAAS,EAAgB,CAAC,EAA0C,CAC1E,GAAI,OAAO,IAAQ,UAClB,OAAO,EAAM,EAAc,GAE5B,GAAI,EAAO,EAAK,OAAO,GAAK,MAAM,QAAQ,EAAI,KAAK,EAClD,MAAO,CAAE,SAAU,EAAI,MAAO,KAAM,OAAQ,EAE7C,GAAI,EAAO,EAAK,OAAO,GAAK,MAAM,QAAQ,EAAI,KAAK,EAClD,MAAO,CAAE,SAAU,EAAI,MAAO,KAAM,OAAQ,EAG7C,IAAI,EAAS,EAAkB,IAAI,CAAG,EACtC,GAAI,IAAW,OACd,EAAS,CAAE,SAAU,CAAC,CAAG,EAAG,KAAM,MAAO,EACzC,EAAkB,IAAI,EAAK,CAAM,EAElC,OAAO,EAkCR,SAAS,CAAW,CACnB,EACA,EACiB,CACjB,GAAI,OAAO,IAAQ,WAAa,OAAO,IAAQ,UAAW,OAAO,KAWjE,GAAI,EAAO,EAAK,KAAK,GAAK,EAAW,EAAI,GAAG,EAAG,CAC9C,IAAM,EAAY,EAAI,IAUtB,GAAI,EAAW,EAAU,UAAU,GAAK,MAAM,QAAQ,EAAU,QAAQ,EAAG,CAC1E,IAA2B,WAArB,EAIwB,SAAxB,GAAc,EAGpB,GAAI,EAAW,EAAI,UAAU,EAAG,CAC/B,IAAM,EAAW,EAAI,WAIf,EAAc,MAAM,QAAQ,EAAI,QAAQ,EAC1C,EAAI,SACL,CAAC,EACE,EAAc,OAAO,KAAK,CAAQ,EAsDxC,GAjD4B,EAAY,KAAK,CAAC,IAAQ,CACrD,IAAM,EAAa,EAAS,GAC5B,GAAI,OAAO,IAAe,UAAW,MAAO,GAC5C,IAAM,EAAU,EAKhB,GACC,EAAY,SAAS,CAAG,GACxB,CAAC,EAAY,SAAS,CAAG,GACzB,CAAC,EAAO,EAAU,CAAG,EAErB,MAAO,GAIR,GAAI,CAAC,EAAO,EAAU,CAAG,EAAG,MAAO,GACnC,IAAM,EAAa,EAAS,GAC5B,GAAI,OAAO,IAAe,UAAW,MAAO,GAC5C,IAAM,EAAU,EAGhB,GAAI,EAAO,EAAS,OAAO,GAAK,EAAO,EAAS,OAAO,GACtD,GAAI,CAAC,EAAU,EAAQ,MAAO,EAAQ,KAAK,EAC1C,MAAO,GAMT,GAAI,EAAO,EAAS,MAAM,GAAK,MAAM,QAAQ,EAAQ,IAAI,EAAG,CAC3D,GAAI,EAAO,EAAS,OAAO,GAI1B,GAAI,CAHc,EAAQ,KAAK,KAAK,CAAC,IACpC,EAAU,EAAG,EAAQ,KAAK,CAC3B,EACgB,MAAO,GAExB,GAAI,EAAO,EAAS,MAAM,GAAK,MAAM,QAAQ,EAAQ,IAAI,GAIxD,GAHsB,EAAQ,KAAK,MAClC,CAAC,IAAM,CAAC,EAAQ,MAAM,KAAK,CAAC,IAAO,EAAU,EAAG,CAAE,CAAC,CACpD,EACmB,MAAO,IAI5B,MAAO,GACP,EAEwB,MAAO,GAsChC,GAlCsB,EAAY,MAAM,CAAC,IAAQ,CAChD,IAAM,EAAa,EAAS,GAC5B,GAAI,OAAO,IAAe,UAAW,MAAO,GAC5C,IAAM,EAAU,EAGhB,GAAI,EAAY,SAAS,CAAG,GAAK,CAAC,EAAY,SAAS,CAAG,EACzD,MAAO,GACR,GAAI,CAAC,EAAO,EAAU,CAAG,EAAG,MAAO,GACnC,IAAM,EAAa,EAAS,GAC5B,GAAI,OAAO,IAAe,UAAW,MAAO,GAC5C,IAAM,EAAU,EAGhB,GAAI,EAAO,EAAS,OAAO,GAAK,EAAO,EAAS,OAAO,EACtD,OAAO,EAAU,EAAQ,MAAO,EAAQ,KAAK,EAI9C,GAAI,EAAO,EAAS,MAAM,GAAK,MAAM,QAAQ,EAAQ,IAAI,EAAG,CAC3D,GAAI,EAAO,EAAS,OAAO,EAC1B,OAAO,EAAQ,KAAK,KAAK,CAAC,IAAM,EAAU,EAAG,EAAQ,KAAK,CAAC,EAE5D,GAAI,EAAO,EAAS,MAAM,GAAK,MAAM,QAAQ,EAAQ,IAAI,EAExD,OAAO,EAAQ,KAAK,MAAM,CAAC,IAC1B,EAAQ,MAAM,KAAK,CAAC,IAAO,EAAU,EAAG,CAAE,CAAC,CAC5C,EAIF,MAAO,GACP,EAEkB,MAAO,IAU5B,GAAI,EAAO,EAAW,OAAO,GAAK,EAAO,EAAK,OAAO,EAAG,CACvD,IAAM,EAAW,EAAU,MACrB,EAAW,EAAI,MACrB,GAAI,EAAU,EAAU,CAAQ,EAAG,MAAO,GAC1C,MAAO,GAKR,GACC,EAAO,EAAW,MAAM,GACxB,MAAM,QAAQ,EAAU,IAAI,GAC5B,EAAO,EAAK,MAAM,GAClB,MAAM,QAAQ,EAAI,IAAI,GAMtB,GAHoB,EAAI,KAAK,MAC5B,CAAC,IAAQ,CAAC,EAAU,MAAM,KAAK,CAAC,IAAW,EAAU,EAAK,CAAM,CAAC,CAClE,EACiB,MAAO,GAUzB,GAAI,EAAO,EAAW,MAAM,GAAK,EAAO,EAAK,MAAM,EAAG,CACrD,IAAM,EAAU,EAAU,KACpB,EAAU,EAAI,KAGpB,GAAI,OAAO,IAAY,UAAY,OAAO,IAAY,UAGrD,GACC,CAAC,EAAO,EAAW,OAAO,GAC1B,CAAC,EAAO,EAAW,MAAM,GACzB,CAAC,EAAW,EAAU,UAAU,EAC/B,CACD,GAAI,IAAY,EAAS,MAAO,GAChC,MAAO,IAKT,GAAI,MAAM,QAAQ,CAAO,GAAK,OAAO,IAAY,SAAU,CAC1D,GAAI,EAAQ,SAAS,CAAO,EAAG,MAAO,GACtC,MAAO,IAOT,GAAI,EAAO,EAAW,OAAO,GAAK,MAAM,QAAQ,EAAU,KAAK,EAAG,CACjE,IAAM,EAAW,EAAU,MAW3B,GATwB,EAAS,MAAM,CAAC,IAAW,CAClD,GAAI,OAAO,IAAW,UAAW,MAAO,CAAC,EAMzC,OAJe,EAAY,EAAK,CAAE,IAAK,CAAO,CAAC,IAI7B,GAClB,EACoB,MAAO,GAQ5B,GALyB,EAAS,KAAK,CAAC,IAAW,CAClD,GAAI,OAAO,IAAW,UAAW,OAAO,EAExC,OADe,EAAY,EAAK,CAAE,IAAK,CAAO,CAAC,IAC7B,GAClB,EACqB,MAAO,GAI9B,GAAI,EAAO,EAAW,OAAO,GAAK,MAAM,QAAQ,EAAU,KAAK,EAAG,CACjE,IAAM,EAAW,EAAU,MAM3B,GALwB,EAAS,MAAM,CAAC,IAAW,CAClD,GAAI,OAAO,IAAW,UAAW,MAAO,CAAC,EAEzC,OADe,EAAY,EAAK,CAAE,IAAK,CAAO,CAAC,IAC7B,GAClB,EACoB,MAAO,GAO5B,GALyB,EAAS,KAAK,CAAC,IAAW,CAClD,GAAI,OAAO,IAAW,UAAW,OAAO,EAExC,OADe,EAAY,EAAK,CAAE,IAAK,CAAO,CAAC,IAC7B,GAClB,EACqB,MAAO,GAK9B,GAAI,EAAO,EAAW,QAAQ,GAAK,EAAO,EAAK,QAAQ,EAAG,CACzD,IAAM,EAAY,EAAI,OAChB,EAAY,EAAU,OAC5B,GAAI,IAAc,EAAW,MAAO,GAEpC,MAAO,IAKT,GAAI,EAAO,EAAK,KAAK,GAAK,EAAO,EAAK,KAAK,GAC1C,GAAI,EAAU,EAAI,IAAK,EAAI,GAAG,EAAG,MAAO,GAGzC,OAAO,KAiBR,SAAS,CAAe,CACvB,EACA,EACA,EAAyB,GACD,CACxB,GAAI,OAAO,IAAQ,WAAa,OAAO,IAAQ,UAAW,OAAO,EAEjE,IAAI,EAAS,EAGb,GAAI,GAAiB,EAAO,EAAQ,KAAK,EACxC,EAAS,EAAS,EAA8C,CAC/D,KACD,CAAC,EAMF,GACC,EAAW,EAAO,UAAU,GAC5B,EAAY,EAAoB,UAAU,EACzC,CACD,IAAM,EAAY,EAAoB,WAIhC,EAAW,EAAO,WACpB,EAEJ,QAAW,KAAO,OAAO,KAAK,CAAQ,EAAG,CACxC,IAAM,EAAa,EAAS,GACtB,EAAa,EAAS,GAC5B,GACC,IAAe,QACf,IAAe,QACf,OAAO,IAAe,WACtB,OAAO,IAAe,WACtB,EAAO,EAAY,KAAK,GAIxB,GADsB,EAAY,EAAY,CAAU,IAClC,GAAM,CAE3B,GAAI,CAAC,EAAU,EAAW,IAAK,CAAS,EACxC,EAAS,GAAO,EACf,EACA,CAAC,KAAK,CACP,IAKH,GAAI,EACH,EAAS,IAAK,EAAQ,WAAY,CAAS,EAI7C,OAAO,EAoBR,SAAS,CAAmB,CAC3B,EACA,EACwB,CACxB,GAAI,OAAO,IAAQ,WAAa,OAAO,IAAQ,UAAW,OAAO,EAEjE,IAAM,EAAsB,EAGxB,EAAsB,EACtB,EAAS,GAEb,SAAS,CAAU,EAAgB,CAClC,GAAI,CAAC,EACJ,EAAS,IAAK,CAAO,EACrB,EAAS,GAEV,OAAO,EAIR,GACC,EAAO,EAAQ,SAAS,GACxB,EAAO,EAAK,SAAS,GACrB,EAAO,UAAa,EAAoB,SAMxC,GAJkB,EAChB,EAAoB,QACrB,EAAO,OACR,IACkB,GACjB,EAAS,EAAS,EAAW,EAAyC,CACrE,SACD,CAAC,EACD,EAAS,GAKX,GACC,EAAW,EAAO,UAAU,GAC5B,EAAY,EAAoB,UAAU,EACzC,CACD,IAAM,EAAY,EAAoB,WAIhC,EAAW,EAAO,WACpB,EAAgB,GAChB,EAEJ,QAAW,KAAO,OAAO,KAAK,CAAQ,EAAG,CACxC,IAAM,EAAa,EAAS,GACtB,EAAa,EAAS,GAC5B,GACC,IAAe,QACf,IAAe,QACf,OAAO,IAAe,WACtB,OAAO,IAAe,WACtB,EAAO,EAAY,SAAS,GAC5B,EAAO,EAAY,SAAS,GAC5B,EAAW,UAAY,EAAW,SAMlC,GAJsB,EACpB,EAA2B,QAC3B,EAA2B,OAC7B,IACsB,GAAM,CAC3B,GAAI,CAAC,EAAU,EAAW,IAAK,CAAS,EACxC,EAAS,GAAO,EACf,EACA,CAAC,SAAS,CACX,EACA,EAAgB,KAKnB,GAAI,GAAiB,EACpB,EAAW,EAAE,WAAa,EAK5B,GACC,EAAW,EAAO,KAAK,GACvB,OAAO,EAAO,QAAU,WACxB,EAAY,EAAoB,KAAK,GACrC,OAAQ,EAAoB,QAAU,UACrC,CACD,IAAM,EAAY,EAAoB,MAChC,EAAW,EAAO,MACxB,GACC,EAAO,EAAU,SAAS,GAC1B,EAAO,EAAU,SAAS,GAC1B,EAAS,UAAY,EAAS,SAM9B,GAJuB,EACtB,EAAS,QACT,EAAS,OACV,IACuB,GACtB,EAAW,EAAE,MAAQ,EACpB,EACA,CAAC,SAAS,CACX,GAKH,OAAO,EAuBD,SAAS,EAAgB,CAC/B,EACA,EACA,EACU,CACV,IAAQ,SAAU,GAAgB,GAAiB,CAAG,EAGtD,GAAI,EAAY,SAAW,GAAK,EAAY,KAAO,EAAK,CAEvD,IAAM,EAAY,EAAY,EAAK,CAAG,EACtC,GAAI,IAAc,GAAO,MAAO,GAOhC,GACC,OAAO,IAAQ,WACf,OAAO,IAAQ,WACf,EAAO,EAAK,QAAQ,GACpB,EAAO,EAAK,QAAQ,GACpB,EAAI,SAAW,EAAI,QAMnB,GAJkB,EACjB,EAAI,OACJ,EAAI,MACL,IACkB,GAAM,MAAO,GAQhC,GACC,OAAO,IAAQ,WACf,OAAO,IAAQ,WACf,EAAO,EAAK,SAAS,GACrB,EAAO,EAAK,SAAS,GACrB,EAAI,UAAY,EAAI,SAMpB,GAJkB,EACjB,EAAI,QACJ,EAAI,OACL,IACkB,GAAO,MAAO,GAOjC,IAAI,EAAe,EACnB,GAAI,OAAO,IAAQ,UAAW,CAE7B,GAAI,IAAc,IAGjB,GAFA,EAAe,EAAgB,EAAK,EAAK,EAAI,EAG5C,OAAO,IAAiB,WACxB,OAAO,KAAK,CAAY,EAAE,SAAW,EAErC,MAAO,GAMR,OAAe,EAAgB,EAAK,EAAK,EAAK,EAO/C,EAAe,EAAoB,EAAK,CAAY,EAGrD,IAAM,EAAS,EAAO,MAAM,EAAK,CAAY,EAC7C,GAAI,IAAW,KAAM,MAAO,GAI5B,GAAI,EAAU,EAAQ,CAAG,EAAG,MAAO,GAGnC,IAAM,EAAmB,EAAU,CAAM,EACzC,OACC,EAAU,EAAkB,CAAG,GAAK,EAAO,QAAQ,EAAkB,CAAG,EAK1E,OAAO,EAAY,KAAK,CAAC,IAAW,CAEnC,IAAM,EAAY,EAAY,EAAK,CAAM,EACzC,GAAI,IAAc,GAAO,MAAO,GAGhC,GACC,OAAO,IAAQ,WACf,OAAO,IAAW,WAClB,EAAO,EAAK,SAAS,GACrB,EAAO,EAAQ,SAAS,GACxB,EAAI,UAAY,EAAO,SAMvB,GAJkB,EACjB,EAAI,QACJ,EAAO,OACR,IACkB,GAAO,MAAO,GAIjC,IAAI,EAAkB,EACtB,GAAI,OAAO,IAAW,UAAW,CAChC,GAAI,IAAc,IAEjB,GADA,EAAkB,EAAgB,EAAK,EAAQ,EAAI,EAElD,OAAO,IAAoB,WAC3B,OAAO,KAAK,CAAe,EAAE,SAAW,EAExC,MAAO,GAGR,OAAkB,EAAgB,EAAK,EAAQ,EAAK,EAIrD,EAAkB,EAAoB,EAAK,CAAe,EAG3D,IAAM,EAAS,EAAO,MAAM,EAAK,CAAe,EAChD,GAAI,IAAW,KAAM,MAAO,GAE5B,GAAI,EAAU,EAAQ,CAAG,EAAG,MAAO,GACnC,IAAM,EAAmB,EAAU,CAAM,EACzC,OACC,EAAU,EAAkB,CAAG,GAAK,EAAO,QAAQ,EAAkB,CAAG,EAEzE,EAcK,SAAS,EAAgB,CAC/B,EACA,EACA,EACA,EAAyB,QACV,CACf,IAAM,EAAyB,CAAC,EAC5B,EAAY,GAGV,EAAc,IAAe,OAAS,QAAU,EAEtD,QAAS,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC5C,IAAM,EAAS,EAAY,GAC3B,GAAI,IAAW,OAAW,SAC1B,GAAI,CAAC,GAAiB,EAAQ,EAAK,CAAM,EACxC,EAAY,GACZ,EAAS,KAAK,CACb,KAAM,GAAG,KAAe,KACxB,KAAM,UACN,YAAa,EACb,YAAa,iCACd,CAAC,EAIH,IAAM,EAAgB,EACnB,CAAC,EACD,EAAqB,EAAY,IAAM,GAAM,EAAK,CAAQ,EAE7D,MAAO,CACN,SAAU,EACV,OAAQ,EACL,IAAe,QACd,CAAE,MAAO,CAAY,EACrB,CAAE,MAAO,CAAY,EACtB,KACH,MAAO,EACP,eACD,EAWM,SAAS,EAAgB,CAC/B,EACA,EACA,EACA,EAAyB,QACV,CACf,QAAW,KAAU,EAAa,CAEjC,IAAI,EAAkB,EACtB,GAAI,OAAO,IAAQ,WAAa,OAAO,IAAW,UACjD,EAAkB,EAAoB,EAAK,CAAM,EAElD,IAAM,EAAS,EAAO,MAAM,EAAK,CAAe,EAChD,GAAI,IAAW,KAAM,CAEpB,GAAI,EAAU,EAAQ,CAAG,EACxB,MAAO,CAAE,SAAU,GAAM,SAAQ,MAAO,CAAC,EAAG,cAAe,CAAC,CAAE,EAE/D,IAAM,EAAmB,EAAU,CAAM,EACzC,GACC,EAAU,EAAkB,CAAG,GAC/B,EAAO,QAAQ,EAAkB,CAAG,EAEpC,MAAO,CAAE,SAAU,GAAM,SAAQ,MAAO,CAAC,EAAG,cAAe,CAAC,CAAE,GAQjE,IAAM,EAA8B,CACnC,CACC,KAAM,IACN,KAAM,UACN,YAAa,EACb,YAAa,2BAPK,IAAe,OAAS,QAAU,uBAQrD,CACD,EAEA,MAAO,CACN,SAAU,GACV,OAAQ,KACR,MAAO,EACP,cAAe,EACd,EACA,IAAe,QAAU,CAAE,MAAO,CAAY,EAAI,CAAE,MAAO,CAAY,EACvE,CACD,CACD,EAUM,SAAS,EAAW,CAC1B,EACA,EACA,EACe,CAIf,IAAI,EAAe,EACnB,GAAI,OAAO,IAAQ,WAAa,OAAO,IAAQ,UAC9C,EAAe,EAAoB,EAAK,CAAG,EAG5C,GAAI,CACH,IAAM,EAAS,EAAO,aAAa,EAAK,CAAY,EAGpD,GAAI,EAAU,EAAQ,CAAG,EACxB,MAAO,CAAE,SAAU,GAAM,SAAQ,MAAO,CAAC,EAAG,cAAe,CAAC,CAAE,EAG/D,IAAM,EAAmB,EAAU,CAAM,EAEzC,GACC,EAAU,EAAkB,CAAG,GAC/B,EAAO,QAAQ,EAAkB,CAAG,EAEpC,MAAO,CACN,SAAU,GACV,OAAQ,EACR,MAAO,CAAC,EACR,cAAe,CAAC,CACjB,EAGD,IAAM,EAAQ,EAAa,EAAK,EAAkB,EAAE,EAC9C,EAAgB,EAAqB,EAAK,EAAc,CAAK,EACnE,MAAO,CAAE,SAAU,GAAO,OAAQ,EAAkB,QAAO,eAAc,EACxE,MAAO,EAAG,CACX,IAAM,EAAsB,CAC3B,CACC,KAAM,IACN,KAAM,UACN,YAAa,EACb,YAAa,iBAAiB,aAAa,MAAQ,EAAE,QAAU,OAAO,CAAC,GACxE,CACD,EACA,MAAO,CACN,SAAU,GACV,OAAQ,KACR,QACA,cAAe,EAAqB,EAAK,EAAc,CAAK,CAC7D",
10
+ "debugId": "189EA8740626810064756E2164756E21",
11
+ "names": []
12
+ }
@@ -0,0 +1,7 @@
1
+ var z={"missing-required-property":"\uD83D\uDD34","property-not-guaranteed":"\uD83D\uDFE1","type-mismatch":"\uD83D\uDD34","type-too-wide":"\uD83D\uDFE0","enum-not-subset":"\uD83D\uDFE0","const-mismatch":"\uD83D\uDD34","constraint-too-loose":"\uD83D\uDFE1","additional-properties-conflict":"\uD83D\uDFE0","property-not-allowed":"\uD83D\uDD34","format-mismatch":"\uD83D\uDFE1","pattern-not-subset":"\uD83D\uDFE1","incompatible-items":"\uD83D\uDFE0","schema-incompatible":"\uD83D\uDD34"};function B(j){switch(j.type){case"added":return` + ${j.path}: ${JSON.stringify(j.mergedValue)}`;case"removed":return` - ${j.path}: was ${JSON.stringify(j.sourceValue)}`;default:return` ~ ${j.path}: ${JSON.stringify(j.sourceValue)} → ${JSON.stringify(j.mergedValue)}`}}function y(j){return` ${z[j.type]??"⚪"} [${j.type}] ${j.message}`}function H(j,k){let w=[`${k.isSubset?"✅":"❌"} ${j}: ${k.isSubset}`];if(!k.isSubset){if(k.semanticDiffs&&k.semanticDiffs.length>0){w.push(" Diffs:");for(let x of k.semanticDiffs)w.push(` ${y(x)}`)}else if(k.diffs.length>0){w.push(" Diffs (structural):");for(let x of k.diffs)w.push(` ${B(x)}`)}}return w.join(`
2
+ `)}function J(j){if(j.length===0)return"";return j.map(y).join(`
3
+ `)}
4
+ export{H as n,J as o};
5
+
6
+ //# debugId=D076377302008F4164756E2164756E21
7
+ //# sourceMappingURL=chunk-8qenxa2z.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/formatter.ts"],
4
+ "sourcesContent": [
5
+ "import type { SemanticDiff } from \"./semantic-diff/types\";\nimport type { SubsetResult } from \"./types\";\n\n// ─── Result Formatter ────────────────────────────────────────────────────────\n//\n// Formate un `SubsetResult` en chaîne lisible pour logs / debug.\n// Supporte les diffs structurelles (legacy) et les diffs sémantiques.\n\n// ─── Semantic diff icons ─────────────────────────────────────────────────────\n\n/** Icône associée à chaque type de diff sémantique */\nconst SEMANTIC_ICONS: Readonly<Record<string, string>> = {\n\t\"missing-required-property\": \"🔴\",\n\t\"property-not-guaranteed\": \"🟡\",\n\t\"type-mismatch\": \"🔴\",\n\t\"type-too-wide\": \"🟠\",\n\t\"enum-not-subset\": \"🟠\",\n\t\"const-mismatch\": \"🔴\",\n\t\"constraint-too-loose\": \"🟡\",\n\t\"additional-properties-conflict\": \"🟠\",\n\t\"property-not-allowed\": \"🔴\",\n\t\"format-mismatch\": \"🟡\",\n\t\"pattern-not-subset\": \"🟡\",\n\t\"incompatible-items\": \"🟠\",\n\t\"schema-incompatible\": \"🔴\",\n};\n\n// ─── Structural diff formatting (legacy) ─────────────────────────────────────\n\n/**\n * Formate un diff structurel individuel en ligne lisible avec préfixe iconique.\n *\n * @param d Le diff à formater\n * @returns Ligne formatée avec +, - ou ~ selon le type\n */\nfunction formatStructuralDiffLine(d: {\n\ttype: string;\n\tpath: string;\n\tsourceValue: unknown;\n\tmergedValue: unknown;\n}): string {\n\tswitch (d.type) {\n\t\tcase \"added\":\n\t\t\treturn ` + ${d.path}: ${JSON.stringify(d.mergedValue)}`;\n\t\tcase \"removed\":\n\t\t\treturn ` - ${d.path}: was ${JSON.stringify(d.sourceValue)}`;\n\t\tdefault:\n\t\t\treturn ` ~ ${d.path}: ${JSON.stringify(d.sourceValue)} → ${JSON.stringify(d.mergedValue)}`;\n\t}\n}\n\n// ─── Semantic diff formatting ────────────────────────────────────────────────\n\n/**\n * Formate un diff sémantique en ligne lisible avec icône et message.\n *\n * @param d Le diff sémantique à formater\n * @returns Ligne formatée avec icône, type et message\n */\nfunction formatSemanticDiffLine(d: SemanticDiff): string {\n\tconst icon = SEMANTIC_ICONS[d.type] ?? \"⚪\";\n\treturn ` ${icon} [${d.type}] ${d.message}`;\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Formate un SubsetResult en chaîne lisible (utile pour logs/debug).\n *\n * Affiche les diffs sémantiques en priorité (si disponibles),\n * avec un fallback sur les diffs structurelles.\n *\n * @param label Label descriptif du check (ex: \"strict ⊆ loose\")\n * @param result Le résultat du check à formater\n * @returns Chaîne multi-lignes formatée avec icônes et diffs\n *\n * @example\n * ```\n * ✅ strict ⊆ loose: true\n * ```\n *\n * @example\n * ```\n * ❌ loose ⊆ strict: false\n * Diffs:\n * 🔴 [missing-required-property] Target requires property 'meetingId' (string) which source does not provide\n * ```\n */\nexport function formatResult(label: string, result: SubsetResult): string {\n\tconst icon = result.isSubset ? \"✅\" : \"❌\";\n\tconst lines: string[] = [`${icon} ${label}: ${result.isSubset}`];\n\n\tif (!result.isSubset) {\n\t\t// Prefer semantic diffs over structural diffs\n\t\tif (result.semanticDiffs && result.semanticDiffs.length > 0) {\n\t\t\tlines.push(\" Diffs:\");\n\t\t\tfor (const d of result.semanticDiffs) {\n\t\t\t\tlines.push(` ${formatSemanticDiffLine(d)}`);\n\t\t\t}\n\t\t} else if (result.diffs.length > 0) {\n\t\t\tlines.push(\" Diffs (structural):\");\n\t\t\tfor (const d of result.diffs) {\n\t\t\t\tlines.push(` ${formatStructuralDiffLine(d)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Formate uniquement les diffs sémantiques en chaîne lisible.\n *\n * Utile quand on veut afficher les diagnostics sans le résultat global.\n *\n * @param diffs Les diffs sémantiques à formater\n * @returns Chaîne multi-lignes, ou chaîne vide si pas de diffs\n */\nexport function formatSemanticDiffs(diffs: SemanticDiff[]): string {\n\tif (diffs.length === 0) return \"\";\n\treturn diffs.map(formatSemanticDiffLine).join(\"\\n\");\n}\n"
6
+ ],
7
+ "mappings": "AAWA,IAAM,EAAmD,CACxD,4BAA6B,eAC7B,0BAA2B,eAC3B,gBAAiB,eACjB,gBAAiB,eACjB,kBAAmB,eACnB,iBAAkB,eAClB,uBAAwB,eACxB,iCAAkC,eAClC,uBAAwB,eACxB,kBAAmB,eACnB,qBAAsB,eACtB,qBAAsB,eACtB,sBAAuB,cACxB,EAUA,SAAS,CAAwB,CAAC,EAKvB,CACV,OAAQ,EAAE,UACJ,QACJ,MAAO,OAAO,EAAE,SAAS,KAAK,UAAU,EAAE,WAAW,QACjD,UACJ,MAAO,OAAO,EAAE,aAAa,KAAK,UAAU,EAAE,WAAW,YAEzD,MAAO,OAAO,EAAE,SAAS,KAAK,UAAU,EAAE,WAAW,OAAM,KAAK,UAAU,EAAE,WAAW,KAY1F,SAAS,CAAsB,CAAC,EAAyB,CAExD,MAAO,KADM,EAAe,EAAE,OAAS,QAClB,EAAE,SAAS,EAAE,UA2B5B,SAAS,CAAY,CAAC,EAAe,EAA8B,CAEzE,IAAM,EAAkB,CAAC,GADZ,EAAO,SAAW,IAAK,OACA,MAAU,EAAO,UAAU,EAE/D,GAAI,CAAC,EAAO,UAEX,GAAI,EAAO,eAAiB,EAAO,cAAc,OAAS,EAAG,CAC5D,EAAM,KAAK,WAAW,EACtB,QAAW,KAAK,EAAO,cACtB,EAAM,KAAK,QAAQ,EAAuB,CAAC,GAAG,EAEzC,QAAI,EAAO,MAAM,OAAS,EAAG,CACnC,EAAM,KAAK,wBAAwB,EACnC,QAAW,KAAK,EAAO,MACtB,EAAM,KAAK,QAAQ,EAAyB,CAAC,GAAG,GAKnD,OAAO,EAAM,KAAK;AAAA,CAAI,EAWhB,SAAS,CAAmB,CAAC,EAA+B,CAClE,GAAI,EAAM,SAAW,EAAG,MAAO,GAC/B,OAAO,EAAM,IAAI,CAAsB,EAAE,KAAK;AAAA,CAAI",
8
+ "debugId": "D076377302008F4164756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,5 +1,5 @@
1
- import{r as w}from"./chunk-07z7fc5q.js";import{t as E}from"./chunk-yqhv3py7.js";import{v as L,w as Y,x as B,y as I,z as R}from"./chunk-jkdzdb3r.js";var x=new Set(["required","properties","dependencies"]),D=new Set(["additionalProperties","items","contains","propertyNames","not"]),C=new Set(["minimum","exclusiveMinimum","minLength","minItems","minProperties"]),P=new Set(["maximum","exclusiveMaximum","maxLength","maxItems","maxProperties"]);function O(J,W){if(W===void 0)return!0;let H=Array.isArray(W)?W:[W],z=E(J);return H.some((Q)=>Q===z||Q==="number"&&z==="integer")}function V(J,W){if(W.minimum!==void 0&&!(J>=W.minimum))return!1;if(W.maximum!==void 0&&!(J<=W.maximum))return!1;if(W.exclusiveMinimum!==void 0&&!(J>W.exclusiveMinimum))return!1;if(W.exclusiveMaximum!==void 0&&!(J<W.exclusiveMaximum))return!1;if(W.multipleOf!==void 0&&J%W.multipleOf!==0)return!1;return!0}var T=new Map;function k(J){let W=T.get(J);if(W===void 0)W=new RegExp(J),T.set(J,W);return W}function g(J,W){if(W.minLength!==void 0&&!(J.length>=W.minLength))return!1;if(W.maxLength!==void 0&&!(J.length<=W.maxLength))return!1;if(W.pattern!==void 0&&!k(W.pattern).test(J))return!1;return!0}function f(J,W){if(W.minItems!==void 0&&!(J.length>=W.minItems))return!1;if(W.maxItems!==void 0&&!(J.length<=W.maxItems))return!1;if(W.uniqueItems===!0){let H=J.length;for(let z=0;z<H;z++)for(let Q=z+1;Q<H;Q++)if(B(J[z],J[Q]))return!1}return!0}function q(J,W){if(L(J.properties)){if(!Object.keys(J.properties).every((z)=>{let Q=J.properties?.[z];if(typeof Q==="boolean")return!0;let $=Q,Z=W[z];if(Z===void 0)return!0;if(Y($,"const")){if(!B(Z,$.const))return!1}if(Y($,"enum")){if(!$.enum?.some((F)=>B(F,Z)))return!1}if(Y($,"type")&&Z!==void 0){if(!O(Z,$.type))return!1}if(typeof Z==="number"){if(!V(Z,$))return!1}if(typeof Z==="string"){if(!g(Z,$))return!1}if(Array.isArray(Z)){if(!f(Z,$))return!1}if($.format!==void 0&&typeof Z==="string"){if(w(Z,$.format)===!1)return!1}if(L($.properties)||Array.isArray($.required)){if(L(Z)){if(!q($,Z))return!1}}return!0}))return!1}if(Array.isArray(J.required)){if(!J.required.every((z)=>Y(W,z)))return!1}if(Array.isArray(J.allOf)){if(!J.allOf.every((z)=>{if(typeof z==="boolean")return z;return q(z,W)}))return!1}if(Array.isArray(J.anyOf)){if(!J.anyOf.some((z)=>{if(typeof z==="boolean")return z;return q(z,W)}))return!1}if(Array.isArray(J.oneOf)){let H=0;for(let z of J.oneOf){if(typeof z==="boolean"?z:q(z,W))H++;if(H>1)break}if(H!==1)return!1}if(Y(J,"not")&&L(J.not)&&typeof J.not!=="boolean"){if(q(J.not,W))return!1}return!0}var S=["const","enum","minimum","maximum","exclusiveMinimum","exclusiveMaximum","pattern","minLength","maxLength","multipleOf","minItems","maxItems","format"];function K(J,W,H){if(!L(J.properties))return;let z=J.properties;for(let Q of Object.keys(z)){let $=z[Q];if(typeof $==="boolean")continue;let Z=$;if(S.some((G)=>Y(Z,G))&&Y(W,Q))H[Q]=W[Q]}}function j(J,W,H){if(typeof W==="boolean")return;let z=W;if(Array.isArray(z.required))J.required=R(J.required??[],z.required);if(L(z.properties)){let Q=z.properties,$={...J.properties??{}};for(let Z of Object.keys(Q)){let F=Q[Z];if(F===void 0)continue;let G=J.properties?.[Z];if(G!==void 0&&typeof G!=="boolean"&&typeof F!=="boolean"){let U=H.merge(G,F);$[Z]=U??F}else $[Z]=F}J.properties=$}if(L(z.dependencies)){let Q=J.dependencies??{},$=z.dependencies,Z={...Q};for(let F of Object.keys($)){let G=$[F];if(G===void 0)continue;let U=Z[F];if(U===void 0)Z[F]=G;else if(Array.isArray(U)&&Array.isArray(G))Z[F]=R(U,G);else if(L(U)&&L(G)){let X=H.merge(U,G);Z[F]=X??G}else Z[F]=G}J.dependencies=Z}for(let Q of Object.keys(z)){if(x.has(Q))return;let $=z[Q],Z=J[Q];if(Z===void 0){J[Q]=$;return}if(B(Z,$))return;if(D.has(Q)){let X=H.merge(Z,$);if(X!==null)J[Q]=X;else J[Q]=$;return}if(C.has(Q)){if(typeof Z==="number"&&typeof $==="number")J[Q]=Math.max(Z,$);else J[Q]=$;return}if(P.has(Q)){if(typeof Z==="number"&&typeof $==="number")J[Q]=Math.min(Z,$);else J[Q]=$;return}if(Q==="uniqueItems"){J[Q]=Z===!0||$===!0;return}if(Q==="pattern"||Q==="format"){J[Q]=$;return}let F={[Q]:Z},G={[Q]:$},U=H.merge(F,G);if(U&&typeof U!=="boolean"&&Y(U,Q))J[Q]=U[Q];else J[Q]=$}}function b(J,W,H){let z=null,Q={},$=J.if!==void 0,Z=Array.isArray(J.allOf)&&J.allOf.some((G)=>typeof G!=="boolean"&&Y(G,"if"));if(!$&&!Z)return{resolved:_(J,W,H,Q),branch:z,discriminant:Q};let F={...J};if(Z)F=u(F,W,H,Q);if(F.if!==void 0){let G=F.if,U=q(G,W);K(G,W,Q);let X=U?F.then:F.else;if(z=U?"then":"else",X)j(F,X,H);delete F.if,delete F.then,delete F.else}return F=_(F,W,H,Q),{resolved:F,branch:z,discriminant:Q}}function u(J,W,H,z){if(!Array.isArray(J.allOf))return J;let Q=[];for(let $ of J.allOf){if(typeof $==="boolean"){Q.push($);continue}let Z=$;if(Z.if===void 0){Q.push($);continue}let F=Z.if,G=q(F,W);K(F,W,z);let U=G?Z.then:Z.else;if(U)j(J,U,H);let X=I(Z,["if","then","else"]);if(Object.keys(X).length>0)Q.push(X)}if(J={...J},Q.length===0)delete J.allOf;else J.allOf=Q;return J}function _(J,W,H,z){if(!L(J.properties))return J;let Q=J.properties,$=Object.keys(Q),Z=!1,F={};for(let G of $){let U=Q[G];if(U===void 0)continue;if(typeof U==="boolean"){F[G]=U;continue}let X=U;if(!(X.if!==void 0||Array.isArray(X.allOf)&&X.allOf.some((M)=>typeof M!=="boolean"&&Y(M,"if")))){F[G]=U;continue}let A=L(W[G])?W[G]:{},N=b(X,A,H);for(let M of Object.keys(N.discriminant))z[`${G}.${M}`]=N.discriminant[M];F[G]=N.resolved,Z=!0}return Z?{...J,properties:F}:J}
2
- export{b as k};
1
+ import{t as w}from"./chunk-gdf3h8q4.js";import{v as E}from"./chunk-ywa6h8q4.js";import{A as I,B as R,x as L,y as Y,z as B}from"./chunk-w1ypc97a.js";var x=new Set(["required","properties","dependencies"]),D=new Set(["additionalProperties","items","contains","propertyNames","not"]),C=new Set(["minimum","exclusiveMinimum","minLength","minItems","minProperties"]),P=new Set(["maximum","exclusiveMaximum","maxLength","maxItems","maxProperties"]);function O(J,W){if(W===void 0)return!0;let H=Array.isArray(W)?W:[W],z=E(J);return H.some((Q)=>Q===z||Q==="number"&&z==="integer")}function V(J,W){if(W.minimum!==void 0&&!(J>=W.minimum))return!1;if(W.maximum!==void 0&&!(J<=W.maximum))return!1;if(W.exclusiveMinimum!==void 0&&!(J>W.exclusiveMinimum))return!1;if(W.exclusiveMaximum!==void 0&&!(J<W.exclusiveMaximum))return!1;if(W.multipleOf!==void 0&&J%W.multipleOf!==0)return!1;return!0}var T=new Map;function k(J){let W=T.get(J);if(W===void 0)W=new RegExp(J),T.set(J,W);return W}function g(J,W){if(W.minLength!==void 0&&!(J.length>=W.minLength))return!1;if(W.maxLength!==void 0&&!(J.length<=W.maxLength))return!1;if(W.pattern!==void 0&&!k(W.pattern).test(J))return!1;return!0}function f(J,W){if(W.minItems!==void 0&&!(J.length>=W.minItems))return!1;if(W.maxItems!==void 0&&!(J.length<=W.maxItems))return!1;if(W.uniqueItems===!0){let H=J.length;for(let z=0;z<H;z++)for(let Q=z+1;Q<H;Q++)if(B(J[z],J[Q]))return!1}return!0}function q(J,W){if(L(J.properties)){if(!Object.keys(J.properties).every((z)=>{let Q=J.properties?.[z];if(typeof Q==="boolean")return!0;let $=Q,Z=W[z];if(Z===void 0)return!0;if(Y($,"const")){if(!B(Z,$.const))return!1}if(Y($,"enum")){if(!$.enum?.some((F)=>B(F,Z)))return!1}if(Y($,"type")&&Z!==void 0){if(!O(Z,$.type))return!1}if(typeof Z==="number"){if(!V(Z,$))return!1}if(typeof Z==="string"){if(!g(Z,$))return!1}if(Array.isArray(Z)){if(!f(Z,$))return!1}if($.format!==void 0&&typeof Z==="string"){if(w(Z,$.format)===!1)return!1}if(L($.properties)||Array.isArray($.required)){if(L(Z)){if(!q($,Z))return!1}}return!0}))return!1}if(Array.isArray(J.required)){if(!J.required.every((z)=>Y(W,z)))return!1}if(Array.isArray(J.allOf)){if(!J.allOf.every((z)=>{if(typeof z==="boolean")return z;return q(z,W)}))return!1}if(Array.isArray(J.anyOf)){if(!J.anyOf.some((z)=>{if(typeof z==="boolean")return z;return q(z,W)}))return!1}if(Array.isArray(J.oneOf)){let H=0;for(let z of J.oneOf){if(typeof z==="boolean"?z:q(z,W))H++;if(H>1)break}if(H!==1)return!1}if(Y(J,"not")&&L(J.not)&&typeof J.not!=="boolean"){if(q(J.not,W))return!1}return!0}var S=["const","enum","minimum","maximum","exclusiveMinimum","exclusiveMaximum","pattern","minLength","maxLength","multipleOf","minItems","maxItems","format"];function K(J,W,H){if(!L(J.properties))return;let z=J.properties;for(let Q of Object.keys(z)){let $=z[Q];if(typeof $==="boolean")continue;let Z=$;if(S.some((G)=>Y(Z,G))&&Y(W,Q))H[Q]=W[Q]}}function j(J,W,H){if(typeof W==="boolean")return;let z=W;if(Array.isArray(z.required))J.required=R(J.required??[],z.required);if(L(z.properties)){let Q=z.properties,$={...J.properties??{}};for(let Z of Object.keys(Q)){let F=Q[Z];if(F===void 0)continue;let G=J.properties?.[Z];if(G!==void 0&&typeof G!=="boolean"&&typeof F!=="boolean"){let U=H.merge(G,F);$[Z]=U??F}else $[Z]=F}J.properties=$}if(L(z.dependencies)){let Q=J.dependencies??{},$=z.dependencies,Z={...Q};for(let F of Object.keys($)){let G=$[F];if(G===void 0)continue;let U=Z[F];if(U===void 0)Z[F]=G;else if(Array.isArray(U)&&Array.isArray(G))Z[F]=R(U,G);else if(L(U)&&L(G)){let X=H.merge(U,G);Z[F]=X??G}else Z[F]=G}J.dependencies=Z}for(let Q of Object.keys(z)){if(x.has(Q))return;let $=z[Q],Z=J[Q];if(Z===void 0){J[Q]=$;return}if(B(Z,$))return;if(D.has(Q)){let X=H.merge(Z,$);if(X!==null)J[Q]=X;else J[Q]=$;return}if(C.has(Q)){if(typeof Z==="number"&&typeof $==="number")J[Q]=Math.max(Z,$);else J[Q]=$;return}if(P.has(Q)){if(typeof Z==="number"&&typeof $==="number")J[Q]=Math.min(Z,$);else J[Q]=$;return}if(Q==="uniqueItems"){J[Q]=Z===!0||$===!0;return}if(Q==="pattern"||Q==="format"){J[Q]=$;return}let F={[Q]:Z},G={[Q]:$},U=H.merge(F,G);if(U&&typeof U!=="boolean"&&Y(U,Q))J[Q]=U[Q];else J[Q]=$}}function b(J,W,H){let z=null,Q={},$=J.if!==void 0,Z=Array.isArray(J.allOf)&&J.allOf.some((G)=>typeof G!=="boolean"&&Y(G,"if"));if(!$&&!Z)return{resolved:_(J,W,H,Q),branch:z,discriminant:Q};let F={...J};if(Z)F=u(F,W,H,Q);if(F.if!==void 0){let G=F.if,U=q(G,W);K(G,W,Q);let X=U?F.then:F.else;if(z=U?"then":"else",X)j(F,X,H);delete F.if,delete F.then,delete F.else}return F=_(F,W,H,Q),{resolved:F,branch:z,discriminant:Q}}function u(J,W,H,z){if(!Array.isArray(J.allOf))return J;let Q=[];for(let $ of J.allOf){if(typeof $==="boolean"){Q.push($);continue}let Z=$;if(Z.if===void 0){Q.push($);continue}let F=Z.if,G=q(F,W);K(F,W,z);let U=G?Z.then:Z.else;if(U)j(J,U,H);let X=I(Z,["if","then","else"]);if(Object.keys(X).length>0)Q.push(X)}if(J={...J},Q.length===0)delete J.allOf;else J.allOf=Q;return J}function _(J,W,H,z){if(!L(J.properties))return J;let Q=J.properties,$=Object.keys(Q),Z=!1,F={};for(let G of $){let U=Q[G];if(U===void 0)continue;if(typeof U==="boolean"){F[G]=U;continue}let X=U;if(!(X.if!==void 0||Array.isArray(X.allOf)&&X.allOf.some((M)=>typeof M!=="boolean"&&Y(M,"if")))){F[G]=U;continue}let A=L(W[G])?W[G]:{},N=b(X,A,H);for(let M of Object.keys(N.discriminant))z[`${G}.${M}`]=N.discriminant[M];F[G]=N.resolved,Z=!0}return Z?{...J,properties:F}:J}
2
+ export{b as l};
3
3
 
4
- //# debugId=472160296CD0458364756E2164756E21
5
- //# sourceMappingURL=chunk-pyrx217p.js.map
4
+ //# debugId=3781F36453BE4FD264756E2164756E21
5
+ //# sourceMappingURL=chunk-ayae82am.js.map
@@ -5,6 +5,6 @@
5
5
  "import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { validateFormat } from \"./format-validator\";\nimport type { MergeEngine } from \"./merge-engine\";\nimport { inferType } from \"./normalizer\";\nimport type { ResolvedConditionResult } from \"./types\";\nimport { deepEqual, hasOwn, isPlainObj, omitKeys, unionStrings } from \"./utils\";\n\n// ─── Condition Resolver ──────────────────────────────────────────────────────\n//\n// Résout les `if/then/else` d'un schema en évaluant le `if` contre\n// des données partielles (discriminants).\n//\n// Stratégie :\n// 1. Évaluer si les données partielles satisfont le `if`\n// 2. Merger la branche applicable (`then` ou `else`) dans le schema de base\n// 3. Supprimer les mots-clés `if/then/else` du résultat\n// 4. Récurser dans les `properties` pour résoudre les conditions imbriquées\n//\n// L'évaluation du `if` (via `evaluateCondition`) gère :\n// - `properties` avec `const`, `enum`, `type`, contraintes numériques/string/array\n// - `required` (vérification de présence des clés)\n// - `allOf` (toutes les entrées doivent matcher — récursion) [2.1]\n// - `anyOf` (au moins une entrée doit matcher — récursion) [2.2]\n// - `oneOf` (exactement une entrée doit matcher — récursion) [2.3]\n// - `not` (inversion du résultat — récursion) [2.4]\n// - Propriétés imbriquées (nested objects — récursion) [2.5]\n// - `format` via `validateFormat` de `format-validator.ts` [2.6]\n//\n// Utilise lodash massivement :\n// - `_.has` / `_.get` pour l'accès sûr aux propriétés\n// - `_.every` / `_.some` pour les prédicats sur les collections\n// - `_.union` / `_.uniq` pour la fusion de tableaux (required, deps)\n// - `_.isArray` / `_.isPlainObject` pour le typage des valeurs\n// - `_.mapValues` pour transformer les propriétés\n// - `_.omit` / `_.pick` pour sélectionner/exclure des clés\n// - `_.keys` / `_.forEach` pour l'itération\n// - `_.reduce` pour accumuler les résultats\n// - `_.isEqual` pour la comparaison profonde\n// - `_.size` / `_.filter` pour le comptage (oneOf)\n\n// ─── Keywords classification ─────────────────────────────────────────────────\n\n/** Mots-clés qui ne doivent pas être traités par la boucle générique de mergeBranchInto */\nconst SPECIAL_MERGE_KEYS = new Set([\"required\", \"properties\", \"dependencies\"]);\n\n/** Mots-clés contenant un sous-schema unique (mergeable via engine.merge) */\nconst SUB_SCHEMA_KEYS = new Set([\n\t\"additionalProperties\",\n\t\"items\",\n\t\"contains\",\n\t\"propertyNames\",\n\t\"not\",\n]);\n\n/** Mots-clés numériques de type \"minimum\" (prendre le max pour être plus restrictif) */\nconst MIN_KEYS = new Set([\n\t\"minimum\",\n\t\"exclusiveMinimum\",\n\t\"minLength\",\n\t\"minItems\",\n\t\"minProperties\",\n]);\n\n/** Mots-clés numériques de type \"maximum\" (prendre le min pour être plus restrictif) */\nconst MAX_KEYS = new Set([\n\t\"maximum\",\n\t\"exclusiveMaximum\",\n\t\"maxLength\",\n\t\"maxItems\",\n\t\"maxProperties\",\n]);\n\n// ─── Condition evaluation (internal) ─────────────────────────────────────────\n\n/**\n * Vérifie si `value` correspond à un type JSON Schema.\n */\nfunction matchesType(value: unknown, type: JSONSchema7[\"type\"]): boolean {\n\tif (type === undefined) return true;\n\n\tconst types = Array.isArray(type) ? type : [type];\n\tconst actualType = inferType(value);\n\n\treturn types.some(\n\t\t(t) => t === actualType || (t === \"number\" && actualType === \"integer\"),\n\t);\n}\n\n/**\n * Évalue une contrainte numérique sur une valeur.\n * Point 5 — Enrichissement de evaluateCondition.\n */\nfunction evaluateNumericConstraints(value: number, prop: JSONSchema7): boolean {\n\tif (prop.minimum !== undefined && !(value >= prop.minimum)) return false;\n\tif (prop.maximum !== undefined && !(value <= prop.maximum)) return false;\n\tif (\n\t\tprop.exclusiveMinimum !== undefined &&\n\t\t!(value > (prop.exclusiveMinimum as number))\n\t)\n\t\treturn false;\n\tif (\n\t\tprop.exclusiveMaximum !== undefined &&\n\t\t!(value < (prop.exclusiveMaximum as number))\n\t)\n\t\treturn false;\n\tif (prop.multipleOf !== undefined && value % prop.multipleOf !== 0)\n\t\treturn false;\n\treturn true;\n}\n\n/**\n * Évalue une contrainte string sur une valeur.\n * Point 5 — Enrichissement de evaluateCondition.\n */\n/** Cache for compiled RegExp patterns used in evaluateStringConstraints */\nconst patternRegexCache = new Map<string, RegExp>();\n\nfunction getOrCompileRegex(pattern: string): RegExp {\n\tlet regex = patternRegexCache.get(pattern);\n\tif (regex === undefined) {\n\t\tregex = new RegExp(pattern);\n\t\tpatternRegexCache.set(pattern, regex);\n\t}\n\treturn regex;\n}\n\nfunction evaluateStringConstraints(value: string, prop: JSONSchema7): boolean {\n\tif (prop.minLength !== undefined && !(value.length >= prop.minLength))\n\t\treturn false;\n\tif (prop.maxLength !== undefined && !(value.length <= prop.maxLength))\n\t\treturn false;\n\tif (\n\t\tprop.pattern !== undefined &&\n\t\t!getOrCompileRegex(prop.pattern).test(value)\n\t)\n\t\treturn false;\n\treturn true;\n}\n\n/**\n * Évalue une contrainte array sur une valeur.\n * Point 5 — Enrichissement de evaluateCondition.\n */\nfunction evaluateArrayConstraints(\n\tvalue: unknown[],\n\tprop: JSONSchema7,\n): boolean {\n\tif (prop.minItems !== undefined && !(value.length >= prop.minItems))\n\t\treturn false;\n\tif (prop.maxItems !== undefined && !(value.length <= prop.maxItems))\n\t\treturn false;\n\tif (prop.uniqueItems === true) {\n\t\t// Vérifier l'unicité via deepEqual pour les éléments non-primitifs\n\t\t// Optimisation : double boucle sans slice pour éviter les allocations\n\t\tconst len = value.length;\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tfor (let j = i + 1; j < len; j++) {\n\t\t\t\tif (deepEqual(value[i], value[j])) return false;\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Évalue si des données partielles satisfont un `if` schema.\n *\n * Stratégie pragmatique (pas un validateur complet) :\n * - Vérifie les `properties` avec `const`, `enum`, `type`\n * - Point 5 : Vérifie aussi minimum/maximum, minLength/maxLength,\n * pattern, multipleOf, minItems/maxItems, uniqueItems\n * - Vérifie les `required`\n * - 2.1 : `allOf` → toutes les entrées doivent matcher (récursion)\n * - 2.2 : `anyOf` → au moins une entrée doit matcher (récursion)\n * - 2.3 : `oneOf` → exactement une entrée doit matcher (récursion)\n * - 2.4 : `not` → inversion du résultat (récursion)\n * - 2.5 : Propriétés imbriquées → récursion sur les sous-objets\n * - 2.6 : `format` → validation via `validateFormat`\n *\n * Utilise `_.forEach` / `_.every` / `_.has` pour une itération idiomatique.\n */\nfunction evaluateCondition(\n\tifSchema: JSONSchema7,\n\tdata: Record<string, unknown>,\n): boolean {\n\tif (isPlainObj(ifSchema.properties)) {\n\t\tconst propsOk = Object.keys(ifSchema.properties).every((key) => {\n\t\t\tconst propDef = ifSchema.properties?.[key];\n\t\t\tif (typeof propDef === \"boolean\") return true;\n\t\t\tconst prop = propDef as JSONSchema7;\n\t\t\tconst value = data[key];\n\n\t\t\t// ── Propriété absente → skip ──\n\t\t\t// Selon la spec JSON Schema Draft-07, le keyword `properties` ne valide\n\t\t\t// une propriété que si elle est **présente** dans l'instance.\n\t\t\t// C'est le keyword `required` qui gère la présence obligatoire.\n\t\t\tif (value === undefined) return true;\n\n\t\t\t// ── const ──\n\t\t\tif (hasOwn(prop, \"const\")) {\n\t\t\t\tif (!deepEqual(value, prop.const)) return false;\n\t\t\t}\n\n\t\t\t// ── enum ──\n\t\t\tif (hasOwn(prop, \"enum\")) {\n\t\t\t\tif (!prop.enum?.some((v) => deepEqual(v, value))) return false;\n\t\t\t}\n\n\t\t\t// ── type ──\n\t\t\tif (hasOwn(prop, \"type\") && value !== undefined) {\n\t\t\t\tif (!matchesType(value, prop.type)) return false;\n\t\t\t}\n\n\t\t\t// ── Point 5 : Contraintes numériques/string/array ──\n\t\t\t// Quand `value` est `undefined`, aucun de ces blocs ne s'exécute\n\t\t\t// (`typeof undefined` vaut `\"undefined\"`, pas `\"number\"` ni `\"string\"`,\n\t\t\t// et `isArray(undefined)` retourne `false`).\n\t\t\t// C'est le comportement voulu : on ne peut pas évaluer une contrainte\n\t\t\t// sur une donnée absente → on skip, cohérent avec la logique pragmatique.\n\t\t\tif (typeof value === \"number\") {\n\t\t\t\tif (!evaluateNumericConstraints(value, prop)) return false;\n\t\t\t}\n\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tif (!evaluateStringConstraints(value, prop)) return false;\n\t\t\t}\n\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tif (!evaluateArrayConstraints(value as unknown[], prop)) return false;\n\t\t\t}\n\n\t\t\t// ── 2.6 — format ──\n\t\t\t// Valide la valeur contre le format via class-validator.\n\t\t\t// Le format ne s'applique qu'aux strings en Draft-07.\n\t\t\t// Si le format est inconnu → skip (retourne null → on continue).\n\t\t\tif (prop.format !== undefined && typeof value === \"string\") {\n\t\t\t\tconst formatResult = validateFormat(value, prop.format);\n\t\t\t\tif (formatResult === false) return false;\n\t\t\t\t// null (format inconnu) → skip, cohérent avec l'approche pragmatique\n\t\t\t}\n\n\t\t\t// ── 2.5 — Propriétés imbriquées (nested objects) ──\n\t\t\t// Si la propriété elle-même a des `properties` ou un `required`,\n\t\t\t// et que la valeur dans data est un objet, récurser dans evaluateCondition\n\t\t\t// en passant la sous-donnée comme nouveau `data`.\n\t\t\t// Si data[key] n'est pas un objet, on skip (retourne true pour cette prop,\n\t\t\t// cohérent avec \"absence = pas de contrainte\").\n\t\t\tif (isPlainObj(prop.properties) || Array.isArray(prop.required)) {\n\t\t\t\tif (isPlainObj(value)) {\n\t\t\t\t\tif (!evaluateCondition(prop, value as Record<string, unknown>)) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// value n'est pas un objet → skip, on ne peut pas évaluer les sous-props\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\t\tif (!propsOk) return false;\n\t}\n\n\t// ── required ──\n\tif (Array.isArray(ifSchema.required)) {\n\t\tconst allRequired = ifSchema.required.every((key) =>\n\t\t\thasOwn(data, key as string),\n\t\t);\n\t\tif (!allRequired) return false;\n\t}\n\n\t// ── 2.1 — allOf ──\n\t// Toutes les entrées du allOf doivent matcher (évaluation récursive).\n\tif (Array.isArray(ifSchema.allOf)) {\n\t\tconst allMatch = ifSchema.allOf.every((entry) => {\n\t\t\tif (typeof entry === \"boolean\") return entry;\n\t\t\treturn evaluateCondition(entry as JSONSchema7, data);\n\t\t});\n\t\tif (!allMatch) return false;\n\t}\n\n\t// ── 2.2 — anyOf ──\n\t// Au moins une entrée du anyOf doit matcher (évaluation récursive).\n\tif (Array.isArray(ifSchema.anyOf)) {\n\t\tconst anyMatch = ifSchema.anyOf.some((entry) => {\n\t\t\tif (typeof entry === \"boolean\") return entry;\n\t\t\treturn evaluateCondition(entry as JSONSchema7, data);\n\t\t});\n\t\tif (!anyMatch) return false;\n\t}\n\n\t// ── 2.3 — oneOf ──\n\t// Exactement une entrée du oneOf doit matcher (évaluation récursive).\n\tif (Array.isArray(ifSchema.oneOf)) {\n\t\tlet matchCount = 0;\n\t\tfor (const entry of ifSchema.oneOf) {\n\t\t\tconst matches =\n\t\t\t\ttypeof entry === \"boolean\"\n\t\t\t\t\t? entry\n\t\t\t\t\t: evaluateCondition(entry as JSONSchema7, data);\n\t\t\tif (matches) matchCount++;\n\t\t\tif (matchCount > 1) break;\n\t\t}\n\t\tif (matchCount !== 1) return false;\n\t}\n\n\t// ── 2.4 — not ──\n\t// Inverser le résultat de l'évaluation du contenu du `not`.\n\tif (\n\t\thasOwn(ifSchema, \"not\") &&\n\t\tisPlainObj(ifSchema.not) &&\n\t\ttypeof ifSchema.not !== \"boolean\"\n\t) {\n\t\tconst notResult = evaluateCondition(ifSchema.not as JSONSchema7, data);\n\t\tif (notResult) return false; // Le not matche → la condition not ne matche pas\n\t}\n\n\treturn true;\n}\n\n// ─── Discriminant extraction ─────────────────────────────────────────────────\n\n/**\n * Mots-clés qui indiquent qu'une propriété est un discriminant\n * (sa valeur dans les données est utilisée pour la résolution).\n *\n * Point 5 — Étendu avec les contraintes numériques/string/pattern.\n */\nconst DISCRIMINANT_INDICATORS = [\n\t\"const\",\n\t\"enum\",\n\t\"minimum\",\n\t\"maximum\",\n\t\"exclusiveMinimum\",\n\t\"exclusiveMaximum\",\n\t\"pattern\",\n\t\"minLength\",\n\t\"maxLength\",\n\t\"multipleOf\",\n\t\"minItems\",\n\t\"maxItems\",\n\t\"format\",\n] as const;\n\n/**\n * Extrait les valeurs discriminantes utilisées dans un `if` schema\n * depuis les données partielles.\n *\n * Point 5 — Collecte aussi les discriminants pour les nouvelles contraintes\n * (minimum, maximum, pattern, etc.).\n *\n * Utilise `_.some` pour vérifier qu'au moins un indicateur est présent,\n * et `_.has` pour un accès sûr.\n */\nfunction extractDiscriminants(\n\tifSchema: JSONSchema7,\n\tdata: Record<string, unknown>,\n\tout: Record<string, unknown>,\n): void {\n\tif (!isPlainObj(ifSchema.properties)) return;\n\n\tconst props = ifSchema.properties as Record<string, JSONSchema7Definition>;\n\tfor (const key of Object.keys(props)) {\n\t\tconst propDef = props[key];\n\t\tif (typeof propDef === \"boolean\") continue;\n\t\tconst prop = propDef as JSONSchema7;\n\n\t\t// Collecter si au moins un indicateur de discriminant est présent\n\t\tconst hasIndicator = DISCRIMINANT_INDICATORS.some((indicator) =>\n\t\t\thasOwn(prop, indicator),\n\t\t);\n\n\t\tif (hasIndicator && hasOwn(data, key)) {\n\t\t\tout[key] = data[key];\n\t\t}\n\t}\n}\n\n// ─── Branch merging (deduplicated) ───────────────────────────────────────────\n\n/**\n * Merge une branche conditionnelle (`then` ou `else`) dans le schema résolu.\n *\n * Point 4 — Fix first-writer-wins :\n * Au lieu d'ignorer les keywords déjà présents dans `resolved`,\n * on tente un merge intelligent selon le type de keyword :\n *\n * - `required` → union dédupliquée via `_.union`\n * - `properties` → merge individuel via engine.merge\n * - `dependencies` → Point 3 : union des tableaux (forme 1),\n * merge des schemas (forme 2) via `_.mapValues`\n * - Sub-schema keys → merge via engine.merge\n * - Min keys → `Math.max` (plus restrictif)\n * - Max keys → `Math.min` (plus restrictif)\n * - `uniqueItems` → `true` gagne sur `false`\n * - `pattern` / `format` → la branche gagne (plus spécifique)\n * - Autres → tentative de merge via engine, sinon la branche gagne\n *\n * Utilise lodash massivement pour chaque opération de merge.\n */\nfunction mergeBranchInto(\n\tresolved: JSONSchema7,\n\tbranchDef: JSONSchema7Definition,\n\tengine: MergeEngine,\n): void {\n\tif (typeof branchDef === \"boolean\") return;\n\n\tconst branchSchema = branchDef as JSONSchema7;\n\n\t// ── Merger required via _.union (dédupliquée automatiquement) ──\n\tif (Array.isArray(branchSchema.required)) {\n\t\tresolved.required = unionStrings(\n\t\t\tresolved.required ?? [],\n\t\t\tbranchSchema.required,\n\t\t);\n\t}\n\n\t// ── Merger properties ──\n\tif (isPlainObj(branchSchema.properties)) {\n\t\tconst branchProps = branchSchema.properties as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition\n\t\t>;\n\t\tconst mergedProps: Record<string, JSONSchema7Definition> = {\n\t\t\t...(resolved.properties ?? {}),\n\t\t};\n\t\tfor (const key of Object.keys(branchProps)) {\n\t\t\tconst branchProp = branchProps[key];\n\t\t\tif (branchProp === undefined) continue;\n\t\t\tconst existing = resolved.properties?.[key];\n\t\t\tif (\n\t\t\t\texisting !== undefined &&\n\t\t\t\ttypeof existing !== \"boolean\" &&\n\t\t\t\ttypeof branchProp !== \"boolean\"\n\t\t\t) {\n\t\t\t\tconst merged = engine.merge(\n\t\t\t\t\texisting as JSONSchema7Definition,\n\t\t\t\t\tbranchProp as JSONSchema7Definition,\n\t\t\t\t);\n\t\t\t\tmergedProps[key] = (merged ?? branchProp) as JSONSchema7Definition;\n\t\t\t} else {\n\t\t\t\tmergedProps[key] = branchProp;\n\t\t\t}\n\t\t}\n\t\tresolved.properties = mergedProps;\n\t}\n\n\t// ── Merger dependencies (Point 3) ──\n\tif (isPlainObj(branchSchema.dependencies)) {\n\t\tconst resolvedDeps = (resolved.dependencies ?? {}) as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\t\tconst branchDeps = branchSchema.dependencies as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\n\t\tconst acc = { ...resolvedDeps };\n\t\tfor (const depKey of Object.keys(branchDeps)) {\n\t\t\tconst branchVal = branchDeps[depKey] as\n\t\t\t\t| JSONSchema7Definition\n\t\t\t\t| string[]\n\t\t\t\t| undefined;\n\t\t\tif (branchVal === undefined) continue;\n\t\t\tconst existingVal = acc[depKey] as\n\t\t\t\t| JSONSchema7Definition\n\t\t\t\t| string[]\n\t\t\t\t| undefined;\n\n\t\t\tif (existingVal === undefined) {\n\t\t\t\t// Pas de valeur existante → copier directement\n\t\t\t\tacc[depKey] = branchVal;\n\t\t\t} else if (Array.isArray(existingVal) && Array.isArray(branchVal)) {\n\t\t\t\t// Forme 1 : union dédupliquée des tableaux de strings\n\t\t\t\tacc[depKey] = unionStrings(\n\t\t\t\t\texistingVal as string[],\n\t\t\t\t\tbranchVal as string[],\n\t\t\t\t);\n\t\t\t} else if (isPlainObj(existingVal) && isPlainObj(branchVal)) {\n\t\t\t\t// Forme 2 : merge des sous-schemas\n\t\t\t\tconst merged = engine.merge(\n\t\t\t\t\texistingVal as JSONSchema7Definition,\n\t\t\t\t\tbranchVal as JSONSchema7Definition,\n\t\t\t\t);\n\t\t\t\tacc[depKey] = (merged ?? branchVal) as JSONSchema7Definition;\n\t\t\t} else {\n\t\t\t\t// Types incompatibles (tableau vs schema) → la branche gagne\n\t\t\t\tacc[depKey] = branchVal;\n\t\t\t}\n\t\t}\n\t\tresolved.dependencies = acc as Record<\n\t\t\tstring,\n\t\t\tJSONSchema7Definition | string[]\n\t\t>;\n\t}\n\n\t// ── Merger les autres mots-clés (Point 4 — fix first-writer-wins) ──\n\tfor (const key of Object.keys(branchSchema) as (keyof JSONSchema7)[]) {\n\t\t// Skip les clés déjà traitées ci-dessus\n\t\tif (SPECIAL_MERGE_KEYS.has(key)) return;\n\n\t\tconst branchVal = branchSchema[key];\n\t\tconst resolvedVal = resolved[key];\n\n\t\t// Si le resolved n'a pas cette clé → copier directement\n\t\tif (resolvedVal === undefined) {\n\t\t\t(resolved as Record<string, unknown>)[key] = branchVal;\n\t\t\treturn;\n\t\t}\n\n\t\t// Si les deux ont la même valeur → rien à faire\n\t\tif (deepEqual(resolvedVal, branchVal)) return;\n\n\t\t// ── Sub-schema keys → merge via engine ──\n\t\tif (SUB_SCHEMA_KEYS.has(key)) {\n\t\t\tconst merged = engine.merge(\n\t\t\t\tresolvedVal as JSONSchema7Definition,\n\t\t\t\tbranchVal as JSONSchema7Definition,\n\t\t\t);\n\t\t\tif (merged !== null) {\n\t\t\t\t(resolved as Record<string, unknown>)[key] = merged;\n\t\t\t} else {\n\t\t\t\t// Merge impossible → la branche gagne (contexte conditionnel)\n\t\t\t\t(resolved as Record<string, unknown>)[key] = branchVal;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// ── Min keys → Math.max (plus restrictif) ──\n\t\tif (MIN_KEYS.has(key)) {\n\t\t\tif (typeof resolvedVal === \"number\" && typeof branchVal === \"number\") {\n\t\t\t\t(resolved as Record<string, unknown>)[key] = Math.max(\n\t\t\t\t\tresolvedVal,\n\t\t\t\t\tbranchVal,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t(resolved as Record<string, unknown>)[key] = branchVal;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// ── Max keys → Math.min (plus restrictif) ──\n\t\tif (MAX_KEYS.has(key)) {\n\t\t\tif (typeof resolvedVal === \"number\" && typeof branchVal === \"number\") {\n\t\t\t\t(resolved as Record<string, unknown>)[key] = Math.min(\n\t\t\t\t\tresolvedVal,\n\t\t\t\t\tbranchVal,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t(resolved as Record<string, unknown>)[key] = branchVal;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// ── uniqueItems → true gagne sur false ──\n\t\tif (key === \"uniqueItems\") {\n\t\t\t(resolved as Record<string, unknown>)[key] =\n\t\t\t\tresolvedVal === true || branchVal === true;\n\t\t\treturn;\n\t\t}\n\n\t\t// ── pattern / format → la branche gagne (plus spécifique au contexte) ──\n\t\tif (key === \"pattern\" || key === \"format\") {\n\t\t\t(resolved as Record<string, unknown>)[key] = branchVal;\n\t\t\treturn;\n\t\t}\n\n\t\t// ── Fallback : tentative de merge via engine pour les cas restants ──\n\t\tconst base = { [key]: resolvedVal } as JSONSchema7Definition;\n\t\tconst branch = { [key]: branchVal } as JSONSchema7Definition;\n\t\tconst merged = engine.merge(base, branch);\n\t\tif (\n\t\t\tmerged &&\n\t\t\ttypeof merged !== \"boolean\" &&\n\t\t\thasOwn(merged as object, key)\n\t\t) {\n\t\t\t(resolved as Record<string, unknown>)[key] = (\n\t\t\t\tmerged as unknown as Record<string, unknown>\n\t\t\t)[key];\n\t\t} else {\n\t\t\t// Merge échoué → la branche gagne (contexte conditionnel applicable)\n\t\t\t(resolved as Record<string, unknown>)[key] = branchVal;\n\t\t}\n\t}\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Résout les `if/then/else` d'un schema en évaluant le `if` contre\n * des données partielles (discriminants).\n *\n * @param schema Le schema contenant potentiellement des if/then/else\n * @param data Données partielles utilisées pour évaluer les conditions\n * @param engine Le MergeEngine pour merger les branches\n *\n * @example\n * ```ts\n * const form = {\n * type: \"object\",\n * properties: { accountType: { type: \"string\" }, ... },\n * if: { properties: { accountType: { const: \"business\" } } },\n * then: { required: [\"companyName\"] },\n * else: { required: [\"firstName\"] },\n * };\n *\n * const { resolved } = resolveConditions(form, { accountType: \"business\" }, engine);\n * // → resolved n'a plus de if/then/else, mais a required: [\"companyName\"]\n * ```\n */\nexport function resolveConditions(\n\tschema: JSONSchema7,\n\tdata: Record<string, unknown>,\n\tengine: MergeEngine,\n): ResolvedConditionResult {\n\tlet branch: \"then\" | \"else\" | null = null;\n\tconst discriminant: Record<string, unknown> = {};\n\n\t// ── Fast path: no conditions at all ──\n\t// If there's no `if` and no `allOf` with conditions, skip the copy entirely.\n\tconst hasTopLevelIf = schema.if !== undefined;\n\tconst hasAllOfConditions =\n\t\tArray.isArray(schema.allOf) &&\n\t\tschema.allOf.some(\n\t\t\t(e) => typeof e !== \"boolean\" && hasOwn(e as object, \"if\"),\n\t\t);\n\n\tif (!hasTopLevelIf && !hasAllOfConditions) {\n\t\t// Phase 3 only: check nested properties (resolveNestedProperties\n\t\t// already returns the original if nothing changes)\n\t\tconst resolved = resolveNestedProperties(\n\t\t\tschema,\n\t\t\tdata,\n\t\t\tengine,\n\t\t\tdiscriminant,\n\t\t);\n\t\treturn { resolved, branch, discriminant };\n\t}\n\n\t// ── Copy-on-write: only copy when mutations are needed ──\n\tlet resolved = { ...schema };\n\n\t// ── Phase 1 : Résoudre les if/then/else dans allOf ──\n\tif (hasAllOfConditions) {\n\t\tresolved = resolveAllOfConditions(resolved, data, engine, discriminant);\n\t}\n\n\t// ── Phase 2 : Résoudre le if/then/else de ce niveau ──\n\tif (resolved.if !== undefined) {\n\t\tconst ifSchema = resolved.if as JSONSchema7;\n\t\tconst matches = evaluateCondition(ifSchema, data);\n\n\t\textractDiscriminants(ifSchema, data, discriminant);\n\n\t\tconst applicableBranch = matches ? resolved.then : resolved.else;\n\t\tbranch = matches ? \"then\" : \"else\";\n\n\t\tif (applicableBranch) {\n\t\t\tmergeBranchInto(\n\t\t\t\tresolved,\n\t\t\t\tapplicableBranch as JSONSchema7Definition,\n\t\t\t\tengine,\n\t\t\t);\n\t\t}\n\n\t\tdelete resolved.if;\n\t\tdelete resolved.then;\n\t\tdelete resolved.else;\n\t}\n\n\t// ── Phase 3 : Récurser dans les properties ──\n\tresolved = resolveNestedProperties(resolved, data, engine, discriminant);\n\n\treturn { resolved, branch, discriminant };\n}\n\n// ─── Internal phases ─────────────────────────────────────────────────────────\n\n/**\n * Phase 1 : Parcourt les entrées `allOf` et résout celles qui contiennent\n * un `if/then/else`. Les entrées non-conditionnelles sont préservées.\n *\n * Utilise `_.reduce` pour accumuler les entrées restantes et `_.filter`\n * pour séparer les clés conditionnelles des non-conditionnelles.\n */\nfunction resolveAllOfConditions(\n\tresolved: JSONSchema7,\n\tdata: Record<string, unknown>,\n\tengine: MergeEngine,\n\tdiscriminant: Record<string, unknown>,\n): JSONSchema7 {\n\tif (!Array.isArray(resolved.allOf)) return resolved;\n\n\tconst remainingAllOf: JSONSchema7Definition[] = [];\n\n\tfor (const entry of resolved.allOf) {\n\t\tif (typeof entry === \"boolean\") {\n\t\t\tremainingAllOf.push(entry);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst subSchema = entry as JSONSchema7;\n\n\t\tif (subSchema.if === undefined) {\n\t\t\tremainingAllOf.push(entry);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Résoudre la condition de cette entrée allOf\n\t\tconst ifSchema = subSchema.if as JSONSchema7;\n\t\tconst matches = evaluateCondition(ifSchema, data);\n\n\t\textractDiscriminants(ifSchema, data, discriminant);\n\n\t\tconst applicableBranch = matches ? subSchema.then : subSchema.else;\n\n\t\tif (applicableBranch) {\n\t\t\tmergeBranchInto(\n\t\t\t\tresolved,\n\t\t\t\tapplicableBranch as JSONSchema7Definition,\n\t\t\t\tengine,\n\t\t\t);\n\t\t}\n\n\t\t// Garder les parties non-conditionnelles de l'entrée allOf\n\t\tconst remaining = omitKeys(\n\t\t\tsubSchema as unknown as Record<string, unknown>,\n\t\t\t[\"if\", \"then\", \"else\"],\n\t\t);\n\t\tif (Object.keys(remaining).length > 0) {\n\t\t\tremainingAllOf.push(remaining as JSONSchema7);\n\t\t}\n\t}\n\n\tresolved = { ...resolved };\n\tif (remainingAllOf.length === 0) {\n\t\tdelete resolved.allOf;\n\t} else {\n\t\tresolved.allOf = remainingAllOf;\n\t}\n\n\treturn resolved;\n}\n\n/**\n * Phase 3 : Récurse dans les `properties` du schema résolu pour résoudre\n * les conditions imbriquées (ex: un objet dont une propriété a un if/then/else).\n *\n * Utilise `_.mapValues` pour transformer chaque propriété en une seule passe,\n * et `_.forEach` pour remonter les discriminants imbriqués.\n */\nfunction resolveNestedProperties(\n\tresolved: JSONSchema7,\n\tdata: Record<string, unknown>,\n\tengine: MergeEngine,\n\tdiscriminant: Record<string, unknown>,\n): JSONSchema7 {\n\tif (!isPlainObj(resolved.properties)) return resolved;\n\n\tconst props = resolved.properties as Record<string, JSONSchema7Definition>;\n\tconst propKeys = Object.keys(props);\n\tlet changed = false;\n\tconst resolvedProps: Record<string, JSONSchema7Definition> = {};\n\n\tfor (const key of propKeys) {\n\t\tconst propDef = props[key];\n\t\tif (propDef === undefined) continue;\n\t\tif (typeof propDef === \"boolean\") {\n\t\t\tresolvedProps[key] = propDef;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst propSchema = propDef as JSONSchema7;\n\t\tconst hasConditions =\n\t\t\tpropSchema.if !== undefined ||\n\t\t\t(Array.isArray(propSchema.allOf) &&\n\t\t\t\tpropSchema.allOf.some(\n\t\t\t\t\t(e) => typeof e !== \"boolean\" && hasOwn(e as object, \"if\"),\n\t\t\t\t));\n\n\t\tif (!hasConditions) {\n\t\t\tresolvedProps[key] = propDef;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Données imbriquées disponibles → résoudre récursivement\n\t\tconst nestedData = isPlainObj(data[key])\n\t\t\t? (data[key] as Record<string, unknown>)\n\t\t\t: {};\n\n\t\tconst nested = resolveConditions(propSchema, nestedData, engine);\n\n\t\t// Remonter les discriminants imbriqués avec prefix\n\t\tfor (const dk of Object.keys(nested.discriminant)) {\n\t\t\tdiscriminant[`${key}.${dk}`] = nested.discriminant[dk];\n\t\t}\n\n\t\tresolvedProps[key] = nested.resolved;\n\t\tchanged = true;\n\t}\n\n\treturn changed ? { ...resolved, properties: resolvedProps } : resolved;\n}\n"
6
6
  ],
7
7
  "mappings": "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",
8
- "debugId": "472160296CD0458364756E2164756E21",
8
+ "debugId": "3781F36453BE4FD264756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,5 @@
1
+ import{u as q}from"./chunk-gdf3h8q4.js";import{x,y as X,z as _}from"./chunk-w1ypc97a.js";import{createComparator as K,createMerger as T,createShallowAllOfMerge as E}from"@x0k/json-schema-merge";import{createDeduplicator as I,createIntersector as V}from"@x0k/json-schema-merge/lib/array";function j(z,B){if(typeof z==="boolean"||typeof B==="boolean")return!1;let Q=X(z,"const"),J=X(B,"const"),U=z.const,Z=B.const,G=z.enum,Y=B.enum;if(Q&&J)return!_(U,Z);if(Q&&Array.isArray(Y))return!Y.some(($)=>_($,U));if(J&&Array.isArray(G))return!G.some(($)=>_($,Z));return!1}var F=["items","additionalProperties","contains","propertyNames","not"],M=["properties","patternProperties"];function v(z,B){if(j(z,B))return!0;if(typeof z==="boolean"||typeof B==="boolean")return!1;for(let Q of F){let J=z[Q],U=B[Q];if(x(J)&&x(U)&&v(J,U))return!0}for(let Q of M){let J=z[Q],U=B[Q];if(!x(J)||!x(U))continue;let Z=J,G=U;for(let Y of Object.keys(Z)){let $=Z[Y],W=G[Y];if($!==void 0&&W!==void 0&&X(G,Y)&&v($,W))return!0}}if(Array.isArray(z.items)&&Array.isArray(B.items)){let Q=z.items,J=B.items,U=Math.min(Q.length,J.length);for(let Z=0;Z<U;Z++){let G=Q[Z],Y=J[Z];if(G===void 0||Y===void 0)continue;if(v(G,Y))return!0}}return!1}function A(z,B){if(typeof z==="boolean"||typeof B==="boolean")return!1;let Q=x(z.properties)?z.properties:void 0,J=x(B.properties)?B.properties:void 0;if(!Q&&!J)return!1;let U=Q?Object.keys(Q):[],Z=J?Object.keys(J):[],G=Array.isArray(z.required)?z.required:[],Y=Array.isArray(B.required)?B.required:[];if(z.additionalProperties===!1&&Q&&J){if(Y.some((W)=>!X(Q,W)&&X(J,W))&&U.length>0)return!0}if(x(z.additionalProperties)&&typeof z.additionalProperties!=="boolean"&&Q&&J){let $=z.additionalProperties;if(X($,"type")){let W=$.type;if(Y.some((N)=>{if(X(Q,N))return!1;if(!X(J,N))return!1;let g=J[N];if(typeof g==="boolean")return!1;let L=g;if(!X(L,"type"))return!1;if(typeof W==="string"&&typeof L.type==="string")return W!==L.type&&!(W==="number"&&L.type==="integer")&&!(W==="integer"&&L.type==="number");return!1}))return!0}}if(B.additionalProperties===!1&&J&&Q){if(G.some((W)=>!X(J,W)&&X(Q,W))&&Z.length>0)return!0}if(x(B.additionalProperties)&&typeof B.additionalProperties!=="boolean"&&J&&Q){let $=B.additionalProperties;if(X($,"type")){let W=$.type;if(G.some((N)=>{if(X(J,N))return!1;if(!X(Q,N))return!1;let g=Q[N];if(typeof g==="boolean")return!1;let L=g;if(!X(L,"type"))return!1;if(typeof W==="string"&&typeof L.type==="string")return W!==L.type&&!(W==="number"&&L.type==="integer")&&!(W==="integer"&&L.type==="number");return!1}))return!0}}if(Q&&J)for(let $ of U){if(!X(J,$))continue;let W=Q[$],R=J[$];if(typeof W==="boolean"||typeof R==="boolean")continue;if(A(W,R))return!0}return!1}function H(z,B){if(typeof z==="boolean"||typeof B==="boolean")return!1;if(X(z,"format")&&X(B,"format")){let Q=z.format,J=B.format;if(Q!==J){if(q(Q,J)!==!0){if(q(J,Q)!==!0)return!0}}}if(x(z.properties)&&x(B.properties)){let Q=z.properties,J=B.properties;for(let U of Object.keys(Q)){let Z=Q[U],G=J[U];if(Z!==void 0&&G!==void 0&&X(J,U)&&H(Z,G))return!0}}if(x(z.items)&&x(B.items)){if(H(z.items,B.items))return!0}if(x(z.additionalProperties)&&x(B.additionalProperties)){if(H(z.additionalProperties,B.additionalProperties))return!0}return!1}class u{compareFn;shallowAllOfMergeFn;constructor(){let{compareSchemaDefinitions:z,compareSchemaValues:B}=K(),Q=(U,Z)=>{if(U===null&&Z===null)return 0;return B(U,Z)},{mergeArrayOfSchemaDefinitions:J}=T({intersectJson:V(Q),deduplicateJsonSchemaDef:I(z)});this.compareFn=z,this.shallowAllOfMergeFn=E(J)}merge(z,B){if(v(z,B))return null;if(H(z,B))return null;if(A(z,B))return null;try{return this.shallowAllOfMergeFn({allOf:[z,B]})}catch{return null}}mergeOrThrow(z,B){if(v(z,B))throw Error("Incompatible const values: schemas have conflicting const constraints");if(H(z,B))throw Error("Incompatible format values: schemas have conflicting format constraints");if(A(z,B))throw Error("Incompatible additionalProperties: required properties conflict with additionalProperties constraint");return this.shallowAllOfMergeFn({allOf:[z,B]})}compare(z,B){return this.compareFn(z,B)}isEqual(z,B){return this.compareFn(z,B)===0}}
2
+ export{u as p};
3
+
4
+ //# debugId=B46B487D9063BA4D64756E2164756E21
5
+ //# sourceMappingURL=chunk-etwjsbj3.js.map
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import {\n\tcreateComparator,\n\tcreateMerger,\n\tcreateShallowAllOfMerge,\n} from \"@x0k/json-schema-merge\";\nimport {\n\tcreateDeduplicator,\n\tcreateIntersector,\n} from \"@x0k/json-schema-merge/lib/array\";\n\nimport type {\n\tJSONSchema7,\n\tJSONSchema7Definition,\n\tJSONSchema7Type,\n} from \"json-schema\";\n\nimport { isFormatSubset } from \"./format-validator\";\nimport { deepEqual, hasOwn, isPlainObj } from \"./utils\";\n\n// ─── Merge Engine ────────────────────────────────────────────────────────────\n//\n// Encapsule la librairie `@x0k/json-schema-merge` et expose une API simple\n// pour merger et comparer des JSON Schemas.\n//\n// Principe mathématique :\n// A ∩ B = allOf([A, B]) résolu via shallow merge\n// A ≡ B ⟺ compare(A, B) === 0\n//\n// Pré-checks avant merge :\n// - `hasDeepConstConflict` : détecte les conflits de `const`/`enum`\n// - `hasAdditionalPropertiesConflict` : détecte les conflits `additionalProperties`\n// - `hasFormatConflict` : détecte les conflits de `format` entre deux schemas\n\n// ─── Const conflict detection ────────────────────────────────────────────────\n\n/**\n * Détecte un conflit de `const` entre deux schemas.\n *\n * Cas 1 — const vs const : les deux schemas ont un `const` avec des valeurs\n * différentes → intersection vide.\n *\n * Cas 2 — const vs enum : un schema a `const`, l'autre a `enum`.\n * Si la valeur de `const` n'est pas dans l'`enum` → intersection vide.\n *\n * Utilise `lodash/isEqual` pour la comparaison profonde (objets, tableaux).\n */\nfunction hasConstConflict(\n\ta: JSONSchema7Definition,\n\tb: JSONSchema7Definition,\n): boolean {\n\tif (typeof a === \"boolean\" || typeof b === \"boolean\") return false;\n\n\tconst aHasConst = hasOwn(a, \"const\");\n\tconst bHasConst = hasOwn(b, \"const\");\n\tconst aConst = (a as Record<string, unknown>).const;\n\tconst bConst = (b as Record<string, unknown>).const;\n\tconst aEnum = a.enum as unknown[] | undefined;\n\tconst bEnum = b.enum as unknown[] | undefined;\n\n\t// Cas 1 — const vs const\n\tif (aHasConst && bHasConst) {\n\t\treturn !deepEqual(aConst, bConst);\n\t}\n\n\t// Cas 2 — const vs enum\n\tif (aHasConst && Array.isArray(bEnum)) {\n\t\treturn !bEnum.some((v) => deepEqual(v, aConst));\n\t}\n\tif (bHasConst && Array.isArray(aEnum)) {\n\t\treturn !aEnum.some((v) => deepEqual(v, bConst));\n\t}\n\n\treturn false;\n}\n\n/** Mots-clés contenant un unique sous-schema à vérifier récursivement */\nconst SINGLE_SCHEMA_CONFLICT_KEYS = [\n\t\"items\",\n\t\"additionalProperties\",\n\t\"contains\",\n\t\"propertyNames\",\n\t\"not\",\n] as const;\n\n/** Mots-clés contenant un Record<string, JSONSchema7Definition> */\nconst PROPERTIES_MAP_CONFLICT_KEYS = [\n\t\"properties\",\n\t\"patternProperties\",\n] as const;\n\n/**\n * Détecte récursivement les conflits de `const` dans les sous-schemas.\n *\n * Quand la librairie de merge fait un shallow merge, les sous-schemas\n * imbriqués peuvent aussi avoir des conflits de `const` masqués\n * (elle utilise `identity` pour `const`).\n *\n * Récurse dans :\n * - `properties`, `patternProperties` (clés communes)\n * - `items` (single schema), tuple `items` (par index)\n * - `additionalProperties`, `contains`, `propertyNames`, `not`\n */\nfunction hasDeepConstConflict(\n\ta: JSONSchema7Definition,\n\tb: JSONSchema7Definition,\n): boolean {\n\tif (hasConstConflict(a, b)) return true;\n\n\tif (typeof a === \"boolean\" || typeof b === \"boolean\") return false;\n\n\t// ── Single sub-schema keywords ──\n\tfor (const key of SINGLE_SCHEMA_CONFLICT_KEYS) {\n\t\tconst aVal = (a as Record<string, unknown>)[key] as\n\t\t\t| JSONSchema7Definition\n\t\t\t| undefined;\n\t\tconst bVal = (b as Record<string, unknown>)[key] as\n\t\t\t| JSONSchema7Definition\n\t\t\t| undefined;\n\t\tif (\n\t\t\tisPlainObj(aVal) &&\n\t\t\tisPlainObj(bVal) &&\n\t\t\thasDeepConstConflict(\n\t\t\t\taVal as JSONSchema7Definition,\n\t\t\t\tbVal as JSONSchema7Definition,\n\t\t\t)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// ── Properties-like maps (properties, patternProperties) ──\n\tfor (const key of PROPERTIES_MAP_CONFLICT_KEYS) {\n\t\tconst aMap = (a as Record<string, unknown>)[key] as\n\t\t\t| Record<string, JSONSchema7Definition>\n\t\t\t| undefined;\n\t\tconst bMap = (b as Record<string, unknown>)[key] as\n\t\t\t| Record<string, JSONSchema7Definition>\n\t\t\t| undefined;\n\t\tif (!isPlainObj(aMap) || !isPlainObj(bMap)) continue;\n\t\tconst aMapSafe = aMap as Record<string, JSONSchema7Definition>;\n\t\tconst bMapSafe = bMap as Record<string, JSONSchema7Definition>;\n\t\tfor (const propKey of Object.keys(aMapSafe)) {\n\t\t\tconst aVal = aMapSafe[propKey];\n\t\t\tconst bVal = bMapSafe[propKey];\n\t\t\tif (\n\t\t\t\taVal !== undefined &&\n\t\t\t\tbVal !== undefined &&\n\t\t\t\thasOwn(bMapSafe, propKey) &&\n\t\t\t\thasDeepConstConflict(aVal, bVal)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Tuple items (array of schemas, compared by index) ──\n\tif (Array.isArray(a.items) && Array.isArray(b.items)) {\n\t\tconst aItems = a.items as JSONSchema7Definition[];\n\t\tconst bItems = b.items as JSONSchema7Definition[];\n\t\tconst len = Math.min(aItems.length, bItems.length);\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tconst aItem = aItems[i];\n\t\t\tconst bItem = bItems[i];\n\t\t\tif (aItem === undefined || bItem === undefined) continue;\n\t\t\tif (hasDeepConstConflict(aItem, bItem)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// ─── additionalProperties conflict detection ─────────────────────────────────\n\n/**\n * Détecte un conflit entre `additionalProperties` et les propriétés extra\n * **requises** de l'autre schema.\n *\n * ⚠️ Cette fonction est **ultra-conservatrice** : elle ne détecte que les\n * conflits où une propriété est à la fois :\n * - INTERDITE par `additionalProperties: false` d'un côté\n * - REQUISE (`required`) par l'autre côté\n * - ABSENTE des `properties` du côté restrictif\n * - ET le côté restrictif AUSSI a un `required` qui rend l'objet non-vide\n * (sinon la librairie gère déjà le cas en excluant les propriétés extra)\n *\n * La librairie de merge (`@x0k/json-schema-merge`) gère DÉJÀ correctement\n * le cas `additionalProperties: false` avec des propriétés simplement DÉFINIES\n * (non requises) dans l'autre schema — elle les exclut du résultat.\n * On ne détecte donc QUE les contradictions `required` impossibles à résoudre.\n *\n * Cas gérés :\n * 1. `a` a `additionalProperties: false` et `b` REQUIERT des propriétés\n * absentes de `a.properties`, ET ces propriétés sont dans `b.properties`\n * → conflit certain (intersection vide car b exige, a interdit)\n * 2. Symétrique pour `b.additionalProperties: false`\n * 3. `additionalProperties` comme schema → vérifier la compatibilité de type\n * des propriétés extra REQUISES uniquement\n * 4. Récursion dans les propriétés communes (sous-objets)\n *\n * ⚠️ Ne vérifie que les clés de `properties`, pas les `patternProperties`\n * (trop complexe à résoudre statiquement).\n *\n * Retourne `true` si un conflit évident est détecté, `false` sinon.\n * En cas de doute → `false` (conservateur, laisser le merge décider).\n *\n * Utilise `_.keys`, `_.some`, `_.every`, `_.has`, `_.get`, `_.isPlainObject`,\n * `_.includes` pour des vérifications concises.\n */\nfunction hasAdditionalPropertiesConflict(\n\ta: JSONSchema7Definition,\n\tb: JSONSchema7Definition,\n): boolean {\n\tif (typeof a === \"boolean\" || typeof b === \"boolean\") return false;\n\n\tconst aProps = isPlainObj(a.properties)\n\t\t? (a.properties as Record<string, JSONSchema7Definition>)\n\t\t: undefined;\n\tconst bProps = isPlainObj(b.properties)\n\t\t? (b.properties as Record<string, JSONSchema7Definition>)\n\t\t: undefined;\n\n\t// Si aucun des deux n'a de properties, on ne peut rien déterminer\n\tif (!aProps && !bProps) return false;\n\n\tconst aKeys = aProps ? Object.keys(aProps) : [];\n\tconst bKeys = bProps ? Object.keys(bProps) : [];\n\tconst aRequired = Array.isArray(a.required) ? (a.required as string[]) : [];\n\tconst bRequired = Array.isArray(b.required) ? (b.required as string[]) : [];\n\n\t// ── Vérifier additionalProperties: false de a vs propriétés REQUISES extra de b ──\n\t// Condition stricte : b doit DÉFINIR la propriété dans b.properties ET la\n\t// REQUÉRIR dans b.required, ET cette propriété doit être ABSENTE de a.properties.\n\t// De plus, a doit lui-même avoir des propriétés (sinon on ne peut rien dire).\n\tif (a.additionalProperties === false && aProps && bProps) {\n\t\tconst hasRequiredExtra = bRequired.some(\n\t\t\t(k) => !hasOwn(aProps, k) && hasOwn(bProps, k),\n\t\t);\n\t\t// Ne détecter le conflit que si a a aussi un required qui rend l'objet\n\t\t// structurellement contraint (pas un schema vague)\n\t\tif (hasRequiredExtra && aKeys.length > 0) return true;\n\t}\n\n\t// ── Vérification du cas additionalProperties comme schema ──\n\t// Si a.additionalProperties est un schema avec un type, et que b REQUIERT\n\t// une propriété extra dont le type est incompatible → conflit\n\tif (\n\t\tisPlainObj(a.additionalProperties) &&\n\t\ttypeof a.additionalProperties !== \"boolean\" &&\n\t\taProps &&\n\t\tbProps\n\t) {\n\t\tconst addPropsSchema = a.additionalProperties as JSONSchema7;\n\t\tif (hasOwn(addPropsSchema, \"type\")) {\n\t\t\tconst addPropsType = addPropsSchema.type;\n\t\t\tconst hasTypeConflict = bRequired.some((k) => {\n\t\t\t\tif (hasOwn(aProps, k)) return false;\n\t\t\t\tif (!hasOwn(bProps, k)) return false;\n\t\t\t\tconst bPropDef = bProps[k];\n\t\t\t\tif (typeof bPropDef === \"boolean\") return false;\n\t\t\t\tconst bProp = bPropDef as JSONSchema7;\n\t\t\t\tif (!hasOwn(bProp, \"type\")) return false;\n\t\t\t\tif (\n\t\t\t\t\ttypeof addPropsType === \"string\" &&\n\t\t\t\t\ttypeof bProp.type === \"string\"\n\t\t\t\t) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\taddPropsType !== bProp.type &&\n\t\t\t\t\t\t!(addPropsType === \"number\" && bProp.type === \"integer\") &&\n\t\t\t\t\t\t!(addPropsType === \"integer\" && bProp.type === \"number\")\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (hasTypeConflict) return true;\n\t\t}\n\t}\n\n\t// ── Vérification symétrique : additionalProperties de b vs propriétés REQUISES extra de a ──\n\tif (b.additionalProperties === false && bProps && aProps) {\n\t\tconst hasRequiredExtra = aRequired.some(\n\t\t\t(k) => !hasOwn(bProps, k) && hasOwn(aProps, k),\n\t\t);\n\t\tif (hasRequiredExtra && bKeys.length > 0) return true;\n\t}\n\n\t// Symétrique pour additionalProperties comme schema\n\tif (\n\t\tisPlainObj(b.additionalProperties) &&\n\t\ttypeof b.additionalProperties !== \"boolean\" &&\n\t\tbProps &&\n\t\taProps\n\t) {\n\t\tconst addPropsSchema = b.additionalProperties as JSONSchema7;\n\t\tif (hasOwn(addPropsSchema, \"type\")) {\n\t\t\tconst addPropsType = addPropsSchema.type;\n\t\t\tconst hasTypeConflict = aRequired.some((k) => {\n\t\t\t\tif (hasOwn(bProps, k)) return false;\n\t\t\t\tif (!hasOwn(aProps, k)) return false;\n\t\t\t\tconst aPropDef = aProps[k];\n\t\t\t\tif (typeof aPropDef === \"boolean\") return false;\n\t\t\t\tconst aProp = aPropDef as JSONSchema7;\n\t\t\t\tif (!hasOwn(aProp, \"type\")) return false;\n\t\t\t\tif (\n\t\t\t\t\ttypeof addPropsType === \"string\" &&\n\t\t\t\t\ttypeof aProp.type === \"string\"\n\t\t\t\t) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\taddPropsType !== aProp.type &&\n\t\t\t\t\t\t!(addPropsType === \"number\" && aProp.type === \"integer\") &&\n\t\t\t\t\t\t!(addPropsType === \"integer\" && aProp.type === \"number\")\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (hasTypeConflict) return true;\n\t\t}\n\t}\n\n\t// ── Récursion dans les propriétés communes ──\n\t// Si les deux schemas ont des propriétés communes qui sont des objets,\n\t// vérifier récursivement les conflits additionalProperties\n\tif (aProps && bProps) {\n\t\tfor (const k of aKeys) {\n\t\t\tif (!hasOwn(bProps, k)) continue;\n\t\t\tconst aPropDef = aProps[k];\n\t\t\tconst bPropDef = bProps[k];\n\t\t\tif (typeof aPropDef === \"boolean\" || typeof bPropDef === \"boolean\")\n\t\t\t\tcontinue;\n\t\t\tif (\n\t\t\t\thasAdditionalPropertiesConflict(\n\t\t\t\t\taPropDef as JSONSchema7Definition,\n\t\t\t\t\tbPropDef as JSONSchema7Definition,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// ─── Format conflict detection ───────────────────────────────────────────────\n\n/**\n * Détecte un conflit de format entre deux schemas.\n *\n * ⚠️ Ne se déclenche QUE quand les DEUX schemas ont un `format`.\n * Si un seul schema a un `format`, il n'y a PAS de conflit — le merge\n * engine gère nativement ce cas (le format est conservé dans l'intersection,\n * et la comparaison `merged ≡ sub` détermine correctement la relation ⊆).\n *\n * Deux schemas avec des formats différents et sans relation d'inclusion\n * connue ont une intersection vide (ex: \"email\" ∩ \"ipv4\" = ∅).\n *\n * Utilise `isFormatSubset` de `format-validator.ts` pour vérifier la hiérarchie.\n *\n * Récurse dans les sous-schemas (`properties`, `items`, etc.) pour détecter\n * les conflits de format imbriqués.\n *\n * @returns `true` si un conflit de format est détecté, `false` sinon\n */\nfunction hasFormatConflict(\n\ta: JSONSchema7Definition,\n\tb: JSONSchema7Definition,\n): boolean {\n\tif (typeof a === \"boolean\" || typeof b === \"boolean\") return false;\n\n\t// ── Seulement quand LES DEUX ont un format ──\n\t// Si un seul a un format → pas de conflit, le merge gère nativement\n\tif (hasOwn(a, \"format\") && hasOwn(b, \"format\")) {\n\t\tconst aFormat = a.format as string;\n\t\tconst bFormat = b.format as string;\n\n\t\t// Même format → pas de conflit\n\t\tif (aFormat !== bFormat) {\n\t\t\t// Vérifier si l'un est un sous-ensemble de l'autre via la hiérarchie\n\t\t\tconst subsetCheck = isFormatSubset(aFormat, bFormat);\n\t\t\tif (subsetCheck !== true) {\n\t\t\t\tconst reverseCheck = isFormatSubset(bFormat, aFormat);\n\t\t\t\tif (reverseCheck !== true) {\n\t\t\t\t\t// Formats différents sans relation connue → conflit\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Récursion dans les sous-schemas ──\n\t// Vérifier les conflits de format dans les propriétés communes\n\tif (isPlainObj(a.properties) && isPlainObj(b.properties)) {\n\t\tconst aMap = a.properties as Record<string, JSONSchema7Definition>;\n\t\tconst bMap = b.properties as Record<string, JSONSchema7Definition>;\n\t\tfor (const k of Object.keys(aMap)) {\n\t\t\tconst aVal = aMap[k];\n\t\t\tconst bVal = bMap[k];\n\t\t\tif (\n\t\t\t\taVal !== undefined &&\n\t\t\t\tbVal !== undefined &&\n\t\t\t\thasOwn(bMap, k) &&\n\t\t\t\thasFormatConflict(aVal, bVal)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Vérifier items (single schema)\n\tif (isPlainObj(a.items) && isPlainObj(b.items)) {\n\t\tif (\n\t\t\thasFormatConflict(\n\t\t\t\ta.items as JSONSchema7Definition,\n\t\t\t\tb.items as JSONSchema7Definition,\n\t\t\t)\n\t\t)\n\t\t\treturn true;\n\t}\n\n\t// Vérifier additionalProperties\n\tif (\n\t\tisPlainObj(a.additionalProperties) &&\n\t\tisPlainObj(b.additionalProperties)\n\t) {\n\t\tif (\n\t\t\thasFormatConflict(\n\t\t\t\ta.additionalProperties as JSONSchema7Definition,\n\t\t\t\tb.additionalProperties as JSONSchema7Definition,\n\t\t\t)\n\t\t)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// ─── MergeEngine class ───────────────────────────────────────────────────────\n\nexport class MergeEngine {\n\tprivate readonly compareFn: (\n\t\ta: JSONSchema7Definition,\n\t\tb: JSONSchema7Definition,\n\t) => number;\n\n\tprivate readonly shallowAllOfMergeFn: (\n\t\tschema: JSONSchema7 & { allOf: JSONSchema7Definition[] },\n\t) => JSONSchema7Definition;\n\n\tconstructor() {\n\t\tconst { compareSchemaDefinitions, compareSchemaValues } =\n\t\t\tcreateComparator();\n\n\t\t// ── Null-safe wrapper for compareSchemaValues ──\n\t\t// The library's compareSchemaValues has a bug: when both a and b are null,\n\t\t// it returns -1 instead of 0 (the null check for `a` fires before checking\n\t\t// if `b` is also null). This causes createIntersector to lose null values\n\t\t// during enum intersection (the sort-merge join relies on compare(x,x)===0).\n\t\tconst safeCompareSchemaValues = (\n\t\t\ta: JSONSchema7Type,\n\t\t\tb: JSONSchema7Type,\n\t\t): number => {\n\t\t\tif (a === null && b === null) return 0;\n\t\t\treturn compareSchemaValues(a, b);\n\t\t};\n\n\t\tconst { mergeArrayOfSchemaDefinitions } = createMerger({\n\t\t\tintersectJson: createIntersector(safeCompareSchemaValues),\n\t\t\tdeduplicateJsonSchemaDef: createDeduplicator(compareSchemaDefinitions),\n\t\t});\n\n\t\tthis.compareFn = compareSchemaDefinitions;\n\t\tthis.shallowAllOfMergeFn = createShallowAllOfMerge(\n\t\t\tmergeArrayOfSchemaDefinitions,\n\t\t);\n\t}\n\n\t/**\n\t * Merge deux schemas via `allOf([a, b])`.\n\t * Retourne `null` si les schemas sont incompatibles.\n\t *\n\t * Post-merge : détecte les conflits de `const` que la librairie\n\t * ne capture pas (elle utilise `identity` pour `const`).\n\t */\n\tmerge(\n\t\ta: JSONSchema7Definition,\n\t\tb: JSONSchema7Definition,\n\t): JSONSchema7Definition | null {\n\t\t// Pré-check : conflit de const détectable avant le merge\n\t\tif (hasDeepConstConflict(a, b)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Pré-check : conflit de format (les DEUX ont un format incompatible)\n\t\tif (hasFormatConflict(a, b)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Pré-check : conflit additionalProperties vs propriétés REQUISES extra\n\t\t// Ne détecte que les cas où une propriété est à la fois interdite\n\t\t// (additionalProperties: false) et requise (required) → intersection vide.\n\t\t// Les cas où les propriétés sont simplement définies sans être requises\n\t\t// sont gérés correctement par la librairie de merge elle-même.\n\t\tif (hasAdditionalPropertiesConflict(a, b)) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\treturn this.shallowAllOfMergeFn({ allOf: [a, b] });\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Merge via `shallowAllOfMerge` — lève une exception si incompatible.\n\t * Utile quand on veut capturer l'erreur pour le diagnostic.\n\t *\n\t * Post-merge : détecte les conflits de `const` et lève une exception.\n\t */\n\tmergeOrThrow(\n\t\ta: JSONSchema7Definition,\n\t\tb: JSONSchema7Definition,\n\t): JSONSchema7Definition {\n\t\t// Pré-check : conflit de const\n\t\tif (hasDeepConstConflict(a, b)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Incompatible const values: schemas have conflicting const constraints\",\n\t\t\t);\n\t\t}\n\n\t\t// Pré-check : conflit de format\n\t\tif (hasFormatConflict(a, b)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Incompatible format values: schemas have conflicting format constraints\",\n\t\t\t);\n\t\t}\n\n\t\t// Pré-check : conflit additionalProperties vs propriétés REQUISES extra\n\t\tif (hasAdditionalPropertiesConflict(a, b)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Incompatible additionalProperties: required properties conflict with additionalProperties constraint\",\n\t\t\t);\n\t\t}\n\n\t\treturn this.shallowAllOfMergeFn({ allOf: [a, b] });\n\t}\n\n\t/**\n\t * Compare structurellement deux schema definitions.\n\t * Retourne 0 si elles sont identiques, sinon un entier non nul.\n\t */\n\tcompare(a: JSONSchema7Definition, b: JSONSchema7Definition): number {\n\t\treturn this.compareFn(a, b);\n\t}\n\n\t/**\n\t * Vérifie l'égalité structurelle entre deux schema definitions.\n\t */\n\tisEqual(a: JSONSchema7Definition, b: JSONSchema7Definition): boolean {\n\t\treturn this.compareFn(a, b) === 0;\n\t}\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "4666F85E3B6FD5BA64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "B46B487D9063BA4D64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  import{isEmail as y,isFQDN as z,isIP as C,isISO8601 as H,isURL as w,isUUID as Y}from"class-validator";var Z=/^\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/,$=/^\d{4}-\d{2}-\d{2}$/,x=/^(\/([^~/]|~[01])*)*$/,K=/^\d+(#|(\/([^~/]|~[01])*)*)$/;var W=new Set(["date-time","date","time","email","idn-email","hostname","idn-hostname","ipv4","ipv6","uri","uri-reference","iri","iri-reference","uri-template","uuid","json-pointer","relative-json-pointer","regex"]),q={email:["idn-email"],hostname:["idn-hostname"],uri:["iri"],"uri-reference":["iri-reference"]},J={"date-time":(g)=>{return H(g,{strict:!0})},date:(g)=>{if(!$.test(g))return!1;let j=new Date(`${g}T00:00:00Z`);return!Number.isNaN(j.getTime())&&g===j.toISOString().slice(0,10)},time:(g)=>{return Z.test(g)},email:(g)=>{return y(g)},"idn-email":(g)=>{return y(g)},hostname:(g)=>{return z(g,{require_tld:!1})},"idn-hostname":(g)=>{return z(g,{require_tld:!1})},ipv4:(g)=>{return C(g,4)},ipv6:(g)=>{return C(g,6)},uri:(g)=>{return w(g,{require_protocol:!0})},"uri-reference":(g)=>{return w(g,{require_protocol:!1})},iri:(g)=>{return w(g,{require_protocol:!0})},"iri-reference":(g)=>{return w(g,{require_protocol:!1})},"uri-template":(g)=>{let j=!1;for(let k of g)if(k==="{"){if(j)return!1;j=!0}else if(k==="}"){if(!j)return!1;j=!1}return!j},uuid:(g)=>{return Y(g)},"json-pointer":(g)=>{if(g==="")return!0;return x.test(g)},"relative-json-pointer":(g)=>{return K.test(g)},regex:(g)=>{try{return new RegExp(g),!0}catch{return!1}}};function V(g){return W.has(g)}function h(g,j){if(typeof g!=="string")return!0;let k=J[j];if(!k)return null;return k(g)}function b(g,j){if(g===j)return!0;if(q[g]?.includes(j))return!0;return null}
2
- export{W as o,q as p,V as q,h as r,b as s};
2
+ export{W as q,q as r,V as s,h as t,b as u};
3
3
 
4
- //# debugId=23E9231E413DFF0864756E2164756E21
5
- //# sourceMappingURL=chunk-07z7fc5q.js.map
4
+ //# debugId=84623DE4C3DA393664756E2164756E21
5
+ //# sourceMappingURL=chunk-gdf3h8q4.js.map