@svelte-vitals/vite 0.18.0 → 0.20.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.
@@ -53,7 +53,7 @@ function parseHtmlHead(html) {
53
53
  value: attrValue(href),
54
54
  ...asAttr != null ? { hasAs: true, as: asAttr } : {},
55
55
  ...hasCrossorigin ? { hasCrossorigin: true } : {},
56
- // Keep a literal empty hreflang="" (present-but-invalid) so SEO026 can flag it.
56
+ // Keep a literal empty hreflang="" (present-but-invalid) so seo/hreflang can flag it.
57
57
  ...hreflang != null ? { hreflang } : {},
58
58
  ...href ? { href } : {}
59
59
  });
@@ -5,7 +5,7 @@ import { RuleSetting } from '@svelte-vitals/core';
5
5
  interface SvelteVitalsHookOptions {
6
6
  /** Component names treated as meta sources (design §11 layer 4). Mirrors the plugin option. */
7
7
  metaComponents?: string[];
8
- /** Per-rule overrides keyed by rule id, e.g. `{ SEO008: 'off' }`. Mirrors the plugin option. */
8
+ /** Per-rule overrides keyed by rule id, e.g. `{ 'seo/json-ld': 'off' }`. Mirrors the plugin option. */
9
9
  rules?: Record<string, RuleSetting>;
10
10
  }
11
11
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  isLoopbackOrigin,
3
3
  parseHtmlHead
4
- } from "../chunk-4LXPHVAW.js";
4
+ } from "../chunk-HURGA7UH.js";
5
5
 
6
6
  // src/hooks/handle.ts
7
7
  import { DEV } from "esm-env";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Plugin } from 'vite';
2
- import { TreatDynamicAs, RuleSetting, Severity, Category } from '@svelte-vitals/core';
2
+ import { TreatDynamicAs, RuleSetting, RuleOverride, Severity, Category } from '@svelte-vitals/core';
3
3
 
