@nifrajs/core 2.1.0 → 2.3.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 (138) hide show
  1. package/README.md +2 -2
  2. package/dist/assurance.d.ts +48 -4
  3. package/dist/assurance.d.ts.map +1 -1
  4. package/dist/assurance.js +87 -9
  5. package/dist/assurance.js.map +1 -1
  6. package/dist/binary.d.ts +54 -0
  7. package/dist/binary.d.ts.map +1 -0
  8. package/dist/binary.js +90 -0
  9. package/dist/binary.js.map +1 -0
  10. package/dist/budget.d.ts +1 -1
  11. package/dist/budget.js +1 -1
  12. package/dist/capabilities.d.ts +19 -2
  13. package/dist/capabilities.d.ts.map +1 -1
  14. package/dist/capabilities.js +60 -8
  15. package/dist/capabilities.js.map +1 -1
  16. package/dist/classification.d.ts +1 -1
  17. package/dist/classification.js +1 -1
  18. package/dist/diff.d.ts +6 -6
  19. package/dist/diff.js +6 -6
  20. package/dist/durable-adapters.d.ts.map +1 -1
  21. package/dist/durable-adapters.js +36 -70
  22. package/dist/durable-adapters.js.map +1 -1
  23. package/dist/durable-execution.d.ts +2 -2
  24. package/dist/durable-execution.js +2 -2
  25. package/dist/idempotency.d.ts +3 -3
  26. package/dist/idempotency.js +4 -4
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.js +3 -3
  29. package/dist/internal/brand.d.ts +1 -1
  30. package/dist/internal/brand.js +1 -1
  31. package/dist/internal/route-catalog.d.ts +58 -0
  32. package/dist/internal/route-catalog.d.ts.map +1 -0
  33. package/dist/internal/route-catalog.js +58 -0
  34. package/dist/internal/route-catalog.js.map +1 -0
  35. package/dist/internal/route-execution.d.ts +75 -0
  36. package/dist/internal/route-execution.d.ts.map +1 -0
  37. package/dist/internal/route-execution.js +2 -0
  38. package/dist/internal/route-execution.js.map +1 -0
  39. package/dist/internal/same-origin.d.ts +29 -0
  40. package/dist/internal/same-origin.d.ts.map +1 -0
  41. package/dist/internal/same-origin.js +47 -0
  42. package/dist/internal/same-origin.js.map +1 -0
  43. package/dist/internal/secret.d.ts +1 -1
  44. package/dist/internal/secret.js +1 -1
  45. package/dist/ledger.d.ts +9 -9
  46. package/dist/ledger.js +5 -5
  47. package/dist/reflection.d.ts +1 -1
  48. package/dist/router/pattern.d.ts +26 -1
  49. package/dist/router/pattern.d.ts.map +1 -1
  50. package/dist/router/pattern.js +164 -8
  51. package/dist/router/pattern.js.map +1 -1
  52. package/dist/router/router.d.ts.map +1 -1
  53. package/dist/router/router.js +52 -4
  54. package/dist/router/router.js.map +1 -1
  55. package/dist/schema/standard.d.ts +2 -2
  56. package/dist/schema/standard.js +2 -2
  57. package/dist/seo.d.ts +3 -3
  58. package/dist/seo.js +4 -4
  59. package/dist/server/body.d.ts +2 -2
  60. package/dist/server/body.js +2 -2
  61. package/dist/server/context.d.ts +18 -18
  62. package/dist/server/contract.d.ts +7 -7
  63. package/dist/server/contract.js +3 -3
  64. package/dist/server/cookies.d.ts +4 -4
  65. package/dist/server/cookies.js +8 -8
  66. package/dist/server/edge.d.ts +83 -0
  67. package/dist/server/edge.d.ts.map +1 -0
  68. package/dist/server/edge.js +71 -0
  69. package/dist/server/edge.js.map +1 -0
  70. package/dist/server/install.d.ts +2 -0
  71. package/dist/server/install.d.ts.map +1 -1
  72. package/dist/server/install.js +2 -0
  73. package/dist/server/install.js.map +1 -1
  74. package/dist/server/logger.d.ts +7 -7
  75. package/dist/server/logger.js +4 -4
  76. package/dist/server/registry.d.ts +5 -5
  77. package/dist/server/response-contract-lane.d.ts +91 -0
  78. package/dist/server/response-contract-lane.d.ts.map +1 -0
  79. package/dist/server/response-contract-lane.js +81 -0
  80. package/dist/server/response-contract-lane.js.map +1 -0
  81. package/dist/server/server.d.ts +52 -91
  82. package/dist/server/server.d.ts.map +1 -1
  83. package/dist/server/server.js +130 -186
  84. package/dist/server/server.js.map +1 -1
  85. package/dist/server/sse.d.ts +4 -4
  86. package/dist/server/sse.js +7 -7
  87. package/dist/server/webhook.d.ts +1 -1
  88. package/dist/server/webhook.js +5 -5
  89. package/dist/server/websocket.d.ts +19 -19
  90. package/dist/server/websocket.js +9 -9
  91. package/dist/server/ws-bun.d.ts +4 -4
  92. package/dist/server/ws-bun.js +3 -3
  93. package/dist/server.d.ts +3 -1
  94. package/dist/server.d.ts.map +1 -1
  95. package/dist/server.js +3 -1
  96. package/dist/server.js.map +1 -1
  97. package/dist/transport-codec.d.ts +13 -1
  98. package/dist/transport-codec.d.ts.map +1 -1
  99. package/dist/transport-codec.js +48 -9
  100. package/dist/transport-codec.js.map +1 -1
  101. package/package.json +12 -2
  102. package/src/assurance.ts +154 -8
  103. package/src/binary.ts +128 -0
  104. package/src/budget.ts +1 -1
  105. package/src/capabilities.ts +71 -9
  106. package/src/classification.ts +1 -1
  107. package/src/diff.ts +8 -8
  108. package/src/durable-adapters.ts +40 -70
  109. package/src/durable-execution.ts +2 -2
  110. package/src/idempotency.ts +4 -4
  111. package/src/index.ts +3 -3
  112. package/src/internal/brand.ts +1 -1
  113. package/src/internal/route-catalog.ts +94 -0
  114. package/src/internal/route-execution.ts +106 -0
  115. package/src/internal/same-origin.ts +43 -0
  116. package/src/internal/secret.ts +1 -1
  117. package/src/ledger.ts +11 -11
  118. package/src/reflection.ts +1 -1
  119. package/src/router/pattern.ts +179 -8
  120. package/src/router/router.ts +80 -6
  121. package/src/schema/standard.ts +2 -2
  122. package/src/seo.ts +6 -6
  123. package/src/server/body.ts +2 -2
  124. package/src/server/context.ts +18 -18
  125. package/src/server/contract.ts +13 -13
  126. package/src/server/cookies.ts +8 -8
  127. package/src/server/edge.ts +150 -0
  128. package/src/server/install.ts +5 -0
  129. package/src/server/logger.ts +8 -8
  130. package/src/server/registry.ts +5 -5
  131. package/src/server/response-contract-lane.ts +164 -0
  132. package/src/server/server.ts +159 -366
  133. package/src/server/sse.ts +11 -11
  134. package/src/server/webhook.ts +5 -5
  135. package/src/server/websocket.ts +22 -22
  136. package/src/server/ws-bun.ts +4 -4
  137. package/src/server.ts +8 -5
  138. package/src/transport-codec.ts +63 -10
