svelte-vitals 0.27.0 → 0.28.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/bin.js +93 -29
- package/dist/{chunk-NRQKNTAB.js → chunk-O5VMXV2Q.js} +1 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CONFIG_FILENAMES,
|
|
4
4
|
buildRulesConfig,
|
|
5
|
+
discoverApps,
|
|
5
6
|
findUnknownRuleIds,
|
|
6
7
|
isReporterName,
|
|
7
8
|
knownRuleIds,
|
|
8
9
|
readCoreVersion,
|
|
9
10
|
readPackageVersion,
|
|
10
11
|
run
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-O5VMXV2Q.js";
|
|
12
13
|
|
|
13
14
|
// src/bin.ts
|
|
14
15
|
import mri3 from "mri";
|
|
@@ -960,13 +961,17 @@ var LOCKFILE_TO_PM = {
|
|
|
960
961
|
"pnpm-lock.yaml": "pnpm",
|
|
961
962
|
"yarn.lock": "yarn",
|
|
962
963
|
"bun.lock": "bun",
|
|
963
|
-
"bun.lockb": "bun"
|
|
964
|
+
"bun.lockb": "bun",
|
|
965
|
+
"package-lock.json": "npm"
|
|
964
966
|
};
|
|
965
|
-
function
|
|
967
|
+
function detectPackageManagerFromLockfile(io) {
|
|
966
968
|
for (const [file, pm] of Object.entries(LOCKFILE_TO_PM)) {
|
|
967
969
|
if (io.readFile(join3(io.cwd, file)) !== void 0) return pm;
|
|
968
970
|
}
|
|
969
|
-
return
|
|
971
|
+
return void 0;
|
|
972
|
+
}
|
|
973
|
+
function detectPackageManager(io) {
|
|
974
|
+
return detectPackageManagerFromLockfile(io) ?? "npm";
|
|
970
975
|
}
|
|
971
976
|
function hasVitePackage(io) {
|
|
972
977
|
const raw = io.readFile(join3(io.cwd, "package.json"));
|
|
@@ -993,31 +998,34 @@ function readInstalledViteVersion(io) {
|
|
|
993
998
|
}
|
|
994
999
|
|
|
995
1000
|
// src/ci/action-pin.generated.ts
|
|
996
|
-
var ACTION_SHA = "
|
|
997
|
-
var ACTION_VERSION = "0.3.
|
|
1001
|
+
var ACTION_SHA = "90b7538b5bed65ac123f46d77511dd4b48fa69bb";
|
|
1002
|
+
var ACTION_VERSION = "0.3.3";
|
|
998
1003
|
|
|
999
1004
|
// src/install/index.ts
|
|
1005
|
+
function detectPackageManagerNear(io, appDir) {
|
|
1006
|
+
return detectPackageManagerFromLockfile({ ...io, cwd: appDir }) ?? detectPackageManager(io);
|
|
1007
|
+
}
|
|
1000
1008
|
function planForClient(client, scope, io, force) {
|
|
1001
1009
|
const path = client.resolvePath(scope, io.cwd, io.home);
|
|
1002
1010
|
const existing = io.readFile(path);
|
|
1003
1011
|
const merged = client.format === "toml" ? mergeToml(existing, MCP_ENTRY, force) : mergeJson(existing, MCP_ENTRY, force);
|
|
1004
1012
|
return { id: client.id, label: client.label, scope, path, status: merged.status, content: merged.content };
|
|
1005
1013
|
}
|
|
1006
|
-
function resolveCandidate(io, candidates) {
|
|
1014
|
+
function resolveCandidate(io, baseDir, candidates) {
|
|
1007
1015
|
for (const rel of candidates) {
|
|
1008
|
-
const path = join4(
|
|
1016
|
+
const path = join4(baseDir, rel);
|
|
1009
1017
|
const content = io.readFile(path);
|
|
1010
1018
|
if (content !== void 0) return { path, content };
|
|
1011
1019
|
}
|
|
1012
|
-
return { path: join4(
|
|
1020
|
+
return { path: join4(baseDir, candidates[0]), content: void 0 };
|
|
1013
1021
|
}
|
|
1014
|
-
function planForVitePlugin(io) {
|
|
1015
|
-
const { path, content } = resolveCandidate(io, ["vite.config.ts", "vite.config.js", "vite.config.mjs"]);
|
|
1022
|
+
function planForVitePlugin(io, appDir) {
|
|
1023
|
+
const { path, content } = resolveCandidate(io, appDir, ["vite.config.ts", "vite.config.js", "vite.config.mjs"]);
|
|
1016
1024
|
const result = codemodViteConfig(content);
|
|
1017
1025
|
return { id: "vite-plugin", label: viteTargetById("vite-plugin").label, path, ...result };
|
|
1018
1026
|
}
|
|
1019
|
-
function planForViteHooks(io) {
|
|
1020
|
-
const { path, content } = resolveCandidate(io, ["src/hooks.server.ts", "src/hooks.server.js"]);
|
|
1027
|
+
function planForViteHooks(io, appDir) {
|
|
1028
|
+
const { path, content } = resolveCandidate(io, appDir, ["src/hooks.server.ts", "src/hooks.server.js"]);
|
|
1021
1029
|
const result = codemodHooksServer(content);
|
|
1022
1030
|
return { id: "vite-hooks", label: viteTargetById("vite-hooks").label, path, ...result };
|
|
1023
1031
|
}
|
|
@@ -1044,23 +1052,23 @@ function planForAgentTarget(target, io, force, version) {
|
|
|
1044
1052
|
return { id: target.id, label: target.label, path, status, content };
|
|
1045
1053
|
});
|
|
1046
1054
|
}
|
|
1047
|
-
function planForConfigTarget(target, io, force) {
|
|
1048
|
-
const existingRel = findExistingConfigFile(io.readFile,
|
|
1055
|
+
function planForConfigTarget(target, io, force, appDir) {
|
|
1056
|
+
const existingRel = findExistingConfigFile(io.readFile, appDir);
|
|
1049
1057
|
if (existingRel !== void 0) {
|
|
1050
|
-
const path2 = join4(
|
|
1058
|
+
const path2 = join4(appDir, existingRel);
|
|
1051
1059
|
const status = force ? "updated" : "exists";
|
|
1052
1060
|
const content2 = force ? buildConfigFileTemplate({
|
|
1053
|
-
useDefineConfig: existingRel.endsWith(".ts") && hasSvelteVitalsDependency(io.readFile,
|
|
1054
|
-
useCommonJs: existingRel.endsWith(".js") && !isEsmProject(io.readFile,
|
|
1061
|
+
useDefineConfig: existingRel.endsWith(".ts") && hasSvelteVitalsDependency(io.readFile, appDir),
|
|
1062
|
+
useCommonJs: existingRel.endsWith(".js") && !isEsmProject(io.readFile, appDir)
|
|
1055
1063
|
}) : void 0;
|
|
1056
1064
|
return { id: target.id, label: target.label, path: path2, status, content: content2 };
|
|
1057
1065
|
}
|
|
1058
1066
|
const ext = detectBestConfigExtension({
|
|
1059
1067
|
readFile: io.readFile,
|
|
1060
|
-
cwd:
|
|
1068
|
+
cwd: appDir,
|
|
1061
1069
|
nodeVersion: io.nodeVersion ?? process.version
|
|
1062
1070
|
});
|
|
1063
|
-
const path = join4(
|
|
1071
|
+
const path = join4(appDir, `svelte-vitals.config.${ext}`);
|
|
1064
1072
|
const content = buildConfigFileTemplate({ useDefineConfig: ext === "ts" });
|
|
1065
1073
|
return { id: target.id, label: target.label, path, status: "created", content };
|
|
1066
1074
|
}
|
|
@@ -1187,6 +1195,44 @@ async function runInstall(flags, io, prompts, version = "0.0.0") {
|
|
|
1187
1195
|
io.errorLog("svelte-vitals: no valid clients or targets selected.");
|
|
1188
1196
|
return 2;
|
|
1189
1197
|
}
|
|
1198
|
+
const hasSvelteConfig = (dir) => {
|
|
1199
|
+
try {
|
|
1200
|
+
return io.readFile(join4(dir, "svelte.config.js")) !== void 0 || io.readFile(join4(dir, "svelte.config.ts")) !== void 0;
|
|
1201
|
+
} catch {
|
|
1202
|
+
return false;
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
const needsApp = viteIds.length > 0 || configIds.length > 0;
|
|
1206
|
+
let appDir = io.cwd;
|
|
1207
|
+
if (needsApp) {
|
|
1208
|
+
if (flags.app) {
|
|
1209
|
+
const candidate = join4(io.cwd, flags.app);
|
|
1210
|
+
if (!hasSvelteConfig(candidate)) {
|
|
1211
|
+
io.errorLog(`svelte-vitals: --app '${flags.app}' is not a SvelteKit app (no svelte.config.{js,ts} there).`);
|
|
1212
|
+
return 2;
|
|
1213
|
+
}
|
|
1214
|
+
appDir = candidate;
|
|
1215
|
+
} else if (!hasSvelteConfig(io.cwd)) {
|
|
1216
|
+
const apps = await (io.discoverApps ?? discoverApps)(io.cwd);
|
|
1217
|
+
if (apps.length === 1) {
|
|
1218
|
+
io.errorLog(`svelte-vitals: detected SvelteKit app at ${apps[0]}; targeting it for the Vite/config targets.`);
|
|
1219
|
+
appDir = join4(io.cwd, apps[0]);
|
|
1220
|
+
} else if (apps.length > 1) {
|
|
1221
|
+
if (io.isTTY) {
|
|
1222
|
+
const picked = await prompts.selectApp(apps);
|
|
1223
|
+
if (picked === null) {
|
|
1224
|
+
io.log("Cancelled.");
|
|
1225
|
+
return 0;
|
|
1226
|
+
}
|
|
1227
|
+
appDir = join4(io.cwd, picked);
|
|
1228
|
+
} else {
|
|
1229
|
+
io.errorLog(`svelte-vitals: multiple SvelteKit apps found: ${apps.join(", ")}.`);
|
|
1230
|
+
io.errorLog(`svelte-vitals: pass one with --app, e.g. \`svelte-vitals install --app ${apps[0]}\`.`);
|
|
1231
|
+
return 2;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1190
1236
|
const rows = [];
|
|
1191
1237
|
for (const client of clients) {
|
|
1192
1238
|
let scope;
|
|
@@ -1215,7 +1261,7 @@ async function runInstall(flags, io, prompts, version = "0.0.0") {
|
|
|
1215
1261
|
}
|
|
1216
1262
|
}
|
|
1217
1263
|
for (const viteId of viteIds) {
|
|
1218
|
-
rows.push(viteId === "vite-plugin" ? planForVitePlugin(io) : planForViteHooks(io));
|
|
1264
|
+
rows.push(viteId === "vite-plugin" ? planForVitePlugin(io, appDir) : planForViteHooks(io, appDir));
|
|
1219
1265
|
}
|
|
1220
1266
|
for (const agentId of agentIds) {
|
|
1221
1267
|
const target = agentTargetById(agentId);
|
|
@@ -1231,7 +1277,7 @@ async function runInstall(flags, io, prompts, version = "0.0.0") {
|
|
|
1231
1277
|
for (const configId of configIds) {
|
|
1232
1278
|
const target = configTargetById(configId);
|
|
1233
1279
|
try {
|
|
1234
|
-
rows.push(planForConfigTarget(target, io, flags.force ?? false));
|
|
1280
|
+
rows.push(planForConfigTarget(target, io, flags.force ?? false, appDir));
|
|
1235
1281
|
} catch (err) {
|
|
1236
1282
|
io.errorLog(
|
|
1237
1283
|
`svelte-vitals: could not check existing config file: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -1291,17 +1337,18 @@ ${indent(r.snippet ?? "")}`);
|
|
|
1291
1337
|
io.errorLog(`svelte-vitals: failed to write ${r.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1292
1338
|
}
|
|
1293
1339
|
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1340
|
+
const appIo = { ...io, cwd: appDir };
|
|
1341
|
+
if (viteWasWritten && io.runCommand && !hasVitePackage(appIo)) {
|
|
1342
|
+
const pm = appDir === io.cwd ? detectPackageManager(io) : detectPackageManagerNear(io, appDir);
|
|
1296
1343
|
const { command, args } = installCommand(pm);
|
|
1297
1344
|
io.log(`Installing @svelte-vitals/vite via ${pm}...`);
|
|
1298
|
-
const code = io.runCommand(command, args,
|
|
1345
|
+
const code = io.runCommand(command, args, appDir);
|
|
1299
1346
|
if (code !== 0) {
|
|
1300
1347
|
io.errorLog(
|
|
1301
1348
|
`svelte-vitals: failed to install @svelte-vitals/vite (${command} ${args.join(" ")} exited ${code}). Install it manually.`
|
|
1302
1349
|
);
|
|
1303
1350
|
} else {
|
|
1304
|
-
const installedVersion = readInstalledViteVersion(io);
|
|
1351
|
+
const installedVersion = readInstalledViteVersion(appIo) ?? readInstalledViteVersion(io);
|
|
1305
1352
|
io.log(
|
|
1306
1353
|
installedVersion ? `svelte-vitals: installed @svelte-vitals/vite@${installedVersion} \u2014 compare against \`svelte-vitals --version\`'s core number if findings ever seem out of sync.` : "svelte-vitals: installed @svelte-vitals/vite (could not read the installed version from node_modules)."
|
|
1307
1354
|
);
|
|
@@ -1345,18 +1392,20 @@ function resolveInstallArgs(argv) {
|
|
|
1345
1392
|
if (rawScope === "project" || rawScope === "global") scope = rawScope;
|
|
1346
1393
|
else errors.push(`svelte-vitals: unknown --scope '${rawScope}'; expected project|global.`);
|
|
1347
1394
|
}
|
|
1395
|
+
const app = typeof argv.app === "string" && argv.app.trim() !== "" ? argv.app.trim() : void 0;
|
|
1348
1396
|
const refresh = Boolean(argv.refresh);
|
|
1349
1397
|
if (refresh && rawClients.length > 0) {
|
|
1350
1398
|
errors.push("svelte-vitals: --refresh regenerates existing files and cannot be combined with --client.");
|
|
1351
1399
|
}
|
|
1352
1400
|
if (errors.length > 0) return { flags: null, warnings, errors };
|
|
1353
|
-
if (refresh && (scope !== void 0 || Boolean(argv.yes) || Boolean(argv.force))) {
|
|
1354
|
-
warnings.push("svelte-vitals: --scope, --yes, and --
|
|
1401
|
+
if (refresh && (scope !== void 0 || Boolean(argv.yes) || Boolean(argv.force) || app !== void 0)) {
|
|
1402
|
+
warnings.push("svelte-vitals: --scope, --yes, --force, and --app are ignored with --refresh.");
|
|
1355
1403
|
}
|
|
1356
1404
|
return {
|
|
1357
1405
|
flags: {
|
|
1358
1406
|
...client.length > 0 ? { client } : {},
|
|
1359
1407
|
...scope ? { scope } : {},
|
|
1408
|
+
...app !== void 0 && !refresh ? { app } : {},
|
|
1360
1409
|
yes: Boolean(argv.yes),
|
|
1361
1410
|
dryRun: Boolean(argv["dry-run"]),
|
|
1362
1411
|
force: Boolean(argv.force),
|
|
@@ -1400,6 +1449,13 @@ Options:
|
|
|
1400
1449
|
the same pass as everything else; supports --force to regenerate. \`svelte-vitals
|
|
1401
1450
|
ci upgrade\` remains the way to bump an existing workflow's pinned action version.
|
|
1402
1451
|
--scope <scope> project | global (applies to all selected clients; codex is always global)
|
|
1452
|
+
--app <dir> Monorepo: the SvelteKit app directory the vite-plugin/vite-hooks/config-file
|
|
1453
|
+
targets write into (e.g. --app apps/web). Without it, when the current
|
|
1454
|
+
directory isn't itself a SvelteKit app, one detected app is used
|
|
1455
|
+
automatically (with a notice), several prompt a picker on a TTY, and
|
|
1456
|
+
non-interactive runs exit 2 asking for --app. All other targets (MCP
|
|
1457
|
+
configs, skills, ci-workflow) always write at the current directory \u2014
|
|
1458
|
+
the repo root is their correct home.
|
|
1403
1459
|
--yes, -y Skip the confirmation prompt
|
|
1404
1460
|
--dry-run Print the planned changes and exit without writing
|
|
1405
1461
|
--force Overwrite an existing svelte-vitals entry
|
|
@@ -1470,6 +1526,14 @@ function clackPrompts() {
|
|
|
1470
1526
|
});
|
|
1471
1527
|
return p.isCancel(res) ? null : res;
|
|
1472
1528
|
},
|
|
1529
|
+
selectApp: async (apps) => {
|
|
1530
|
+
const res = await p.select({
|
|
1531
|
+
message: "Multiple SvelteKit apps found \u2014 which one should the Vite/config targets go into?",
|
|
1532
|
+
options: apps.map((a) => ({ value: a, label: a })),
|
|
1533
|
+
initialValue: apps[0]
|
|
1534
|
+
});
|
|
1535
|
+
return p.isCancel(res) ? null : res;
|
|
1536
|
+
},
|
|
1473
1537
|
confirm: async (planText) => {
|
|
1474
1538
|
const res = await p.confirm({ message: `Apply this plan?
|
|
1475
1539
|
${planText}` });
|
|
@@ -1480,7 +1544,7 @@ ${planText}` });
|
|
|
1480
1544
|
async function runInstallCli(args) {
|
|
1481
1545
|
const argv = mri(args, {
|
|
1482
1546
|
boolean: ["yes", "dry-run", "force", "refresh", "help"],
|
|
1483
|
-
string: ["client", "scope"],
|
|
1547
|
+
string: ["client", "scope", "app"],
|
|
1484
1548
|
alias: { y: "yes", h: "help" }
|
|
1485
1549
|
});
|
|
1486
1550
|
if (argv.help) {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-vitals",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "A SvelteKit SEO checker — not a runtime Web Vitals reporter. Static analysis of your routes' head metadata.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"smol-toml": "^1.7.0",
|
|
47
47
|
"svelte": "^5.56.4",
|
|
48
48
|
"tinyglobby": "^0.2.17",
|
|
49
|
-
"@svelte-vitals/core": "0.
|
|
49
|
+
"@svelte-vitals/core": "0.25.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^24.13.3"
|