@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.
Files changed (2) hide show
  1. package/dist/cli.js +48 -14
  2. 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(body) {
22871
+ async function computeSignature(payload) {
22870
22872
  const key = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
22871
- const data2 = typeof body === "string" ? new TextEncoder().encode(body) : body;
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: "SHA-256" }, false, ["sign"]).then((k) => crypto2.subtle.sign("HMAC", k, data2)).then((sig) => {
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
- const expectedSig = await computeSignature(body);
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> or <Head> \u2014 page title is critical for SEO" }];
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.5",
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.5",
12
- "@vesk/compiler": "^0.2.50-canary.5",
13
- "@vesk/plugin-tailwind": "^0.2.50-canary.5",
14
- "@vesk/runtime": "^0.2.50-canary.5",
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",