@beignet/core 0.0.3 → 0.0.5

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 (360) hide show
  1. package/CHANGELOG.md +159 -0
  2. package/README.md +792 -50
  3. package/dist/application/index.d.ts +28 -2
  4. package/dist/application/index.d.ts.map +1 -1
  5. package/dist/application/index.js +140 -12
  6. package/dist/application/index.js.map +1 -1
  7. package/dist/client/client.d.ts +2 -2
  8. package/dist/client/client.d.ts.map +1 -1
  9. package/dist/client/client.js +136 -48
  10. package/dist/client/client.js.map +1 -1
  11. package/dist/client/error-messages.d.ts +14 -0
  12. package/dist/client/error-messages.d.ts.map +1 -0
  13. package/dist/client/error-messages.js +23 -0
  14. package/dist/client/error-messages.js.map +1 -0
  15. package/dist/client/index.d.ts +8 -4
  16. package/dist/client/index.d.ts.map +1 -1
  17. package/dist/client/index.js +6 -2
  18. package/dist/client/index.js.map +1 -1
  19. package/dist/client/types.d.ts +35 -5
  20. package/dist/client/types.d.ts.map +1 -1
  21. package/dist/client-only.d.ts +8 -0
  22. package/dist/client-only.d.ts.map +1 -0
  23. package/dist/client-only.js +8 -0
  24. package/dist/client-only.js.map +1 -0
  25. package/dist/config/index.d.ts +5 -5
  26. package/dist/config/index.d.ts.map +1 -1
  27. package/dist/config/index.js +2 -2
  28. package/dist/config/index.js.map +1 -1
  29. package/dist/contracts/catalog-errors.d.ts +27 -0
  30. package/dist/contracts/catalog-errors.d.ts.map +1 -0
  31. package/dist/contracts/catalog-errors.js +69 -0
  32. package/dist/contracts/catalog-errors.js.map +1 -0
  33. package/dist/contracts/contract-builder.d.ts +15 -12
  34. package/dist/contracts/contract-builder.d.ts.map +1 -1
  35. package/dist/contracts/contract-builder.js +15 -41
  36. package/dist/contracts/contract-builder.js.map +1 -1
  37. package/dist/contracts/contract-group.d.ts +11 -8
  38. package/dist/contracts/contract-group.d.ts.map +1 -1
  39. package/dist/contracts/contract-group.js +13 -40
  40. package/dist/contracts/contract-group.js.map +1 -1
  41. package/dist/contracts/contract-like.d.ts +1 -1
  42. package/dist/contracts/contract-like.d.ts.map +1 -1
  43. package/dist/contracts/index.d.ts +13 -9
  44. package/dist/contracts/index.d.ts.map +1 -1
  45. package/dist/contracts/index.js +9 -5
  46. package/dist/contracts/index.js.map +1 -1
  47. package/dist/contracts/openapi-meta.d.ts +48 -0
  48. package/dist/contracts/openapi-meta.d.ts.map +1 -1
  49. package/dist/contracts/openapi-meta.js +3 -0
  50. package/dist/contracts/openapi-meta.js.map +1 -1
  51. package/dist/contracts/path-template.d.ts +1 -1
  52. package/dist/contracts/path-template.js +2 -2
  53. package/dist/contracts/path-template.js.map +1 -1
  54. package/dist/contracts/schema-shape.d.ts +37 -0
  55. package/dist/contracts/schema-shape.d.ts.map +1 -0
  56. package/dist/contracts/schema-shape.js +61 -0
  57. package/dist/contracts/schema-shape.js.map +1 -0
  58. package/dist/contracts/success-status.d.ts +32 -0
  59. package/dist/contracts/success-status.d.ts.map +1 -0
  60. package/dist/contracts/success-status.js +18 -0
  61. package/dist/contracts/success-status.js.map +1 -0
  62. package/dist/contracts/types.d.ts +25 -5
  63. package/dist/contracts/types.d.ts.map +1 -1
  64. package/dist/contracts/types.js.map +1 -1
  65. package/dist/contracts/utils.d.ts +1 -1
  66. package/dist/contracts/utils.d.ts.map +1 -1
  67. package/dist/contracts/utils.js +1 -1
  68. package/dist/contracts/utils.js.map +1 -1
  69. package/dist/domain/events.d.ts +1 -1
  70. package/dist/domain/events.d.ts.map +1 -1
  71. package/dist/domain/events.js +1 -1
  72. package/dist/domain/events.js.map +1 -1
  73. package/dist/domain/index.d.ts +3 -3
  74. package/dist/domain/index.d.ts.map +1 -1
  75. package/dist/domain/index.js +3 -3
  76. package/dist/domain/index.js.map +1 -1
  77. package/dist/errors/catalog.d.ts +9 -1
  78. package/dist/errors/catalog.d.ts.map +1 -1
  79. package/dist/errors/catalog.js +7 -1
  80. package/dist/errors/catalog.js.map +1 -1
  81. package/dist/errors/http.d.ts +10 -0
  82. package/dist/errors/http.d.ts.map +1 -1
  83. package/dist/errors/http.js +11 -1
  84. package/dist/errors/http.js.map +1 -1
  85. package/dist/errors/index.d.ts +4 -4
  86. package/dist/errors/index.d.ts.map +1 -1
  87. package/dist/errors/index.js +4 -4
  88. package/dist/errors/index.js.map +1 -1
  89. package/dist/errors/response.d.ts +4 -1
  90. package/dist/errors/response.d.ts.map +1 -1
  91. package/dist/errors/response.js.map +1 -1
  92. package/dist/events/index.d.ts +10 -12
  93. package/dist/events/index.d.ts.map +1 -1
  94. package/dist/events/index.js +10 -10
  95. package/dist/events/index.js.map +1 -1
  96. package/dist/idempotency/index.d.ts +5 -3
  97. package/dist/idempotency/index.d.ts.map +1 -1
  98. package/dist/idempotency/index.js.map +1 -1
  99. package/dist/jobs/index.d.ts +12 -14
  100. package/dist/jobs/index.d.ts.map +1 -1
  101. package/dist/jobs/index.js +13 -13
  102. package/dist/jobs/index.js.map +1 -1
  103. package/dist/notifications/index.d.ts +14 -16
  104. package/dist/notifications/index.d.ts.map +1 -1
  105. package/dist/notifications/index.js +14 -14
  106. package/dist/notifications/index.js.map +1 -1
  107. package/dist/openapi/index.d.ts +8 -3
  108. package/dist/openapi/index.d.ts.map +1 -1
  109. package/dist/openapi/index.js +41 -29
  110. package/dist/openapi/index.js.map +1 -1
  111. package/dist/openapi/schema-introspector.d.ts +37 -0
  112. package/dist/openapi/schema-introspector.d.ts.map +1 -1
  113. package/dist/openapi/schema-introspector.js +23 -17
  114. package/dist/openapi/schema-introspector.js.map +1 -1
  115. package/dist/outbox/index.d.ts +15 -6
  116. package/dist/outbox/index.d.ts.map +1 -1
  117. package/dist/outbox/index.js +60 -16
  118. package/dist/outbox/index.js.map +1 -1
  119. package/dist/ports/audit.d.ts +56 -10
  120. package/dist/ports/audit.d.ts.map +1 -1
  121. package/dist/ports/audit.js +71 -3
  122. package/dist/ports/audit.js.map +1 -1
  123. package/dist/ports/auth.d.ts +92 -0
  124. package/dist/ports/auth.d.ts.map +1 -1
  125. package/dist/ports/auth.js +92 -0
  126. package/dist/ports/auth.js.map +1 -1
  127. package/dist/ports/events.d.ts +2 -2
  128. package/dist/ports/events.d.ts.map +1 -1
  129. package/dist/ports/index.d.ts +62 -33
  130. package/dist/ports/index.d.ts.map +1 -1
  131. package/dist/ports/index.js +28 -34
  132. package/dist/ports/index.js.map +1 -1
  133. package/dist/ports/policy.d.ts +32 -3
  134. package/dist/ports/policy.d.ts.map +1 -1
  135. package/dist/ports/policy.js +13 -2
  136. package/dist/ports/policy.js.map +1 -1
  137. package/dist/ports/testing.d.ts +1030 -2
  138. package/dist/ports/testing.d.ts.map +1 -1
  139. package/dist/ports/testing.js +1031 -1
  140. package/dist/ports/testing.js.map +1 -1
  141. package/dist/ports/unbound.d.ts +21 -0
  142. package/dist/ports/unbound.d.ts.map +1 -0
  143. package/dist/ports/unbound.js +57 -0
  144. package/dist/ports/unbound.js.map +1 -0
  145. package/dist/ports/unit-of-work.d.ts +1 -1
  146. package/dist/ports/unit-of-work.d.ts.map +1 -1
  147. package/dist/ports/unit-of-work.js +1 -1
  148. package/dist/ports/unit-of-work.js.map +1 -1
  149. package/dist/providers/index.d.ts +3 -2
  150. package/dist/providers/index.d.ts.map +1 -1
  151. package/dist/providers/index.js +3 -2
  152. package/dist/providers/index.js.map +1 -1
  153. package/dist/providers/instrumentation.d.ts +45 -4
  154. package/dist/providers/instrumentation.d.ts.map +1 -1
  155. package/dist/providers/instrumentation.js +25 -6
  156. package/dist/providers/instrumentation.js.map +1 -1
  157. package/dist/providers/metadata.d.ts +39 -0
  158. package/dist/providers/metadata.d.ts.map +1 -0
  159. package/dist/providers/metadata.js +169 -0
  160. package/dist/providers/metadata.js.map +1 -0
  161. package/dist/providers/provider.d.ts +114 -9
  162. package/dist/providers/provider.d.ts.map +1 -1
  163. package/dist/providers/provider.js +3 -20
  164. package/dist/providers/provider.js.map +1 -1
  165. package/dist/schedules/index.d.ts +94 -13
  166. package/dist/schedules/index.d.ts.map +1 -1
  167. package/dist/schedules/index.js +66 -12
  168. package/dist/schedules/index.js.map +1 -1
  169. package/dist/server/audit-context.d.ts +29 -0
  170. package/dist/server/audit-context.d.ts.map +1 -0
  171. package/dist/server/audit-context.js +44 -0
  172. package/dist/server/audit-context.js.map +1 -0
  173. package/dist/server/context.d.ts +141 -0
  174. package/dist/server/context.d.ts.map +1 -0
  175. package/dist/server/context.js +39 -0
  176. package/dist/server/context.js.map +1 -0
  177. package/dist/server/contract-like.d.ts +1 -1
  178. package/dist/server/contract-like.d.ts.map +1 -1
  179. package/dist/server/contract-like.js +1 -1
  180. package/dist/server/contract-like.js.map +1 -1
  181. package/dist/server/health.d.ts +2 -2
  182. package/dist/server/health.d.ts.map +1 -1
  183. package/dist/server/hooks/auth.d.ts +49 -10
  184. package/dist/server/hooks/auth.d.ts.map +1 -1
  185. package/dist/server/hooks/auth.js +77 -37
  186. package/dist/server/hooks/auth.js.map +1 -1
  187. package/dist/server/hooks/cors.d.ts +1 -1
  188. package/dist/server/hooks/cors.d.ts.map +1 -1
  189. package/dist/server/hooks/errors.d.ts +2 -2
  190. package/dist/server/hooks/errors.d.ts.map +1 -1
  191. package/dist/server/hooks/errors.js +2 -2
  192. package/dist/server/hooks/errors.js.map +1 -1
  193. package/dist/server/hooks/idempotency.d.ts +78 -0
  194. package/dist/server/hooks/idempotency.d.ts.map +1 -0
  195. package/dist/server/hooks/idempotency.js +154 -0
  196. package/dist/server/hooks/idempotency.js.map +1 -0
  197. package/dist/server/hooks/index.d.ts +8 -7
  198. package/dist/server/hooks/index.d.ts.map +1 -1
  199. package/dist/server/hooks/index.js +6 -5
  200. package/dist/server/hooks/index.js.map +1 -1
  201. package/dist/server/hooks/logging.d.ts +2 -2
  202. package/dist/server/hooks/logging.d.ts.map +1 -1
  203. package/dist/server/hooks/logging.js +1 -1
  204. package/dist/server/hooks/logging.js.map +1 -1
  205. package/dist/server/hooks/rate-limit.d.ts +25 -7
  206. package/dist/server/hooks/rate-limit.d.ts.map +1 -1
  207. package/dist/server/hooks/rate-limit.js +47 -12
  208. package/dist/server/hooks/rate-limit.js.map +1 -1
  209. package/dist/server/hooks.d.ts +1 -1
  210. package/dist/server/hooks.d.ts.map +1 -1
  211. package/dist/server/hooks.js +1 -1
  212. package/dist/server/hooks.js.map +1 -1
  213. package/dist/server/http.d.ts +61 -35
  214. package/dist/server/http.d.ts.map +1 -1
  215. package/dist/server/http.js +1 -20
  216. package/dist/server/http.js.map +1 -1
  217. package/dist/server/index.d.ts +36 -12
  218. package/dist/server/index.d.ts.map +1 -1
  219. package/dist/server/index.js +24 -8
  220. package/dist/server/index.js.map +1 -1
  221. package/dist/server/instrumentation.d.ts +108 -0
  222. package/dist/server/instrumentation.d.ts.map +1 -0
  223. package/dist/server/instrumentation.js +297 -0
  224. package/dist/server/instrumentation.js.map +1 -0
  225. package/dist/server/openapi.d.ts +3 -3
  226. package/dist/server/openapi.d.ts.map +1 -1
  227. package/dist/server/openapi.js +1 -1
  228. package/dist/server/openapi.js.map +1 -1
  229. package/dist/server/providers/index.d.ts +3 -3
  230. package/dist/server/providers/index.d.ts.map +1 -1
  231. package/dist/server/providers/index.js +3 -3
  232. package/dist/server/providers/index.js.map +1 -1
  233. package/dist/server/providers/loadProviderConfig.d.ts +2 -2
  234. package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
  235. package/dist/server/providers/loadProviderConfig.js +2 -2
  236. package/dist/server/providers/loadProviderConfig.js.map +1 -1
  237. package/dist/server/request-context.d.ts +67 -0
  238. package/dist/server/request-context.d.ts.map +1 -0
  239. package/dist/server/request-context.js +79 -0
  240. package/dist/server/request-context.js.map +1 -0
  241. package/dist/server/server-context.d.ts +38 -0
  242. package/dist/server/server-context.d.ts.map +1 -0
  243. package/dist/server/server-context.js +38 -0
  244. package/dist/server/server-context.js.map +1 -0
  245. package/dist/server/server.d.ts +105 -33
  246. package/dist/server/server.d.ts.map +1 -1
  247. package/dist/server/server.js +434 -118
  248. package/dist/server/server.js.map +1 -1
  249. package/dist/server/types.d.ts +2 -2
  250. package/dist/server/types.d.ts.map +1 -1
  251. package/dist/server/types.js +2 -2
  252. package/dist/server/types.js.map +1 -1
  253. package/dist/server/use-case-route.d.ts +263 -0
  254. package/dist/server/use-case-route.d.ts.map +1 -0
  255. package/dist/server/use-case-route.js +77 -0
  256. package/dist/server/use-case-route.js.map +1 -0
  257. package/dist/server-only.d.ts +8 -0
  258. package/dist/server-only.d.ts.map +1 -0
  259. package/dist/server-only.js +8 -0
  260. package/dist/server-only.js.map +1 -0
  261. package/dist/tasks/index.d.ts +139 -0
  262. package/dist/tasks/index.d.ts.map +1 -0
  263. package/dist/tasks/index.js +98 -0
  264. package/dist/tasks/index.js.map +1 -0
  265. package/dist/testing/index.d.ts +607 -5
  266. package/dist/testing/index.d.ts.map +1 -1
  267. package/dist/testing/index.js +426 -4
  268. package/dist/testing/index.js.map +1 -1
  269. package/dist/tracing/index.d.ts +89 -0
  270. package/dist/tracing/index.d.ts.map +1 -0
  271. package/dist/tracing/index.js +101 -0
  272. package/dist/tracing/index.js.map +1 -0
  273. package/dist/uploads/client.d.ts +1 -1
  274. package/dist/uploads/client.d.ts.map +1 -1
  275. package/dist/uploads/index.d.ts +2 -2
  276. package/dist/uploads/index.d.ts.map +1 -1
  277. package/dist/uploads/index.js +1 -1
  278. package/dist/uploads/index.js.map +1 -1
  279. package/package.json +24 -2
  280. package/src/application/index.ts +193 -10
  281. package/src/client/client.ts +148 -150
  282. package/src/client/error-messages.ts +35 -0
  283. package/src/client/index.ts +12 -4
  284. package/src/client/types.ts +44 -5
  285. package/src/client-only.ts +7 -0
  286. package/src/config/index.ts +6 -6
  287. package/src/contracts/catalog-errors.ts +115 -0
  288. package/src/contracts/contract-builder.ts +39 -76
  289. package/src/contracts/contract-group.ts +33 -68
  290. package/src/contracts/contract-like.ts +1 -1
  291. package/src/contracts/index.ts +24 -11
  292. package/src/contracts/openapi-meta.ts +55 -0
  293. package/src/contracts/path-template.ts +2 -2
  294. package/src/contracts/schema-shape.ts +75 -0
  295. package/src/contracts/success-status.ts +68 -0
  296. package/src/contracts/types.ts +32 -5
  297. package/src/contracts/utils.ts +5 -2
  298. package/src/domain/events.ts +6 -2
  299. package/src/domain/index.ts +3 -3
  300. package/src/errors/catalog.ts +9 -1
  301. package/src/errors/http.ts +11 -1
  302. package/src/errors/index.ts +4 -4
  303. package/src/errors/response.ts +4 -1
  304. package/src/events/index.ts +12 -26
  305. package/src/idempotency/index.ts +5 -3
  306. package/src/jobs/index.ts +14 -24
  307. package/src/notifications/index.ts +17 -27
  308. package/src/openapi/index.ts +73 -38
  309. package/src/openapi/schema-introspector.ts +68 -17
  310. package/src/outbox/index.ts +84 -19
  311. package/src/ports/audit.ts +120 -11
  312. package/src/ports/auth.ts +132 -0
  313. package/src/ports/events.ts +2 -2
  314. package/src/ports/index.ts +104 -35
  315. package/src/ports/policy.ts +50 -3
  316. package/src/ports/testing.ts +2220 -33
  317. package/src/ports/unbound.ts +64 -0
  318. package/src/ports/unit-of-work.ts +6 -2
  319. package/src/providers/index.ts +16 -3
  320. package/src/providers/instrumentation.ts +86 -7
  321. package/src/providers/metadata.ts +234 -0
  322. package/src/providers/provider.ts +168 -9
  323. package/src/schedules/index.ts +173 -23
  324. package/src/server/audit-context.ts +45 -0
  325. package/src/server/context.ts +224 -0
  326. package/src/server/contract-like.ts +1 -1
  327. package/src/server/health.ts +2 -2
  328. package/src/server/hooks/auth.ts +141 -51
  329. package/src/server/hooks/cors.ts +1 -1
  330. package/src/server/hooks/errors.ts +7 -4
  331. package/src/server/hooks/idempotency.ts +263 -0
  332. package/src/server/hooks/index.ts +14 -7
  333. package/src/server/hooks/logging.ts +3 -3
  334. package/src/server/hooks/rate-limit.ts +85 -17
  335. package/src/server/hooks.ts +1 -1
  336. package/src/server/http.ts +78 -51
  337. package/src/server/index.ts +62 -12
  338. package/src/server/instrumentation.ts +470 -0
  339. package/src/server/openapi.ts +4 -4
  340. package/src/server/providers/index.ts +6 -3
  341. package/src/server/providers/loadProviderConfig.ts +4 -4
  342. package/src/server/request-context.ts +116 -0
  343. package/src/server/server-context.ts +44 -0
  344. package/src/server/server.ts +886 -238
  345. package/src/server/types.ts +2 -2
  346. package/src/server/use-case-route.ts +430 -0
  347. package/src/server-only.ts +7 -0
  348. package/src/tasks/index.ts +275 -0
  349. package/src/testing/index.ts +1142 -6
  350. package/src/tracing/index.ts +176 -0
  351. package/src/uploads/client.ts +1 -1
  352. package/src/uploads/index.ts +7 -3
  353. package/dist/ports/mailer.d.ts +0 -6
  354. package/dist/ports/mailer.d.ts.map +0 -1
  355. package/dist/ports/mailer.js +0 -2
  356. package/dist/ports/mailer.js.map +0 -1
  357. package/dist/ports/schedules.d.ts +0 -9
  358. package/dist/ports/schedules.d.ts.map +0 -1
  359. package/dist/ports/schedules.js +0 -2
  360. package/dist/ports/schedules.js.map +0 -1
