@nifrajs/cli 1.6.0 → 1.11.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.
Files changed (57) hide show
  1. package/README.md +25 -0
  2. package/dist/assure.d.ts +11 -0
  3. package/dist/assure.d.ts.map +1 -0
  4. package/dist/assure.js +67 -0
  5. package/dist/assure.js.map +1 -0
  6. package/dist/capabilities-tool.d.ts +33 -0
  7. package/dist/capabilities-tool.d.ts.map +1 -0
  8. package/dist/capabilities-tool.js +320 -0
  9. package/dist/capabilities-tool.js.map +1 -0
  10. package/dist/check.d.ts +1 -1
  11. package/dist/check.d.ts.map +1 -1
  12. package/dist/check.js +117 -11
  13. package/dist/check.js.map +1 -1
  14. package/dist/cli.d.ts.map +1 -1
  15. package/dist/cli.js +196 -9
  16. package/dist/cli.js.map +1 -1
  17. package/dist/levels-tool.d.ts +37 -0
  18. package/dist/levels-tool.d.ts.map +1 -0
  19. package/dist/levels-tool.js +180 -0
  20. package/dist/levels-tool.js.map +1 -0
  21. package/dist/manifest-tool.d.ts +15 -0
  22. package/dist/manifest-tool.d.ts.map +1 -0
  23. package/dist/manifest-tool.js +67 -0
  24. package/dist/manifest-tool.js.map +1 -0
  25. package/dist/mcp-http.js +1 -1
  26. package/dist/mcp-http.js.map +1 -1
  27. package/dist/mcp.d.ts +1 -0
  28. package/dist/mcp.d.ts.map +1 -1
  29. package/dist/mcp.js +31 -0
  30. package/dist/mcp.js.map +1 -1
  31. package/dist/recipes/1.8.0.d.ts +12 -0
  32. package/dist/recipes/1.8.0.d.ts.map +1 -0
  33. package/dist/recipes/1.8.0.js +20 -0
  34. package/dist/recipes/1.8.0.js.map +1 -0
  35. package/dist/recipes/index.d.ts +28 -0
  36. package/dist/recipes/index.d.ts.map +1 -0
  37. package/dist/recipes/index.js +27 -0
  38. package/dist/recipes/index.js.map +1 -0
  39. package/dist/upgrade.d.ts +82 -0
  40. package/dist/upgrade.d.ts.map +1 -0
  41. package/dist/upgrade.js +220 -0
  42. package/dist/upgrade.js.map +1 -0
  43. package/docs/examples.json +12 -0
  44. package/docs/llms-full.txt +419 -13
  45. package/docs/types.json +1923 -32
  46. package/package.json +8 -8
  47. package/src/assure.ts +88 -0
  48. package/src/capabilities-tool.ts +406 -0
  49. package/src/check.ts +135 -12
  50. package/src/cli.ts +203 -14
  51. package/src/levels-tool.ts +222 -0
  52. package/src/manifest-tool.ts +103 -0
  53. package/src/mcp-http.ts +1 -1
  54. package/src/mcp.ts +37 -0
  55. package/src/recipes/1.8.0.ts +21 -0
  56. package/src/recipes/index.ts +52 -0
  57. package/src/upgrade.ts +269 -0
@@ -1682,6 +1682,89 @@ trustworthy client IP can be derived, and never trusts `X-Forwarded-For` unless
1682
1682
  bodies before routing (fails closed with `411` on a length-less body). The read-time
1683
1683
  guard above (`c.boundedBody` / schema cap) remains the source of truth.
1684
1684
 
