fix: PR JS

This commit is contained in:
Brennan Wilkes (Text Groove) 2026-01-22 12:06:42 -08:00
parent a29c3920e5
commit 3ba5658149

View file

@ -221,7 +221,7 @@ function applyInsertionsToArrayText({
incoming, incoming,
keyFn, keyFn,
normalizeFn, normalizeFn,
}) { }) {
const span = findJsonArraySpan(src, propName); const span = findJsonArraySpan(src, propName);
if (!span) die(`Could not find "${propName}" array in ${filePath}`); if (!span) die(`Could not find "${propName}" array in ${filePath}`);
@ -231,20 +231,16 @@ function applyInsertionsToArrayText({
const itemIndent = detectItemIndent(inner, span.fieldIndent); const itemIndent = detectItemIndent(inner, span.fieldIndent);
// Parse existing objects to build a dedupe set (does NOT modify inner text)
const rawBlocks = splitArrayObjectBlocks(inner); const rawBlocks = splitArrayObjectBlocks(inner);
const existing = [];
const seen = new Set(); const seen = new Set();
for (const raw of rawBlocks) { for (const raw of rawBlocks) {
try { try {
const obj = JSON.parse(raw); const obj = JSON.parse(raw);
const k = keyFn(obj); const k = keyFn(obj);
existing.push({ raw, obj, key: k });
if (k) seen.add(k); if (k) seen.add(k);
} catch { } catch {
// If parsing fails, keep the raw block as-is, but don't use it for keying // ignore unparsable blocks for dedupe purposes
existing.push({ raw, obj: null, key: "" });
} }
} }
@ -254,66 +250,36 @@ function applyInsertionsToArrayText({
const k = keyFn(nx); const k = keyFn(nx);
if (!k || seen.has(k)) continue; if (!k || seen.has(k)) continue;
seen.add(k); seen.add(k);
toAdd.push({ obj: nx, key: k }); toAdd.push(nx);
} }
if (!toAdd.length) return src; // nothing to do if (!toAdd.length) return src;
// Insert each new item into sorted position by key (lex) // Deterministic order for new items only (doesn't reorder existing)
// We rebuild the list of raw blocks but preserve existing raw blocks untouched. const addBlocks = toAdd
const outBlocks = existing.slice(); // keep {raw,obj,key} .map((obj) => ({ obj, key: keyFn(obj) }))
.sort((a, b) => String(a.key).localeCompare(String(b.key)))
.map((x) => makePrettyObjBlock(itemIndent, x.obj));
function findInsertIndex(k) {
for (let i = 0; i < outBlocks.length; i++) {
const kk = outBlocks[i]?.key || "";
if (!kk) continue; // unknown blocks: keep them where they are
if (kk > k) return i;
}
return outBlocks.length;
}
// Sort additions so results are deterministic
toAdd.sort((a, b) => a.key.localeCompare(b.key));
for (const add of toAdd) {
const idx = findInsertIndex(add.key);
const raw = makePrettyObjBlock(itemIndent, add.obj);
outBlocks.splice(idx, 0, { raw, obj: add.obj, key: add.key });
}
// Rebuild inner text, preserving inline-empty formatting if it was empty
let newInner = "";
if (outBlocks.length === 0) {
newInner = inner; // shouldn't happen, but keep original
} else {
// Determine if original was inline empty: "links": []
const wasInlineEmpty = /^\s*$/.test(inner); const wasInlineEmpty = /^\s*$/.test(inner);
if (wasInlineEmpty) {
// Convert to pretty multi-line on first insert (minimal and stable)
newInner =
"\n" +
outBlocks.map((x) => x.raw).join(",\n") +
"\n" +
span.fieldIndent;
} else {
// Keep pretty multi-line (same join style as JSON.stringify)
// Ensure leading/trailing newlines similar to original
const trimmed = inner.replace(/^\s+|\s+$/g, "");
const hadLeadingNL = /^\s*\n/.test(inner);
const hadTrailingNL = /\n\s*$/.test(inner);
const body = outBlocks.map((x) => x.raw).join(",\n"); let newInner;
if (wasInlineEmpty) {
// "links": [] -> pretty multiline
newInner = newInner =
(hadLeadingNL ? "\n" : "") + "\n" + addBlocks.join(",\n") + "\n" + span.fieldIndent;
body + } else {
(hadTrailingNL ? "\n" + span.fieldIndent : ""); // Keep existing whitespace EXACTLY; append before trailing whitespace
// If original didn't have trailing newline before ']', keep it tight const m = inner.match(/\s*$/);
if (!hadTrailingNL) newInner = "\n" + body + "\n" + span.fieldIndent; const tail = m ? m[0] : "";
} const body = inner.slice(0, inner.length - tail.length).replace(/\s*$/, ""); // end at last non-ws
newInner = body + ",\n" + addBlocks.join(",\n") + tail;
} }
return before + newInner + after; return before + newInner + after;
} }
/* ---------------- Apply edits ---------------- */ /* ---------------- Apply edits ---------------- */