---
package: "@webjsdev/server"
version: 0.8.13
date: 2026-06-03T13:20:48.082Z
commit_count: 5
---
## Features

- **emit SRI integrity for live-resolved vendor imports** ([#300](https://github.com/webjsdev/webjs/pull/300)) [`72ae06f9`](https://github.com/webjsdev/webjs/commit/72ae06f9)
  * feat: emit SRI integrity for live-resolved (unpinned) vendor imports
  
  SRI was already computed when an app pins (the pin importmap carries sha384 integrity), but an app with no pin file (the in-repo norm and a fresh scaffold) hit the live-resolve path, which returned integrity:{}, so cross-origin jspm.io modules served with crossorigin but no integrity attribute. A swapped or compromised CDN response then executed unverified.
- **add sitemap() and sitemapIndex() helpers for spec-valid XML** ([#306](https://github.com/webjsdev/webjs/pull/306)) [`9cc6d9af`](https://github.com/webjsdev/webjs/commit/9cc6d9af)
  * feat: add sitemap() and sitemapIndex() helpers for spec-valid XML
  
  An author of app/sitemap.{js,ts} had to hand-construct the entire <urlset> XML string, escaping URLs and formatting lastmod dates by hand, and a malformed string is silently rejected by search engines. There was also no sitemap-index support, so a site over the 50,000-URL / 50MB per-file limit had no built-in sharding path.
- **document the handle() test harness, ship test helpers, fix the saas auth test** ([#308](https://github.com/webjsdev/webjs/pull/308)) [`9df85d23`](https://github.com/webjsdev/webjs/commit/9df85d23)
  createRequestHandler().handle(request) drives the full pipeline (middleware, routing, SSR, actions, auth/CSRF) and the framework's own suite uses it, but it was documented only as an embedding API, with no testRequest() recipe, no helper to build an authenticated/CSRF request, and no helper to round-trip an action through the /__webjs/action/<hash>/<fn> serializer+dispatch path. Actions were tested by direct import, bypassing CSRF and prod error sanitization. The saas template's test asserted only TypeScript shapes and sat on test/unit/, contradicting the documented test/<feature>/ convention.
  
  Add packages/server/src/testing.js (a ./testing export): testRequest fires a native Request through handle(); getCsrf mints a valid token+cookie off the first SSR response (reusing the real csrf.js constants); loginAndGetCookies drives the real credentials login and captures the genuine signed session cookie; actionEndpoint computes the real /__webjs/action/<hash>/<fn> path; and invokeActionForTest round-trips an action through that endpoint with the real serializer + CSRF, so a regression test proves it catches what a direct import misses (a Map surviving only because the wire serializer ran, a 403 on a CSRF-missing request, and prod error sanitization hiding a stack + secret field the direct throw leaks). The saas scaffold now ships a real auth-flow test at test/auth/auth.test.ts: the unauthenticated-protected-route-redirect always runs, and the signup/login/authenticated-render path runs when the DB is set up (skips cleanly otherwise).
- **input validation on the RPC action path, shared with expose()** ([#309](https://github.com/webjsdev/webjs/pull/309)) [`4cbe55d9`](https://github.com/webjsdev/webjs/commit/4cbe55d9)
  * feat: input validation on the RPC action path, shared with expose()
  
  The primary way actions are called (importing them from a client component, which becomes the RPC stub) had no input-validation seam: invokeAction deserialized args and called fn(...args) with no hook. A validate option was honored only on the expose() REST path, so a validator could not be declared once and shared by both paths, and a REST validation failure was a thrown 400 rather than a structured field-error result an app can render.
- **add a webjs doctor project-health command** ([#311](https://github.com/webjsdev/webjs/pull/311)) [`44ff8600`](https://github.com/webjsdev/webjs/commit/44ff8600)
  * feat: add a webjs doctor project-health command
  
  There was no single command to verify a webjs project is set up correctly. webjs has unusually many fragile preconditions (the Node 24+ strip-types floor, the erasableSyntaxOnly TS flag, importmap pin freshness, git-hook activation, env drift, @webjsdev version coherence), each an independent failure mode a contributor onboarding to an existing repo hits only at runtime.