1685
+ ### Route assurance — prove every route is guarded
1686
+
1687
+ Installing security middleware is not the same as proving it covers every route. Nifra's
1688
+ official auth, CSRF, body-limit, rate-limit, idempotency, IP-restriction, and security-header
1689
+ modules publish reflection-safe evidence at the hook where they enforce it. A policy then
1690
+ classifies every route and fails closed when evidence is missing or forbidden.
1691
+
1692
+ ```ts
1693
+ // doc-check: skip — configuration file imports your application backend.
1694
+ // nifra.assurance.ts
1695
+ import { defineAssuranceConfig, NIFRA_ASSURANCE } from "@nifrajs/core/assurance"
1696
+ import { app } from "./backend.ts"
1697
+
1698
+ export default defineAssuranceConfig({
1699
+ source: app,
1700
+ policy: {
1701
+ // First match owns the route: put narrow exceptions before broad defaults.
1702
+ rules: [
1703
+ { name: "health", match: { paths: ["/health"] }, require: [],
1704
+ forbid: [NIFRA_ASSURANCE.AUTHENTICATED] },
1705
+ { name: "mutation", match: { methods: ["POST", "PUT", "PATCH", "DELETE"] },
1706
+ require: [NIFRA_ASSURANCE.AUTHENTICATED, NIFRA_ASSURANCE.CSRF,
1707
+ NIFRA_ASSURANCE.BODY_BOUNDED] },
1708
+ { name: "read", match: { methods: ["GET", "HEAD"] },
1709
+ require: [NIFRA_ASSURANCE.AUTHENTICATED] },
1710
+ ],
1711
+ },
1712
+ })
1713
+
1714
+ // CI: nifra assure # human diagnostics
1715
+ // CI: nifra assure --json # complete machine-readable report
1716
+ ```
1717
+
1718
+ Evidence follows real lifecycle semantics: pre-routing and response hooks cover the whole app,
1719
+ while authentication and other order-scoped hooks cover only routes registered after them.
1720
+ Method and path filters prevent a narrow guard from claiming broader coverage. The evaluation
1721
+ runs only through reflection or `nifra assure`, so requests pay no assurance cost.
1722
+
1723
+ ### Effect assurance — declared capability versus provenance
1724
+
1725
+ Authentication does not reveal what a route can do. Capability assurance compares an exact
1726
+ route declaration against every approved effect import reachable through that route's local
1727
+ module graph. Static, dynamic, `require`, and re-export edges are scanned; raw provider
1728
+ imports fail `nifra check`. Runtime beacons add denial at owned adapters, but are never
1729
+ treated as a substitute for static provenance.
1730
+
1731
+ ```ts
1732
+ // doc-check: skip — combines route and assurance-config excerpts.
1733
+ // route: exact effect declaration + runtime beacon at the owned adapter seam
1734
+ import { useCapability } from "@nifrajs/core/capabilities"
1735
+
1736
+ app.post("/orders", { capabilities: ["db.write"] }, async (c) => {
1737
+ useCapability(c, "db.write") // undeclared use fails before the effect
1738
+ return orders.write(c.body)
1739
+ })
1740
+
1741
+ // in nifra.assurance.ts, alongside policy:
1742
+ capabilities: {
1743
+ definitions: [
1744
+ { id: "db.read", zone: "domain", access: "read" },
1745
+ { id: "db.write", zone: "domain", access: "write", idempotency: "request" },
1746
+ { id: "telemetry.write", zone: "operational", access: "write" },
1747
+ ],
1748
+ provenance: {
1749
+ // Use effect-specific facades. A broad module that mixes reads/writes cannot prove either.
1750
+ imports: [
1751
+ { specifier: "@app/db/read", capabilities: ["db.read"] },
1752
+ { specifier: "@app/db/write", capabilities: ["db.write"] },
1753
+ ],
1754
+ forbiddenImports: [
1755
+ { specifier: "postgres", reason: "use the tenant-scoped DB facade" },
1756
+ ],
1757
+ },
1758
+ }
1759
+
1760
+ // developer: nifra capabilities snapshot
1761
+ // CI: nifra check && nifra assure && nifra capabilities check
1762
+ ```
1763
+
1764
+ Domain writes on `GET`/`HEAD` are hard violations. Each write definition may
1765
+ require request idempotency or durable command/provider-key evidence. The lockfile contains only
1766
+ method, path, and capability tokens—no payloads or tenant data—and CI never rewrites it.
1767
+
1685
1768
  ### Already built in
1686
1769
 
1687
1770
  These add to Nifra's standing defaults: strict-by-default schema validation (unknown fields
@@ -3148,9 +3231,10 @@ backend over HTTP — so a browser `POST /api/sync` hit the page router and 404/
3148
3231
  until you hand-wrote a dispatch branch in `server-bun.ts`. Now
3149
3232
  `createWebApp` mounts it for you: a request whose pathname is exactly
3150
3233
  `apiPrefix` (default `/api`) or starts with
3151
- `apiPrefix + "/"` is dispatched to `api.fetch(req.url, req)`
3152
- **before** page routing, and the backend's `Response` is returned
3153
- untouched (the request body is passed through, never pre-read).
3234
+ `apiPrefix + "/"` is dispatched through Nifra's platform-aware backend mount
3235
+ interface **before** page routing. The backend receives the same Workers
3236
+ `env` bindings and `waitUntil` lifetime as the web app, and its
3237
+ `Response` is returned untouched (the request body is passed through, never pre-read).
3154
3238
 
