@bettercms-ai/convert 0.25.1 → 0.26.1
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 +14 -0
- package/dist/cli.js +105 -26
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +103 -24
- 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.26.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c83b686: The codemod routes an image through `bcmsImage` where a call site already declares its field in `bcmsBindings` and still passes the raw import (the element was stamped, and the page kept rendering the file its code imports), and names an image's asset from an optimizer url (`/_image?href=…`). The components skill gains "Read a published value where the app renders the page".
|
|
8
|
+
- Updated dependencies [1a52ee6]
|
|
9
|
+
- @bettercms-ai/types@1.36.0
|
|
10
|
+
|
|
11
|
+
## 0.26.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 69dfcfa: A server app hosted on BetterCMS shows a publish on its very next request: the converted-site helper (v14) and `readPublishedContent` ask the content file's time on every read instead of once a second. Helper v14 also renders an image an editor replaced on a page the app renders per request: `bcmsImage` returns the local copy BetterCMS puts beside the app, in the shape of an import, where it used to keep the build's picture. A site built with an older helper gets v14 on its next BetterCMS build, with no commit.
|
|
16
|
+
|
|
3
17
|
## 0.25.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/cli.js
CHANGED
|
@@ -4090,6 +4090,13 @@ var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".avif", ".gif", ".svg
|
|
|
4090
4090
|
var ASSET_COMPONENTS = /* @__PURE__ */ new Set(["Image", "Picture"]);
|
|
4091
4091
|
var ASSET_MODULE = "astro:assets";
|
|
4092
4092
|
function baseName(url) {
|
|
4093
|
+
const inner = /[?&](?:href|url)=([^&#]+)/.exec(url)?.[1];
|
|
4094
|
+
if (inner) {
|
|
4095
|
+
try {
|
|
4096
|
+
url = decodeURIComponent(inner);
|
|
4097
|
+
} catch {
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
4093
4100
|
const file = url.split(/[?#]/)[0].split("/").pop() ?? "";
|
|
4094
4101
|
const base = file.split(".")[0] ?? "";
|
|
4095
4102
|
return base === "" ? null : base.toLowerCase();
|
|
@@ -4115,6 +4122,29 @@ function passedTo(content, parsed, binding) {
|
|
|
4115
4122
|
for (const root of parsed.roots) visit(root);
|
|
4116
4123
|
return out;
|
|
4117
4124
|
}
|
|
4125
|
+
function declaredAt(content, parsed, binding, path) {
|
|
4126
|
+
const out = [];
|
|
4127
|
+
const names = [`"${path}"`, `'${path}'`];
|
|
4128
|
+
const visit = (node) => {
|
|
4129
|
+
if (node.type === "expr") {
|
|
4130
|
+
for (const child of node.children) visit(child);
|
|
4131
|
+
return;
|
|
4132
|
+
}
|
|
4133
|
+
if (node.type !== "element" || node.raw) return;
|
|
4134
|
+
const bindings = node.attrs.find((a) => a.name === "bcmsBindings");
|
|
4135
|
+
const declared = bindings?.expressionRange ? content.slice(bindings.expressionRange.start, bindings.expressionRange.end) : "";
|
|
4136
|
+
if (/^[A-Z]/.test(node.tag) && !ASSET_COMPONENTS.has(node.tag) && names.some((name) => declared.includes(name))) {
|
|
4137
|
+
for (const attr of node.attrs) {
|
|
4138
|
+
if (!attr.expressionRange) continue;
|
|
4139
|
+
const inner = content.slice(attr.expressionRange.start, attr.expressionRange.end).replace(/^\{|\}$/g, "").trim();
|
|
4140
|
+
if (inner === binding) out.push({ node, prop: attr.name, attr });
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
for (const child of node.children) visit(child);
|
|
4144
|
+
};
|
|
4145
|
+
for (const root of parsed.roots) visit(root);
|
|
4146
|
+
return out;
|
|
4147
|
+
}
|
|
4118
4148
|
function assetCandidates(parsed, dialect, original) {
|
|
4119
4149
|
const wanted = baseName(original);
|
|
4120
4150
|
if (wanted === null || parsed.error) return [];
|
|
@@ -4162,6 +4192,18 @@ async function bindImages(ctx, targets) {
|
|
|
4162
4192
|
const rendered = binding === null ? [] : renderedBy(ctx.content, ctx.parsed, ctx.dialect, binding);
|
|
4163
4193
|
const free = rendered.filter((hit2) => !claimed.has(hit2.node.attrInsertAt));
|
|
4164
4194
|
const args = (b) => [ctx.snapshotName(target.slug), JSON.stringify(target.path), b, ...ctx.slug ? [ctx.slug] : []];
|
|
4195
|
+
if (free.length === 0 && binding !== null) {
|
|
4196
|
+
const declared = declaredAt(ctx.content, ctx.parsed, binding, target.path).filter((c) => !claimed.has(c.attr.range.start));
|
|
4197
|
+
if (declared.length === 1) {
|
|
4198
|
+
const call = declared[0];
|
|
4199
|
+
claimed.add(call.attr.range.start);
|
|
4200
|
+
out.splices.push({ start: call.attr.range.start, end: call.attr.range.end, text: rule.attr(call.prop, `${ctx.image}(${args(binding).join(", ")})`) });
|
|
4201
|
+
out.slugs.push(target.slug);
|
|
4202
|
+
out.bound.push(target.key);
|
|
4203
|
+
continue;
|
|
4204
|
+
}
|
|
4205
|
+
}
|
|
4206
|
+
if (target.declared) continue;
|
|
4165
4207
|
if (free.length === 0 && binding !== null && ctx.drill) {
|
|
4166
4208
|
const calls = passedTo(ctx.content, ctx.parsed, binding).filter((c) => !claimed.has(c.node.attrInsertAt));
|
|
4167
4209
|
const call = calls.length === 1 ? calls[0] : null;
|
|
@@ -4203,7 +4245,7 @@ async function bindImages(ctx, targets) {
|
|
|
4203
4245
|
|
|
4204
4246
|
// src/helper.ts
|
|
4205
4247
|
import { createHash as createHash2 } from "crypto";
|
|
4206
|
-
var HELPER_VERSION =
|
|
4248
|
+
var HELPER_VERSION = 14;
|
|
4207
4249
|
var HEADER = "// @bettercms-ai/convert helper v";
|
|
4208
4250
|
var HELPER_PATH = Object.fromEntries(
|
|
4209
4251
|
Object.keys(DIALECT_RULES).map((d) => [d, DIALECT_RULES[d].helper])
|
|
@@ -4277,11 +4319,11 @@ function render(value: unknown): string | undefined {
|
|
|
4277
4319
|
*
|
|
4278
4320
|
* Nowhere else does anything change: with no variable (a build, \`astro dev\`, a browser, an edge
|
|
4279
4321
|
* runtime) every snapshot is the one the bundle imported, exactly as before. A file that cannot be
|
|
4280
|
-
* read keeps the last good copy
|
|
4322
|
+
* read keeps the last good copy. Its modification time is asked on EVERY read (a stat, microseconds;
|
|
4323
|
+
* the file is parsed again only when it changed), so a publish shows on the very next request.
|
|
4281
4324
|
*/
|
|
4282
|
-
type BcmsLiveContent = { stamp: number; bySlug: Map<string, unknown>; layout: unknown };
|
|
4325
|
+
type BcmsLiveContent = { helper: string; stamp: number; bySlug: Map<string, unknown>; entries: Record<string, unknown>; layout: unknown };
|
|
4283
4326
|
let bcmsLive: BcmsLiveContent | null = null;
|
|
4284
|
-
let bcmsLiveCheckedAt = 0;
|
|
4285
4327
|
|
|
4286
4328
|
function liveContent(): BcmsLiveContent | null {
|
|
4287
4329
|
const proc = (globalThis as {
|
|
@@ -4289,9 +4331,6 @@ function liveContent(): BcmsLiveContent | null {
|
|
|
4289
4331
|
}).process;
|
|
4290
4332
|
const file = proc?.env?.BCMS_CONTENT_FILE;
|
|
4291
4333
|
if (!file || typeof proc?.getBuiltinModule !== "function") return null;
|
|
4292
|
-
const now = Date.now();
|
|
4293
|
-
if (now - bcmsLiveCheckedAt < 1000) return bcmsLive;
|
|
4294
|
-
bcmsLiveCheckedAt = now;
|
|
4295
4334
|
try {
|
|
4296
4335
|
const fs = proc.getBuiltinModule("node:fs") as {
|
|
4297
4336
|
statSync(path: string): { mtimeMs: number };
|
|
@@ -4305,13 +4344,30 @@ function liveContent(): BcmsLiveContent | null {
|
|
|
4305
4344
|
for (const rows of Object.values(collections)) {
|
|
4306
4345
|
if (!Array.isArray(rows)) continue;
|
|
4307
4346
|
for (const row of rows) {
|
|
4308
|
-
|
|
4347
|
+
// A published row carries its values under \`data\` (the delivery API's shape); the snapshot a
|
|
4348
|
+
// template reads is the values themselves. Read flat, as before, where a row has none.
|
|
4349
|
+
if (isRecord(row) && typeof row.slug === "string" && !bySlug.has(row.slug)) {
|
|
4350
|
+
bySlug.set(row.slug, isRecord(row.data) ? { ...row.data, slug: row.slug } : row);
|
|
4351
|
+
}
|
|
4309
4352
|
}
|
|
4310
4353
|
}
|
|
4354
|
+
// A dynamic route reads \`page.entries[slug]\`: every published row, by its slug.
|
|
4355
|
+
const entries: Record<string, unknown> = Object.fromEntries(bySlug);
|
|
4356
|
+
for (const row of bySlug.values()) if (isRecord(row) && !("entries" in row)) row.entries = entries;
|
|
4311
4357
|
const pages = isRecord(snapshot) && Array.isArray(snapshot.pages) ? snapshot.pages : [];
|
|
4312
4358
|
const withLayout = pages.find((page: unknown) => isRecord(page) && isRecord(page.layout));
|
|
4313
|
-
|
|
4314
|
-
|
|
4359
|
+
// The site's Layout first; a page's own (its overrides resolved in) only where there is no other.
|
|
4360
|
+
const delivered = isRecord(snapshot) && isRecord(snapshot.layout) ? snapshot.layout : isRecord(withLayout) ? withLayout.layout : undefined;
|
|
4361
|
+
// A template addresses a Layout value as \`<section id>:<field id>\`; the published Layout holds
|
|
4362
|
+
// each Section's values under \`sections.<slug>.fields\`. Both spellings are answered.
|
|
4363
|
+
const layout: Record<string, unknown> | undefined = isRecord(delivered) ? { ...delivered } : undefined;
|
|
4364
|
+
for (const section of layout && isRecord(delivered) && isRecord(delivered.sections) ? Object.values(delivered.sections) : []) {
|
|
4365
|
+
if (!isRecord(section) || typeof section.id !== "string" || !isRecord(section.fields)) continue;
|
|
4366
|
+
for (const [field, value] of Object.entries(section.fields)) layout![section.id + ":" + field] = value;
|
|
4367
|
+
}
|
|
4368
|
+
// \`helper\` names this reader in the built bundle: the platform reads it to know the app shows a
|
|
4369
|
+
// publish on its next request, and an image BetterCMS copied beside it (@see bcmsImage).
|
|
4370
|
+
bcmsLive = { helper: "bcms-helper@${HELPER_VERSION}", stamp, bySlug, entries, layout };
|
|
4315
4371
|
} catch {
|
|
4316
4372
|
// Unreadable, or caught mid-write: keep serving the last good copy.
|
|
4317
4373
|
}
|
|
@@ -4323,7 +4379,10 @@ function live(page: unknown): unknown {
|
|
|
4323
4379
|
const content = liveContent();
|
|
4324
4380
|
if (!content) return page;
|
|
4325
4381
|
if (page === layoutSnapshot) return isRecord(content.layout) ? content.layout : page;
|
|
4326
|
-
if (isRecord(page) && typeof page.slug === "string")
|
|
4382
|
+
if (isRecord(page) && typeof page.slug === "string") {
|
|
4383
|
+
// A collection's page has no row of its own: its entries are the published ones all the same.
|
|
4384
|
+
return content.bySlug.get(page.slug) ?? ("entries" in page ? page : { ...page, entries: content.entries });
|
|
4385
|
+
}
|
|
4327
4386
|
return page;
|
|
4328
4387
|
}
|
|
4329
4388
|
|
|
@@ -4337,7 +4396,10 @@ export function bcms(page: unknown, path: string, fallback: string, slug?: strin
|
|
|
4337
4396
|
|
|
4338
4397
|
/** One field of the shared layout \u2014 the header and footer every route renders. */
|
|
4339
4398
|
export function bcmsLayout(path: string, fallback: string): string {
|
|
4340
|
-
|
|
4399
|
+
const layout = live(layoutSnapshot);
|
|
4400
|
+
// The whole address first: a field id may carry a dot of its own (\`derived.nav-cta\`).
|
|
4401
|
+
const whole = isRecord(layout) ? layout[path] : undefined;
|
|
4402
|
+
return render(whole !== undefined ? whole : readPath(layout, path)) ?? fallback;
|
|
4341
4403
|
}
|
|
4342
4404
|
|
|
4343
4405
|
/**
|
|
@@ -4414,13 +4476,24 @@ export function bcmsTuples(page: unknown, paths: string[][], fallback: string[][
|
|
|
4414
4476
|
* release write (\`writeImage\`) puts the editor's image on the \`data-bcms-field\` element, which
|
|
4415
4477
|
* is where every published value lands. A plain string fallback (\`<img src="/hero.png">\`) has
|
|
4416
4478
|
* no such rule and takes the CMS url directly.
|
|
4479
|
+
*
|
|
4480
|
+
* \u{1F534} ON A HOSTED SERVER THE EDITOR'S IMAGE IS A LOCAL FILE. A page the app renders per request has no
|
|
4481
|
+
* release write: what this returns is the page. BetterCMS copies a replaced image beside the app and
|
|
4482
|
+
* names the copy on the published value (\`local\`, with its size), and it is returned in the shape
|
|
4483
|
+
* of an import (\`{ src, width, height, format }\`), so \`<Image>\` optimises it like the site's own.
|
|
4484
|
+
* Absent (a build, or the site's own picture) the import stands.
|
|
4417
4485
|
*/
|
|
4418
4486
|
export function bcmsImage<T>(page: unknown, path: string, fallback: T, slug?: string): T | string {
|
|
4419
4487
|
page = live(page);
|
|
4420
|
-
if (fallback !== null && typeof fallback === "object") return fallback;
|
|
4421
4488
|
const entries = isRecord(page) ? page.entries : undefined;
|
|
4422
4489
|
const root = slug !== undefined && isRecord(entries) ? entries[slug] : page;
|
|
4423
|
-
|
|
4490
|
+
const value = readPath(root, path);
|
|
4491
|
+
if (fallback !== null && typeof fallback === "object") {
|
|
4492
|
+
if (!isRecord(value) || typeof value.local !== "string" || typeof value.width !== "number" || typeof value.height !== "number") return fallback;
|
|
4493
|
+
const format = /\\.([a-z0-9]+)$/i.exec(value.local)?.[1]?.toLowerCase() ?? "";
|
|
4494
|
+
return { src: value.local, width: value.width, height: value.height, format: format === "jpg" ? "jpeg" : format } as unknown as T;
|
|
4495
|
+
}
|
|
4496
|
+
return render(value) ?? fallback;
|
|
4424
4497
|
}
|
|
4425
4498
|
|
|
4426
4499
|
/**
|
|
@@ -4753,7 +4826,8 @@ var HISTORICAL = {
|
|
|
4753
4826
|
9: "d6441db2ff4578c3c5d4b7d461f3374b89247ef6ba9e0d535791e840d803e4f3",
|
|
4754
4827
|
10: "ffcb59862972b15a67c5951e9f3b94ce5b8b50345e6aac2bfa5789cfc3136910",
|
|
4755
4828
|
11: "ceb2a932d4c2761a5045ff35032e0b45130a0b5034547ff37579c72c9ce3594e",
|
|
4756
|
-
12: "10f71724484c84af12aa3eb90db44bf6acbf71fcf8ddff5b6361c1190ba16528"
|
|
4829
|
+
12: "10f71724484c84af12aa3eb90db44bf6acbf71fcf8ddff5b6361c1190ba16528",
|
|
4830
|
+
13: "cd8bdd74dbc944f2331503bdf8e995cb7f74f0d5b307d08aee4690e1695ae798"
|
|
4757
4831
|
},
|
|
4758
4832
|
"src/lib/bcms-content.ts": {
|
|
4759
4833
|
1: "ae72ae14d706943d481c880d70da5789b4816ba1ba319a10fbc63ded4d0b42f2",
|
|
@@ -4767,7 +4841,8 @@ var HISTORICAL = {
|
|
|
4767
4841
|
9: "eee9fb1635ae7d6f8f33676a1f390600ca24a62ee992775252273c73a011c494",
|
|
4768
4842
|
10: "35bb7c0e30f5c41fe68e52259ec4764de6de2734064fa0e1521f3338eef0a09e",
|
|
4769
4843
|
11: "818784f2088150d64d91b42eac944dc9503f104d32a0e7a18c753d2982a5adc0",
|
|
4770
|
-
12: "79dafc525a541feae55ada5dbe2ea966cac82acd741a4b41d61fe9e0cdfaa208"
|
|
4844
|
+
12: "79dafc525a541feae55ada5dbe2ea966cac82acd741a4b41d61fe9e0cdfaa208",
|
|
4845
|
+
13: "06ee70c9f0bb25e03f3930d2250da8dae172ade457f27ebba20382b6482ad3f4"
|
|
4771
4846
|
},
|
|
4772
4847
|
"composables/bcms-content.ts": {
|
|
4773
4848
|
1: "c272412532efed7db64b6cf313b2bed4291f9951430412289c8a588b7f565407",
|
|
@@ -4781,7 +4856,8 @@ var HISTORICAL = {
|
|
|
4781
4856
|
9: "d6441db2ff4578c3c5d4b7d461f3374b89247ef6ba9e0d535791e840d803e4f3",
|
|
4782
4857
|
10: "ffcb59862972b15a67c5951e9f3b94ce5b8b50345e6aac2bfa5789cfc3136910",
|
|
4783
4858
|
11: "ceb2a932d4c2761a5045ff35032e0b45130a0b5034547ff37579c72c9ce3594e",
|
|
4784
|
-
12: "10f71724484c84af12aa3eb90db44bf6acbf71fcf8ddff5b6361c1190ba16528"
|
|
4859
|
+
12: "10f71724484c84af12aa3eb90db44bf6acbf71fcf8ddff5b6361c1190ba16528",
|
|
4860
|
+
13: "cd8bdd74dbc944f2331503bdf8e995cb7f74f0d5b307d08aee4690e1695ae798"
|
|
4785
4861
|
}
|
|
4786
4862
|
};
|
|
4787
4863
|
var sha256 = (value) => createHash2("sha256").update(value, "utf8").digest("hex");
|
|
@@ -10150,10 +10226,13 @@ async function convertSources(briefIn, sources, options) {
|
|
|
10150
10226
|
async function convertFile(file, content, targets, parsed, declared, llmFallback, drill) {
|
|
10151
10227
|
const outcomes = /* @__PURE__ */ new Map();
|
|
10152
10228
|
const pendingTargets = [];
|
|
10229
|
+
let unreadImages = false;
|
|
10153
10230
|
const dialect = dialectOf(file, content);
|
|
10154
10231
|
for (const target of targets) {
|
|
10155
10232
|
if (parsed && dialect && convertedHere(content, parsed, dialect, target, file)) {
|
|
10156
10233
|
outcomes.set(target.key, "declared");
|
|
10234
|
+
if (target.kind === "image" && !content.includes("bcmsImage(")) unreadImages = true;
|
|
10235
|
+
else if (target.kind === "image" && !new RegExp(`bcmsImage\\([^)]*["']${target.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}["']`).test(content)) unreadImages = true;
|
|
10157
10236
|
} else pendingTargets.push(target);
|
|
10158
10237
|
}
|
|
10159
10238
|
const empty = {
|
|
@@ -10168,7 +10247,7 @@ async function convertFile(file, content, targets, parsed, declared, llmFallback
|
|
|
10168
10247
|
snapshots: [],
|
|
10169
10248
|
notes: []
|
|
10170
10249
|
};
|
|
10171
|
-
if (pendingTargets.length === 0) return empty;
|
|
10250
|
+
if (pendingTargets.length === 0 && !unreadImages) return empty;
|
|
10172
10251
|
if (!dialect) {
|
|
10173
10252
|
if (isTolerantDialect(file)) {
|
|
10174
10253
|
const already = declaredByScan(content);
|
|
@@ -10369,15 +10448,15 @@ async function plan(file, content, dialect, targets, sites, importAt, outcomes,
|
|
|
10369
10448
|
continue;
|
|
10370
10449
|
}
|
|
10371
10450
|
const declares = (d) => d.scope === target.scope && (d.path === target.path || d.path === shapeOfPath(target.path));
|
|
10372
|
-
const
|
|
10451
|
+
const declaredAt2 = new Set(declarations.filter(declares).map((d) => d.at));
|
|
10373
10452
|
const claimedAt = new Set(declarations.filter((d) => !declares(d) && d.via === "field").map((d) => d.at));
|
|
10374
10453
|
const writesField = (site) => site.where !== "attr" || target.kind === "image";
|
|
10375
10454
|
const fresh = eligible.filter(
|
|
10376
|
-
(site) => !
|
|
10455
|
+
(site) => !declaredAt2.has(site.attrInsertAt) && !(writesField(site) && claimedAt.has(site.attrInsertAt))
|
|
10377
10456
|
);
|
|
10378
10457
|
located += eligible.length;
|
|
10379
10458
|
const blocked = eligible.filter(
|
|
10380
|
-
(site) => !
|
|
10459
|
+
(site) => !declaredAt2.has(site.attrInsertAt) && writesField(site) && claimedAt.has(site.attrInsertAt)
|
|
10381
10460
|
);
|
|
10382
10461
|
if (blocked.length > 0) {
|
|
10383
10462
|
outcomes.set(target.key, "AMBIGUOUS_LITERAL");
|
|
@@ -10386,7 +10465,7 @@ async function plan(file, content, dialect, targets, sites, importAt, outcomes,
|
|
|
10386
10465
|
if (fresh.length === 0) {
|
|
10387
10466
|
outcomes.set(
|
|
10388
10467
|
target.key,
|
|
10389
|
-
eligible.some((site) =>
|
|
10468
|
+
eligible.some((site) => declaredAt2.has(site.attrInsertAt)) ? "declared" : "AMBIGUOUS_LITERAL"
|
|
10390
10469
|
);
|
|
10391
10470
|
continue;
|
|
10392
10471
|
}
|
|
@@ -10572,8 +10651,8 @@ async function plan(file, content, dialect, targets, sites, importAt, outcomes,
|
|
|
10572
10651
|
},
|
|
10573
10652
|
targets.filter((t) => {
|
|
10574
10653
|
const outcome = outcomes.get(t.key);
|
|
10575
|
-
return t.kind === "image" && t.scope === "page" && (outcome === void 0 || UNPLACED.has(outcome));
|
|
10576
|
-
}).map((t) => ({ key: t.key, path: t.path, kind: t.kind, original: t.fallback, slug: t.slug }))
|
|
10654
|
+
return t.kind === "image" && t.scope === "page" && (outcome === void 0 || outcome === "declared" || UNPLACED.has(outcome));
|
|
10655
|
+
}).map((t) => ({ key: t.key, path: t.path, kind: t.kind, original: t.fallback, slug: t.slug, declared: outcomes.get(t.key) === "declared" }))
|
|
10577
10656
|
);
|
|
10578
10657
|
for (const key of images.bound) outcomes.set(key, "rewritten");
|
|
10579
10658
|
for (const refusal of images.refused) outcomes.set(refusal.key, refusal.reason);
|
|
@@ -10863,7 +10942,7 @@ function styleEdits(before, after) {
|
|
|
10863
10942
|
// package.json
|
|
10864
10943
|
var package_default = {
|
|
10865
10944
|
name: "@bettercms-ai/convert",
|
|
10866
|
-
version: "0.
|
|
10945
|
+
version: "0.26.1",
|
|
10867
10946
|
type: "module",
|
|
10868
10947
|
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.",
|
|
10869
10948
|
bin: {
|
|
@@ -10896,7 +10975,7 @@ var package_default = {
|
|
|
10896
10975
|
dependencies: {
|
|
10897
10976
|
"@astrojs/compiler": "^2.13.1",
|
|
10898
10977
|
"@babel/parser": "^7.29.2",
|
|
10899
|
-
"@bettercms-ai/types": "^1.
|
|
10978
|
+
"@bettercms-ai/types": "^1.36.0",
|
|
10900
10979
|
"@vue/compiler-sfc": "^3.5.0",
|
|
10901
10980
|
"magic-string": "^0.30.21",
|
|
10902
10981
|
parse5: "^7.3.0",
|