@bettercms-ai/convert 0.5.0 β 0.7.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 +18 -4
- package/README.md +59 -4
- package/dist/cli.js +1383 -784
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +181 -3
- package/dist/index.js +1391 -788
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @bettercms-ai/convert
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e8b5b1c: Convert the shapes real template sites are made of: data literals rendered through `.map`, headings whose copy is one text node of a mixed element, and images imported from `src/assets`. Root-level `.md` files are no longer read as templates, and a located-but-unplaced path now carries a reason that is true (`IN_EXPRESSION`, or `NOT_IN_SOURCE` with the file named).
|
|
8
|
+
|
|
9
|
+
New helper exports `bcmsRowsAs` and `bcmsImage` (helper v5), and two new pending reasons: `REPEATER_AMBIGUOUS` and `IMAGE_ASSET_UNRESOLVED`.
|
|
10
|
+
|
|
11
|
+
## 0.6.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 5ad31fd: Astro SSR draft recipe now names `@astrojs/node` standalone, the auto-injected draft routes, and `loadPage` + `loadComponents`.
|
|
16
|
+
|
|
3
17
|
## 0.5.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -97,7 +111,7 @@ reject the checkout, which is what broke the migrator image on #616.
|
|
|
97
111
|
has; a `bcmsField` the file demonstrably builds from our helper is left alone and only its
|
|
98
112
|
bindings are wrapped; anything else is `SECTION_UNMIGRATABLE`.
|
|
99
113
|
|
|
100
|
-
π΄ A NAME IS NOT A PROVENANCE. Reusing anything
|
|
114
|
+
π΄ A NAME IS NOT A PROVENANCE. Reusing anything _called_ `bcmsFields` trusted an import from
|
|
101
115
|
any module at all β `import { bcmsFields } from "./their-utils"` is a different function with
|
|
102
116
|
the same name β and any coexisting `bcmsField` vouched for itself. The specifier must RESOLVE
|
|
103
117
|
to the helper module this package writes (through the project's own aliases), and `bcmsField`
|
|
@@ -203,7 +217,7 @@ reject the checkout, which is what broke the migrator image on #616.
|
|
|
203
217
|
catch, reached through the check itself. Two shapes are provable: a string literal and NOTHING
|
|
204
218
|
else, and a template literal whose every interpolation is an INDEX (`[${i}]`, what a repeater
|
|
205
219
|
writes, which cannot change the prefix). Everything else β `{computedPath}`, `{"a" + x}`,
|
|
206
|
-
``
|
|
220
|
+
``{`${prefix}.title`}`` β is opaque, and opaque is `PROP_MAP_INCONSISTENT`.
|
|
207
221
|
|
|
208
222
|
- `COPY_MODE_MISMATCH` ignores sections the SERVER already refused.
|
|
209
223
|
|
|
@@ -224,7 +238,7 @@ reject the checkout, which is what broke the migrator image on #616.
|
|
|
224
238
|
|
|
225
239
|
The in-place call site β `<Hero bind="hero" page={pageSnapshot("home")} />` β is written by
|
|
226
240
|
the codemod from the plan and carries no `blockId` and no `overrides`; it never consults the
|
|
227
|
-
CMS's blocks at all, which is exactly what makes the inline form componentisation
|
|
241
|
+
CMS's blocks at all, which is exactly what makes the inline form componentisation _without_
|
|
228
242
|
the page builder. Emitting it for a placement whose copy has MOVED rendered the page's field
|
|
229
243
|
group and declared the page lane for an address that no longer holds anything. The component
|
|
230
244
|
is still written; the page is left as its author wrote it.
|
|
@@ -294,7 +308,7 @@ reject the checkout, which is what broke the migrator image on #616.
|
|
|
294
308
|
the dashboard renders. The committed helper needed nothing: `bcmsRows` already passes a
|
|
295
309
|
nested array through untouched and `bcmsSection` hands a section its group whole.
|
|
296
310
|
|
|
297
|
-
The bindings are ``
|
|
311
|
+
The bindings are ``data-bcms-field={`cards[${i}].items[${j}].label`}`` and the shape is
|
|
298
312
|
`cards[*].items[*].label`; the loop now REPORTS the bindings it wrote, both loop variables
|
|
299
313
|
included, instead of the caller re-deriving a literal the file does not contain. ONE level
|
|
300
314
|
of nesting β what the plan mints and what the component prop validator accepts β so a leaf
|
package/README.md
CHANGED
|
@@ -58,10 +58,52 @@ tolerant pass that will only place a literal occurring exactly once between a `>
|
|
|
58
58
|
that, an injected `llmFallback` whose output is accepted only if it re-parses and declares exactly
|
|
59
59
|
the paths that were asked for. The CLI injects none β the agent running it is tier 3.
|
|
60
60
|
|
|
61
|
-
**
|
|
62
|
-
|
|
63
|
-
`
|
|
64
|
-
|
|
61
|
+
**A prose file is a template only where a framework renders one.** `.md`, `.mdx`, `.njk`, `.hbs`,
|
|
62
|
+
`.ejs`, `.liquid`, `.erb` and `.twig` are opened under a directory named `pages`, `content`, `src`,
|
|
63
|
+
`app`, `routes`, `layouts`, `components`, `templates`, `views`, `_includes` or `_layouts` β and
|
|
64
|
+
never at the repository root or under `docs/`. A README quoting the hero line is documentation
|
|
65
|
+
ABOUT the site, and because a path counts as rewritten only when every located occurrence was, one
|
|
66
|
+
of them pended 176 of 735 paths on a real repository with a reason naming a file nobody would ever
|
|
67
|
+
want bound.
|
|
68
|
+
|
|
69
|
+
**A scalar module literal is converted too.** `const tagline = "β¦"` rendered as `{tagline}` becomes
|
|
70
|
+
`const tagline = bcms(page, "<path>", "β¦")`, with the declaration on the element that renders it β
|
|
71
|
+
a literal path, because there is no index to template. Refused as `IN_EXPRESSION` when the
|
|
72
|
+
identifier is rendered more than once, used in an attribute as well, or transformed on the way:
|
|
73
|
+
moving the declaration to a CMS read changes the value everywhere that identifier is used.
|
|
74
|
+
|
|
75
|
+
**Copy that lives in a data literal is converted too.** `deriveSchema` reads the BUILT page, so
|
|
76
|
+
four cards arrive as `cards[0..3]`; the repository renders ONE element from a frontmatter (astro)
|
|
77
|
+
or module-scope (jsx/tsx) array through `.map`. The declaration becomes
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
const features = bcmsRowsAs(bcmsHome, "cards", [ β¦the original array, verbatimβ¦ ],
|
|
81
|
+
{ title: "h3-field", body: "p-field" });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
β the rows come from the CMS and are renamed onto the template's OWN property names, so
|
|
85
|
+
`feature.tone`, `feature.link` and every other property the brief never heard of keep rendering
|
|
86
|
+
(`bcmsRowsAs` merges each CMS row over the row the template shipped with, and a row an editor adds
|
|
87
|
+
inherits row 0's styling). Each row element then declares
|
|
88
|
+
`` data-bcms-field={`cards[${i}].<leaf>`} ``, and the callback gains an index parameter if it had
|
|
89
|
+
none. An imported data module stays `IN_DATA_FILE`.
|
|
90
|
+
|
|
91
|
+
**An image is bound through its import, not through its url.** An image's `original` is the name
|
|
92
|
+
the bundler minted (`/_astro/hero.do77EGgx_ZNfVA8.jpg`) β it exists in no file, and the asset
|
|
93
|
+
itself is not a source candidate, so a text search can never find it. What survives the build is
|
|
94
|
+
the BASE NAME, and the page says it itself: `import hero from "../assets/hero.jpg"`. The element
|
|
95
|
+
rendering that binding β `<img>`, `<source>`, `<video poster>`, or `<Image>`/`<Picture>` from
|
|
96
|
+
`astro:assets`, which forward unknown props to the `<img>` they render β gets
|
|
97
|
+
`src={bcmsImage(page, "<path>", hero)}` and the declaration beside it.
|
|
98
|
+
|
|
99
|
+
**Everything it will not do has a name, and the name is TRUE.** `AMBIGUOUS_LITERAL` when two
|
|
100
|
+
different paths share a sentence and position cannot separate them (both are skipped; the rest of
|
|
101
|
+
the file still converts), `SUBSTRING_ONLY`, `IN_SCRIPT_OR_COMMENT`, `KIND_MISMATCH`,
|
|
102
|
+
`REPEATER_AMBIGUOUS` (one array declaration, two loops over it β the row has two homes),
|
|
103
|
+
`IMAGE_ASSET_UNRESOLVED`, `PARSE_ERROR`. `NOT_IN_SOURCE` is reserved for what it says: a path
|
|
104
|
+
`locate` found in a file is `IN_EXPRESSION` when it sits in the module region or an expression
|
|
105
|
+
node, and where `NOT_IN_SOURCE` is still the answer the row names the file it was found in. And
|
|
106
|
+
the receipt's arithmetic is checked, not hoped for:
|
|
65
107
|
|
|
66
108
|
```
|
|
67
109
|
paths.declared === paths.rewritten + paths.alreadyDeclared + paths.pending.length
|
|
@@ -428,6 +470,19 @@ and removing them would mean editing statements no section asked about.
|
|
|
428
470
|
|
|
429
471
|
## Not here yet
|
|
430
472
|
|
|
473
|
+
An array of PRIMITIVES β `const items = ["a", "b", "c"]`, or of tuples β whose elements the brief
|
|
474
|
+
gave a separate NON-indexed path each (`li-field`, `li-rtl`, β¦) rather than one repeater group.
|
|
475
|
+
There is no group to key and no constant to rewrite, so those stay `IN_EXPRESSION`; what would fix
|
|
476
|
+
them is the derive lane minting the group, not a third shape here. Svelte and vue data literals are
|
|
477
|
+
not converted either β both lanes are written against the two dialects that keep their module and
|
|
478
|
+
their markup in one file with an AST this package already holds.
|
|
479
|
+
|
|
480
|
+
SHARED CHROME the brief still calls page copy. A header rendered by one component that nine routes
|
|
481
|
+
each declare a `nav[0].label` for is nine targets on one element, and there is no honest binding: a
|
|
482
|
+
read names ONE route's snapshot. That is `promoteSharedChrome`'s job on the derive side β once the
|
|
483
|
+
field is `scope: "layout"` the codemod collapses the nine to one identity and binds it. Until then
|
|
484
|
+
those paths are `AMBIGUOUS_LITERAL`, which is true.
|
|
485
|
+
|
|
431
486
|
`promoteSharedChrome`, and prop drilling through a svelte or vue component (both parse, and both
|
|
432
487
|
bind their own copy; only `findPropTargets` is jsx/astro-only, so a drilled prop there is
|
|
433
488
|
`PROP_TARGET_NOT_FOUND` rather than a wrong edit).
|