svelte-vitals 0.5.2 → 0.6.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 +1 -1
- package/dist/{chunk-LQPB2WAL.js → chunk-LWN65ZOR.js} +50 -14
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -164,6 +164,13 @@ function attrValue(attributes, name) {
|
|
|
164
164
|
if (v && v.type === "ExpressionTag") return "dynamic";
|
|
165
165
|
return "absent";
|
|
166
166
|
}
|
|
167
|
+
function lineOf(source, offset) {
|
|
168
|
+
if (typeof offset !== "number" || offset < 0) return 0;
|
|
169
|
+
let line = 1;
|
|
170
|
+
const end = Math.min(offset, source.length);
|
|
171
|
+
for (let i = 0; i < end; i++) if (source[i] === "\n") line++;
|
|
172
|
+
return line;
|
|
173
|
+
}
|
|
167
174
|
function findAttr(attributes, name) {
|
|
168
175
|
if (!Array.isArray(attributes)) return void 0;
|
|
169
176
|
return attributes.find((a) => a?.type === "Attribute" && a.name === name);
|
|
@@ -231,16 +238,39 @@ function collectComponents(node, acc) {
|
|
|
231
238
|
if (key in node) collectComponents(node[key], acc);
|
|
232
239
|
}
|
|
233
240
|
}
|
|
241
|
+
function collectImages(node, source, acc) {
|
|
242
|
+
if (Array.isArray(node)) {
|
|
243
|
+
for (const child of node) collectImages(child, source, acc);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (!node || typeof node !== "object") return;
|
|
247
|
+
if (node.type === "RegularElement" && node.name === "img") {
|
|
248
|
+
const attrs = node.attributes ?? [];
|
|
249
|
+
const hasSpread = attrs.some((a) => a?.type === "SpreadAttribute");
|
|
250
|
+
acc.push({
|
|
251
|
+
hasWidth: hasSpread || Boolean(findAttr(attrs, "width")),
|
|
252
|
+
hasHeight: hasSpread || Boolean(findAttr(attrs, "height")),
|
|
253
|
+
hasLoading: hasSpread || Boolean(findAttr(attrs, "loading")),
|
|
254
|
+
line: lineOf(source, node.start)
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
for (const key of CHILD_NODE_KEYS) {
|
|
258
|
+
if (key in node) collectImages(node[key], source, acc);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
234
261
|
function parseFile(source, filename) {
|
|
235
262
|
const ast = parse(source, { modern: true, filename });
|
|
236
263
|
const heads = [];
|
|
237
264
|
collectSvelteHeads(ast.fragment ?? ast, heads);
|
|
238
265
|
const components = [];
|
|
239
266
|
collectComponents(ast.fragment ?? ast, components);
|
|
267
|
+
const images = [];
|
|
268
|
+
collectImages(ast.fragment ?? ast, source, images);
|
|
240
269
|
return {
|
|
241
270
|
headTags: heads.flatMap(tagsFromHead),
|
|
242
271
|
components,
|
|
243
|
-
imports: collectImports(ast)
|
|
272
|
+
imports: collectImports(ast),
|
|
273
|
+
images
|
|
244
274
|
};
|
|
245
275
|
}
|
|
246
276
|
|
|
@@ -403,9 +433,13 @@ async function resolveRoute(rt, cwd, pageRel, config) {
|
|
|
403
433
|
const composed = /* @__PURE__ */ new Map();
|
|
404
434
|
let broadOwn = false;
|
|
405
435
|
let broadInherited = false;
|
|
436
|
+
const images = [];
|
|
406
437
|
for (const { rel, isPage } of files) {
|
|
407
438
|
const source = await rt.readFile(rt.join(cwd, rel));
|
|
408
439
|
const parsed = parseFile(source, rel);
|
|
440
|
+
for (const img of parsed.images) {
|
|
441
|
+
images.push({ ...img, file: rel });
|
|
442
|
+
}
|
|
409
443
|
const resolved = await resolveFileTags(rt, cwd, rel, parsed, config, MAX_DEPTH, /* @__PURE__ */ new Set([rel]));
|
|
410
444
|
for (const tag of resolved.tags) {
|
|
411
445
|
composed.set(tagKey(tag), { ...tag, presence: isPage ? "own" : "inherited", file: rel });
|
|
@@ -422,20 +456,20 @@ async function resolveRoute(rt, cwd, pageRel, config) {
|
|
|
422
456
|
if (!composed.has(key)) composed.set(key, { ...tag, presence });
|
|
423
457
|
}
|
|
424
458
|
}
|
|
459
|
+
const route = deriveRoute(pageRel);
|
|
425
460
|
return {
|
|
426
|
-
route:
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
461
|
+
head: { route, source: "static", tags: [...composed.values()], file: pageRel },
|
|
462
|
+
images: { route, images }
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
async function collectRoutes(rt, cwd, config = defaultConfig) {
|
|
466
|
+
const pages = await enumerateRoutePages(rt, cwd);
|
|
467
|
+
const facts = await Promise.all(pages.map((page) => resolveRoute(rt, cwd, page, config)));
|
|
468
|
+
return {
|
|
469
|
+
heads: facts.map((f) => f.head),
|
|
470
|
+
images: facts.map((f) => f.images)
|
|
430
471
|
};
|
|
431
472
|
}
|
|
432
|
-
var sourceHeadProvider = {
|
|
433
|
-
mode: "static",
|
|
434
|
-
async collect(rt, cwd, config = defaultConfig) {
|
|
435
|
-
const pages = await enumerateRoutePages(rt, cwd);
|
|
436
|
-
return Promise.all(pages.map((page) => resolveRoute(rt, cwd, page, config)));
|
|
437
|
-
}
|
|
438
|
-
};
|
|
439
473
|
|
|
440
474
|
// src/version.ts
|
|
441
475
|
import { readFileSync } from "fs";
|
|
@@ -513,10 +547,12 @@ async function analyzeProject(opts = {}) {
|
|
|
513
547
|
});
|
|
514
548
|
await detectProject(rt, cwd);
|
|
515
549
|
const matches = routeMatcher(opts.route);
|
|
516
|
-
const
|
|
550
|
+
const collected = await collectRoutes(rt, cwd, config);
|
|
551
|
+
const heads = collected.heads.filter((h) => matches(h.route));
|
|
552
|
+
const images = collected.images.filter((i) => matches(i.route));
|
|
517
553
|
const project = await collectProjectFacts(rt, cwd);
|
|
518
554
|
const rules = selectRules(allRules2, config);
|
|
519
|
-
const results = applyRuleSeverities(await runRules(rules, { heads, project, config }), config);
|
|
555
|
+
const results = applyRuleSeverities(await runRules(rules, { heads, images, project, config }), config);
|
|
520
556
|
return { results, config, version: readPackageVersion() };
|
|
521
557
|
}
|
|
522
558
|
async function run(opts = {}) {
|
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.6.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",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"mri": "^1.2.0",
|
|
43
43
|
"svelte": "^5.56.3",
|
|
44
44
|
"tinyglobby": "^0.2.17",
|
|
45
|
-
"@svelte-vitals/core": "0.
|
|
45
|
+
"@svelte-vitals/core": "0.8.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^24.7.0"
|