@bettercms-ai/convert 0.18.2 → 0.19.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 +15 -0
- package/dist/cli.js +55 -19
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +53 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @bettercms-ai/convert
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3d022b0: A locale copy placed on its default-locale twin's section component now carries `props.bindPaths` (`{ <propKey>: "<this page's field path>" }`) beside `bind`, because its own field keys differ from the component's. `ComponentProps.bindPaths` is new in types; the convert helper (v9) and the extracted section components and registry read a prop's copy and declare its address through it, so `/fr` renders and edits its own words instead of a field it does not have. Older readers ignore it.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [12b2d62]
|
|
12
|
+
- Updated dependencies [3d022b0]
|
|
13
|
+
- Updated dependencies [a0a6ad9]
|
|
14
|
+
- Updated dependencies [621a70e]
|
|
15
|
+
- Updated dependencies [2729e58]
|
|
16
|
+
- @bettercms-ai/types@1.25.0
|
|
17
|
+
|
|
3
18
|
## 0.18.2
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/cli.js
CHANGED
|
@@ -4190,7 +4190,7 @@ async function bindImages(ctx, targets) {
|
|
|
4190
4190
|
|
|
4191
4191
|
// src/helper.ts
|
|
4192
4192
|
import { createHash as createHash2 } from "crypto";
|
|
4193
|
-
var HELPER_VERSION =
|
|
4193
|
+
var HELPER_VERSION = 9;
|
|
4194
4194
|
var HEADER = "// @bettercms-ai/convert helper v";
|
|
4195
4195
|
var HELPER_PATH = Object.fromEntries(
|
|
4196
4196
|
Object.keys(DIALECT_RULES).map((d) => [d, DIALECT_RULES[d].helper])
|
|
@@ -4355,9 +4355,19 @@ export function bcmsImage<T>(page: unknown, path: string, fallback: T, slug?: st
|
|
|
4355
4355
|
* the fallback the template shipped with \u2014 which is why a section renders correctly against the
|
|
4356
4356
|
* committed \`{}\` stub.
|
|
4357
4357
|
*/
|
|
4358
|
-
export function bcmsSection(
|
|
4358
|
+
export function bcmsSection(
|
|
4359
|
+
page: unknown,
|
|
4360
|
+
bind?: string,
|
|
4361
|
+
overrides?: unknown,
|
|
4362
|
+
bindPaths?: Record<string, string>,
|
|
4363
|
+
): Record<string, unknown> {
|
|
4359
4364
|
const group = bind ? readPath(page, bind) : undefined;
|
|
4360
4365
|
const base: Record<string, unknown> = isRecord(group) ? { ...group } : {};
|
|
4366
|
+
// A locale copy on its twin's component spells its fields its own way: each prop's copy is
|
|
4367
|
+
// read from the path the placement names for it.
|
|
4368
|
+
if (bind && isRecord(bindPaths)) {
|
|
4369
|
+
for (const [key, path] of Object.entries(bindPaths)) base[key] = readPath(page, path);
|
|
4370
|
+
}
|
|
4361
4371
|
if (!isRecord(overrides)) return base;
|
|
4362
4372
|
for (const key of Object.keys(overrides)) {
|
|
4363
4373
|
const value = overrides[key];
|
|
@@ -4420,21 +4430,25 @@ export function bcmsSectionPaths(
|
|
|
4420
4430
|
overrides: unknown,
|
|
4421
4431
|
prefix: string,
|
|
4422
4432
|
map: BcmsPathMap,
|
|
4433
|
+
bindPaths?: Record<string, string>,
|
|
4423
4434
|
): Record<string, unknown> {
|
|
4424
4435
|
const out: Record<string, unknown> = isRecord(page) ? { ...page } : {};
|
|
4425
4436
|
const own = isRecord(overrides) ? overrides : {};
|
|
4426
4437
|
const separator = prefix.slice(-1);
|
|
4427
|
-
|
|
4428
|
-
|
|
4438
|
+
// A re-keyed locale copy names each prop's path on its own page; any other placement re-bases.
|
|
4439
|
+
const fromPage = (path: string, key: string): unknown =>
|
|
4440
|
+
!bind ? undefined
|
|
4441
|
+
: isRecord(bindPaths) && typeof bindPaths[key] === "string" ? readPath(page, bindPaths[key])
|
|
4442
|
+
: readPath(page, bind + separator + path.slice(prefix.length));
|
|
4429
4443
|
for (const [path, key] of Object.entries(map.scalars ?? {})) {
|
|
4430
4444
|
const value = own[key];
|
|
4431
|
-
out[path] = value !== undefined && value !== null ? value : fromPage(path);
|
|
4445
|
+
out[path] = value !== undefined && value !== null ? value : fromPage(path, key);
|
|
4432
4446
|
}
|
|
4433
4447
|
for (const [path, table] of Object.entries(map.tables ?? {})) {
|
|
4434
4448
|
const held = own[table.key];
|
|
4435
4449
|
const rows = isRecord(held) && Array.isArray(held.rows) ? held.rows : held;
|
|
4436
4450
|
if (!Array.isArray(rows)) {
|
|
4437
|
-
out[path] = fromPage(path);
|
|
4451
|
+
out[path] = fromPage(path, table.key);
|
|
4438
4452
|
continue;
|
|
4439
4453
|
}
|
|
4440
4454
|
const pageColumn = new Map(Object.entries(table.columns).map(([column, key]) => [key, column]));
|
|
@@ -4449,12 +4463,17 @@ export function bcmsSectionPaths(
|
|
|
4449
4463
|
}
|
|
4450
4464
|
|
|
4451
4465
|
export function bcmsFields(
|
|
4452
|
-
placement: { blockId?: string; bind?: string; overrides?: unknown },
|
|
4466
|
+
placement: { blockId?: string; bind?: string; overrides?: unknown; bindPaths?: Record<string, string> },
|
|
4453
4467
|
pathPrefix: string,
|
|
4454
4468
|
map?: BcmsPathMap,
|
|
4455
4469
|
): (path: string) => string {
|
|
4456
4470
|
const id = placement.blockId;
|
|
4457
4471
|
const own = typeof id === "string" && id !== "" && !placement.bind && isRecord(placement.overrides);
|
|
4472
|
+
/** A re-keyed locale copy's own path for a prop, with whatever follows the prop kept. */
|
|
4473
|
+
const moved = (key: string | undefined, rest: string): string | undefined => {
|
|
4474
|
+
const paths = placement.bind && isRecord(placement.bindPaths) ? placement.bindPaths : undefined;
|
|
4475
|
+
return key !== undefined && paths && typeof paths[key] === "string" ? paths[key] + rest : undefined;
|
|
4476
|
+
};
|
|
4458
4477
|
/**
|
|
4459
4478
|
* What replaces the prefix the markup was cut with, or null for "leave every path alone".
|
|
4460
4479
|
*
|
|
@@ -4473,11 +4492,14 @@ export function bcmsFields(
|
|
|
4473
4492
|
const separator = pathPrefix.slice(-1);
|
|
4474
4493
|
return (path: string): string => {
|
|
4475
4494
|
if (!path.startsWith(pathPrefix) || !(own || placement.bind)) return path;
|
|
4476
|
-
if (!own) return placement.bind + separator + path.slice(pathPrefix.length);
|
|
4477
4495
|
const scalar = map.scalars?.[path];
|
|
4478
|
-
if (scalar !== undefined) return id + "__overrides." + scalar;
|
|
4479
4496
|
const row = /^([^[]+)\\[(\\d+)\\]\\.(.+)$/.exec(path);
|
|
4480
4497
|
const table = row ? map.tables?.[row[1]] : undefined;
|
|
4498
|
+
if (!own) {
|
|
4499
|
+
return moved(scalar, "") ?? moved(table?.key, row ? "[" + row[2] + "]." + row[3] : "")
|
|
4500
|
+
?? placement.bind + separator + path.slice(pathPrefix.length);
|
|
4501
|
+
}
|
|
4502
|
+
if (scalar !== undefined) return id + "__overrides." + scalar;
|
|
4481
4503
|
const column = row && table ? table.columns[row[3]] : undefined;
|
|
4482
4504
|
return table && column !== undefined ? id + "__overrides." + table.key + "[" + row![2] + "]." + column : path;
|
|
4483
4505
|
};
|
|
@@ -4487,7 +4509,9 @@ export function bcmsFields(
|
|
|
4487
4509
|
// it names a key the instance does not hold and a group this placement is not bound to.
|
|
4488
4510
|
// (An EMPTY prefix is a plan saying the prop key IS the page path, and matches everything.)
|
|
4489
4511
|
if (lane === null || !path.startsWith(pathPrefix)) return path;
|
|
4490
|
-
|
|
4512
|
+
const rest = path.slice(pathPrefix.length);
|
|
4513
|
+
const key = /^[^.[]+/.exec(rest)?.[0];
|
|
4514
|
+
return (own ? undefined : moved(key, rest.slice(key?.length ?? 0))) ?? lane + rest;
|
|
4491
4515
|
};
|
|
4492
4516
|
}
|
|
4493
4517
|
`;
|
|
@@ -4500,7 +4524,8 @@ var HISTORICAL = {
|
|
|
4500
4524
|
4: "a5742f64dacb1b26ee6dd5e1469a54871487934c71bc8267df19e3a80e417595",
|
|
4501
4525
|
5: "0472fe3ffdcfa49e719c7b9da9cb63b6eba637cc22783bb00c3c2cadd3d800da",
|
|
4502
4526
|
6: "c907e7245578d947c6541b1ab2c5c6659ea7789a1519e895b4a4aed122c6f649",
|
|
4503
|
-
7: "f22514ef48c50230985e605bea6cf9bf41756384a7dc80603e347baba9b65d93"
|
|
4527
|
+
7: "f22514ef48c50230985e605bea6cf9bf41756384a7dc80603e347baba9b65d93",
|
|
4528
|
+
8: "484e72852d2b496e016a1f2a2b1a77bb993f8a163b290781522d6114b6519bb9"
|
|
4504
4529
|
},
|
|
4505
4530
|
"src/lib/bcms-content.ts": {
|
|
4506
4531
|
1: "ae72ae14d706943d481c880d70da5789b4816ba1ba319a10fbc63ded4d0b42f2",
|
|
@@ -4509,7 +4534,8 @@ var HISTORICAL = {
|
|
|
4509
4534
|
4: "0146d027a727ecd3c9e3fc336fcf1299b59ddf75b04091c05703f3f983ec28af",
|
|
4510
4535
|
5: "c8c93655320fa65664611ba84541f3fa7bfa292cc9a2fd655373440b99049fba",
|
|
4511
4536
|
6: "63f1fa29e47e70c5193b81ee24addb238ba100247124d55bc17713102d587df5",
|
|
4512
|
-
7: "ed92fb88de953d9951abbe6a1edae1d048f4050eaf6fb607ac08167f94d8bcc7"
|
|
4537
|
+
7: "ed92fb88de953d9951abbe6a1edae1d048f4050eaf6fb607ac08167f94d8bcc7",
|
|
4538
|
+
8: "1a6f669d76d42effe77f082436e9d21c0efa6fc499e919e3d116bc3a27a7f3d5"
|
|
4513
4539
|
},
|
|
4514
4540
|
"composables/bcms-content.ts": {
|
|
4515
4541
|
1: "c272412532efed7db64b6cf313b2bed4291f9951430412289c8a588b7f565407",
|
|
@@ -4518,7 +4544,8 @@ var HISTORICAL = {
|
|
|
4518
4544
|
4: "a5742f64dacb1b26ee6dd5e1469a54871487934c71bc8267df19e3a80e417595",
|
|
4519
4545
|
5: "0472fe3ffdcfa49e719c7b9da9cb63b6eba637cc22783bb00c3c2cadd3d800da",
|
|
4520
4546
|
6: "c907e7245578d947c6541b1ab2c5c6659ea7789a1519e895b4a4aed122c6f649",
|
|
4521
|
-
7: "f22514ef48c50230985e605bea6cf9bf41756384a7dc80603e347baba9b65d93"
|
|
4547
|
+
7: "f22514ef48c50230985e605bea6cf9bf41756384a7dc80603e347baba9b65d93",
|
|
4548
|
+
8: "484e72852d2b496e016a1f2a2b1a77bb993f8a163b290781522d6114b6519bb9"
|
|
4522
4549
|
}
|
|
4523
4550
|
};
|
|
4524
4551
|
var sha256 = (value) => createHash2("sha256").update(value, "utf8").digest("hex");
|
|
@@ -8114,6 +8141,7 @@ function componentFile(dialect, path, fromFile, content, parsed, resolved, pathP
|
|
|
8114
8141
|
provided: [
|
|
8115
8142
|
"blockId",
|
|
8116
8143
|
"bind",
|
|
8144
|
+
"bindPaths",
|
|
8117
8145
|
"overrides",
|
|
8118
8146
|
"page",
|
|
8119
8147
|
fieldName,
|
|
@@ -8128,8 +8156,8 @@ function componentFile(dialect, path, fromFile, content, parsed, resolved, pathP
|
|
|
8128
8156
|
const key = /^[A-Za-z_$][\w$]*$/.test(groupKey) ? groupKey : JSON.stringify(groupKey);
|
|
8129
8157
|
const carriedDeclarations = carry.declarations.length > 0 ? `${carry.declarations.join("\n")}
|
|
8130
8158
|
` : "";
|
|
8131
|
-
const copy = !snapshot ? "" : flat3 ? `const ${snapshot} = bcmsSectionPaths(page, bind, overrides, ${JSON.stringify(pathPrefix)}, ${JSON.stringify(pathMap)});` : `const ${snapshot} = { ${key}: bcmsSection(page, bind, overrides) };`;
|
|
8132
|
-
const field = bound > 0 ? `const ${fieldName} = ${fieldsName}({ blockId, bind, overrides }, ${JSON.stringify(pathPrefix)}${flat3 ? `, ${JSON.stringify(pathMap)}` : ""});` : "";
|
|
8159
|
+
const copy = !snapshot ? "" : flat3 ? `const ${snapshot} = bcmsSectionPaths(page, bind, overrides, ${JSON.stringify(pathPrefix)}, ${JSON.stringify(pathMap)}, bindPaths);` : `const ${snapshot} = { ${key}: bcmsSection(page, bind, overrides, bindPaths) };`;
|
|
8160
|
+
const field = bound > 0 ? `const ${fieldName} = ${fieldsName}({ blockId, bind, bindPaths, overrides }, ${JSON.stringify(pathPrefix)}${flat3 ? `, ${JSON.stringify(pathMap)}` : ""});` : "";
|
|
8133
8161
|
const declared = [copy, field].filter(Boolean).join("\n");
|
|
8134
8162
|
const styles = dialect === "astro" ? carriedStyles(content) : "";
|
|
8135
8163
|
if (dialect === "astro") {
|
|
@@ -8142,12 +8170,14 @@ interface Props {
|
|
|
8142
8170
|
blockId?: string;
|
|
8143
8171
|
/** The page field group this placement renders \u2014 Phase A keeps the copy where P2 put it. */
|
|
8144
8172
|
bind?: string;
|
|
8173
|
+
/** A locale copy's own field path for each prop, when its keys differ from this component's. */
|
|
8174
|
+
bindPaths?: Record<string, string>;
|
|
8145
8175
|
/** The instance's own copy, when an editor gave it any. Wins over the bound group. */
|
|
8146
8176
|
overrides?: Record<string, unknown>;
|
|
8147
8177
|
/** The page snapshot, so one component can serve every page whose group has this shape. */
|
|
8148
8178
|
page?: unknown;
|
|
8149
8179
|
}
|
|
8150
|
-
const { blockId, bind, overrides, page } = Astro.props;
|
|
8180
|
+
const { blockId, bind, bindPaths, overrides, page } = Astro.props;
|
|
8151
8181
|
${carriedDeclarations}${declared}
|
|
8152
8182
|
---
|
|
8153
8183
|
${markup}
|
|
@@ -8159,7 +8189,7 @@ ${styles}
|
|
|
8159
8189
|
${[...carried, `import { ${helpers.join(", ")} } from "${helperSpecifier}";`, `import type { BcmsSectionProps } from "${relativeImport(path, SECTIONS_LIB).replace(/\.tsx?$/, "")}";`].join("\n")}
|
|
8160
8190
|
${carriedDeclarations === "" ? "" : `
|
|
8161
8191
|
${carriedDeclarations}`}
|
|
8162
|
-
export default function ${resolved.name}({ blockId, bind, overrides, page }: BcmsSectionProps) {
|
|
8192
|
+
export default function ${resolved.name}({ blockId, bind, bindPaths, overrides, page }: BcmsSectionProps) {
|
|
8163
8193
|
${declared.split("\n").join("\n ")}
|
|
8164
8194
|
return (
|
|
8165
8195
|
${markup}
|
|
@@ -8521,6 +8551,7 @@ const isRecord = (v: unknown): v is Record<string, unknown> =>
|
|
|
8521
8551
|
export interface BcmsSectionProps {
|
|
8522
8552
|
blockId?: string;
|
|
8523
8553
|
bind?: string;
|
|
8554
|
+
bindPaths?: Record<string, string>;
|
|
8524
8555
|
overrides?: Record<string, unknown>;
|
|
8525
8556
|
page?: unknown;
|
|
8526
8557
|
}
|
|
@@ -8530,6 +8561,8 @@ export interface BcmsPlacement {
|
|
|
8530
8561
|
blockId?: string;
|
|
8531
8562
|
slug: string;
|
|
8532
8563
|
bind?: string;
|
|
8564
|
+
/** A locale copy's own field path for each prop, when its keys differ from the component's. */
|
|
8565
|
+
bindPaths?: Record<string, string>;
|
|
8533
8566
|
overrides?: Record<string, unknown>;
|
|
8534
8567
|
}
|
|
8535
8568
|
|
|
@@ -8590,6 +8623,7 @@ export function pageSections(pageSlug: string): BcmsPlacement[] {
|
|
|
8590
8623
|
blockId: typeof block.id === "string" ? block.id : undefined,
|
|
8591
8624
|
slug,
|
|
8592
8625
|
bind: typeof props.bind === "string" ? props.bind : undefined,
|
|
8626
|
+
bindPaths: isRecord(props.bindPaths) ? (props.bindPaths as Record<string, string>) : undefined,
|
|
8593
8627
|
overrides: isRecord(props.overrides) ? props.overrides : undefined,
|
|
8594
8628
|
});
|
|
8595
8629
|
}
|
|
@@ -8655,6 +8689,7 @@ const snapshot = pageSnapshot(page);
|
|
|
8655
8689
|
<Component
|
|
8656
8690
|
blockId={placement.blockId}
|
|
8657
8691
|
bind={placement.bind}
|
|
8692
|
+
bindPaths={placement.bindPaths}
|
|
8658
8693
|
overrides={placement.overrides}
|
|
8659
8694
|
page={snapshot}
|
|
8660
8695
|
/>
|
|
@@ -8677,6 +8712,7 @@ export default function Sections({ page }: { page: string }) {
|
|
|
8677
8712
|
key={placement.blockId ?? \`\${placement.slug}-\${i}\`}
|
|
8678
8713
|
blockId={placement.blockId}
|
|
8679
8714
|
bind={placement.bind}
|
|
8715
|
+
bindPaths={placement.bindPaths}
|
|
8680
8716
|
overrides={placement.overrides}
|
|
8681
8717
|
page={snapshot}
|
|
8682
8718
|
/>
|
|
@@ -9952,7 +9988,7 @@ function styleEdits(before, after) {
|
|
|
9952
9988
|
// package.json
|
|
9953
9989
|
var package_default = {
|
|
9954
9990
|
name: "@bettercms-ai/convert",
|
|
9955
|
-
version: "0.
|
|
9991
|
+
version: "0.19.0",
|
|
9956
9992
|
type: "module",
|
|
9957
9993
|
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.",
|
|
9958
9994
|
bin: {
|
|
@@ -9985,7 +10021,7 @@ var package_default = {
|
|
|
9985
10021
|
dependencies: {
|
|
9986
10022
|
"@astrojs/compiler": "^2.13.1",
|
|
9987
10023
|
"@babel/parser": "^7.29.2",
|
|
9988
|
-
"@bettercms-ai/types": "^1.
|
|
10024
|
+
"@bettercms-ai/types": "^1.25.0",
|
|
9989
10025
|
"@vue/compiler-sfc": "^3.5.0",
|
|
9990
10026
|
"magic-string": "^0.30.21",
|
|
9991
10027
|
parse5: "^7.3.0",
|