@@ -1,50 +1,90 @@
1
- import { AuthUnauthorizedError } from "../../ports";
2
- function toAuthArgs(args) {
3
- return {
4
- req: args.req,
5
- ctx: args.ctx,
6
- contract: args.contract,
7
- path: args.path,
8
- query: args.query,
9
- headers: args.headers,
10
- body: args.body,
11
- };
1
+ import { AuthUnauthorizedError } from "../../ports/index.js";
2
+ function rawRequestHeaders(req) {
3
+ const record = {};
4
+ req.headers.forEach((value, key) => {
5
+ record[key.toLowerCase()] = value;
6
+ });
7
+ return record;
8
+ }
9
+ async function parseAuthHeaders(schema, req) {
10
+ const raw = rawRequestHeaders(req);
11
+ if (!schema) {
12
+ return { ok: true, headers: raw };
13
+ }
14
+ const result = await schema["~standard"].validate(raw);
15
+ if (result.issues) {
16
+ return { ok: false };
17
+ }
18
+ return { ok: true, headers: result.value };
12
19
  }
13
20
  /**
14
21
  * Create route-scoped authentication hooks.
15
22
  *
23
+ * The outer call binds the app context; the inner call takes auth options and
24
+ * infers the added context from `resolve`:
25
+ *
26
+ * ```ts
27
+ * const auth = createAuthHooks<AppContext>()({
28
+ * resolve: ({ ctx }) => (ctx.auth ? { user: ctx.auth.user } : null),
29
+ * });
30
+ * ```
31
+ *
16
32
  * Use `auth.required()` on routes that require an authenticated actor and
17
33
  * `auth.optional()` where handlers can use auth when present. The returned
18
34
  * route hooks enrich handler `ctx`; business authorization still belongs in
19
35
  * feature policies or use cases.
20
36
  *
21
- * @param options - Auth resolution callback and optional diagnostic name.
22
- * @returns Public, optional, and required route-hook factories.
37
+ * Declare a `headers` schema when credentials live in request headers. The
38
+ * hook validates the raw lowercase header record itself, so `resolve` receives
39
+ * typed headers without contract casts and a `required()` hook rejects
40
+ * missing or malformed credentials with a framework-owned 401.
41
+ *
42
+ * @returns A function that takes auth options and returns public, optional,
43
+ * and required route-hook factories.
23
44
  */
24
- export function createAuthHooks(options) {
25
- const name = options.name ?? "auth";
26
- return {
27
- public: () => ({
28
- name: `${name}.public`,
29
- resolve: () => undefined,
30
- }),
31
- optional: () => ({
32
- name: `${name}.optional`,
33
- resolve: async (args) => {
34
- const additions = await options.resolve(toAuthArgs(args));
35
- return additions ?? undefined;
36
- },
37
- }),
38
- required: () => ({
39
- name: `${name}.required`,
40
- resolve: async (args) => {
41
- const additions = await options.resolve(toAuthArgs(args));
42
- if (!additions) {
43
- throw new AuthUnauthorizedError();
44
- }
45
- return additions;
46
- },
47
- }),
45
+ export function createAuthHooks() {
46
+ return (options) => {
47
+ const name = options.name ?? "auth";
48
+ const toAuthArgs = (args, headers) => ({
49
+ req: args.req,
50
+ ctx: args.ctx,
51
+ contract: args.contract,
52
+ path: args.path,
53
+ query: args.query,
54
+ headers,
55
+ body: args.body,
56
+ });
57
+ return {
58
+ public: () => ({
59
+ name: `${name}.public`,
60
+ resolve: () => undefined,
61
+ }),
62
+ optional: () => ({
63
+ name: `${name}.optional`,
64
+ resolve: async (args) => {
65
+ const parsed = await parseAuthHeaders(options.headers, args.req);
66
+ if (!parsed.ok) {
67
+ return undefined;
68
+ }
69
+ const additions = await options.resolve(toAuthArgs(args, parsed.headers));
70
+ return additions ?? undefined;
71
+ },
72
+ }),
73
+ required: () => ({
74
+ name: `${name}.required`,
75
+ resolve: async (args) => {
76
+ const parsed = await parseAuthHeaders(options.headers, args.req);
77
+ if (!parsed.ok) {
78
+ throw new AuthUnauthorizedError();
79
+ }
80
+ const additions = await options.resolve(toAuthArgs(args, parsed.headers));
81
+ if (!additions) {
82
+ throw new AuthUnauthorizedError();
83
+ }
84
+ return additions;
85
+ },
86
+ }),
87
+ };
48
88
  };
49
89
  }
50
90
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/hooks/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AA4EpD,SAAS,UAAU,CACjB,IAAsD;IAEtD,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAwC;IAExC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC;IAEpC,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACb,IAAI,EAAE,GAAG,IAAI,SAAS;YACtB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;SACzB,CAAC;QACF,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACf,IAAI,EAAE,GAAG,IAAI,WAAW;YACxB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACtB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBAE1D,OAAO,SAAS,IAAI,SAAS,CAAC;YAChC,CAAC;SACF,CAAC;QACF,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACf,IAAI,EAAE,GAAG,IAAI,WAAW;YACxB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACtB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,IAAI,qBAAqB,EAAE,CAAC;gBACpC,CAAC;gBAED,OAAO,SAAS,CAAC;YACnB,CAAC;SACF,CAAC;KACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/hooks/auth.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * CORS hook utilities for @beignet/core/server
3
3
  */
4
- import type { HttpRequestLike, ServerHook } from "../types";
4
+ import type { HttpRequestLike, ServerHook } from "../types.js";
5
5
  /**
6
6
  * CORS configuration for `createCorsHooks(...)`.
7
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/cors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,eAAe,EACpB,UAAU,EAAE,UAAU,GACrB,IAAI,CA4BN;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAsBxE"}
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/cors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,eAAe,EACpB,UAAU,EAAE,UAAU,GACrB,IAAI,CA4BN;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAsBxE"}
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * Framework-agnostic error mapping utilities for @beignet/core/server
3
3
  */
4
- import type { AppEnvironment } from "../health";
4
+ import type { AppEnvironment } from "../health.js";
5
5
  /**
6
6
  * Re-export `AppEnvironment` for convenience.
7
7
  */
8
- export type { AppEnvironment } from "../health";
8
+ export type { AppEnvironment } from "../health.js";
9
9
  /**
10
10
  * Framework-neutral response produced by an error mapper.
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD;;GAEG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,GAAG;IACrC,oCAAoC;IACpC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,kBAAkB,CAAC;IAEpE,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,+BAA+B;IAC/B,GAAG,CAAC,EAAE,cAAc,CAAC;CACtB;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAC9B,kBAAkB,CAwBpB"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD;;GAEG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,GAAG;IACrC,oCAAoC;IACpC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,kBAAkB,CAAC;IAEpE,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,+BAA+B;IAC/B,GAAG,CAAC,EAAE,cAAc,CAAC;CACtB;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAC9B,kBAAkB,CAwBpB"}
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Framework-agnostic error mapping utilities for @beignet/core/server
3
3
  */
4
- import { createErrorResponseBody } from "../../errors";
5
- import { getRequestIdFromContext } from "./utils";
4
+ import { createErrorResponseBody, } from "../../errors/index.js";
5
+ import { getRequestIdFromContext } from "./utils.js";
6
6
  /**
7
7
  * Create default error response body
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/server/hooks/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAA0B,MAAM,cAAc,CAAC;AAE/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAuClD;;GAEG;AACH,SAAS,sBAAsB,CAC7B,GAAY,EACZ,YAAqB,EACrB,SAAkB;IAElB,OAAO,uBAAuB,CAAC;QAC7B,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,uBAAuB;QAChC,SAAS;QACT,OAAO,EACL,YAAY,IAAI,GAAG,YAAY,KAAK;YAClC,CAAC,CAAC;gBACE,KAAK,EAAE;oBACL,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;iBACjB;aACF;YACH,CAAC,CAAC,SAAS;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,yBAAyB,CACvC,GAAY,EACZ,GAAQ,EACR,MAA+B;IAE/B,6CAA6C;IAC7C,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,+CAA+C;QACjD,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,YAAY,GAChB,MAAM,CAAC,sBAAsB;QAC7B,CAAC,MAAM,CAAC,GAAG,KAAK,aAAa,IAAI,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;IAE1D,yBAAyB;IACzB,MAAM,SAAS,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,sBAAsB,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;IAElE,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI;QACJ,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/server/hooks/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,uBAAuB,GAExB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAuCrD;;GAEG;AACH,SAAS,sBAAsB,CAC7B,GAAY,EACZ,YAAqB,EACrB,SAAkB;IAElB,OAAO,uBAAuB,CAAC;QAC7B,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,uBAAuB;QAChC,SAAS;QACT,OAAO,EACL,YAAY,IAAI,GAAG,YAAY,KAAK;YAClC,CAAC,CAAC;gBACE,KAAK,EAAE;oBACL,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;iBACjB;aACF;YACH,CAAC,CAAC,SAAS;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,yBAAyB,CACvC,GAAY,EACZ,GAAQ,EACR,MAA+B;IAE/B,6CAA6C;IAC7C,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,+CAA+C;QACjD,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,YAAY,GAChB,MAAM,CAAC,sBAAsB;QAC7B,CAAC,MAAM,CAAC,GAAG,KAAK,aAAa,IAAI,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;IAE1D,yBAAyB;IACzB,MAAM,SAAS,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,sBAAsB,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;IAElE,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI;QACJ,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Idempotency hooks for @beignet/core/server
3
+ */
4
+ import { type IdempotencyMeta, type IdempotencyPort, type IdempotencyScope } from "../../idempotency/index.js";
5
+ import type { ActivityActor, ActivityTenant } from "../../ports/index.js";
6
+ import type { HttpRequestLike, ServerHook } from "../types.js";
7
+ /**
8
+ * Ports required by idempotency hooks.
9
+ */
10
+ export type IdempotencyPorts = {
11
+ idempotency: IdempotencyPort;
12
+ };
13
+ /**
14
+ * Minimal context shape required for actor- and tenant-scoped idempotency.
15
+ */
16
+ export type CtxWithIdempotency = {
17
+ ports: IdempotencyPorts;
18
+ actor?: ActivityActor;
19
+ tenant?: ActivityTenant;
20
+ };
21
+ /**
22
+ * Options for `createIdempotencyHooks(...)`.
23
+ */
24
+ export interface IdempotencyHooksOptions<Ctx> {
25
+ /**
26
+ * Build the idempotency namespace for a contract.
27
+ *
28
+ * Defaults to `http.<contract name>` so HTTP reservations never collide with
29
+ * use-case `runIdempotently(...)` namespaces.
30
+ */
31
+ namespace?: (args: {
32
+ contract: {
33
+ name: string;
34
+ };
35
+ }) => string;
36
+ /**
37
+ * Build the idempotency scope after context exists.
38
+ *
39
+ * Defaults to a scope derived from `meta.scope`: `"global"` stays global,
40
+ * `"actor"` scopes by `ctx.actor?.id`, `"tenant"` scopes by `ctx.tenant?.id`,
41
+ * and `"actor-tenant"` scopes by both.
42
+ */
43
+ scope?: (args: {
44
+ ctx: Ctx;
45
+ req: HttpRequestLike;
46
+ meta: IdempotencyMeta;
47
+ }) => IdempotencyScope;
48
+ /**
49
+ * Build the fingerprint input from the parsed request.
50
+ *
51
+ * Defaults to `{ path, query, body }`.
52
+ */
53
+ fingerprintInput?: (args: {
54
+ path: unknown;
55
+ query: unknown;
56
+ body: unknown;
57
+ }) => unknown;
58
+ }
59
+ /**
60
+ * Create metadata-driven idempotency hooks.
61
+ *
62
+ * The hook reads `contract.metadata.idempotency` and enforces it with
63
+ * `ctx.ports.idempotency`. In `beforeHandle` it reserves the client key after
64
+ * request parsing, replays completed matching responses with an
65
+ * `idempotency-replayed: true` header, and rejects in-progress or conflicting
66
+ * keys with the framework `IdempotencyInProgress`/`IdempotencyConflict` catalog
67
+ * errors. In `beforeSend` it stores 2xx framework-neutral responses for replay
68
+ * and releases the reservation for errors, non-2xx responses, and native
69
+ * `Response` results, which are not replayable.
70
+ *
71
+ * Use `runIdempotently(...)` from `@beignet/core/idempotency` for non-HTTP
72
+ * workflows such as jobs, listeners, webhooks, and schedules.
73
+ *
74
+ * @param options - Optional namespace, scope, and fingerprint-input builders.
75
+ * @returns A server hook backed by `ctx.ports.idempotency`.
76
+ */
77
+ export declare function createIdempotencyHooks<Ctx extends CtxWithIdempotency>(options?: IdempotencyHooksOptions<Ctx>): ServerHook<Ctx, IdempotencyPorts>;
78
+ //# sourceMappingURL=idempotency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/idempotency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EACV,eAAe,EAEf,UAAU,EACX,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,eAAe,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,GAAG;IAC1C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,KAAK,MAAM,CAAC;IAC7D;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE;QACb,GAAG,EAAE,GAAG,CAAC;QACT,GAAG,EAAE,eAAe,CAAC;QACrB,IAAI,EAAE,eAAe,CAAC;KACvB,KAAK,gBAAgB,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;KACf,KAAK,OAAO,CAAC;CACf;AAmDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,SAAS,kBAAkB,EACnE,OAAO,GAAE,uBAAuB,CAAC,GAAG,CAAM,GACzC,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,CA0HnC"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Idempotency hooks for @beignet/core/server
3
+ */
4
+ import { AppError, httpErrors } from "../../errors/index.js";
5
+ import { createIdempotencyFingerprint, IdempotencyConflictError, IdempotencyInProgressError, } from "../../idempotency/index.js";
6
+ /**
7
+ * Header set on replayed responses.
8
+ */
9
+ const IDEMPOTENCY_REPLAYED_HEADER = "idempotency-replayed";
10
+ function defaultIdempotencyScope(ctx, meta) {
11
+ const mode = meta.scope ?? "global";
12
+ switch (mode) {
13
+ case "global":
14
+ return "global";
15
+ case "actor":
16
+ return { actorId: ctx.actor?.id };
17
+ case "tenant":
18
+ return { tenantId: ctx.tenant?.id };
19
+ case "actor-tenant":
20
+ return { actorId: ctx.actor?.id, tenantId: ctx.tenant?.id };
21
+ }
22
+ }
23
+ function isReplayableHttpResponse(value) {
24
+ if (typeof value !== "object" || value === null)
25
+ return false;
26
+ const candidate = value;
27
+ if (typeof candidate.status !== "number")
28
+ return false;
29
+ if (candidate.headers !== undefined &&
30
+ (typeof candidate.headers !== "object" ||
31
+ candidate.headers === null ||
32
+ Array.isArray(candidate.headers))) {
33
+ return false;
34
+ }
35
+ return true;
36
+ }
37
+ /**
38
+ * Create metadata-driven idempotency hooks.
39
+ *
40
+ * The hook reads `contract.metadata.idempotency` and enforces it with
41
+ * `ctx.ports.idempotency`. In `beforeHandle` it reserves the client key after
42
+ * request parsing, replays completed matching responses with an
43
+ * `idempotency-replayed: true` header, and rejects in-progress or conflicting
44
+ * keys with the framework `IdempotencyInProgress`/`IdempotencyConflict` catalog
45
+ * errors. In `beforeSend` it stores 2xx framework-neutral responses for replay
46
+ * and releases the reservation for errors, non-2xx responses, and native
47
+ * `Response` results, which are not replayable.
48
+ *
49
+ * Use `runIdempotently(...)` from `@beignet/core/idempotency` for non-HTTP
50
+ * workflows such as jobs, listeners, webhooks, and schedules.
51
+ *
52
+ * @param options - Optional namespace, scope, and fingerprint-input builders.
53
+ * @returns A server hook backed by `ctx.ports.idempotency`.
54
+ */
55
+ export function createIdempotencyHooks(options = {}) {
56
+ const pending = new WeakMap();
57
+ return {
58
+ name: "idempotency",
59
+ beforeHandle: async ({ ctx, contract, req, path, query, body }) => {
60
+ const meta = contract.metadata?.idempotency;
61
+ if (!meta) {
62
+ return undefined;
63
+ }
64
+ const header = (meta.header ?? "idempotency-key").toLowerCase();
65
+ const key = req.headers.get(header);
66
+ if (!key) {
67
+ if (meta.required) {
68
+ throw new AppError(httpErrors.BadRequest, {
69
+ contract: contract.name,
70
+ header,
71
+ }, `Missing required idempotency key header "${header}"`);
72
+ }
73
+ return undefined;
74
+ }
75
+ const namespace = options.namespace?.({ contract: { name: contract.name } }) ??
76
+ `http.${contract.name}`;
77
+ const scope = options.scope?.({ ctx, req, meta }) ??
78
+ defaultIdempotencyScope(ctx, meta);
79
+ const fingerprint = await createIdempotencyFingerprint(options.fingerprintInput?.({ path, query, body }) ?? {
80
+ path,
81
+ query,
82
+ body,
83
+ });
84
+ const reservation = await ctx.ports.idempotency.reserve({
85
+ namespace,
86
+ key,
87
+ scope,
88
+ fingerprint,
89
+ ttlSec: meta.ttlSec,
90
+ });
91
+ switch (reservation.status) {
92
+ case "replay": {
93
+ if (!isReplayableHttpResponse(reservation.result)) {
94
+ throw new AppError(httpErrors.InternalServerError, { namespace, key }, `Stored idempotency result for "${namespace}" key "${key}" is not a replayable HTTP response`);
95
+ }
96
+ return {
97
+ status: reservation.result.status,
98
+ headers: {
99
+ ...(reservation.result.headers ?? {}),
100
+ [IDEMPOTENCY_REPLAYED_HEADER]: "true",
101
+ },
102
+ body: reservation.result.body,
103
+ };
104
+ }
105
+ case "inProgress": {
106
+ throw new IdempotencyInProgressError(reservation);
107
+ }
108
+ case "conflict": {
109
+ throw new IdempotencyConflictError(reservation);
110
+ }
111
+ case "reserved": {
112
+ pending.set(req, {
113
+ port: ctx.ports.idempotency,
114
+ namespace,
115
+ key,
116
+ scope,
117
+ fingerprint,
118
+ });
119
+ return undefined;
120
+ }
121
+ }
122
+ },
123
+ beforeSend: async ({ req, response, error, native }) => {
124
+ const reservation = pending.get(req);
125
+ if (!reservation) {
126
+ return undefined;
127
+ }
128
+ pending.delete(req);
129
+ const { port, namespace, key, scope, fingerprint } = reservation;
130
+ if (!native &&
131
+ !error &&
132
+ response.status >= 200 &&
133
+ response.status < 300) {
134
+ await port.complete({
135
+ namespace,
136
+ key,
137
+ scope,
138
+ fingerprint,
139
+ result: {
140
+ status: response.status,
141
+ headers: response.headers,
142
+ body: response.body,
143
+ },
144
+ });
145
+ return undefined;
146
+ }
147
+ // Errors, non-2xx responses, and native `Response` results release the
148
+ // reservation. Streams are not replayable.
149
+ await port.fail({ namespace, key, scope, fingerprint, error });
150
+ return undefined;
151
+ },
152
+ };
153
+ }
154
+ //# sourceMappingURL=idempotency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../../src/server/hooks/idempotency.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * Hook utilities for @beignet/core/server
3
3
  */
4
- import type { AnyPorts } from "../../ports";
5
- import type { ServerHook } from "../http";
6
- export { type AuthHookArgs, type AuthHooksOptions, type AuthRouteHooks, createAuthHooks, } from "./auth";
7
- export { applyCorsHeaders, type CorsConfig, createCorsHooks, } from "./cors";
8
- export { defaultMapErrorToResponse, type ErrorMappingConfig, type ErrorMappingResult, } from "./errors";
9
- export { createLoggingHooks, type Logger, type LoggingConfig, } from "./logging";
10
- export { type CtxWithRateLimit, createRateLimitHooks, type RateLimitOptions, } from "./rate-limit";
4
+ import type { AnyPorts } from "../../ports/index.js";
5
+ import type { ServerHook } from "../http.js";
6
+ export { type AuthHookArgs, type AuthHooksOptions, type AuthRouteHooks, createAuthHooks, } from "./auth.js";
7
+ export { applyCorsHeaders, type CorsConfig, createCorsHooks, } from "./cors.js";
8
+ export { defaultMapErrorToResponse, type ErrorMappingConfig, type ErrorMappingResult, } from "./errors.js";
9
+ export { type CtxWithIdempotency, createIdempotencyHooks, type IdempotencyHooksOptions, type IdempotencyPorts, } from "./idempotency.js";
10
+ export { createLoggingHooks, type Logger, type LoggingConfig, } from "./logging.js";
11
+ export { type CtxWithRateLimit, createRateLimitHooks, type RateLimitIpSource, type RateLimitOptions, } from "./rate-limit.js";
11
12
  /**
12
13
  * Flatten hook arrays into a single hook list.
13
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,kBAAkB,EAClB,KAAK,MAAM,EACX,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,gBAAgB,EACrB,oBAAoB,EACpB,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,SAAS,QAAQ,GAAG,QAAQ,EACjE,GAAG,KAAK,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,SAAS,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,GACvE,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAE1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAClB,KAAK,MAAM,EACX,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,gBAAgB,EACrB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,SAAS,QAAQ,GAAG,QAAQ,EACjE,GAAG,KAAK,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,SAAS,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,GACvE,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAE1B"}
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * Hook utilities for @beignet/core/server
3
3
  */
4
- export { createAuthHooks, } from "./auth";
5
- export { applyCorsHeaders, createCorsHooks, } from "./cors";
6
- export { defaultMapErrorToResponse, } from "./errors";
7
- export { createLoggingHooks, } from "./logging";
8
- export { createRateLimitHooks, } from "./rate-limit";
4
+ export { createAuthHooks, } from "./auth.js";
5
+ export { applyCorsHeaders, createCorsHooks, } from "./cors.js";
6
+ export { defaultMapErrorToResponse, } from "./errors.js";
7
+ export { createIdempotencyHooks, } from "./idempotency.js";
8
+ export { createLoggingHooks, } from "./logging.js";
9
+ export { createRateLimitHooks, } from "./rate-limit.js";
9
10
  /**
10
11
  * Flatten hook arrays into a single hook list.
11
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAIL,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,gBAAgB,EAEhB,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,yBAAyB,GAG1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,kBAAkB,GAGnB,MAAM,WAAW,CAAC;AACnB,OAAO,EAEL,oBAAoB,GAErB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAG,KAAqE;IAExE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAIL,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,gBAAgB,EAEhB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,yBAAyB,GAG1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,sBAAsB,GAGvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,GAGnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,oBAAoB,GAGrB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAG,KAAqE;IAExE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC"}
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Logging hook utilities for @beignet/core/server
3
3
  */
4
- import type { HttpContractConfig } from "../../contracts";
5
- import type { HttpRequestLike, ServerHook } from "../types";
4
+ import type { HttpContractConfig } from "../../contracts/index.js";
5
+ import type { HttpRequestLike, ServerHook } from "../types.js";
6
6
  /**
7
7
  * Minimal logger shape accepted by `createLoggingHooks(...)`.
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/logging.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG5D;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB;;OAEG;IACH,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,GAAG;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QACtB,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,GAAG,EAAE,eAAe,CAAC;QACrB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;KAC/B,KAAK,IAAI,CAAC;IACX;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QACpB,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,GAAG,EAAE,eAAe,CAAC;QACrB,GAAG,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAC;QACzD,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;QAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,KAAK,IAAI,CAAC;CACZ;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EACpC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GACzB,UAAU,CAAC,GAAG,CAAC,CAqFjB"}
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/logging.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG/D;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB;;OAEG;IACH,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,GAAG;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QACtB,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,GAAG,EAAE,eAAe,CAAC;QACrB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;KAC/B,KAAK,IAAI,CAAC;IACX;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QACpB,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,GAAG,EAAE,eAAe,CAAC;QACrB,GAAG,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAC;QACzD,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;QAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,KAAK,IAAI,CAAC;CACZ;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EACpC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GACzB,UAAU,CAAC,GAAG,CAAC,CAqFjB"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Logging hook utilities for @beignet/core/server
3
3
  */
4
- import { getRequestIdFromContext } from "./utils";
4
+ import { getRequestIdFromContext } from "./utils.js";
5
5
  /**
6
6
  * Create request logging hooks.
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sourceRoot":"","sources":["../../../src/server/hooks/logging.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../../../src/server/hooks/logging.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Rate limit hooks for @beignet/core/server
3
3
  */
4
- import type { RateLimitScope } from "../../contracts";
5
- import type { ActivityActor, RateLimitPort } from "../../ports";
6
- import type { HttpRequestLike, ServerHook } from "../types";
4
+ import type { RateLimitScope } from "../../contracts/index.js";
5
+ import type { ActivityActor, RateLimitPort } from "../../ports/index.js";
6
+ import type { HttpRequestLike, ServerHook } from "../types.js";
7
7
  /**
8
8
  * Ports required by rate-limit hooks.
9
9
  */
@@ -18,6 +18,19 @@ export type CtxWithRateLimit = {
18
18
  actor?: ActivityActor;
19
19
  };
20
20
  type EarlyRateLimitScope = Exclude<RateLimitScope, "user">;
21
+ /**
22
+ * Strategy for resolving the client IP used by `ip`-scoped limits.
23
+ *
24
+ * - `"x-forwarded-for-last"` (default): the last `x-forwarded-for` entry.
25
+ * This is the address appended by the platform's trusted reverse proxy and
26
+ * cannot be chosen by the client.
27
+ * - `"x-forwarded-for-first"`: the first `x-forwarded-for` entry. This value
28
+ * is client-controlled, so only use it when a trusted edge normalizes the
29
+ * header before it reaches the app.
30
+ * - A function receives the raw request and returns the client IP, for
31
+ * platform-specific headers such as `cf-connecting-ip`.
32
+ */
33
+ export type RateLimitIpSource = "x-forwarded-for-last" | "x-forwarded-for-first" | ((req: HttpRequestLike) => string | undefined);
21
34
  /**
22
35
  * Options for `createRateLimitHooks(...)`.
23
36
  */
@@ -42,9 +55,12 @@ export interface RateLimitOptions<Ctx> {
42
55
  scope: EarlyRateLimitScope;
43
56
  }) => string;
44
57
  /**
45
- * Resolve a client IP from the raw request.
58
+ * Resolve the client IP for `ip`-scoped limits.
59
+ *
60
+ * Defaults to `"x-forwarded-for-last"`, the entry appended by the
61
+ * platform's trusted proxy. Pass a function for platform-specific headers.
46
62
  */
47
- getClientIp?: (req: HttpRequestLike) => string | undefined;
63
+ ipSource?: RateLimitIpSource;
48
64
  }
49
65
  /**
50
66
  * Create metadata-driven rate-limit hooks.
@@ -52,9 +68,11 @@ export interface RateLimitOptions<Ctx> {
52
68
  * The hook reads `contract.metadata.rateLimit`. Global and IP-scoped limits run
53
69
  * in `onRequest` before context creation; user-scoped limits run in
54
70
  * `beforeHandle` after `ctx.actor` is available. Exceeded limits throw the
55
- * framework `TooManyRequests` app error.
71
+ * framework `TooManyRequests` app error with `scope`, `retryAfterSeconds`, and
72
+ * `resetAt` details. The bucket key is never sent to clients; denials emit a
73
+ * `rateLimit.denied` instrumentation event that carries the key for operators.
56
74
  *
57
- * @param options - Optional key builders and client-IP resolver.
75
+ * @param options - Optional key builders and client-IP source.
58
76
  * @returns A server hook backed by `ctx.ports.rateLimit`.
59
77
  */
60
78
  export declare function createRateLimitHooks<Ctx extends CtxWithRateLimit>(options?: RateLimitOptions<Ctx>): ServerHook<Ctx, RateLimitPorts>;
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/rate-limit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF,KAAK,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,GAAG;IACnC;;;;OAIG;IACH,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;QACX,GAAG,EAAE,GAAG,CAAC;QACT,GAAG,EAAE,eAAe,CAAC;QACrB,KAAK,EAAE,cAAc,CAAC;KACvB,KAAK,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,GAAG,EAAE,eAAe,CAAC;QACrB,KAAK,EAAE,mBAAmB,CAAC;KAC5B,KAAK,MAAM,CAAC;IACb;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D;AAmFD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,SAAS,gBAAgB,EAC/D,OAAO,GAAE,gBAAgB,CAAC,GAAG,CAAM,GAClC,UAAU,CAAC,GAAG,EAAE,cAAc,CAAC,CAsDjC"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/rate-limit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAKzE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF,KAAK,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,iBAAiB,GACzB,sBAAsB,GACtB,uBAAuB,GACvB,CAAC,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,GAAG;IACnC;;;;OAIG;IACH,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;QACX,GAAG,EAAE,GAAG,CAAC;QACT,GAAG,EAAE,eAAe,CAAC;QACrB,KAAK,EAAE,cAAc,CAAC;KACvB,KAAK,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,GAAG,EAAE,eAAe,CAAC;QACrB,KAAK,EAAE,mBAAmB,CAAC;KAC5B,KAAK,MAAM,CAAC;IACb;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AA4HD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,SAAS,gBAAgB,EAC/D,OAAO,GAAE,gBAAgB,CAAC,GAAG,CAAM,GAClC,UAAU,CAAC,GAAG,EAAE,cAAc,CAAC,CAuDjC"}