@bettercms-ai/convert 0.13.0 → 0.14.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 +9 -0
- package/dist/cli.js +36 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +20 -4
- package/dist/index.js +35 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -33,9 +33,12 @@ interface BriefPath {
|
|
|
33
33
|
* what it said.
|
|
34
34
|
*/
|
|
35
35
|
scope?: "page" | "layout";
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
/**
|
|
37
|
+
* `data-bcms-kind`, as `kindOf` spells it: text | richtext | image | document. The props-lane
|
|
38
|
+
* members of the union (url, number, array) never appear on a brief path.
|
|
39
|
+
*/
|
|
40
|
+
kind: BindingKind;
|
|
41
|
+
/** The declared field type. It agrees with `kind` now; the injector reads it for LINK_TYPES. */
|
|
39
42
|
type: string;
|
|
40
43
|
/**
|
|
41
44
|
* The richtext value IS the element's whole inline subtree — the field's `config.inline`.
|
|
@@ -229,6 +232,12 @@ interface PendingFix {
|
|
|
229
232
|
/** The bytes at `line`, trimmed — so the agent can see it is looking at the right place. */
|
|
230
233
|
snippet: string;
|
|
231
234
|
action: FixAction;
|
|
235
|
+
/**
|
|
236
|
+
* `declare-richtext` only: WHICH container this is. A `document` is a whole Body — one element
|
|
237
|
+
* holds every block — and binding a paragraph of it instead publishes the entire article into
|
|
238
|
+
* that paragraph. The two are different instructions, not one with a longer value.
|
|
239
|
+
*/
|
|
240
|
+
kind?: "richtext" | "document";
|
|
232
241
|
/** One sentence, present whenever the action alone does not say enough. */
|
|
233
242
|
why?: string;
|
|
234
243
|
}
|
|
@@ -287,7 +296,14 @@ declare function routeCounts(pending: readonly PendingPath[]): Map<string, numbe
|
|
|
287
296
|
* is only `rewritten` when EVERY located occurrence of it was.
|
|
288
297
|
*/
|
|
289
298
|
|
|
290
|
-
type PendingReason =
|
|
299
|
+
type PendingReason =
|
|
300
|
+
/**
|
|
301
|
+
* A Body the codemod refuses to touch, and the only pending reason that is a DECISION rather
|
|
302
|
+
* than a failure. Its value is a whole Portable Text array and its `original` is only the first
|
|
303
|
+
* block's text, so locating it lands on one paragraph — and publish then writes the entire
|
|
304
|
+
* article into that paragraph, or refuses it outright. The fix names the wrapper to declare.
|
|
305
|
+
*/
|
|
306
|
+
"DOCUMENT_DECLARE_ONLY" | "NO_ORIGINAL" | "NOT_IN_SOURCE" | "DIALECT_UNSUPPORTED" | "IN_EXPRESSION" | "IN_SCRIPT_OR_COMMENT" | "IN_DATA_FILE" | "AMBIGUOUS_LITERAL" | "KIND_MISMATCH" | "SUBSTRING_ONLY"
|
|
291
307
|
/** An INLINE richtext value whose element holds a component, a `<slot>` or an expression. */
|
|
292
308
|
| "SUBTREE_NOT_HTML" | "PROP_TARGET_NOT_FOUND" | "PROP_DRILLED_DEEP" | "REPEATER_FIXED_LENGTH"
|
|
293
309
|
/** One array declaration, two loops over it: the row this leaf belongs to has two homes. */
|
package/dist/index.js
CHANGED
|
@@ -2560,7 +2560,11 @@ var IMAGE_SOURCES = {
|
|
|
2560
2560
|
video: ["poster"]
|
|
2561
2561
|
};
|
|
2562
2562
|
var isImageSource = (site) => site.where === "attr" && (IMAGE_SOURCES[site.tag.toLowerCase()] ?? []).includes(site.attr ?? "");
|
|
2563
|
-
var ownsSubtree = (kind, site, inline) =>
|
|
2563
|
+
var ownsSubtree = (kind, site, inline) => (
|
|
2564
|
+
// A `document` is the same claim at article scale: the element renders EVERY block of the Body,
|
|
2565
|
+
// so its children come from the stored value and nothing else may be bound inside it.
|
|
2566
|
+
(kind === "richtext" || kind === "document") && (inline === true ? !site.nonHtml : !(site.mixed && site.textRange !== null))
|
|
2567
|
+
);
|
|
2564
2568
|
var norm = (value) => decodeEntities(value.normalize("NFC")).replace(/\s+/g, " ").trim();
|
|
2565
2569
|
var BCMS_ATTRS = [
|
|
2566
2570
|
"data-bcms-field",
|
|
@@ -5369,7 +5373,7 @@ function actionFor(reason, input, file, inData) {
|
|
|
5369
5373
|
return chosen;
|
|
5370
5374
|
}
|
|
5371
5375
|
function reasonAction(reason, input, file, inData) {
|
|
5372
|
-
const richtext = input.kind === "richtext" || input.inline === true;
|
|
5376
|
+
const richtext = input.kind === "richtext" || input.kind === "document" || input.inline === true;
|
|
5373
5377
|
switch (reason) {
|
|
5374
5378
|
case "AMBIGUOUS_LITERAL":
|
|
5375
5379
|
if (input.routes > 1) {
|
|
@@ -5420,6 +5424,11 @@ function reasonAction(reason, input, file, inData) {
|
|
|
5420
5424
|
return { action: "wrap-span", why: "Only part of the element's text is this value \u2014 give it its own span." };
|
|
5421
5425
|
case "SUBTREE_NOT_HTML":
|
|
5422
5426
|
return { action: "declare-richtext", why: "The value is the element's whole subtree \u2014 bind it as richtext." };
|
|
5427
|
+
case "DOCUMENT_DECLARE_ONLY":
|
|
5428
|
+
return {
|
|
5429
|
+
action: "declare-richtext",
|
|
5430
|
+
why: 'This is a Body: bind the ONE element that renders every block of it \u2014 an article, a main or a div \u2014 with the richtext helper and data-bcms-kind="document". Never the paragraph holding its first block: that is where the whole article would be published.'
|
|
5431
|
+
};
|
|
5423
5432
|
default:
|
|
5424
5433
|
return { action: "manual", why: `${reason} \u2014 see the receipt's message for what blocked this path.` };
|
|
5425
5434
|
}
|
|
@@ -5436,7 +5445,10 @@ function fixFor(row, input) {
|
|
|
5436
5445
|
...place.col !== void 0 ? { col: place.col } : {},
|
|
5437
5446
|
snippet: place.snippet,
|
|
5438
5447
|
action,
|
|
5439
|
-
...why ? { why } : {}
|
|
5448
|
+
...why ? { why } : {},
|
|
5449
|
+
// Only `declare-richtext` carries it, and only to say WHICH container is meant: one element
|
|
5450
|
+
// for a rich-text value, the whole Body's wrapper for a document.
|
|
5451
|
+
...action === "declare-richtext" && (input.kind === "document" || input.kind === "richtext") ? { kind: input.kind } : {}
|
|
5440
5452
|
};
|
|
5441
5453
|
}
|
|
5442
5454
|
function routeCounts(pending) {
|
|
@@ -8789,10 +8801,28 @@ async function convertSources(briefIn, sources, options) {
|
|
|
8789
8801
|
}
|
|
8790
8802
|
pend2(target, miss.reason === "no-original" ? "NO_ORIGINAL" : "NOT_IN_SOURCE");
|
|
8791
8803
|
}
|
|
8804
|
+
const documents = /* @__PURE__ */ new Set();
|
|
8805
|
+
for (const [key, hit] of locatedByKey) {
|
|
8806
|
+
const target = targets.get(key);
|
|
8807
|
+
if (!target || target.kind !== "document") continue;
|
|
8808
|
+
documents.add(key);
|
|
8809
|
+
const byHand = declaredByHand(target, hit.files);
|
|
8810
|
+
if (byHand !== null) {
|
|
8811
|
+
declaredOnly++;
|
|
8812
|
+
declaredRow(target, false, byHand);
|
|
8813
|
+
continue;
|
|
8814
|
+
}
|
|
8815
|
+
pend2(
|
|
8816
|
+
target,
|
|
8817
|
+
"DOCUMENT_DECLARE_ONLY",
|
|
8818
|
+
hit.files[0],
|
|
8819
|
+
"A Body is bound by declaring the one element that renders every block of it, never the paragraph that happens to hold its first block."
|
|
8820
|
+
);
|
|
8821
|
+
}
|
|
8792
8822
|
const byFile = /* @__PURE__ */ new Map();
|
|
8793
8823
|
for (const [key, hit] of locatedByKey) {
|
|
8794
8824
|
const target = targets.get(key);
|
|
8795
|
-
if (!target) continue;
|
|
8825
|
+
if (!target || documents.has(key)) continue;
|
|
8796
8826
|
for (const file of hit.files) byFile.set(file, [...byFile.get(file) ?? [], target]);
|
|
8797
8827
|
}
|
|
8798
8828
|
const drill = {
|
|
@@ -8841,6 +8871,7 @@ async function convertSources(briefIn, sources, options) {
|
|
|
8841
8871
|
let rewritten = 0;
|
|
8842
8872
|
let alreadyDeclared = declaredOnly;
|
|
8843
8873
|
for (const [key, hit] of locatedByKey) {
|
|
8874
|
+
if (documents.has(key)) continue;
|
|
8844
8875
|
const target = targets.get(key);
|
|
8845
8876
|
const outcomes = hit.files.map((file) => results.get(file)?.get(target.key) ?? "NOT_IN_SOURCE");
|
|
8846
8877
|
const worst = outcomes.find((o) => o !== "rewritten" && o !== "declared");
|