@vivero/stoma 0.1.0-rc.10

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 (254) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/LICENSE +21 -0
  3. package/README.md +325 -0
  4. package/dist/adapters/bun.d.ts +9 -0
  5. package/dist/adapters/bun.js +8 -0
  6. package/dist/adapters/bun.js.map +1 -0
  7. package/dist/adapters/cloudflare.d.ts +49 -0
  8. package/dist/adapters/cloudflare.js +85 -0
  9. package/dist/adapters/cloudflare.js.map +1 -0
  10. package/dist/adapters/deno.d.ts +9 -0
  11. package/dist/adapters/deno.js +8 -0
  12. package/dist/adapters/deno.js.map +1 -0
  13. package/dist/adapters/durable-object.d.ts +63 -0
  14. package/dist/adapters/durable-object.js +46 -0
  15. package/dist/adapters/durable-object.js.map +1 -0
  16. package/dist/adapters/index.d.ts +13 -0
  17. package/dist/adapters/index.js +53 -0
  18. package/dist/adapters/index.js.map +1 -0
  19. package/dist/adapters/memory.d.ts +9 -0
  20. package/dist/adapters/memory.js +14 -0
  21. package/dist/adapters/memory.js.map +1 -0
  22. package/dist/adapters/node.d.ts +9 -0
  23. package/dist/adapters/node.js +8 -0
  24. package/dist/adapters/node.js.map +1 -0
  25. package/dist/adapters/postgres.d.ts +109 -0
  26. package/dist/adapters/postgres.js +242 -0
  27. package/dist/adapters/postgres.js.map +1 -0
  28. package/dist/adapters/redis.d.ts +116 -0
  29. package/dist/adapters/redis.js +194 -0
  30. package/dist/adapters/redis.js.map +1 -0
  31. package/dist/adapters/testing.d.ts +32 -0
  32. package/dist/adapters/testing.js +33 -0
  33. package/dist/adapters/testing.js.map +1 -0
  34. package/dist/adapters/types.d.ts +4 -0
  35. package/dist/adapters/types.js +1 -0
  36. package/dist/adapters/types.js.map +1 -0
  37. package/dist/config/index.d.ts +11 -0
  38. package/dist/config/index.js +21 -0
  39. package/dist/config/index.js.map +1 -0
  40. package/dist/config/merge.d.ts +48 -0
  41. package/dist/config/merge.js +83 -0
  42. package/dist/config/merge.js.map +1 -0
  43. package/dist/config/schema.d.ts +254 -0
  44. package/dist/config/schema.js +109 -0
  45. package/dist/config/schema.js.map +1 -0
  46. package/dist/core/errors.d.ts +66 -0
  47. package/dist/core/errors.js +47 -0
  48. package/dist/core/errors.js.map +1 -0
  49. package/dist/core/gateway.d.ts +44 -0
  50. package/dist/core/gateway.js +400 -0
  51. package/dist/core/gateway.js.map +1 -0
  52. package/dist/core/health.d.ts +78 -0
  53. package/dist/core/health.js +65 -0
  54. package/dist/core/health.js.map +1 -0
  55. package/dist/core/pipeline.d.ts +62 -0
  56. package/dist/core/pipeline.js +214 -0
  57. package/dist/core/pipeline.js.map +1 -0
  58. package/dist/core/protocol.d.ts +4 -0
  59. package/dist/core/protocol.js +1 -0
  60. package/dist/core/protocol.js.map +1 -0
  61. package/dist/core/scope.d.ts +67 -0
  62. package/dist/core/scope.js +44 -0
  63. package/dist/core/scope.js.map +1 -0
  64. package/dist/core/types.d.ts +252 -0
  65. package/dist/core/types.js +1 -0
  66. package/dist/core/types.js.map +1 -0
  67. package/dist/index.d.ts +57 -0
  68. package/dist/index.js +158 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/observability/admin.d.ts +32 -0
  71. package/dist/observability/admin.js +85 -0
  72. package/dist/observability/admin.js.map +1 -0
  73. package/dist/observability/metrics.d.ts +78 -0
  74. package/dist/observability/metrics.js +107 -0
  75. package/dist/observability/metrics.js.map +1 -0
  76. package/dist/observability/tracing.d.ts +149 -0
  77. package/dist/observability/tracing.js +191 -0
  78. package/dist/observability/tracing.js.map +1 -0
  79. package/dist/policies/auth/api-key-auth.d.ts +64 -0
  80. package/dist/policies/auth/api-key-auth.js +93 -0
  81. package/dist/policies/auth/api-key-auth.js.map +1 -0
  82. package/dist/policies/auth/basic-auth.d.ts +33 -0
  83. package/dist/policies/auth/basic-auth.js +96 -0
  84. package/dist/policies/auth/basic-auth.js.map +1 -0
  85. package/dist/policies/auth/crypto.d.ts +29 -0
  86. package/dist/policies/auth/crypto.js +100 -0
  87. package/dist/policies/auth/crypto.js.map +1 -0
  88. package/dist/policies/auth/generate-http-signature.d.ts +30 -0
  89. package/dist/policies/auth/generate-http-signature.js +79 -0
  90. package/dist/policies/auth/generate-http-signature.js.map +1 -0
  91. package/dist/policies/auth/generate-jwt.d.ts +44 -0
  92. package/dist/policies/auth/generate-jwt.js +99 -0
  93. package/dist/policies/auth/generate-jwt.js.map +1 -0
  94. package/dist/policies/auth/http-signature-base.d.ts +55 -0
  95. package/dist/policies/auth/http-signature-base.js +140 -0
  96. package/dist/policies/auth/http-signature-base.js.map +1 -0
  97. package/dist/policies/auth/jws.d.ts +46 -0
  98. package/dist/policies/auth/jws.js +317 -0
  99. package/dist/policies/auth/jws.js.map +1 -0
  100. package/dist/policies/auth/jwt-auth.d.ts +64 -0
  101. package/dist/policies/auth/jwt-auth.js +266 -0
  102. package/dist/policies/auth/jwt-auth.js.map +1 -0
  103. package/dist/policies/auth/oauth2.d.ts +38 -0
  104. package/dist/policies/auth/oauth2.js +254 -0
  105. package/dist/policies/auth/oauth2.js.map +1 -0
  106. package/dist/policies/auth/rbac.d.ts +30 -0
  107. package/dist/policies/auth/rbac.js +115 -0
  108. package/dist/policies/auth/rbac.js.map +1 -0
  109. package/dist/policies/auth/verify-http-signature.d.ts +30 -0
  110. package/dist/policies/auth/verify-http-signature.js +147 -0
  111. package/dist/policies/auth/verify-http-signature.js.map +1 -0
  112. package/dist/policies/index.d.ts +51 -0
  113. package/dist/policies/index.js +109 -0
  114. package/dist/policies/index.js.map +1 -0
  115. package/dist/policies/mock.d.ts +60 -0
  116. package/dist/policies/mock.js +29 -0
  117. package/dist/policies/mock.js.map +1 -0
  118. package/dist/policies/observability/assign-metrics.d.ts +37 -0
  119. package/dist/policies/observability/assign-metrics.js +29 -0
  120. package/dist/policies/observability/assign-metrics.js.map +1 -0
  121. package/dist/policies/observability/metrics-reporter.d.ts +25 -0
  122. package/dist/policies/observability/metrics-reporter.js +62 -0
  123. package/dist/policies/observability/metrics-reporter.js.map +1 -0
  124. package/dist/policies/observability/request-log.d.ts +135 -0
  125. package/dist/policies/observability/request-log.js +134 -0
  126. package/dist/policies/observability/request-log.js.map +1 -0
  127. package/dist/policies/observability/server-timing.d.ts +35 -0
  128. package/dist/policies/observability/server-timing.js +89 -0
  129. package/dist/policies/observability/server-timing.js.map +1 -0
  130. package/dist/policies/proxy.d.ts +59 -0
  131. package/dist/policies/proxy.js +47 -0
  132. package/dist/policies/proxy.js.map +1 -0
  133. package/dist/policies/resilience/circuit-breaker.d.ts +4 -0
  134. package/dist/policies/resilience/circuit-breaker.js +280 -0
  135. package/dist/policies/resilience/circuit-breaker.js.map +1 -0
  136. package/dist/policies/resilience/latency-injection.d.ts +35 -0
  137. package/dist/policies/resilience/latency-injection.js +26 -0
  138. package/dist/policies/resilience/latency-injection.js.map +1 -0
  139. package/dist/policies/resilience/retry.d.ts +71 -0
  140. package/dist/policies/resilience/retry.js +79 -0
  141. package/dist/policies/resilience/retry.js.map +1 -0
  142. package/dist/policies/resilience/timeout.d.ts +32 -0
  143. package/dist/policies/resilience/timeout.js +46 -0
  144. package/dist/policies/resilience/timeout.js.map +1 -0
  145. package/dist/policies/sdk/define-policy.d.ts +176 -0
  146. package/dist/policies/sdk/define-policy.js +42 -0
  147. package/dist/policies/sdk/define-policy.js.map +1 -0
  148. package/dist/policies/sdk/helpers.d.ts +132 -0
  149. package/dist/policies/sdk/helpers.js +87 -0
  150. package/dist/policies/sdk/helpers.js.map +1 -0
  151. package/dist/policies/sdk/index.d.ts +10 -0
  152. package/dist/policies/sdk/index.js +35 -0
  153. package/dist/policies/sdk/index.js.map +1 -0
  154. package/dist/policies/sdk/priority.d.ts +44 -0
  155. package/dist/policies/sdk/priority.js +36 -0
  156. package/dist/policies/sdk/priority.js.map +1 -0
  157. package/dist/policies/sdk/testing.d.ts +53 -0
  158. package/dist/policies/sdk/testing.js +41 -0
  159. package/dist/policies/sdk/testing.js.map +1 -0
  160. package/dist/policies/sdk/trace.d.ts +73 -0
  161. package/dist/policies/sdk/trace.js +25 -0
  162. package/dist/policies/sdk/trace.js.map +1 -0
  163. package/dist/policies/traffic/cache.d.ts +4 -0
  164. package/dist/policies/traffic/cache.js +224 -0
  165. package/dist/policies/traffic/cache.js.map +1 -0
  166. package/dist/policies/traffic/dynamic-routing.d.ts +54 -0
  167. package/dist/policies/traffic/dynamic-routing.js +36 -0
  168. package/dist/policies/traffic/dynamic-routing.js.map +1 -0
  169. package/dist/policies/traffic/geo-ip-filter.d.ts +37 -0
  170. package/dist/policies/traffic/geo-ip-filter.js +74 -0
  171. package/dist/policies/traffic/geo-ip-filter.js.map +1 -0
  172. package/dist/policies/traffic/http-callout.d.ts +59 -0
  173. package/dist/policies/traffic/http-callout.js +69 -0
  174. package/dist/policies/traffic/http-callout.js.map +1 -0
  175. package/dist/policies/traffic/interrupt.d.ts +46 -0
  176. package/dist/policies/traffic/interrupt.js +38 -0
  177. package/dist/policies/traffic/interrupt.js.map +1 -0
  178. package/dist/policies/traffic/ip-filter.d.ts +47 -0
  179. package/dist/policies/traffic/ip-filter.js +57 -0
  180. package/dist/policies/traffic/ip-filter.js.map +1 -0
  181. package/dist/policies/traffic/json-threat-protection.d.ts +51 -0
  182. package/dist/policies/traffic/json-threat-protection.js +173 -0
  183. package/dist/policies/traffic/json-threat-protection.js.map +1 -0
  184. package/dist/policies/traffic/rate-limit.d.ts +4 -0
  185. package/dist/policies/traffic/rate-limit.js +145 -0
  186. package/dist/policies/traffic/rate-limit.js.map +1 -0
  187. package/dist/policies/traffic/regex-threat-protection.d.ts +54 -0
  188. package/dist/policies/traffic/regex-threat-protection.js +109 -0
  189. package/dist/policies/traffic/regex-threat-protection.js.map +1 -0
  190. package/dist/policies/traffic/request-limit.d.ts +27 -0
  191. package/dist/policies/traffic/request-limit.js +41 -0
  192. package/dist/policies/traffic/request-limit.js.map +1 -0
  193. package/dist/policies/traffic/resource-filter.d.ts +38 -0
  194. package/dist/policies/traffic/resource-filter.js +184 -0
  195. package/dist/policies/traffic/resource-filter.js.map +1 -0
  196. package/dist/policies/traffic/ssl-enforce.d.ts +27 -0
  197. package/dist/policies/traffic/ssl-enforce.js +38 -0
  198. package/dist/policies/traffic/ssl-enforce.js.map +1 -0
  199. package/dist/policies/traffic/traffic-shadow.d.ts +40 -0
  200. package/dist/policies/traffic/traffic-shadow.js +87 -0
  201. package/dist/policies/traffic/traffic-shadow.js.map +1 -0
  202. package/dist/policies/transform/assign-attributes.d.ts +33 -0
  203. package/dist/policies/transform/assign-attributes.js +38 -0
  204. package/dist/policies/transform/assign-attributes.js.map +1 -0
  205. package/dist/policies/transform/assign-content.d.ts +40 -0
  206. package/dist/policies/transform/assign-content.js +185 -0
  207. package/dist/policies/transform/assign-content.js.map +1 -0
  208. package/dist/policies/transform/cors.d.ts +57 -0
  209. package/dist/policies/transform/cors.js +23 -0
  210. package/dist/policies/transform/cors.js.map +1 -0
  211. package/dist/policies/transform/json-validation.d.ts +50 -0
  212. package/dist/policies/transform/json-validation.js +125 -0
  213. package/dist/policies/transform/json-validation.js.map +1 -0
  214. package/dist/policies/transform/override-method.d.ts +33 -0
  215. package/dist/policies/transform/override-method.js +48 -0
  216. package/dist/policies/transform/override-method.js.map +1 -0
  217. package/dist/policies/transform/request-validation.d.ts +59 -0
  218. package/dist/policies/transform/request-validation.js +121 -0
  219. package/dist/policies/transform/request-validation.js.map +1 -0
  220. package/dist/policies/transform/transform.d.ts +75 -0
  221. package/dist/policies/transform/transform.js +116 -0
  222. package/dist/policies/transform/transform.js.map +1 -0
  223. package/dist/policies/types.d.ts +4 -0
  224. package/dist/policies/types.js +1 -0
  225. package/dist/policies/types.js.map +1 -0
  226. package/dist/protocol-2fD3DJrL.d.ts +725 -0
  227. package/dist/utils/cidr.d.ts +58 -0
  228. package/dist/utils/cidr.js +107 -0
  229. package/dist/utils/cidr.js.map +1 -0
  230. package/dist/utils/debug.d.ts +1 -0
  231. package/dist/utils/debug.js +13 -0
  232. package/dist/utils/debug.js.map +1 -0
  233. package/dist/utils/headers.d.ts +68 -0
  234. package/dist/utils/headers.js +25 -0
  235. package/dist/utils/headers.js.map +1 -0
  236. package/dist/utils/ip.d.ts +64 -0
  237. package/dist/utils/ip.js +29 -0
  238. package/dist/utils/ip.js.map +1 -0
  239. package/dist/utils/redact.d.ts +30 -0
  240. package/dist/utils/redact.js +52 -0
  241. package/dist/utils/redact.js.map +1 -0
  242. package/dist/utils/request-id.d.ts +11 -0
  243. package/dist/utils/request-id.js +7 -0
  244. package/dist/utils/request-id.js.map +1 -0
  245. package/dist/utils/timing-safe.d.ts +31 -0
  246. package/dist/utils/timing-safe.js +17 -0
  247. package/dist/utils/timing-safe.js.map +1 -0
  248. package/dist/utils/timing.d.ts +27 -0
  249. package/dist/utils/timing.js +12 -0
  250. package/dist/utils/timing.js.map +1 -0
  251. package/dist/utils/trace-context.d.ts +51 -0
  252. package/dist/utils/trace-context.js +37 -0
  253. package/dist/utils/trace-context.js.map +1 -0
  254. package/package.json +213 -0
