@bettercms-ai/convert 0.17.0 → 0.17.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,17 @@
1
1
  # @bettercms-ai/convert
2
2
 
3
+ ## 0.17.2
4
+
5
+ ### Patch Changes
6
+
7
+ - d247026: `--xray` now measures a page exactly as the release pass does. `data-bcms-block` and `data-bcms-path` no longer own the text under them (only `data-bcms-field` and `data-bcms-layout-field` do); `<select>`, `<object>`, `<canvas>` and MathML are skipped; numbers such as `$1,200` and short copy such as `OK` count as copy; only a real in-page skip link is excluded. A page's unaddressable figure may rise: it now matches what the binding report says for the same build.
8
+
9
+ ## 0.17.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 5a2fcc5: An Astro project that already has a live-preview lane no longer gets the `SSR_DRAFT_ROUTE` pending row. A mounted `<BcmsLiveBlocks>` reads as `bridge`, and `output: "server"` plus a mounted `<BcmsLive>` reads as `draft-route`. Before this, every Astro receipt stayed incomplete no matter what was wired.
14
+
3
15
  ## 0.17.0
4
16
 
5
17
  ### Minor Changes
package/dist/cli.js CHANGED
@@ -6080,9 +6080,28 @@ var pend = (reason, hint, file, line) => ({
6080
6080
  hint
6081
6081
  });
6082
6082
  var ASTRO_LANE_PENDING = pend("SSR_DRAFT_ROUTE", SSR_DRAFT_RECIPE);