3155
3239
  ```ts
3156
3240
  // server.ts (prod) — createWebApp serves pages AND auto-mounts the backend at /api/*.
@@ -3224,6 +3308,55 @@ They share the backend: a route `action` and a browser `fetch` can both
3224
3308
  call `POST /api/sync` — one in-process, one over the mount — and get identical
3225
3309
  validation and behavior.
3226
3310
 
3311
+ ## Nifra — Request budgets
3312
+
3313
+ > Propagate one absolute deadline through Nifra requests and downstream adapters without resetting time at each hop.
3314
+
3315
+ A timeout should not restart at every hop. Nifra admits one absolute wire deadline, clamps it
3316
+ to local policy, and exposes monotonic remaining time beside the existing cancellation signal.
3317
+
3318
+ ### Clamp once at admission
3319
+
3320
+ ```ts
3321
+ import { server } from "@nifrajs/core"
3322
+
3323
+ const app = server({
3324
+ requestTimeoutMs: 2_000,
3325
+ acceptInboundDeadlines: true,
3326
+ maxInboundDeadlineMs: 5_000,
3327
+ }).get("/report", async (c) => {
3328
+ // c.signal aborts at the SAME effective deadline.
3329
+ // remaining() is monotonic even if the wall clock jumps.
3330
+ return { remainingMs: c.budget.remaining() }
3331
+ })
3332
+ ```
3333
+
3334
+ The canonical header is `x-nifra-deadline`, containing Unix epoch milliseconds.
3335
+ Admission is an explicit trust-boundary choice via `acceptInboundDeadlines`; ordinary
3336
+ public routes ignore the header by default. Once enabled, a client value can only shorten
3337
+ local work. Malformed values return 400, expired values return 408, and a request that exhausts
3338
+ an inherited deadline returns 504.
3339
+
3340
+ ### Reserve time for the caller
3341
+
3342
+ ```ts
3343
+ // doc-check: skip — context and downstream adapter are established by the app
3344
+ const child = c.budget.child(50) // keep 50ms to serialize the response
3345
+
3346
+ await fetch(url, {
3347
+ signal: child.signal,
3348
+ headers: withDeadlineHeader(undefined, child),
3349
+ })
3350
+ ```
3351
+
3352
+ `child(reserveMs)` preserves response cleanup time without resetting the absolute
3353
+ deadline. Downstream adapters must also use `remaining()` for their actual timeout;
3354
+ forwarding the header alone is decorative.
3355
+
3356
+ Configure a finite `requestTimeoutMs` before handing `c.budget` to a
3357
+ production adapter. The no-timeout compatibility path is deliberately unbounded and is not
3358
+ written to the wire.
3359
+
3227
3360
  ## Nifra — Framework contract
3228
3361
 
3229
3362
  > The one-page contract: LoaderContext shape, loader/action/meta/head signatures, the client↔server boundary, and the build-output contract — every signature verified against the source.
@@ -4160,6 +4293,117 @@ backend you can also ship on its own. Start with [Getting started](/docs).
4160
4293
  Moving a backend (Express, Hono, Fastify, Elysia) instead? See
4161
4294
  [Migrating a backend](/docs/migrate-backend).
4162
4295
 
4296
+ ## Nifra — Contract-derived adversarial testing
4297
+
4298
+ > Turn route schemas into hostile input, response-conformance, replay, shrinking, and runtime-matrix tests with @nifrajs/testing.
4299
+
4300
+ A route contract should be more than documentation. `@nifrajs/testing` turns it
4301
+ into a laboratory: valid requests, hostile inputs, real boundary rejection, response
4302
+ conformance, shrinking, replay seeds, and adapter parity from one small test interface.
4303
+
4304
+ ### One assertion, every contracted boundary
4305
+
4306
+ ```ts
4307
+ import { assertAdversarialContract } from "@nifrajs/testing"
4308
+ import { app } from "../src/app"
4309
+
4310
+ const { test } = await import("bun:test")
4311
+
4312
+ test("the API contract withstands hostile inputs", async () => {
4313
+ await assertAdversarialContract(app, { seed: 73 })
4314
+ })
4315
+ ```
4316
+
4317
+ For every selected route, the laboratory synthesizes a valid **contract witness**. It then
4318
+ changes types, removes required fields, crosses numeric and length bounds, inserts unknown
4319
+ properties, and descends into nested objects and arrays. A mutation is sent only after the
4320
+ route's own Standard Schema validator proves it invalid. Query values are proved after URL
4321
+ serialization, exactly as the server receives them.
4322
+
4323
+ Invalid inputs must produce 422 by default. A valid witness is also executed for every
4324
+ declared `response`, and the real JSON body is validated off the request hot path.
4325
+ Use `expectedValidationStatuses` or `isRejected` when your app deliberately
4326
+ has a different validation response.
4327
+
4328
+ ### Opaque schemas stay validator-neutral
4329
+
4330
+ Nifra's `t` schemas carry inspectable JSON Schema, so witness generation is
4331
+ automatic. Other Standard Schema libraries do not have to expose structure. Supply a known-good
4332
+ witness; their own validator still proves every hostile mutation.
4333
+
4334
+ ```ts
4335
+ // Standard Schema guarantees validation, not introspection.
4336
+ // Give opaque Zod/Valibot/ArkType routes only their known-good request values.
4337
+ await assertAdversarialContract(app, {
4338
+ witnesses: {
4339
+ "POST /users/:id": {
4340
+ params: { id: "user-1" },
4341
+ body: { name: "Ada" },
4342
+ query: { notify: "true" },
4343
+ },
4344
+ },
4345
+ })
4346
+ ```
4347
+
4348
+ Missing, invalid, or unsynthesizable witnesses become explicit coverage gaps. The default is
4349
+ fail-closed; `requireCoverage: false` makes gaps advisory.
4350
+
4351
+ ### Auth and tenant context
4352
+
4353
+ `prepareRequest` runs for every case and runtime. Use it to attach a test session,
4354
+ tenant identity, signed headers, or platform bindings without putting secrets into reports.
4355
+
4356
+ ```ts
4357
+ await assertAdversarialContract(app, {
4358
+ prepareRequest(request, context) {
4359
+ const headers = new Headers(request.headers)
4360
+ headers.set("authorization", "Bearer test-session")
4361
+ headers.set("x-tenant-id", context.runtime === "worker" ? "edge-test" : "local-test")
4362
+ return new Request(request, { headers })
4363
+ },
4364
+ })
4365
+ ```
4366
+
4367
+ ### One contract, many runtimes
4368
+
4369
+ Supply fetch targets to exercise the identical cases through Bun, Node, Deno, or Workers
4370
+ adapters. Reflection still comes from the original app, so there is one authoritative contract.
4371
+
4372
+ ```ts
4373
+ const report = await assertAdversarialContract(app, {
4374
+ runtimes: [
4375
+ { name: "bun", fetch: (request) => bunApp.fetch(request) },
4376
+ { name: "node", fetch: (request) => nodeAdapter.fetch(request) },
4377
+ { name: "worker", fetch: (request) => worker.fetch(request, env) },
4378
+ ],
4379
+ })
4380
+
4381
+ // Each target receives the same case IDs and deterministic witnesses.
4382
+ console.log(report.seed, report.counts)
4383
+ ```
4384
+
4385
+ ### Shrink and replay failures
4386
+
4387
+ Unexpectedly accepted hostile inputs are greedily reduced to a smaller validator-invalid
4388
+ request. Results do not print request bodies or headers; the stable case ID, runtime, and seed
4389
+ are enough to replay deterministically.
4390
+
4391
+ ```ts
4392
+ const report = await runAdversarialContract(app, { seed: 73 })
4393
+ const failure = report.failures[0]
4394
+
4395
+ // CI can print this small, payload-free replay tuple.
4396
+ console.error(failure.replay) // { seed: 73, caseId: "...", runtime: "worker" }
4397
+
4398
+ await assertAdversarialContract(app, {
4399
+ seed: failure.replay.seed,
4400
+ only: failure.replay.caseId,
4401
+ })
4402
+ ```
4403
+
4404
+ The response-conformance pass executes handlers, including POST/DELETE handlers. Run it with
4405
+ isolated fixtures and a test database. Never point a contract laboratory at production.
4406
+
4163
4407
  ## Nifra — Types-first architecture
4164
4408
 
4165
4409
  > One schema is the single source of truth: it drives runtime validation, inferred TypeScript types, the no-codegen typed client, an OpenAPI document, and the MCP contract your agents read.
@@ -4411,6 +4655,38 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
4411
4655
  [`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
