@reddoorla/maintenance 0.6.6 → 0.6.7
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 +90 -160
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +12 -21
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/index.js +72 -83
- package/dist/index.js.map +1 -1
- package/dist/recipes/sync-configs.js +7 -6
- package/dist/recipes/sync-configs.js.map +1 -1
- package/dist/util/git.js +2 -3
- package/dist/util/git.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,6 +31,11 @@ var defaultSpawn = (cmd, args, opts = {}) => new Promise((resolve, reject) => {
|
|
|
31
31
|
import { readFile } from "fs/promises";
|
|
32
32
|
import { join } from "path";
|
|
33
33
|
|
|
34
|
+
// src/util/site.ts
|
|
35
|
+
function siteLabel(site) {
|
|
36
|
+
return site.name ?? site.path;
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
// src/configs/baseline-versions.ts
|
|
35
40
|
var baselineVersions = {
|
|
36
41
|
// SvelteKit core
|
|
@@ -71,9 +76,6 @@ var baselineVersions = {
|
|
|
71
76
|
};
|
|
72
77
|
|
|
73
78
|
// src/audits/deps.ts
|
|
74
|
-
function siteLabel(site) {
|
|
75
|
-
return site.name ?? site.path;
|
|
76
|
-
}
|
|
77
79
|
function stripCaret(range) {
|
|
78
80
|
return range.replace(/^[\^~]/, "");
|
|
79
81
|
}
|
|
@@ -146,9 +148,6 @@ import { check as prettierCheck, resolveConfig as prettierResolveConfig } from "
|
|
|
146
148
|
import { glob } from "tinyglobby";
|
|
147
149
|
var TARGET_GLOBS = ["**/*.{ts,js,svelte}"];
|
|
148
150
|
var IGNORE = ["node_modules/**", "dist/**", ".svelte-kit/**", "build/**", ".netlify/**"];
|
|
149
|
-
function siteLabel2(site) {
|
|
150
|
-
return site.name ?? site.path;
|
|
151
|
-
}
|
|
152
151
|
async function listFiles(cwd) {
|
|
153
152
|
return glob(TARGET_GLOBS, { cwd, ignore: IGNORE, absolute: false });
|
|
154
153
|
}
|
|
@@ -158,7 +157,7 @@ async function lintAudit(ctx) {
|
|
|
158
157
|
if (!existsSync(configPath)) {
|
|
159
158
|
return {
|
|
160
159
|
audit: "lint",
|
|
161
|
-
site:
|
|
160
|
+
site: siteLabel(site),
|
|
162
161
|
status: "skip",
|
|
163
162
|
summary: "no eslint config at site root"
|
|
164
163
|
};
|
|
@@ -184,7 +183,7 @@ async function lintAudit(ctx) {
|
|
|
184
183
|
const summary = status === "pass" ? `lint clean across ${relFiles.length} files` : `${eslintErrors} eslint errors, ${eslintWarnings} warnings, ${prettierUnformatted.length} unformatted`;
|
|
185
184
|
return {
|
|
186
185
|
audit: "lint",
|
|
187
|
-
site:
|
|
186
|
+
site: siteLabel(site),
|
|
188
187
|
status,
|
|
189
188
|
summary,
|
|
190
189
|
details: {
|
|
@@ -197,9 +196,6 @@ async function lintAudit(ctx) {
|
|
|
197
196
|
}
|
|
198
197
|
|
|
199
198
|
// src/audits/security.ts
|
|
200
|
-
function siteLabel3(site) {
|
|
201
|
-
return site.name ?? site.path;
|
|
202
|
-
}
|
|
203
199
|
function classify(v) {
|
|
204
200
|
if (v.critical > 0 || v.high > 0) return "fail";
|
|
205
201
|
if (v.moderate > 0 || v.low > 0) return "warn";
|
|
@@ -285,7 +281,8 @@ async function runAuditTool(spawn2, cmd, args, cwd) {
|
|
|
285
281
|
if (errEnvelope && typeof errEnvelope === "object") {
|
|
286
282
|
return { kind: "error", reason: errEnvelope.code ?? "error envelope returned" };
|
|
287
283
|
}
|
|
288
|
-
|
|
284
|
+
const vulnsMeta = parsed.metadata?.vulnerabilities;
|
|
285
|
+
if (!vulnsMeta || Object.keys(vulnsMeta).length === 0) {
|
|
289
286
|
return { kind: "error", reason: "no metadata.vulnerabilities in output" };
|
|
290
287
|
}
|
|
291
288
|
return { kind: "ok", parsed };
|
|
@@ -293,7 +290,7 @@ async function runAuditTool(spawn2, cmd, args, cwd) {
|
|
|
293
290
|
async function securityAudit(ctx) {
|
|
294
291
|
const spawn2 = ctx.spawn ?? defaultSpawn;
|
|
295
292
|
const site = ctx.site;
|
|
296
|
-
const label =
|
|
293
|
+
const label = siteLabel(site);
|
|
297
294
|
let used = "pnpm audit";
|
|
298
295
|
let result = await runAuditTool(spawn2, "pnpm", ["audit", "--json", "--prod"], site.path);
|
|
299
296
|
if (result.kind !== "ok") {
|
|
@@ -374,9 +371,6 @@ var lighthouseConfig = {
|
|
|
374
371
|
};
|
|
375
372
|
|
|
376
373
|
// src/audits/lighthouse.ts
|
|
377
|
-
function siteLabel4(site) {
|
|
378
|
-
return site.name ?? site.path;
|
|
379
|
-
}
|
|
380
374
|
async function readJsonMaybe(path) {
|
|
381
375
|
try {
|
|
382
376
|
const raw = await readFile3(path, "utf-8");
|
|
@@ -414,7 +408,7 @@ function messageForAssertion(a) {
|
|
|
414
408
|
async function lighthouseAudit(ctx) {
|
|
415
409
|
const spawn2 = ctx.spawn ?? defaultSpawn;
|
|
416
410
|
const site = ctx.site;
|
|
417
|
-
const label =
|
|
411
|
+
const label = siteLabel(site);
|
|
418
412
|
const configDir = await mkdtemp(join3(tmpdir(), "reddoor-lhci-"));
|
|
419
413
|
const configPath = join3(configDir, "lighthouserc.json");
|
|
420
414
|
await writeFile(configPath, JSON.stringify(lighthouseConfig), "utf-8");
|
|
@@ -512,9 +506,6 @@ var playwrightA11yConfig = defineConfig({
|
|
|
512
506
|
|
|
513
507
|
// src/audits/a11y.ts
|
|
514
508
|
var RESULTS_REL = ".reddoor-a11y/results.json";
|
|
515
|
-
function siteLabel5(site) {
|
|
516
|
-
return site.name ?? site.path;
|
|
517
|
-
}
|
|
518
509
|
async function readJsonMaybe2(path) {
|
|
519
510
|
try {
|
|
520
511
|
const raw = await readFile4(path, "utf-8");
|
|
@@ -572,7 +563,7 @@ test("a11y across configured routes", async ({ page }) => {
|
|
|
572
563
|
async function a11yAudit(ctx) {
|
|
573
564
|
const spawn2 = ctx.spawn ?? defaultSpawn;
|
|
574
565
|
const site = ctx.site;
|
|
575
|
-
const label =
|
|
566
|
+
const label = siteLabel(site);
|
|
576
567
|
const specDir = await mkdtemp2(join4(tmpdir2(), "reddoor-a11y-spec-"));
|
|
577
568
|
const specPath = join4(specDir, "a11y.spec.ts");
|
|
578
569
|
await writeFile2(specPath, buildSpec(), "utf-8");
|
|
@@ -820,9 +811,8 @@ async function git(cwd, args) {
|
|
|
820
811
|
return exec("git", args, { cwd, env: process.env });
|
|
821
812
|
}
|
|
822
813
|
function branchName(recipe, when = /* @__PURE__ */ new Date()) {
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
return `maint/${recipe}-${trimmed}`;
|
|
814
|
+
const compact = when.toISOString().replace(/[-:.]/g, "");
|
|
815
|
+
return `maint/${recipe}-${compact}`;
|
|
826
816
|
}
|
|
827
817
|
async function isWorkingTreeClean(cwd) {
|
|
828
818
|
const { stdout } = await git(cwd, ["status", "--porcelain"]);
|
|
@@ -853,9 +843,6 @@ async function commit(cwd, message) {
|
|
|
853
843
|
|
|
854
844
|
// src/recipes/sync-configs.ts
|
|
855
845
|
var GITIGNORE_CONFIG = "gitignore";
|
|
856
|
-
function siteLabel6(site) {
|
|
857
|
-
return site.name ?? site.path;
|
|
858
|
-
}
|
|
859
846
|
async function readMaybe(path) {
|
|
860
847
|
try {
|
|
861
848
|
return await readFile5(path, "utf-8");
|
|
@@ -886,7 +873,7 @@ async function applyGitignore(cwd, plan) {
|
|
|
886
873
|
}
|
|
887
874
|
}
|
|
888
875
|
async function syncConfigs(site, opts = {}) {
|
|
889
|
-
const label =
|
|
876
|
+
const label = siteLabel(site);
|
|
890
877
|
const requested = opts.which ?? ALL_TEMPLATES.map((t) => t.config).concat(GITIGNORE_CONFIG);
|
|
891
878
|
const templateNames = requested.filter((c) => c !== GITIGNORE_CONFIG);
|
|
892
879
|
const templates = templatesByName(templateNames);
|
|
@@ -933,9 +920,6 @@ async function syncConfigs(site, opts = {}) {
|
|
|
933
920
|
// src/recipes/bump-deps.ts
|
|
934
921
|
import { stat } from "fs/promises";
|
|
935
922
|
import { join as join6 } from "path";
|
|
936
|
-
function siteLabel7(site) {
|
|
937
|
-
return site.name ?? site.path;
|
|
938
|
-
}
|
|
939
923
|
async function exists(path) {
|
|
940
924
|
try {
|
|
941
925
|
await stat(path);
|
|
@@ -954,7 +938,7 @@ function upFlagsForGroup(group) {
|
|
|
954
938
|
return [];
|
|
955
939
|
}
|
|
956
940
|
async function bumpDeps(site, opts = {}) {
|
|
957
|
-
const label =
|
|
941
|
+
const label = siteLabel(site);
|
|
958
942
|
const group = opts.group ?? "minor";
|
|
959
943
|
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
960
944
|
const hasPnpmLock = await exists(join6(site.path, "pnpm-lock.yaml"));
|
|
@@ -1196,6 +1180,34 @@ import { glob as glob2 } from "tinyglobby";
|
|
|
1196
1180
|
// src/recipes/svelte-5/codemods/on-event-to-handler.ts
|
|
1197
1181
|
var SCRIPT_BLOCK = /<script\b[^>]*>[\s\S]*?<\/script>/g;
|
|
1198
1182
|
var SIMPLE_ON_EVENT = /\bon:([a-z]+)(?=\s*=)/g;
|
|
1183
|
+
var MODIFIER_EVENT = /\bon:[a-z]+\|[a-zA-Z]+(?=\s*=)/g;
|
|
1184
|
+
function flagEventModifiers(source) {
|
|
1185
|
+
const insertions = [];
|
|
1186
|
+
let m;
|
|
1187
|
+
MODIFIER_EVENT.lastIndex = 0;
|
|
1188
|
+
while ((m = MODIFIER_EVENT.exec(source)) !== null) {
|
|
1189
|
+
const tagStart = source.lastIndexOf("<", m.index);
|
|
1190
|
+
if (tagStart === -1) continue;
|
|
1191
|
+
const prevLineEnd = tagStart - 1;
|
|
1192
|
+
if (prevLineEnd >= 0) {
|
|
1193
|
+
const prevLineStart = source.lastIndexOf("\n", prevLineEnd - 1) + 1;
|
|
1194
|
+
const prevLine = source.slice(prevLineStart, prevLineEnd + 1);
|
|
1195
|
+
if (/<!--\s*@migration-task/.test(prevLine)) continue;
|
|
1196
|
+
}
|
|
1197
|
+
const lineStart = source.lastIndexOf("\n", tagStart - 1) + 1;
|
|
1198
|
+
const indent = source.slice(lineStart, tagStart);
|
|
1199
|
+
const safeIndent = /^[ \t]*$/.test(indent) ? indent : "";
|
|
1200
|
+
insertions.push({ tagStart, indent: safeIndent, modifier: m[0] });
|
|
1201
|
+
}
|
|
1202
|
+
let out = source;
|
|
1203
|
+
for (let i = insertions.length - 1; i >= 0; i--) {
|
|
1204
|
+
const { tagStart, indent, modifier } = insertions[i];
|
|
1205
|
+
const comment = `<!-- @migration-task: Svelte 5 removed event modifier syntax (\`${modifier}\`). Rewrite inline, e.g. onclick={(e) => { e.preventDefault(); ... }}. -->
|
|
1206
|
+
${indent}`;
|
|
1207
|
+
out = out.slice(0, tagStart) + comment + out.slice(tagStart);
|
|
1208
|
+
}
|
|
1209
|
+
return out;
|
|
1210
|
+
}
|
|
1199
1211
|
function onEventToHandler(source) {
|
|
1200
1212
|
const masked = [];
|
|
1201
1213
|
const placeholder = (i) => ` SCRIPT_${i} `;
|
|
@@ -1203,8 +1215,9 @@ function onEventToHandler(source) {
|
|
|
1203
1215
|
masked.push(match);
|
|
1204
1216
|
return placeholder(masked.length - 1);
|
|
1205
1217
|
});
|
|
1206
|
-
|
|
1207
|
-
|
|
1218
|
+
let processed = intermediate.replace(SIMPLE_ON_EVENT, (_full, name) => `on${name}`);
|
|
1219
|
+
processed = flagEventModifiers(processed);
|
|
1220
|
+
let out = processed;
|
|
1208
1221
|
masked.forEach((blk, i) => {
|
|
1209
1222
|
out = out.replace(placeholder(i), blk);
|
|
1210
1223
|
});
|
|
@@ -1254,6 +1267,22 @@ function exportLetToProps(source) {
|
|
|
1254
1267
|
return source.replace(SCRIPT_BLOCK2, (full) => full.replace(inner, body));
|
|
1255
1268
|
}
|
|
1256
1269
|
|
|
1270
|
+
// src/util/svelte-source.ts
|
|
1271
|
+
function findStringEnd(source, openIdx) {
|
|
1272
|
+
const quote = source[openIdx];
|
|
1273
|
+
let i = openIdx + 1;
|
|
1274
|
+
while (i < source.length) {
|
|
1275
|
+
const ch = source[i];
|
|
1276
|
+
if (ch === "\\") {
|
|
1277
|
+
i += 2;
|
|
1278
|
+
continue;
|
|
1279
|
+
}
|
|
1280
|
+
if (ch === quote) return i;
|
|
1281
|
+
i++;
|
|
1282
|
+
}
|
|
1283
|
+
return -1;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1257
1286
|
// src/recipes/svelte-5/codemods/dollar-restprops.ts
|
|
1258
1287
|
function removeInterfaceBlock(source) {
|
|
1259
1288
|
const re = /^\s*interface\s+\$\$Props\s*\{/m;
|
|
@@ -1277,20 +1306,6 @@ function removeInterfaceBlock(source) {
|
|
|
1277
1306
|
out = out.slice(0, match.index) + out.slice(endIdx);
|
|
1278
1307
|
}
|
|
1279
1308
|
}
|
|
1280
|
-
function findStringEnd(source, openIdx) {
|
|
1281
|
-
const quote = source[openIdx];
|
|
1282
|
-
let i = openIdx + 1;
|
|
1283
|
-
while (i < source.length) {
|
|
1284
|
-
const ch = source[i];
|
|
1285
|
-
if (ch === "\\") {
|
|
1286
|
-
i += 2;
|
|
1287
|
-
continue;
|
|
1288
|
-
}
|
|
1289
|
-
if (ch === quote) return i;
|
|
1290
|
-
i++;
|
|
1291
|
-
}
|
|
1292
|
-
return -1;
|
|
1293
|
-
}
|
|
1294
1309
|
function maskStringLiterals(source) {
|
|
1295
1310
|
const strings = [];
|
|
1296
1311
|
let out = "";
|
|
@@ -1367,7 +1382,8 @@ function stateEffectSyncToDerived(source) {
|
|
|
1367
1382
|
|
|
1368
1383
|
// src/recipes/svelte-5/codemods/dollar-props-class.ts
|
|
1369
1384
|
var PROPS_DESTRUCTURE = /let\s*\{([\s\S]*?)\}(\s*:\s*\{([\s\S]*?)\})?\s*=\s*\$props\(\)/;
|
|
1370
|
-
var
|
|
1385
|
+
var HAS_DOLLAR_PROPS_CLASS = /\$\$props\.class\b/;
|
|
1386
|
+
var DOLLAR_PROPS_CLASS_GLOBAL = /\$\$props\.class\b/g;
|
|
1371
1387
|
var DOLLAR_PROPS_ANY = /\$\$props\b/;
|
|
1372
1388
|
var SCRIPT_BLOCK4 = /<script\b[^>]*>[\s\S]*?<\/script>/g;
|
|
1373
1389
|
var MIGRATION_TASK = /^<!--\s*@migration-task[\s\S]*?-->\s*\n?/gm;
|
|
@@ -1389,8 +1405,7 @@ function restoreScripts(masked, blocks) {
|
|
|
1389
1405
|
}
|
|
1390
1406
|
function dollarPropsClass(source) {
|
|
1391
1407
|
const { masked } = maskScripts(source);
|
|
1392
|
-
if (!
|
|
1393
|
-
DOLLAR_PROPS_CLASS.lastIndex = 0;
|
|
1408
|
+
if (!HAS_DOLLAR_PROPS_CLASS.test(masked)) return source;
|
|
1394
1409
|
if (!PROPS_DESTRUCTURE.test(source)) return source;
|
|
1395
1410
|
let updated = source.replace(PROPS_DESTRUCTURE, (full, body, typeAnno, typeBody) => {
|
|
1396
1411
|
if (/\bclass\s*:/.test(body)) return full;
|
|
@@ -1404,7 +1419,7 @@ function dollarPropsClass(source) {
|
|
|
1404
1419
|
return `let { ${newBody} } = $props()`;
|
|
1405
1420
|
});
|
|
1406
1421
|
const reMasked = maskScripts(updated);
|
|
1407
|
-
const templateRewritten = reMasked.masked.replace(
|
|
1422
|
+
const templateRewritten = reMasked.masked.replace(DOLLAR_PROPS_CLASS_GLOBAL, IDENT);
|
|
1408
1423
|
updated = restoreScripts(templateRewritten, reMasked.blocks);
|
|
1409
1424
|
const stripped = updated.replace(MIGRATION_TASK, "");
|
|
1410
1425
|
if (!DOLLAR_PROPS_ANY.test(stripped)) {
|
|
@@ -1423,7 +1438,7 @@ function findMatchingClose(source, openIdx) {
|
|
|
1423
1438
|
while (i < source.length) {
|
|
1424
1439
|
const ch = source[i];
|
|
1425
1440
|
if (ch === '"' || ch === "'" || ch === "`") {
|
|
1426
|
-
const closeStr =
|
|
1441
|
+
const closeStr = findStringEnd(source, i);
|
|
1427
1442
|
if (closeStr === -1) return -1;
|
|
1428
1443
|
i = closeStr + 1;
|
|
1429
1444
|
continue;
|
|
@@ -1437,20 +1452,6 @@ function findMatchingClose(source, openIdx) {
|
|
|
1437
1452
|
}
|
|
1438
1453
|
return -1;
|
|
1439
1454
|
}
|
|
1440
|
-
function findStringClose(source, openIdx) {
|
|
1441
|
-
const quote = source[openIdx];
|
|
1442
|
-
let i = openIdx + 1;
|
|
1443
|
-
while (i < source.length) {
|
|
1444
|
-
const ch = source[i];
|
|
1445
|
-
if (ch === "\\") {
|
|
1446
|
-
i += 2;
|
|
1447
|
-
continue;
|
|
1448
|
-
}
|
|
1449
|
-
if (ch === quote) return i;
|
|
1450
|
-
i++;
|
|
1451
|
-
}
|
|
1452
|
-
return -1;
|
|
1453
|
-
}
|
|
1454
1455
|
var MIGRATION_MARKER = "// @migration-task: $effect won't trigger UI updates on plain `let` bindings \u2014 refine mutated locals to $state or split into per-variable $derived.";
|
|
1455
1456
|
function transformBlocks(body) {
|
|
1456
1457
|
const out = [];
|
|
@@ -1562,9 +1563,6 @@ async function writeMigrationSummary(input) {
|
|
|
1562
1563
|
}
|
|
1563
1564
|
|
|
1564
1565
|
// src/recipes/svelte-5/index.ts
|
|
1565
|
-
function siteLabel8(site) {
|
|
1566
|
-
return site.name ?? site.path;
|
|
1567
|
-
}
|
|
1568
1566
|
async function alreadyOnSvelte5(cwd) {
|
|
1569
1567
|
try {
|
|
1570
1568
|
const pkg = await readPackageJson(join12(cwd, "package.json"));
|
|
@@ -1575,7 +1573,7 @@ async function alreadyOnSvelte5(cwd) {
|
|
|
1575
1573
|
}
|
|
1576
1574
|
}
|
|
1577
1575
|
async function upgradeSvelte4to5(site, opts = {}) {
|
|
1578
|
-
const label =
|
|
1576
|
+
const label = siteLabel(site);
|
|
1579
1577
|
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1580
1578
|
if (await alreadyOnSvelte5(site.path)) {
|
|
1581
1579
|
return {
|
|
@@ -1646,11 +1644,8 @@ async function upgradeSvelte4to5(site, opts = {}) {
|
|
|
1646
1644
|
// src/recipes/svelte-codemods.ts
|
|
1647
1645
|
import { writeFile as writeFile8 } from "fs/promises";
|
|
1648
1646
|
import { join as join13 } from "path";
|
|
1649
|
-
function siteLabel9(site) {
|
|
1650
|
-
return site.name ?? site.path;
|
|
1651
|
-
}
|
|
1652
1647
|
async function svelteCodemods(site) {
|
|
1653
|
-
const label =
|
|
1648
|
+
const label = siteLabel(site);
|
|
1654
1649
|
const changes = await planGotchaCodemods(site.path);
|
|
1655
1650
|
if (changes.length === 0) {
|
|
1656
1651
|
return {
|
|
@@ -1714,11 +1709,8 @@ async function exists2(path) {
|
|
|
1714
1709
|
return false;
|
|
1715
1710
|
}
|
|
1716
1711
|
}
|
|
1717
|
-
function siteLabel10(site) {
|
|
1718
|
-
return site.name ?? site.path;
|
|
1719
|
-
}
|
|
1720
1712
|
async function convertToPnpm(site, opts = {}) {
|
|
1721
|
-
const label =
|
|
1713
|
+
const label = siteLabel(site);
|
|
1722
1714
|
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1723
1715
|
const pnpmVersion = opts.pnpmVersion ?? DEFAULT_PNPM_VERSION;
|
|
1724
1716
|
const pnpmLockPath = join14(site.path, "pnpm-lock.yaml");
|
|
@@ -1844,14 +1836,11 @@ async function exists3(path) {
|
|
|
1844
1836
|
return false;
|
|
1845
1837
|
}
|
|
1846
1838
|
}
|
|
1847
|
-
function siteLabel11(site) {
|
|
1848
|
-
return site.name ?? site.path;
|
|
1849
|
-
}
|
|
1850
1839
|
function isDeclared(pkg, name) {
|
|
1851
1840
|
return Boolean(pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]);
|
|
1852
1841
|
}
|
|
1853
1842
|
async function onboard(site, opts = {}) {
|
|
1854
|
-
const label =
|
|
1843
|
+
const label = siteLabel(site);
|
|
1855
1844
|
const spawn2 = opts.spawn ?? defaultSpawn;
|
|
1856
1845
|
const audits = opts.audits ?? ["lighthouse", "a11y"];
|
|
1857
1846
|
const packageVersion = opts.packageVersion ?? selfCaretRange(import.meta.url);
|