@@ -1,17 +1,17 @@
1
1
  /**
2
- * WebSocket seam — portable types shared by `@nifrajs/core`'s `app.ws()` and every serving adapter
2
+ * WebSocket seam - portable types shared by `@nifrajs/core`'s `app.ws()` and every serving adapter
3
3
  * (Bun `listen()`, `@nifrajs/node`, `@nifrajs/deno`, `toFetchHandler` on Workers). No runtime code here, so
4
4
  * it stays edge-safe and dependency-free; each adapter implements {@link NifraWebSocket} over its
5
5
  * runtime's native socket and dispatches to the handler.
6
6
  *
7
- * A WS upgrade can't go through `app.fetch` (which has no socket) — it's adapter-integrated. The
7
+ * A WS upgrade can't go through `app.fetch` (which has no socket) - it's adapter-integrated. The
8
8
  * adapter calls `app.resolveWebSocketUpgrade(req)` (runs the route's `upgrade()` guard in a real
9
9
  * request context), then performs the runtime upgrade with the returned data.
10
10
  */
11
11
  import { validateStandard } from "../schema/standard.js";
12
12
  import { decodeTransportFrame } from "../transport-codec.js";
13
13
  /**
14
- * In-process pub/sub for `ws.subscribe(topic)` + `app.publish(topic, data)`. **Single-instance only** —
14
+ * In-process pub/sub for `ws.subscribe(topic)` + `app.publish(topic, data)`. **Single-instance only** -
15
15
  * topics live in this process's memory, so a multi-instance deploy (multiple servers behind a load
16
16
  * balancer) needs an external fan-out (Redis pub/sub, a Cloudflare Durable Object, NATS, …) bridged to
17
17
  * `app.publish`. The same registry instance is shared by an app's connections and its `publish`.
@@ -38,11 +38,11 @@ export class TopicRegistry {
38
38
  if (subs !== undefined) {
39
39
  subs.delete(ws);
40
40
  if (subs.size === 0)
41
- this.topics.delete(topic); // reclaim empty topics — no unbounded growth
41
+ this.topics.delete(topic); // reclaim empty topics - no unbounded growth
42
42
  }
43
43
  this.memberships.get(ws)?.delete(topic);
44
44
  }
45
- /** Drop every subscription for a connection — called on close so a registry never leaks dead sockets. */
45
+ /** Drop every subscription for a connection - called on close so a registry never leaks dead sockets. */
46
46
  unsubscribeAll(ws) {
47
47
  const mine = this.memberships.get(ws);
48
48
  if (mine === undefined)
@@ -80,13 +80,13 @@ function toBinary(raw) {
80
80
  return new Uint8Array(raw);
81
81
  if (ArrayBuffer.isView(raw))
82
82
  return new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
83
- return new Uint8Array(0); // unknown (e.g. an unconverted Blob) — adapters set binaryType to avoid this
83
+ return new Uint8Array(0); // unknown (e.g. an unconverted Blob) - adapters set binaryType to avoid this
84
84
  }
85
85
  /**
86
86
  * Wire a standard server-side `WebSocket` to a nifra {@link WebSocketHandler}, returning the portable
87
87
  * {@link NifraWebSocket}. Shared by the Deno and Workers bridges. `openNow` fires `open` immediately
88
88
  * (Workers, where the socket is already open after `accept()`); otherwise `open` waits for the socket's
89
- * `open` event (Deno). Lifecycle callbacks are error-isolated — a throw (or async rejection) routes to
89
+ * `open` event (Deno). Lifecycle callbacks are error-isolated - a throw (or async rejection) routes to
90
90
  * `error()` and never tears the process down; binary frames are normalized to `Uint8Array`.
91
91
  */
92
92
  export function attachWebSocket(socket, handler, data, options) {
@@ -111,7 +111,7 @@ export function attachWebSocket(socket, handler, data, options) {
111
111
  r.catch(() => { });
112
112
  }
113
113
  catch {
114
- /* the error handler itself failed — last resort, swallow */
114
+ /* the error handler itself failed - last resort, swallow */
115
115
  }
116
116
  };
117
117
  const safe = (call) => {
@@ -147,7 +147,7 @@ export function attachWebSocket(socket, handler, data, options) {
147
147
  }
148
148
  const WS_MESSAGE_DECODER = new TextDecoder();
149
149
  /**
150
- * If the handler declares a `messageSchema`, return a copy whose `message` validates each frame —
150
+ * If the handler declares a `messageSchema`, return a copy whose `message` validates each frame -
151
151
  * parse as JSON, run the Standard Schema, then call the user's `message` with the typed value, or
152
152
  * `onInvalidMessage` on failure. Returns the handler unchanged when no schema is set. Called once at
153
153
  * `app.ws()` registration, so every adapter dispatches validated messages with no per-adapter code.
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Bun WebSocket plumbing — the `websocket` dispatcher config `listen()` hands to Bun's serve when
2
+ * Bun WebSocket plumbing - the `websocket` dispatcher config `listen()` hands to Bun's serve when
3
3
  * the app has WS routes. Lives behind the `@nifrajs/core/ws` subpath (via `ws-hook.ts`) so the base
4
4
  * bundle of a no-WebSocket app never ships it; `server.ts` only imports the **types** from here
5
- * (erased). No `Bun.*` calls here — the runtime seam stays in `server.ts` (see runtime-boundary.test).
5
+ * (erased). No `Bun.*` calls here - the runtime seam stays in `server.ts` (see runtime-boundary.test).
6
6
  */
7
7
  import type { NifraWebSocket, TopicRegistry, WebSocketHandler } from "./websocket.js";
8
8
  import type { BunWsHandlers } from "./ws-hook.js";
@@ -13,7 +13,7 @@ export interface BunWsData {
13
13
  data: unknown;
14
14
  nifra?: NifraWebSocket;
15
15
  }
16
- /** Structural view of Bun's `ServerWebSocket` — keeps `Bun.*` types out of the public `.d.ts`
16
+ /** Structural view of Bun's `ServerWebSocket` - keeps `Bun.*` types out of the public `.d.ts`
17
17
  * (`listen()` casts for the same reason). The real socket satisfies this. */
18
18
  export interface BunSocket {
19
19
  send(data: string | ArrayBufferView | ArrayBuffer, compress?: boolean): number;
@@ -21,7 +21,7 @@ export interface BunSocket {
21
21
  readonly readyState: number;
22
22
  readonly data: BunWsData;
23
23
  }
24
- /** The shared Bun `websocket` dispatcher config for one app — each connection's
24
+ /** The shared Bun `websocket` dispatcher config for one app - each connection's
25
25
  * `ws.data.handler` is the matched route's handler, set by `server.upgrade`. */
26
26
  export declare function createBunWsHandlers(topics: TopicRegistry): BunWsHandlers;
27
27
  //# sourceMappingURL=ws-bun.d.ts.map
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Bun WebSocket plumbing — the `websocket` dispatcher config `listen()` hands to Bun's serve when
2
+ * Bun WebSocket plumbing - the `websocket` dispatcher config `listen()` hands to Bun's serve when
3
3
  * the app has WS routes. Lives behind the `@nifrajs/core/ws` subpath (via `ws-hook.ts`) so the base
4
4
  * bundle of a no-WebSocket app never ships it; `server.ts` only imports the **types** from here
5
- * (erased). No `Bun.*` calls here — the runtime seam stays in `server.ts` (see runtime-boundary.test).
5
+ * (erased). No `Bun.*` calls here - the runtime seam stays in `server.ts` (see runtime-boundary.test).
6
6
  */
7
7
  /** Normalize a received binary frame to `Uint8Array` (Bun hands a `Buffer`, already one; an
8
8
  * `ArrayBuffer` is wrapped). Text frames stay `string`. */
@@ -55,7 +55,7 @@ function dispatchWsCallback(call, ws, handler) {
55
55
  reportWsError(error, ws, handler);
56
56
  }
57
57
  }
58
- /** The shared Bun `websocket` dispatcher config for one app — each connection's
58
+ /** The shared Bun `websocket` dispatcher config for one app - each connection's
59
59
  * `ws.data.handler` is the matched route's handler, set by `server.upgrade`. */
60
60
  export function createBunWsHandlers(topics) {
61
61
  return {
package/dist/server.d.ts CHANGED
@@ -9,13 +9,15 @@
9
9
  */
10
10
  export { FrameworkError, RouteConfigError, type RouteConfigErrorCode } from "./errors.js";
11
11
  export { FRAMEWORK_NAME, type FrameworkName } from "./internal/brand.js";
12
+ export { isSameOriginRequest } from "./internal/same-origin.js";
12
13
  export { METHODS, type Method, Router, type RouterMatch } from "./router/router.js";
13
14
  export type { InferInput, InferOutput, StandardIssue, StandardResult, StandardSchemaV1, StandardTypes, ValidationOutcome, } from "./schema/standard.js";
14
15
  export type { Context, Params, Platform, Prettify, ResponseControls, RouteSchema, } from "./server/context.js";
15
16
  export { type CookieOptions, parseCookies, serializeCookie, signValue, unsignValue, } from "./server/cookies.js";
17
+ export { type DurableObjectNamespaceLike, type ExecutionContext, type ScheduledController, type ScheduledHandler, toFetchHandler, } from "./server/edge.js";
16
18
  export { commonSecretPatterns, jsonLogger, type LogFields, type Logger, type RedactOptions, redactLogFields, silentLogger, } from "./server/logger.js";
17
19
  export type { Registry, RouteInfo } from "./server/registry.js";
18
- export { type AdmissionController, type AdmissionDecision, type AnyServer, type DurableObjectNamespaceLike, defineIdentityPlugin, definePlugin, defineRouterPlugin, type ExecutionContext, type Handler, type IdentityPlugin, type McpPromptDescriptor, type McpResourceDescriptor, type Middleware, type NifraPlugin, type NodeServeOutcome, type OnRequestResult, type PromptArgument, type PromptMessage, type ResponseFinalization, type RouteDescriptor, type RunningServer, type ScheduledController, type ScheduledHandler, Server, type ServerOptions, server, type ToolAnnotations, toFetchHandler, } from "./server/server.js";
20
+ export { type AdmissionController, type AdmissionDecision, type AnyServer, defineIdentityPlugin, definePlugin, defineRouterPlugin, type Handler, type IdentityPlugin, type McpPromptDescriptor, type McpResourceDescriptor, type Middleware, type NifraPlugin, type NodeServeOutcome, type OnRequestResult, type PromptArgument, type PromptMessage, type ResponseFinalization, type RouteDescriptor, type RunningServer, Server, type ServerOptions, server, type ToolAnnotations, } from "./server/server.js";
19
21
  export type { SSEContext, SSEInit, SSEMessage, SSEStream, TypedSSEStream, } from "./server/sse.js";
20
22
  export type { NifraWebSocket, StandardWebSocket, WebSocketContext, WebSocketData, WebSocketHandler, WebSocketUpgradeOutcome, } from "./server/websocket.js";
21
23
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACnF,YAAY,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,KAAK,aAAa,EAClB,YAAY,EACZ,eAAe,EACf,SAAS,EACT,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,eAAe,EACf,YAAY,GACb,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,0BAA0B,EAC/B,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,MAAM,EACN,KAAK,aAAa,EAClB,MAAM,EACN,KAAK,eAAe,EACpB,cAAc,GACf,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,UAAU,EACV,OAAO,EACP,UAAU,EACV,SAAS,EACT,cAAc,GACf,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACnF,YAAY,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,KAAK,aAAa,EAClB,YAAY,EACZ,eAAe,EACf,SAAS,EACT,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,eAAe,EACf,YAAY,GACb,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,MAAM,EACN,KAAK,aAAa,EAClB,MAAM,EACN,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,UAAU,EACV,OAAO,EACP,UAAU,EACV,SAAS,EACT,cAAc,GACf,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,uBAAuB,CAAA"}
package/dist/server.js CHANGED
@@ -9,8 +9,10 @@
9
9
  */
10
10
  export { FrameworkError, RouteConfigError } from "./errors.js";
11
11
  export { FRAMEWORK_NAME } from "./internal/brand.js";
12
+ export { isSameOriginRequest } from "./internal/same-origin.js";
12
13
  export { METHODS, Router } from "./router/router.js";
13
14
  export { parseCookies, serializeCookie, signValue, unsignValue, } from "./server/cookies.js";
15
+ export { toFetchHandler, } from "./server/edge.js";
14
16
  export { commonSecretPatterns, jsonLogger, redactLogFields, silentLogger, } from "./server/logger.js";
15
- export { defineIdentityPlugin, definePlugin, defineRouterPlugin, Server, server, toFetchHandler, } from "./server/server.js";
17
+ export { defineIdentityPlugin, definePlugin, defineRouterPlugin, Server, server, } from "./server/server.js";
16
18
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAA6B,MAAM,aAAa,CAAA;AACzF,OAAO,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,OAAO,EAAe,MAAM,EAAoB,MAAM,oBAAoB,CAAA;AAkBnF,OAAO,EAEL,YAAY,EACZ,eAAe,EACf,SAAS,EACT,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,oBAAoB,EACpB,UAAU,EAIV,eAAe,EACf,YAAY,GACb,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAKL,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAiBlB,MAAM,EAEN,MAAM,EAEN,cAAc,GACf,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAA6B,MAAM,aAAa,CAAA;AACzF,OAAO,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAe,MAAM,EAAoB,MAAM,oBAAoB,CAAA;AAkBnF,OAAO,EAEL,YAAY,EACZ,eAAe,EACf,SAAS,EACT,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAKL,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,oBAAoB,EACpB,UAAU,EAIV,eAAe,EACf,YAAY,GACb,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAIL,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAclB,MAAM,EAEN,MAAM,GAEP,MAAM,oBAAoB,CAAA"}
@@ -13,7 +13,7 @@ export interface TransportCodec {
13
13
  decode(text: string): unknown;
14
14
  }
15
15
  export declare class TransportCodecError extends TypeError {
16
- constructor(message: string);
16
+ constructor(message: string, options?: ErrorOptions);
17
17
  }
18
18
  export declare const plainJsonCodec: TransportCodec;
19
19
  export interface TransportCodecRegistry {
@@ -25,6 +25,18 @@ export interface TransportCodecRegistry {
25
25
  export declare function createTransportCodecRegistry(codecs: readonly TransportCodec[], fallback?: TransportCodec): TransportCodecRegistry;
26
26
  export declare const defaultTransportCodecs: TransportCodecRegistry;
27
27
  export declare function encodeTransportResponse(value: unknown, codec?: TransportCodec, init?: ResponseInit): Response;
28
+ /**
29
+ * Read a response body into memory, refusing to exceed `maxBytes`.
30
+ *
31
+ * Bounded while STREAMING rather than after the fact: the `content-length` shortcut only helps when a
32
+ * sender declares one, so the loop also counts as it goes and cancels the reader the moment the total
33
+ * passes the limit. A cap that buffers first and complains afterwards has already spent the memory it
34
+ * was meant to protect.
35
+ *
36
+ * Exported so the client can bound a plain-text body with the same reader it bounds JSON with, rather
37
+ * than growing a second copy of this loop that could drift from it.
38
+ */
39
+ export declare function readBoundedBytes(response: Response, options: TransportDecodeOptions): Promise<Uint8Array>;
28
40
  export declare function decodeTransportResponse(response: Response, registry?: TransportCodecRegistry, options?: TransportDecodeOptions): Promise<unknown>;
29
41
  export declare function encodeTransportFrame(value: unknown, codec?: TransportCodec): string;
30
42
  export declare function decodeTransportFrame(frame: string, registry?: TransportCodecRegistry, options?: TransportDecodeOptions): unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"transport-codec.d.ts","sourceRoot":"","sources":["../src/transport-codec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAA;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAC9B;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAmBD,eAAO,MAAM,cAAc,EAAE,cAY3B,CAAA;AAEF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAAA;IAC1D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAAA;IAChD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAAA;CACxD;AAUD,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,QAAQ,GAAE,cAA+B,GACxC,sBAAsB,CA0ExB;AAED,eAAO,MAAM,sBAAsB,EAAE,sBAEnC,CAAA;AAEF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,KAAK,GAAE,cAA+B,EACtC,IAAI,GAAE,YAAiB,GACtB,QAAQ,CAKV;AA2CD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,sBAA+C,EACzD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAIlB;AAQD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,KAAK,GAAE,cAA+B,GACrC,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,sBAA+C,EACzD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAcT"}
1
+ {"version":3,"file":"transport-codec.d.ts","sourceRoot":"","sources":["../src/transport-codec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAA;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAC9B;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAsCD,eAAO,MAAM,cAAc,EAAE,cAY3B,CAAA;AAEF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAAA;IAC1D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAAA;IAChD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAAA;CACxD;AAUD,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,QAAQ,GAAE,cAA+B,GACxC,sBAAsB,CA0ExB;AAED,eAAO,MAAM,sBAAsB,EAAE,sBAEnC,CAAA;AAEF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,KAAK,GAAE,cAA+B,EACtC,IAAI,GAAE,YAAiB,GACtB,QAAQ,CAKV;AAQD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,UAAU,CAAC,CA8BrB;AAaD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,sBAA+C,EACzD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAQlB;AAQD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,KAAK,GAAE,cAA+B,GACrC,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,sBAA+C,EACzD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAsBT"}
@@ -5,11 +5,31 @@
5
5
  const DEFAULT_MAX_BYTES = 16 * 1024 * 1024;
6
6
  const TOKEN = /^[a-z][a-z0-9_.-]{0,63}$/;
7
7
  export class TransportCodecError extends TypeError {
8
- constructor(message) {
9
- super(message);
8
+ constructor(message, options) {
9
+ super(message, options);
10
10
  this.name = "TransportCodecError";
11
11
  }
12
12
  }
13
+ /**
14
+ * Run a decode step and normalize whatever it throws into {@link TransportCodecError}.
15
+ *
16
+ * Decoding is the one place this module touches attacker-controlled bytes, and the primitives it
17
+ * delegates to raise their own native types - `JSON.parse` throws `SyntaxError`, a BYO codec throws
18
+ * whatever it likes. Every other failure here is a `TransportCodecError`, so letting those escape
19
+ * would mean a malformed payload - the single most likely hostile input - is the one case that slips
20
+ * past a caller catching the documented error type. The original is kept as `cause`, so the parse
21
+ * failure stays diagnosable; a codec already speaking the contract is re-thrown untouched.
22
+ */
23
+ function decodeOrThrow(decode, message) {
24
+ try {
25
+ return decode();
26
+ }
27
+ catch (cause) {
28
+ if (cause instanceof TransportCodecError)
29
+ throw cause;
30
+ throw new TransportCodecError(message, { cause });
31
+ }
32
+ }
13
33
  function maxBytesOf(options) {
14
34
  const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
15
35
  if (!Number.isSafeInteger(maxBytes) || maxBytes < 0)
@@ -132,13 +152,24 @@ function appendVary(current, name) {
132
152
  const values = current.split(",").map((value) => value.trim().toLowerCase());
133
153
  return values.includes(name.toLowerCase()) ? current : `${current}, ${name}`;
134
154
  }
135
- async function readBoundedText(response, options) {
155
+ /**
156
+ * Read a response body into memory, refusing to exceed `maxBytes`.
157
+ *
158
+ * Bounded while STREAMING rather than after the fact: the `content-length` shortcut only helps when a
159
+ * sender declares one, so the loop also counts as it goes and cancels the reader the moment the total
160
+ * passes the limit. A cap that buffers first and complains afterwards has already spent the memory it
161
+ * was meant to protect.
162
+ *
163
+ * Exported so the client can bound a plain-text body with the same reader it bounds JSON with, rather
164
+ * than growing a second copy of this loop that could drift from it.
165
+ */
166
+ export async function readBoundedBytes(response, options) {
136
167
  const maxBytes = maxBytesOf(options);
137
168
  const declared = response.headers.get("content-length");
138
169
  if (declared !== null && /^\d+$/u.test(declared) && Number(declared) > maxBytes)
139
170
  throw new TransportCodecError("transport payload exceeds maxBytes");
140
171
  if (response.body === null)
141
- return "";
172
+ return new Uint8Array(0);
142
173
  const reader = response.body.getReader();
143
174
  const chunks = [];
144
175
  let total = 0;
@@ -164,19 +195,25 @@ async function readBoundedText(response, options) {
164
195
  bytes.set(chunk, offset);
165
196
  offset += chunk.byteLength;
166
197
  }
167
- return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
198
+ return bytes;
199
+ }
200
+ async function readBoundedText(response, options) {
201
+ const bytes = await readBoundedBytes(response, options);
202
+ return decodeOrThrow(() => new TextDecoder("utf-8", { fatal: true }).decode(bytes), "transport payload is not valid UTF-8");
168
203
  }
169
204
  export async function decodeTransportResponse(response, registry = defaultTransportCodecs, options = {}) {
170
205
  const codec = registry.forContentType(response.headers.get("content-type"));
171
206
  const text = await readBoundedText(response, options);
172
- return text === "" ? undefined : codec.decode(text);
207
+ if (text === "")
208
+ return undefined;
209
+ return decodeOrThrow(() => codec.decode(text), `malformed transport body for codec ${codec.id}@${codec.version}`);
173
210
  }
174
211
  export function encodeTransportFrame(value, codec = plainJsonCodec) {
175
212
  return JSON.stringify({ codec: codec.id, version: codec.version, payload: codec.encode(value) });
176
213
  }
177
214
  export function decodeTransportFrame(frame, registry = defaultTransportCodecs, options = {}) {
178
215
  assertBounded(frame, options);
179
- const envelope = JSON.parse(frame);
216
+ const envelope = decodeOrThrow(() => JSON.parse(frame), "malformed transport frame");
180
217
  if (envelope === null ||
181
218
  typeof envelope !== "object" ||
182
219
  typeof envelope.codec !== "string" ||
@@ -184,7 +221,9 @@ export function decodeTransportFrame(frame, registry = defaultTransportCodecs, o
184
221
  typeof envelope.payload !== "string") {
185
222
  throw new TransportCodecError("malformed transport frame");
186
223
  }
187
- assertBounded(envelope.payload, options);
188
- return registry.byIdentity(envelope.codec, envelope.version).decode(envelope.payload);
224
+ const payload = envelope.payload;
225
+ assertBounded(payload, options);
226
+ const codec = registry.byIdentity(envelope.codec, envelope.version);
227
+ return decodeOrThrow(() => codec.decode(payload), `malformed transport frame payload for codec ${codec.id}@${codec.version}`);
189
228
  }
190
229
  //# sourceMappingURL=transport-codec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport-codec.js","sourceRoot":"","sources":["../src/transport-codec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport-codec.js","sourceRoot":"","sources":["../src/transport-codec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nifrajs/core",
3
- "version": "2.1.0",
4
- "description": "Bun-native, contract-first HTTP framework — the router, server, and route descriptor.",
3
+ "version": "2.3.0",
4
+ "description": "Bun-native, contract-first HTTP framework - the router, server, and route descriptor.",
5
5
  "keywords": [
6
6
  "bun",
7
7
  "typescript",
@@ -72,6 +72,11 @@
72
72
  "types": "./dist/assurance.d.ts",
73
73
  "default": "./dist/assurance.js"
74
74
  },
75
+ "./binary": {
76
+ "bun": "./src/binary.ts",
77
+ "types": "./dist/binary.d.ts",
78
+ "default": "./dist/binary.js"
79
+ },
75
80
  "./capabilities": {
76
81
  "bun": "./src/capabilities.ts",
77
82
  "types": "./dist/capabilities.d.ts",
@@ -201,6 +206,11 @@
201
206
  "bun": "./src/server/webhook.ts",
202
207
  "types": "./dist/server/webhook.d.ts",
203
208
  "default": "./dist/server/webhook.js"
209
+ },
210
+ "./response-contract": {
211
+ "bun": "./src/server/response-contract-lane.ts",
212
+ "types": "./dist/server/response-contract-lane.d.ts",
213
+ "default": "./dist/server/response-contract-lane.js"
204
214
  }
205
215
  },
206
216
  "files": [
package/src/assurance.ts CHANGED
@@ -4,8 +4,11 @@
4
4
  */
5
5
 
6
6
  import {
7
+ type CapabilityAccess,
7
8
  type CapabilityAssuranceReport,
9
+ type CapabilityDefinition,
8
10
  type CapabilityPolicy,
11
+ type CapabilityZone,
9
12
  defineCapabilityPolicy,
10
13
  } from "./capabilities.ts"
11
14
  import type {
@@ -40,6 +43,62 @@ export interface AssuranceRouteSelector {
40
43
  readonly paths?: readonly string[]
41
44
  /** Restrict the rule to MCP tool routes (`true`) or non-tool routes (`false`). */
42
45
  readonly tools?: boolean
46
+ /**
47
+ * Match routes declaring ANY of these capability tokens.
48
+ *
49
+ * Lets a policy be written about what a route DOES rather than where it lives: "anything that writes
50
+ * to the database must be authenticated" survives a route being moved or renamed, which a path glob
51
+ * does not. Reflection already carries the declared tokens, so this reads what the route said about
52
+ * itself.
53
+ *
54
+ * Naming exact tokens is precise but closed: a rule listing `db.write` does not cover `storage.write`,
55
+ * and a capability added next year escapes it in silence. Prefer `access`/`zone` for a rule that is
56
+ * meant to hold for a CLASS of effect.
57
+ */
58
+ readonly capabilities?: readonly string[]
59
+ /**
60
+ * Match routes declaring any capability whose definition has this access.
61
+ *
62
+ * This is the selector to reach for when the rule is "anything that writes must prove who asked":
63
+ * it is keyed on what the capability IS rather than what it is called, so a token introduced later
64
+ * is covered the day it is declared instead of the day someone remembers to widen the rule.
65
+ *
66
+ * Requires capability definitions. A policy using it without them is refused rather than quietly
67
+ * matching nothing - a selector that matches nothing lets the route fall through to a laxer rule.
68
+ */
69
+ readonly access?: CapabilityAccess
70
+ /**
71
+ * Match routes declaring any capability in this zone. Combined with `access`, both must hold for the
72
+ * SAME capability, so `{ access: "write", zone: "domain" }` is "writes business state" and does not
73
+ * match a route that only writes an audit log.
74
+ */
75
+ readonly zone?: CapabilityZone
76
+ }
77
+
78
+ /** Extra inputs an assurance evaluation needs beyond the routes themselves. */
79
+ export interface AssuranceEvaluationOptions {
80
+ /**
81
+ * Capability definitions, required by any rule selecting on `access`/`zone`. Normally
82
+ * `config.capabilities.definitions`.
83
+ */
84
+ readonly definitions?: readonly CapabilityDefinition[]
85
+ }
86
+
87
+ /** Selector keys that cannot be resolved from reflection alone. */
88
+ const CLASS_SELECTOR_KEYS = ["access", "zone"] as const
89
+
90
+ const usesClassSelector = (selector: AssuranceRouteSelector): boolean =>
91
+ selector.access !== undefined || selector.zone !== undefined
92
+
93
+ /** The rules whose selector needs capability definitions to mean anything. */
94
+ function rulesNeedingDefinitions(policy: AssurancePolicy): readonly string[] {
95
+ return policy.rules.filter((rule) => usesClassSelector(rule.match)).map((rule) => rule.name)
96
+ }
97
+
98
+ function definitionMap(
99
+ definitions: readonly CapabilityDefinition[] | undefined,
100
+ ): ReadonlyMap<string, CapabilityDefinition> {
101
+ return new Map((definitions ?? []).map((definition) => [definition.id, definition]))
43
102
  }
44
103
 
45
104
  export interface AssuranceRule {
@@ -166,6 +225,19 @@ export function defineAssurancePolicy(policy: AssurancePolicy): AssurancePolicy
166
225
  if (names.has(name))
167
226
  throw new Error(`route assurance: duplicate rule name ${JSON.stringify(name)}`)
168
227
  names.add(name)
228
+ // The selector is rebuilt from known keys below, so an unrecognised one would be dropped in
229
+ // silence - and a selector that loses its only constraint matches EVERY route, making the rule
230
+ // swallow everything after it. A misspelled key is a policy hole, so it is refused here.
231
+ const unknown = Object.keys(rule.match).filter(
232
+ (key) => !["methods", "paths", "tools", "capabilities", ...CLASS_SELECTOR_KEYS].includes(key),
233
+ )
234
+ if (unknown.length > 0) {
235
+ throw new Error(
236
+ `route assurance: rule ${JSON.stringify(rule.name)} has unknown selector key(s) ${unknown
237
+ .map((key) => JSON.stringify(key))
238
+ .join(", ")} - a dropped selector would match every route`,
239
+ )
240
+ }
169
241
  if (rule.match.tools !== undefined && typeof rule.match.tools !== "boolean") {
170
242
  throw new Error(
171
243
  `route assurance: rule ${JSON.stringify(name)} tools selector must be boolean`,
@@ -181,6 +253,24 @@ export function defineAssurancePolicy(policy: AssurancePolicy): AssurancePolicy
181
253
  routeGlob(path)
182
254
  return path
183
255
  })
256
+ const capabilities = rule.match.capabilities
257
+ if (capabilities !== undefined && (!Array.isArray(capabilities) || capabilities.length === 0)) {
258
+ throw new Error(
259
+ `route assurance: rule ${JSON.stringify(name)} capabilities selector must be a non-empty array`,
260
+ )
261
+ }
262
+ const access = rule.match.access
263
+ if (access !== undefined && access !== "read" && access !== "write") {
264
+ throw new Error(
265
+ `route assurance: rule ${JSON.stringify(name)} access selector must be "read" or "write"`,
266
+ )
267
+ }
268
+ const zone = rule.match.zone
269
+ if (zone !== undefined && zone !== "domain" && zone !== "operational") {
270
+ throw new Error(
271
+ `route assurance: rule ${JSON.stringify(name)} zone selector must be "domain" or "operational"`,
272
+ )
273
+ }
184
274
  const required = normalizeEvidenceIds(rule.require, "required")
185
275
  const forbidden = normalizeEvidenceIds(rule.forbid, "forbidden")
186
276
  const overlap = required.find((id) => forbidden.includes(id))
@@ -195,6 +285,9 @@ export function defineAssurancePolicy(policy: AssurancePolicy): AssurancePolicy
195
285
  ...(methods !== undefined ? { methods: Object.freeze(methods as Method[]) } : {}),
196
286
  ...(paths !== undefined ? { paths: Object.freeze(paths) } : {}),
197
287
  ...(rule.match.tools !== undefined ? { tools: rule.match.tools } : {}),
288
+ ...(capabilities !== undefined ? { capabilities: Object.freeze([...capabilities]) } : {}),
289
+ ...(access !== undefined ? { access } : {}),
290
+ ...(zone !== undefined ? { zone } : {}),
198
291
  }),
199
292
  require: required,
200
293
  forbid: forbidden,
@@ -219,12 +312,27 @@ export function defineAssuranceConfig(config: AssuranceConfig): AssuranceConfig
219
312
  if (config.invariants !== undefined && typeof config.invariants.executor !== "function") {
220
313
  throw new Error("route assurance: invariant executor must be a function")
221
314
  }
315
+ const policy = defineAssurancePolicy(config.policy)
316
+ const capabilities =
317
+ config.capabilities !== undefined ? defineCapabilityPolicy(config.capabilities) : undefined
318
+ // An `access`/`zone` selector is resolved through the capability definitions. Without them it can
319
+ // only ever match nothing, and a rule that matches nothing does not fail - the route falls past it
320
+ // to whatever laxer rule comes next. Refuse the config here rather than ship a policy whose
321
+ // strictest rule is inert.
322
+ const needDefinitions = rulesNeedingDefinitions(policy)
323
+ if (needDefinitions.length > 0 && (capabilities?.definitions.length ?? 0) === 0) {
324
+ throw new Error(
325
+ `route assurance: rule(s) ${needDefinitions
326
+ .map((name) => JSON.stringify(name))
327
+ .join(
328
+ ", ",
329
+ )} select on ${CLASS_SELECTOR_KEYS.join("/")}, which needs capability definitions - add a \`capabilities\` policy defining the tokens your routes declare`,
330
+ )
331
+ }
222
332
  return Object.freeze({
223
333
  source: config.source,
224
- policy: defineAssurancePolicy(config.policy),
225
- ...(config.capabilities !== undefined
226
- ? { capabilities: defineCapabilityPolicy(config.capabilities) }
227
- : {}),
334
+ policy,
335
+ ...(capabilities !== undefined ? { capabilities } : {}),
228
336
  ...(config.manifest !== undefined
229
337
  ? {
230
338
  manifest: Object.freeze({
@@ -239,16 +347,38 @@ export function defineAssuranceConfig(config: AssuranceConfig): AssuranceConfig
239
347
  })
240
348
  }
241
349
 
242
- /** Shared selector semantics for policy rules and framework adapters. */
350
+ /**
351
+ * Shared selector semantics for policy rules and framework adapters.
352
+ *
353
+ * `definitions` is only consulted by the `access`/`zone` selectors; every other selector reads
354
+ * reflection alone. A caller that omits it while the selector needs it gets no match, so callers that
355
+ * accept user policy must reject that combination up front - `defineAssuranceConfig` does.
356
+ */
243
357
  export function matchesAssuranceSelector(
244
- route: Pick<ReflectedRoute, "method" | "path" | "tool">,
358
+ route: Pick<ReflectedRoute, "method" | "path" | "tool" | "capabilities">,
245
359
  selector: AssuranceRouteSelector,
360
+ definitions?: ReadonlyMap<string, CapabilityDefinition>,
246
361
  ): boolean {
247
- const { methods, paths, tools } = selector
362
+ const { methods, paths, tools, capabilities, access, zone } = selector
248
363
  if (methods !== undefined && !methods.includes(route.method as Method)) return false
249
364
  if (paths !== undefined && !paths.some((pattern) => routeGlob(pattern).test(route.path)))
250
365
  return false
251
366
  if (tools !== undefined && (route.tool !== undefined) !== tools) return false
367
+ const declared = route.capabilities ?? []
368
+ if (capabilities !== undefined && !capabilities.some((token) => declared.includes(token)))
369
+ return false
370
+ if (access !== undefined || zone !== undefined) {
371
+ // Both constraints must hold for the SAME capability: a route that reads the database and writes
372
+ // an audit log must not satisfy "writes business state" by combining halves of two tokens.
373
+ const matched = declared.some((token) => {
374
+ const definition = definitions?.get(token)
375
+ if (definition === undefined) return false
376
+ if (access !== undefined && definition.access !== access) return false
377
+ if (zone !== undefined && definition.zone !== zone) return false
378
+ return true
379
+ })
380
+ if (!matched) return false
381
+ }
252
382
  return true
253
383
  }
254
384
 
@@ -256,8 +386,22 @@ export function matchesAssuranceSelector(
256
386
  export function evaluateRouteAssurance(
257
387
  source: unknown,
258
388
  policyInput: AssurancePolicy,
389
+ options?: AssuranceEvaluationOptions,
259
390
  ): AssuranceReport {
260
391
  const policy = defineAssurancePolicy(policyInput)
392
+ const definitions = definitionMap(options?.definitions)
393
+ // Same reasoning as `defineAssuranceConfig`, repeated for callers that evaluate a bare policy: a
394
+ // class selector with nothing to resolve against is an inert rule, not a lenient one.
395
+ const needDefinitions = rulesNeedingDefinitions(policy)
396
+ if (needDefinitions.length > 0 && definitions.size === 0) {
397
+ throw new Error(
398
+ `route assurance: rule(s) ${needDefinitions
399
+ .map((name) => JSON.stringify(name))
400
+ .join(
401
+ ", ",
402
+ )} select on ${CLASS_SELECTOR_KEYS.join("/")} but no capability definitions were supplied`,
403
+ )
404
+ }
261
405
  const findings: AssuranceFinding[] = []
262
406
  const routes: AssuredRoute[] = []
263
407
  const reflected = reflectRoutes(source)
@@ -272,7 +416,9 @@ export function evaluateRouteAssurance(
272
416
  }
273
417
 
274
418
  for (const route of reflected) {
275
- const rule = policy.rules.find((candidate) => matchesAssuranceSelector(route, candidate.match))
419
+ const rule = policy.rules.find((candidate) =>
420
+ matchesAssuranceSelector(route, candidate.match, definitions),
421
+ )
276
422
  const evidence = route.assurance ?? []
277
423
  const evidenceIds = new Set(evidence.map((item) => item.id))
278
424
  if (rule === undefined) {