4412
4656
  done-gate, or `nifra mcp` to give the agent live project tools.
4413
4657
 
4658
+ ## @nifrajs/budget
4659
+
4660
+ Compatibility import for the request-deadline mechanics owned by `@nifrajs/core/budget`. Existing
4661
+ Nifra, Hono, and Fetch consumers can keep this import unchanged; new core consumers may use the
4662
+ subpath directly. Both paths resolve to the same implementation and classes.
4663
+
4664
+ ```ts
4665
+ import {
4666
+ assertBudgetRemaining,
4667
+ createRequestBudget,
4668
+ withDeadlineHeader,
4669
+ } from "@nifrajs/budget"
4670
+
4671
+ const budget = createRequestBudget({
4672
+ deadline: Date.now() + 2_000,
4673
+ signal: request.signal,
4674
+ })
4675
+
4676
+ assertBudgetRemaining(budget, 100)
4677
+ await fetch(url, {
4678
+ signal: budget.signal,
4679
+ headers: withDeadlineHeader(undefined, budget.child(50)),
4680
+ })
4681
+ ```
4682
+
4683
+ The wire value is an absolute Unix epoch deadline. `remaining()` samples wall time once, then uses a
4684
+ monotonic clock so NTP changes cannot extend or shorten admitted work. A budget does not choose retry,
4685
+ provider, tenant, or money policy; it only answers how much time remains.
4686
+
4687
+ Nifra route handlers receive the same primitive as `c.budget`. `c.signal` remains the cancellation
4688
+ signal and aborts at the effective server deadline.
4689
+
4414
4690
  ## @nifrajs/cache
4415
4691
 
4416
4692
  Typed KV cache for nifra — **TTL**, **stale-while-revalidate**, **tag invalidation**, and **single-flight
@@ -4479,9 +4755,33 @@ nifra start [--port <n>] [--out <dir>] Serve the built app (client + SSR) on
4479
4755
  nifra context Print this project's API + page routes + conventions.
4480
4756
  nifra mcp MCP server (stdio) exposing this project to a coding agent.
4481
4757
  nifra check [--json] Gate: typecheck + lints; --json includes fixes/suggestions.
4758
+ nifra assure [--config <file>] [--json] Gate reflected routes against enforcement evidence.
4759
+ nifra capabilities check [--json] Gate effect provenance + the reviewed capability lockfile.
4760
+ nifra manifest emit [--sign <key-ref>] Emit the hash-verified route trust artifact after assurance.
4761
+ nifra manifest diff <before> <after> Block promotion on contract/governance regressions.
4482
4762
  nifra doctor [--json] [--auto-fix] Catch undeclared imported packages; auto-fix safe local versions.
