@reddoorla/maintenance 0.8.0 → 0.9.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/README.md +1 -1
- package/dist/cli/bin.js +120 -80
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +65 -25
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/index.js +108 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -335,9 +335,9 @@ async function securityAudit(ctx) {
|
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
// src/audits/lighthouse.ts
|
|
338
|
-
import { readFile as
|
|
338
|
+
import { readFile as readFile4, writeFile, mkdtemp, rm } from "fs/promises";
|
|
339
339
|
import { tmpdir } from "os";
|
|
340
|
-
import { join as
|
|
340
|
+
import { join as join4 } from "path";
|
|
341
341
|
|
|
342
342
|
// src/configs/lighthouse.ts
|
|
343
343
|
var lighthouseConfig = {
|
|
@@ -370,10 +370,37 @@ var lighthouseConfig = {
|
|
|
370
370
|
}
|
|
371
371
|
};
|
|
372
372
|
|
|
373
|
+
// src/audits/util/site-config.ts
|
|
374
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
375
|
+
import { join as join3 } from "path";
|
|
376
|
+
async function readSiteConfig(sitePath) {
|
|
377
|
+
let raw;
|
|
378
|
+
try {
|
|
379
|
+
raw = await readFile3(join3(sitePath, "package.json"), "utf-8");
|
|
380
|
+
} catch {
|
|
381
|
+
return {};
|
|
382
|
+
}
|
|
383
|
+
let pkg;
|
|
384
|
+
try {
|
|
385
|
+
pkg = JSON.parse(raw);
|
|
386
|
+
} catch {
|
|
387
|
+
return {};
|
|
388
|
+
}
|
|
389
|
+
if (!pkg || typeof pkg !== "object") return {};
|
|
390
|
+
const cfg = pkg.reddoor;
|
|
391
|
+
if (!cfg || typeof cfg !== "object") return {};
|
|
392
|
+
const out = {};
|
|
393
|
+
const url = cfg.lighthouseUrl;
|
|
394
|
+
if (typeof url === "string" && url.length > 0) {
|
|
395
|
+
out.lighthouseUrl = url;
|
|
396
|
+
}
|
|
397
|
+
return out;
|
|
398
|
+
}
|
|
399
|
+
|
|
373
400
|
// src/audits/lighthouse.ts
|
|
374
401
|
async function readJsonMaybe(path) {
|
|
375
402
|
try {
|
|
376
|
-
const raw = await
|
|
403
|
+
const raw = await readFile4(path, "utf-8");
|
|
377
404
|
return JSON.parse(raw);
|
|
378
405
|
} catch {
|
|
379
406
|
return null;
|
|
@@ -409,15 +436,28 @@ async function lighthouseAudit(ctx) {
|
|
|
409
436
|
const spawn2 = ctx.spawn ?? defaultSpawn;
|
|
410
437
|
const site = ctx.site;
|
|
411
438
|
const label = siteLabel(site);
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
439
|
+
const siteCfg = await readSiteConfig(site.path);
|
|
440
|
+
const resolvedConfig = siteCfg.lighthouseUrl ? {
|
|
441
|
+
...lighthouseConfig,
|
|
442
|
+
ci: {
|
|
443
|
+
...lighthouseConfig.ci,
|
|
444
|
+
collect: { ...lighthouseConfig.ci.collect, url: [siteCfg.lighthouseUrl] }
|
|
445
|
+
}
|
|
446
|
+
} : lighthouseConfig;
|
|
447
|
+
const configDir = await mkdtemp(join4(tmpdir(), "reddoor-lhci-"));
|
|
448
|
+
const configPath = join4(configDir, "lighthouserc.json");
|
|
449
|
+
await writeFile(configPath, JSON.stringify(resolvedConfig), "utf-8");
|
|
450
|
+
const resultsDir = join4(site.path, ".lighthouseci");
|
|
416
451
|
await rm(resultsDir, { recursive: true, force: true });
|
|
417
452
|
let raw;
|
|
418
453
|
try {
|
|
419
454
|
raw = await spawn2("npx", ["--yes", "@lhci/cli", "autorun", `--config=${configPath}`], {
|
|
420
|
-
cwd: site.path
|
|
455
|
+
cwd: site.path,
|
|
456
|
+
// lhci autorun boots the site's dev server, downloads Chrome on first
|
|
457
|
+
// use, and runs the audit — easily 2–3 min on a cold tree. The shared
|
|
458
|
+
// 30 s default in runAudits is fine for deps/lint/security but starves
|
|
459
|
+
// lhci.
|
|
460
|
+
timeoutMs: 5 * 6e4
|
|
421
461
|
});
|
|
422
462
|
} catch (err) {
|
|
423
463
|
await rm(configDir, { recursive: true, force: true });
|
|
@@ -433,7 +473,7 @@ async function lighthouseAudit(ctx) {
|
|
|
433
473
|
throw err;
|
|
434
474
|
}
|
|
435
475
|
await rm(configDir, { recursive: true, force: true });
|
|
436
|
-
const manifest = await readJsonMaybe(
|
|
476
|
+
const manifest = await readJsonMaybe(join4(resultsDir, "manifest.json"));
|
|
437
477
|
if (!manifest || manifest.length === 0) {
|
|
438
478
|
return {
|
|
439
479
|
audit: "lighthouse",
|
|
@@ -442,7 +482,7 @@ async function lighthouseAudit(ctx) {
|
|
|
442
482
|
summary: `lighthouse: no manifest written (exit ${raw.code})${raw.stderr ? ` \u2014 ${raw.stderr.slice(0, 200)}` : ""}`
|
|
443
483
|
};
|
|
444
484
|
}
|
|
445
|
-
const assertionResults = await readJsonMaybe(
|
|
485
|
+
const assertionResults = await readJsonMaybe(join4(resultsDir, "assertion-results.json")) ?? [];
|
|
446
486
|
const failed = assertionResults.filter((a) => !a.passed);
|
|
447
487
|
const assertions = failed.map((a) => ({
|
|
448
488
|
category: categoryFromAssertion(a),
|
|
@@ -468,9 +508,9 @@ async function lighthouseAudit(ctx) {
|
|
|
468
508
|
}
|
|
469
509
|
|
|
470
510
|
// src/audits/a11y.ts
|
|
471
|
-
import { readFile as
|
|
511
|
+
import { readFile as readFile5, writeFile as writeFile2, mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
|
|
472
512
|
import { tmpdir as tmpdir2 } from "os";
|
|
473
|
-
import { join as
|
|
513
|
+
import { join as join5 } from "path";
|
|
474
514
|
|
|
475
515
|
// src/configs/playwright-a11y.ts
|
|
476
516
|
import { defineConfig, devices } from "@playwright/test";
|
|
@@ -508,7 +548,7 @@ var playwrightA11yConfig = defineConfig({
|
|
|
508
548
|
var RESULTS_REL = ".reddoor-a11y/results.json";
|
|
509
549
|
async function readJsonMaybe2(path) {
|
|
510
550
|
try {
|
|
511
|
-
const raw = await
|
|
551
|
+
const raw = await readFile5(path, "utf-8");
|
|
512
552
|
return JSON.parse(raw);
|
|
513
553
|
} catch {
|
|
514
554
|
return null;
|
|
@@ -564,11 +604,11 @@ async function a11yAudit(ctx) {
|
|
|
564
604
|
const spawn2 = ctx.spawn ?? defaultSpawn;
|
|
565
605
|
const site = ctx.site;
|
|
566
606
|
const label = siteLabel(site);
|
|
567
|
-
const specDir = await mkdtemp2(
|
|
568
|
-
const specPath =
|
|
607
|
+
const specDir = await mkdtemp2(join5(tmpdir2(), "reddoor-a11y-spec-"));
|
|
608
|
+
const specPath = join5(specDir, "a11y.spec.ts");
|
|
569
609
|
await writeFile2(specPath, buildSpec(), "utf-8");
|
|
570
|
-
const resultsPath =
|
|
571
|
-
await rm2(
|
|
610
|
+
const resultsPath = join5(site.path, RESULTS_REL);
|
|
611
|
+
await rm2(join5(site.path, ".reddoor-a11y"), { recursive: true, force: true });
|
|
572
612
|
let raw;
|
|
573
613
|
try {
|
|
574
614
|
raw = await spawn2("npx", ["--yes", "playwright", "test", "--reporter=line", specPath], {
|
|
@@ -650,8 +690,8 @@ async function runAuditsAcross(sites, which) {
|
|
|
650
690
|
}
|
|
651
691
|
|
|
652
692
|
// src/recipes/sync-configs.ts
|
|
653
|
-
import { readFile as
|
|
654
|
-
import { join as
|
|
693
|
+
import { readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
|
|
694
|
+
import { join as join6 } from "path";
|
|
655
695
|
|
|
656
696
|
// src/recipes/sync-configs/templates.ts
|
|
657
697
|
var eslint = {
|
|
@@ -904,7 +944,7 @@ async function withRecipe(body) {
|
|
|
904
944
|
var GITIGNORE_CONFIG = "gitignore";
|
|
905
945
|
async function readMaybe(path) {
|
|
906
946
|
try {
|
|
907
|
-
return await
|
|
947
|
+
return await readFile6(path, "utf-8");
|
|
908
948
|
} catch {
|
|
909
949
|
return null;
|
|
910
950
|
}
|
|
@@ -912,13 +952,13 @@ async function readMaybe(path) {
|
|
|
912
952
|
async function planTemplateDiffs(cwd, templates) {
|
|
913
953
|
const diffs = [];
|
|
914
954
|
for (const t of templates) {
|
|
915
|
-
const existing = await readMaybe(
|
|
955
|
+
const existing = await readMaybe(join6(cwd, t.path));
|
|
916
956
|
if (existing !== t.contents) diffs.push(t);
|
|
917
957
|
}
|
|
918
958
|
return diffs;
|
|
919
959
|
}
|
|
920
960
|
async function planGitignore(cwd) {
|
|
921
|
-
const existing = await readMaybe(
|
|
961
|
+
const existing = await readMaybe(join6(cwd, ".gitignore"));
|
|
922
962
|
const merge = mergeGitignore(existing, CANONICAL_GITIGNORE_ENTRIES);
|
|
923
963
|
const tracked = await listTrackedFiles(cwd);
|
|
924
964
|
const toUntrack = findTrackedArtifacts(tracked, CANONICAL_GITIGNORE_ENTRIES);
|
|
@@ -926,7 +966,7 @@ async function planGitignore(cwd) {
|
|
|
926
966
|
return { kind: "apply", content: merge.content, toUntrack, added: merge.added };
|
|
927
967
|
}
|
|
928
968
|
async function applyGitignore(cwd, plan) {
|
|
929
|
-
await writeFile3(
|
|
969
|
+
await writeFile3(join6(cwd, ".gitignore"), plan.content, "utf-8");
|
|
930
970
|
if (plan.toUntrack.length > 0) {
|
|
931
971
|
await removeFromIndex(cwd, plan.toUntrack);
|
|
932
972
|
}
|
|
@@ -949,7 +989,7 @@ async function syncConfigs(site, opts = {}) {
|
|
|
949
989
|
},
|
|
950
990
|
apply: async ({ templateDiffs, gitignorePlan }, { commit: commit2 }) => {
|
|
951
991
|
for (const t of templateDiffs) {
|
|
952
|
-
await writeFile3(
|
|
992
|
+
await writeFile3(join6(site.path, t.path), t.contents, "utf-8");
|
|
953
993
|
await commit2(`chore: sync ${t.config} config from @reddoorla/maintenance`);
|
|
954
994
|
}
|
|
955
995
|
if (gitignorePlan.kind === "apply") {
|
|
@@ -963,7 +1003,7 @@ async function syncConfigs(site, opts = {}) {
|
|
|
963
1003
|
|
|
964
1004
|
// src/recipes/bump-deps.ts
|
|
965
1005
|
import { stat } from "fs/promises";
|
|
966
|
-
import { join as
|
|
1006
|
+
import { join as join7 } from "path";
|
|
967
1007
|
async function exists(path) {
|
|
968
1008
|
try {
|
|
969
1009
|
await stat(path);
|
|
@@ -992,10 +1032,10 @@ async function bumpDeps(site, opts = {}) {
|
|
|
992
1032
|
// land on top of whatever else was in the tree.
|
|
993
1033
|
checkTreeFirst: true,
|
|
994
1034
|
plan: async () => {
|
|
995
|
-
const hasPnpmLock = await exists(
|
|
1035
|
+
const hasPnpmLock = await exists(join7(site.path, "pnpm-lock.yaml"));
|
|
996
1036
|
if (!hasPnpmLock) {
|
|
997
|
-
const hasNpmLock = await exists(
|
|
998
|
-
const hasYarnLock = await exists(
|
|
1037
|
+
const hasNpmLock = await exists(join7(site.path, "package-lock.json"));
|
|
1038
|
+
const hasYarnLock = await exists(join7(site.path, "yarn.lock"));
|
|
999
1039
|
if (hasNpmLock || hasYarnLock) {
|
|
1000
1040
|
const competing = hasNpmLock ? "package-lock.json" : "yarn.lock";
|
|
1001
1041
|
return {
|
|
@@ -1030,12 +1070,12 @@ async function bumpDeps(site, opts = {}) {
|
|
|
1030
1070
|
}
|
|
1031
1071
|
|
|
1032
1072
|
// src/recipes/svelte-5/index.ts
|
|
1033
|
-
import { join as
|
|
1073
|
+
import { join as join13 } from "path";
|
|
1034
1074
|
|
|
1035
1075
|
// src/util/pkg.ts
|
|
1036
|
-
import { readFile as
|
|
1076
|
+
import { readFile as readFile7, writeFile as writeFile4 } from "fs/promises";
|
|
1037
1077
|
async function readPackageJson(path) {
|
|
1038
|
-
const raw = await
|
|
1078
|
+
const raw = await readFile7(path, "utf-8");
|
|
1039
1079
|
return JSON.parse(raw);
|
|
1040
1080
|
}
|
|
1041
1081
|
function detectIndentFromContent(raw) {
|
|
@@ -1045,7 +1085,7 @@ function detectIndentFromContent(raw) {
|
|
|
1045
1085
|
async function writePackageJson(path, pkg) {
|
|
1046
1086
|
let indent = " ";
|
|
1047
1087
|
try {
|
|
1048
|
-
const existing = await
|
|
1088
|
+
const existing = await readFile7(path, "utf-8");
|
|
1049
1089
|
indent = detectIndentFromContent(existing);
|
|
1050
1090
|
} catch {
|
|
1051
1091
|
}
|
|
@@ -1079,7 +1119,7 @@ function bumpDep(pkg, name, version, opts = {}) {
|
|
|
1079
1119
|
}
|
|
1080
1120
|
|
|
1081
1121
|
// src/recipes/svelte-5/step-bump-versions.ts
|
|
1082
|
-
import { join as
|
|
1122
|
+
import { join as join8 } from "path";
|
|
1083
1123
|
var SVELTE_5_VERSIONS = {
|
|
1084
1124
|
svelte: "^5.55.5",
|
|
1085
1125
|
"@sveltejs/kit": "^2.59.0",
|
|
@@ -1092,7 +1132,7 @@ var SVELTE_5_VERSIONS = {
|
|
|
1092
1132
|
"typescript-svelte-plugin": "^0.3.52"
|
|
1093
1133
|
};
|
|
1094
1134
|
async function bumpToSvelte5Versions(cwd) {
|
|
1095
|
-
const pkgPath =
|
|
1135
|
+
const pkgPath = join8(cwd, "package.json");
|
|
1096
1136
|
const pkg = await readPackageJson(pkgPath);
|
|
1097
1137
|
let next = pkg;
|
|
1098
1138
|
for (const [name, version] of Object.entries(SVELTE_5_VERSIONS)) {
|
|
@@ -1104,8 +1144,8 @@ async function bumpToSvelte5Versions(cwd) {
|
|
|
1104
1144
|
}
|
|
1105
1145
|
|
|
1106
1146
|
// src/recipes/svelte-5/step-svelte-config.ts
|
|
1107
|
-
import { readFile as
|
|
1108
|
-
import { join as
|
|
1147
|
+
import { readFile as readFile8, writeFile as writeFile5 } from "fs/promises";
|
|
1148
|
+
import { join as join9 } from "path";
|
|
1109
1149
|
var VITE_PLUGIN_PKG = "@sveltejs/vite-plugin-svelte";
|
|
1110
1150
|
var IMPORT_FROM_VITE_PLUGIN = new RegExp(
|
|
1111
1151
|
String.raw`^import\s+\{\s*([^}]+?)\s*\}\s+from\s+["']` + VITE_PLUGIN_PKG.replace(/[/]/g, "\\/") + String.raw`["'];?[ \t]*\n`,
|
|
@@ -1146,10 +1186,10 @@ function dropPreprocessKey(source) {
|
|
|
1146
1186
|
return source.slice(0, m.index) + source.slice(tailIdx).replace(new RegExp(`^${indent}\\n`), "");
|
|
1147
1187
|
}
|
|
1148
1188
|
async function migrateSvelteConfig(cwd) {
|
|
1149
|
-
const path =
|
|
1189
|
+
const path = join9(cwd, "svelte.config.js");
|
|
1150
1190
|
let src;
|
|
1151
1191
|
try {
|
|
1152
|
-
src = await
|
|
1192
|
+
src = await readFile8(path, "utf-8");
|
|
1153
1193
|
} catch {
|
|
1154
1194
|
return false;
|
|
1155
1195
|
}
|
|
@@ -1183,9 +1223,9 @@ async function runSvelteMigrate(cwd, spawn2 = defaultSpawn) {
|
|
|
1183
1223
|
}
|
|
1184
1224
|
|
|
1185
1225
|
// src/recipes/svelte-5/step-tailwind-upgrade.ts
|
|
1186
|
-
import { join as
|
|
1226
|
+
import { join as join10 } from "path";
|
|
1187
1227
|
async function upgradeTailwind(cwd, spawn2 = defaultSpawn) {
|
|
1188
|
-
const pkg = await readPackageJson(
|
|
1228
|
+
const pkg = await readPackageJson(join10(cwd, "package.json"));
|
|
1189
1229
|
const tailwindVersion = pkg.devDependencies?.tailwindcss ?? pkg.dependencies?.tailwindcss;
|
|
1190
1230
|
if (!tailwindVersion) return { ran: false, reason: "tailwindcss not installed" };
|
|
1191
1231
|
if (/^\^?4\./.test(tailwindVersion)) return { ran: false, reason: "already on tailwind 4.x" };
|
|
@@ -1206,8 +1246,8 @@ async function upgradeTailwind(cwd, spawn2 = defaultSpawn) {
|
|
|
1206
1246
|
}
|
|
1207
1247
|
|
|
1208
1248
|
// src/recipes/svelte-5/step-gotchas.ts
|
|
1209
|
-
import { readFile as
|
|
1210
|
-
import { join as
|
|
1249
|
+
import { readFile as readFile9, writeFile as writeFile6 } from "fs/promises";
|
|
1250
|
+
import { join as join11 } from "path";
|
|
1211
1251
|
import { glob as glob2 } from "tinyglobby";
|
|
1212
1252
|
|
|
1213
1253
|
// src/recipes/svelte-5/codemods/on-event-to-handler.ts
|
|
@@ -1539,8 +1579,8 @@ async function planGotchaCodemods(cwd) {
|
|
|
1539
1579
|
const changes = [];
|
|
1540
1580
|
const relPaths = await glob2(SVELTE_GLOBS, { cwd, ignore: IGNORE2, absolute: false });
|
|
1541
1581
|
for (const rel of relPaths) {
|
|
1542
|
-
const path =
|
|
1543
|
-
const before = await
|
|
1582
|
+
const path = join11(cwd, rel);
|
|
1583
|
+
const before = await readFile9(path, "utf-8");
|
|
1544
1584
|
const after = CODEMODS.reduce((s, fn) => fn(s), before);
|
|
1545
1585
|
if (after !== before) changes.push({ rel, after });
|
|
1546
1586
|
}
|
|
@@ -1549,7 +1589,7 @@ async function planGotchaCodemods(cwd) {
|
|
|
1549
1589
|
async function applyGotchaCodemods(cwd) {
|
|
1550
1590
|
const changes = await planGotchaCodemods(cwd);
|
|
1551
1591
|
for (const c of changes) {
|
|
1552
|
-
await writeFile6(
|
|
1592
|
+
await writeFile6(join11(cwd, c.rel), c.after, "utf-8");
|
|
1553
1593
|
}
|
|
1554
1594
|
return { filesChanged: changes.length };
|
|
1555
1595
|
}
|
|
@@ -1573,7 +1613,7 @@ async function verifyMigration(cwd, spawn2 = defaultSpawn) {
|
|
|
1573
1613
|
|
|
1574
1614
|
// src/recipes/svelte-5/step-summary.ts
|
|
1575
1615
|
import { writeFile as writeFile7 } from "fs/promises";
|
|
1576
|
-
import { join as
|
|
1616
|
+
import { join as join12 } from "path";
|
|
1577
1617
|
async function writeMigrationSummary(input) {
|
|
1578
1618
|
const lines = [
|
|
1579
1619
|
`# Svelte 4 \u2192 5 migration summary`,
|
|
@@ -1590,7 +1630,7 @@ async function writeMigrationSummary(input) {
|
|
|
1590
1630
|
`- Verify Playwright a11y tests still pass.`
|
|
1591
1631
|
];
|
|
1592
1632
|
const content = lines.join("\n") + "\n";
|
|
1593
|
-
const path =
|
|
1633
|
+
const path = join12(input.cwd, "MIGRATION_SVELTE_5.md");
|
|
1594
1634
|
await writeFile7(path, content, "utf-8");
|
|
1595
1635
|
return path;
|
|
1596
1636
|
}
|
|
@@ -1598,7 +1638,7 @@ async function writeMigrationSummary(input) {
|
|
|
1598
1638
|
// src/recipes/svelte-5/index.ts
|
|
1599
1639
|
async function alreadyOnSvelte5(cwd) {
|
|
1600
1640
|
try {
|
|
1601
|
-
const pkg = await readPackageJson(
|
|
1641
|
+
const pkg = await readPackageJson(join13(cwd, "package.json"));
|
|
1602
1642
|
const v = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte;
|
|
1603
1643
|
return !!v && /^\^?5\./.test(v);
|
|
1604
1644
|
} catch {
|
|
@@ -1653,7 +1693,7 @@ async function upgradeSvelte4to5(site, opts = {}) {
|
|
|
1653
1693
|
|
|
1654
1694
|
// src/recipes/svelte-codemods.ts
|
|
1655
1695
|
import { writeFile as writeFile8 } from "fs/promises";
|
|
1656
|
-
import { join as
|
|
1696
|
+
import { join as join14 } from "path";
|
|
1657
1697
|
async function svelteCodemods(site) {
|
|
1658
1698
|
return withRecipe({
|
|
1659
1699
|
name: "svelte-codemods",
|
|
@@ -1667,7 +1707,7 @@ async function svelteCodemods(site) {
|
|
|
1667
1707
|
},
|
|
1668
1708
|
apply: async (changes, { commit: commit2, cwd }) => {
|
|
1669
1709
|
for (const c of changes) {
|
|
1670
|
-
await writeFile8(
|
|
1710
|
+
await writeFile8(join14(cwd, c.rel), c.after, "utf-8");
|
|
1671
1711
|
}
|
|
1672
1712
|
await commit2(`refactor(svelte5): apply codemods (${changes.length} files)`);
|
|
1673
1713
|
return { kind: "ok" };
|
|
@@ -1677,7 +1717,7 @@ async function svelteCodemods(site) {
|
|
|
1677
1717
|
|
|
1678
1718
|
// src/recipes/convert-to-pnpm.ts
|
|
1679
1719
|
import { rm as rm3, stat as stat2 } from "fs/promises";
|
|
1680
|
-
import { join as
|
|
1720
|
+
import { join as join15 } from "path";
|
|
1681
1721
|
|
|
1682
1722
|
// src/recipes/convert-to-pnpm/script-rewrites.ts
|
|
1683
1723
|
function rewriteScriptForPnpm(script) {
|
|
@@ -1710,9 +1750,9 @@ async function exists2(path) {
|
|
|
1710
1750
|
async function convertToPnpm(site, opts = {}) {
|
|
1711
1751
|
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1712
1752
|
const pnpmVersion = opts.pnpmVersion ?? DEFAULT_PNPM_VERSION;
|
|
1713
|
-
const pnpmLockPath =
|
|
1714
|
-
const npmLockPath =
|
|
1715
|
-
const yarnLockPath =
|
|
1753
|
+
const pnpmLockPath = join15(site.path, "pnpm-lock.yaml");
|
|
1754
|
+
const npmLockPath = join15(site.path, "package-lock.json");
|
|
1755
|
+
const yarnLockPath = join15(site.path, "yarn.lock");
|
|
1716
1756
|
return withRecipe({
|
|
1717
1757
|
name: "convert-to-pnpm",
|
|
1718
1758
|
site,
|
|
@@ -1735,7 +1775,7 @@ async function convertToPnpm(site, opts = {}) {
|
|
|
1735
1775
|
if (hasYarnLock) await rm3(yarnLockPath, { force: true });
|
|
1736
1776
|
const sourceLock = hasNpmLock ? "package-lock.json" : "yarn.lock";
|
|
1737
1777
|
await commit2(`chore(pnpm): remove ${sourceLock}`);
|
|
1738
|
-
const pkgPath =
|
|
1778
|
+
const pkgPath = join15(cwd, "package.json");
|
|
1739
1779
|
const pkg = await readPackageJson(pkgPath);
|
|
1740
1780
|
const next = { ...pkg, packageManager: `pnpm@${pnpmVersion}` };
|
|
1741
1781
|
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
@@ -1748,7 +1788,7 @@ async function convertToPnpm(site, opts = {}) {
|
|
|
1748
1788
|
}
|
|
1749
1789
|
await writePackageJson(pkgPath, next);
|
|
1750
1790
|
await commit2("chore(pnpm): pin packageManager + rewrite npm scripts");
|
|
1751
|
-
await rm3(
|
|
1791
|
+
await rm3(join15(cwd, "node_modules"), { recursive: true, force: true });
|
|
1752
1792
|
const installResult = await spawn2("pnpm", ["install"], { cwd, streaming: true });
|
|
1753
1793
|
if (installResult.code !== 0) {
|
|
1754
1794
|
return { kind: "failed", notes: `pnpm install failed (exit ${installResult.code})` };
|
|
@@ -1761,16 +1801,16 @@ async function convertToPnpm(site, opts = {}) {
|
|
|
1761
1801
|
|
|
1762
1802
|
// src/recipes/onboard.ts
|
|
1763
1803
|
import { stat as stat3 } from "fs/promises";
|
|
1764
|
-
import { join as
|
|
1804
|
+
import { join as join17 } from "path";
|
|
1765
1805
|
|
|
1766
1806
|
// src/util/self-version.ts
|
|
1767
1807
|
import { readFileSync } from "fs";
|
|
1768
1808
|
import { fileURLToPath } from "url";
|
|
1769
|
-
import { dirname, join as
|
|
1809
|
+
import { dirname, join as join16 } from "path";
|
|
1770
1810
|
function selfPackageVersion(callerImportMetaUrl) {
|
|
1771
1811
|
try {
|
|
1772
1812
|
const here2 = dirname(fileURLToPath(callerImportMetaUrl));
|
|
1773
|
-
const raw = readFileSync(
|
|
1813
|
+
const raw = readFileSync(join16(here2, "..", "..", "package.json"), "utf-8");
|
|
1774
1814
|
const pkg = JSON.parse(raw);
|
|
1775
1815
|
return pkg.version ?? "0.0.0";
|
|
1776
1816
|
} catch {
|
|
@@ -1820,13 +1860,13 @@ async function onboard(site, opts = {}) {
|
|
|
1820
1860
|
name: "onboard",
|
|
1821
1861
|
site,
|
|
1822
1862
|
plan: async () => {
|
|
1823
|
-
if (!await exists3(
|
|
1863
|
+
if (!await exists3(join17(site.path, "pnpm-lock.yaml"))) {
|
|
1824
1864
|
return {
|
|
1825
1865
|
kind: "failed",
|
|
1826
1866
|
notes: "no pnpm-lock.yaml at site root \u2014 run convert-to-pnpm first"
|
|
1827
1867
|
};
|
|
1828
1868
|
}
|
|
1829
|
-
const pkgPath =
|
|
1869
|
+
const pkgPath = join17(site.path, "package.json");
|
|
1830
1870
|
const pkg = await readPackageJson(pkgPath);
|
|
1831
1871
|
const toAdd = [];
|
|
1832
1872
|
if (!isDeclared(pkg, PACKAGE_NAME)) {
|
|
@@ -1846,7 +1886,7 @@ async function onboard(site, opts = {}) {
|
|
|
1846
1886
|
return { kind: "apply", plan: { pkg, toAdd } };
|
|
1847
1887
|
},
|
|
1848
1888
|
apply: async ({ pkg, toAdd }, { commit: commit2, cwd }) => {
|
|
1849
|
-
const pkgPath =
|
|
1889
|
+
const pkgPath = join17(cwd, "package.json");
|
|
1850
1890
|
let next = pkg;
|
|
1851
1891
|
for (const dep of toAdd) {
|
|
1852
1892
|
next = bumpDep(next, dep.name, dep.version);
|
|
@@ -1889,7 +1929,7 @@ function localPath(path, opts = {}) {
|
|
|
1889
1929
|
}
|
|
1890
1930
|
|
|
1891
1931
|
// src/inventory/json.ts
|
|
1892
|
-
import { readFile as
|
|
1932
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
1893
1933
|
import { isAbsolute } from "path";
|
|
1894
1934
|
function validate(raw) {
|
|
1895
1935
|
if (!Array.isArray(raw)) {
|
|
@@ -1919,7 +1959,7 @@ function validate(raw) {
|
|
|
1919
1959
|
}
|
|
1920
1960
|
function fromJsonFile(path) {
|
|
1921
1961
|
return async () => {
|
|
1922
|
-
const raw = JSON.parse(await
|
|
1962
|
+
const raw = JSON.parse(await readFile10(path, "utf-8"));
|
|
1923
1963
|
return validate(raw);
|
|
1924
1964
|
};
|
|
1925
1965
|
}
|
|
@@ -1994,16 +2034,16 @@ import { dirname as dirname3 } from "path";
|
|
|
1994
2034
|
import mjml2html from "mjml";
|
|
1995
2035
|
|
|
1996
2036
|
// src/reports/maintenance-email/assets/index.ts
|
|
1997
|
-
import { readFile as
|
|
1998
|
-
import { dirname as dirname2, join as
|
|
2037
|
+
import { readFile as readFile11 } from "fs/promises";
|
|
2038
|
+
import { dirname as dirname2, join as join18 } from "path";
|
|
1999
2039
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2000
2040
|
var here = dirname2(fileURLToPath2(import.meta.url));
|
|
2001
2041
|
var CHECK_CID = "rd-check-png";
|
|
2002
2042
|
var BLURRED_CID = "rd-blurred-tests-jpg";
|
|
2003
2043
|
async function loadBundledImages() {
|
|
2004
2044
|
const [check, blurred] = await Promise.all([
|
|
2005
|
-
|
|
2006
|
-
|
|
2045
|
+
readFile11(join18(here, "check.png")),
|
|
2046
|
+
readFile11(join18(here, "blurredTests.jpg"))
|
|
2007
2047
|
]);
|
|
2008
2048
|
return {
|
|
2009
2049
|
check: {
|