@svelte-vitals/vite 0.31.1 → 0.32.1
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.
|
@@ -41,8 +41,10 @@ function collectA11y(root) {
|
|
|
41
41
|
const nestedLandmarks = [];
|
|
42
42
|
const ids = [];
|
|
43
43
|
const idRefs = [];
|
|
44
|
+
const elementTags = /* @__PURE__ */ new Set();
|
|
44
45
|
const walk = (el, ctx) => {
|
|
45
46
|
const tag = el.rawTagName?.toLowerCase();
|
|
47
|
+
if (tag && ctx.inBody) elementTags.add(tag);
|
|
46
48
|
const roleAttr = el.getAttribute("role");
|
|
47
49
|
let landmark;
|
|
48
50
|
if (roleAttr !== void 0) {
|
|
@@ -76,12 +78,13 @@ function collectA11y(root) {
|
|
|
76
78
|
const nextCtx = {
|
|
77
79
|
sectioning: ctx.sectioning + (SECTIONING_TAGS.has(tag) ? 1 : 0),
|
|
78
80
|
asideDemoting: ctx.asideDemoting + (ASIDE_DEMOTING_TAGS.has(tag) ? 1 : 0),
|
|
79
|
-
landmarks: landmark ? [...ctx.landmarks, landmark] : ctx.landmarks
|
|
81
|
+
landmarks: landmark ? [...ctx.landmarks, landmark] : ctx.landmarks,
|
|
82
|
+
inBody: ctx.inBody || tag === "body"
|
|
80
83
|
};
|
|
81
84
|
for (const child of el.children) walk(child, nextCtx);
|
|
82
85
|
};
|
|
83
|
-
for (const child of root.children) walk(child, { sectioning: 0, asideDemoting: 0, landmarks: [] });
|
|
84
|
-
return { landmarks, nestedLandmarks, ids, idRefs };
|
|
86
|
+
for (const child of root.children) walk(child, { sectioning: 0, asideDemoting: 0, landmarks: [], inBody: false });
|
|
87
|
+
return { landmarks, nestedLandmarks, ids, idRefs, elementTags: [...elementTags] };
|
|
85
88
|
}
|
|
86
89
|
function parseHtmlHead(html) {
|
|
87
90
|
const root = parse(html);
|
|
@@ -228,7 +231,10 @@ async function collectRenderedHeads(prerenderPagesDir) {
|
|
|
228
231
|
idCandidates: [...new Set(parsed.ids)],
|
|
229
232
|
// The prerendered document IS the closed world: every id/landmark/reference it can ever
|
|
230
233
|
// have is already in it, unlike source mode which may hit an unresolved component.
|
|
231
|
-
fullyResolved: true
|
|
234
|
+
fullyResolved: true,
|
|
235
|
+
elementTags: parsed.elementTags,
|
|
236
|
+
elementsClosed: true,
|
|
237
|
+
file: rel
|
|
232
238
|
});
|
|
233
239
|
}
|
|
234
240
|
return { heads, headings, images, a11y, htmlLang };
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ interface SvelteVitalsHookOptions {
|
|
|
9
9
|
rules?: Record<string, RuleSetting>;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* SvelteKit `handle` that analyzes each visited page's rendered
|
|
12
|
+
* SvelteKit `handle` that analyzes each visited page's rendered HTML, in dev only,
|
|
13
13
|
* and (when the live dashboard is enabled) feeds the results in — upgrading that
|
|
14
14
|
* route's dashboard findings from static (source-only) to `measured` (real rendered
|
|
15
15
|
* HTML). Add it to `src/hooks.server.ts`, e.g. `sequence(svelteVitalsHandle())`.
|
package/dist/hooks/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
isLoopbackOrigin,
|
|
3
3
|
parseHtmlHead,
|
|
4
4
|
toOccurrenceMap
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-KII3SU3J.js";
|
|
6
6
|
|
|
7
7
|
// src/hooks/handle.ts
|
|
8
8
|
import { DEV } from "esm-env";
|
|
@@ -10,6 +10,7 @@ import { defineConfig } from "@svelte-vitals/core";
|
|
|
10
10
|
import {
|
|
11
11
|
allRules,
|
|
12
12
|
applyRuleSeverities,
|
|
13
|
+
defaultProject,
|
|
13
14
|
effectiveSeverity,
|
|
14
15
|
formatFailedRuleWarning,
|
|
15
16
|
isPenalized,
|
|
@@ -43,16 +44,7 @@ async function postIngest(origin, route, results, failedRuleIds) {
|
|
|
43
44
|
}
|
|
44
45
|
async function analyzeAndIngest(html, route, origin, rules, config, lastSignature) {
|
|
45
46
|
try {
|
|
46
|
-
const {
|
|
47
|
-
tags,
|
|
48
|
-
htmlLang,
|
|
49
|
-
headings: levels,
|
|
50
|
-
images: imgs,
|
|
51
|
-
landmarks,
|
|
52
|
-
nestedLandmarks,
|
|
53
|
-
ids,
|
|
54
|
-
idRefs
|
|
55
|
-
} = parseHtmlHead(html);
|
|
47
|
+
const { tags, headings: levels, images: imgs, landmarks, nestedLandmarks, ids, idRefs } = parseHtmlHead(html);
|
|
56
48
|
const head = { route, source: "rendered", tags, file: route };
|
|
57
49
|
const headings = [
|
|
58
50
|
{ route, headings: levels.map((level) => ({ level, line: 0, file: route })) }
|
|
@@ -69,13 +61,12 @@ async function analyzeAndIngest(html, route, origin, rules, config, lastSignatur
|
|
|
69
61
|
fullyResolved: true
|
|
70
62
|
}
|
|
71
63
|
];
|
|
72
|
-
const project = { hasRobotsTxt: true, hasSitemap: true, htmlLang };
|
|
73
64
|
const { results: ruleResults, failedRules } = await runRules(rules, {
|
|
74
65
|
heads: [head],
|
|
75
66
|
headings,
|
|
76
67
|
images,
|
|
77
68
|
a11y,
|
|
78
|
-
project,
|
|
69
|
+
project: defaultProject,
|
|
79
70
|
config
|
|
80
71
|
});
|
|
81
72
|
const results = applyRuleSeverities(ruleResults, config);
|
|
@@ -99,7 +90,7 @@ function svelteVitalsHandle(options = {}) {
|
|
|
99
90
|
metaComponents: options.metaComponents ?? [],
|
|
100
91
|
rules: options.rules ?? {}
|
|
101
92
|
});
|
|
102
|
-
const rules = selectRules(allRules, config);
|
|
93
|
+
const rules = selectRules(allRules, config).filter((r) => r.scope === "route" && !r.crossRoute);
|
|
103
94
|
const lastSignature = /* @__PURE__ */ new Map();
|
|
104
95
|
return ({ event, resolve }) => {
|
|
105
96
|
let buffer = "";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
collectRenderedHeads,
|
|
3
3
|
isLoopbackOrigin
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KII3SU3J.js";
|
|
5
5
|
|
|
6
6
|
// src/plugin.ts
|
|
7
7
|
import { existsSync } from "fs";
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
selectRules,
|
|
25
25
|
applyRuleSeverities,
|
|
26
26
|
applyOverrides,
|
|
27
|
+
applyInlineDirectives,
|
|
28
|
+
unknownDirectiveIds,
|
|
27
29
|
runRules,
|
|
28
30
|
withFailedRulesOff,
|
|
29
31
|
formatFailedRuleWarning,
|
|
@@ -184,6 +186,11 @@ async function analyze(prerenderPagesDir, cwd, options, extraProjectFacts, resol
|
|
|
184
186
|
};
|
|
185
187
|
const kitModules = await collectKitModuleFacts(cwd, project.kitAliases);
|
|
186
188
|
const selected = selectRules(allRules, config);
|
|
189
|
+
if (selected.some((r) => r.id === "a11y/unverified-id-ref")) {
|
|
190
|
+
warnings.push(
|
|
191
|
+
"a11y/unverified-id-ref has no effect in rendered mode \u2014 the prerendered document is always fully resolved."
|
|
192
|
+
);
|
|
193
|
+
}
|
|
187
194
|
const {
|
|
188
195
|
results: rawResults,
|
|
189
196
|
examined,
|
|
@@ -199,8 +206,19 @@ async function analyze(prerenderPagesDir, cwd, options, extraProjectFacts, resol
|
|
|
199
206
|
kitModules,
|
|
200
207
|
sourceFiles
|
|
201
208
|
});
|
|
202
|
-
const
|
|
209
|
+
const directives = /* @__PURE__ */ new Map();
|
|
210
|
+
for (const c of components) directives.set(c.file, c.suppressions ?? []);
|
|
211
|
+
for (const m of kitModules) directives.set(m.file, m.suppressions ?? []);
|
|
212
|
+
if (project.viteMinifyDisabled?.file)
|
|
213
|
+
directives.set(project.viteMinifyDisabled.file, project.viteMinifyDisabled.suppressions ?? []);
|
|
214
|
+
const results = applyInlineDirectives(
|
|
215
|
+
applyOverrides(applyRuleSeverities(rawResults, config), config),
|
|
216
|
+
directives,
|
|
217
|
+
selected,
|
|
218
|
+
config
|
|
219
|
+
);
|
|
203
220
|
warnings.push(...skippedFileWarnings([...components, ...kitModules]));
|
|
221
|
+
warnings.push(...unknownDirectiveIds(directives, allRules));
|
|
204
222
|
for (const f of failedRules) warnings.push(formatFailedRuleWarning(f));
|
|
205
223
|
const scoringConfig = withFailedRulesOff(
|
|
206
224
|
config,
|
|
@@ -235,18 +253,28 @@ Scanned ${components.length} component(s) under src/ for Correctness/Security/Ar
|
|
|
235
253
|
// src/minify-flag.ts
|
|
236
254
|
import { readFile as readFile3 } from "fs/promises";
|
|
237
255
|
import { relative } from "path";
|
|
238
|
-
import {
|
|
256
|
+
import {
|
|
257
|
+
collectSuppressions,
|
|
258
|
+
findMinifyDisabled
|
|
259
|
+
} from "@svelte-vitals/core/internal";
|
|
239
260
|
async function resolveMinifyDisabled(minify, configFile, root) {
|
|
240
261
|
if (minify !== false) return void 0;
|
|
241
262
|
if (!configFile) return {};
|
|
242
263
|
const rel = relative(root, configFile).split("\\").join("/");
|
|
243
264
|
const file = rel === "" ? configFile.split("\\").join("/") : rel;
|
|
244
265
|
let line;
|
|
266
|
+
let suppressions;
|
|
245
267
|
try {
|
|
246
|
-
|
|
268
|
+
const source = await readFile3(configFile, "utf8");
|
|
269
|
+
line = findMinifyDisabled(source)?.line;
|
|
270
|
+
suppressions = collectSuppressions(source);
|
|
247
271
|
} catch {
|
|
248
272
|
}
|
|
249
|
-
return {
|
|
273
|
+
return {
|
|
274
|
+
file,
|
|
275
|
+
...line !== void 0 ? { line } : {},
|
|
276
|
+
...suppressions !== void 0 ? { suppressions } : {}
|
|
277
|
+
};
|
|
250
278
|
}
|
|
251
279
|
|
|
252
280
|
// src/ui/middleware.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svelte-vitals/vite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.1",
|
|
4
4
|
"description": "Vite/SvelteKit plugin for svelte-vitals — analyzes prerendered HTML during vite build, plus a live dev dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"esm-env": "^1.2.2",
|
|
43
43
|
"node-html-parser": "^9.0.1",
|
|
44
44
|
"tinyglobby": "^0.2.17",
|
|
45
|
-
"
|
|
46
|
-
"svelte-vitals": "0.
|
|
45
|
+
"svelte-vitals": "0.50.0",
|
|
46
|
+
"@svelte-vitals/core": "0.47.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@sveltejs/kit": "^2.70.
|
|
49
|
+
"@sveltejs/kit": "^2.70.3",
|
|
50
50
|
"vite": "^8.2.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependenciesMeta": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@sveltejs/kit": "^2.70.
|
|
58
|
+
"@sveltejs/kit": "^2.70.3",
|
|
59
59
|
"@types/node": "^24.13.3",
|
|
60
60
|
"jsdom": "^30.0.1",
|
|
61
61
|
"svelte": "^5.56.9",
|