4483
4763
  ```
4484
4764
 
4765
+ ## `nifra assure` — the route-enforcement gate
4766
+
4767
+ Create `nifra.assurance.ts` with a default `defineAssuranceConfig({ source, policy })` export, then run
4768
+ `nifra assure` in CI. Official middleware publishes evidence at the same seam where it installs its
4769
+ hooks; the gate classifies every reflected route with the first matching rule and exits non-zero for an
4770
+ unclassified route, missing evidence, or forbidden evidence. Evaluation is startup/CI-only and adds no
4771
+ request-path overhead. Use `--json` for the complete per-route report or `--config` for another file.
4772
+
4773
+ ## `nifra manifest` — the deploy trust artifact
4774
+
4775
+ Add optional `manifest: { path, signer }` settings to `nifra.assurance.ts`, then run
4776
+ `nifra manifest emit`. Emission refuses failing route or capability assurance and joins the route
4777
+ schemas, enforcement evidence, effect tokens, and field-level response classification into one
4778
+ deterministic SHA-256 artifact. `--sign <key-ref>` asks the configured callback to produce a detached
4779
+ Ed25519 sidecar, so the private key can stay inside KMS/HSM infrastructure.
4780
+
4781
+ At promotion time, `nifra manifest diff previous.json candidate.json` hash-verifies both files and exits
4782
+ non-zero on a breaking API change, removed assurance, expanded effect, lost provenance coverage, or
4783
+ increased data sensitivity. This is separate from the frontend asset `dist/manifest.json`.
4784
+
4485
4785
  ## `nifra check` — the drift gate (run as "done")
4486
4786
 
4487
4787
  `nifra check` makes nifra's anti-drift guarantees actually fire instead of relying on the agent to
@@ -4534,6 +4834,7 @@ an agent can act on the project, not just read about it. Core tools:
4534
4834
  - **`nifra_test`** — run bounded `bun test` with structured output.
4535
4835
  - **`nifra_check`** — run the drift gate and get the structured `{ ok, typecheck, diagnostics[] }`
4536
4836
  result with suggestions, so the agent verifies its own work and fixes each diagnostic before finishing.
4837
+ - **`nifra_assure`** — evaluate `nifra.assurance.ts` and return the complete per-route evidence report.
4537
4838
  - **`nifra_doctor`** — catch imported packages missing from `package.json`; with `autoFix:true`, write
4538
4839
  safe dependency entries when a version can be inferred locally and return exact `bun add` commands
4539
4840
  for anything that needs a package-manager decision.
@@ -4671,8 +4972,32 @@ export type App = typeof app // hand this to @nifrajs/client for end-to-end type
4671
4972
  `onRequest`/`beforeHandle`/`afterHandle`/`onResponse`/`onError` run around handlers;
4672
4973
  `use(middleware)` applies a bundle.
4673
4974
  - **Hardening built in.** `stop({ drainMs })` graceful shutdown (+ opt-in SIGTERM/
4674
- SIGINT), `requestTimeoutMs` (+ `ctx.signal`), a streaming body-size cap, and a
4975
+ SIGINT), `requestTimeoutMs` (+ `ctx.signal` and `ctx.budget`), a streaming body-size cap, and a
4675
4976
  redacting structured `Logger`.
4977
+ - **One request budget.** `ctx.budget` carries the admitted absolute deadline and monotonic
4978
+ `remaining()` time. An inbound `x-nifra-deadline` can only shorten `requestTimeoutMs`/
4979
+ `maxInboundDeadlineMs`; malformed and expired values fail before the handler. `ctx.signal`
4980
+ remains the cancellation primitive and aborts at that same effective deadline.
4981
+ - **Route assurance.** Official auth, CSRF, body-limit, rate-limit, idempotency,
4982
+ IP-restriction, and security-header modules publish reflection-safe enforcement evidence.
4983
+ An ordered `AssurancePolicy` classifies every route and fails closed on missing or forbidden
4984
+ evidence without adding work to the request path.
4985
+
4986
+ ```ts
4987
+ import { defineAssurancePolicy, evaluateRouteAssurance, NIFRA_ASSURANCE } from "@nifrajs/core/assurance"
4988
+
4989
+ const policy = defineAssurancePolicy({
4990
+ rules: [
4991
+ { name: "health", match: { paths: ["/health"] }, require: [] },
4992
+ { name: "mutation", match: { methods: ["POST", "PUT", "PATCH", "DELETE"] },
4993
+ require: [NIFRA_ASSURANCE.AUTHENTICATED, NIFRA_ASSURANCE.CSRF] },
4994
+ { name: "read", match: { methods: ["GET", "HEAD"] },
4995
+ require: [NIFRA_ASSURANCE.AUTHENTICATED] },
4996
+ ],
4997
+ })
4998
+
4999
+ evaluateRouteAssurance(app, policy).ok // pure reflection-time evaluation
5000
+ ```
4676
5001
 
4677
5002
  ESM-only; requires Bun at runtime. MIT.
4678
5003
 
@@ -4873,6 +5198,12 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
4873
5198
  [`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
4874
5199
  done-gate, or `nifra mcp` to give the agent live project tools.
4875
5200
 