@@ -0,0 +1,725 @@
1
+ import { MiddlewareHandler, Context } from 'hono';
2
+ import { TraceReporter } from './policies/sdk/trace.js';
3
+ import { DebugLogger } from '@vivero/stoma-core';
4
+
5
+ /**
6
+ * Policy type system - the building blocks of gateway pipelines.
7
+ *
8
+ * A {@link Policy} is a named middleware with priority ordering and
9
+ * optional protocol-agnostic evaluation. Policies are composed into
10
+ * pipelines at the global and route level, merged by name (route-level
11
+ * wins), and sorted by priority ascending.
12
+ *
13
+ * The HTTP runtime uses {@link Policy.handler} (Hono middleware).
14
+ * Non-HTTP runtimes (ext_proc, WebSocket) use {@link Policy.evaluate}.
15
+ *
16
+ * The {@link PolicyContext} provides request metadata (ID, timing, debug)
17
+ * to policies at runtime via `getGatewayContext(c)`.
18
+ *
19
+ * @module policy-types
20
+ */
21
+
22
+ /**
23
+ * A Policy is a named middleware with priority ordering and optional
24
+ * protocol-agnostic evaluation.
25
+ *
26
+ * - {@link handler} - HTTP runtime entry point (Hono middleware).
27
+ * Used by {@link createGateway}.
28
+ * - {@link evaluate} - Protocol-agnostic entry point. Used by non-HTTP
29
+ * runtimes (ext_proc, WebSocket) to invoke the policy without Hono.
30
+ * - {@link phases} - Which processing phases this policy participates in.
31
+ * Used by phase-based runtimes to skip irrelevant policies.
32
+ * - {@link httpOnly} - Set to `true` for policies that can ONLY work with
33
+ * the HTTP protocol and don't make sense for ext_proc or WebSocket.
34
+ */
35
+ interface Policy {
36
+ /** Unique policy name (e.g. "jwt-auth", "rate-limit") */
37
+ name: string;
38
+ /** The Hono middleware handler - HTTP runtime entry point. */
39
+ handler: MiddlewareHandler;
40
+ /** Policy priority - lower numbers execute first. Default: 100. */
41
+ priority?: number;
42
+ /**
43
+ * Protocol-agnostic evaluation entry point.
44
+ *
45
+ * Used by non-HTTP runtimes (ext_proc, WebSocket) to invoke this
46
+ * policy without Hono. The HTTP runtime ({@link createGateway}) uses
47
+ * {@link handler} directly and ignores this field.
48
+ *
49
+ * Policies that implement `evaluate` work across all runtimes.
50
+ * Policies that only implement `handler` are HTTP-only.
51
+ */
52
+ evaluate?: PolicyEvaluator;
53
+ /**
54
+ * Processing phases this policy participates in.
55
+ *
56
+ * Used by phase-based runtimes (ext_proc) to skip policies that don't
57
+ * apply to the current processing phase. For example, a JWT auth policy
58
+ * only needs `"request-headers"`, while a response transform policy
59
+ * needs `"response-headers"` and `"response-body"`.
60
+ *
61
+ * Default: `["request-headers"]` (most policies only inspect request headers).
62
+ */
63
+ phases?: ProcessingPhase[];
64
+ /**
65
+ * Set to `true` for policies that only work with the HTTP protocol.
66
+ *
67
+ * These policies rely on HTTP-specific concepts (Request/Response objects,
68
+ * specific headers, HTTP status codes, etc.) and cannot be meaningfully
69
+ * evaluated in other protocols like ext_proc or WebSocket.
70
+ *
71
+ * Examples:
72
+ * - `cors` - uses HTTP-specific `Access-Control-*` headers
73
+ * - `ssl-enforce` - HTTP-only protocol concept
74
+ * - `proxy` - HTTP-to-HTTP forwarding
75
+ * - `mock` - returns HTTP Response objects
76
+ *
77
+ * Tooling can use this flag to:
78
+ * - Skip these policies when generating docs for non-HTTP runtimes
79
+ * - Warn if an HTTP-only policy is used in a non-HTTP gateway config
80
+ */
81
+ httpOnly?: true;
82
+ }
83
+ /** Base configuration shared by all policies */
84
+ interface PolicyConfig {
85
+ /** Skip this policy when condition returns true */
86
+ skip?: (c: unknown) => boolean | Promise<boolean>;
87
+ }
88
+ /** Context available to policies during execution */
89
+ interface PolicyContext {
90
+ /** Unique request ID for tracing */
91
+ requestId: string;
92
+ /** Timestamp when the request entered the gateway */
93
+ startTime: number;
94
+ /** Gateway name */
95
+ gatewayName: string;
96
+ /** Matched route path pattern */
97
+ routePath: string;
98
+ /** W3C Trace Context - 32-hex trace ID (propagated or generated). */
99
+ traceId: string;
100
+ /** W3C Trace Context - 16-hex span ID for this gateway request. */
101
+ spanId: string;
102
+ /**
103
+ * Get a debug logger for the given namespace.
104
+ * Returns a no-op when debug is disabled (zero overhead).
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const ctx = getGatewayContext(c);
109
+ * const debug = ctx?.debug("stoma:policy:cache");
110
+ * debug?.("HIT", cacheKey);
111
+ * ```
112
+ */
113
+ debug: (namespace: string) => DebugLogger;
114
+ /** Runtime adapter providing store implementations and runtime-specific capabilities. */
115
+ adapter?: GatewayAdapter;
116
+ }
117
+
118
+ /**
119
+ * Circuit breaker policy - protect upstream services from cascading failures.
120
+ *
121
+ * Implements the three-state circuit breaker pattern (closed / open / half-open)
122
+ * with pluggable state storage via {@link CircuitBreakerStore}.
123
+ *
124
+ * @module circuit-breaker
125
+ */
126
+
127
+ /** The three states of the circuit breaker state machine. */
128
+ type CircuitState = "closed" | "open" | "half-open";
129
+ /** Point-in-time snapshot of a circuit's state and counters. */
130
+ interface CircuitBreakerSnapshot {
131
+ /** Current circuit state. */
132
+ state: CircuitState;
133
+ /** Number of consecutive failures since last reset. */
134
+ failureCount: number;
135
+ /** Number of successful probes in half-open state. */
136
+ successCount: number;
137
+ /** Epoch ms of the most recent failure. `0` if no failures recorded. */
138
+ lastFailureTime: number;
139
+ /** Epoch ms of the most recent state transition. */
140
+ lastStateChange: number;
141
+ }
142
+ /**
143
+ * Pluggable storage backend for circuit breaker state.
144
+ *
145
+ * Implement this interface to store circuit state in Durable Objects,
146
+ * KV, or any shared datastore for multi-instance deployments.
147
+ */
148
+ interface CircuitBreakerStore {
149
+ /** Read the current snapshot for a circuit key. */
150
+ getState(key: string): Promise<CircuitBreakerSnapshot>;
151
+ /** Record a successful request and return the updated snapshot. */
152
+ recordSuccess(key: string): Promise<CircuitBreakerSnapshot>;
153
+ /** Record a failed request and return the updated snapshot. */
154
+ recordFailure(key: string): Promise<CircuitBreakerSnapshot>;
155
+ /** Transition the circuit to a new state and return the updated snapshot. */
156
+ transition(key: string, to: CircuitState): Promise<CircuitBreakerSnapshot>;
157
+ /** Fully reset a circuit, removing all state. */
158
+ reset(key: string): Promise<void>;
159
+ /** Optional cleanup - release timers, close connections, etc. */
160
+ destroy?(): void;
161
+ }
162
+ declare class InMemoryCircuitBreakerStore implements CircuitBreakerStore {
163
+ private circuits;
164
+ private getOrCreate;
165
+ getState(key: string): Promise<CircuitBreakerSnapshot>;
166
+ recordSuccess(key: string): Promise<CircuitBreakerSnapshot>;
167
+ recordFailure(key: string): Promise<CircuitBreakerSnapshot>;
168
+ transition(key: string, to: CircuitState): Promise<CircuitBreakerSnapshot>;
169
+ reset(key: string): Promise<void>;
170
+ /** Remove all circuits (for testing) */
171
+ clear(): void;
172
+ /** Release all state. */
173
+ destroy(): void;
174
+ }
175
+ interface CircuitBreakerConfig extends PolicyConfig {
176
+ /** Number of failures before opening the circuit. Default: 5. */
177
+ failureThreshold?: number;
178
+ /** Time in ms before transitioning from open → half-open. Default: 30000. */
179
+ resetTimeoutMs?: number;
180
+ /** Max concurrent probes allowed in half-open state. Default: 1. */
181
+ halfOpenMax?: number;
182
+ /** Status codes considered failures. Default: [500, 502, 503, 504]. */
183
+ failureOn?: number[];
184
+ /** Storage backend. Default: InMemoryCircuitBreakerStore. */
185
+ store?: CircuitBreakerStore;
186
+ /** Key extractor. Default: request URL pathname. */
187
+ key?: (c: Context) => string;
188
+ /** HTTP status code when the circuit is open. Default: 503. */
189
+ openStatusCode?: number;
190
+ /**
191
+ * Callback invoked on every state transition.
192
+ *
193
+ * Called via `safeCall` so errors are swallowed - a failing callback
194
+ * never blocks traffic. Useful for metrics, logging, or alerting.
195
+ *
196
+ * @param key - The circuit key that transitioned.
197
+ * @param from - The previous circuit state.
198
+ * @param to - The new circuit state.
199
+ */
200
+ onStateChange?: (key: string, from: CircuitState, to: CircuitState) => void | Promise<void>;
201
+ }
202
+ /**
203
+ * Protect upstream services by breaking the circuit on repeated failures.
204
+ *
205
+ * Implements the three-state circuit breaker pattern:
206
+ * - **Closed** - requests flow normally; failures are counted.
207
+ * - **Open** - requests are immediately rejected with 503; a `Retry-After` header is set.
208
+ * - **Half-open** - a limited number of probe requests are allowed through to test recovery.
209
+ *
210
+ * State transitions: `closed → open` when failures reach the threshold,
211
+ * `open → half-open` after the reset timeout, `half-open → closed` on
212
+ * probe success or `half-open → open` on probe failure.
213
+ *
214
+ * @param config - Failure threshold, reset timeout, and storage backend.
215
+ * @returns A {@link Policy} at priority 30.
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * // Open after 5 failures, retry after 30s
220
+ * circuitBreaker();
221
+ *
222
+ * // Tighter threshold with custom store
223
+ * circuitBreaker({
224
+ * failureThreshold: 3,
225
+ * resetTimeoutMs: 10_000,
226
+ * failureOn: [500, 502, 503],
227
+ * store: new InMemoryCircuitBreakerStore(),
228
+ * });
229
+ *
230
+ * // With state change notifications
231
+ * circuitBreaker({
232
+ * failureThreshold: 5,
233
+ * onStateChange: (key, from, to) => {
234
+ * console.log(`Circuit ${key}: ${from} -> ${to}`);
235
+ * },
236
+ * });
237
+ * ```
238
+ */
239
+ declare function circuitBreaker(config?: CircuitBreakerConfig): Policy;
240
+
241
+ /**
242
+ * Response caching policy with pluggable storage backends.
243
+ *
244
+ * @module cache
245
+ */
246
+
247
+ /** Pluggable cache storage backend */
248
+ interface CacheStore {
249
+ /** Retrieve a cached response by key. Returns null on miss. */
250
+ get(key: string): Promise<Response | null>;
251
+ /** Store a response under key with a TTL in seconds. */
252
+ put(key: string, response: Response, ttlSeconds: number): Promise<void>;
253
+ /** Delete a cached entry. Returns true if something was removed. */
254
+ delete(key: string): Promise<boolean>;
255
+ /** Optional cleanup - clear expired entries, release resources. */
256
+ destroy?(): void;
257
+ }
258
+ /** Options for the in-memory cache store. */
259
+ interface InMemoryCacheStoreOptions {
260
+ /** Maximum number of cached entries. When exceeded, the oldest entry is evicted (LRU). */
261
+ maxEntries?: number;
262
+ }
263
+ declare class InMemoryCacheStore implements CacheStore {
264
+ private entries;
265
+ private maxEntries;
266
+ constructor(options?: InMemoryCacheStoreOptions);
267
+ get(key: string): Promise<Response | null>;
268
+ put(key: string, response: Response, ttlSeconds: number): Promise<void>;
269
+ delete(key: string): Promise<boolean>;
270
+ /** Remove all entries (for testing) */
271
+ clear(): void;
272
+ /** Current number of entries (for testing/inspection) */
273
+ get size(): number;
274
+ /** Release all cached entries. */
275
+ destroy(): void;
276
+ }
277
+ interface CacheConfig extends PolicyConfig {
278
+ /** Cache TTL in seconds. Default: 300. */
279
+ ttlSeconds?: number;
280
+ /** HTTP methods to cache. Default: ["GET"]. Case-insensitive. */
281
+ methods?: string[];
282
+ /** Custom cache key builder. Supports async for body-based keys. Default: method + url (+ body hash for POST/PUT/PATCH). */
283
+ cacheKeyFn?: (c: Context) => string | Promise<string>;
284
+ /** Only cache responses with these status codes. When set, responses with other statuses are not cached (5xx is always excluded regardless). */
285
+ cacheableStatuses?: number[];
286
+ /** Vary cache key on these request headers. */
287
+ varyHeaders?: string[];
288
+ /** Storage backend. Default: InMemoryCacheStore. */
289
+ store?: CacheStore;
290
+ /** Respect upstream Cache-Control directives. Default: true. */
291
+ respectCacheControl?: boolean;
292
+ /** Response header name for cache status (HIT/MISS/BYPASS/SKIP). Default: `"x-cache"`. */
293
+ cacheStatusHeader?: string;
294
+ /** Cache-Control directives that trigger a bypass. Matched at the directive level, not substring. Default: `["no-store", "no-cache"]`. */
295
+ bypassDirectives?: string[];
296
+ }
297
+ /**
298
+ * Cache upstream responses to reduce latency and load.
299
+ *
300
+ * Sets a cache status header on **every** response:
301
+ * - `HIT` - served from cache
302
+ * - `MISS` - fetched from upstream, now cached
303
+ * - `BYPASS` - upstream Cache-Control directive prevented caching
304
+ * - `SKIP` - not eligible for caching (wrong method or server error status)
305
+ *
306
+ * Server error responses (5xx) are never cached. Store failures degrade
307
+ * gracefully via {@link safeCall} - a broken cache store never crashes the
308
+ * request.
309
+ *
310
+ * For methods with a request body (POST, PUT, PATCH), the default cache key
311
+ * includes a SHA-256 hash of the body to prevent key collisions across
312
+ * different payloads.
313
+ *
314
+ * @param config - Cache TTL, storage backend, and key strategy. All fields optional.
315
+ * @returns A {@link Policy} at priority 40.
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * // Simple 5-minute in-memory cache for GET requests
320
+ * cache({ ttlSeconds: 300 });
321
+ *
322
+ * // Cache with Vary on Accept-Language and custom store
323
+ * cache({
324
+ * ttlSeconds: 600,
325
+ * varyHeaders: ["accept-language"],
326
+ * store: new CacheApiCacheStore(caches.default),
327
+ * });
328
+ * ```
329
+ */
330
+ declare function cache(config?: CacheConfig): Policy;
331
+
332
+ interface RateLimitConfig extends PolicyConfig {
333
+ /** Maximum requests per window */
334
+ max: number;
335
+ /** Time window in seconds. Default: 60. */
336
+ windowSeconds?: number;
337
+ /** Key extractor - determines the rate limit bucket. Default: client IP. */
338
+ keyBy?: (c: Context) => string | Promise<string>;
339
+ /** Storage backend for counters */
340
+ store?: RateLimitStore;
341
+ /** Response status code when limited. Default: 429. */
342
+ statusCode?: number;
343
+ /** Custom response body when limited */
344
+ message?: string;
345
+ /** Ordered list of headers to inspect for the client IP (when `keyBy` is not set). Default: `["cf-connecting-ip", "x-forwarded-for"]`. */
346
+ ipHeaders?: string[];
347
+ }
348
+ /** Pluggable storage backend for rate limit counters */
349
+ interface RateLimitStore {
350
+ /** Increment the counter for a key, returning the new count and TTL */
351
+ increment(key: string, windowSeconds: number): Promise<{
352
+ count: number;
353
+ resetAt: number;
354
+ }>;
355
+ /** Optional: cleanup resources (like intervals) used by the store */
356
+ destroy?(): void;
357
+ }
358
+ /** Default in-memory rate limit store */
359
+ interface InMemoryRateLimitStoreOptions {
360
+ /** Maximum number of unique keys to prevent memory exhaustion. Default: 100000. */
361
+ maxKeys?: number;
362
+ /** Cleanup interval in ms for expired entries. Default: 60000. */
363
+ cleanupIntervalMs?: number;
364
+ }
365
+ /**
366
+ * Default in-memory rate limit store backed by a `Map`.
367
+ *
368
+ * The store is bounded by `maxKeys` (default 100,000) to prevent unbounded
369
+ * memory growth from unique rate-limit keys. When the store reaches capacity
370
+ * and no expired entries can be evicted, it **fails closed** - returning
371
+ * `MAX_SAFE_INTEGER` as the count to trigger rate limiting. This is an
372
+ * intentional security design: memory safety takes priority over availability.
373
+ *
374
+ * Note the distinction between store-level and policy-level failure modes:
375
+ * - **Store at capacity** (this class): fail-closed - reject the request
376
+ * - **Store throws/times out** (policy handler via `safeCall`): fail-open - allow the request
377
+ */
378
+ declare class InMemoryRateLimitStore implements RateLimitStore {
379
+ private counters;
380
+ private cleanupInterval;
381
+ /** Maximum number of unique keys to prevent memory exhaustion */
382
+ private maxKeys;
383
+ private cleanupIntervalMs;
384
+ constructor(options?: InMemoryRateLimitStoreOptions | number);
385
+ /** Start the periodic cleanup interval on first use (Workers-safe). */
386
+ private ensureCleanupInterval;
387
+ /**
388
+ * Increment the counter for a key within the given time window.
389
+ *
390
+ * When the store reaches `maxKeys` capacity and no expired entries can
391
+ * be evicted, returns `{ count: MAX_SAFE_INTEGER, resetAt }` to trigger
392
+ * rate limiting (fail-closed). This prevents unbounded memory growth at
393
+ * the cost of potentially rejecting legitimate requests - an intentional
394
+ * security trade-off where memory safety takes priority over availability.
395
+ */
396
+ increment(key: string, windowSeconds: number): Promise<{
397
+ count: number;
398
+ resetAt: number;
399
+ }>;
400
+ private cleanup;
401
+ /** Stop the cleanup interval (for testing) */
402
+ destroy(): void;
403
+ /** Reset all counters (for testing) */
404
+ reset(): void;
405
+ }
406
+ /**
407
+ * Rate limit requests with pluggable storage backends.
408
+ *
409
+ * Defaults to client IP extraction via `CF-Connecting-IP` or `X-Forwarded-For`.
410
+ * Sets standard `X-RateLimit-*` response headers on every request and
411
+ * throws a 429 when the limit is exceeded.
412
+ *
413
+ * @param config - Rate limit settings. `max` is required; other fields have sensible defaults.
414
+ * @returns A {@link Policy} at priority 20 (runs after auth).
415
+ *
416
+ * @example
417
+ * ```ts
418
+ * // 100 requests per minute per IP (in-memory)
419
+ * rateLimit({ max: 100 });
420
+ *
421
+ * // Custom key + Cloudflare KV store
422
+ * rateLimit({
423
+ * max: 50,
424
+ * windowSeconds: 300,
425
+ * keyBy: (c) => c.req.header("x-user-id") ?? "anonymous",
426
+ * store: new KVRateLimitStore(env.RATE_LIMIT_KV),
427
+ * });
428
+ * ```
429
+ */
430
+ declare const rateLimit: (config: RateLimitConfig) => Policy;
431
+
432
+ /** Bag of optional store implementations and runtime capabilities for a given runtime. */
433
+ interface GatewayAdapter {
434
+ rateLimitStore?: RateLimitStore;
435
+ circuitBreakerStore?: CircuitBreakerStore;
436
+ cacheStore?: CacheStore;
437
+ /** Schedule background work that outlives the response (e.g. Cloudflare `executionCtx.waitUntil`). */
438
+ waitUntil?: (promise: Promise<unknown>) => void;
439
+ /** Dispatch a request to a named service binding or sidecar. */
440
+ dispatchBinding?: (service: string, request: Request) => Promise<Response>;
441
+ }
442
+
443
+ /**
444
+ * Protocol-agnostic types for multi-runtime policy evaluation.
445
+ *
446
+ * These types define the contract between policy logic and protocol runtimes.
447
+ * The HTTP runtime (Hono-based) uses {@link Policy.handler} directly.
448
+ * Non-HTTP runtimes (ext_proc, WebSocket) use {@link Policy.evaluate}.
449
+ *
450
+ * **Architecture:**
451
+ * ```
452
+ * ┌─────────────────────────────┐
453
+ * │ Policy Definitions │
454
+ * │ name, priority, evaluate() │
455
+ * │ (protocol-agnostic) │
456
+ * └──────────┬──────────────────┘
457
+ * │
458
+ * ┌────────────────┼────────────────┐
459
+ * │ │ │
460
+ * ┌─────────▼──────┐ ┌──────▼──────┐ ┌──────▼───────┐
461
+ * │ HTTP Runtime │ │ ext_proc │ │ WebSocket │
462
+ * │ (Hono-based) │ │ (gRPC) │ │ Runtime │
463
+ * │ createGateway() │ │ │ │ │
464
+ * └────────────────┘ └─────────────┘ └──────────────┘
465
+ * ```
466
+ *
467
+ * Hono powers the HTTP runtime. Other runtimes (ext_proc via gRPC,
468
+ * WebSocket) are peer implementations - same policy definitions,
469
+ * different wire protocols.
470
+ *
471
+ * @module protocol
472
+ */
473
+
474
+ /**
475
+ * Lifecycle phases a policy can participate in.
476
+ *
477
+ * Maps to:
478
+ * - **HTTP**: `request-headers` → `request-body` → `response-headers` → `response-body`
479
+ * (trailers are N/A for HTTP/1.1; available in HTTP/2)
480
+ * - **ext_proc**: All 6 phases - Envoy sends each as a `ProcessingRequest`
481
+ * - **WebSocket**: `request-headers` (upgrade) → `request-body` (per-message)
482
+ */
483
+ type ProcessingPhase = "request-headers" | "request-body" | "request-trailers" | "response-headers" | "response-body" | "response-trailers";
484
+ /** Identifies the protocol runtime invoking a policy. */
485
+ type ProtocolType = "http" | "grpc" | "websocket";
486
+ /**
487
+ * Protocol-agnostic view of what's being processed.
488
+ *
489
+ * Constructed by each runtime from its native message type:
490
+ * - HTTP runtime builds it from Hono's `Context`
491
+ * - ext_proc runtime builds it from gRPC `ProcessingRequest`
492
+ * - WebSocket runtime builds it from the upgrade request or message frame
493
+ */
494
+ interface PolicyInput {
495
+ /** Current processing phase. */
496
+ phase: ProcessingPhase;
497
+ /**
498
+ * Request method or action.
499
+ *
500
+ * - HTTP: `"GET"`, `"POST"`, etc.
501
+ * - gRPC: Full method name, e.g. `"users.UserService/GetUser"`
502
+ */
503
+ method: string;
504
+ /**
505
+ * Request path or resource identifier.
506
+ *
507
+ * - HTTP: URL path, e.g. `"/users/123"`
508
+ * - gRPC: Service path, e.g. `"/users.UserService/GetUser"`
509
+ */
510
+ path: string;
511
+ /**
512
+ * Headers (HTTP) or metadata (gRPC).
513
+ *
514
+ * Treat as read-only - express modifications via
515
+ * {@link PolicyResult} mutations, not by mutating this object.
516
+ */
517
+ headers: Headers;
518
+ /**
519
+ * Client IP address, extracted by the runtime from protocol-specific
520
+ * sources (e.g. `CF-Connecting-IP`, `X-Forwarded-For`, gRPC peer address).
521
+ */
522
+ clientIp?: string;
523
+ /**
524
+ * Message body, present only during body phases.
525
+ *
526
+ * May be the full buffered body or a streaming chunk, depending on
527
+ * the runtime's buffering mode.
528
+ */
529
+ body?: ArrayBuffer | string;
530
+ /**
531
+ * Trailers, present only during trailer phases.
532
+ *
533
+ * Relevant for gRPC (which uses trailers for status codes and error
534
+ * details) and HTTP/2.
535
+ */
536
+ trailers?: Headers;
537
+ /**
538
+ * Cross-policy attribute bag.
539
+ *
540
+ * Policies read attributes set by upstream policies and set
541
+ * attributes for downstream policies via {@link AttributeMutation}.
542
+ * Runtime-populated attributes use the `runtime.*` namespace
543
+ * (e.g. `runtime.matched_route`, `runtime.upstream_name`).
544
+ */
545
+ attributes: Map<string, unknown>;
546
+ /** The protocol runtime that constructed this input. */
547
+ protocol: ProtocolType;
548
+ }
549
+ /**
550
+ * The outcome of a policy evaluation. Discriminated on `action`.
551
+ *
552
+ * - `"continue"` - Allow processing to continue, optionally with mutations.
553
+ * - `"reject"` - Reject with a structured error response.
554
+ * - `"immediate-response"` - Short-circuit with a complete non-error response.
555
+ */
556
+ type PolicyResult = PolicyContinue | PolicyReject | PolicyImmediateResponse;
557
+ /**
558
+ * Allow processing to continue, optionally with mutations.
559
+ *
560
+ * Equivalent to `await next()` in HTTP middleware, or ext_proc
561
+ * `CommonResponse` with header/body mutations.
562
+ */
563
+ interface PolicyContinue {
564
+ action: "continue";
565
+ /** Mutations to apply before continuing to the next policy or upstream. */
566
+ mutations?: Mutation[];
567
+ }
568
+ /**
569
+ * Reject the request with a structured error.
570
+ *
571
+ * Equivalent to `throw new GatewayError(...)` in HTTP middleware, or
572
+ * ext_proc `ImmediateResponse` with an error status code.
573
+ */
574
+ interface PolicyReject {
575
+ action: "reject";
576
+ /** HTTP status code (or gRPC status equivalent). */
577
+ status: number;
578
+ /** Machine-readable error code (e.g. `"rate_limited"`, `"unauthorized"`). */
579
+ code: string;
580
+ /** Human-readable error message. */
581
+ message: string;
582
+ /** Additional headers to include on the error response. */
583
+ headers?: Record<string, string>;
584
+ }
585
+ /**
586
+ * Short-circuit with a complete non-error response.
587
+ *
588
+ * Used for cache hits, mock responses, redirects - cases where the
589
+ * policy provides the full response and upstream should not be called.
590
+ *
591
+ * Equivalent to returning a `Response` without calling `next()` in
592
+ * HTTP middleware, or ext_proc `ImmediateResponse` with a success status.
593
+ */
594
+ interface PolicyImmediateResponse {
595
+ action: "immediate-response";
596
+ /** HTTP status code for the response. */
597
+ status: number;
598
+ /** Response headers. */
599
+ headers?: Record<string, string>;
600
+ /** Response body. */
601
+ body?: string | ArrayBuffer;
602
+ }
603
+ /**
604
+ * A discrete modification to apply to the request or response.
605
+ * Discriminated on `type`.
606
+ *
607
+ * Designed to map cleanly to ext_proc `HeaderMutation`, `BodyMutation`,
608
+ * and Envoy dynamic metadata.
609
+ */
610
+ type Mutation = HeaderMutation | BodyMutation | StatusMutation | AttributeMutation;
611
+ /** Add, remove, or append a header value. */
612
+ interface HeaderMutation {
613
+ type: "header";
614
+ /** `"set"` replaces, `"remove"` deletes, `"append"` adds without replacing. */
615
+ op: "set" | "remove" | "append";
616
+ /** Header name (case-insensitive). */
617
+ name: string;
618
+ /** Header value. Required for `"set"` and `"append"`, ignored for `"remove"`. */
619
+ value?: string;
620
+ }
621
+ /** Replace or clear the message body. */
622
+ interface BodyMutation {
623
+ type: "body";
624
+ /** `"replace"` substitutes the body, `"clear"` removes it entirely. */
625
+ op: "replace" | "clear";
626
+ /** New body content. Required for `"replace"`, ignored for `"clear"`. */
627
+ content?: string | ArrayBuffer;
628
+ }
629
+ /**
630
+ * Modify the response status code.
631
+ *
632
+ * Only meaningful during response processing phases. Ignored during
633
+ * request phases.
634
+ */
635
+ interface StatusMutation {
636
+ type: "status";
637
+ /** New HTTP status code. */
638
+ code: number;
639
+ }
640
+ /**
641
+ * Set a cross-policy attribute.
642
+ *
643
+ * Downstream policies see this value in {@link PolicyInput.attributes}.
644
+ * In ext_proc, this maps to Envoy dynamic metadata.
645
+ */
646
+ interface AttributeMutation {
647
+ type: "attribute";
648
+ /** Attribute key. Use namespaced keys (e.g. `"auth.user_id"`) to avoid collisions. */
649
+ key: string;
650
+ /** Attribute value. */
651
+ value: unknown;
652
+ }
653
+ /**
654
+ * Runtime-facing evaluation context provided to policy evaluators.
655
+ *
656
+ * This is the base context without typed config - runtimes construct
657
+ * this from their native request representation. The policy SDK
658
+ * ({@link definePolicy}) extends this with a typed `config` field
659
+ * via `PolicyEvalHandlerContext`.
660
+ */
661
+ interface PolicyEvalContext {
662
+ /** Debug logger pre-namespaced to `stoma:policy:{name}`. Always callable. */
663
+ debug: DebugLogger;
664
+ /** Trace reporter - always callable, no-op when tracing is not active. */
665
+ trace: TraceReporter;
666
+ /** Unique request ID for correlation. */
667
+ requestId: string;
668
+ /** W3C trace ID (32-hex). */
669
+ traceId: string;
670
+ /** Runtime adapter (stores, waitUntil, etc.). */
671
+ adapter?: GatewayAdapter;
672
+ }
673
+ /**
674
+ * Protocol-agnostic policy evaluation entry point.
675
+ *
676
+ * Implement this on a {@link Policy} to make it work across all runtimes
677
+ * (HTTP, ext_proc, WebSocket). The HTTP runtime uses {@link Policy.handler}
678
+ * directly - `evaluate` is consumed by non-HTTP runtimes.
679
+ *
680
+ * Runtimes call `onRequest` for request-phase processing and `onResponse`
681
+ * for response-phase processing. A policy can implement one or both.
682
+ *
683
+ * @example
684
+ * ```ts
685
+ * // Protocol-agnostic JWT verification
686
+ * const evaluator: PolicyEvaluator = {
687
+ * onRequest: async (input, ctx) => {
688
+ * const auth = input.headers.get("authorization");
689
+ * if (!auth) return { action: "reject", status: 401, code: "unauthorized", message: "Missing token" };
690
+ * // ... verify token ...
691
+ * return { action: "continue", mutations: [
692
+ * { type: "header", op: "set", name: "x-user-id", value: claims.sub },
693
+ * ]};
694
+ * },
695
+ * };
696
+ * ```
697
+ */
698
+ /**
699
+ * Current `evaluate` coverage across policy categories:
700
+ * - auth: 6/9 (jwt-auth, api-key-auth, basic-auth, oauth2, rbac, jws)
701
+ * - traffic: 5/13 (rate-limit, ip-filter, cache, geo-ip-filter, ssl-enforce)
702
+ * - transform: 5/7 (cors, assign-attributes, assign-content, request-transform, response-transform)
703
+ * - observability: 0/4
704
+ * - resilience: 0/4
705
+ *
706
+ * Total: 16/38 policies have evaluate support. The remaining policies
707
+ * will gain evaluate implementations as non-HTTP runtimes (ext_proc, WebSocket)
708
+ * are built out. See PLAN.md Phase 5 for the ext_proc roadmap.
709
+ */
710
+ interface PolicyEvaluator {
711
+ /**
712
+ * Evaluate during request processing phases.
713
+ *
714
+ * Called for: `request-headers`, `request-body`, `request-trailers`.
715
+ */
716
+ onRequest?: (input: PolicyInput, ctx: PolicyEvalContext) => Promise<PolicyResult>;
717
+ /**
718
+ * Evaluate during response processing phases.
719
+ *
720
+ * Called for: `response-headers`, `response-body`, `response-trailers`.
721
+ */
722
+ onResponse?: (input: PolicyInput, ctx: PolicyEvalContext) => Promise<PolicyResult>;
723
+ }
724
+
725
+ export { type AttributeMutation as A, type BodyMutation as B, type CacheStore as C, type GatewayAdapter as G, type HeaderMutation as H, InMemoryCacheStore as I, type Mutation as M, type Policy as P, type RateLimitStore as R, type StatusMutation as S, type CircuitBreakerSnapshot as a, type CircuitBreakerStore as b, type CircuitState as c, type InMemoryCacheStoreOptions as d, InMemoryCircuitBreakerStore as e, type InMemoryRateLimitStoreOptions as f, type PolicyConfig as g, type PolicyContext as h, type PolicyContinue as i, type PolicyEvalContext as j, type PolicyEvaluator as k, type PolicyImmediateResponse as l, type PolicyInput as m, type PolicyReject as n, type PolicyResult as o, type ProcessingPhase as p, type ProtocolType as q, cache as r, circuitBreaker as s, rateLimit as t, type CacheConfig as u, type CircuitBreakerConfig as v, InMemoryRateLimitStore as w, type RateLimitConfig as x };