json-merge-resolver
Version:
A rules-based JSON conflict resolver that parses Git conflict markers, reconstructs ours/theirs, and merges with deterministic strategies — beyond line-based merges.
2 lines (1 loc) • 3.44 kB
JavaScript
var h=Object.create;var d=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,$=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var r in e)d(t,r,{get:e[r],enumerable:!0})},x=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of v(e))!$.call(t,a)&&a!==r&&d(t,a,{get:()=>e[a],enumerable:!(s=R(e,a))||s.enumerable});return t};var T=(t,e,r)=>(r=t!=null?h(F(t)):{},x(e||!t||!t.__esModule?d(r,"default",{value:t,enumerable:!0}):r,t)),_=t=>x(d({},"__esModule",{value:!0}),t);var P={};b(P,{BuiltInStrategies:()=>A,mergeObject:()=>M,statusToString:()=>E});module.exports=_(P);var k=(t,{rules:e,matcher:r})=>{var f,l,c;let s=(f=e.exact[t])!=null?f:[],a=(c=e.exactFields[(l=t.split(".").pop())!=null?l:""])!=null?c:[],i=Object.entries(e.patterns).filter(([n])=>r.isMatch(t,[n])).flatMap(([,n])=>n),g=[...s.flatMap(n=>n.strategies),...a.flatMap(n=>n.strategies),...i.flatMap(n=>n.strategies),...e.default],p=g.filter(n=>n.important),u=g.filter(n=>!n.important);return[...p,...u].map(n=>n.name)};var N=T(require("fs/promises")),O=T(require("path")),C=Symbol("MERGE_DROP");var o=0,y=1,m=2,S=3;var E=t=>{switch(t){case o:return"OK";case y:return"CONTINUE";case m:return"FAIL";case S:return"SKIP";default:return`UNKNOWN(${t})`}},w=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),A={ours:({ours:t})=>({status:o,value:t}),theirs:({theirs:t})=>({status:o,value:t}),base:({base:t})=>({status:o,value:t}),drop:t=>({status:o,value:C}),skip:({path:t})=>({status:S,reason:`Skip strategy applied at ${t}`}),"non-empty":({ours:t,theirs:e,base:r})=>t!=null&&t!==""?{status:o,value:t}:e!=null&&e!==""?{status:o,value:e}:r!=null&&r!==""?{status:o,value:r}:{status:y},update:({ours:t,theirs:e})=>t!==void 0?{status:o,value:e}:{status:o,value:C},merge:async t=>{let{ours:e,theirs:r,base:s,path:a,filePath:i,ctx:g,conflicts:p,logger:u}=t;if(w(e)&&w(r)){let f=new Set([...Object.keys(e),...Object.keys(r)]),l={};for(let c of f){let n=c.replace(/\./g,"\0").replace(/\\/g,"");l[c]=await M({ours:e[c],theirs:r[c],base:w(s)?s[c]:void 0,path:a?`${a}.${n}`:n,filePath:i,ctx:g,conflicts:p,logger:u})}return{status:o,value:l}}return{status:y,reason:"Unmergeable type"}},concat:({ours:t,theirs:e,path:r})=>Array.isArray(t)&&Array.isArray(e)?{status:o,value:[...t,...e]}:{status:y,reason:`Cannot concat at ${r}`},unique:({ours:t,theirs:e,path:r})=>Array.isArray(t)&&Array.isArray(e)?{status:o,value:[...new Set([...t,...e])]}:{status:y,reason:`Cannot concat at ${r}`}},M=async({ours:t,theirs:e,base:r,path:s,filePath:a,ctx:i,conflicts:g,logger:p})=>{var f;if(t===e)return t;i._strategyCache||(i._strategyCache=new Map);let u=i._strategyCache.get(s);u||(u=k(s,i.config),i._strategyCache.set(s,u)),p.debug(a!=null?a:"all",`path: ${s}, strategies: ${u.join(", ")||"none"}`);for(let l of u){p.debug(a!=null?a:"all",`Applying strategy '${l}' at ${s}`);let c=(f=A[l])!=null?f:i.strategies[l];if(!c)continue;let n=await c({ours:t,theirs:e,base:r,path:s,filePath:a,ctx:i,conflicts:g,logger:p});switch(n.status){case o:return n.value;case y:continue;case S:g.push({path:s,reason:n.reason});return;case m:throw g.push({path:s,reason:n.reason}),new Error(`Merge failed at ${s}: ${n.reason}`)}}g.push({path:s,reason:`All strategies failed (tried: ${u.join(", ")||"none"})`,...i.config.debug?{ours:t,theirs:e,base:r}:{}})};0&&(module.exports={BuiltInStrategies,mergeObject,statusToString});
;