@beignet/core 0.0.2 → 0.0.4

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 +173 -0
  2. package/README.md +821 -30
  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 +148 -16
  100. package/dist/jobs/index.d.ts.map +1 -1
  101. package/dist/jobs/index.js +174 -14
  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 +18 -4
  116. package/dist/outbox/index.d.ts.map +1 -1
  117. package/dist/outbox/index.js +104 -4
  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 +46 -5
  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 +89 -65
  184. package/dist/server/hooks/auth.d.ts.map +1 -1
  185. package/dist/server/hooks/auth.js +84 -55
  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 +84 -6
  214. package/dist/server/http.d.ts.map +1 -1
  215. package/dist/server/index.d.ts +36 -12
  216. package/dist/server/index.d.ts.map +1 -1
  217. package/dist/server/index.js +24 -8
  218. package/dist/server/index.js.map +1 -1
  219. package/dist/server/instrumentation.d.ts +108 -0
  220. package/dist/server/instrumentation.d.ts.map +1 -0
  221. package/dist/server/instrumentation.js +297 -0
  222. package/dist/server/instrumentation.js.map +1 -0
  223. package/dist/server/openapi.d.ts +3 -3
  224. package/dist/server/openapi.d.ts.map +1 -1
  225. package/dist/server/openapi.js +1 -1
  226. package/dist/server/openapi.js.map +1 -1
  227. package/dist/server/providers/index.d.ts +3 -3
  228. package/dist/server/providers/index.d.ts.map +1 -1
  229. package/dist/server/providers/index.js +3 -3
  230. package/dist/server/providers/index.js.map +1 -1
  231. package/dist/server/providers/loadProviderConfig.d.ts +2 -2
  232. package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
  233. package/dist/server/providers/loadProviderConfig.js +2 -2
  234. package/dist/server/providers/loadProviderConfig.js.map +1 -1
  235. package/dist/server/request-context.d.ts +67 -0
  236. package/dist/server/request-context.d.ts.map +1 -0
  237. package/dist/server/request-context.js +79 -0
  238. package/dist/server/request-context.js.map +1 -0
  239. package/dist/server/server-context.d.ts +38 -0
  240. package/dist/server/server-context.d.ts.map +1 -0
  241. package/dist/server/server-context.js +38 -0
  242. package/dist/server/server-context.js.map +1 -0
  243. package/dist/server/server.d.ts +148 -35
  244. package/dist/server/server.d.ts.map +1 -1
  245. package/dist/server/server.js +482 -145
  246. package/dist/server/server.js.map +1 -1
  247. package/dist/server/types.d.ts +2 -2
  248. package/dist/server/types.d.ts.map +1 -1
  249. package/dist/server/types.js +2 -2
  250. package/dist/server/types.js.map +1 -1
  251. package/dist/server/use-case-route.d.ts +263 -0
  252. package/dist/server/use-case-route.d.ts.map +1 -0
  253. package/dist/server/use-case-route.js +77 -0
  254. package/dist/server/use-case-route.js.map +1 -0
  255. package/dist/server-only.d.ts +8 -0
  256. package/dist/server-only.d.ts.map +1 -0
  257. package/dist/server-only.js +8 -0
  258. package/dist/server-only.js.map +1 -0
  259. package/dist/tasks/index.d.ts +139 -0
  260. package/dist/tasks/index.d.ts.map +1 -0
  261. package/dist/tasks/index.js +98 -0
  262. package/dist/tasks/index.js.map +1 -0
  263. package/dist/testing/index.d.ts +611 -5
  264. package/dist/testing/index.d.ts.map +1 -1
  265. package/dist/testing/index.js +434 -4
  266. package/dist/testing/index.js.map +1 -1
  267. package/dist/tracing/index.d.ts +89 -0
  268. package/dist/tracing/index.d.ts.map +1 -0
  269. package/dist/tracing/index.js +101 -0
  270. package/dist/tracing/index.js.map +1 -0
  271. package/dist/uploads/client.d.ts +278 -0
  272. package/dist/uploads/client.d.ts.map +1 -0
  273. package/dist/uploads/client.js +428 -0
  274. package/dist/uploads/client.js.map +1 -0
  275. package/dist/uploads/index.d.ts +361 -0
  276. package/dist/uploads/index.d.ts.map +1 -0
  277. package/dist/uploads/index.js +543 -0
  278. package/dist/uploads/index.js.map +1 -0
  279. package/package.json +34 -3
  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 +340 -29
  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 +151 -6
  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 +93 -8
  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 +175 -158
  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 +15 -12
  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 +112 -6
  337. package/src/server/index.ts +63 -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 +1045 -229
  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 +1153 -6
  350. package/src/tracing/index.ts +176 -0
  351. package/src/uploads/client.ts +861 -0
  352. package/src/uploads/index.ts +1071 -0
  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,99 +1,123 @@
