@reddoorla/maintenance 0.1.3 → 0.3.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/dist/cli/bin.js +326 -7
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +6 -2
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/configs/lighthouse.d.ts +1 -1
- package/dist/configs/lighthouse.js +4 -1
- package/dist/configs/lighthouse.js.map +1 -1
- package/dist/configs/playwright-a11y.js +2 -1
- package/dist/configs/playwright-a11y.js.map +1 -1
- package/dist/index.d.ts +22 -3
- package/dist/index.js +223 -3
- package/dist/index.js.map +1 -1
- package/dist/recipes/sync-configs.d.ts +1 -1
- package/dist/{sync-configs-Z5a0iaDd.d.ts → sync-configs-D_Dm-68_.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -347,7 +347,10 @@ var lighthouseConfig = {
|
|
|
347
347
|
ci: {
|
|
348
348
|
collect: {
|
|
349
349
|
url: ["http://localhost:5173/dev/a11y-fixtures"],
|
|
350
|
-
|
|
350
|
+
// `npm run vite:dev` works on both pnpm and npm sites — pnpm respects
|
|
351
|
+
// the `run` form too. Keeps this config portable across the fleet
|
|
352
|
+
// while sites transition to pnpm.
|
|
353
|
+
startServerCommand: "npm run vite:dev",
|
|
351
354
|
startServerReadyPattern: "ready in",
|
|
352
355
|
startServerReadyTimeout: 12e4,
|
|
353
356
|
numberOfRuns: 1,
|
|
@@ -499,7 +502,8 @@ var playwrightA11yConfig = defineConfig({
|
|
|
499
502
|
}
|
|
500
503
|
],
|
|
501
504
|
webServer: {
|
|
502
|
-
|
|
505
|
+
// Portable across pnpm and npm sites — pnpm respects `npm run` too.
|
|
506
|
+
command: "npm run vite:dev",
|
|
503
507
|
url: "http://localhost:5173/dev/a11y-fixtures",
|
|
504
508
|
reuseExistingServer: !process.env.CI,
|
|
505
509
|
timeout: 12e4
|
|
@@ -1243,8 +1247,222 @@ async function upgradeSvelte4to5(site, opts = {}) {
|
|
|
1243
1247
|
};
|
|
1244
1248
|
}
|
|
1245
1249
|
|
|
1250
|
+
// src/recipes/convert-to-pnpm.ts
|
|
1251
|
+
import { rm as rm3, stat } from "fs/promises";
|
|
1252
|
+
import { join as join12 } from "path";
|
|
1253
|
+
|
|
1254
|
+
// src/recipes/convert-to-pnpm/script-rewrites.ts
|
|
1255
|
+
function rewriteScriptForPnpm(script) {
|
|
1256
|
+
let out = script;
|
|
1257
|
+
out = out.replace(/\bnpm run(?=\s)/g, "pnpm run");
|
|
1258
|
+
out = out.replace(/\bnpx(?=\s)/g, "pnpm dlx");
|
|
1259
|
+
return out;
|
|
1260
|
+
}
|
|
1261
|
+
function rewriteScriptsForPnpm(scripts) {
|
|
1262
|
+
const next = {};
|
|
1263
|
+
let changedCount = 0;
|
|
1264
|
+
for (const [name, value] of Object.entries(scripts)) {
|
|
1265
|
+
const rewritten = rewriteScriptForPnpm(value);
|
|
1266
|
+
next[name] = rewritten;
|
|
1267
|
+
if (rewritten !== value) changedCount++;
|
|
1268
|
+
}
|
|
1269
|
+
return { scripts: next, changedCount };
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
// src/recipes/convert-to-pnpm.ts
|
|
1273
|
+
var DEFAULT_PNPM_VERSION = "10.33.1";
|
|
1274
|
+
async function exists(path) {
|
|
1275
|
+
try {
|
|
1276
|
+
await stat(path);
|
|
1277
|
+
return true;
|
|
1278
|
+
} catch {
|
|
1279
|
+
return false;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
function siteLabel9(site) {
|
|
1283
|
+
return site.name ?? site.path;
|
|
1284
|
+
}
|
|
1285
|
+
async function convertToPnpm(site, opts = {}) {
|
|
1286
|
+
const label = siteLabel9(site);
|
|
1287
|
+
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1288
|
+
const pnpmVersion = opts.pnpmVersion ?? DEFAULT_PNPM_VERSION;
|
|
1289
|
+
const pnpmLockPath = join12(site.path, "pnpm-lock.yaml");
|
|
1290
|
+
const npmLockPath = join12(site.path, "package-lock.json");
|
|
1291
|
+
const yarnLockPath = join12(site.path, "yarn.lock");
|
|
1292
|
+
if (await exists(pnpmLockPath)) {
|
|
1293
|
+
return {
|
|
1294
|
+
recipe: "convert-to-pnpm",
|
|
1295
|
+
site: label,
|
|
1296
|
+
status: "noop",
|
|
1297
|
+
commits: [],
|
|
1298
|
+
notes: "site already has pnpm-lock.yaml"
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
const hasNpmLock = await exists(npmLockPath);
|
|
1302
|
+
const hasYarnLock = await exists(yarnLockPath);
|
|
1303
|
+
if (!hasNpmLock && !hasYarnLock) {
|
|
1304
|
+
return {
|
|
1305
|
+
recipe: "convert-to-pnpm",
|
|
1306
|
+
site: label,
|
|
1307
|
+
status: "noop",
|
|
1308
|
+
commits: [],
|
|
1309
|
+
notes: "no convertible lockfile (package-lock.json or yarn.lock) at site root"
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
if (!await isWorkingTreeClean(site.path)) {
|
|
1313
|
+
throw new Error(`refusing to run: working tree is not clean at ${site.path}`);
|
|
1314
|
+
}
|
|
1315
|
+
const branch = branchName("convert-to-pnpm");
|
|
1316
|
+
await createBranch(site.path, branch);
|
|
1317
|
+
const shas = [];
|
|
1318
|
+
if (hasNpmLock) await rm3(npmLockPath, { force: true });
|
|
1319
|
+
if (hasYarnLock) await rm3(yarnLockPath, { force: true });
|
|
1320
|
+
const sourceLock = hasNpmLock ? "package-lock.json" : "yarn.lock";
|
|
1321
|
+
const lockSha = await commit(site.path, `chore(pnpm): remove ${sourceLock}`);
|
|
1322
|
+
if (lockSha) shas.push(lockSha);
|
|
1323
|
+
const pkgPath = join12(site.path, "package.json");
|
|
1324
|
+
const pkg = await readPackageJson(pkgPath);
|
|
1325
|
+
const next = { ...pkg, packageManager: `pnpm@${pnpmVersion}` };
|
|
1326
|
+
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
1327
|
+
const { scripts: rewritten, changedCount } = rewriteScriptsForPnpm(
|
|
1328
|
+
pkg.scripts
|
|
1329
|
+
);
|
|
1330
|
+
if (changedCount > 0) {
|
|
1331
|
+
next.scripts = rewritten;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
await writePackageJson(pkgPath, next);
|
|
1335
|
+
const pkgSha = await commit(site.path, "chore(pnpm): pin packageManager + rewrite npm scripts");
|
|
1336
|
+
if (pkgSha) shas.push(pkgSha);
|
|
1337
|
+
const installResult = await spawn2("pnpm", ["install"], {
|
|
1338
|
+
cwd: site.path,
|
|
1339
|
+
streaming: true
|
|
1340
|
+
});
|
|
1341
|
+
if (installResult.code !== 0) {
|
|
1342
|
+
return {
|
|
1343
|
+
recipe: "convert-to-pnpm",
|
|
1344
|
+
site: label,
|
|
1345
|
+
status: "failed",
|
|
1346
|
+
commits: shas,
|
|
1347
|
+
notes: `pnpm install failed (exit ${installResult.code}). branch ${branch} left for inspection.`
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
const installSha = await commit(site.path, "chore(pnpm): add pnpm-lock.yaml");
|
|
1351
|
+
if (installSha) shas.push(installSha);
|
|
1352
|
+
return {
|
|
1353
|
+
recipe: "convert-to-pnpm",
|
|
1354
|
+
site: label,
|
|
1355
|
+
status: "applied",
|
|
1356
|
+
commits: shas,
|
|
1357
|
+
notes: `branch: ${branch}`
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// src/recipes/onboard.ts
|
|
1362
|
+
import { stat as stat2 } from "fs/promises";
|
|
1363
|
+
import { join as join13 } from "path";
|
|
1364
|
+
var PACKAGE_NAME = "@reddoorla/maintenance";
|
|
1365
|
+
var DEFAULT_PACKAGE_VERSION = "^0.2.0";
|
|
1366
|
+
var AUDIT_DEPS = {
|
|
1367
|
+
lighthouse: [{ name: "@lhci/cli", version: "^0.15.1" }],
|
|
1368
|
+
a11y: [
|
|
1369
|
+
{ name: "@playwright/test", version: "^1.59.1" },
|
|
1370
|
+
{ name: "@axe-core/playwright", version: "^4.11.3" }
|
|
1371
|
+
]
|
|
1372
|
+
};
|
|
1373
|
+
async function exists2(path) {
|
|
1374
|
+
try {
|
|
1375
|
+
await stat2(path);
|
|
1376
|
+
return true;
|
|
1377
|
+
} catch {
|
|
1378
|
+
return false;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
function siteLabel10(site) {
|
|
1382
|
+
return site.name ?? site.path;
|
|
1383
|
+
}
|
|
1384
|
+
function isDeclared(pkg, name) {
|
|
1385
|
+
return Boolean(pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]);
|
|
1386
|
+
}
|
|
1387
|
+
async function onboard(site, opts = {}) {
|
|
1388
|
+
const label = siteLabel10(site);
|
|
1389
|
+
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1390
|
+
const audits = opts.audits ?? ["lighthouse", "a11y"];
|
|
1391
|
+
const packageVersion = opts.packageVersion ?? DEFAULT_PACKAGE_VERSION;
|
|
1392
|
+
if (!await exists2(join13(site.path, "pnpm-lock.yaml"))) {
|
|
1393
|
+
return {
|
|
1394
|
+
recipe: "onboard",
|
|
1395
|
+
site: label,
|
|
1396
|
+
status: "failed",
|
|
1397
|
+
commits: [],
|
|
1398
|
+
notes: "no pnpm-lock.yaml at site root \u2014 run convert-to-pnpm first"
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1401
|
+
const pkgPath = join13(site.path, "package.json");
|
|
1402
|
+
const pkg = await readPackageJson(pkgPath);
|
|
1403
|
+
const toAdd = [];
|
|
1404
|
+
if (!isDeclared(pkg, PACKAGE_NAME)) {
|
|
1405
|
+
toAdd.push({ name: PACKAGE_NAME, version: packageVersion });
|
|
1406
|
+
}
|
|
1407
|
+
for (const audit of audits) {
|
|
1408
|
+
for (const dep of AUDIT_DEPS[audit]) {
|
|
1409
|
+
if (!isDeclared(pkg, dep.name)) toAdd.push(dep);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
if (toAdd.length === 0) {
|
|
1413
|
+
return {
|
|
1414
|
+
recipe: "onboard",
|
|
1415
|
+
site: label,
|
|
1416
|
+
status: "noop",
|
|
1417
|
+
commits: [],
|
|
1418
|
+
notes: `site already has ${PACKAGE_NAME} and audit deps (${audits.join("+")})`
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
if (!await isWorkingTreeClean(site.path)) {
|
|
1422
|
+
throw new Error(`refusing to run: working tree is not clean at ${site.path}`);
|
|
1423
|
+
}
|
|
1424
|
+
const branch = branchName("onboard");
|
|
1425
|
+
await createBranch(site.path, branch);
|
|
1426
|
+
let next = pkg;
|
|
1427
|
+
for (const dep of toAdd) {
|
|
1428
|
+
next = bumpDep(next, dep.name, dep.version);
|
|
1429
|
+
}
|
|
1430
|
+
await writePackageJson(pkgPath, next);
|
|
1431
|
+
const installResult = await spawn2("pnpm", ["install"], {
|
|
1432
|
+
cwd: site.path,
|
|
1433
|
+
streaming: true
|
|
1434
|
+
});
|
|
1435
|
+
if (installResult.code !== 0) {
|
|
1436
|
+
return {
|
|
1437
|
+
recipe: "onboard",
|
|
1438
|
+
site: label,
|
|
1439
|
+
status: "failed",
|
|
1440
|
+
commits: [],
|
|
1441
|
+
notes: `pnpm install failed (exit ${installResult.code}). branch ${branch} left for inspection.`
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
const sha = await commit(
|
|
1445
|
+
site.path,
|
|
1446
|
+
`chore(reddoor): onboard with ${PACKAGE_NAME} ${packageVersion}`
|
|
1447
|
+
);
|
|
1448
|
+
const shas = sha ? [sha] : [];
|
|
1449
|
+
return {
|
|
1450
|
+
recipe: "onboard",
|
|
1451
|
+
site: label,
|
|
1452
|
+
status: "applied",
|
|
1453
|
+
commits: shas,
|
|
1454
|
+
notes: `branch: ${branch}. Added ${toAdd.length} dep(s): ${toAdd.map((d) => d.name).join(", ")}`
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1246
1458
|
// src/recipes/index.ts
|
|
1247
|
-
var ALL_RECIPE_NAMES = [
|
|
1459
|
+
var ALL_RECIPE_NAMES = [
|
|
1460
|
+
"sync-configs",
|
|
1461
|
+
"bump-deps",
|
|
1462
|
+
"svelte-4-to-5",
|
|
1463
|
+
"convert-to-pnpm",
|
|
1464
|
+
"onboard"
|
|
1465
|
+
];
|
|
1248
1466
|
function isRecipeName(value) {
|
|
1249
1467
|
return ALL_RECIPE_NAMES.includes(value);
|
|
1250
1468
|
}
|
|
@@ -1296,12 +1514,14 @@ export {
|
|
|
1296
1514
|
ALL_RECIPE_NAMES,
|
|
1297
1515
|
a11yAudit,
|
|
1298
1516
|
bumpDeps,
|
|
1517
|
+
convertToPnpm,
|
|
1299
1518
|
depsAudit,
|
|
1300
1519
|
fromJsonFile,
|
|
1301
1520
|
isRecipeName,
|
|
1302
1521
|
lighthouseAudit,
|
|
1303
1522
|
lintAudit,
|
|
1304
1523
|
localPath,
|
|
1524
|
+
onboard,
|
|
1305
1525
|
runAudits,
|
|
1306
1526
|
runAuditsAcross,
|
|
1307
1527
|
securityAudit,
|