@bettercms-ai/convert 0.18.1 → 0.18.2
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 +6 -0
- package/dist/cli.js +39 -15
- package/dist/cli.js.map +1 -1
- package/dist/index.js +36 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -6489,7 +6489,7 @@ function* formsIn(nodes, chain = []) {
|
|
|
6489
6489
|
}
|
|
6490
6490
|
}
|
|
6491
6491
|
var isComponentTag = (dialect, tag) => dialect !== "html" && /^[A-Z]/.test(tag);
|
|
6492
|
-
function candidateOf(file, dialect, form, imported, landmark) {
|
|
6492
|
+
function candidateOf(file, dialect, form, imported, landmark, content) {
|
|
6493
6493
|
const controls = /* @__PURE__ */ new Map();
|
|
6494
6494
|
const wrapper = /* @__PURE__ */ new Map();
|
|
6495
6495
|
const foreign = /* @__PURE__ */ new Set();
|
|
@@ -6526,7 +6526,11 @@ function candidateOf(file, dialect, form, imported, landmark) {
|
|
|
6526
6526
|
const id = attrOf(control, "id")?.value;
|
|
6527
6527
|
if (id && !controls.has(id)) controls.set(id, control);
|
|
6528
6528
|
}
|
|
6529
|
-
|
|
6529
|
+
const computed = (attr) => !!attr?.expression && !!attr.expressionRange && /[A-Za-z_$]/.test(
|
|
6530
|
+
content.slice(attr.expressionRange.start, attr.expressionRange.end).replace(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'|`(?:[^`\\$]|\\.|\$(?!\{))*`/g, "")
|
|
6531
|
+
);
|
|
6532
|
+
const dynamic = all.some((control) => !foreign.has(control) && computed(attrOf(control, "name")));
|
|
6533
|
+
return { file, dialect, el: form, controls, wrapper, foreign, landmark, dynamic };
|
|
6530
6534
|
}
|
|
6531
6535
|
async function importedControls(source, parsed, dialect, project, cache) {
|
|
6532
6536
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -6620,11 +6624,12 @@ async function wireForms(briefIn, sources, options_ = {}) {
|
|
|
6620
6624
|
}
|
|
6621
6625
|
const imported = dialect === "html" ? /* @__PURE__ */ new Map() : await importedControls(source, parsed, dialect, project, componentFiles);
|
|
6622
6626
|
for (const { el, landmark } of formsIn(parsed.roots)) {
|
|
6623
|
-
candidates.push(candidateOf(source.path, dialect, el, imported, landmark));
|
|
6627
|
+
candidates.push(candidateOf(source.path, dialect, el, imported, landmark, source.content));
|
|
6624
6628
|
}
|
|
6625
6629
|
}
|
|
6626
6630
|
const holds = (c, f) => f.fields.filter((field) => c.controls.has(field.key)).length;
|
|
6627
|
-
const
|
|
6631
|
+
const wiredTo = (c, f) => attrOf(c.el, "data-bcms-form")?.value === f.id;
|
|
6632
|
+
const covers2 = (c, f) => c.dynamic && wiredTo(c, f) || f.fields.length > 0 && holds(c, f) === f.fields.length;
|
|
6628
6633
|
const samePath = (a, b) => a.replace(/\\/g, "/").replace(/^\.\//, "") === b.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
6629
6634
|
const options = new Map(forms.map((f) => [f.id, candidates.filter((c) => covers2(c, f))]));
|
|
6630
6635
|
const pinned = /* @__PURE__ */ new Map();
|
|
@@ -6707,6 +6712,11 @@ async function wireForms(briefIn, sources, options_ = {}) {
|
|
|
6707
6712
|
continue;
|
|
6708
6713
|
}
|
|
6709
6714
|
const candidate = list[0];
|
|
6715
|
+
if (wiredTo(candidate, form)) {
|
|
6716
|
+
alreadyWired++;
|
|
6717
|
+
onSite.push({ form, file: candidate.file });
|
|
6718
|
+
continue;
|
|
6719
|
+
}
|
|
6710
6720
|
if (attrOf(candidate.el, "action")?.expression) {
|
|
6711
6721
|
pend2(form, "ACTION_IS_EXPRESSION", candidate.file, "its action is an expression, so this run will not replace it.");
|
|
6712
6722
|
continue;
|
|
@@ -6719,11 +6729,6 @@ async function wireForms(briefIn, sources, options_ = {}) {
|
|
|
6719
6729
|
pend2(form, "FIELD_UNMATCHED", candidate.file, `the control for ${misnamed.key} posts under an expression, so its name cannot be set to the CMS key.`);
|
|
6720
6730
|
continue;
|
|
6721
6731
|
}
|
|
6722
|
-
if (attrOf(candidate.el, "data-bcms-form")?.value === form.id) {
|
|
6723
|
-
alreadyWired++;
|
|
6724
|
-
onSite.push({ form, file: candidate.file });
|
|
6725
|
-
continue;
|
|
6726
|
-
}
|
|
6727
6732
|
matched.push({ form, candidate });
|
|
6728
6733
|
onSite.push({ form, file: candidate.file });
|
|
6729
6734
|
}
|
|
@@ -6844,7 +6849,8 @@ var TEMPLATE_DIRS = /* @__PURE__ */ new Set([
|
|
|
6844
6849
|
"_includes",
|
|
6845
6850
|
"_layouts"
|
|
6846
6851
|
]);
|
|
6847
|
-
var
|
|
6852
|
+
var READ_CONFIG = /^astro\.config\.[^./]+$/;
|
|
6853
|
+
var isAboutTheSite = (lower) => /\.(test|spec)\.[^./]+$/.test(lower) || /^[^/]*\.config\.[^./]+$/.test(lower) && !READ_CONFIG.test(lower);
|
|
6848
6854
|
function isSourceCandidate(path) {
|
|
6849
6855
|
const lower = path.toLowerCase();
|
|
6850
6856
|
if (SKIP_DIRS.some((dir) => lower === dir.slice(0, -1) || lower.startsWith(dir) || lower.includes(`/${dir}`)))
|
|
@@ -6891,7 +6897,7 @@ function measureUnaddressable(html) {
|
|
|
6891
6897
|
let visible = 0;
|
|
6892
6898
|
let unaddressable = 0;
|
|
6893
6899
|
const buckets = /* @__PURE__ */ new Map();
|
|
6894
|
-
const visit = (node, tag, context, bound) => {
|
|
6900
|
+
const visit = (node, tag, context, bound, inForm = false) => {
|
|
6895
6901
|
if (node.type === "text") {
|
|
6896
6902
|
const text = flat2(node.value);
|
|
6897
6903
|
if (isDecorativeGlyph(text) || PLATFORM_BADGE.test(text)) return;
|
|
@@ -6911,9 +6917,10 @@ function measureUnaddressable(html) {
|
|
|
6911
6917
|
if (attrs.has("hidden") || attrs.get("aria-hidden") === "true" || /display\s*:\s*none/i.test(attrs.get("style") ?? "") || isSkipLink(node, attrs)) {
|
|
6912
6918
|
return;
|
|
6913
6919
|
}
|
|
6914
|
-
const
|
|
6920
|
+
const form = inForm || attrs.has("data-bcms-form");
|
|
6921
|
+
const owned = bound || BOUND_ATTRS.some((name) => attrs.has(name)) || form && attrs.has("data-bcms-form-part");
|
|
6915
6922
|
const chain = CONTEXT_TAGS.has(node.tag) ? context === "body" ? node.tag : `${context}>${node.tag}` : context;
|
|
6916
|
-
for (const child of node.children) visit(child, node.tag, chain, owned);
|
|
6923
|
+
for (const child of node.children) visit(child, node.tag, chain, owned, form);
|
|
6917
6924
|
};
|
|
6918
6925
|
for (const root of parsed.roots) visit(root, "body", "body", false);
|
|
6919
6926
|
return {
|
|
@@ -9403,7 +9410,23 @@ async function plan(file, content, dialect, targets, sites, importAt, outcomes,
|
|
|
9403
9410
|
continue;
|
|
9404
9411
|
}
|
|
9405
9412
|
const resolved = sharing.length === 1 ? { assigned: /* @__PURE__ */ new Map([[sharing[0].key, forLiteral]]), ambiguous: /* @__PURE__ */ new Set() } : resolvePositionally(sharing, forLiteral);
|
|
9413
|
+
const exactly = new Map(
|
|
9414
|
+
sharing.length > 1 ? sharing.flatMap((target) => {
|
|
9415
|
+
const own = forLiteral.filter(
|
|
9416
|
+
(site) => site.where === "text" && !site.partial && !site.mixed && isIntrinsic(site.tag) && declarations.some((d) => d.scope === target.scope && d.path === target.path && d.at === site.attrInsertAt)
|
|
9417
|
+
);
|
|
9418
|
+
return own.length > 0 ? [[target.key, own]] : [];
|
|
9419
|
+
}) : []
|
|
9420
|
+
);
|
|
9421
|
+
const unmarked = forLiteral.filter((site) => ![...exactly.values()].some((own) => own.includes(site)));
|
|
9422
|
+
const settled = unmarked.length <= sharing.length - exactly.size ? exactly : /* @__PURE__ */ new Map();
|
|
9406
9423
|
for (const target of sharing) {
|
|
9424
|
+
const own = settled.get(target.key);
|
|
9425
|
+
if (own) {
|
|
9426
|
+
outcomes.set(target.key, "declared");
|
|
9427
|
+
located += own.length;
|
|
9428
|
+
continue;
|
|
9429
|
+
}
|
|
9407
9430
|
if (resolved.ambiguous.has(target.key)) {
|
|
9408
9431
|
outcomes.set(target.key, "AMBIGUOUS_LITERAL");
|
|
9409
9432
|
continue;
|
|
@@ -9929,7 +9952,7 @@ function styleEdits(before, after) {
|
|
|
9929
9952
|
// package.json
|
|
9930
9953
|
var package_default = {
|
|
9931
9954
|
name: "@bettercms-ai/convert",
|
|
9932
|
-
version: "0.18.
|
|
9955
|
+
version: "0.18.2",
|
|
9933
9956
|
type: "module",
|
|
9934
9957
|
description: "Deterministic codemod that turns an imported site's text-matched bindings into declared ones \u2014 parser offsets in, one magic-string pass out, plus a receipt of everything it could not do.",
|
|
9935
9958
|
bin: {
|
|
@@ -9956,7 +9979,8 @@ var package_default = {
|
|
|
9956
9979
|
build: "tsup",
|
|
9957
9980
|
test: "vitest run",
|
|
9958
9981
|
"test:watch": "vitest",
|
|
9959
|
-
briefs: "bun --conditions=development scripts/build-briefs.ts"
|
|
9982
|
+
briefs: "bun --conditions=development scripts/build-briefs.ts",
|
|
9983
|
+
prepublishOnly: "bun run build"
|
|
9960
9984
|
},
|
|
9961
9985
|
dependencies: {
|
|
9962
9986
|
"@astrojs/compiler": "^2.13.1",
|