@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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @bettercms-ai/convert
2
2
 
3
+ ## 0.18.2
4
+
5
+ ### Patch Changes
6
+
7
+ - b201770: Rebuild before publishing. 1.22.1 / 0.18.1 shipped a stale dist/ that predated their own changes; this release carries the built fixes.
8
+
3
9
  ## 0.18.1
4
10
 
5
11
  ### Patch Changes
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
- return { file, dialect, el: form, controls, wrapper, foreign, landmark };
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 covers2 = (c, f) => f.fields.length > 0 && holds(c, f) === f.fields.length;
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 isAboutTheSite = (lower) => /\.(test|spec)\.[^./]+$/.test(lower) || /^[^/]*\.config\.[^./]+$/.test(lower);
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 owned = bound || BOUND_ATTRS.some((name) => attrs.has(name));
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.0",
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",