@bettercms-ai/convert 0.24.1 → 0.25.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 +10 -0
- package/dist/cli.js +74 -7
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +31 -1
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @bettercms-ai/convert
|
|
2
2
|
|
|
3
|
+
## 0.25.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 832e08a: A converted repository whose `build` runs checks before the build (`astro check && astro build`, `tsc --noEmit && vite build`, `npm run lint && next build`) gets a `build:bcms` script beside it with the same build minus those checks, `prebuild`/`postbuild` folded in. BetterCMS builds with `build:bcms` when a project declares one, so a deploy no longer pays for the project's CI checks; `build` is left unchanged. Every writing run adds it once (a repository that already has one is never touched), and only for a plain `&&` chain. Exported as `bcmsBuildScript`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- c6fd790: The codemod never walks into a directory holding its own `.git` (a git worktree, submodule or vendored clone), so a tool's worktree copy of the repo is no longer converted alongside the real source.
|
|
12
|
+
|
|
3
13
|
## 0.24.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { execFileSync } from "child_process";
|
|
5
|
+
import { existsSync } from "fs";
|
|
5
6
|
import { readdir, readFile, writeFile, mkdir, stat } from "fs/promises";
|
|
6
7
|
import { dirname, join as join2, relative, resolve, sep } from "path";
|
|
7
8
|
|
|
@@ -7664,6 +7665,54 @@ function moduleScope(parsed, content) {
|
|
|
7664
7665
|
return out;
|
|
7665
7666
|
}
|
|
7666
7667
|
|
|
7668
|
+
// src/build-script.ts
|
|
7669
|
+
var CHECK = /^(?:npx\s+|pnpm\s+(?:exec\s+)?|yarn\s+|bunx\s+)?(?:astro\s+check|svelte-check|vue-tsc|tsc(?:\s|$)|eslint|next\s+lint|biome\s+(?:check|lint|ci)|prettier\s+(?:--check|-c)\b|stylelint|oxlint)/;
|
|
7670
|
+
var RUN_CHECK = /^(?:npm\s+run|pnpm(?:\s+run)?|yarn(?:\s+run)?|bun\s+run)\s+(?:lint|typecheck|type-check|check|check:types|types|format:check|test)(?::[\w-]+)?\s*$/;
|
|
7671
|
+
var UNSAFE = /;|\|\||\||(?:^|[^&])&(?:[^&]|$)|\$\(|`|\n/;
|
|
7672
|
+
var isCheck = (step) => CHECK.test(step) || RUN_CHECK.test(step);
|
|
7673
|
+
function steps(script) {
|
|
7674
|
+
if (UNSAFE.test(script)) return null;
|
|
7675
|
+
const out = script.split("&&").map((s) => s.trim());
|
|
7676
|
+
return out.some((s) => s === "") ? null : out;
|
|
7677
|
+
}
|
|
7678
|
+
function bcmsBuildScript(packageJson) {
|
|
7679
|
+
let pkg;
|
|
7680
|
+
try {
|
|
7681
|
+
pkg = JSON.parse(packageJson);
|
|
7682
|
+
} catch {
|
|
7683
|
+
return null;
|
|
7684
|
+
}
|
|
7685
|
+
const scripts = pkg?.scripts;
|
|
7686
|
+
if (!scripts || typeof scripts !== "object" || "build:bcms" in scripts) return null;
|
|
7687
|
+
const build = scripts.build;
|
|
7688
|
+
if (typeof build !== "string") return null;
|
|
7689
|
+
const parts = [];
|
|
7690
|
+
for (const name of ["prebuild", "build", "postbuild"]) {
|
|
7691
|
+
const value = scripts[name];
|
|
7692
|
+
if (value === void 0) continue;
|
|
7693
|
+
if (typeof value !== "string") return null;
|
|
7694
|
+
const s = steps(value);
|
|
7695
|
+
if (!s) return null;
|
|
7696
|
+
parts.push(s);
|
|
7697
|
+
}
|
|
7698
|
+
const all = parts.flat();
|
|
7699
|
+
const dropped = all.filter(isCheck);
|
|
7700
|
+
const kept = all.filter((s) => !isCheck(s));
|
|
7701
|
+
if (dropped.length === 0 || kept.length === 0) return null;
|
|
7702
|
+
const script = kept.join(" && ");
|
|
7703
|
+
const next = {};
|
|
7704
|
+
for (const [key, value] of Object.entries(scripts)) {
|
|
7705
|
+
next[key] = value;
|
|
7706
|
+
if (key === "build") next["build:bcms"] = script;
|
|
7707
|
+
}
|
|
7708
|
+
const indent = /^[ \t]+(?=")/m.exec(packageJson)?.[0] ?? " ";
|
|
7709
|
+
const eol = packageJson.includes("\r\n") ? "\r\n" : "\n";
|
|
7710
|
+
let content = JSON.stringify({ ...pkg, scripts: next }, null, indent);
|
|
7711
|
+
if (eol !== "\n") content = content.replace(/\n/g, eol);
|
|
7712
|
+
if (/\r?\n$/.test(packageJson)) content += eol;
|
|
7713
|
+
return { content, script, dropped };
|
|
7714
|
+
}
|
|
7715
|
+
|
|
7667
7716
|
// src/componentize.ts
|
|
7668
7717
|
import MagicString5 from "magic-string";
|
|
7669
7718
|
var SectionInvariantError = class extends Error {
|
|
@@ -10784,7 +10833,7 @@ function styleEdits(before, after) {
|
|
|
10784
10833
|
// package.json
|
|
10785
10834
|
var package_default = {
|
|
10786
10835
|
name: "@bettercms-ai/convert",
|
|
10787
|
-
version: "0.
|
|
10836
|
+
version: "0.25.0",
|
|
10788
10837
|
type: "module",
|
|
10789
10838
|
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.",
|
|
10790
10839
|
bin: {
|
|
@@ -10961,7 +11010,7 @@ async function readTree(root, verbose) {
|
|
|
10961
11010
|
const full = join2(dir, entry.name);
|
|
10962
11011
|
const rel = relative(root, full).split(sep).join("/");
|
|
10963
11012
|
if (entry.isDirectory()) {
|
|
10964
|
-
if (isSourceCandidate(`${rel}/x.html`)) await walk(full);
|
|
11013
|
+
if (isSourceCandidate(`${rel}/x.html`) && !existsSync(join2(full, ".git"))) await walk(full);
|
|
10965
11014
|
continue;
|
|
10966
11015
|
}
|
|
10967
11016
|
if (!entry.isFile() || !isSourceCandidate(rel)) continue;
|
|
@@ -11142,6 +11191,21 @@ async function verifyStyles(root, base, verbose) {
|
|
|
11142
11191
|
);
|
|
11143
11192
|
return 1;
|
|
11144
11193
|
}
|
|
11194
|
+
async function addBcmsBuild(root, dryRun) {
|
|
11195
|
+
let packageJson;
|
|
11196
|
+
try {
|
|
11197
|
+
packageJson = await readFile(join2(root, "package.json"), "utf-8");
|
|
11198
|
+
} catch {
|
|
11199
|
+
return;
|
|
11200
|
+
}
|
|
11201
|
+
const added = bcmsBuildScript(packageJson);
|
|
11202
|
+
if (!added) return;
|
|
11203
|
+
if (!dryRun) await writeFile(join2(root, "package.json"), added.content, "utf-8");
|
|
11204
|
+
process.stderr.write(
|
|
11205
|
+
`package.json: ${dryRun ? "would add" : "added"} "build:bcms": "${added.script}" \u2014 BetterCMS builds with it, without ${added.dropped.join(", ")}; "build" is unchanged.
|
|
11206
|
+
`
|
|
11207
|
+
);
|
|
11208
|
+
}
|
|
11145
11209
|
async function main() {
|
|
11146
11210
|
const args = parseArgs(process.argv.slice(2));
|
|
11147
11211
|
if (args.help) {
|
|
@@ -11173,6 +11237,7 @@ async function main() {
|
|
|
11173
11237
|
await writeFile(target, file.content, "utf-8");
|
|
11174
11238
|
}
|
|
11175
11239
|
}
|
|
11240
|
+
await addBcmsBuild(root2, args.dryRun);
|
|
11176
11241
|
if (args.receipt) await writeFile(resolve(args.receipt), `${JSON.stringify(receipt2, null, 2)}
|
|
11177
11242
|
`, "utf-8");
|
|
11178
11243
|
reportUpgrade(files2, receipt2, args.dryRun);
|
|
@@ -11200,12 +11265,14 @@ async function main() {
|
|
|
11200
11265
|
if (args.verbose) process.stderr.write(`read ${sources.length} candidate files under ${root}
|
|
11201
11266
|
`);
|
|
11202
11267
|
const written = async (files2) => {
|
|
11203
|
-
if (args.dryRun)
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11268
|
+
if (!args.dryRun) {
|
|
11269
|
+
for (const file of files2) {
|
|
11270
|
+
const target = under(root, file.path);
|
|
11271
|
+
await mkdir(dirname(target), { recursive: true });
|
|
11272
|
+
await writeFile(target, file.content, "utf-8");
|
|
11273
|
+
}
|
|
11208
11274
|
}
|
|
11275
|
+
await addBcmsBuild(root, args.dryRun);
|
|
11209
11276
|
};
|
|
11210
11277
|
const saveReceipt = async (receipt2) => {
|
|
11211
11278
|
if (!args.receipt) return;
|