6083
+ function mounts(content, component) {
6084
+ const from = new RegExp(
6085
+ `import\\s+([A-Za-z_$][\\w$]*)\\s+from\\s+["']@bettercms-ai/astro/components/${component}\\.astro["']`
6086
+ );
6087
+ const local = content.match(from)?.[1];
6088
+ return local !== void 0 && new RegExp(`<${local}[\\s/>]`).test(content);
6089
+ }
6090
+ var ASTRO_CONFIG = /(^|\/)astro\.config\.(mjs|cjs|js|ts|mts)$/;
6091
+ function astroLane(sources) {
6092
+ const astro = sources.filter((s) => s.path.toLowerCase().endsWith(".astro"));
6093
+ const server = sources.some(
6094
+ (s) => ASTRO_CONFIG.test(s.path) && /\boutput\s*:\s*["']server["']/.test(s.content)
6095
+ );
6096
+ if (server && astro.some((s) => mounts(s.content, "BcmsLive"))) return "draft-route";
6097
+ if (astro.some((s) => mounts(s.content, "BcmsLiveBlocks"))) return "bridge";
6098
+ return null;
6099
+ }
6083
6100
  function canvasBridge(sources, routes) {
6084
- if (sources.some((s) => s.path.toLowerCase().endsWith(".astro")))
6085
- return { lane: "pending", files: [], edits: /* @__PURE__ */ new Map(), pending: [ASTRO_LANE_PENDING] };
6101
+ if (sources.some((s) => s.path.toLowerCase().endsWith(".astro"))) {
6102
+ const lane = astroLane(sources);
6103
+ return lane ? { lane, files: [], edits: /* @__PURE__ */ new Map(), pending: [] } : { lane: "pending", files: [], edits: /* @__PURE__ */ new Map(), pending: [ASTRO_LANE_PENDING] };
6104
+ }
6086
6105
  const files = [];
6087
6106
  const edits = /* @__PURE__ */ new Map();
6088
6107
  const pending = [];
@@ -6782,7 +6801,7 @@ function isSourceCandidate(path) {
6782
6801
  }
6783
6802
 
6784
6803
  // src/xray.ts
6785
- var SKIP_TAGS = /* @__PURE__ */ new Set(["svg", "iframe", "head", "title"]);
6804
+ var SKIP_TAGS = /* @__PURE__ */ new Set(["svg", "math", "iframe", "head", "title", "object", "canvas", "select"]);
6786
6805
  var CONTEXT_TAGS = /* @__PURE__ */ new Set([
6787
6806
  "nav",
6788
6807
  "header",
@@ -6800,10 +6819,16 @@ var CONTEXT_TAGS = /* @__PURE__ */ new Set([
6800
6819
  "figure",
6801
6820
  "blockquote"
6802
6821
  ]);
6803
- var BOUND_ATTRS = ["data-bcms-field", "data-bcms-layout-field", "data-bcms-path", "data-bcms-block"];
6804
- var isDecorativeGlyph = (text) => text.length <= 2 || /^\d{1,2}\s*[/.)\-–]?$/.test(text) || !new RegExp("\\p{L}", "u").test(text) || /^made with\b/i.test(text) || /^skip to\b/i.test(text);
6822
+ var BOUND_ATTRS = ["data-bcms-field", "data-bcms-layout-field"];
6823
+ var isDecorativeGlyph = (text) => {
6824
+ const t = flat2(text);
6825
+ return t === "" || !/[\p{L}\p{N}]/u.test(t) || new RegExp("^\\p{Nd}{1,2}\\s*[/.)\\-\u2013\u2014]?$", "u").test(t);
6826
+ };
6827
+ var PLATFORM_BADGE = /^made with\b/iu;
6805
6828
  var MAX_BUCKETS = 12;
6806
6829
  var flat2 = (value) => value.replace(/\s+/g, " ").trim();
6830
+ var textOf = (node) => node.type === "text" ? node.value : node.type === "element" ? node.children.map(textOf).join("") : "";
6831
+ var isSkipLink = (node, attrs) => node.tag === "a" && (attrs.get("href") ?? "").startsWith("#") && (/^skip\b/iu.test(flat2(textOf(node))) || /\bskip[-_]?(link|nav|to|content)\b/iu.test(attrs.get("class") ?? ""));
6807
6832
  function measureUnaddressable(html) {
6808
6833
  const parsed = parse2(html);
6809
6834
  let visible = 0;
@@ -6812,7 +6837,7 @@ function measureUnaddressable(html) {
6812
6837
  const visit = (node, tag, context, bound) => {
6813
6838
  if (node.type === "text") {
6814
6839
  const text = flat2(node.value);
6815
- if (!text || isDecorativeGlyph(text)) return;
6840
+ if (isDecorativeGlyph(text) || PLATFORM_BADGE.test(text)) return;
6816
6841
  visible += text.length;
6817
6842
  if (bound) return;
6818
6843
  unaddressable += text.length;
@@ -6826,7 +6851,7 @@ function measureUnaddressable(html) {
6826
6851
  }
6827
6852
  if (node.type !== "element" || node.raw || SKIP_TAGS.has(node.tag)) return;
6828
6853
  const attrs = new Map(node.attrs.map((a) => [a.name, a.value]));
6829
- if (attrs.has("hidden") || attrs.get("aria-hidden") === "true" || /display\s*:\s*none/.test(attrs.get("style") ?? "")) {
6854
+ if (attrs.has("hidden") || attrs.get("aria-hidden") === "true" || /display\s*:\s*none/i.test(attrs.get("style") ?? "") || isSkipLink(node, attrs)) {
6830
6855
  return;
6831
6856
  }
6832
6857
  const owned = bound || BOUND_ATTRS.some((name) => attrs.has(name));
@@ -6837,7 +6862,7 @@ function measureUnaddressable(html) {
6837
6862
  return {
6838
6863
  visible,
6839
6864
  unaddressable,
6840
- buckets: [...buckets.values()].sort((a, b) => b.chars - a.chars).slice(0, MAX_BUCKETS)
6865
+ buckets: [...buckets.values()].sort((a, b) => b.chars - a.chars || `${a.tag} @ ${a.context}`.localeCompare(`${b.tag} @ ${b.context}`)).slice(0, MAX_BUCKETS)
6841
6866
  };
6842
6867
  }
6843
6868
 
@@ -9782,7 +9807,7 @@ function emitStubs2(dialects, slugs, contents, out) {
9782
9807
  // package.json
9783
9808
  var package_default = {
9784
9809
  name: "@bettercms-ai/convert",
9785
- version: "0.17.0",
9810
+ version: "0.17.2",
9786
9811
  type: "module",
9787
9812
  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.",
9788
9813
  bin: {