@vesk/vesk-cli 0.2.50-canary.5 → 0.2.50-canary.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.js +48 -14
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -22862,18 +22862,20 @@ function webhook(options) {
|
|
|
22862
22862
|
secret,
|
|
22863
22863
|
handler,
|
|
22864
22864
|
headerName = "x-webhook-signature",
|
|
22865
|
-
signaturePrefix = "sha256="
|
|
22865
|
+
signaturePrefix = "sha256=",
|
|
22866
|
+
algorithm = "SHA-256",
|
|
22867
|
+
signedPayload
|
|
22866
22868
|
} = options;
|
|
22867
22869
|
if (!secret) throw new Error("webhook() requires a secret");
|
|
22868
22870
|
if (!handler) throw new Error("webhook() requires a handler function");
|
|
22869
|
-
async function computeSignature(
|
|
22871
|
+
async function computeSignature(payload) {
|
|
22870
22872
|
const key = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
22871
|
-
const data2 =
|
|
22873
|
+
const data2 = new TextEncoder().encode(payload);
|
|
22872
22874
|
const crypto2 = globalThis.crypto;
|
|
22873
22875
|
if (!crypto2?.subtle) {
|
|
22874
22876
|
throw new Error("Web Crypto API not available (required for webhook signature verification)");
|
|
22875
22877
|
}
|
|
22876
|
-
return crypto2.subtle.importKey("raw", key, { name: "HMAC", hash:
|
|
22878
|
+
return crypto2.subtle.importKey("raw", key, { name: "HMAC", hash: algorithm }, false, ["sign"]).then((k) => crypto2.subtle.sign("HMAC", k, data2)).then((sig) => {
|
|
22877
22879
|
const hex = Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
22878
22880
|
return hex;
|
|
22879
22881
|
});
|
|
@@ -22893,7 +22895,25 @@ function webhook(options) {
|
|
|
22893
22895
|
});
|
|
22894
22896
|
}
|
|
22895
22897
|
const body = await request.text();
|
|
22896
|
-
|
|
22898
|
+
let parsed;
|
|
22899
|
+
try {
|
|
22900
|
+
parsed = JSON.parse(body);
|
|
22901
|
+
} catch {
|
|
22902
|
+
parsed = body;
|
|
22903
|
+
}
|
|
22904
|
+
const event = parsed;
|
|
22905
|
+
let payload = body;
|
|
22906
|
+
if (signedPayload) {
|
|
22907
|
+
try {
|
|
22908
|
+
payload = signedPayload(event);
|
|
22909
|
+
} catch {
|
|
22910
|
+
return new Response(JSON.stringify({ error: "Invalid signature" }), {
|
|
22911
|
+
status: 401,
|
|
22912
|
+
headers: { "Content-Type": "application/json" }
|
|
22913
|
+
});
|
|
22914
|
+
}
|
|
22915
|
+
}
|
|
22916
|
+
const expectedSig = await computeSignature(payload);
|
|
22897
22917
|
const prefixLen = signaturePrefix.length;
|
|
22898
22918
|
const providedSig = signature.startsWith(signaturePrefix) ? signature.slice(prefixLen) : signature;
|
|
22899
22919
|
if (providedSig.length !== expectedSig.length) {
|
|
@@ -22912,12 +22932,6 @@ function webhook(options) {
|
|
|
22912
22932
|
headers: { "Content-Type": "application/json" }
|
|
22913
22933
|
});
|
|
22914
22934
|
}
|
|
22915
|
-
let event;
|
|
22916
|
-
try {
|
|
22917
|
-
event = JSON.parse(body);
|
|
22918
|
-
} catch {
|
|
22919
|
-
event = body;
|
|
22920
|
-
}
|
|
22921
22935
|
return handler(event, request);
|
|
22922
22936
|
}
|
|
22923
22937
|
return webhookHandler;
|
|
@@ -34359,14 +34373,18 @@ function collectCombinedSource(appDir) {
|
|
|
34359
34373
|
}
|
|
34360
34374
|
return combined;
|
|
34361
34375
|
}
|
|
34376
|
+
function hasMetadataDeclaration(src2) {
|
|
34377
|
+
return /\bdefineMetadata\s*\(|export\s+const\s+metadata\b/.test(src2);
|
|
34378
|
+
}
|
|
34362
34379
|
function runSeoAudit(appDir, _options) {
|
|
34363
34380
|
const combined = collectCombinedSource(appDir);
|
|
34364
34381
|
if (combined.length === 0) {
|
|
34365
34382
|
console.error("vesk seo-audit: no page.vsk files found");
|
|
34366
|
-
return { passed: 0, errors: 0, warnings: 0 };
|
|
34383
|
+
return { passed: 0, errors: 0, warnings: 0, issues: [] };
|
|
34367
34384
|
}
|
|
34368
34385
|
let errors = 0;
|
|
34369
34386
|
let warnings = 0;
|
|
34387
|
+
const allIssues = [];
|
|
34370
34388
|
for (const { path, src: src2 } of combined) {
|
|
34371
34389
|
const relPath = path.replace(appDir, "").replace(/^[\\/]/, "");
|
|
34372
34390
|
const routeDir = relPath === "page.vsk" ? "" : relPath.replace(/[\\/]page\.vsk$/, "");
|
|
@@ -34378,6 +34396,7 @@ function runSeoAudit(appDir, _options) {
|
|
|
34378
34396
|
for (const check of Object.values(SEO_CHECKS)) {
|
|
34379
34397
|
const issues = check(src2);
|
|
34380
34398
|
for (const issue of issues) {
|
|
34399
|
+
allIssues.push({ ...issue, page: relPath || "page.vsk" });
|
|
34381
34400
|
if (issue.severity === SEVERITY.ERROR) {
|
|
34382
34401
|
fileErrors++;
|
|
34383
34402
|
} else {
|
|
@@ -34401,7 +34420,7 @@ function runSeoAudit(appDir, _options) {
|
|
|
34401
34420
|
const total = combined.length;
|
|
34402
34421
|
const status = errors > 0 ? "FAIL" : warnings > 0 ? "PASS_WARN" : "PASS";
|
|
34403
34422
|
console.error(`vesk seo-audit: ${total} pages \u2014 ${errors} errors, ${warnings} warnings [${status}]`);
|
|
34404
|
-
return { passed: total, errors, warnings };
|
|
34423
|
+
return { passed: total, errors, warnings, issues: allIssues };
|
|
34405
34424
|
}
|
|
34406
34425
|
var SEVERITY, SEO_CHECKS;
|
|
34407
34426
|
var init_seo_audit = __esm({
|
|
@@ -34444,6 +34463,12 @@ var init_seo_audit = __esm({
|
|
|
34444
34463
|
return issues;
|
|
34445
34464
|
},
|
|
34446
34465
|
metaDescription: (src2) => {
|
|
34466
|
+
if (hasMetadataDeclaration(src2)) {
|
|
34467
|
+
if (!/\bdescription\s*:/.test(src2)) {
|
|
34468
|
+
return [{ severity: SEVERITY.WARN, message: "No `description` in the metadata declaration" }];
|
|
34469
|
+
}
|
|
34470
|
+
return [];
|
|
34471
|
+
}
|
|
34447
34472
|
if (!/name=["']description["']/.test(src2)) {
|
|
34448
34473
|
return [{ severity: SEVERITY.WARN, message: "Missing meta description" }];
|
|
34449
34474
|
}
|
|
@@ -34451,6 +34476,9 @@ var init_seo_audit = __esm({
|
|
|
34451
34476
|
},
|
|
34452
34477
|
ogTags: (src2) => {
|
|
34453
34478
|
const issues = [];
|
|
34479
|
+
if (hasMetadataDeclaration(src2)) {
|
|
34480
|
+
return issues;
|
|
34481
|
+
}
|
|
34454
34482
|
const required2 = ["og:title", "og:description", "og:image"];
|
|
34455
34483
|
for (const tag of required2) {
|
|
34456
34484
|
const pattern2 = new RegExp(`property=["']${tag}["']`);
|
|
@@ -34467,8 +34495,14 @@ var init_seo_audit = __esm({
|
|
|
34467
34495
|
return [];
|
|
34468
34496
|
},
|
|
34469
34497
|
title: (src2) => {
|
|
34498
|
+
if (hasMetadataDeclaration(src2)) {
|
|
34499
|
+
if (!/\btitle\s*:/.test(src2)) {
|
|
34500
|
+
return [{ severity: SEVERITY.WARN, message: "No `title` in the metadata declaration \u2014 it will render no <title>" }];
|
|
34501
|
+
}
|
|
34502
|
+
return [];
|
|
34503
|
+
}
|
|
34470
34504
|
if (!/<title>/i.test(src2) && !/<Head>/i.test(src2) && !/title>/i.test(src2)) {
|
|
34471
|
-
return [{ severity: SEVERITY.ERROR, message: "Missing <title
|
|
34505
|
+
return [{ severity: SEVERITY.ERROR, message: "Missing <title>, <Head>, or `export const metadata` \u2014 page title is critical for SEO" }];
|
|
34472
34506
|
}
|
|
34473
34507
|
return [];
|
|
34474
34508
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/vesk-cli",
|
|
3
|
-
"version": "0.2.50-canary.
|
|
3
|
+
"version": "0.2.50-canary.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/cli.js",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@vesk/adapter": "^0.2.50-canary.
|
|
12
|
-
"@vesk/compiler": "^0.2.50-canary.
|
|
13
|
-
"@vesk/plugin-tailwind": "^0.2.50-canary.
|
|
14
|
-
"@vesk/runtime": "^0.2.50-canary.
|
|
11
|
+
"@vesk/adapter": "^0.2.50-canary.7",
|
|
12
|
+
"@vesk/compiler": "^0.2.50-canary.7",
|
|
13
|
+
"@vesk/plugin-tailwind": "^0.2.50-canary.7",
|
|
14
|
+
"@vesk/runtime": "^0.2.50-canary.7",
|
|
15
15
|
"esrap": "^2.3.0",
|
|
16
16
|
"typescript": "^5.8.0",
|
|
17
17
|
"ws": "^8.18.0",
|