Setting the file. One moment. Structured Link Patch · Wix Replatform · wix/skills · Skills Docslib/structured-link-patch.js
JavaScript·59 lines·3 KB
/'/
g
, quote
===
'"'
?
'"'
:
'''
);
7}
8
9function patchHtmlHref(html, occurrence, destination) {
10 if (typeof html !== 'string' || !/^char:\d+$/.test(occurrence.location || '')) throw new Error('HTML link location required');
11 const start = Number(occurrence.location.slice(5));
12 const fragment = html.slice(start);
13 const match = /^(href|action)\s*=\s*(["'])(.*?)\2/is.exec(fragment);
14 if (!match || decodeHtmlEntities(match[3]) !== occurrence.original) throw new Error('HTML link location or original value changed');
15 const replacement = `${match[1]}=${match[2]}${escapeAttribute(destination, match[2])}${match[2]}`;
16 return { value: `${html.slice(0, start)}${replacement}${html.slice(start + match[0].length)}`, preservedUnrelated: true, changedLocations: [occurrence.location] };
17}
18
19function jsonPathParts(location) {
20 if (!location || !location.startsWith('$.')) throw new Error('JSON field location required');
21 const parts = [];
22 for (const match of location.slice(2).matchAll(/(?:^|\.)([^.\[\]]+)|\[(\d+)\]/g)) parts.push(match[1] === undefined ? Number(match[2]) : match[1]);
23 if (!parts.length) throw new Error('unsupported JSON field location');
24 return parts;
25}
26
27function patchJsonLink(value, occurrence, destination) {
28 const clone = structuredClone(value);
29 const parts = jsonPathParts(occurrence.location);
30 let parent = clone;
31 for (const part of parts.slice(0, -1)) {
32 parent = parent && parent[part];
33 if (parent === undefined) throw new Error('JSON link location missing');
34 }
35 const key = parts.at(-1);
36 if (!parent || parent[key] !== occurrence.original) throw new Error('JSON link original value changed');
37 parent[key] = destination;
38 return { value: clone, preservedUnrelated: true, changedLocations: [occurrence.location] };
39}
40
41function structuredLinkPatch(baseValue, occurrence, destination) {
42 if (occurrence.location && occurrence.location.startsWith('char:')) return patchHtmlHref(baseValue, occurrence, destination);
43 const embedded = /^(\$\..+):(char:\d+)$/.exec(occurrence.location || '');
44 if (embedded) {
45 if (typeof baseValue === 'string') return patchHtmlHref(baseValue, { ...occurrence, location: embedded[2] }, destination);
46 const clone = structuredClone(baseValue);
47 const parts = jsonPathParts(embedded[1]);
48 let parent = clone;
49 for (const part of parts.slice(0, -1)) parent = parent && parent[part];
50 if (!parent || typeof parent[parts.at(-1)] !== 'string') throw new Error('embedded HTML field missing');
51 const patched = patchHtmlHref(parent[parts.at(-1)], { ...occurrence, location: embedded[2] }, destination);
52 parent[parts.at(-1)] = patched.value;
53 return { value: clone, preservedUnrelated: true, changedLocations: [occurrence.location] };
54 }
55 if (occurrence.location && occurrence.location.startsWith('$.')) return patchJsonLink(baseValue, occurrence, destination);
56 throw new Error('unsupported link patch location');
57}
58
59module.exports = { patchHtmlHref, patchJsonLink, structuredLinkPatch };