@reddoorla/maintenance 0.1.1 → 0.1.2
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 +182 -68
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +70 -32
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +130 -40
- package/dist/index.js.map +1 -1
- package/dist/util/pkg.d.ts +6 -2
- package/dist/util/pkg.js +3 -1
- package/dist/util/pkg.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/bin.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/bin.ts
|
|
4
|
-
import {
|
|
5
|
-
import { dirname, join as join14 } from "path";
|
|
4
|
+
import { dirname } from "path";
|
|
6
5
|
import { fileURLToPath } from "url";
|
|
7
6
|
import { cac } from "cac";
|
|
8
7
|
|
|
@@ -12,15 +11,18 @@ import { resolve as resolve2 } from "path";
|
|
|
12
11
|
// src/audits/util/spawn.ts
|
|
13
12
|
import { spawn } from "child_process";
|
|
14
13
|
var defaultSpawn = (cmd, args, opts = {}) => new Promise((resolve6, reject) => {
|
|
14
|
+
const streaming = opts.streaming === true;
|
|
15
15
|
const child = spawn(cmd, [...args], {
|
|
16
16
|
cwd: opts.cwd,
|
|
17
17
|
env: opts.env ?? process.env,
|
|
18
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
18
|
+
stdio: streaming ? ["ignore", "inherit", "inherit"] : ["ignore", "pipe", "pipe"]
|
|
19
19
|
});
|
|
20
20
|
let stdout = "";
|
|
21
21
|
let stderr = "";
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
if (!streaming) {
|
|
23
|
+
child.stdout?.on("data", (chunk) => stdout += String(chunk));
|
|
24
|
+
child.stderr?.on("data", (chunk) => stderr += String(chunk));
|
|
25
|
+
}
|
|
24
26
|
const timer = opts.timeoutMs ? setTimeout(() => {
|
|
25
27
|
child.kill("SIGTERM");
|
|
26
28
|
reject(new Error(`spawn timeout after ${opts.timeoutMs}ms: ${cmd}`));
|
|
@@ -115,10 +117,10 @@ async function depsAudit(ctx) {
|
|
|
115
117
|
details: { error: String(err) }
|
|
116
118
|
};
|
|
117
119
|
}
|
|
118
|
-
const
|
|
120
|
+
const pkg = JSON.parse(pkgRaw);
|
|
119
121
|
const installed = {
|
|
120
|
-
...
|
|
121
|
-
...
|
|
122
|
+
...pkg.dependencies ?? {},
|
|
123
|
+
...pkg.devDependencies ?? {}
|
|
122
124
|
};
|
|
123
125
|
const details = [];
|
|
124
126
|
for (const [name, baseline] of Object.entries(baselineVersions)) {
|
|
@@ -148,7 +150,7 @@ async function depsAudit(ctx) {
|
|
|
148
150
|
// src/audits/lint.ts
|
|
149
151
|
import { existsSync } from "fs";
|
|
150
152
|
import { readFile as readFile2 } from "fs/promises";
|
|
151
|
-
import { join as join2
|
|
153
|
+
import { join as join2 } from "path";
|
|
152
154
|
import { ESLint } from "eslint";
|
|
153
155
|
import { check as prettierCheck, resolveConfig as prettierResolveConfig } from "prettier";
|
|
154
156
|
import { glob } from "tinyglobby";
|
|
@@ -177,19 +179,19 @@ async function lintAudit(ctx) {
|
|
|
177
179
|
errorOnUnmatchedPattern: false
|
|
178
180
|
});
|
|
179
181
|
const relFiles = await listFiles(site.path);
|
|
180
|
-
const
|
|
181
|
-
const eslintResults = await eslint2.lintFiles(filesToLint);
|
|
182
|
+
const eslintResults = await eslint2.lintFiles(relFiles);
|
|
182
183
|
const eslintErrors = eslintResults.reduce((n, r) => n + r.errorCount, 0);
|
|
183
184
|
const eslintWarnings = eslintResults.reduce((n, r) => n + r.warningCount, 0);
|
|
184
185
|
const prettierUnformatted = [];
|
|
185
|
-
for (const
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
-
const
|
|
189
|
-
|
|
186
|
+
for (const rel of relFiles) {
|
|
187
|
+
const absForResolve = join2(site.path, rel);
|
|
188
|
+
const source = await readFile2(absForResolve, "utf-8");
|
|
189
|
+
const options = await prettierResolveConfig(absForResolve) ?? {};
|
|
190
|
+
const ok = await prettierCheck(source, { ...options, filepath: absForResolve });
|
|
191
|
+
if (!ok) prettierUnformatted.push(rel);
|
|
190
192
|
}
|
|
191
193
|
const status = eslintErrors > 0 || prettierUnformatted.length > 0 ? "fail" : eslintWarnings > 0 ? "warn" : "pass";
|
|
192
|
-
const summary = status === "pass" ? `lint clean across ${
|
|
194
|
+
const summary = status === "pass" ? `lint clean across ${relFiles.length} files` : `${eslintErrors} eslint errors, ${eslintWarnings} warnings, ${prettierUnformatted.length} unformatted`;
|
|
193
195
|
return {
|
|
194
196
|
audit: "lint",
|
|
195
197
|
site: siteLabel2(site),
|
|
@@ -199,7 +201,7 @@ async function lintAudit(ctx) {
|
|
|
199
201
|
eslintErrors,
|
|
200
202
|
eslintWarnings,
|
|
201
203
|
prettierUnformatted,
|
|
202
|
-
files:
|
|
204
|
+
files: relFiles.length
|
|
203
205
|
}
|
|
204
206
|
};
|
|
205
207
|
}
|
|
@@ -215,7 +217,7 @@ function classify(v) {
|
|
|
215
217
|
}
|
|
216
218
|
function normalizeSeverity(s) {
|
|
217
219
|
if (s === "low" || s === "moderate" || s === "high" || s === "critical") return s;
|
|
218
|
-
return "
|
|
220
|
+
return "low";
|
|
219
221
|
}
|
|
220
222
|
function extractAdvisoriesFromPnpm(parsed) {
|
|
221
223
|
const out = [];
|
|
@@ -231,29 +233,42 @@ function extractAdvisoriesFromPnpm(parsed) {
|
|
|
231
233
|
}
|
|
232
234
|
return out;
|
|
233
235
|
}
|
|
236
|
+
function resolveNpmAdvisoryRoot(startName, vulnerabilities) {
|
|
237
|
+
const seen = /* @__PURE__ */ new Set();
|
|
238
|
+
let current = startName;
|
|
239
|
+
while (!seen.has(current)) {
|
|
240
|
+
seen.add(current);
|
|
241
|
+
const entry = vulnerabilities[current];
|
|
242
|
+
if (!entry || !Array.isArray(entry.via)) return { rootName: current };
|
|
243
|
+
const detailed = entry.via.find(
|
|
244
|
+
(e) => typeof e === "object" && e !== null
|
|
245
|
+
);
|
|
246
|
+
if (detailed) return { rootName: current, detail: detailed };
|
|
247
|
+
const next = entry.via.find((e) => typeof e === "string");
|
|
248
|
+
if (!next || next === current) return { rootName: current };
|
|
249
|
+
current = next;
|
|
250
|
+
}
|
|
251
|
+
return { rootName: current };
|
|
252
|
+
}
|
|
234
253
|
function extractAdvisoriesFromNpm(parsed) {
|
|
235
|
-
const
|
|
236
|
-
|
|
254
|
+
const vulnerabilities = parsed.vulnerabilities ?? {};
|
|
255
|
+
const roots = /* @__PURE__ */ new Map();
|
|
256
|
+
for (const [name, v] of Object.entries(vulnerabilities)) {
|
|
237
257
|
if (!v) continue;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
out.push({
|
|
250
|
-
module: v.name ?? name,
|
|
251
|
-
severity: normalizeSeverity(v.severity),
|
|
258
|
+
const { rootName, detail } = resolveNpmAdvisoryRoot(name, vulnerabilities);
|
|
259
|
+
if (roots.has(rootName)) continue;
|
|
260
|
+
const rootEntry = vulnerabilities[rootName];
|
|
261
|
+
const severity = normalizeSeverity(rootEntry?.severity ?? v.severity);
|
|
262
|
+
const title = detail?.title ?? rootName;
|
|
263
|
+
const url = detail?.url;
|
|
264
|
+
roots.set(rootName, {
|
|
265
|
+
module: rootEntry?.name ?? rootName,
|
|
266
|
+
severity,
|
|
252
267
|
title,
|
|
253
268
|
...url ? { url } : {}
|
|
254
269
|
});
|
|
255
270
|
}
|
|
256
|
-
return
|
|
271
|
+
return [...roots.values()];
|
|
257
272
|
}
|
|
258
273
|
async function tryRun(spawn2, cmd, args, cwd) {
|
|
259
274
|
try {
|
|
@@ -518,6 +533,10 @@ import { dirname } from "node:path";
|
|
|
518
533
|
const pages = ${JSON.stringify(a11yRoutes)};
|
|
519
534
|
const OUTPUT = process.env.REDDOOR_A11Y_OUTPUT;
|
|
520
535
|
|
|
536
|
+
// Playwright's default per-test timeout is 30s. We loop through every
|
|
537
|
+
// configured route in a single test, so the budget needs to scale.
|
|
538
|
+
test.setTimeout(5 * 60_000);
|
|
539
|
+
|
|
521
540
|
test("a11y across configured routes", async ({ page }) => {
|
|
522
541
|
const violations = [];
|
|
523
542
|
for (const { path, name } of pages) {
|
|
@@ -649,6 +668,7 @@ function localPath(path, opts = {}) {
|
|
|
649
668
|
|
|
650
669
|
// src/inventory/json.ts
|
|
651
670
|
import { readFile as readFile5 } from "fs/promises";
|
|
671
|
+
import { isAbsolute } from "path";
|
|
652
672
|
function validate(raw) {
|
|
653
673
|
if (!Array.isArray(raw)) {
|
|
654
674
|
throw new Error("inventory JSON must be an array of sites");
|
|
@@ -661,6 +681,11 @@ function validate(raw) {
|
|
|
661
681
|
if (typeof e.path !== "string" || e.path.length === 0) {
|
|
662
682
|
throw new Error(`inventory entry ${i} is missing required field: path`);
|
|
663
683
|
}
|
|
684
|
+
if (!isAbsolute(e.path)) {
|
|
685
|
+
throw new Error(
|
|
686
|
+
`inventory entry ${i}: path must be absolute (got "${e.path}"). Relative paths are rejected so cwd at invocation can't change which site is targeted.`
|
|
687
|
+
);
|
|
688
|
+
}
|
|
664
689
|
const site = { path: e.path };
|
|
665
690
|
if (typeof e.name === "string") site.name = e.name;
|
|
666
691
|
if (typeof e.repoUrl === "string") site.repoUrl = e.repoUrl;
|
|
@@ -711,11 +736,22 @@ async function resolveSites(input) {
|
|
|
711
736
|
|
|
712
737
|
// src/cli/fleet/clone-if-needed.ts
|
|
713
738
|
import { stat, readdir, mkdir } from "fs/promises";
|
|
714
|
-
import { join as join5 } from "path";
|
|
739
|
+
import { isAbsolute as isAbsolute2, join as join5 } from "path";
|
|
715
740
|
function deriveNameFromRepoUrl(repoUrl) {
|
|
716
741
|
const slash = repoUrl.split("/").pop() ?? repoUrl;
|
|
717
742
|
return slash.replace(/\.git$/, "");
|
|
718
743
|
}
|
|
744
|
+
function assertSafeName(name) {
|
|
745
|
+
if (isAbsolute2(name)) {
|
|
746
|
+
throw new Error(`unsafe site name (absolute path not allowed): ${name}`);
|
|
747
|
+
}
|
|
748
|
+
if (name.includes("/") || name.includes("\\")) {
|
|
749
|
+
throw new Error(`unsafe site name (path separator not allowed): ${name}`);
|
|
750
|
+
}
|
|
751
|
+
if (name.split(/[\\/]/).some((seg) => seg === "..")) {
|
|
752
|
+
throw new Error(`unsafe site name (traversal segment not allowed): ${name}`);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
719
755
|
async function isNonEmptyDir(path) {
|
|
720
756
|
try {
|
|
721
757
|
const s = await stat(path);
|
|
@@ -732,6 +768,7 @@ async function cloneIfNeeded(site, opts) {
|
|
|
732
768
|
throw new Error(`site path does not exist (${site.path}) and no repoUrl is set \u2014 cannot clone`);
|
|
733
769
|
}
|
|
734
770
|
const name = site.name ?? deriveNameFromRepoUrl(site.repoUrl);
|
|
771
|
+
assertSafeName(name);
|
|
735
772
|
const target = join5(opts.workdir, name);
|
|
736
773
|
await mkdir(opts.workdir, { recursive: true });
|
|
737
774
|
if (await isNonEmptyDir(target)) {
|
|
@@ -995,6 +1032,7 @@ async function bumpDeps(site, opts = {}) {
|
|
|
995
1032
|
const label = siteLabel7(site);
|
|
996
1033
|
const group = opts.group ?? "minor";
|
|
997
1034
|
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1035
|
+
await spawn2("pnpm", ["install"], { cwd: site.path, streaming: true });
|
|
998
1036
|
const outdated = await spawn2("pnpm", ["outdated", "--json", ...outdatedFlagsForGroup(group)], {
|
|
999
1037
|
cwd: site.path
|
|
1000
1038
|
});
|
|
@@ -1019,7 +1057,10 @@ async function bumpDeps(site, opts = {}) {
|
|
|
1019
1057
|
}
|
|
1020
1058
|
const branch = branchName("bump-deps");
|
|
1021
1059
|
await createBranch(site.path, branch);
|
|
1022
|
-
await spawn2("pnpm", ["up", ...upFlagsForGroup(group)], {
|
|
1060
|
+
await spawn2("pnpm", ["up", ...upFlagsForGroup(group)], {
|
|
1061
|
+
cwd: site.path,
|
|
1062
|
+
streaming: true
|
|
1063
|
+
});
|
|
1023
1064
|
const sha = await commit(site.path, `chore(deps): bump dependencies (${group})`);
|
|
1024
1065
|
const shas = sha ? [sha] : [];
|
|
1025
1066
|
return {
|
|
@@ -1075,31 +1116,33 @@ async function readPackageJson(path) {
|
|
|
1075
1116
|
const raw = await readFile8(path, "utf-8");
|
|
1076
1117
|
return JSON.parse(raw);
|
|
1077
1118
|
}
|
|
1078
|
-
async function writePackageJson(path,
|
|
1079
|
-
const content = JSON.stringify(
|
|
1119
|
+
async function writePackageJson(path, pkg) {
|
|
1120
|
+
const content = JSON.stringify(pkg, null, 2) + "\n";
|
|
1080
1121
|
await writeFile4(path, content, "utf-8");
|
|
1081
1122
|
}
|
|
1082
|
-
function bumpDep(
|
|
1123
|
+
function bumpDep(pkg, name, version2, opts = {}) {
|
|
1124
|
+
const mode = opts.mode ?? "ensure";
|
|
1083
1125
|
const next = {
|
|
1084
|
-
...
|
|
1126
|
+
...pkg
|
|
1085
1127
|
};
|
|
1086
|
-
if (
|
|
1087
|
-
next.dependencies = { ...
|
|
1128
|
+
if (pkg.dependencies) {
|
|
1129
|
+
next.dependencies = { ...pkg.dependencies };
|
|
1088
1130
|
}
|
|
1089
|
-
if (
|
|
1090
|
-
next.devDependencies = { ...
|
|
1131
|
+
if (pkg.devDependencies) {
|
|
1132
|
+
next.devDependencies = { ...pkg.devDependencies };
|
|
1091
1133
|
}
|
|
1092
1134
|
if (next.dependencies && name in next.dependencies) {
|
|
1093
|
-
if (next.dependencies[name] ===
|
|
1094
|
-
next.dependencies[name] =
|
|
1135
|
+
if (next.dependencies[name] === version2) return pkg;
|
|
1136
|
+
next.dependencies[name] = version2;
|
|
1095
1137
|
return next;
|
|
1096
1138
|
}
|
|
1097
1139
|
if (next.devDependencies && name in next.devDependencies) {
|
|
1098
|
-
if (next.devDependencies[name] ===
|
|
1099
|
-
next.devDependencies[name] =
|
|
1140
|
+
if (next.devDependencies[name] === version2) return pkg;
|
|
1141
|
+
next.devDependencies[name] = version2;
|
|
1100
1142
|
return next;
|
|
1101
1143
|
}
|
|
1102
|
-
|
|
1144
|
+
if (mode === "bump-only") return pkg;
|
|
1145
|
+
next.devDependencies = { ...next.devDependencies ?? {}, [name]: version2 };
|
|
1103
1146
|
return next;
|
|
1104
1147
|
}
|
|
1105
1148
|
|
|
@@ -1118,12 +1161,12 @@ var SVELTE_5_VERSIONS = {
|
|
|
1118
1161
|
};
|
|
1119
1162
|
async function bumpToSvelte5Versions(cwd) {
|
|
1120
1163
|
const pkgPath = join8(cwd, "package.json");
|
|
1121
|
-
const
|
|
1122
|
-
let next =
|
|
1123
|
-
for (const [name,
|
|
1124
|
-
next = bumpDep(next, name,
|
|
1164
|
+
const pkg = await readPackageJson(pkgPath);
|
|
1165
|
+
let next = pkg;
|
|
1166
|
+
for (const [name, version2] of Object.entries(SVELTE_5_VERSIONS)) {
|
|
1167
|
+
next = bumpDep(next, name, version2, { mode: "bump-only" });
|
|
1125
1168
|
}
|
|
1126
|
-
if (next ===
|
|
1169
|
+
if (next === pkg) return false;
|
|
1127
1170
|
await writePackageJson(pkgPath, next);
|
|
1128
1171
|
return true;
|
|
1129
1172
|
}
|
|
@@ -1131,6 +1174,45 @@ async function bumpToSvelte5Versions(cwd) {
|
|
|
1131
1174
|
// src/recipes/svelte-5/step-svelte-config.ts
|
|
1132
1175
|
import { readFile as readFile9, writeFile as writeFile5 } from "fs/promises";
|
|
1133
1176
|
import { join as join9 } from "path";
|
|
1177
|
+
var VITE_PLUGIN_PKG = "@sveltejs/vite-plugin-svelte";
|
|
1178
|
+
var IMPORT_FROM_VITE_PLUGIN = new RegExp(
|
|
1179
|
+
String.raw`^import\s+\{\s*([^}]+?)\s*\}\s+from\s+["']` + VITE_PLUGIN_PKG.replace(/[/]/g, "\\/") + String.raw`["'];?[ \t]*\n`,
|
|
1180
|
+
"m"
|
|
1181
|
+
);
|
|
1182
|
+
function dropVitePreprocessImport(source) {
|
|
1183
|
+
return source.replace(IMPORT_FROM_VITE_PLUGIN, (full, names) => {
|
|
1184
|
+
const remaining = names.split(",").map((n) => n.trim()).filter((n) => n.length > 0 && n !== "vitePreprocess");
|
|
1185
|
+
if (remaining.length === 0) return "";
|
|
1186
|
+
return `import { ${remaining.join(", ")} } from "${VITE_PLUGIN_PKG}";
|
|
1187
|
+
`;
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
function findMatchingParen(source, openIdx) {
|
|
1191
|
+
if (source[openIdx] !== "(") return -1;
|
|
1192
|
+
let depth = 0;
|
|
1193
|
+
for (let i = openIdx; i < source.length; i++) {
|
|
1194
|
+
const ch = source[i];
|
|
1195
|
+
if (ch === "(") depth++;
|
|
1196
|
+
else if (ch === ")") {
|
|
1197
|
+
depth--;
|
|
1198
|
+
if (depth === 0) return i;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
return -1;
|
|
1202
|
+
}
|
|
1203
|
+
function dropPreprocessKey(source) {
|
|
1204
|
+
const startRe = /^(\s*)preprocess:\s*vitePreprocess\(/m;
|
|
1205
|
+
const m = startRe.exec(source);
|
|
1206
|
+
if (!m) return source;
|
|
1207
|
+
const indent = m[1] ?? "";
|
|
1208
|
+
const parenOpenAbs = m.index + m[0].length - 1;
|
|
1209
|
+
const parenCloseAbs = findMatchingParen(source, parenOpenAbs);
|
|
1210
|
+
if (parenCloseAbs < 0) return source;
|
|
1211
|
+
let tailIdx = parenCloseAbs + 1;
|
|
1212
|
+
while (tailIdx < source.length && /[ \t,]/.test(source[tailIdx] ?? "")) tailIdx++;
|
|
1213
|
+
if (source[tailIdx] === "\n") tailIdx++;
|
|
1214
|
+
return source.slice(0, m.index) + source.slice(tailIdx).replace(new RegExp(`^${indent}\\n`), "");
|
|
1215
|
+
}
|
|
1134
1216
|
async function migrateSvelteConfig(cwd) {
|
|
1135
1217
|
const path = join9(cwd, "svelte.config.js");
|
|
1136
1218
|
let src;
|
|
@@ -1140,11 +1222,8 @@ async function migrateSvelteConfig(cwd) {
|
|
|
1140
1222
|
return false;
|
|
1141
1223
|
}
|
|
1142
1224
|
let next = src;
|
|
1143
|
-
next = next
|
|
1144
|
-
|
|
1145
|
-
""
|
|
1146
|
-
);
|
|
1147
|
-
next = next.replace(/^\s*preprocess:\s*vitePreprocess\(\)\s*,?\s*\n/m, "");
|
|
1225
|
+
next = dropPreprocessKey(next);
|
|
1226
|
+
next = dropVitePreprocessImport(next);
|
|
1148
1227
|
if (next === src) return false;
|
|
1149
1228
|
await writeFile5(path, next, "utf-8");
|
|
1150
1229
|
return true;
|
|
@@ -1174,8 +1253,8 @@ async function runSvelteMigrate(cwd, spawn2 = defaultSpawn) {
|
|
|
1174
1253
|
// src/recipes/svelte-5/step-tailwind-upgrade.ts
|
|
1175
1254
|
import { join as join10 } from "path";
|
|
1176
1255
|
async function upgradeTailwind(cwd, spawn2 = defaultSpawn) {
|
|
1177
|
-
const
|
|
1178
|
-
const tailwindVersion =
|
|
1256
|
+
const pkg = await readPackageJson(join10(cwd, "package.json"));
|
|
1257
|
+
const tailwindVersion = pkg.devDependencies?.tailwindcss ?? pkg.dependencies?.tailwindcss;
|
|
1179
1258
|
if (!tailwindVersion) return { ran: false, reason: "tailwindcss not installed" };
|
|
1180
1259
|
if (/^\^?4\./.test(tailwindVersion)) return { ran: false, reason: "already on tailwind 4.x" };
|
|
1181
1260
|
try {
|
|
@@ -1254,10 +1333,32 @@ function exportLetToProps(source) {
|
|
|
1254
1333
|
}
|
|
1255
1334
|
|
|
1256
1335
|
// src/recipes/svelte-5/codemods/dollar-restprops.ts
|
|
1336
|
+
function removeInterfaceBlock(source) {
|
|
1337
|
+
const re = /^\s*interface\s+\$\$Props\s*\{/m;
|
|
1338
|
+
let out = source;
|
|
1339
|
+
while (true) {
|
|
1340
|
+
const match = re.exec(out);
|
|
1341
|
+
if (!match) return out;
|
|
1342
|
+
const openBraceIdx = match.index + match[0].length - 1;
|
|
1343
|
+
let depth = 1;
|
|
1344
|
+
let i = openBraceIdx + 1;
|
|
1345
|
+
while (i < out.length && depth > 0) {
|
|
1346
|
+
const ch = out[i];
|
|
1347
|
+
if (ch === "{") depth++;
|
|
1348
|
+
else if (ch === "}") depth--;
|
|
1349
|
+
i++;
|
|
1350
|
+
}
|
|
1351
|
+
if (depth !== 0) return out;
|
|
1352
|
+
let endIdx = i;
|
|
1353
|
+
while (endIdx < out.length && /[ \t]/.test(out[endIdx] ?? "")) endIdx++;
|
|
1354
|
+
if (out[endIdx] === "\n") endIdx++;
|
|
1355
|
+
out = out.slice(0, match.index) + out.slice(endIdx);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1257
1358
|
function removeDollarRestProps(source) {
|
|
1258
1359
|
let next = source;
|
|
1259
1360
|
next = next.replace(/\$\$restProps/g, "rest");
|
|
1260
|
-
next = next
|
|
1361
|
+
next = removeInterfaceBlock(next);
|
|
1261
1362
|
return next;
|
|
1262
1363
|
}
|
|
1263
1364
|
|
|
@@ -1327,8 +1428,8 @@ function siteLabel8(site) {
|
|
|
1327
1428
|
}
|
|
1328
1429
|
async function alreadyOnSvelte5(cwd) {
|
|
1329
1430
|
try {
|
|
1330
|
-
const
|
|
1331
|
-
const v =
|
|
1431
|
+
const pkg = await readPackageJson(join13(cwd, "package.json"));
|
|
1432
|
+
const v = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte;
|
|
1332
1433
|
return !!v && /^\^?5\./.test(v);
|
|
1333
1434
|
} catch {
|
|
1334
1435
|
return false;
|
|
@@ -1440,9 +1541,22 @@ async function runUpgradeCommand(upgradeName, site, opts = {}) {
|
|
|
1440
1541
|
return { output, code };
|
|
1441
1542
|
}
|
|
1442
1543
|
|
|
1544
|
+
// src/cli/version.ts
|
|
1545
|
+
import { readFileSync } from "fs";
|
|
1546
|
+
import { join as join14 } from "path";
|
|
1547
|
+
function resolvePackageVersion(fromDir) {
|
|
1548
|
+
try {
|
|
1549
|
+
const raw = readFileSync(join14(fromDir, "..", "..", "package.json"), "utf-8");
|
|
1550
|
+
const pkg = JSON.parse(raw);
|
|
1551
|
+
return pkg.version ?? "unknown";
|
|
1552
|
+
} catch {
|
|
1553
|
+
return "unknown";
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1443
1557
|
// src/cli/bin.ts
|
|
1444
1558
|
var here = dirname(fileURLToPath(import.meta.url));
|
|
1445
|
-
var
|
|
1559
|
+
var version = resolvePackageVersion(here);
|
|
1446
1560
|
var AUDIT_DESCRIPTIONS = {
|
|
1447
1561
|
deps: "Diff site package.json against the bundled baseline version map.",
|
|
1448
1562
|
lighthouse: "Run @lhci/cli autorun using the canonical lighthouserc.",
|
|
@@ -1521,6 +1635,6 @@ cli.command("upgrade <upgrade> [site]", "Run a named upgrade recipe (svelte-4-to
|
|
|
1521
1635
|
}
|
|
1522
1636
|
);
|
|
1523
1637
|
cli.help();
|
|
1524
|
-
cli.version(
|
|
1638
|
+
cli.version(version);
|
|
1525
1639
|
cli.parse();
|
|
1526
1640
|
//# sourceMappingURL=bin.js.map
|