@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 +12 -0
- package/dist/cli.js +34 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +33 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -409,7 +409,7 @@ interface ConversionReceipt {
|
|
|
409
409
|
* reader must treat absent as unknown rather than as `"pending"`.
|
|
410
410
|
*/
|
|
411
411
|
canvas?: {
|
|
412
|
-
lane: "bridge" | "pending";
|
|
412
|
+
lane: "bridge" | "draft-route" | "pending";
|
|
413
413
|
files?: string[];
|
|
414
414
|
};
|
|
415
415
|
/**
|
|
@@ -1242,7 +1242,7 @@ interface CanvasSource {
|
|
|
1242
1242
|
ast?: unknown;
|
|
1243
1243
|
}
|
|
1244
1244
|
interface CanvasResult {
|
|
1245
|
-
lane: "bridge" | "pending";
|
|
1245
|
+
lane: "bridge" | "draft-route" | "pending";
|
|
1246
1246
|
/** Files the bridge was installed in. */
|
|
1247
1247
|
files: string[];
|
|
1248
1248
|
/** Rewritten contents, by path. Empty when the lane is pending. */
|
|
@@ -1257,8 +1257,8 @@ declare const ASTRO_LANE_PENDING: PendingPath;
|
|
|
1257
1257
|
* Install the draft bridge, or say why not.
|
|
1258
1258
|
*
|
|
1259
1259
|
* `routes` maps a brief route (`/about`) to its slug, so a route written as a literal in the page
|
|
1260
|
-
* can name itself. An Astro project is
|
|
1261
|
-
*
|
|
1260
|
+
* can name itself. An Astro project is never bridged here: it either wired a lane itself (see
|
|
1261
|
+
* {@link astroLane}) or it carries the SSR recipe.
|
|
1262
1262
|
*/
|
|
1263
1263
|
declare function canvasBridge(sources: CanvasSource[], routes: Map<string, string>): CanvasResult;
|
|
1264
1264
|
|
|
@@ -1293,10 +1293,11 @@ declare function isSourceCandidate(path: string): boolean;
|
|
|
1293
1293
|
* could lift — and the target is a number someone has to be able to reach. They are not copy an
|
|
1294
1294
|
* author edits, so they are not copy this measures.
|
|
1295
1295
|
*
|
|
1296
|
-
* - a decorative glyph:
|
|
1297
|
-
*
|
|
1296
|
+
* - a decorative glyph: no letter and no digit (`✓`, `→`), or an ordinal (`01`, `2.`, `3 /`)
|
|
1297
|
+
* that numbers a list rather than saying anything. Length decides nothing: `OK` and `$1,200`
|
|
1298
|
+
* are copy. The server's `extract-fields.ts` isDecorativeGlyph, verbatim;
|
|
1298
1299
|
* - the platform badge every free site renders;
|
|
1299
|
-
* - a skip link, which exists for keyboards and is never edited.
|
|
1300
|
+
* - a skip link, which exists for keyboards and is never edited. @see isSkipLink
|
|
1300
1301
|
*/
|
|
1301
1302
|
declare const isDecorativeGlyph: (text: string) => boolean;
|
|
1302
1303
|
interface XrayBucket {
|
package/dist/index.js
CHANGED
|
@@ -6090,9 +6090,28 @@ var pend = (reason, hint, file, line) => ({
|
|
|
6090
6090
|
hint
|
|
6091
6091
|
});
|
|
6092
6092
|
var ASTRO_LANE_PENDING = pend("SSR_DRAFT_ROUTE", SSR_DRAFT_RECIPE);
|
|
6093
|
+
function mounts(content, component) {
|
|
6094
|
+
const from = new RegExp(
|
|
6095
|
+
`import\\s+([A-Za-z_$][\\w$]*)\\s+from\\s+["']@bettercms-ai/astro/components/${component}\\.astro["']`
|
|
6096
|
+
);
|
|
6097
|
+
const local = content.match(from)?.[1];
|
|
6098
|
+
return local !== void 0 && new RegExp(`<${local}[\\s/>]`).test(content);
|
|
6099
|
+
}
|
|
6100
|
+
var ASTRO_CONFIG = /(^|\/)astro\.config\.(mjs|cjs|js|ts|mts)$/;
|
|
6101
|
+
function astroLane(sources) {
|
|
6102
|
+
const astro = sources.filter((s) => s.path.toLowerCase().endsWith(".astro"));
|
|
6103
|
+
const server = sources.some(
|
|
6104
|
+
(s) => ASTRO_CONFIG.test(s.path) && /\boutput\s*:\s*["']server["']/.test(s.content)
|
|
6105
|
+
);
|
|
6106
|
+
if (server && astro.some((s) => mounts(s.content, "BcmsLive"))) return "draft-route";
|
|
6107
|
+
if (astro.some((s) => mounts(s.content, "BcmsLiveBlocks"))) return "bridge";
|
|
6108
|
+
return null;
|
|
6109
|
+
}
|
|
6093
6110
|
function canvasBridge(sources, routes) {
|
|
6094
|
-
if (sources.some((s) => s.path.toLowerCase().endsWith(".astro")))
|
|
6095
|
-
|
|
6111
|
+
if (sources.some((s) => s.path.toLowerCase().endsWith(".astro"))) {
|
|
6112
|
+
const lane = astroLane(sources);
|
|
6113
|
+
return lane ? { lane, files: [], edits: /* @__PURE__ */ new Map(), pending: [] } : { lane: "pending", files: [], edits: /* @__PURE__ */ new Map(), pending: [ASTRO_LANE_PENDING] };
|
|
6114
|
+
}
|
|
6096
6115
|
const files = [];
|
|
6097
6116
|
const edits = /* @__PURE__ */ new Map();
|
|
6098
6117
|
const pending = [];
|
|
@@ -6792,7 +6811,7 @@ function isSourceCandidate(path) {
|
|
|
6792
6811
|
}
|
|
6793
6812
|
|
|
6794
6813
|
// src/xray.ts
|
|
6795
|
-
var SKIP_TAGS = /* @__PURE__ */ new Set(["svg", "iframe", "head", "title"]);
|
|
6814
|
+
var SKIP_TAGS = /* @__PURE__ */ new Set(["svg", "math", "iframe", "head", "title", "object", "canvas", "select"]);
|
|
6796
6815
|
var CONTEXT_TAGS = /* @__PURE__ */ new Set([
|
|
6797
6816
|
"nav",
|
|
6798
6817
|
"header",
|
|
@@ -6810,10 +6829,16 @@ var CONTEXT_TAGS = /* @__PURE__ */ new Set([
|
|
|
6810
6829
|
"figure",
|
|
6811
6830
|
"blockquote"
|
|
6812
6831
|
]);
|
|
6813
|
-
var BOUND_ATTRS = ["data-bcms-field", "data-bcms-layout-field"
|
|
6814
|
-
var isDecorativeGlyph = (text) =>
|
|
6832
|
+
var BOUND_ATTRS = ["data-bcms-field", "data-bcms-layout-field"];
|
|
6833
|
+
var isDecorativeGlyph = (text) => {
|
|
6834
|
+
const t = flat2(text);
|
|
6835
|
+
return t === "" || !/[\p{L}\p{N}]/u.test(t) || new RegExp("^\\p{Nd}{1,2}\\s*[/.)\\-\u2013\u2014]?$", "u").test(t);
|
|
6836
|
+
};
|
|
6837
|
+
var PLATFORM_BADGE = /^made with\b/iu;
|
|
6815
6838
|
var MAX_BUCKETS = 12;
|
|
6816
6839
|
var flat2 = (value) => value.replace(/\s+/g, " ").trim();
|
|
6840
|
+
var textOf = (node) => node.type === "text" ? node.value : node.type === "element" ? node.children.map(textOf).join("") : "";
|
|
6841
|
+
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") ?? ""));
|
|
6817
6842
|
function measureUnaddressable(html) {
|
|
6818
6843
|
const parsed = parse2(html);
|
|
6819
6844
|
let visible = 0;
|
|
@@ -6822,7 +6847,7 @@ function measureUnaddressable(html) {
|
|
|
6822
6847
|
const visit = (node, tag, context, bound) => {
|
|
6823
6848
|
if (node.type === "text") {
|
|
6824
6849
|
const text = flat2(node.value);
|
|
6825
|
-
if (
|
|
6850
|
+
if (isDecorativeGlyph(text) || PLATFORM_BADGE.test(text)) return;
|
|
6826
6851
|
visible += text.length;
|
|
6827
6852
|
if (bound) return;
|
|
6828
6853
|
unaddressable += text.length;
|
|
@@ -6836,7 +6861,7 @@ function measureUnaddressable(html) {
|
|
|
6836
6861
|
}
|
|
6837
6862
|
if (node.type !== "element" || node.raw || SKIP_TAGS.has(node.tag)) return;
|
|
6838
6863
|
const attrs = new Map(node.attrs.map((a) => [a.name, a.value]));
|
|
6839
|
-
if (attrs.has("hidden") || attrs.get("aria-hidden") === "true" || /display\s*:\s*none
|
|
6864
|
+
if (attrs.has("hidden") || attrs.get("aria-hidden") === "true" || /display\s*:\s*none/i.test(attrs.get("style") ?? "") || isSkipLink(node, attrs)) {
|
|
6840
6865
|
return;
|
|
6841
6866
|
}
|
|
6842
6867
|
const owned = bound || BOUND_ATTRS.some((name) => attrs.has(name));
|
|
@@ -6847,7 +6872,7 @@ function measureUnaddressable(html) {
|
|
|
6847
6872
|
return {
|
|
6848
6873
|
visible,
|
|
6849
6874
|
unaddressable,
|
|
6850
|
-
buckets: [...buckets.values()].sort((a, b) => b.chars - a.chars).slice(0, MAX_BUCKETS)
|
|
6875
|
+
buckets: [...buckets.values()].sort((a, b) => b.chars - a.chars || `${a.tag} @ ${a.context}`.localeCompare(`${b.tag} @ ${b.context}`)).slice(0, MAX_BUCKETS)
|
|
6851
6876
|
};
|
|
6852
6877
|
}
|
|
6853
6878
|
|