1
- import { type AuthPort, type AuthSession } from "../../ports";
2
- import type { HttpRequestLike, HttpResponse, ServerHook } from "../types";
1
+ import type { InferOutput, StandardSchema } from "../../contracts/index.js";
2
+ import type { HttpRequestLike, RouteHook } from "../types.js";
3
3
  type MaybePromise<T> = T | Promise<T>;
4
4
  /**
5
- * Authentication mode for one matched contract.
5
+ * Arguments passed to auth route-hook callbacks.
6
6
  */
7
- export type AuthHookMode = "public" | "optional" | "required";
8
- /**
9
- * Input accepted when resolving auth mode from contract metadata or options.
10
- *
11
- * `true` maps to `"required"`; `false`, `null`, and `undefined` map to
12
- * `"public"`.
13
- */
14
- export type AuthHookModeInput = AuthHookMode | boolean | null | undefined;
15
- /**
16
- * Minimal context shape required when `createAuthHooks(...)` reads
17
- * `ctx.ports.auth`.
18
- */
19
- export type CtxWithAuthPort = {
20
- ports: {
21
- auth: AuthPort;
22
- };
23
- };
24
- /**
25
- * Arguments passed to auth hook callbacks.
26
- */
27
- export type AuthHookArgs<Ctx> = {
7
+ export type AuthHookArgs<Ctx, HeadersSchema extends StandardSchema | undefined = undefined> = {
8
+ /**
9
+ * Framework-neutral request.
10
+ */
28
11
  req: HttpRequestLike;
12
+ /**
13
+ * Current route handler context.
14
+ */
29
15
  ctx: Ctx;
16
+ /**
17
+ * Matched contract metadata and schemas.
18
+ */
30
19
  contract: {
31
20
  metadata?: Record<string, unknown>;
32
21
  };
22
+ /**
23
+ * Parsed path parameters.
24
+ */
33
25
  path: unknown;
26
+ /**
27
+ * Parsed query parameters.
28
+ */
34
29
  query: unknown;
35
- headers: unknown;
30
+ /**
31
+ * Hook-owned request headers.
32
+ *
33
+ * When the auth hooks declare a `headers` schema, this is that schema's
34
+ * output parsed from the raw lowercase request header record. Without a
35
+ * schema it is the raw lowercase header record itself, so auth resolution
36
+ * never depends on each route's contract header schema.
37
+ */
38
+ headers: HeadersSchema extends StandardSchema ? InferOutput<HeadersSchema> : Record<string, string>;
39
+ /**
40
+ * Parsed request body.
41
+ */
36
42
  body: unknown;
37
43
  };
38
44
  /**
39
- * Arguments passed to the auth `assign` callback.
40
- */
41
- export type AuthHookAssignArgs<Ctx, Session> = AuthHookArgs<Ctx> & {
42
- session: Session | null;
43
- };
44
- /**
45
- * Arguments passed to the auth `unauthorized` callback.
46
- */
47
- export type AuthHookUnauthorizedArgs<Ctx, Session> = AuthHookArgs<Ctx> & {
48
- session: Session | null;
49
- };
50
- /**
51
- * Options for `createAuthHooks(...)`.
45
+ * Options for route-scoped auth hooks.
46
+ *
47
+ * Auth additions must not include `gate`: the server re-attaches the gate
48
+ * declared by the context blueprint after every hook, so elevated identities
49
+ * are authorized against the updated context automatically.
52
50
  */
53
- export type AuthHooksOptions<Ctx, Session> = {
51
+ export type AuthHooksOptions<Ctx, AddedCtx extends object & {
52
+ gate?: never;
53
+ }, HeadersSchema extends StandardSchema | undefined = undefined> = {
54
54
  /**
55
- * Hook name used in diagnostics.
55
+ * Hook name prefix used in diagnostics.
56
56
  */
57
57
  name?: string;
58
58
  /**
59
- * Resolve whether the current contract is public, optional-auth, or required-auth.
59
+ * Optional Standard Schema for the credential headers this hook reads.
60
+ *
61
+ * The schema is validated against the raw lowercase request header record
62
+ * before `resolve` runs. On `required()` hooks a schema failure rejects the
63
+ * request with a framework-owned 401; on `optional()` hooks a schema failure
64
+ * skips auth resolution; `public()` hooks never parse headers.
60
65
  */
61
- mode?: (args: AuthHookArgs<Ctx>) => MaybePromise<AuthHookModeInput>;
66
+ headers?: HeadersSchema;
62
67
  /**
63
- * Custom session lookup. Required when context does not expose
64
- * `ctx.ports.auth`.
68
+ * Resolve authenticated context additions for the current request.
69
+ *
70
+ * Return `null` when the request is unauthenticated. Required hooks will
71
+ * reject that request; optional hooks will add no auth context.
65
72
  */
66
- getSession?: (args: AuthHookArgs<Ctx>) => MaybePromise<Session | null>;
73
+ resolve: (args: AuthHookArgs<Ctx, HeadersSchema>) => MaybePromise<AddedCtx | null>;
74
+ };
75
+ /**
76
+ * Route-scoped auth hook set.
77
+ */
78
+ export type AuthRouteHooks<Ctx, AddedCtx extends object & {
79
+ gate?: never;
80
+ }> = {
67
81
  /**
68
- * Decide whether a resolved session counts as authenticated.
82
+ * Mark a route as intentionally public.
69
83
  */
70
- isAuthenticated?: (session: Session | null) => boolean;
84
+ public: () => RouteHook<Ctx, Record<string, never>>;
71
85
  /**
72
- * Return an updated context with auth/session fields attached.
86
+ * Resolve auth when present and add optional auth fields to the handler ctx.
73
87
  */
74
- assign?: (args: AuthHookAssignArgs<Ctx, Session>) => MaybePromise<Ctx>;
88
+ optional: () => RouteHook<Ctx, Partial<AddedCtx>>;
75
89
  /**
76
- * Return a custom unauthorized response for required-auth routes.
90
+ * Require auth and add authenticated fields to the handler ctx.
77
91
  */
78
- unauthorized?: (args: AuthHookUnauthorizedArgs<Ctx, Session>) => MaybePromise<HttpResponse>;
92
+ required: () => RouteHook<Ctx, AddedCtx>;
79
93
  };
80
- type InferAuthSession<TAuth> = TAuth extends AuthPort<infer User, infer SessionMetadata> ? AuthSession<User, SessionMetadata> : unknown;
81
94
  /**
82
- * Create metadata-driven authentication hooks.
95
+ * Create route-scoped authentication hooks.
96
+ *
97
+ * The outer call binds the app context; the inner call takes auth options and
98
+ * infers the added context from `resolve`:
99
+ *
100
+ * ```ts
101
+ * const auth = createAuthHooks<AppContext>()({
102
+ * resolve: ({ ctx }) => (ctx.auth ? { user: ctx.auth.user } : null),
103
+ * });
104
+ * ```
105
+ *
106
+ * Use `auth.required()` on routes that require an authenticated actor and
107
+ * `auth.optional()` where handlers can use auth when present. The returned
108
+ * route hooks enrich handler `ctx`; business authorization still belongs in
109
+ * feature policies or use cases.
83
110
  *
84
- * By default the hook reads `contract.metadata.auth`: `"required"` or `true`
85
- * requires an authenticated session, `"optional"` attaches a session when one
86
- * exists, and missing/false metadata treats the route as public. The hook
87
- * identifies a user; business authorization still belongs in policies or use
88
- * cases.
111
+ * Declare a `headers` schema when credentials live in request headers. The
112
+ * hook validates the raw lowercase header record itself, so `resolve` receives
113
+ * typed headers without contract casts and a `required()` hook rejects
114
+ * missing or malformed credentials with a framework-owned 401.
89
115
  *
90
- * @param options - Optional auth mode, session lookup, context assignment, and
91
- * unauthorized response customization.
92
- * @returns A server hook that runs before route handlers.
116
+ * @returns A function that takes auth options and returns public, optional,
117
+ * and required route-hook factories.
93
118
  */
94
- export declare function createAuthHooks<Ctx extends CtxWithAuthPort>(options?: AuthHooksOptions<Ctx, InferAuthSession<Ctx["ports"]["auth"]>>): ServerHook<Ctx, Ctx["ports"]>;
95
- export declare function createAuthHooks<Ctx, Session>(options: AuthHooksOptions<Ctx, Session> & {
96
- getSession: (args: AuthHookArgs<Ctx>) => MaybePromise<Session | null>;
97
- }): ServerHook<Ctx>;
119
+ export declare function createAuthHooks<Ctx>(): <AddedCtx extends object & {
120
+ gate?: never;
121
+ }, HeadersSchema extends StandardSchema | undefined = undefined>(options: AuthHooksOptions<Ctx, AddedCtx, HeadersSchema>) => AuthRouteHooks<Ctx, AddedCtx>;
98
122
  export {};
99
123
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/hooks/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE9D,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtC;;GAEG;AACH,MAAM,MAAM,YAAY,CACtB,GAAG,EACH,aAAa,SAAS,cAAc,GAAG,SAAS,GAAG,SAAS,IAC1D;IACF;;OAEG;IACH,GAAG,EAAE,eAAe,CAAC;IACrB;;OAEG;IACH,GAAG,EAAE,GAAG,CAAC;IACT;;OAEG;IACH,QAAQ,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAAC;IACF;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,aAAa,SAAS,cAAc,GACzC,WAAW,CAAC,aAAa,CAAC,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,CAC1B,GAAG,EACH,QAAQ,SAAS,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,EAC1C,aAAa,SAAS,cAAc,GAAG,SAAS,GAAG,SAAS,IAC1D;IACF;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB;;;;;OAKG;IACH,OAAO,EAAE,CACP,IAAI,EAAE,YAAY,CAAC,GAAG,EAAE,aAAa,CAAC,KACnC,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,GAAG,EAAE,QAAQ,SAAS,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,IAAI;IAC5E;;OAEG;IACH,MAAM,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACpD;;OAEG;IACH,QAAQ,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClD;;OAEG;IACH,QAAQ,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;CAC1C,CAAC;AA6BF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,GAAG,MAE/B,QAAQ,SAAS,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,EAC1C,aAAa,SAAS,cAAc,GAAG,SAAS,GAAG,SAAS,EAE5D,SAAS,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,KACtD,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAyDjC"}
@@ -1,61 +1,90 @@
1
- import { AuthUnauthorizedError, } from "../../ports";
2
- function modeFromInput(input) {
3
- if (input === true || input === "required")
4
- return "required";
5
- if (input === "optional")
6
- return "optional";
7
- return "public";
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
8
  }
9
- function defaultMode(args) {
10
- return modeFromInput(args.contract.metadata?.auth);
11
- }
12
- async function defaultGetSession(args) {
13
- const auth = args.ctx.ports?.auth;
14
- if (!auth) {
15
- throw new Error("createAuthHooks requires ctx.ports.auth or an explicit getSession option.");
9
+ async function parseAuthHeaders(schema, req) {
10
+ const raw = rawRequestHeaders(req);
11
+ if (!schema) {
12
+ return { ok: true, headers: raw };
16
13
  }
17
- return auth.getSession(args.req);
18
- }
19
- function defaultIsAuthenticated(session) {
20
- return session !== null;
14
+ const result = await schema["~standard"].validate(raw);
15
+ if (result.issues) {
16
+ return { ok: false };
17
+ }
18
+ return { ok: true, headers: result.value };
21
19
  }
22
- export function createAuthHooks(options = {}) {
23
- return {
24
- name: options.name ?? "auth",
25
- beforeHandle: async ({ req, ctx, contract, path, query, headers, body, }) => {
26
- const args = {
27
- req,
28
- ctx,
29
- contract,
30
- path,
31
- query,
32
- headers,
33
- body,
34
- };
35
- const mode = modeFromInput(options.mode ? await options.mode(args) : defaultMode(args));
36
- if (mode === "public") {
37
- return undefined;
38
- }
39
- const session = options.getSession
40
- ? await options.getSession(args)
41
- : (await defaultGetSession(args));
42
- const isAuthenticated = options.isAuthenticated?.(session) ?? defaultIsAuthenticated(session);
43
- if (mode === "required" && !isAuthenticated) {
44
- if (options.unauthorized) {
45
- return {
46
- ctx,
47
- response: await options.unauthorized({ ...args, session }),
48
- };
49
- }
50
- throw new AuthUnauthorizedError();
51
- }
52
- if (!options.assign) {
53
- return undefined;
54
- }
55
- return {
56
- ctx: await options.assign({ ...args, session }),
57
- };
58
- },
20
+ /**
21
+ * Create route-scoped authentication hooks.
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
+ *
32
+ * Use `auth.required()` on routes that require an authenticated actor and
33
+ * `auth.optional()` where handlers can use auth when present. The returned
34
+ * route hooks enrich handler `ctx`; business authorization still belongs in
35
+ * feature policies or use cases.
36
+ *
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.
44
+ */
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
+ };
59
88
  };
60
89
  }
61
90
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/hooks/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,qBAAqB,GACtB,MAAM,aAAa,CAAC;AA+FrB,SAAS,aAAa,CAAC,KAAwB;IAC7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAC9D,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAC5C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAM,IAAuB;IAC/C,OAAO,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAyB,CAAC,CAAC;AAC1E,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,IAAuB;IAEvB,MAAM,IAAI,GAAI,IAAI,CAAC,GAAuC,CAAC,KAAK,EAAE,IAAI,CAAC;IACvE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,sBAAsB,CAAU,OAAuB;IAC9D,OAAO,OAAO,KAAK,IAAI,CAAC;AAC1B,CAAC;AAuBD,MAAM,UAAU,eAAe,CAC7B,UAA0C,EAAE;IAE5C,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;QAC5B,YAAY,EAAE,KAAK,EAAE,EACnB,GAAG,EACH,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,OAAO,EACP,IAAI,GACL,EAAE,EAAE;YACH,MAAM,IAAI,GAAsB;gBAC9B,GAAG;gBACH,GAAG;gBACH,QAAQ;gBACR,IAAI;gBACJ,KAAK;gBACL,OAAO;gBACP,IAAI;aACL,CAAC;YACF,MAAM,IAAI,GAAG,aAAa,CACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAC5D,CAAC;YAEF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU;gBAChC,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;gBAChC,CAAC,CAAE,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAoB,CAAC;YACxD,MAAM,eAAe,GACnB,OAAO,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;YAExE,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC5C,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;oBACzB,OAAO;wBACL,GAAG;wBACH,QAAQ,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC;qBAC3D,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,qBAAqB,EAAE,CAAC;YACpC,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,OAAO;gBACL,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC;aAChD,CAAC;QACJ,CAAC;KACF,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"}