4
4
  interface SvelteVitalsOptions {
5
5
  /** Project root (defaults to the Vite config root / cwd). */
@@ -7,6 +7,8 @@ interface SvelteVitalsOptions {
7
7
  treatDynamicAs?: TreatDynamicAs;
8
8
  metaComponents?: string[];
9
9
  rules?: Record<string, RuleSetting>;
10
+ /** Route-/file-scoped rule overrides applied to build-gate results (option > config file). */
11
+ overrides?: RuleOverride[];
10
12
  /** Minimum severity that fails the build (default: 'critical'). */
11
13
  failOn?: Severity;
12
14
  /** Per-category weights for the combined Health score shown in the JSON/console report (flag > config file > default 1 each). */
package/dist/index.js CHANGED
@@ -2,12 +2,12 @@ import {
2
2
  isLoopbackHost,
3
3
  isLoopbackOrigin,
4
4
  parseHtmlHead
5
- } from "./chunk-4LXPHVAW.js";
5
+ } from "./chunk-HURGA7UH.js";
6
6
 
7
7
  // src/plugin.ts
8
8
  import { existsSync } from "fs";
9
9
  import { writeFile, mkdir } from "fs/promises";
10
- import { join as join4, isAbsolute, dirname, relative as relative2, basename, sep as sep2 } from "path";
10
+ import { join as join4, isAbsolute, dirname, relative as relative3, basename, sep as sep2 } from "path";
11
11
  import { defineConfig as defineConfig2 } from "@svelte-vitals/core";
12
12
  import { loadConfigFile as loadConfigFile2 } from "svelte-vitals";
13
13
 
@@ -16,6 +16,7 @@ import {
16
16
  allRules,
17
17
  selectRules,
18
18
  applyRuleSeverities,
19
+ applyOverrides,
19
20
  runRules,
20
21
  computeScore,
21
22
  summarize,
@@ -150,24 +151,40 @@ function readCoreVersion() {
150
151
  }
151
152
 
152
153
  // src/analyze.ts
153
- async function analyze(prerenderPagesDir, cwd, options) {
154
+ async function analyze(prerenderPagesDir, cwd, options, extraProjectFacts) {
154
155
  const loaded = await loadConfigFile(cwd);
155
156
  const fileConfig = loaded?.config;
156
157
  const warnings = loaded?.warnings ?? [];
157
158
  const weights = options.weights ?? fileConfig?.weights;
159
+ const overrides = options.overrides ?? fileConfig?.overrides;
158
160
  const config = defineConfig({
159
161
  treatDynamicAs: options.treatDynamicAs ?? fileConfig?.treatDynamicAs ?? "pass",
160
162
  metaComponents: options.metaComponents ?? fileConfig?.metaComponents ?? [],
161
163
  rules: options.rules ?? fileConfig?.rules ?? {},
162
164
  failOn: options.failOn ?? fileConfig?.failOn ?? "critical",
163
- ...weights !== void 0 ? { weights } : {}
165
+ ...weights !== void 0 ? { weights } : {},
166
+ ...overrides !== void 0 ? { overrides } : {}
164
167
  });
165
168
  const { heads, headings, images, htmlLang } = await collectRenderedHeads(prerenderPagesDir);
166
- const project = await collectRenderedProject(cwd, htmlLang);
169
+ const project = {
170
+ ...await collectRenderedProject(cwd, htmlLang),
171
+ ...extraProjectFacts
172
+ };
167
173
  const components = await collectComponentFacts(cwd);
168
174
  const kitModules = await collectKitModuleFacts(cwd);
169
- const results = applyRuleSeverities(
170
- await runRules(selectRules(allRules, config), { heads, headings, images, project, components, config, kitModules }),
175
+ const results = applyOverrides(
176
+ applyRuleSeverities(
177
+ await runRules(selectRules(allRules, config), {
178
+ heads,
179
+ headings,
180
+ images,
181
+ project,
182
+ components,
183
+ config,
184
+ kitModules
185
+ }),
186
+ config
187
+ ),
171
188
  config
172
189
  );
173
190
  const { score } = computeScore(results, config);
@@ -190,6 +207,23 @@ Scanned ${components.length} component(s) under src/ for Correctness/Security/Ar
190
207
  };
191
208
  }
192
209
 
210
+ // src/minify-flag.ts
211
+ import { readFile as readFile4 } from "fs/promises";
212
+ import { relative } from "path";
213
+ import { findMinifyDisabled } from "@svelte-vitals/core";
214
+ async function resolveMinifyDisabled(minify, configFile, root) {
215
+ if (minify !== false) return void 0;
216
+ if (!configFile) return {};
217
+ const rel = relative(root, configFile).split("\\").join("/");
218
+ const file = rel === "" ? configFile.split("\\").join("/") : rel;
219
+ let line;
220
+ try {
221
+ line = findMinifyDisabled(await readFile4(configFile, "utf8"))?.line;
222
+ } catch {
223
+ }
224
+ return { file, ...line !== void 0 ? { line } : {} };
225
+ }
226
+
193
227
  // src/ui/middleware.ts
194
228
  import { renderAppShell } from "@svelte-vitals/core";
195
229
 
@@ -382,7 +416,7 @@ function createStore() {
382
416
  }
383
417
 
384
418
  // src/ui/analysis.ts
385
- import { relative, sep } from "path";
419
+ import { relative as relative2, sep } from "path";
386
420
  function createAnalysisRunner(opts) {
387
421
  const debounceMs = opts.debounceMs ?? 500;
388
422
  let cachedAnalyze = opts.analyze;
@@ -431,7 +465,7 @@ function createAnalysisRunner(opts) {
431
465
  },
432
466
  notifyChange(file) {
433
467
  if (stopped) return;
434
- const rel = relative(opts.root, file).split(sep).join("/");
468
+ const rel = relative2(opts.root, file).split(sep).join("/");
435
469
  parseCache.delete(rel);
436
470
  if (timer !== void 0) clearTimeout(timer);
437
471
  timer = setTimeout(() => {
@@ -458,11 +492,17 @@ var CONFIG_BASENAMES = /* @__PURE__ */ new Set([
458
492
  "svelte.config.ts",
459
493
  "svelte-vitals.config.mjs",
460
494
  "svelte-vitals.config.js",
461
- "svelte-vitals.config.ts"
495
+ "svelte-vitals.config.ts",
496
+ "vite.config.js",
497
+ "vite.config.mjs",
498
+ "vite.config.ts",
499
+ "vite.config.cjs",
500
+ "vite.config.mts",
501
+ "vite.config.cts"
462
502
  ]);
463
503
  var IGNORED_SEGMENTS = /* @__PURE__ */ new Set(["node_modules", ".svelte-kit", "build", "dist"]);
464
504
  function isRelevant(file, root) {
465
- const rel = relative2(root, file);
505
+ const rel = relative3(root, file);
466
506
  if (rel === "" || rel.startsWith("..")) return false;
467
507
  const segments = rel.split(sep2);
468
508
  if (segments.some((s) => IGNORED_SEGMENTS.has(s))) return false;
@@ -472,12 +512,14 @@ function isRelevant(file, root) {
472
512
  var DEFAULT_PRERENDER_DIR = ".svelte-kit/output/prerendered/pages";
473
513
  function svelteVitals(options = {}) {
474
514
  let root = options.cwd ?? process.cwd();
515
+ let minifyFlag;
475
516
  const buildPlugin = {
476
517
  name: "svelte-vitals",
477
518
  apply: "build",
478
519
  enforce: "post",
479
520
  configResolved(config) {
480
521
  if (!options.cwd) root = config.root;
522
+ if (!config.build.ssr) minifyFlag = { minify: config.build.minify, configFile: config.configFile };
481
523
  },
482
524
  async closeBundle() {
483
525
  const pagesDir = options.prerenderDir ? options.prerenderDir : join4(root, DEFAULT_PRERENDER_DIR);
@@ -485,7 +527,8 @@ function svelteVitals(options = {}) {
485
527
  if (!existsSync(resolved)) return;
486
528
  let result;
487
529
  try {
488
- result = await analyze(resolved, root, options);
530
+ const viteMinifyDisabled = minifyFlag ? await resolveMinifyDisabled(minifyFlag.minify, minifyFlag.configFile, root) : void 0;
531
+ result = await analyze(resolved, root, options, viteMinifyDisabled ? { viteMinifyDisabled } : void 0);
489
532
  } catch (err) {
490
533
  console.warn(`svelte-vitals: skipped \u2014 analysis failed: ${err instanceof Error ? err.message : String(err)}`);
491
534
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svelte-vitals/vite",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Vite/SvelteKit plugin for svelte-vitals — analyzes prerendered HTML during vite build.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -42,12 +42,12 @@
42
42
  "esm-env": "^1.2.2",
43
43
  "node-html-parser": "^9.0.0",
44
44
  "tinyglobby": "^0.2.17",
45
- "@svelte-vitals/core": "0.26.0",
46
- "svelte-vitals": "0.29.0"
45
+ "@svelte-vitals/core": "0.28.0",
46
+ "svelte-vitals": "0.31.0"
47
47
  },
48
48
  "peerDependencies": {
49
- "@sveltejs/kit": "^2.69.2",
50
- "vite": "^8.1.4"
49
+ "@sveltejs/kit": "^2.70.1",
50
+ "vite": "^8.1.5"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "@sveltejs/kit": {
@@ -55,11 +55,11 @@
55
55
  }
56
56
  },
57
57
  "devDependencies": {
58
- "@sveltejs/kit": "^2.69.2",
58
+ "@sveltejs/kit": "^2.70.1",
59
59
  "@types/node": "^24.13.3",
60
60
  "jsdom": "^29.1.1",
61
- "svelte": "^5.56.4",
62
- "vite": "^8.1.4"
61
+ "svelte": "^5.56.6",
62
+ "vite": "^8.1.5"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "tsup",