5201
+ ## @nifrajs/events
5202
+
5203
+ Portable, versioned event contracts — a typed, transport-agnostic event envelope validated by any Standard Schema.
5204
+
5205
+ See the [nifra docs](https://github.com/nifrajs/nifra#readme).
5206
+
4876
5207
  ## @nifrajs/i18n
4877
5208
 
4878
5209
  Framework-agnostic i18n for nifra — locale negotiation + a tiny ICU message formatter on the platform Intl. Dependency-free.
@@ -5467,10 +5798,79 @@ import { assertSafeKey, StorageKeyError } from "@nifrajs/storage"
5467
5798
 
5468
5799
  ## @nifrajs/testing
5469
5800
 
5470
- Testing helpers for nifra apps. [`@nifrajs/client`](../client)'s **`testClient`** is already the typed,
5471
- no-network in-process request client (nifra's supertest / `inject`). This package adds what it doesn't: a
5472
- **cookie jar** and a **cookie-persisting `testSession`**, so a login → authenticated-request flow tests as
5473
- easily as a single request.
5801
+ Contract-derived adversarial testing and stateful in-process helpers for Nifra apps.
5802
+
5803
+ ## Contract laboratory
5804
+
5805
+ `assertAdversarialContract` turns the schemas already registered on an app into executable tests. It:
5806
+
5807
+ - synthesizes a valid **contract witness** from inspectable JSON Schema;
5808
+ - makes small nested **hostile mutations** and sends only values the route's own Standard Schema
5809
+ validator has proved invalid after HTTP transport normalization;
5810
+ - expects rejection at the real request boundary (422 by default);
5811
+ - executes a valid witness and validates the real success body against `response`;
5812
+ - runs the same stable case IDs across a Bun/Node/Workers runtime matrix; and
5813
+ - retains a replay seed and greedily shrinks unexpected acceptance failures.
5814
+
5815
+ ```ts
5816
+ import { test } from "bun:test"
5817
+ import { assertAdversarialContract } from "@nifrajs/testing"
5818
+ import { app } from "../src/app"
5819
+
5820
+ test("the API contract withstands hostile inputs", async () => {
5821
+ await assertAdversarialContract(app, {
5822
+ seed: 73,
5823
+ prepareRequest(request) {
5824
+ const headers = new Headers(request.headers)
5825
+ headers.set("authorization", "Bearer test-session")
5826
+ return new Request(request, { headers })
5827
+ },
5828
+ })
5829
+ })
5830
+ ```
5831
+
5832
+ Nifra's `t` schemas carry JSON Schema, so witnesses are automatic. Standard Schema deliberately does
5833
+ not require introspection; for an opaque Zod/Valibot/ArkType schema, provide only its known-good values:
5834
+
5835
+ ```ts
5836
+ await assertAdversarialContract(app, {
5837
+ witnesses: {
5838
+ "POST /users/:id": {
5839
+ params: { id: "user-1" },
5840
+ body: { name: "Ada" },
5841
+ query: { notify: "true" },
5842
+ },
5843
+ },
5844
+ })
5845
+ ```
5846
+
5847
+ The validator still decides which generated mutations are truly invalid; the supplied witness does not
5848
+ weaken validation. A missing/invalid witness is a coverage gap, not a silent pass. Set
5849
+ `requireCoverage: false` only when gaps are intentionally advisory.
5850
+
5851
+ To exercise adapter parity, pass runtime fetch targets. The reflected `app` remains the one source of
5852
+ the contract:
5853
+
5854
+ ```ts
5855
+ const report = await assertAdversarialContract(app, {
5856
+ runtimes: [
5857
+ { name: "bun", fetch: (request) => bunApp.fetch(request) },
5858
+ { name: "node", fetch: (request) => nodeAdapter.fetch(request) },
5859
+ { name: "worker", fetch: (request) => worker.fetch(request, env) },
5860
+ ],
5861
+ })
5862
+ ```
5863
+
5864
+ `runAdversarialContract` returns the same structured report without throwing. Every failure includes
5865
+ `replay: { seed, caseId, runtime }`; rerun one case with `only: caseId`. Contract runs execute one valid
5866
+ request for each declared response schema, so use an isolated test app/database—never point the
5867
+ laboratory at production.
5868
+
5869
+ ## Stateful sessions
5870
+
5871
+ [`@nifrajs/client`](../client)'s **`testClient`** is already the typed, no-network in-process request
5872
+ client (Nifra's supertest / `inject`). `testSession` adds a **cookie jar**, so a login → authenticated
5873
+ request flow tests as easily as a single request.
5474
5874
 
5475
5875
  ```ts
5476
5876
  import { testSession } from "@nifrajs/testing"
@@ -5493,6 +5893,8 @@ that every call carries and captures cookies via a shared jar.
5493
5893
 
5494
5894
  ## API
5495
5895
 
5896
+ - `assertAdversarialContract(app, options?)` → green report or throws `AdversarialContractError`.
5897
+ - `runAdversarialContract(app, options?)` → structured `{ ok, results, failures, gaps, seed }` report.
5496
5898
  - `testSession<App>(app, { origin?, cookies? })` → `{ client: Treaty<App>, cookies: CookieJar }`.
5497
5899
  - `cookieJar()` → `CookieJar` — `header()` · `applyTo(headers)` · `store(response)` · `set` · `get` · `clear` · `size`.
5498
5900
  Honours removal (`Max-Age=0` / past `Expires`); other cookie attributes are ignored (in-process, same-origin).
@@ -5841,7 +6243,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
5841
6243
 
5842
6244
  ## @nifrajs/client
5843
6245
 
5844
- `ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `FetchFn`, `inProcessClient`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `Result`, `SubscribeOptions`, `Subscription`, `testClient`, `Treaty`, `TreatyFromRegistry`
6246
+ `ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `FetchFn`, `inProcessClient`, `InProcessClient`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `Result`, `SubscribeOptions`, `Subscription`, `testClient`, `Treaty`, `TreatyFromRegistry`
5845
6247
 
5846
6248
  ## @nifrajs/content
5847
6249
 
@@ -5849,7 +6251,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
5849
6251
 
5850
6252
  ## @nifrajs/core
5851
6253
 
5852
- `AnyServer`, `attachWebSocket`, `commonSecretPatterns`, `Context`, `ContextForOp`, `ContractShape`, `CookieOptions`, `defineContract`, `defineIdentityPlugin`, `definePlugin`, `defineRouterPlugin`, `DurableObjectNamespaceLike`, `ExecutionContext`, `FRAMEWORK_NAME`, `FrameworkError`, `FrameworkName`, `Handler`, `HandlersFor`, `IdentityPlugin`, `implement`, `InferInput`, `InferOutput`, `jsonLogger`, `LogFields`, `Logger`, `McpPromptDescriptor`, `McpResourceDescriptor`, `Method`, `METHODS`, `Middleware`, `NifraPlugin`, `NifraWebSocket`, `NodeServeOutcome`, `OnRequestResult`, `OperationDef`, `Params`, `parseCookies`, `Platform`, `Prettify`, `PromptArgument`, `PromptMessage`, `redactLogFields`, `RedactOptions`, `Registry`, `RegistryFor`, `RegistryFromImpl`, `ResponseControls`, `ResponseDef`, `ResponseFinalization`, `robots`, `RobotsOptions`, `RobotsRule`, `RouteConfigError`, `RouteConfigErrorCode`, `RouteDescriptor`, `RouteInfo`, `Router`, `RouterMatch`, `RouteSchema`, `RunningServer`, `ScheduledController`, `ScheduledHandler`, `serializeCookie`, `server`, `Server`, `ServerOptions`, `SignatureEncoding`, `signValue`, `silentLogger`, `sitemap`, `SitemapChangeFreq`, `SitemapEntry`, `SitemapOptions`, `sse`, `SSEContext`, `SSEInit`, `SSEMessage`, `SSEStream`, `StandardIssue`, `StandardResult`, `StandardSchemaV1`, `StandardTypes`, `StandardWebSocket`, `toFetchHandler`, `ToolAnnotations`, `TopicRegistry`, `typedSSEStream`, `TypedSSEStream`, `unsignValue`, `validateStandard`, `ValidationOutcome`, `verifyWebhook`, `VerifyWebhookOptions`, `Version`, `VERSION`, `WebhookFailureReason`, `WebhookProvider`, `WebhookResult`, `WebSocketContext`, `WebSocketData`, `WebSocketHandler`, `WebSocketUpgradeOutcome`
6254
+ `AdmissionController`, `AdmissionDecision`, `AnyServer`, `attachWebSocket`, `commonSecretPatterns`, `Context`, `ContextForOp`, `ContractShape`, `CookieOptions`, `defineContract`, `defineIdentityPlugin`, `definePlugin`, `defineRouterPlugin`, `DurableObjectNamespaceLike`, `ExecutionContext`, `FRAMEWORK_NAME`, `FrameworkError`, `FrameworkName`, `Handler`, `HandlersFor`, `IdentityPlugin`, `implement`, `InferInput`, `InferOutput`, `jsonLogger`, `LogFields`, `Logger`, `McpPromptDescriptor`, `McpResourceDescriptor`, `Method`, `METHODS`, `Middleware`, `NifraPlugin`, `NifraWebSocket`, `NodeServeOutcome`, `OnRequestResult`, `OperationDef`, `Params`, `parseCookies`, `Platform`, `Prettify`, `PromptArgument`, `PromptMessage`, `redactLogFields`, `RedactOptions`, `Registry`, `RegistryFor`, `RegistryFromImpl`, `ResponseControls`, `ResponseDef`, `ResponseFinalization`, `robots`, `RobotsOptions`, `RobotsRule`, `RouteConfigError`, `RouteConfigErrorCode`, `RouteDescriptor`, `RouteInfo`, `Router`, `RouterMatch`, `RouteSchema`, `RunningServer`, `ScheduledController`, `ScheduledHandler`, `serializeCookie`, `server`, `Server`, `ServerOptions`, `SignatureEncoding`, `signValue`, `silentLogger`, `sitemap`, `SitemapChangeFreq`, `SitemapEntry`, `SitemapOptions`, `sse`, `SSEContext`, `SSEInit`, `SSEMessage`, `SSEStream`, `StandardIssue`, `StandardResult`, `StandardSchemaV1`, `StandardTypes`, `StandardWebSocket`, `toFetchHandler`, `ToolAnnotations`, `TopicRegistry`, `typedSSEStream`, `TypedSSEStream`, `unsignValue`, `validateStandard`, `ValidationOutcome`, `verifyWebhook`, `VerifyWebhookOptions`, `Version`, `VERSION`, `WebhookFailureReason`, `WebhookProvider`, `WebhookResult`, `WebSocketContext`, `WebSocketData`, `WebSocketHandler`, `WebSocketUpgradeOutcome`
5853
6255
 
5854
6256
  ## @nifrajs/cron
5855
6257
 
@@ -5867,6 +6269,10 @@ done-gate, or `nifra mcp` to give the agent live project tools.
5867
6269
 
5868
6270
  `boolean`, `defineEnv`, `DefineEnvOptions`, `enumValue`, `env`, `EnvResult`, `EnvShape`, `InferOutput`, `number`, `port`, `StandardResult`, `StandardSchemaV1`, `string`, `url`
5869
6271
 
6272
+ ## @nifrajs/events
6273
+
6274
+ `createEventRegistry`, `defineEventContract`, `EventContract`, `EventContractError`, `EventEnvelope`, `EventParseResult`, `EventRegistry`, `RegistryParseResult`
6275
+
5870
6276
  ## @nifrajs/i18n
5871
6277
 
5872
6278
  `createFormatter`, `Formatter`, `Locale`, `Messages`, `negotiateLocale`, `NegotiateOptions`
@@ -5893,7 +6299,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
5893
6299
 
5894
6300
  ## @nifrajs/middleware
5895
6301
 
5896
- `apiKey`, `ApiKeyStaticOptions`, `ApiKeyVerifyOptions`, `appendTrailingSlash`, `AuthPlugin`, `basicAuth`, `BasicAuthPlugin`, `BasicAuthStaticOptions`, `BasicAuthVerifyOptions`, `bearer`, `BearerOptions`, `bodyLimit`, `BodyLimitOptions`, `buildOpenApiDocument`, `cache`, `cacheControl`, `CacheControlOptions`, `CachedResponse`, `CacheOptions`, `combine`, `Composable`, `compression`, `CompressionOptions`, `cors`, `CorsOptions`, `createCsrfToken`, `csrf`, `CsrfOptions`, `etag`, `ETagOptions`, `healthcheck`, `HealthcheckOptions`, `idempotency`, `IdempotencyClaim`, `IdempotencyOptions`, `IdempotencyRecord`, `IdempotencyStore`, `IpMatcher`, `ipRestriction`, `IpRestrictionOptions`, `jwk`, `JwkKey`, `jwks`, `JwksOptions`, `jwt`, `JwtAlgorithm`, `JwtClaims`, `JwtHeader`, `JwtKeyResolver`, `JwtOptions`, `JwtPlugin`, `JwtVerificationKey`, `language`, `LanguageMatch`, `LanguageOptions`, `logger`, `LoggerOptions`, `MemoryIdempotencyStore`, `MemoryIdempotencyStoreOptions`, `MemoryResponseCache`, `MemoryResponseCacheOptions`, `MemoryStore`, `MemoryStoreOptions`, `methodOverride`, `MethodOverrideOptions`, `namedCombine`, `openapi`, `OpenApiInfo`, `OpenApiOptions`, `OpenApiServer`, `OpenApiTag`, `OpenApiUiOptions`, `pickLanguage`, `poweredBy`, `PoweredByOptions`, `prettyJson`, `PrettyJsonOptions`, `rateLimit`, `RateLimitOptions`, `RateLimitResult`, `RateLimitStore`, `requestId`, `RequestIdOptions`, `RequestLogFields`, `responseCache`, `ResponseCacheStore`, `RouteLike`, `securityHeaders`, `SecurityHeadersOptions`, `SecurityRequirement`, `timing`, `TimingControls`, `TimingMetric`, `TimingOptions`, `TrailingSlashOptions`, `trimTrailingSlash`, `tryVerifyJwt`, `VerifiedJwt`, `verifyCsrfToken`, `verifyJwt`, `VerifyJwtOptions`, `VerifyJwtResult`
6302
+ `AdmissionControllerHandle`, `AdmissionEvidence`, `AdmissionOptions`, `AdmissionPolicy`, `AdmissionSnapshot`, `apiKey`, `ApiKeyStaticOptions`, `ApiKeyVerifyOptions`, `appendTrailingSlash`, `AuthPlugin`, `basicAuth`, `BasicAuthPlugin`, `BasicAuthStaticOptions`, `BasicAuthVerifyOptions`, `bearer`, `BearerOptions`, `bodyLimit`, `BodyLimitOptions`, `buildOpenApiDocument`, `cache`, `cacheControl`, `CacheControlOptions`, `CachedResponse`, `CacheOptions`, `combine`, `Composable`, `compression`, `CompressionOptions`, `cors`, `CorsOptions`, `createAdmissionController`, `createCsrfToken`, `createEventLoopLagSampler`, `csrf`, `CsrfOptions`, `etag`, `ETagOptions`, `healthcheck`, `HealthcheckOptions`, `idempotency`, `IdempotencyClaim`, `IdempotencyOptions`, `IdempotencyRecord`, `IdempotencyStore`, `IpMatcher`, `ipRestriction`, `IpRestrictionOptions`, `jwk`, `JwkKey`, `jwks`, `JwksOptions`, `jwt`, `JwtAlgorithm`, `JwtClaims`, `JwtHeader`, `JwtKeyResolver`, `JwtOptions`, `JwtPlugin`, `JwtVerificationKey`, `language`, `LanguageMatch`, `LanguageOptions`, `logger`, `LoggerOptions`, `LoopDelayHistogram`, `LoopDelayMonitor`, `MemoryIdempotencyStore`, `MemoryIdempotencyStoreOptions`, `MemoryResponseCache`, `MemoryResponseCacheOptions`, `MemoryStore`, `MemoryStoreOptions`, `methodOverride`, `MethodOverrideOptions`, `namedCombine`, `openapi`, `OpenApiInfo`, `OpenApiOptions`, `OpenApiServer`, `OpenApiTag`, `OpenApiUiOptions`, `pickLanguage`, `poweredBy`, `PoweredByOptions`, `prettyJson`, `PrettyJsonOptions`, `rateLimit`, `RateLimitOptions`, `RateLimitResult`, `RateLimitStore`, `requestId`, `RequestIdOptions`, `RequestLogFields`, `responseCache`, `ResponseCacheStore`, `RouteLike`, `securityHeaders`, `SecurityHeadersOptions`, `SecurityRequirement`, `ShedReason`, `timing`, `TimingControls`, `TimingMetric`, `TimingOptions`, `TrailingSlashOptions`, `trimTrailingSlash`, `tryVerifyJwt`, `VerifiedJwt`, `verifyCsrfToken`, `verifyJwt`, `VerifyJwtOptions`, `VerifyJwtResult`
5897
6303
 
5898
6304
  ## @nifrajs/mock
5899
6305
 
@@ -5925,7 +6331,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
5925
6331
 
5926
6332
  ## @nifrajs/testing
5927
6333
 
5928
- `AppLike`, `cookieJar`, `CookieJar`, `testSession`, `TestSession`, `TestSessionOptions`
6334
+ `AdversarialContractError`, `AdversarialContractOptions`, `AdversarialContractReport`, `AdversarialContractResult`, `AppLike`, `assertAdversarialContract`, `assertIncidentReplays`, `CapturedRequest`, `CapturedRequestInput`, `captureIncident`, `CaptureIncidentOptions`, `ContractCaseContext`, `ContractCaseKind`, `ContractCoverageGap`, `ContractCoverageGapCode`, `ContractReplay`, `ContractRuntime`, `ContractTarget`, `ContractTestApp`, `ContractWitness`, `cookieJar`, `CookieJar`, `generateRegressionTest`, `GenerateRegressionTestOptions`, `IncidentCapsule`, `IncidentReplayError`, `IncidentReplayResult`, `redactForEmission`, `replayIncident`, `ReplayIncidentOptions`, `runAdversarialContract`, `shapeOf`, `testSession`, `TestSession`, `TestSessionOptions`
5929
6335
 
5930
6336
  ## @nifrajs/uploads
5931
6337
 
@@ -5933,7 +6339,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
5933
6339
 
5934
6340
  ## @nifrajs/web
5935
6341
 
5936
- `Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumeratePrerenderedPaths`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `GetStaticPaths`, `hashQueryKey`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaInput`, `MountRouterOptions`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderedPage`, `renderPage`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `routeStyles`, `ScriptDescriptor`, `serializeData`, `ServerOnly`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `styles`, `Submission`, `SubmitOptions`, `withISR`
6342
+ `Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumeratePrerenderedPaths`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `hashQueryKey`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NavigateOptions`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderedPage`, `renderPage`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `routeStyles`, `ScriptDescriptor`, `serializeData`, `ServerOnly`, `setBrowserNavigate`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `styles`, `Submission`, `SubmitOptions`, `withISR`
5937
6343
 
5938
6344
  ## @nifrajs/web-preact
5939
6345