@bettercms-ai/convert 0.7.0 → 0.8.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 +48 -0
- package/README.md +61 -6
- package/dist/cli.js +506 -52
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +72 -4
- package/dist/index.js +507 -52
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @bettercms-ai/convert
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8a4e961: Bind array literals written inline in the markup, and drill a repeater row's leaf into the
|
|
8
|
+
component that renders it.
|
|
9
|
+
|
|
10
|
+
`{['Offer', 'Structure', 'RTL'].map((item) => <li>…</li>)}` had no lane at all — the list lane
|
|
11
|
+
searches the module for a NAMED array, and an inline literal has no name — so every one of its
|
|
12
|
+
items came back `IN_EXPRESSION` with the copy in plain sight. The `]` immediately before the
|
|
13
|
+
`.map(` is the literal's close, which is what makes it safe without a name: there is exactly one
|
|
14
|
+
loop over it and nothing else in the file can hold a second reference. A value rendered beside an
|
|
15
|
+
icon (`<li><span>✓</span>{item}</li>`) gets a `<span>` of its own instead of declaring on the
|
|
16
|
+
parent, because a publish writing the value over the parent deletes the icon.
|
|
17
|
+
|
|
18
|
+
`demos.map((demo) => <DemoCard title={demo.title} />)` refused the whole group with
|
|
19
|
+
`PROP_TARGET_NOT_FOUND`: the value is rendered in the component's file, not the page's. It now
|
|
20
|
+
follows the same drill the scalar lane has always used — a row's leaf is that journey with an index
|
|
21
|
+
in the path. The call site declares one `bcmsBindings={{ title: `cards[${i}].title` }}` per element
|
|
22
|
+
and the component gets `data-bcms-field={bcmsBindings?.title}`. `{...row}` counts as passing the
|
|
23
|
+
prop. Every leaf placed or none, as before: a drill that misses refuses the group by its own reason.
|
|
24
|
+
|
|
25
|
+
Also: `tsconfig.json` / `jsconfig.json` are now opened by the scan gate. `aliasesFrom` reads them
|
|
26
|
+
and nothing ever handed it one, so every `paths` alias resolved to nothing and every prop drilled
|
|
27
|
+
through an `@components/*` import refused with the component sitting right there.
|
|
28
|
+
|
|
29
|
+
`bindDataLiterals` is async for this; it is exported, and a caller outside this package has to
|
|
30
|
+
await it.
|
|
31
|
+
|
|
32
|
+
- 07f6648: Bind arrays of primitives and tuples rendered through `.map`.
|
|
33
|
+
|
|
34
|
+
`const promise = [['Once', 'One message'], …]` iterated as `promise.map(([title, text], i) => …)`
|
|
35
|
+
is the same shape as a row of objects one rung simpler, and the derive lane describes it as a
|
|
36
|
+
repeater group all the same. The declaration becomes `bcmsTuples(page, [[…paths…], …], [ …the
|
|
37
|
+
original array, verbatim… ])` — `bcmsList` for a list one wide — and each rendered element carries
|
|
38
|
+
the same templated `data-bcms-field` a repeater writes, so a second run reads it back and changes
|
|
39
|
+
nothing. The committed helper is v6; an existing v5 helper upgrades in place.
|
|
40
|
+
|
|
41
|
+
The read maps over the path list rather than over the CMS array, so every row's text is editable
|
|
42
|
+
and the number of rows is still the template's: the receipt adds one `PRIMITIVE_LIST` note per
|
|
43
|
+
array saying a row added in the CMS does not appear and a deleted one falls back to the template's
|
|
44
|
+
own copy. A list whose paths are unrelated scalars, one used anywhere but that single `.map` or
|
|
45
|
+
`export`ed, one rendered inside a larger expression, one whose tuple position changes kind between
|
|
46
|
+
rows, and one the brief covers only part of are all refused by name.
|
|
47
|
+
|
|
48
|
+
On the Shatter acceptance repository this moves 16 paths from `IN_EXPRESSION` to `rewritten`
|
|
49
|
+
(219 → 235 of 735).
|
|
50
|
+
|
|
3
51
|
## 0.7.0
|
|
4
52
|
|
|
5
53
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -88,6 +88,58 @@ inherits row 0's styling). Each row element then declares
|
|
|
88
88
|
`` data-bcms-field={`cards[${i}].<leaf>`} ``, and the callback gains an index parameter if it had
|
|
89
89
|
none. An imported data module stays `IN_DATA_FILE`.
|
|
90
90
|
|
|
91
|
+
**An array of PRIMITIVES or TUPLES is converted through its paths, not through its name.** The
|
|
92
|
+
same shape one rung simpler: `const deliverables = ["…", "…", "…"]`, or
|
|
93
|
+
`const faqs = [["q", "a"], …]`, iterated by `.map` with the callback rendering the item (or its
|
|
94
|
+
destructured positions) on one element each. There is no row object to key, so every element's
|
|
95
|
+
path is passed to the read:
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
const faqs = bcmsTuples(bcmsLanding, [["faqs[0].dt-field", "faqs[0].dd-field"], …],
|
|
99
|
+
[ …the original array, verbatim… ]);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`bcmsList` is the same for a list one wide. Each rendered element declares
|
|
103
|
+
`` data-bcms-field={`faqs[${i}].<leaf>`} `` — the same templated path a repeater writes, so a
|
|
104
|
+
second run reads it back and changes nothing — and the callback gains an index parameter, and a
|
|
105
|
+
jsx row its `key`, if it had none.
|
|
106
|
+
|
|
107
|
+
These arrays render exactly the paths this run wrote. Unlike `bcmsRows`, which reads the array
|
|
108
|
+
itself, `bcmsList`/`bcmsTuples` map over that fixed path list — so every row's TEXT is editable and
|
|
109
|
+
the NUMBER of rows is still the template's: a row added in the CMS has no path and never appears,
|
|
110
|
+
and a row deleted falls back to the copy the template shipped with. The receipt says so out loud,
|
|
111
|
+
once per array, as a `PRIMITIVE_LIST` note. Reading the array itself is the derive lane's job, not a
|
|
112
|
+
fourth shape here.
|
|
113
|
+
|
|
114
|
+
The lane refuses, by name: `IN_EXPRESSION` when the identifier is used anywhere but that one `.map`
|
|
115
|
+
or is `export`ed (the read replaces the value everywhere, including in files this run cannot see),
|
|
116
|
+
when the callback renders the item inside a larger expression, when an element is not a string
|
|
117
|
+
literal, when one tuple position is text in one row and richtext in the next (one element has one
|
|
118
|
+
sink), when the brief's paths do not cover EVERY element of the array, and when the paths are
|
|
119
|
+
unrelated scalars rather than one group's rows — that last one could only be declared as an
|
|
120
|
+
expression nothing downstream can verify; `REPEATER_AMBIGUOUS` when two loops iterate the array.
|
|
121
|
+
|
|
122
|
+
**An array literal written INLINE in the markup is the same lane, with no name between the two
|
|
123
|
+
halves.** `{['Offer', 'Structure', 'RTL'].map((item) => <li>…</li>)}` is what a template reaches
|
|
124
|
+
for whenever the list is four words long — nobody lifts four bullet points into a `const` — and the
|
|
125
|
+
copy then sits inside an expression the matcher is blind to by construction. The `]` immediately
|
|
126
|
+
before the `.map(` IS the literal's close, so there is exactly one loop over it and nothing else in
|
|
127
|
+
the file can hold a second reference to it: no "used anywhere but that one `.map`" test is needed,
|
|
128
|
+
and everything else — the paths, the templated declaration, the index parameter, the refusals — is
|
|
129
|
+
the named lane's. A value rendered BESIDE something else (`<li><span>✓</span>{item}</li>`) gets a
|
|
130
|
+
`<span>` of its own rather than declaring on the parent, because a publish writing the value over
|
|
131
|
+
the parent deletes the icon; the same wrap the scalar lane writes for a mixed element.
|
|
132
|
+
|
|
133
|
+
**A row's leaf handed to a component is drilled, exactly as a scalar prop is.**
|
|
134
|
+
`demos.map((demo) => <DemoCard title={demo.title} />)` renders the value in the COMPONENT's file,
|
|
135
|
+
so the page's call site declares `` bcmsBindings={{ title: `cards[${i}].title` }} `` — one object
|
|
136
|
+
per element, merged when a row hands two leaves to one component — and the component's element gets
|
|
137
|
+
`data-bcms-field={bcmsBindings?.title}` with the prop added to its destructuring and its props
|
|
138
|
+
type. `{...row}` counts as passing the prop: it is how most templates hand a row over. The group
|
|
139
|
+
still binds whole or not at all, so a drill that misses (the component cannot be resolved, nothing
|
|
140
|
+
in it renders the prop, this conversion already rewrites that file, or the call site already
|
|
141
|
+
carries a `bcmsBindings`) refuses the WHOLE group by the drill's own reason.
|
|
142
|
+
|
|
91
143
|
**An image is bound through its import, not through its url.** An image's `original` is the name
|
|
92
144
|
the bundler minted (`/_astro/hero.do77EGgx_ZNfVA8.jpg`) — it exists in no file, and the asset
|
|
93
145
|
itself is not a source candidate, so a text search can never find it. What survives the build is
|
|
@@ -470,12 +522,15 @@ and removing them would mean editing statements no section asked about.
|
|
|
470
522
|
|
|
471
523
|
## Not here yet
|
|
472
524
|
|
|
473
|
-
An array of
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
525
|
+
GROWABLE lists. An array of primitives or tuples is bound (above) but renders the number of rows
|
|
526
|
+
the template shipped with, because the read maps over a fixed path list rather than over the CMS
|
|
527
|
+
array — and when the brief gave its elements unrelated scalar paths (`li-field`, `li-rtl`, …)
|
|
528
|
+
rather than one group's rows, it is not bound at all: the only declaration that could carry a
|
|
529
|
+
different path per row is an expression, and one nothing downstream can verify is worse than the
|
|
530
|
+
honest `IN_EXPRESSION`. Both are the same fix on the derive side — minting the group — not a
|
|
531
|
+
further shape here. Svelte and vue data literals are not converted
|
|
532
|
+
either; all three lanes are written against the two dialects that keep their module and their
|
|
533
|
+
markup in one file with an AST this package already holds.
|
|
479
534
|
|
|
480
535
|
SHARED CHROME the brief still calls page copy. A header rendered by one component that nine routes
|
|
481
536
|
each declare a `nav[0].label` for is nine targets on one element, and there is no honest binding: a
|