@bettercms-ai/convert 0.2.1 → 0.3.0
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.
- package/CHANGELOG.md +105 -0
- package/README.md +88 -9
- package/dist/cli.js +626 -164
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +78 -2
- package/dist/index.js +629 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2622,6 +2622,75 @@ function locate(brief, sources, options) {
|
|
|
2622
2622
|
// src/loops.ts
|
|
2623
2623
|
import MagicString from "magic-string";
|
|
2624
2624
|
|
|
2625
|
+
// src/declarations.ts
|
|
2626
|
+
var BINDING_ATTR = /data-bcms-(?:layout-)?field\s*=\s*["']([^"']+)["']/g;
|
|
2627
|
+
var PROPS_ATTR = /data-bcms-props\s*=\s*["']([^"']+)["']/g;
|
|
2628
|
+
var TEMPLATE_SCAN = /:?data-bcms-(?:layout-)?field\s*=\s*(?:\{\s*`([^`]+)`\s*\}|"\s*`([^`]+)`\s*")/g;
|
|
2629
|
+
var BINDINGS_SCAN = /bcmsBindings\s*=\s*\{\{[^}]*\}\}/g;
|
|
2630
|
+
var propsDeclarations = (value, at) => value.split(";").flatMap((entry) => {
|
|
2631
|
+
const [address, kind] = entry.split("|");
|
|
2632
|
+
if (!address) return [];
|
|
2633
|
+
const scope = address.startsWith("layout:") ? "layout" : "page";
|
|
2634
|
+
return [{ scope, path: stripLayoutPrefix(address), kind: kind ?? "", at, via: "props" }];
|
|
2635
|
+
});
|
|
2636
|
+
var propsPaths = (value) => propsDeclarations(value, 0).map((d) => ({ scope: d.scope, path: d.path }));
|
|
2637
|
+
var TEMPLATE_BINDING = /^:?data-bcms-(?:layout-)?field\s*=\s*(?:\{\s*`([^`]+)`\s*\}|"\s*`([^`]+)`\s*")$/;
|
|
2638
|
+
var shapeOfPath = (path) => path.replace(/\[(?:\d+|\$\{[^}]*\})\]/g, "[*]");
|
|
2639
|
+
function declarationsIn(roots, content) {
|
|
2640
|
+
const out = [];
|
|
2641
|
+
const visit = (node) => {
|
|
2642
|
+
if (node.type === "expr") {
|
|
2643
|
+
for (const child of node.children) visit(child);
|
|
2644
|
+
return;
|
|
2645
|
+
}
|
|
2646
|
+
if (node.type !== "element") return;
|
|
2647
|
+
const kind = node.attrs.find((a) => a.name === "data-bcms-kind")?.value ?? "";
|
|
2648
|
+
const at = node.attrInsertAt;
|
|
2649
|
+
for (const attr of node.attrs) {
|
|
2650
|
+
const name = attr.name.replace(/^:/, "");
|
|
2651
|
+
if (name === "data-bcms-field" || name === "data-bcms-layout-field") {
|
|
2652
|
+
const scope = name === "data-bcms-layout-field" ? "layout" : "page";
|
|
2653
|
+
const template = content.slice(attr.range.start, attr.range.end).match(TEMPLATE_BINDING);
|
|
2654
|
+
const templated = template?.[1] ?? template?.[2];
|
|
2655
|
+
if (templated) out.push({ scope, path: shapeOfPath(stripLayoutPrefix(templated)), kind, at, via: "field" });
|
|
2656
|
+
else if (attr.value) out.push({ scope, path: stripLayoutPrefix(attr.value), kind, at, via: "field" });
|
|
2657
|
+
} else if (attr.name === "data-bcms-props") {
|
|
2658
|
+
out.push(...propsDeclarations(attr.value, at));
|
|
2659
|
+
} else if (attr.name === "bcmsBindings") {
|
|
2660
|
+
for (const path of bindingsPaths(content.slice(attr.range.start, attr.range.end))) {
|
|
2661
|
+
out.push({ scope: "page", path, kind: "", at, via: "prop" });
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
for (const child of node.children) visit(child);
|
|
2666
|
+
};
|
|
2667
|
+
for (const root of roots) visit(root);
|
|
2668
|
+
return out;
|
|
2669
|
+
}
|
|
2670
|
+
var bindingsPaths = (text) => [...text.matchAll(/["']([^"']+)["']/g)].map((match) => match[1]);
|
|
2671
|
+
var scopedPath = (scope, path) => `${scope}::${path}`;
|
|
2672
|
+
var covers = (declared, target) => declared !== void 0 && (declared.has(scopedPath(target.scope, target.path)) || declared.has(scopedPath(target.scope, shapeOfPath(target.path))));
|
|
2673
|
+
var declaredInTree = (roots, content) => new Set(declarationsIn(roots, content).map((d) => scopedPath(d.scope, d.path)));
|
|
2674
|
+
var scannedDeclarations = (content) => [...declaredByScan(content)].map((entry) => {
|
|
2675
|
+
const [scope, ...rest] = entry.split("::");
|
|
2676
|
+
return { scope, path: rest.join("::") };
|
|
2677
|
+
});
|
|
2678
|
+
function declaredByScan(content) {
|
|
2679
|
+
const out = /* @__PURE__ */ new Set();
|
|
2680
|
+
const add = (scope, path) => void out.add(scopedPath(scope, path));
|
|
2681
|
+
for (const match of content.matchAll(BINDING_ATTR)) {
|
|
2682
|
+
add(match[0].includes("layout-field") ? "layout" : "page", stripLayoutPrefix(match[1]));
|
|
2683
|
+
}
|
|
2684
|
+
for (const match of content.matchAll(TEMPLATE_SCAN)) {
|
|
2685
|
+
add(match[0].includes("layout-field") ? "layout" : "page", shapeOfPath(stripLayoutPrefix(match[1] ?? match[2])));
|
|
2686
|
+
}
|
|
2687
|
+
for (const match of content.matchAll(BINDINGS_SCAN)) for (const path of bindingsPaths(match[0])) add("page", path);
|
|
2688
|
+
for (const match of content.matchAll(PROPS_ATTR))
|
|
2689
|
+
for (const entry of propsPaths(match[1])) add(entry.scope, entry.path);
|
|
2690
|
+
return out;
|
|
2691
|
+
}
|
|
2692
|
+
var stripLayoutPrefix = (value) => value.startsWith("layout:") ? value.slice("layout:".length) : value;
|
|
2693
|
+
|
|
2625
2694
|
// src/scope.ts
|
|
2626
2695
|
function patternNames(node, out) {
|
|
2627
2696
|
if (!node || typeof node !== "object") return;
|
|
@@ -2908,7 +2977,10 @@ function wordBounded(haystack, needle) {
|
|
|
2908
2977
|
}
|
|
2909
2978
|
|
|
2910
2979
|
// src/loops.ts
|
|
2911
|
-
|
|
2980
|
+
function splitNested(leaf) {
|
|
2981
|
+
const match = leaf.match(/^([^[\]]+)\[(\d+)\]\.(.+)$/);
|
|
2982
|
+
return match ? { array: match[1], index: Number(match[2]), leaf: match[3] } : null;
|
|
2983
|
+
}
|
|
2912
2984
|
var elementEnd = (node) => node.inner ? node.inner.end + node.tag.length + 3 : null;
|
|
2913
2985
|
function findRows(roots, members) {
|
|
2914
2986
|
const wanted = new Set(members.map((m) => m.index));
|
|
@@ -2980,6 +3052,69 @@ function indentOf(content, at) {
|
|
|
2980
3052
|
const prefix = content.slice(lineStart, at);
|
|
2981
3053
|
return prefix.trim() === "" ? prefix : "";
|
|
2982
3054
|
}
|
|
3055
|
+
function writeLeaf(source, shift, member, rule, read, row, literal) {
|
|
3056
|
+
const site = member.site;
|
|
3057
|
+
const expression = `${read}(${row}, ${JSON.stringify(member.leaf)}, "")`;
|
|
3058
|
+
if (member.kind === "richtext" && rule.richtext) {
|
|
3059
|
+
source.remove(site.inner.start + shift, site.inner.end + shift);
|
|
3060
|
+
source.appendLeft(site.attrInsertAt + shift, ` ${rule.richtext(expression)}`);
|
|
3061
|
+
} else {
|
|
3062
|
+
source.overwrite(site.inner.start + shift, site.inner.end + shift, rule.text(expression));
|
|
3063
|
+
}
|
|
3064
|
+
const kind = member.kind ? ` data-bcms-kind="${member.kind}"` : "";
|
|
3065
|
+
source.appendLeft(site.attrInsertAt + shift, ` ${rule.attr("data-bcms-field", `\`${literal}\``)}${kind}`);
|
|
3066
|
+
}
|
|
3067
|
+
function emitNested(rule, array, members, prefix, outer, parent, ctx) {
|
|
3068
|
+
if (!rule.loop || !rule.text) return null;
|
|
3069
|
+
const inner = [];
|
|
3070
|
+
for (const member of members) {
|
|
3071
|
+
const split = splitNested(member.leaf);
|
|
3072
|
+
if (!split || splitNested(split.leaf) !== null) return null;
|
|
3073
|
+
inner.push({ ...member, index: split.index, leaf: split.leaf });
|
|
3074
|
+
}
|
|
3075
|
+
const rows = findRows([parent.node], inner);
|
|
3076
|
+
if (!rows || rows.length === 0) return null;
|
|
3077
|
+
if (!consecutive(rows, ctx.content)) return null;
|
|
3078
|
+
if (!sameShape(rows, ctx.content)) return null;
|
|
3079
|
+
const template = rows[0];
|
|
3080
|
+
const used = /* @__PURE__ */ new Set([
|
|
3081
|
+
...ctx.content.slice(template.range.start, template.range.end).match(/[A-Za-z_$][\w$]*/g) ?? [],
|
|
3082
|
+
outer.row,
|
|
3083
|
+
outer.index
|
|
3084
|
+
]);
|
|
3085
|
+
const allocated = allocateNames(used, [
|
|
3086
|
+
{ key: "row", name: "item" },
|
|
3087
|
+
{ key: "index", name: "j" }
|
|
3088
|
+
]);
|
|
3089
|
+
const names = { row: allocated.get("row"), index: allocated.get("index") };
|
|
3090
|
+
const fallback = [];
|
|
3091
|
+
const writable = inner.every((member) => setLeaf(fallback[member.index] ??= emptyRow(), member.leaf, member.fallback));
|
|
3092
|
+
if (!writable) return null;
|
|
3093
|
+
const source = new MagicString(ctx.content.slice(template.range.start, template.range.end));
|
|
3094
|
+
const shift = -template.range.start;
|
|
3095
|
+
const declarations = [];
|
|
3096
|
+
for (const member of template.members) {
|
|
3097
|
+
const literal = `${prefix}.${array}[\${${names.index}}].${member.leaf}`;
|
|
3098
|
+
writeLeaf(source, shift, member, rule, ctx.read, names.row, literal);
|
|
3099
|
+
declarations.push({ path: shapeOfPath(literal), literal });
|
|
3100
|
+
}
|
|
3101
|
+
const rowsExpr = `${ctx.rows}(${outer.row}, ${JSON.stringify(array)}, ${JSON.stringify(fallback.filter(Boolean))})`;
|
|
3102
|
+
if (rule.loop.kind === "attr") {
|
|
3103
|
+
source.appendRight(template.attrInsertAt + shift, ` ${rule.loop.attr(rowsExpr, names.row, names.index)}`);
|
|
3104
|
+
}
|
|
3105
|
+
if (rule.loopKey) {
|
|
3106
|
+
const key = rule.loopKey(names.index);
|
|
3107
|
+
if (!template.keyAttr) source.appendRight(template.attrInsertAt + shift, ` ${key}`);
|
|
3108
|
+
else if (template.keyAttr.end > template.keyAttr.start)
|
|
3109
|
+
source.overwrite(template.keyAttr.start + shift, template.keyAttr.end + shift, key);
|
|
3110
|
+
else return null;
|
|
3111
|
+
}
|
|
3112
|
+
const indent = indentOf(ctx.content, template.range.start);
|
|
3113
|
+
const text = rule.loop.kind === "wrap" ? `${rule.loop.open(rowsExpr, names.row, names.index)}
|
|
3114
|
+
${indented(source.toString(), indent)}
|
|
3115
|
+
${indent}${rule.loop.close}` : source.toString();
|
|
3116
|
+
return { range: { start: template.range.start, end: rows[rows.length - 1].range.end }, text, declarations };
|
|
3117
|
+
}
|
|
2983
3118
|
function emitRepeater(dialect, group, arrayPath, fallbackRows, ctx) {
|
|
2984
3119
|
const rule = DIALECT_RULES[dialect];
|
|
2985
3120
|
if (!rule.loop || !rule.text || group.length === 0) return null;
|
|
@@ -2997,20 +3132,25 @@ function emitRepeater(dialect, group, arrayPath, fallbackRows, ctx) {
|
|
|
2997
3132
|
const names = { row: allocated.get("row"), index: allocated.get("index") };
|
|
2998
3133
|
const source = new MagicString(ctx.content.slice(template.range.start, template.range.end));
|
|
2999
3134
|
const shift = -template.range.start;
|
|
3000
|
-
const
|
|
3135
|
+
const declarations = [];
|
|
3136
|
+
const nested = /* @__PURE__ */ new Map();
|
|
3137
|
+
const direct = [];
|
|
3001
3138
|
for (const member of template.members) {
|
|
3002
|
-
const
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
}
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3139
|
+
const inner = splitNested(member.leaf);
|
|
3140
|
+
if (inner === null) direct.push(member);
|
|
3141
|
+
else nested.set(inner.array, [...nested.get(inner.array) ?? [], member]);
|
|
3142
|
+
}
|
|
3143
|
+
for (const [array, members] of nested) {
|
|
3144
|
+
const plan2 = emitNested(rule, array, members, `${arrayPath}[\${${names.index}}]`, names, template, ctx);
|
|
3145
|
+
if (!plan2) return null;
|
|
3146
|
+
if (direct.some((m) => m.site.range.start >= plan2.range.start && m.site.range.end <= plan2.range.end)) return null;
|
|
3147
|
+
source.overwrite(plan2.range.start + shift, plan2.range.end + shift, plan2.text);
|
|
3148
|
+
declarations.push(...plan2.declarations);
|
|
3149
|
+
}
|
|
3150
|
+
for (const member of direct) {
|
|
3151
|
+
const literal = `${arrayPath}[\${${names.index}}].${member.leaf}`;
|
|
3152
|
+
writeLeaf(source, shift, member, rule, ctx.read, names.row, literal);
|
|
3153
|
+
declarations.push({ path: shapeOfPath(literal), literal });
|
|
3014
3154
|
}
|
|
3015
3155
|
const args = [ctx.snapshot, JSON.stringify(arrayPath), JSON.stringify(fallbackRows), ...ctx.slug ? [ctx.slug] : []];
|
|
3016
3156
|
const rowsExpr = `${ctx.rows}(${args.join(", ")})`;
|
|
@@ -3031,7 +3171,8 @@ ${indent}${rule.loop.close}` : source.toString();
|
|
|
3031
3171
|
return {
|
|
3032
3172
|
range: { start: template.range.start, end: rows[rows.length - 1].range.end },
|
|
3033
3173
|
text,
|
|
3034
|
-
|
|
3174
|
+
declarations,
|
|
3175
|
+
bindings: [...new Set(declarations.map((d) => d.path))],
|
|
3035
3176
|
names
|
|
3036
3177
|
};
|
|
3037
3178
|
}
|
|
@@ -3061,9 +3202,9 @@ function setLeaf(row, leaf, value) {
|
|
|
3061
3202
|
var FORBIDDEN = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
3062
3203
|
var emptyRow = () => /* @__PURE__ */ Object.create(null);
|
|
3063
3204
|
function splitIndexed(arrayPath, path) {
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
return { index: Number(match[
|
|
3205
|
+
if (!path.startsWith(`${arrayPath}[`)) return null;
|
|
3206
|
+
const match = path.slice(arrayPath.length).match(/^\[(\d+)\]\.(.+)$/);
|
|
3207
|
+
return match ? { index: Number(match[1]), leaf: match[2] } : null;
|
|
3067
3208
|
}
|
|
3068
3209
|
|
|
3069
3210
|
// src/sites/jsx.ts
|
|
@@ -3556,22 +3697,68 @@ var firstPresent = (base, files) => [base, ...EXTENSIONS.map((ext) => `${base}${
|
|
|
3556
3697
|
function aliasesFrom(sources) {
|
|
3557
3698
|
const out = /* @__PURE__ */ new Map();
|
|
3558
3699
|
for (const source of sources) {
|
|
3559
|
-
if (!
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
}
|
|
3570
|
-
} catch {
|
|
3700
|
+
if (!isProjectConfig(source.path)) continue;
|
|
3701
|
+
const parsed = readJsonc(source.content);
|
|
3702
|
+
if (parsed === null) continue;
|
|
3703
|
+
const base = parsed.compilerOptions?.baseUrl?.replace(/^\.\/?/, "").replace(/\/$/, "") ?? "";
|
|
3704
|
+
const root = source.path.split("/").slice(0, -1).join("/");
|
|
3705
|
+
for (const [pattern, targets] of Object.entries(parsed.compilerOptions?.paths ?? {})) {
|
|
3706
|
+
out.set(
|
|
3707
|
+
pattern,
|
|
3708
|
+
targets.map((target) => [root, base, target.replace(/^\.\/?/, "")].filter(Boolean).join("/"))
|
|
3709
|
+
);
|
|
3571
3710
|
}
|
|
3572
3711
|
}
|
|
3573
3712
|
return out;
|
|
3574
3713
|
}
|
|
3714
|
+
var isProjectConfig = (path) => path.endsWith("tsconfig.json") || path.endsWith("jsconfig.json");
|
|
3715
|
+
function readJsonc(content) {
|
|
3716
|
+
let out = "";
|
|
3717
|
+
let at = 0;
|
|
3718
|
+
while (at < content.length) {
|
|
3719
|
+
const char = content[at];
|
|
3720
|
+
if (char === '"') {
|
|
3721
|
+
const start = at++;
|
|
3722
|
+
while (at < content.length && content[at] !== '"') at += content[at] === "\\" ? 2 : 1;
|
|
3723
|
+
out += content.slice(start, Math.min(at + 1, content.length));
|
|
3724
|
+
at++;
|
|
3725
|
+
continue;
|
|
3726
|
+
}
|
|
3727
|
+
if (char === "/" && content[at + 1] === "/") {
|
|
3728
|
+
while (at < content.length && content[at] !== "\n") at++;
|
|
3729
|
+
continue;
|
|
3730
|
+
}
|
|
3731
|
+
if (char === "/" && content[at + 1] === "*") {
|
|
3732
|
+
const close = content.indexOf("*/", at + 2);
|
|
3733
|
+
at = close < 0 ? content.length : close + 2;
|
|
3734
|
+
continue;
|
|
3735
|
+
}
|
|
3736
|
+
out += char;
|
|
3737
|
+
at++;
|
|
3738
|
+
}
|
|
3739
|
+
try {
|
|
3740
|
+
const parsed = JSON.parse(out.replace(/,(?=\s*[}\]])/g, ""));
|
|
3741
|
+
return isAliasShaped(parsed) ? parsed : null;
|
|
3742
|
+
} catch {
|
|
3743
|
+
return null;
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3747
|
+
function isAliasShaped(value) {
|
|
3748
|
+
if (!isRecord(value)) return false;
|
|
3749
|
+
const options = value.compilerOptions;
|
|
3750
|
+
if (options === void 0) return true;
|
|
3751
|
+
if (!isRecord(options)) return false;
|
|
3752
|
+
if (options.baseUrl !== void 0 && typeof options.baseUrl !== "string") return false;
|
|
3753
|
+
if (options.paths === void 0) return true;
|
|
3754
|
+
if (!isRecord(options.paths)) return false;
|
|
3755
|
+
return Object.values(options.paths).every(
|
|
3756
|
+
(targets) => Array.isArray(targets) && targets.every((target) => typeof target === "string")
|
|
3757
|
+
);
|
|
3758
|
+
}
|
|
3759
|
+
function unreadableConfigs(sources) {
|
|
3760
|
+
return sources.filter((source) => isProjectConfig(source.path) && readJsonc(source.content) === null).map((source) => source.path);
|
|
3761
|
+
}
|
|
3575
3762
|
function expand(specifier, aliases) {
|
|
3576
3763
|
const out = [];
|
|
3577
3764
|
for (const [pattern, targets] of aliases) {
|
|
@@ -3740,74 +3927,6 @@ function typeMember(content, literal) {
|
|
|
3740
3927
|
return { start: at, end: at, text: `${terminated ? "" : ";"} ${text}` };
|
|
3741
3928
|
}
|
|
3742
3929
|
|
|
3743
|
-
// src/declarations.ts
|
|
3744
|
-
var BINDING_ATTR = /data-bcms-(?:layout-)?field\s*=\s*["']([^"']+)["']/g;
|
|
3745
|
-
var PROPS_ATTR = /data-bcms-props\s*=\s*["']([^"']+)["']/g;
|
|
3746
|
-
var TEMPLATE_SCAN = /:?data-bcms-(?:layout-)?field\s*=\s*(?:\{\s*`([^`]+)`\s*\}|"\s*`([^`]+)`\s*")/g;
|
|
3747
|
-
var BINDINGS_SCAN = /bcmsBindings\s*=\s*\{\{[^}]*\}\}/g;
|
|
3748
|
-
var propsDeclarations = (value, at) => value.split(";").flatMap((entry) => {
|
|
3749
|
-
const [address, kind] = entry.split("|");
|
|
3750
|
-
if (!address) return [];
|
|
3751
|
-
const scope = address.startsWith("layout:") ? "layout" : "page";
|
|
3752
|
-
return [{ scope, path: stripLayoutPrefix(address), kind: kind ?? "", at, via: "props" }];
|
|
3753
|
-
});
|
|
3754
|
-
var propsPaths = (value) => propsDeclarations(value, 0).map((d) => ({ scope: d.scope, path: d.path }));
|
|
3755
|
-
var TEMPLATE_BINDING = /^:?data-bcms-(?:layout-)?field\s*=\s*(?:\{\s*`([^`]+)`\s*\}|"\s*`([^`]+)`\s*")$/;
|
|
3756
|
-
var shapeOfPath = (path) => path.replace(/\[(?:\d+|\$\{[^}]*\})\]/g, "[*]");
|
|
3757
|
-
function declarationsIn(roots, content) {
|
|
3758
|
-
const out = [];
|
|
3759
|
-
const visit = (node) => {
|
|
3760
|
-
if (node.type === "expr") {
|
|
3761
|
-
for (const child of node.children) visit(child);
|
|
3762
|
-
return;
|
|
3763
|
-
}
|
|
3764
|
-
if (node.type !== "element") return;
|
|
3765
|
-
const kind = node.attrs.find((a) => a.name === "data-bcms-kind")?.value ?? "";
|
|
3766
|
-
const at = node.attrInsertAt;
|
|
3767
|
-
for (const attr of node.attrs) {
|
|
3768
|
-
const name = attr.name.replace(/^:/, "");
|
|
3769
|
-
if (name === "data-bcms-field" || name === "data-bcms-layout-field") {
|
|
3770
|
-
const scope = name === "data-bcms-layout-field" ? "layout" : "page";
|
|
3771
|
-
const template = content.slice(attr.range.start, attr.range.end).match(TEMPLATE_BINDING);
|
|
3772
|
-
const templated = template?.[1] ?? template?.[2];
|
|
3773
|
-
if (templated) out.push({ scope, path: shapeOfPath(stripLayoutPrefix(templated)), kind, at, via: "field" });
|
|
3774
|
-
else if (attr.value) out.push({ scope, path: stripLayoutPrefix(attr.value), kind, at, via: "field" });
|
|
3775
|
-
} else if (attr.name === "data-bcms-props") {
|
|
3776
|
-
out.push(...propsDeclarations(attr.value, at));
|
|
3777
|
-
} else if (attr.name === "bcmsBindings") {
|
|
3778
|
-
for (const path of bindingsPaths(content.slice(attr.range.start, attr.range.end))) {
|
|
3779
|
-
out.push({ scope: "page", path, kind: "", at, via: "prop" });
|
|
3780
|
-
}
|
|
3781
|
-
}
|
|
3782
|
-
}
|
|
3783
|
-
for (const child of node.children) visit(child);
|
|
3784
|
-
};
|
|
3785
|
-
for (const root of roots) visit(root);
|
|
3786
|
-
return out;
|
|
3787
|
-
}
|
|
3788
|
-
var bindingsPaths = (text) => [...text.matchAll(/["']([^"']+)["']/g)].map((match) => match[1]);
|
|
3789
|
-
var scopedPath = (scope, path) => `${scope}::${path}`;
|
|
3790
|
-
var declaredInTree = (roots, content) => new Set(declarationsIn(roots, content).map((d) => scopedPath(d.scope, d.path)));
|
|
3791
|
-
var scannedDeclarations = (content) => [...declaredByScan(content)].map((entry) => {
|
|
3792
|
-
const [scope, ...rest] = entry.split("::");
|
|
3793
|
-
return { scope, path: rest.join("::") };
|
|
3794
|
-
});
|
|
3795
|
-
function declaredByScan(content) {
|
|
3796
|
-
const out = /* @__PURE__ */ new Set();
|
|
3797
|
-
const add = (scope, path) => void out.add(scopedPath(scope, path));
|
|
3798
|
-
for (const match of content.matchAll(BINDING_ATTR)) {
|
|
3799
|
-
add(match[0].includes("layout-field") ? "layout" : "page", stripLayoutPrefix(match[1]));
|
|
3800
|
-
}
|
|
3801
|
-
for (const match of content.matchAll(TEMPLATE_SCAN)) {
|
|
3802
|
-
add(match[0].includes("layout-field") ? "layout" : "page", shapeOfPath(stripLayoutPrefix(match[1] ?? match[2])));
|
|
3803
|
-
}
|
|
3804
|
-
for (const match of content.matchAll(BINDINGS_SCAN)) for (const path of bindingsPaths(match[0])) add("page", path);
|
|
3805
|
-
for (const match of content.matchAll(PROPS_ATTR))
|
|
3806
|
-
for (const entry of propsPaths(match[1])) add(entry.scope, entry.path);
|
|
3807
|
-
return out;
|
|
3808
|
-
}
|
|
3809
|
-
var stripLayoutPrefix = (value) => value.startsWith("layout:") ? value.slice("layout:".length) : value;
|
|
3810
|
-
|
|
3811
3930
|
// src/converted.ts
|
|
3812
3931
|
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3813
3932
|
function splitArrayPath(path) {
|
|
@@ -4653,7 +4772,7 @@ var ValidationError = class extends Error {
|
|
|
4653
4772
|
}
|
|
4654
4773
|
code;
|
|
4655
4774
|
};
|
|
4656
|
-
var
|
|
4775
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4657
4776
|
var Check = class {
|
|
4658
4777
|
constructor(code) {
|
|
4659
4778
|
this.code = code;
|
|
@@ -4663,7 +4782,7 @@ var Check = class {
|
|
|
4663
4782
|
throw new ValidationError(this.code, `${where} ${why}.`);
|
|
4664
4783
|
}
|
|
4665
4784
|
record(value, where) {
|
|
4666
|
-
if (!
|
|
4785
|
+
if (!isRecord2(value)) this.fail(where, "is not an object");
|
|
4667
4786
|
return value;
|
|
4668
4787
|
}
|
|
4669
4788
|
array(value, where) {
|
|
@@ -5119,10 +5238,10 @@ var SectionInvariantError = class extends Error {
|
|
|
5119
5238
|
}
|
|
5120
5239
|
};
|
|
5121
5240
|
function assertSections(total, sections) {
|
|
5122
|
-
const sum = sections.extracted + sections.inlineOnly + sections.alreadyExtracted + sections.pending.length;
|
|
5241
|
+
const sum = sections.extracted + sections.inlineOnly + sections.alreadyExtracted + sections.registered + sections.pending.length;
|
|
5123
5242
|
if (sum !== total) {
|
|
5124
5243
|
throw new SectionInvariantError(
|
|
5125
|
-
`The receipt does not account for every section: ${total} planned but ${sections.extracted} extracted + ${sections.inlineOnly} inline-only + ${sections.alreadyExtracted} already extracted + ${sections.pending.length} pending = ${sum}.`
|
|
5244
|
+
`The receipt does not account for every section: ${total} planned but ${sections.extracted} extracted + ${sections.inlineOnly} inline-only + ${sections.alreadyExtracted} already extracted + ${sections.registered} registered + ${sections.pending.length} pending = ${sum}.`
|
|
5126
5245
|
);
|
|
5127
5246
|
}
|
|
5128
5247
|
return sections;
|
|
@@ -5132,16 +5251,28 @@ var REGISTRY_MARKER = "// @bettercms-ai/convert sections v1";
|
|
|
5132
5251
|
var COMPONENT_DIR = "src/components/bcms";
|
|
5133
5252
|
var SECTIONS_LIB = "src/lib/bcms-sections.ts";
|
|
5134
5253
|
var EXTRACTABLE = ["astro", "jsx"];
|
|
5254
|
+
var registryValue = (entry) => entry.member ? `${entry.name}.${entry.member}` : entry.name;
|
|
5255
|
+
function importLine(name, specifier, entry) {
|
|
5256
|
+
if (entry.kind === "namespace") return `import * as ${name} from "${specifier}";`;
|
|
5257
|
+
if (entry.kind === "named") {
|
|
5258
|
+
const exported = entry.imported ?? name;
|
|
5259
|
+
return `import { ${exported === name ? name : `${exported} as ${name}`} } from "${specifier}";`;
|
|
5260
|
+
}
|
|
5261
|
+
return `import ${name} from "${specifier}";`;
|
|
5262
|
+
}
|
|
5135
5263
|
async function componentizeSources(briefIn, planIn, sources, options) {
|
|
5136
5264
|
const pending = [];
|
|
5137
5265
|
let extracted = 0;
|
|
5138
5266
|
let inlineOnly = 0;
|
|
5139
5267
|
let alreadyExtracted = 0;
|
|
5268
|
+
let registered = 0;
|
|
5140
5269
|
let planPending = 0;
|
|
5141
5270
|
let total = 0;
|
|
5142
5271
|
const brief = readBrief(briefIn);
|
|
5143
5272
|
const plan2 = readPlan(planIn);
|
|
5144
5273
|
const contents = new Map(sources.map((s) => [s.path, s.content]));
|
|
5274
|
+
const fileSet = new Set(contents.keys());
|
|
5275
|
+
const aliases = aliasesFrom(sources);
|
|
5145
5276
|
const pend = (route, groupKey, reason, message) => void pending.push({ route, groupKey, reason, ...message ? { message } : {} });
|
|
5146
5277
|
const trees = /* @__PURE__ */ new Map();
|
|
5147
5278
|
const treeOf = async (file) => {
|
|
@@ -5167,6 +5298,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5167
5298
|
};
|
|
5168
5299
|
const fresh = /* @__PURE__ */ new Set();
|
|
5169
5300
|
const registryConflicts = [];
|
|
5301
|
+
const registryUnreadable = [];
|
|
5170
5302
|
for (const dialect of EXTRACTABLE) {
|
|
5171
5303
|
const path = `${COMPONENT_DIR}/Sections.${dialect === "astro" ? "astro" : "tsx"}`;
|
|
5172
5304
|
const existing = contents.get(path);
|
|
@@ -5175,7 +5307,11 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5175
5307
|
registryConflicts.push(path);
|
|
5176
5308
|
continue;
|
|
5177
5309
|
}
|
|
5178
|
-
const held = readRegistry(existing, dialect);
|
|
5310
|
+
const held = await readRegistry(existing, dialect, path, fileSet, aliases);
|
|
5311
|
+
if (held === null) {
|
|
5312
|
+
registryUnreadable.push(path);
|
|
5313
|
+
continue;
|
|
5314
|
+
}
|
|
5179
5315
|
componentsOf(dialect);
|
|
5180
5316
|
for (const [slug, component] of held.components) written.get(dialect).set(slug, component);
|
|
5181
5317
|
const order = shipped.get(dialect) ?? /* @__PURE__ */ new Map();
|
|
@@ -5185,6 +5321,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5185
5321
|
const lib = contents.get(SECTIONS_LIB);
|
|
5186
5322
|
if (lib !== void 0 && !isGenerated(lib)) registryConflicts.push(SECTIONS_LIB);
|
|
5187
5323
|
const registryBlocked = registryConflicts.length > 0 && options?.overwriteHelper !== true;
|
|
5324
|
+
const registryUnread = registryUnreadable.length > 0;
|
|
5188
5325
|
for (const page of plan2.pages ?? []) {
|
|
5189
5326
|
const sections2 = (page.sections ?? []).filter((section) => {
|
|
5190
5327
|
if (section.pending) {
|
|
@@ -5195,6 +5332,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5195
5332
|
});
|
|
5196
5333
|
total += sections2.length;
|
|
5197
5334
|
if (sections2.length === 0) continue;
|
|
5335
|
+
const pendingBefore = pending.length;
|
|
5198
5336
|
const briefPage = brief.pages.find((p) => p.route === page.route);
|
|
5199
5337
|
const pageSlug = briefPage?.slug ?? slugify(page.route === "/" ? "home" : page.route);
|
|
5200
5338
|
if (helperBlocked) {
|
|
@@ -5209,6 +5347,17 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5209
5347
|
}
|
|
5210
5348
|
continue;
|
|
5211
5349
|
}
|
|
5350
|
+
if (registryUnread) {
|
|
5351
|
+
for (const section of sections2) {
|
|
5352
|
+
pend(
|
|
5353
|
+
page.route,
|
|
5354
|
+
section.groupKey,
|
|
5355
|
+
"REGISTRY_UNREADABLE",
|
|
5356
|
+
`${registryUnreadable.join(", ")} carries our marker but its REGISTRY/SHIPPED tables cannot be read back \u2014 rebuilding it would drop the components it names.`
|
|
5357
|
+
);
|
|
5358
|
+
}
|
|
5359
|
+
continue;
|
|
5360
|
+
}
|
|
5212
5361
|
const snapshotPath = `${CONTENT_DIR}/${pageSlug}.json`;
|
|
5213
5362
|
if (!snapshotUsable(contents.get(snapshotPath))) {
|
|
5214
5363
|
for (const section of sections2) {
|
|
@@ -5244,37 +5393,115 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5244
5393
|
}
|
|
5245
5394
|
const live = found.placed;
|
|
5246
5395
|
if (live.length === 0) continue;
|
|
5396
|
+
const content = contents.get(file);
|
|
5397
|
+
const dialect = dialectOf(file, content);
|
|
5398
|
+
if (!dialect || !EXTRACTABLE.includes(dialect)) {
|
|
5399
|
+
for (const placed of live) {
|
|
5400
|
+
pend(page.route, placed.section.groupKey, "DIALECT_UNSUPPORTED", `${file} is ${dialect ?? "not a template"}.`);
|
|
5401
|
+
}
|
|
5402
|
+
continue;
|
|
5403
|
+
}
|
|
5404
|
+
const tree = await treeOf(file);
|
|
5405
|
+
if (!tree) {
|
|
5406
|
+
for (const placed of live) {
|
|
5407
|
+
pend(page.route, placed.section.groupKey, "NOT_IN_SOURCE", `${file} did not parse.`);
|
|
5408
|
+
}
|
|
5409
|
+
continue;
|
|
5410
|
+
}
|
|
5411
|
+
const parsed = tree.parsed;
|
|
5412
|
+
const importedFiles = /* @__PURE__ */ new Map();
|
|
5413
|
+
for (const [local, from] of importsIn(parsed, dialect)) {
|
|
5414
|
+
const resolved = resolveSpecifier(file, from.specifier, fileSet, aliases);
|
|
5415
|
+
if (resolved === null) continue;
|
|
5416
|
+
importedFiles.set(resolved, [
|
|
5417
|
+
...importedFiles.get(resolved) ?? [],
|
|
5418
|
+
{ local, kind: from.kind, imported: from.imported }
|
|
5419
|
+
]);
|
|
5420
|
+
}
|
|
5421
|
+
const bindingOf = (held) => {
|
|
5422
|
+
const bindings = importedFiles.get(held) ?? [];
|
|
5423
|
+
return bindings.find((binding) => calledIn(tree, binding)) ?? bindings[0];
|
|
5424
|
+
};
|
|
5247
5425
|
const placedHere = [];
|
|
5426
|
+
const importedSections = [];
|
|
5248
5427
|
for (const placed of live) {
|
|
5249
5428
|
const elements = placed.byFile.get(file);
|
|
5429
|
+
const alsoRendered = [...placed.byFile.keys()].filter((held2) => held2 !== file && importedFiles.has(held2));
|
|
5250
5430
|
if (elements && elements.length > 0) {
|
|
5431
|
+
if (alsoRendered.length > 0) {
|
|
5432
|
+
pend(
|
|
5433
|
+
page.route,
|
|
5434
|
+
placed.section.groupKey,
|
|
5435
|
+
"SECTION_ROOT_AMBIGUOUS",
|
|
5436
|
+
`rendered inline by ${file} AND by ${alsoRendered.join(", ")}, which it imports.`
|
|
5437
|
+
);
|
|
5438
|
+
continue;
|
|
5439
|
+
}
|
|
5251
5440
|
placedHere.push({ section: placed.section, elements });
|
|
5252
5441
|
continue;
|
|
5253
5442
|
}
|
|
5443
|
+
if (alsoRendered.length > 1) {
|
|
5444
|
+
pend(
|
|
5445
|
+
page.route,
|
|
5446
|
+
placed.section.groupKey,
|
|
5447
|
+
"SECTION_ROOT_AMBIGUOUS",
|
|
5448
|
+
`rendered by ${alsoRendered.join(" and ")}, both imported by ${file}.`
|
|
5449
|
+
);
|
|
5450
|
+
continue;
|
|
5451
|
+
}
|
|
5452
|
+
const only = alsoRendered[0] ?? [...placed.byFile.keys()][0];
|
|
5453
|
+
const held = bindingOf(only);
|
|
5454
|
+
if (held !== void 0 && dialectOf(only, contents.get(only) ?? "") === dialect) {
|
|
5455
|
+
importedSections.push({ section: placed.section, path: only, call: held.local });
|
|
5456
|
+
continue;
|
|
5457
|
+
}
|
|
5254
5458
|
pend(
|
|
5255
5459
|
page.route,
|
|
5256
5460
|
placed.section.groupKey,
|
|
5257
5461
|
"SECTION_ROOT_AMBIGUOUS",
|
|
5258
|
-
`rendered by ${[...placed.byFile.keys()].join(", ")}, not ${file}.`
|
|
5462
|
+
held === void 0 ? `rendered by ${[...placed.byFile.keys()].join(", ")}, which ${file} does not import.` : `rendered by ${only}, which is ${dialectOf(only, contents.get(only) ?? "") ?? "not a template"}, not ${dialect} like ${file}.`
|
|
5259
5463
|
);
|
|
5260
5464
|
}
|
|
5261
|
-
if (placedHere.length === 0) continue;
|
|
5262
|
-
const
|
|
5263
|
-
const
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5465
|
+
if (placedHere.length === 0 && importedSections.length === 0) continue;
|
|
5466
|
+
const extractable = componentsOf(dialect);
|
|
5467
|
+
const registeredHere = [];
|
|
5468
|
+
for (const held of importedSections) {
|
|
5469
|
+
const component = resolveComponent(plan2, held.section);
|
|
5470
|
+
const already = extractable.get(component.slug);
|
|
5471
|
+
if (already !== void 0 && already.path !== held.path) {
|
|
5472
|
+
pend(
|
|
5473
|
+
page.route,
|
|
5474
|
+
held.section.groupKey,
|
|
5475
|
+
"COMPONENT_CONFLICT",
|
|
5476
|
+
`the slug "${component.slug}" already names ${already.path}, not ${held.path}.`
|
|
5477
|
+
);
|
|
5478
|
+
continue;
|
|
5267
5479
|
}
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5480
|
+
const binding = bindingOf(held.path);
|
|
5481
|
+
const member = binding.kind === "namespace" ? namespaceMember(tree, binding.local) : void 0;
|
|
5482
|
+
if (binding.kind === "namespace" && member === void 0) {
|
|
5483
|
+
pend(
|
|
5484
|
+
page.route,
|
|
5485
|
+
held.section.groupKey,
|
|
5486
|
+
"SECTION_ROOT_AMBIGUOUS",
|
|
5487
|
+
`${held.path} is imported as a namespace and ${file} never calls one of its components, so nothing names the export that renders it.`
|
|
5488
|
+
);
|
|
5489
|
+
continue;
|
|
5274
5490
|
}
|
|
5275
|
-
|
|
5491
|
+
extractable.set(component.slug, {
|
|
5492
|
+
name: component.name,
|
|
5493
|
+
path: held.path,
|
|
5494
|
+
kind: binding.kind,
|
|
5495
|
+
imported: binding.imported,
|
|
5496
|
+
...member ? { member } : {}
|
|
5497
|
+
});
|
|
5498
|
+
registered++;
|
|
5499
|
+
registeredHere.push({
|
|
5500
|
+
slug: component.slug,
|
|
5501
|
+
bind: held.section.groupKey,
|
|
5502
|
+
call: callSiteOf(tree, member ? `${binding.local}.${member}` : held.call)
|
|
5503
|
+
});
|
|
5276
5504
|
}
|
|
5277
|
-
const parsed = tree.parsed;
|
|
5278
5505
|
const roots = [];
|
|
5279
5506
|
for (const placed of placedHere) {
|
|
5280
5507
|
const root = lowestCommonAncestor(placed.elements);
|
|
@@ -5298,8 +5525,6 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5298
5525
|
pend(page.route, resolved.section.groupKey, "SECTION_ROOT_AMBIGUOUS", "its root contains another section's.");
|
|
5299
5526
|
}
|
|
5300
5527
|
const candidates = roots.filter((r) => !nested.has(r)).sort((a, b) => a.root.start - b.root.start);
|
|
5301
|
-
if (candidates.length === 0) continue;
|
|
5302
|
-
const extractable = componentsOf(dialect);
|
|
5303
5528
|
const placeable = [];
|
|
5304
5529
|
for (const resolved of candidates) {
|
|
5305
5530
|
const path = `${COMPONENT_DIR}/${resolved.name}.${dialect === "astro" ? "astro" : "tsx"}`;
|
|
@@ -5322,7 +5547,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5322
5547
|
);
|
|
5323
5548
|
continue;
|
|
5324
5549
|
}
|
|
5325
|
-
extractable.set(resolved.slug, { name: resolved.name, path });
|
|
5550
|
+
extractable.set(resolved.slug, { name: resolved.name, path, kind: "default", imported: null });
|
|
5326
5551
|
fresh.add(resolved.slug);
|
|
5327
5552
|
addFile(outFiles, contents, {
|
|
5328
5553
|
path,
|
|
@@ -5331,24 +5556,42 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5331
5556
|
});
|
|
5332
5557
|
placeable.push(resolved);
|
|
5333
5558
|
}
|
|
5334
|
-
if (placeable.length === 0) continue;
|
|
5335
|
-
const
|
|
5559
|
+
if (placeable.length === 0 && registeredHere.length === 0) continue;
|
|
5560
|
+
const spans = [
|
|
5561
|
+
...placeable.map((r) => ({ slug: r.slug, bind: r.section.groupKey, root: r.root })),
|
|
5562
|
+
...registeredHere.map((r) => ({ slug: r.slug, bind: r.bind, root: r.call }))
|
|
5563
|
+
].sort((a, b) => (a.root?.start ?? Number.MAX_SAFE_INTEGER) - (b.root?.start ?? Number.MAX_SAFE_INTEGER));
|
|
5564
|
+
const known = spans.filter((s) => s.root !== null);
|
|
5565
|
+
const layout = runOf(known, parsed.roots, content);
|
|
5336
5566
|
if (layout === null) {
|
|
5337
5567
|
for (const resolved of placeable) {
|
|
5338
5568
|
pend(page.route, resolved.section.groupKey, "SECTION_NOT_CONTIGUOUS", "its roots share no container.");
|
|
5339
5569
|
}
|
|
5340
5570
|
continue;
|
|
5341
5571
|
}
|
|
5572
|
+
const wholePage = registeredHere.length === 0 || known.length === spans.length && pending.length === pendingBefore;
|
|
5573
|
+
const useRun = layout.contiguous && wholePage;
|
|
5342
5574
|
const order = shipped.get(dialect) ?? /* @__PURE__ */ new Map();
|
|
5343
5575
|
shipped.set(dialect, order);
|
|
5344
5576
|
order.set(
|
|
5345
5577
|
pageSlug,
|
|
5346
|
-
|
|
5578
|
+
spans.map((s) => ({ slug: s.slug, bind: s.bind }))
|
|
5347
5579
|
);
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5580
|
+
if (useRun) {
|
|
5581
|
+
addFile(outFiles, contents, {
|
|
5582
|
+
path: file,
|
|
5583
|
+
operation: "modify",
|
|
5584
|
+
content: splicePageRun(file, content, dialect, parsed, known, pageSlug)
|
|
5585
|
+
});
|
|
5586
|
+
extracted += placeable.length;
|
|
5587
|
+
} else if (placeable.length > 0) {
|
|
5588
|
+
addFile(outFiles, contents, {
|
|
5589
|
+
path: file,
|
|
5590
|
+
operation: "modify",
|
|
5591
|
+
content: splicePageInline(file, content, dialect, parsed, placeable, pageSlug, extractable)
|
|
5592
|
+
});
|
|
5593
|
+
inlineOnly += placeable.length;
|
|
5594
|
+
}
|
|
5352
5595
|
}
|
|
5353
5596
|
const componentSlugs = [...written.values()].flatMap((held) => [...held.keys()]);
|
|
5354
5597
|
if (componentSlugs.length > 0) {
|
|
@@ -5370,7 +5613,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5370
5613
|
emitHelper(outFiles, contents, helperVersion, options?.overwriteHelper);
|
|
5371
5614
|
emitStubs(outFiles, contents, pageSlugs);
|
|
5372
5615
|
}
|
|
5373
|
-
const sections = assertSections(total, { extracted, inlineOnly, alreadyExtracted, pending });
|
|
5616
|
+
const sections = assertSections(total, { extracted, inlineOnly, alreadyExtracted, registered, pending });
|
|
5374
5617
|
return {
|
|
5375
5618
|
files: [...outFiles.values()].sort((a, b) => a.path.localeCompare(b.path)),
|
|
5376
5619
|
receipt: {
|
|
@@ -5378,7 +5621,14 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
5378
5621
|
sections,
|
|
5379
5622
|
// What THIS run wrote a file for. A component an earlier run left is reused, not re-reported.
|
|
5380
5623
|
components: [...fresh].sort(),
|
|
5381
|
-
planPending
|
|
5624
|
+
planPending,
|
|
5625
|
+
notes: unreadableConfigs(sources).map(
|
|
5626
|
+
(path) => ({
|
|
5627
|
+
code: "TSCONFIG_UNREADABLE",
|
|
5628
|
+
file: path,
|
|
5629
|
+
message: `${path} is not JSON this package can read, so its \`paths\` aliases resolved to nothing.`
|
|
5630
|
+
})
|
|
5631
|
+
)
|
|
5382
5632
|
}
|
|
5383
5633
|
};
|
|
5384
5634
|
}
|
|
@@ -5391,29 +5641,138 @@ function alreadyOn(content, pageSlug, sections) {
|
|
|
5391
5641
|
}
|
|
5392
5642
|
return sections.map((section) => section.groupKey).filter((groupKey) => new RegExp(`bind=\\s*["']${groupKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}["']`).test(content));
|
|
5393
5643
|
}
|
|
5394
|
-
function readRegistry(content, dialect) {
|
|
5644
|
+
async function readRegistry(content, dialect, path, files, aliases) {
|
|
5395
5645
|
const components = /* @__PURE__ */ new Map();
|
|
5396
5646
|
const shipped = /* @__PURE__ */ new Map();
|
|
5397
|
-
const
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
const table = content
|
|
5409
|
-
|
|
5647
|
+
const parsed = await parseFile4(dialect, content);
|
|
5648
|
+
if (parsed.error) return null;
|
|
5649
|
+
const imports = /* @__PURE__ */ new Map();
|
|
5650
|
+
for (const [local, from] of importsIn(parsed, dialect)) {
|
|
5651
|
+
if (!from.specifier.startsWith(".")) continue;
|
|
5652
|
+
const resolved = resolveSpecifier(path, from.specifier, files, aliases);
|
|
5653
|
+
if (resolved !== null) {
|
|
5654
|
+
imports.set(local, { name: local, path: resolved, kind: from.kind, imported: from.imported });
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5657
|
+
const registry = blockOf(content, "REGISTRY");
|
|
5658
|
+
const table = blockOf(content, "SHIPPED");
|
|
5659
|
+
if (registry === null || table === null) return null;
|
|
5660
|
+
const registryRows = propertiesOf(registry);
|
|
5661
|
+
const shippedRows = propertiesOf(table);
|
|
5662
|
+
if (registryRows === null || shippedRows === null) return null;
|
|
5663
|
+
for (const row of registryRows) {
|
|
5664
|
+
const named = row.value.match(/^([A-Za-z_$][\w$]*)(?:\.([A-Za-z_$][\w$]*))?$/);
|
|
5665
|
+
const entry = named ? imports.get(named[1]) : void 0;
|
|
5666
|
+
if (!named || !entry) return null;
|
|
5667
|
+
components.set(row.key, named[2] === void 0 ? entry : { ...entry, member: named[2] });
|
|
5668
|
+
}
|
|
5669
|
+
for (const row of shippedRows) {
|
|
5410
5670
|
try {
|
|
5411
|
-
|
|
5671
|
+
const placements = JSON.parse(row.value);
|
|
5672
|
+
if (!Array.isArray(placements)) return null;
|
|
5673
|
+
shipped.set(row.key, placements);
|
|
5412
5674
|
} catch {
|
|
5675
|
+
return null;
|
|
5413
5676
|
}
|
|
5414
5677
|
}
|
|
5415
5678
|
return { components, shipped };
|
|
5416
5679
|
}
|
|
5680
|
+
function blockOf(content, name) {
|
|
5681
|
+
const declaration2 = content.indexOf(`const ${name}`);
|
|
5682
|
+
if (declaration2 < 0) return null;
|
|
5683
|
+
const open = content.indexOf("{", declaration2);
|
|
5684
|
+
if (open < 0) return null;
|
|
5685
|
+
let depth = 0;
|
|
5686
|
+
let at = open;
|
|
5687
|
+
while (at < content.length) {
|
|
5688
|
+
const skip = skipTrivia(content, at);
|
|
5689
|
+
if (skip >= 0) {
|
|
5690
|
+
at = skip;
|
|
5691
|
+
continue;
|
|
5692
|
+
}
|
|
5693
|
+
if (content[at] === "{") depth++;
|
|
5694
|
+
else if (content[at] === "}" && --depth === 0) return content.slice(open + 1, at);
|
|
5695
|
+
at++;
|
|
5696
|
+
}
|
|
5697
|
+
return null;
|
|
5698
|
+
}
|
|
5699
|
+
function skipTrivia(source, at) {
|
|
5700
|
+
const char = source[at];
|
|
5701
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
5702
|
+
let cursor = at + 1;
|
|
5703
|
+
while (cursor < source.length && source[cursor] !== char) cursor += source[cursor] === "\\" ? 2 : 1;
|
|
5704
|
+
return Math.min(cursor + 1, source.length);
|
|
5705
|
+
}
|
|
5706
|
+
if (char === "/" && source[at + 1] === "/") {
|
|
5707
|
+
const line = source.indexOf("\n", at);
|
|
5708
|
+
return line < 0 ? source.length : line;
|
|
5709
|
+
}
|
|
5710
|
+
if (char === "/" && source[at + 1] === "*") {
|
|
5711
|
+
const close = source.indexOf("*/", at + 2);
|
|
5712
|
+
return close < 0 ? source.length : close + 2;
|
|
5713
|
+
}
|
|
5714
|
+
return -1;
|
|
5715
|
+
}
|
|
5716
|
+
function withoutComments(text) {
|
|
5717
|
+
let out = "";
|
|
5718
|
+
let at = 0;
|
|
5719
|
+
while (at < text.length) {
|
|
5720
|
+
const skip = skipTrivia(text, at);
|
|
5721
|
+
if (skip < 0) {
|
|
5722
|
+
out += text[at];
|
|
5723
|
+
at++;
|
|
5724
|
+
continue;
|
|
5725
|
+
}
|
|
5726
|
+
out += text[at] === '"' || text[at] === "'" || text[at] === "`" ? text.slice(at, skip) : "";
|
|
5727
|
+
at = skip;
|
|
5728
|
+
}
|
|
5729
|
+
return out;
|
|
5730
|
+
}
|
|
5731
|
+
function propertiesOf(block) {
|
|
5732
|
+
const out = [];
|
|
5733
|
+
const push = (text) => {
|
|
5734
|
+
const held = text.trim();
|
|
5735
|
+
if (held === "") return true;
|
|
5736
|
+
let depth2 = 0;
|
|
5737
|
+
for (let at = 0; at < held.length; ) {
|
|
5738
|
+
const skip = skipTrivia(held, at);
|
|
5739
|
+
if (skip >= 0) {
|
|
5740
|
+
at = skip;
|
|
5741
|
+
continue;
|
|
5742
|
+
}
|
|
5743
|
+
const char = held[at];
|
|
5744
|
+
if ("{[(".includes(char)) depth2++;
|
|
5745
|
+
else if ("}])".includes(char)) depth2--;
|
|
5746
|
+
else if (char === ":" && depth2 === 0) {
|
|
5747
|
+
const key = withoutComments(held.slice(0, at)).trim().replace(/^["'`]|["'`]$/g, "");
|
|
5748
|
+
const value = withoutComments(held.slice(at + 1)).trim();
|
|
5749
|
+
if (key === "" || value === "") return false;
|
|
5750
|
+
out.push({ key, value });
|
|
5751
|
+
return true;
|
|
5752
|
+
}
|
|
5753
|
+
at++;
|
|
5754
|
+
}
|
|
5755
|
+
return false;
|
|
5756
|
+
};
|
|
5757
|
+
let depth = 0;
|
|
5758
|
+
let start = 0;
|
|
5759
|
+
for (let at = 0; at < block.length; ) {
|
|
5760
|
+
const skip = skipTrivia(block, at);
|
|
5761
|
+
if (skip >= 0) {
|
|
5762
|
+
at = skip;
|
|
5763
|
+
continue;
|
|
5764
|
+
}
|
|
5765
|
+
const char = block[at];
|
|
5766
|
+
if ("{[(".includes(char)) depth++;
|
|
5767
|
+
else if ("}])".includes(char)) depth--;
|
|
5768
|
+
else if (char === "," && depth === 0) {
|
|
5769
|
+
if (!push(block.slice(start, at))) return null;
|
|
5770
|
+
start = at + 1;
|
|
5771
|
+
}
|
|
5772
|
+
at++;
|
|
5773
|
+
}
|
|
5774
|
+
return push(block.slice(start)) ? out : null;
|
|
5775
|
+
}
|
|
5417
5776
|
function snapshotUsable(existing) {
|
|
5418
5777
|
if (existing === void 0) return true;
|
|
5419
5778
|
try {
|
|
@@ -5498,7 +5857,22 @@ function lowestCommonAncestor(elements) {
|
|
|
5498
5857
|
}
|
|
5499
5858
|
return common[common.length - 1] ?? null;
|
|
5500
5859
|
}
|
|
5501
|
-
|
|
5860
|
+
var calledIn = (tree, binding) => [...tree.elements.values()].some(
|
|
5861
|
+
(placed) => binding.kind === "namespace" ? placed.node.tag.startsWith(`${binding.local}.`) : placed.node.tag === binding.local
|
|
5862
|
+
);
|
|
5863
|
+
function namespaceMember(tree, local) {
|
|
5864
|
+
const members = new Set(
|
|
5865
|
+
[...tree.elements.values()].map((placed) => placed.node.tag).filter((tag) => tag.startsWith(`${local}.`)).map((tag) => tag.slice(local.length + 1))
|
|
5866
|
+
);
|
|
5867
|
+
return members.size === 1 ? [...members][0] : void 0;
|
|
5868
|
+
}
|
|
5869
|
+
function callSiteOf(tree, local) {
|
|
5870
|
+
const calls = [...tree.elements.values()].map((placed) => placed.node).filter((node) => node.tag === local);
|
|
5871
|
+
const only = calls.length === 1 ? calls[0] : null;
|
|
5872
|
+
return only !== null && only.attrs.length === 0 ? only : null;
|
|
5873
|
+
}
|
|
5874
|
+
function runOf(placeable, roots, content) {
|
|
5875
|
+
if (placeable.length === 0) return null;
|
|
5502
5876
|
const parents = placeable.map((r) => parentOf(r.root, roots));
|
|
5503
5877
|
if (parents.some((p) => p === void 0)) return null;
|
|
5504
5878
|
const [first, ...rest] = parents;
|
|
@@ -5508,9 +5882,14 @@ function runOf(placeable, roots) {
|
|
|
5508
5882
|
);
|
|
5509
5883
|
const indices = placeable.map((r) => siblings.indexOf(r.root)).sort((a, b) => a - b);
|
|
5510
5884
|
if (indices.some((at) => at < 0)) return null;
|
|
5511
|
-
const
|
|
5512
|
-
|
|
5885
|
+
const consecutive2 = indices.every((at, i) => i === 0 || at === indices[i - 1] + 1);
|
|
5886
|
+
const ordered = [...placeable].sort((a, b) => a.root.start - b.root.start);
|
|
5887
|
+
const clean = ordered.every(
|
|
5888
|
+
(span, at) => at === 0 || isTrivia(content.slice(ordered[at - 1].root.end, span.root.start))
|
|
5889
|
+
);
|
|
5890
|
+
return { contiguous: consecutive2 && clean };
|
|
5513
5891
|
}
|
|
5892
|
+
var isTrivia = (between) => between.replace(/<!--[\s\S]*?-->/g, "").replace(/\{\s*\/\*[\s\S]*?\*\/\s*\}/g, "").trim() === "";
|
|
5514
5893
|
function parentOf(target, roots) {
|
|
5515
5894
|
if (roots.some((node) => node === target)) return null;
|
|
5516
5895
|
const search = (nodes, parent) => {
|
|
@@ -5730,9 +6109,9 @@ function registryFile(dialect, path, written, shipped) {
|
|
|
5730
6109
|
const entries = [...written].sort(([a], [b]) => a.localeCompare(b));
|
|
5731
6110
|
const imports = entries.map(([, component]) => {
|
|
5732
6111
|
const specifier = relativeImport(path, component.path);
|
|
5733
|
-
return
|
|
6112
|
+
return importLine(component.name, dialect === "astro" ? specifier : specifier.replace(/\.tsx?$/, ""), component);
|
|
5734
6113
|
}).join("\n");
|
|
5735
|
-
const registry = entries.map(([slug, component]) => ` ${JSON.stringify(slug)}: ${component
|
|
6114
|
+
const registry = entries.map(([slug, component]) => ` ${JSON.stringify(slug)}: ${registryValue(component)},`).join("\n");
|
|
5736
6115
|
const shippedTable = [...shipped].sort(([a], [b]) => a.localeCompare(b)).map(([page, list]) => ` ${JSON.stringify(page)}: ${JSON.stringify(list)},`).join("\n");
|
|
5737
6116
|
const lib = relativeImport(path, SECTIONS_LIB).replace(/\.tsx?$/, "");
|
|
5738
6117
|
const registryType = dialect === "astro" ? "Record<string, unknown>" : "Record<string, (props: BcmsSectionProps) => JSX.Element | null>";
|
|
@@ -5840,17 +6219,24 @@ function splicePageInline(file, content, dialect, parsed, placeable, pageSlug, w
|
|
|
5840
6219
|
const snapshot = names.get("pageSnapshot");
|
|
5841
6220
|
const source = new MagicString3(content);
|
|
5842
6221
|
for (const resolved of placeable) {
|
|
6222
|
+
const component = written.get(resolved.slug);
|
|
6223
|
+
const tag = component.member ? `${names.get(resolved.slug)}.${component.member}` : names.get(resolved.slug);
|
|
5843
6224
|
source.overwrite(
|
|
5844
6225
|
resolved.root.start,
|
|
5845
6226
|
resolved.root.end,
|
|
5846
|
-
`<${
|
|
6227
|
+
`<${tag} bind=${JSON.stringify(resolved.section.groupKey)} page={${snapshot}(${JSON.stringify(pageSlug)})} />`
|
|
5847
6228
|
);
|
|
5848
6229
|
}
|
|
5849
6230
|
const lib = relativeImport(file, SECTIONS_LIB).replace(/\.tsx?$/, "");
|
|
5850
6231
|
const imports = [
|
|
5851
6232
|
...wanted.map(({ key }) => {
|
|
5852
|
-
const
|
|
5853
|
-
|
|
6233
|
+
const component = written.get(key);
|
|
6234
|
+
const specifier = relativeImport(file, component.path);
|
|
6235
|
+
return importLine(
|
|
6236
|
+
names.get(key),
|
|
6237
|
+
dialect === "astro" ? specifier : specifier.replace(/\.tsx?$/, ""),
|
|
6238
|
+
component
|
|
6239
|
+
);
|
|
5854
6240
|
}),
|
|
5855
6241
|
`import { pageSnapshot${snapshot === "pageSnapshot" ? "" : ` as ${snapshot}`} } from "${lib}";`
|
|
5856
6242
|
];
|
|
@@ -6023,28 +6409,78 @@ async function convertSources(briefIn, sources, options) {
|
|
|
6023
6409
|
);
|
|
6024
6410
|
}
|
|
6025
6411
|
let declaredOnly = 0;
|
|
6412
|
+
const declaredRows = [];
|
|
6413
|
+
const briefRoutes = new Set(brief.pages.map((page) => page.route));
|
|
6414
|
+
const declaredRow = (target, readsFromCms, file) => {
|
|
6415
|
+
declaredRows.push({
|
|
6416
|
+
route: target.route,
|
|
6417
|
+
scope: target.scope,
|
|
6418
|
+
path: target.path,
|
|
6419
|
+
kind: target.kind,
|
|
6420
|
+
...file ? { file } : {},
|
|
6421
|
+
readsFromCms
|
|
6422
|
+
});
|
|
6423
|
+
};
|
|
6026
6424
|
const witnessed = async (target) => {
|
|
6027
6425
|
for (const source of sources) {
|
|
6028
6426
|
const parsed = await parseOf(source.path);
|
|
6029
6427
|
const dialect = dialectOf(source.path, source.content);
|
|
6030
6428
|
if (!parsed || !dialect) continue;
|
|
6031
|
-
if (convertedHere(source.content, parsed, dialect, target, source.path))
|
|
6429
|
+
if (convertedHere(source.content, parsed, dialect, target, source.path) && attributable(target, source.path)) {
|
|
6430
|
+
return source.path;
|
|
6431
|
+
}
|
|
6032
6432
|
}
|
|
6033
|
-
return
|
|
6433
|
+
return null;
|
|
6034
6434
|
};
|
|
6035
6435
|
const locatedByKey = /* @__PURE__ */ new Map();
|
|
6036
6436
|
for (const hit of located) {
|
|
6037
6437
|
const key = keyOf(hit.route, hit.scope ?? "page", hit.path);
|
|
6038
6438
|
if (!locatedByKey.has(key)) locatedByKey.set(key, hit);
|
|
6039
6439
|
}
|
|
6440
|
+
const sharingPath = /* @__PURE__ */ new Map();
|
|
6441
|
+
for (const [key, hit] of locatedByKey) {
|
|
6442
|
+
const held = targets.get(key);
|
|
6443
|
+
if (!held) continue;
|
|
6444
|
+
const id = scopedPath(held.scope, held.path);
|
|
6445
|
+
sharingPath.set(id, [...sharingPath.get(id) ?? [], { key, files: hit.files }]);
|
|
6446
|
+
}
|
|
6447
|
+
const claimedByAnother = (target, file) => (sharingPath.get(scopedPath(target.scope, target.path)) ?? []).some(
|
|
6448
|
+
(other) => other.key !== target.key && other.files.includes(file)
|
|
6449
|
+
);
|
|
6450
|
+
const attributable = (target, file, claimed) => {
|
|
6451
|
+
if (target.scope === "layout") return true;
|
|
6452
|
+
const serves = routeOfFile(file);
|
|
6453
|
+
if (serves !== null && serves !== target.route && briefRoutes.has(serves)) return false;
|
|
6454
|
+
if (serves === target.route && pageFilesFor(target.route, contents.keys()).length !== 1) return false;
|
|
6455
|
+
return claimed !== true;
|
|
6456
|
+
};
|
|
6457
|
+
const declaredByHand = (target, within) => {
|
|
6458
|
+
const candidates = within ?? (target.scope === "layout" ? sources.map((s) => s.path) : pageFilesFor(target.route, contents.keys()));
|
|
6459
|
+
for (const file of candidates) {
|
|
6460
|
+
if (!covers(declarations.get(file), target)) continue;
|
|
6461
|
+
if (attributable(target, file, within !== void 0 && claimedByAnother(target, file))) return file;
|
|
6462
|
+
}
|
|
6463
|
+
return null;
|
|
6464
|
+
};
|
|
6040
6465
|
const missed = /* @__PURE__ */ new Set();
|
|
6041
6466
|
for (const miss of unlocated) {
|
|
6042
6467
|
const key = keyOf(miss.route, miss.scope ?? "page", miss.path);
|
|
6043
6468
|
const target = targets.get(key);
|
|
6044
6469
|
if (!target || locatedByKey.has(key) || missed.has(key)) continue;
|
|
6045
6470
|
missed.add(key);
|
|
6046
|
-
|
|
6047
|
-
|
|
6471
|
+
const witness = await witnessed(target);
|
|
6472
|
+
if (witness !== null) {
|
|
6473
|
+
declaredOnly++;
|
|
6474
|
+
declaredRow(target, true, witness);
|
|
6475
|
+
continue;
|
|
6476
|
+
}
|
|
6477
|
+
const byHand = declaredByHand(target);
|
|
6478
|
+
if (byHand !== null) {
|
|
6479
|
+
declaredOnly++;
|
|
6480
|
+
declaredRow(target, false, byHand);
|
|
6481
|
+
continue;
|
|
6482
|
+
}
|
|
6483
|
+
pend(target, miss.reason === "no-original" ? "NO_ORIGINAL" : "NOT_IN_SOURCE");
|
|
6048
6484
|
}
|
|
6049
6485
|
const byFile = /* @__PURE__ */ new Map();
|
|
6050
6486
|
for (const [key, hit] of locatedByKey) {
|
|
@@ -6102,8 +6538,21 @@ async function convertSources(briefIn, sources, options) {
|
|
|
6102
6538
|
if (worst) {
|
|
6103
6539
|
const file = hit.files[outcomes.indexOf(worst)];
|
|
6104
6540
|
pend(target, worst, file);
|
|
6105
|
-
} else if (outcomes.every((o) => o === "declared"))
|
|
6106
|
-
|
|
6541
|
+
} else if (outcomes.every((o) => o === "declared")) {
|
|
6542
|
+
const witness = await witnessed(target);
|
|
6543
|
+
const byHand = witness === null ? declaredByHand(target, hit.files) : null;
|
|
6544
|
+
if (witness === null && byHand === null) {
|
|
6545
|
+
pend(
|
|
6546
|
+
target,
|
|
6547
|
+
"AMBIGUOUS_LITERAL",
|
|
6548
|
+
hit.files[0],
|
|
6549
|
+
`${hit.files.join(", ")} already declares ${target.path}, and nothing there says it is ${target.route}'s.`
|
|
6550
|
+
);
|
|
6551
|
+
continue;
|
|
6552
|
+
}
|
|
6553
|
+
alreadyDeclared++;
|
|
6554
|
+
declaredRow(target, witness !== null, witness ?? byHand);
|
|
6555
|
+
} else rewritten++;
|
|
6107
6556
|
}
|
|
6108
6557
|
for (const [file, splices] of [...componentEdits].sort(([a], [b]) => a.localeCompare(b))) {
|
|
6109
6558
|
const source = new MagicString4(contents.get(file));
|
|
@@ -6129,12 +6578,27 @@ async function convertSources(briefIn, sources, options) {
|
|
|
6129
6578
|
emitStubs2(dialects, snapshotSlugs, contents, outFiles);
|
|
6130
6579
|
const receipt = assertReceipt({
|
|
6131
6580
|
briefDigest: digest,
|
|
6132
|
-
paths: {
|
|
6581
|
+
paths: {
|
|
6582
|
+
declared: targets.size,
|
|
6583
|
+
rewritten,
|
|
6584
|
+
alreadyDeclared,
|
|
6585
|
+
declarations: declaredRows.sort(
|
|
6586
|
+
(a, b) => a.route.localeCompare(b.route) || a.scope.localeCompare(b.scope) || a.path.localeCompare(b.path)
|
|
6587
|
+
),
|
|
6588
|
+
pending
|
|
6589
|
+
},
|
|
6133
6590
|
occurrences: { located: occurrencesLocated, rewritten: occurrencesRewritten },
|
|
6134
6591
|
files: receiptFiles,
|
|
6135
6592
|
helpers,
|
|
6136
6593
|
helperUpgraded,
|
|
6137
|
-
dynamicBindings
|
|
6594
|
+
dynamicBindings,
|
|
6595
|
+
notes: unreadableConfigs(sources).map(
|
|
6596
|
+
(file) => ({
|
|
6597
|
+
code: "TSCONFIG_UNREADABLE",
|
|
6598
|
+
file,
|
|
6599
|
+
message: `${file} is not JSON this package can read, so its \`paths\` aliases resolved to nothing.`
|
|
6600
|
+
})
|
|
6601
|
+
)
|
|
6138
6602
|
});
|
|
6139
6603
|
return { files: outFiles.sort((a, b) => a.path.localeCompare(b.path)), receipt };
|
|
6140
6604
|
}
|
|
@@ -6402,14 +6866,12 @@ async function plan(file, content, dialect, targets, sites, importAt, outcomes,
|
|
|
6402
6866
|
looped.add(member.key);
|
|
6403
6867
|
outcomes.set(member.key, "rewritten");
|
|
6404
6868
|
}
|
|
6405
|
-
for (const
|
|
6869
|
+
for (const declaration2 of plan2.declarations) {
|
|
6406
6870
|
dynamic.push({
|
|
6407
6871
|
file,
|
|
6408
6872
|
prop: null,
|
|
6409
|
-
path:
|
|
6410
|
-
|
|
6411
|
-
// described a binding the file does not contain, which is what the proposer looks for.
|
|
6412
|
-
callSites: [{ file, literal: `${arrayPath}[\${${plan2.names.index}}].${leaf}` }]
|
|
6873
|
+
path: declaration2.path,
|
|
6874
|
+
callSites: [{ file, literal: declaration2.literal }]
|
|
6413
6875
|
});
|
|
6414
6876
|
}
|
|
6415
6877
|
rewrites.push({
|
|
@@ -6695,6 +7157,7 @@ export {
|
|
|
6695
7157
|
rewriteFile,
|
|
6696
7158
|
routeOfFile,
|
|
6697
7159
|
stripTags,
|
|
7160
|
+
unreadableConfigs,
|
|
6698
7161
|
walkAst
|
|
6699
7162
|
};
|
|
6700
7163
|
//# sourceMappingURL=index.js.map
|