@bettercms-ai/convert 0.10.0 → 0.11.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 +16 -0
- package/dist/cli.js +149 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +148 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @bettercms-ai/convert
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- `--componentize` extracts FLAT field families (`wrap-h2-latest`, whose key is `h2_latest`), which were
|
|
8
|
+
refused as `PROP_MAP_INCONSISTENT`. The section reads its copy through the new helper `bcmsSectionPaths`
|
|
9
|
+
and addresses instance copy by the override key the plan names (`overrideKey`, including repeater rows).
|
|
10
|
+
- An Astro section carries the page's scoped plain-CSS `<style>` blocks, so it renders styled on its own —
|
|
11
|
+
for every newly extracted section, dotted families included (Astro scopes styles per file, so page CSS
|
|
12
|
+
never reached a moved section). `is:global`, `define:vars`, `lang="…"` and `@import`/`@use` blocks stay on
|
|
13
|
+
the page.
|
|
14
|
+
- The componentize receipt lists `componentFiles` (`{ slug, path, export }`): submit it with the MCP tool
|
|
15
|
+
`submit_componentize_receipt` so every extracted section is recorded as its component's source and the
|
|
16
|
+
dashboard's Output can build, validate and render it.
|
|
17
|
+
- Helper v7. A v6 helper is recognised and upgraded in place.
|
|
18
|
+
|
|
3
19
|
## 0.10.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/dist/cli.js
CHANGED
|
@@ -4142,7 +4142,7 @@ function bindImages(ctx, targets) {
|
|
|
4142
4142
|
|
|
4143
4143
|
// src/helper.ts
|
|
4144
4144
|
import { createHash as createHash2 } from "crypto";
|
|
4145
|
-
var HELPER_VERSION =
|
|
4145
|
+
var HELPER_VERSION = 7;
|
|
4146
4146
|
var HEADER = "// @bettercms-ai/convert helper v";
|
|
4147
4147
|
var HELPER_PATH = Object.fromEntries(
|
|
4148
4148
|
Object.keys(DIALECT_RULES).map((d) => [d, DIALECT_RULES[d].helper])
|
|
@@ -4335,9 +4335,65 @@ export function bcmsSection(page: unknown, bind?: string, overrides?: unknown):
|
|
|
4335
4335
|
* how the codemod ran: one component renders a Phase A placement on one page and a Phase B
|
|
4336
4336
|
* instance on the next, and a repository does not have to be re-cut when its copy moves.
|
|
4337
4337
|
*/
|
|
4338
|
+
/** How a flat field family maps page paths to an instance's override keys. @see bcmsSectionPaths */
|
|
4339
|
+
export type BcmsPathMap = {
|
|
4340
|
+
scalars?: Record<string, string>;
|
|
4341
|
+
tables?: Record<string, { key: string; columns: Record<string, string> }>;
|
|
4342
|
+
};
|
|
4343
|
+
|
|
4344
|
+
/**
|
|
4345
|
+
* The snapshot for a section whose page fields are a FLAT family (\`wrap-h2-latest\`, not \`wrap.h2_latest\`).
|
|
4346
|
+
*
|
|
4347
|
+
* \`bcmsSection\` returns a group object read through a dotted path, which a flat family does not have: its
|
|
4348
|
+
* copy lives in top-level keys of the page snapshot. So this answers in the page's own spelling \u2014 the
|
|
4349
|
+
* markup reads \`bcms(snapshot, "wrap-h2-latest", \u2026)\` verbatim \u2014 with every mapped path set explicitly:
|
|
4350
|
+
*
|
|
4351
|
+
* - the instance's override for that key when it holds one (a table's rows re-spelled with the page's
|
|
4352
|
+
* column names, \`{ rows }\` unwrapped as in \`bcmsSection\`);
|
|
4353
|
+
* - else, for a placement bound to a group, the page value at the path re-based onto that group;
|
|
4354
|
+
* - else NOTHING \u2014 a placement that owns its copy never falls back to the page's stale copy, exactly as
|
|
4355
|
+
* \`bcmsSection\` synthesizes no group for it.
|
|
4356
|
+
*
|
|
4357
|
+
* Every other page key passes through, so reads outside the family (a shared link) keep working.
|
|
4358
|
+
*/
|
|
4359
|
+
export function bcmsSectionPaths(
|
|
4360
|
+
page: unknown,
|
|
4361
|
+
bind: string | undefined,
|
|
4362
|
+
overrides: unknown,
|
|
4363
|
+
prefix: string,
|
|
4364
|
+
map: BcmsPathMap,
|
|
4365
|
+
): Record<string, unknown> {
|
|
4366
|
+
const out: Record<string, unknown> = isRecord(page) ? { ...page } : {};
|
|
4367
|
+
const own = isRecord(overrides) ? overrides : {};
|
|
4368
|
+
const separator = prefix.slice(-1);
|
|
4369
|
+
const fromPage = (path: string): unknown =>
|
|
4370
|
+
bind ? readPath(page, bind + separator + path.slice(prefix.length)) : undefined;
|
|
4371
|
+
for (const [path, key] of Object.entries(map.scalars ?? {})) {
|
|
4372
|
+
const value = own[key];
|
|
4373
|
+
out[path] = value !== undefined && value !== null ? value : fromPage(path);
|
|
4374
|
+
}
|
|
4375
|
+
for (const [path, table] of Object.entries(map.tables ?? {})) {
|
|
4376
|
+
const held = own[table.key];
|
|
4377
|
+
const rows = isRecord(held) && Array.isArray(held.rows) ? held.rows : held;
|
|
4378
|
+
if (!Array.isArray(rows)) {
|
|
4379
|
+
out[path] = fromPage(path);
|
|
4380
|
+
continue;
|
|
4381
|
+
}
|
|
4382
|
+
const pageColumn = new Map(Object.entries(table.columns).map(([column, key]) => [key, column]));
|
|
4383
|
+
out[path] = rows.map((row) => {
|
|
4384
|
+
if (!isRecord(row)) return row;
|
|
4385
|
+
const spelled: Record<string, unknown> = {};
|
|
4386
|
+
for (const [key, value] of Object.entries(row)) spelled[pageColumn.get(key) ?? key] = value;
|
|
4387
|
+
return spelled;
|
|
4388
|
+
});
|
|
4389
|
+
}
|
|
4390
|
+
return out;
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4338
4393
|
export function bcmsFields(
|
|
4339
4394
|
placement: { blockId?: string; bind?: string; overrides?: unknown },
|
|
4340
4395
|
pathPrefix: string,
|
|
4396
|
+
map?: BcmsPathMap,
|
|
4341
4397
|
): (path: string) => string {
|
|
4342
4398
|
const id = placement.blockId;
|
|
4343
4399
|
const own = typeof id === "string" && id !== "" && !placement.bind && isRecord(placement.overrides);
|
|
@@ -4350,6 +4406,24 @@ export function bcmsFields(
|
|
|
4350
4406
|
* so prepending one would invent an address rather than correct it.
|
|
4351
4407
|
*/
|
|
4352
4408
|
const lane = own ? \`\${id}__overrides.\` : placement.bind && pathPrefix ? \`\${placement.bind}.\` : null;
|
|
4409
|
+
if (map) {
|
|
4410
|
+
/**
|
|
4411
|
+
* A FLAT family: the address is not "prefix swapped". The instance lane names the override key the
|
|
4412
|
+
* plan allocated (\`h2_latest\`, \`group_webgl[0].a_webgl\`); the bind lane keeps the page's own
|
|
4413
|
+
* separator (\`landing-h2-latest\`, never \`landing.h2-latest\`).
|
|
4414
|
+
*/
|
|
4415
|
+
const separator = pathPrefix.slice(-1);
|
|
4416
|
+
return (path: string): string => {
|
|
4417
|
+
if (!path.startsWith(pathPrefix) || !(own || placement.bind)) return path;
|
|
4418
|
+
if (!own) return placement.bind + separator + path.slice(pathPrefix.length);
|
|
4419
|
+
const scalar = map.scalars?.[path];
|
|
4420
|
+
if (scalar !== undefined) return id + "__overrides." + scalar;
|
|
4421
|
+
const row = /^([^[]+)\\[(\\d+)\\]\\.(.+)$/.exec(path);
|
|
4422
|
+
const table = row ? map.tables?.[row[1]] : undefined;
|
|
4423
|
+
const column = row && table ? table.columns[row[3]] : undefined;
|
|
4424
|
+
return table && column !== undefined ? id + "__overrides." + table.key + "[" + row![2] + "]." + column : path;
|
|
4425
|
+
};
|
|
4426
|
+
}
|
|
4353
4427
|
return (path: string): string => {
|
|
4354
4428
|
// A path outside the group this section was cut from is not one this placement re-addresses:
|
|
4355
4429
|
// it names a key the instance does not hold and a group this placement is not bound to.
|
|
@@ -4366,21 +4440,24 @@ var HISTORICAL = {
|
|
|
4366
4440
|
2: "51e2ae65ddd86bf43d14e29b3865e3f16e45f72069692d1fea57e1f986a894f0",
|
|
4367
4441
|
3: "d4305b2983adcb456ef782d35ea9d083a04465c2b68baa0d44a084dfa01a9227",
|
|
4368
4442
|
4: "a5742f64dacb1b26ee6dd5e1469a54871487934c71bc8267df19e3a80e417595",
|
|
4369
|
-
5: "0472fe3ffdcfa49e719c7b9da9cb63b6eba637cc22783bb00c3c2cadd3d800da"
|
|
4443
|
+
5: "0472fe3ffdcfa49e719c7b9da9cb63b6eba637cc22783bb00c3c2cadd3d800da",
|
|
4444
|
+
6: "c907e7245578d947c6541b1ab2c5c6659ea7789a1519e895b4a4aed122c6f649"
|
|
4370
4445
|
},
|
|
4371
4446
|
"src/lib/bcms-content.ts": {
|
|
4372
4447
|
1: "ae72ae14d706943d481c880d70da5789b4816ba1ba319a10fbc63ded4d0b42f2",
|
|
4373
4448
|
2: "a18731eb42f7db55dac0591c45f873758cde8e103fefcd6e5caf67936ae6a002",
|
|
4374
4449
|
3: "0be9c73160361882a038552bc02673c14ed532287823dabaafe36179bc55ed7e",
|
|
4375
4450
|
4: "0146d027a727ecd3c9e3fc336fcf1299b59ddf75b04091c05703f3f983ec28af",
|
|
4376
|
-
5: "c8c93655320fa65664611ba84541f3fa7bfa292cc9a2fd655373440b99049fba"
|
|
4451
|
+
5: "c8c93655320fa65664611ba84541f3fa7bfa292cc9a2fd655373440b99049fba",
|
|
4452
|
+
6: "63f1fa29e47e70c5193b81ee24addb238ba100247124d55bc17713102d587df5"
|
|
4377
4453
|
},
|
|
4378
4454
|
"composables/bcms-content.ts": {
|
|
4379
4455
|
1: "c272412532efed7db64b6cf313b2bed4291f9951430412289c8a588b7f565407",
|
|
4380
4456
|
2: "51e2ae65ddd86bf43d14e29b3865e3f16e45f72069692d1fea57e1f986a894f0",
|
|
4381
4457
|
3: "d4305b2983adcb456ef782d35ea9d083a04465c2b68baa0d44a084dfa01a9227",
|
|
4382
4458
|
4: "a5742f64dacb1b26ee6dd5e1469a54871487934c71bc8267df19e3a80e417595",
|
|
4383
|
-
5: "0472fe3ffdcfa49e719c7b9da9cb63b6eba637cc22783bb00c3c2cadd3d800da"
|
|
4459
|
+
5: "0472fe3ffdcfa49e719c7b9da9cb63b6eba637cc22783bb00c3c2cadd3d800da",
|
|
4460
|
+
6: "c907e7245578d947c6541b1ab2c5c6659ea7789a1519e895b4a4aed122c6f649"
|
|
4384
4461
|
}
|
|
4385
4462
|
};
|
|
4386
4463
|
var sha256 = (value) => createHash2("sha256").update(value, "utf8").digest("hex");
|
|
@@ -6869,6 +6946,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
6869
6946
|
return held;
|
|
6870
6947
|
};
|
|
6871
6948
|
const fresh = /* @__PURE__ */ new Set();
|
|
6949
|
+
const freshFiles = /* @__PURE__ */ new Map();
|
|
6872
6950
|
const bindOf = (section) => instanceOwned(section) ? void 0 : section.groupKey;
|
|
6873
6951
|
const placementOf = (slug, section) => {
|
|
6874
6952
|
const bind = bindOf(section);
|
|
@@ -7196,6 +7274,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
7196
7274
|
}
|
|
7197
7275
|
extractable.set(resolved.slug, { name: resolved.name, path, kind: "default", imported: null });
|
|
7198
7276
|
fresh.add(resolved.slug);
|
|
7277
|
+
freshFiles.set(resolved.slug, path);
|
|
7199
7278
|
addFile(outFiles, contents, {
|
|
7200
7279
|
path,
|
|
7201
7280
|
operation: existing === void 0 ? "add" : "modify",
|
|
@@ -7281,6 +7360,7 @@ async function componentizeSources(briefIn, planIn, sources, options) {
|
|
|
7281
7360
|
sections,
|
|
7282
7361
|
// What THIS run wrote a file for. A component an earlier run left is reused, not re-reported.
|
|
7283
7362
|
components: [...fresh].sort(),
|
|
7363
|
+
componentFiles: [...freshFiles].sort(([a], [b]) => a.localeCompare(b)).map(([slug, path]) => ({ slug, path, export: "default" })),
|
|
7284
7364
|
planPending,
|
|
7285
7365
|
notes
|
|
7286
7366
|
}
|
|
@@ -7460,7 +7540,7 @@ async function locateSections(sections, briefPaths, sources, treeOf) {
|
|
|
7460
7540
|
for (const section of sections) {
|
|
7461
7541
|
const paths = fieldPaths(section);
|
|
7462
7542
|
const literals = new Set(
|
|
7463
|
-
briefPaths.filter((p) => (p.scope ?? "page") === "page" &&
|
|
7543
|
+
briefPaths.filter((p) => (p.scope ?? "page") === "page" && inSection(section, p.path) && p.original).map((p) => flat(stripTags(p.original))).filter(Boolean)
|
|
7464
7544
|
);
|
|
7465
7545
|
const hits = /* @__PURE__ */ new Map();
|
|
7466
7546
|
for (const source of sources) {
|
|
@@ -7471,7 +7551,7 @@ async function locateSections(sections, briefPaths, sources, treeOf) {
|
|
|
7471
7551
|
const found = /* @__PURE__ */ new Map();
|
|
7472
7552
|
for (const declaration2 of declarationsIn(parsed.roots, source.content)) {
|
|
7473
7553
|
if (declaration2.scope !== "page") continue;
|
|
7474
|
-
if (
|
|
7554
|
+
if (!inSection(section, declaration2.path)) continue;
|
|
7475
7555
|
const placed2 = elements.get(declaration2.at);
|
|
7476
7556
|
if (placed2) found.set(declaration2.at, placed2);
|
|
7477
7557
|
}
|
|
@@ -7496,6 +7576,12 @@ async function locateSections(sections, briefPaths, sources, treeOf) {
|
|
|
7496
7576
|
return { placed, misses };
|
|
7497
7577
|
}
|
|
7498
7578
|
var groupOf = (path) => path.split(/[.[]/)[0] ?? "";
|
|
7579
|
+
var inSection = (section, path) => {
|
|
7580
|
+
if (groupOf(path) === section.groupKey) return true;
|
|
7581
|
+
const rowless = (value) => value.replace(/\[\d+\]/g, "[]");
|
|
7582
|
+
const target = rowless(path);
|
|
7583
|
+
return fieldPaths(section).some((fieldPath) => rowless(fieldPath) === target);
|
|
7584
|
+
};
|
|
7499
7585
|
var fieldPaths = (section) => (section.fields ?? []).map((field) => field.path ?? `${section.groupKey}.${field.key ?? ""}`);
|
|
7500
7586
|
function elementIndex(roots) {
|
|
7501
7587
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -7598,6 +7684,9 @@ function componentFile(dialect, path, fromFile, content, parsed, resolved, pathP
|
|
|
7598
7684
|
...addresses.opaque
|
|
7599
7685
|
];
|
|
7600
7686
|
if (unconvertible.length > 0) return { content: "", free: [], duplicates: [], unconvertible };
|
|
7687
|
+
const flat3 = pathPrefix !== "" && !pathPrefix.endsWith(".");
|
|
7688
|
+
const pathMap = flat3 ? flatPathMap(resolved.section, pathPrefix) : null;
|
|
7689
|
+
if (flat3 && !pathMap) return { content: "", free: [], duplicates: [], unconvertible: [`${pathPrefix}* (a repeater leaf without an override address)`] };
|
|
7601
7690
|
const cut = content.slice(resolved.root.start, resolved.root.end);
|
|
7602
7691
|
const reserved = /* @__PURE__ */ new Set([...topLevelBindings(dialect, parsed, content), ...referencedNames2(cut)]);
|
|
7603
7692
|
const introduced = allocateNames(reserved, [
|
|
@@ -7616,7 +7705,7 @@ function componentFile(dialect, path, fromFile, content, parsed, resolved, pathP
|
|
|
7616
7705
|
const helpers = [
|
|
7617
7706
|
.../* @__PURE__ */ new Set([
|
|
7618
7707
|
...helperNames.map((h) => alias(h.name, h.local)),
|
|
7619
|
-
"bcmsSection",
|
|
7708
|
+
flat3 ? "bcmsSectionPaths" : "bcmsSection",
|
|
7620
7709
|
...bound > 0 ? [alias("bcmsFields", fieldsName)] : []
|
|
7621
7710
|
])
|
|
7622
7711
|
].sort();
|
|
@@ -7646,9 +7735,10 @@ function componentFile(dialect, path, fromFile, content, parsed, resolved, pathP
|
|
|
7646
7735
|
const key = /^[A-Za-z_$][\w$]*$/.test(groupKey) ? groupKey : JSON.stringify(groupKey);
|
|
7647
7736
|
const carriedDeclarations = carry.declarations.length > 0 ? `${carry.declarations.join("\n")}
|
|
7648
7737
|
` : "";
|
|
7649
|
-
const copy = snapshot ? `const ${snapshot} = { ${key}: bcmsSection(page, bind, overrides) }
|
|
7650
|
-
const field = bound > 0 ? `const ${fieldName} = ${fieldsName}({ blockId, bind, overrides }, ${JSON.stringify(pathPrefix)});` : "";
|
|
7738
|
+
const copy = !snapshot ? "" : flat3 ? `const ${snapshot} = bcmsSectionPaths(page, bind, overrides, ${JSON.stringify(pathPrefix)}, ${JSON.stringify(pathMap)});` : `const ${snapshot} = { ${key}: bcmsSection(page, bind, overrides) };`;
|
|
7739
|
+
const field = bound > 0 ? `const ${fieldName} = ${fieldsName}({ blockId, bind, overrides }, ${JSON.stringify(pathPrefix)}${flat3 ? `, ${JSON.stringify(pathMap)}` : ""});` : "";
|
|
7651
7740
|
const declared = [copy, field].filter(Boolean).join("\n");
|
|
7741
|
+
const styles = dialect === "astro" ? carriedStyles(content) : "";
|
|
7652
7742
|
if (dialect === "astro") {
|
|
7653
7743
|
return { free: [], duplicates: [], unconvertible: [], content: `---
|
|
7654
7744
|
${SECTION_MARKER}
|
|
@@ -7668,7 +7758,9 @@ const { blockId, bind, overrides, page } = Astro.props;
|
|
|
7668
7758
|
${carriedDeclarations}${declared}
|
|
7669
7759
|
---
|
|
7670
7760
|
${markup}
|
|
7671
|
-
`
|
|
7761
|
+
${styles ? `
|
|
7762
|
+
${styles}
|
|
7763
|
+
` : ""}` };
|
|
7672
7764
|
}
|
|
7673
7765
|
return { free: [], duplicates: [], unconvertible: [], content: `${SECTION_MARKER}
|
|
7674
7766
|
${[...carried, `import { ${helpers.join(", ")} } from "${helperSpecifier}";`, `import type { BcmsSectionProps } from "${relativeImport(path, SECTIONS_LIB).replace(/\.tsx?$/, "")}";`].join("\n")}
|
|
@@ -7942,6 +8034,9 @@ import { bcmsFields } from "${helper}";`);
|
|
|
7942
8034
|
return { files, refused };
|
|
7943
8035
|
}
|
|
7944
8036
|
function propPrefix(section) {
|
|
8037
|
+
return exactPrefix(section) ?? flatPrefix(section);
|
|
8038
|
+
}
|
|
8039
|
+
function exactPrefix(section) {
|
|
7945
8040
|
const prefixes = /* @__PURE__ */ new Set();
|
|
7946
8041
|
for (const field of section.fields ?? []) {
|
|
7947
8042
|
const { path, key } = field;
|
|
@@ -7952,6 +8047,49 @@ function propPrefix(section) {
|
|
|
7952
8047
|
if (prefixes.size > 1) return null;
|
|
7953
8048
|
return prefixes.size === 1 ? [...prefixes][0] : `${section.groupKey}.`;
|
|
7954
8049
|
}
|
|
8050
|
+
var foldKey = (remainder) => remainder.replace(/\[(\d+)\]/g, "_$1").replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "value";
|
|
8051
|
+
function flatPrefix(section) {
|
|
8052
|
+
const prefixes = /* @__PURE__ */ new Set();
|
|
8053
|
+
let informative = false;
|
|
8054
|
+
for (const field of section.fields ?? []) {
|
|
8055
|
+
const { path, key } = field;
|
|
8056
|
+
if (typeof path !== "string" || typeof key !== "string") continue;
|
|
8057
|
+
informative = true;
|
|
8058
|
+
const prefix = ["-", "_"].map((sep2) => `${section.groupKey}${sep2}`).find((candidate) => path.startsWith(candidate) && (typeof field.overrideKey === "string" || foldKey(path.slice(candidate.length)) === key));
|
|
8059
|
+
if (!prefix) return null;
|
|
8060
|
+
prefixes.add(prefix);
|
|
8061
|
+
}
|
|
8062
|
+
return informative && prefixes.size === 1 ? [...prefixes][0] : null;
|
|
8063
|
+
}
|
|
8064
|
+
function flatPathMap(section, prefix) {
|
|
8065
|
+
const scalars = {};
|
|
8066
|
+
const tables = {};
|
|
8067
|
+
for (const field of section.fields ?? []) {
|
|
8068
|
+
const { path, key } = field;
|
|
8069
|
+
if (typeof path !== "string" || typeof key !== "string" || !path.startsWith(prefix)) continue;
|
|
8070
|
+
const row = /^([^[]+)\[\d+\]\.(.+)$/.exec(path);
|
|
8071
|
+
if (!row) {
|
|
8072
|
+
scalars[path] = field.overrideKey ?? key;
|
|
8073
|
+
continue;
|
|
8074
|
+
}
|
|
8075
|
+
const address = typeof field.overrideKey === "string" ? /^([^[]+)\[\d+\]\.(.+)$/.exec(field.overrideKey) : null;
|
|
8076
|
+
if (!address) return null;
|
|
8077
|
+
const table = tables[row[1]] ??= { key: address[1], columns: {} };
|
|
8078
|
+
if (table.key !== address[1]) return null;
|
|
8079
|
+
table.columns[row[2]] = address[2];
|
|
8080
|
+
}
|
|
8081
|
+
return { scalars, tables };
|
|
8082
|
+
}
|
|
8083
|
+
function carriedStyles(content) {
|
|
8084
|
+
const blocks = [];
|
|
8085
|
+
for (const match of content.matchAll(/<style\b([^>]*)>([\s\S]*?)<\/style>/g)) {
|
|
8086
|
+
const attributes = match[1] ?? "";
|
|
8087
|
+
if (/\bis:global\b|\bdefine:vars\b/.test(attributes)) continue;
|
|
8088
|
+
if (/\blang\s*=/.test(attributes) || /@(import|use|forward)\b/.test(match[2] ?? "")) continue;
|
|
8089
|
+
blocks.push(match[0]);
|
|
8090
|
+
}
|
|
8091
|
+
return blocks.join("\n");
|
|
8092
|
+
}
|
|
7955
8093
|
function referencedNames2(markup) {
|
|
7956
8094
|
const out = /* @__PURE__ */ new Set();
|
|
7957
8095
|
for (const [name] of markup.matchAll(/[A-Za-z_$][\w$]*/g)) out.add(name);
|
|
@@ -9288,7 +9426,7 @@ function emitStubs2(dialects, slugs, contents, out) {
|
|
|
9288
9426
|
// package.json
|
|
9289
9427
|
var package_default = {
|
|
9290
9428
|
name: "@bettercms-ai/convert",
|
|
9291
|
-
version: "0.
|
|
9429
|
+
version: "0.11.0",
|
|
9292
9430
|
type: "module",
|
|
9293
9431
|
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.",
|
|
9294
9432
|
bin: {
|