UNPKG

json-conflict-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) 5.38 kB
import{a as c,b as m}from"./chunk-2SJFRDGH.mjs";import{c as P}from"./chunk-WFDJ25NC.mjs";import{b as w}from"./chunk-Q4E7EFS7.mjs";import"./chunk-JD45QQDD.mjs";import{a as y}from"./chunk-ICS3PEIS.mjs";import"./chunk-NHG7C4LQ.mjs";import{a as R}from"./chunk-IOL4YJZP.mjs";import{j as B}from"./chunk-HB6Q755Y.mjs";import{b,c as p}from"./chunk-AUIVUOKV.mjs";import{a as g,b as n,e as d,f as C,g as o,h as e}from"./chunk-WP4ACXPN.mjs";import{a as H}from"./chunk-3PFH3U2T.mjs";import"./chunk-76CZ6Z7T.mjs";import{execSync as z}from"child_process";import S from"fs/promises";e.mock("node:child_process");e.mock("node:fs/promises");e.mock("./file-serializer");e.mock("./merger");e.mock("./normalizer");e.mock("./utils");e.mock("./conflict-helper");e.mock("./logger");e.mock("./file-parser");var f=e.mocked(z),i=e.mocked(S),h=e.mocked(H),l=e.mocked(P),W=e.mocked(w),j=e.mocked(B),v=e.mocked(R),E=e.mocked(y),M=e.mocked(b),k=e.mocked(p);g("processMerge",()=>{let t={info:e.fn(),debug:e.fn(),warn:e.fn(),error:e.fn(),flush:e.fn()},a={defaultStrategy:"ours"},s={debug:!1,customStrategies:{}};d(()=>{e.clearAllMocks(),j.mockResolvedValue("backup/test.json"),h.mockResolvedValue('{"merged":true}')}),n("processes successful merge without conflicts",async()=>{let r={merged:!0};l.mockResolvedValue(r);let u=await c({ours:{a:1},theirs:{b:2},base:{c:3},format:"json",filePath:"test.json",config:a,normalizedConfig:s,logger:t,autoStage:!0});o(l).toHaveBeenCalledWith({ours:{a:1},theirs:{b:2},base:{c:3},filePath:"test.json",conflicts:[],path:"",ctx:o.objectContaining({config:s,strategies:{},_strategyCache:o.any(Map)}),logger:t}),o(j).toHaveBeenCalledWith("test.json",void 0),o(h).toHaveBeenCalledWith("json",r),o(i.writeFile).toHaveBeenCalledWith("test.json",'{"merged":true}',"utf8"),o(f).toHaveBeenCalledWith("git add test.json"),o(u).toEqual({success:!0,conflicts:[]})}),n("processes merge with conflicts",async()=>{let r=[{path:"a",reason:"test conflict"}],u="conflict content";l.mockImplementation(({conflicts:V})=>(V.push(...r),Promise.resolve({}))),v.mockResolvedValue(u);let F=await c({ours:{a:1},theirs:{a:2},format:"json",filePath:"test.json",config:{writeConflictSidecar:!0},normalizedConfig:s,logger:t,autoStage:!1});o(v).toHaveBeenCalledWith({},{a:1},{a:2},"json"),o(i.writeFile).toHaveBeenCalledWith("test.json",u,"utf8"),o(i.writeFile).toHaveBeenCalledWith("test.json.conflict.json",JSON.stringify(r,null,2)),o(f).not.toHaveBeenCalled(),o(F).toEqual({success:!1,conflicts:r})}),n("handles git staging errors gracefully",async()=>{l.mockResolvedValue({}),f.mockImplementation(()=>{throw new Error("git error")});let r=await c({ours:{},theirs:{},format:"json",filePath:"test.json",config:a,normalizedConfig:s,logger:t,autoStage:!0});o(t.warn).toHaveBeenCalledWith("test.json","Failed to stage file: Error: git error"),o(r.success).toBe(!0)}),n("enables debug logging when configured",async()=>{let r={debug:!0,customStrategies:{}};l.mockResolvedValue({merged:!0}),await c({ours:{},theirs:{},format:"json",filePath:"test.json",config:a,normalizedConfig:r,logger:t}),o(t.debug).toHaveBeenCalledWith("test.json",o.stringContaining("merged"))}),n("skips auto-staging when disabled",async()=>{l.mockResolvedValue({}),await c({ours:{},theirs:{},format:"json",filePath:"test.json",config:a,normalizedConfig:s,logger:t,autoStage:!1}),o(f).not.toHaveBeenCalled()})});g("resolveGitMergeFiles",()=>{let t={info:e.fn(),debug:e.fn(),warn:e.fn(),error:e.fn(),flush:e.fn()},a=e.spyOn(process,"exit").mockImplementation(()=>{});d(()=>{e.clearAllMocks(),E.mockResolvedValue(t),W.mockResolvedValue({debug:!1,customStrategies:{}}),i.readFile.mockImplementation(s=>s==="ours.json"?Promise.resolve('{"a":1}'):s==="base.json"?Promise.resolve('{"a":0}'):s==="theirs.json"?Promise.resolve('{"a":2}'):Promise.reject(new Error("File not found"))),M.mockReturnValue(["json"]),k.mockResolvedValue([{a:1},"json"]),l.mockResolvedValue({a:1}),h.mockResolvedValue('{"a":1}'),j.mockResolvedValue("backup/ours.json")}),C(()=>{a.mockClear()}),n("successfully merges files without conflicts",async()=>{await m("ours.json","base.json","theirs.json",{}),o(i.readFile).toHaveBeenCalledWith("ours.json","utf8"),o(i.readFile).toHaveBeenCalledWith("base.json","utf8"),o(i.readFile).toHaveBeenCalledWith("theirs.json","utf8"),o(k).toHaveBeenCalledTimes(3),o(i.writeFile).toHaveBeenCalledWith("ours.json",'{"a":1}',"utf8"),o(t.flush).toHaveBeenCalled(),o(a).toHaveBeenCalledWith(0)}),n("handles merge conflicts",async()=>{let s=[{path:"a",reason:"conflict"}];l.mockImplementation(({conflicts:r})=>(r.push(...s),Promise.resolve({}))),v.mockResolvedValue("conflict content"),await m("ours.json","base.json","theirs.json",{}),o(a).toHaveBeenCalledWith(1)}),n("handles missing base file gracefully",async()=>{i.readFile.mockImplementation(s=>s==="ours.json"?Promise.resolve('{"a":1}'):s==="base.json"?Promise.reject(new Error("Not found")):s==="theirs.json"?Promise.resolve('{"a":2}'):Promise.reject(new Error("File not found"))),await m("ours.json","base.json","theirs.json",{}),o(k).toHaveBeenCalledWith("{}",["json"]),o(a).toHaveBeenCalledWith(0)}),n("enables debug logging when configured",async()=>{W.mockResolvedValue({debug:!0,customStrategies:{}}),await m("ours.json","base.json","theirs.json",{debug:!0}),o(t.debug).toHaveBeenCalledWith("git-merge","Merging files: ours=ours.json, base=base.json, theirs=theirs.json")})});