@classytic/arc 2.28.0 → 2.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +7 -0
  3. package/TRADEMARK.md +22 -0
  4. package/dist/{BaseController-B65zbz9m.mjs → BaseController-De7GqHck.mjs} +25 -24
  5. package/dist/{EventTransport-QmY7A258.d.mts → EventTransport-2uVV34WU.d.mts} +1 -0
  6. package/dist/EventTransport-9mlTgqzE.mjs +104 -0
  7. package/dist/{HookSystem-C1vB_Gc9.mjs → HookSystem-BcmPyq5I.mjs} +16 -35
  8. package/dist/{QueryCache-DOMT_iq7.d.mts → QueryCache-DFA-QrU9.d.mts} +2 -1
  9. package/dist/{ResourceRegistry-y9Hnypus.mjs → ResourceRegistry-qq0mn2s9.mjs} +3 -2
  10. package/dist/{actionPermissions-CAphcmUG.mjs → actionPermissions-BE5NwaQk.mjs} +1 -0
  11. package/dist/audit/index.d.mts +3 -2
  12. package/dist/audit/index.mjs +3 -2
  13. package/dist/auth/audit.d.mts +1 -0
  14. package/dist/auth/audit.mjs +1 -0
  15. package/dist/auth/index.d.mts +5 -4
  16. package/dist/auth/index.mjs +6 -5
  17. package/dist/auth/redis-session.d.mts +2 -1
  18. package/dist/auth/redis-session.mjs +1 -0
  19. package/dist/authorizationDecision-ChvUQGG1.mjs +266 -0
  20. package/dist/{buildHandler-Dtwd8fdz.mjs → buildHandler-CDrCJzmB.mjs} +34 -7
  21. package/dist/cache/index.d.mts +4 -3
  22. package/dist/cache/index.mjs +4 -3
  23. package/dist/{caching-_NJeDd1_.mjs → caching-BFHA6Scf.mjs} +2 -1
  24. package/dist/cleanup/index.d.mts +4 -3
  25. package/dist/cleanup/index.mjs +9 -13
  26. package/dist/cli/commands/describe.d.mts +2 -1
  27. package/dist/cli/commands/describe.mjs +3 -2
  28. package/dist/cli/commands/docs.d.mts +1 -0
  29. package/dist/cli/commands/docs.mjs +3 -2
  30. package/dist/cli/commands/doctor.d.mts +1 -0
  31. package/dist/cli/commands/doctor.mjs +1 -0
  32. package/dist/cli/commands/generate.d.mts +2 -1
  33. package/dist/cli/commands/generate.mjs +2 -1
  34. package/dist/cli/commands/init.d.mts +2 -1
  35. package/dist/cli/commands/init.mjs +2 -1
  36. package/dist/cli/commands/introspect.d.mts +1 -0
  37. package/dist/cli/commands/introspect.mjs +2 -1
  38. package/dist/cli/index.d.mts +3 -2
  39. package/dist/cli/index.mjs +3 -2
  40. package/dist/{constants-DNre0wRg.mjs → constants-D3Dv4LAV.mjs} +1 -0
  41. package/dist/context/index.d.mts +1 -0
  42. package/dist/context/index.mjs +3 -2
  43. package/dist/core/index.d.mts +3 -2
  44. package/dist/core/index.mjs +7 -5
  45. package/dist/{core-BGa8TXJR.mjs → core-BGpIxINN.mjs} +4 -49
  46. package/dist/{createActionRouter-C-N7z2EL.mjs → createActionRouter-CDXEdasl.mjs} +8 -7
  47. package/dist/{createAggregationRouter-wzwFa_dW.mjs → createAggregationRouter-KrQDzx-k.mjs} +10 -22
  48. package/dist/{createApp-Du5G54TM.mjs → createApp-Df89BEni.mjs} +505 -209
  49. package/dist/defineAggregation-DbPPS8RI.mjs +48 -0
  50. package/dist/{defineResource-2zvVVpxg.mjs → defineResource-Bv6EtN1x.mjs} +90 -72
  51. package/dist/discovery/index.d.mts +1 -0
  52. package/dist/discovery/index.mjs +1 -0
  53. package/dist/docs/index.d.mts +3 -2
  54. package/dist/docs/index.mjs +3 -2
  55. package/dist/{elevation-C9s5hFP_.d.mts → elevation-BXCfVcNG.d.mts} +1 -0
  56. package/dist/{elevation-CIz1GjGm.mjs → elevation-D2l1mh4g.mjs} +4 -3
  57. package/dist/encryption/index.d.mts +2 -1
  58. package/dist/encryption/index.mjs +3 -2
  59. package/dist/{errorHandler-Bq2OeEQL.mjs → errorHandler-C5NeD6bT.mjs} +3 -2
  60. package/dist/{errorHandler-C6yv4ZTW.d.mts → errorHandler-CpYUJmPA.d.mts} +1 -0
  61. package/dist/{errors-DHcHVAgk.d.mts → errors-BGdVwP25.d.mts} +1 -0
  62. package/dist/{errors-DkO8Nk6-.mjs → errors-Cj42AntO.mjs} +1 -0
  63. package/dist/{eventPlugin-DrQ_FesK.mjs → eventPlugin-CkffEihm.mjs} +6 -106
  64. package/dist/{eventPlugin-Bg3cP2_u.d.mts → eventPlugin-GF5nnBIq.d.mts} +2 -1
  65. package/dist/events/index.d.mts +4 -3
  66. package/dist/events/index.mjs +17 -340
  67. package/dist/events/transports/redis-stream-entry.d.mts +2 -1
  68. package/dist/events/transports/redis-stream-entry.mjs +1 -0
  69. package/dist/events/transports/redis.d.mts +2 -1
  70. package/dist/events/transports/redis.mjs +1 -0
  71. package/dist/{externalPaths-BE6wFpYv.d.mts → externalPaths-CmGOxOtD.d.mts} +1 -0
  72. package/dist/factory/index.d.mts +9 -5
  73. package/dist/factory/index.mjs +7 -6
  74. package/dist/{fastify-augmentation-OzYGIiU1.d.mts → fastify-augmentation-zh0_AYHa.d.mts} +13 -4
  75. package/dist/{applyPermissionResult-BnyVE9eD.mjs → fields-CB5Cuzk9.mjs} +2 -107
  76. package/dist/{fields-D3lhgzhD.d.mts → fields-I_EeRWND.d.mts} +1 -0
  77. package/dist/{generate-BnsL9GBm.d.mts → generate-DCGuEbqI.d.mts} +1 -0
  78. package/dist/{generate-D0wZupBg.mjs → generate-EcA6ui4i.mjs} +2 -1
  79. package/dist/{headers-BvlQSDMB.mjs → headers-3zvE0rM3.mjs} +2 -1
  80. package/dist/{health-CB_m4S32.mjs → health-DjZYjM7H.mjs} +1 -0
  81. package/dist/hooks/index.d.mts +2 -1
  82. package/dist/hooks/index.mjs +2 -1
  83. package/dist/idempotency/index.d.mts +3 -2
  84. package/dist/idempotency/index.mjs +5 -4
  85. package/dist/idempotency/redis.d.mts +2 -1
  86. package/dist/idempotency/redis.mjs +1 -0
  87. package/dist/{index-CjVg-Epg.d.mts → index-Bc2ox8_U.d.mts} +6 -5
  88. package/dist/{index-CG4yqMDB.d.mts → index-C-481Zf2.d.mts} +74 -18
  89. package/dist/{index-BMnbzvtO.d.mts → index-CEJNZFtX.d.mts} +242 -24
  90. package/dist/index-CFThn1K9.d.mts +224 -0
  91. package/dist/{index-DPRH0Cme.d.mts → index-CpzxqePp.d.mts} +203 -97
  92. package/dist/index.d.mts +9 -8
  93. package/dist/index.mjs +11 -9
  94. package/dist/{init-tlRSt667.mjs → init-BEiNZBsJ.mjs} +19 -23
  95. package/dist/{init-BPEu8cs-.d.mts → init-Cscs4lab.d.mts} +1 -0
  96. package/dist/integrations/event-gateway.d.mts +3 -2
  97. package/dist/integrations/event-gateway.mjs +2 -1
  98. package/dist/integrations/index.d.mts +4 -3
  99. package/dist/integrations/index.mjs +1 -0
  100. package/dist/integrations/jobs/index.d.mts +2 -1
  101. package/dist/integrations/jobs/index.mjs +108 -32
  102. package/dist/integrations/mcp/index.d.mts +9 -9
  103. package/dist/integrations/mcp/index.mjs +2 -1
  104. package/dist/integrations/mcp/testing.d.mts +3 -2
  105. package/dist/integrations/mcp/testing.mjs +2 -2
  106. package/dist/integrations/streamline.d.mts +1 -0
  107. package/dist/integrations/streamline.mjs +3 -2
  108. package/dist/integrations/webhooks.d.mts +1 -0
  109. package/dist/integrations/webhooks.mjs +1 -0
  110. package/dist/integrations/websocket-pushref-redis.d.mts +2 -1
  111. package/dist/integrations/websocket-pushref-redis.mjs +1 -0
  112. package/dist/integrations/websocket-redis.d.mts +2 -1
  113. package/dist/integrations/websocket-redis.mjs +1 -0
  114. package/dist/integrations/websocket.d.mts +3 -2
  115. package/dist/integrations/websocket.mjs +1 -0
  116. package/dist/{interface-BGZCzOGL.d.mts → interface-BOk3YnTz.d.mts} +1 -0
  117. package/dist/{interface-Uk8ONJv7.d.mts → interface-DEWNOMza.d.mts} +1 -0
  118. package/dist/{interface-n5hpKg1d.mjs → interface-DYzM0q-u.mjs} +1 -0
  119. package/dist/{jsonBody-BlzAoGCe.mjs → jsonBody-BYbLDi5D.mjs} +2 -1
  120. package/dist/{keys-Cd316u_y.mjs → keys-C0_pa1tY.mjs} +1 -0
  121. package/dist/{loadResources-DpU8pfjV.mjs → loadResources-yawi9tAE.mjs} +2 -1
  122. package/dist/{loadResourcesFromEntry-kvGT6EcO.mjs → loadResourcesFromEntry-BAjYZonx.mjs} +2 -1
  123. package/dist/logger/index.d.mts +1 -0
  124. package/dist/logger/index.mjs +1 -0
  125. package/dist/{mcpPlugin-Cs6nRGCt.mjs → mcpPlugin-B_es0hiF.mjs} +52 -60
  126. package/dist/{memory-CmnzXE5Z.mjs → memory-DR6wpa9F.mjs} +2 -1
  127. package/dist/{metrics-fdxI5mn_.mjs → metrics-CUdw_wLB.mjs} +2 -1
  128. package/dist/middleware/index.d.mts +2 -1
  129. package/dist/middleware/index.mjs +3 -2
  130. package/dist/migrations/index.d.mts +1 -3
  131. package/dist/migrations/index.mjs +2 -4
  132. package/dist/module-0pFJA6YW.mjs +78 -0
  133. package/dist/{multipartBody-D0eBvkeq.mjs → multipartBody-wOgj_fnj.mjs} +1 -0
  134. package/dist/{openapi-BLV4OMXb.mjs → openapi-B2L4js1v.mjs} +6 -5
  135. package/dist/permissions/index.d.mts +5 -4
  136. package/dist/permissions/index.mjs +6 -4
  137. package/dist/{permissions-BrtiBKGs.mjs → permissions-L--QDAir.mjs} +518 -316
  138. package/dist/{pipe-BOLmGIxa.mjs → pipe-DRDNsI2T.mjs} +2 -1
  139. package/dist/pipeline/index.d.mts +2 -1
  140. package/dist/pipeline/index.mjs +2 -1
  141. package/dist/{pipeline-BGRnV-To.mjs → pipeline-UPQFatit.mjs} +7 -20
  142. package/dist/plugins/index.d.mts +8 -7
  143. package/dist/plugins/index.mjs +16 -15
  144. package/dist/plugins/response-cache.d.mts +1 -0
  145. package/dist/plugins/response-cache.mjs +2 -1
  146. package/dist/plugins/tracing-entry.d.mts +2 -1
  147. package/dist/plugins/tracing-entry.mjs +2 -1
  148. package/dist/{pluralize-BhrgwZb9.mjs → pluralize-O0FZgESl.mjs} +1 -0
  149. package/dist/{preloadResources-CM4uUaFv.d.mts → preloadResources-CyoJMSiO.d.mts} +117 -12
  150. package/dist/{preloadResources-DSY5HGpS.mjs → preloadResources-Dz6BjzM6.mjs} +1 -0
  151. package/dist/presets/filesUpload.d.mts +6 -5
  152. package/dist/presets/filesUpload.mjs +9 -11
  153. package/dist/presets/index.d.mts +15 -2
  154. package/dist/presets/index.mjs +2 -1
  155. package/dist/presets/multiTenant.d.mts +2 -1
  156. package/dist/presets/multiTenant.mjs +3 -2
  157. package/dist/presets/search.d.mts +3 -2
  158. package/dist/presets/search.mjs +2 -1
  159. package/dist/{presets-DwFDVKP0.mjs → presets-C4-g4_4P.mjs} +27 -10
  160. package/dist/projection-BHw6xlOQ.mjs +18 -0
  161. package/dist/{pushref-registry-BbcnpNTm.d.mts → pushref-registry-Dov9l4qE.d.mts} +1 -0
  162. package/dist/{queryCachePlugin-DSGuSVLW.mjs → queryCachePlugin-BZr8v46E.mjs} +5 -4
  163. package/dist/{queryCachePlugin-br4otiqF.d.mts → queryCachePlugin-BzqxconG.d.mts} +3 -2
  164. package/dist/{rateLimit-DrED-C4v.mjs → rateLimit-CMPY5Qms.mjs} +7 -3
  165. package/dist/{rateLimitKey-BoWRH3e7.mjs → rateLimitKey-Dn5JNmkj.mjs} +1 -0
  166. package/dist/{realtime-DEuDu9io.mjs → realtime-C5NoxWFY.mjs} +20 -8
  167. package/dist/{redis-UDtLaNj6.d.mts → redis-CduhKsJi.d.mts} +2 -1
  168. package/dist/{redis-stream-uIaauNpZ.d.mts → redis-stream-qN6A-RFv.d.mts} +2 -1
  169. package/dist/{registerRoute-DTp18Ah_.mjs → registerRoute-CBN84fc7.mjs} +5 -2
  170. package/dist/registry/index.d.mts +3 -2
  171. package/dist/registry/index.mjs +3 -2
  172. package/dist/{registry-9km_w1aP.mjs → registry-4213U4zb.mjs} +3 -2
  173. package/dist/{renewingLease-3cuQH7h8.mjs → renewingLease-Dll8mGgc.mjs} +1 -0
  174. package/dist/{replyHelpers-67tRawQZ.mjs → replyHelpers-DIiZKGUt.mjs} +2 -1
  175. package/dist/repositoryFilter-f9eAfq_l.mjs +45 -0
  176. package/dist/{requestContext-MrlJwECf.mjs → requestContext-2TxXOJ7T.mjs} +1 -0
  177. package/dist/{rolldown-runtime-8H4AJuhK.mjs → rolldown-runtime-CUsjNX9R.mjs} +1 -0
  178. package/dist/{schedules-CjOd2MG9.mjs → schedules-DdtlICTf.mjs} +3 -2
  179. package/dist/{schemaConverter-DJvodiHj.mjs → schemaConverter-D--wdJM-.mjs} +70 -17
  180. package/dist/{schemaIR-Ca7ySNPx.mjs → schemaIR-Bm2enbnh.mjs} +2 -1
  181. package/dist/schemas/index.d.mts +1 -0
  182. package/dist/schemas/index.mjs +1 -0
  183. package/dist/scim/index.d.mts +1 -0
  184. package/dist/scim/index.mjs +2 -1
  185. package/dist/scope/index.d.mts +3 -2
  186. package/dist/scope/index.mjs +5 -4
  187. package/dist/{scope-DfaPntpo.mjs → scope-DHx5Fous.mjs} +4 -3
  188. package/dist/{sessionManager-BHOM3N_0.d.mts → sessionManager-qimlKV0P.d.mts} +1 -0
  189. package/dist/{simpleEqualityMatcher-Cg05HPsn.mjs → simpleEqualityMatcher-DjQJ7FKA.mjs} +1 -0
  190. package/dist/{sse-BQ1w0dfl.mjs → sse-CUTo9y0X.mjs} +5 -4
  191. package/dist/{sseStream-BQ7Qaynp.mjs → sseStream-B_5XcVVd.mjs} +2 -1
  192. package/dist/{storage-DLUZ04kK.d.mts → storage-Cx9Sz3Ou.d.mts} +1 -0
  193. package/dist/{store-helpers-DY6xq4sM.mjs → store-helpers-D1MP_gRG.mjs} +1 -0
  194. package/dist/{streaming-BQcW6_Kq.mjs → streaming-PSZwi8JV.mjs} +1 -0
  195. package/dist/subscribe-helpers-C0Tb2aUp.mjs +340 -0
  196. package/dist/sync/changelog.d.mts +1 -0
  197. package/dist/sync/changelog.mjs +1 -0
  198. package/dist/testing/cleanupStoreContract.d.mts +2 -1
  199. package/dist/testing/cleanupStoreContract.mjs +1 -0
  200. package/dist/testing/index.d.mts +167 -12
  201. package/dist/testing/index.mjs +522 -205
  202. package/dist/testing/outboxStoreContract.d.mts +1 -0
  203. package/dist/testing/outboxStoreContract.mjs +1 -0
  204. package/dist/testing/storageContract.d.mts +2 -1
  205. package/dist/testing/storageContract.mjs +1 -0
  206. package/dist/{tracing-CsGKQJGg.d.mts → tracing-Dro5eH6j.d.mts} +1 -0
  207. package/dist/{transactionContext-PNdoyLLm.mjs → transactionContext-dAfBVUrk.mjs} +1 -0
  208. package/dist/{typeGuards-C9KXUly6.mjs → typeGuards-B0ryPo3I.mjs} +1 -0
  209. package/dist/types/index.d.mts +6 -5
  210. package/dist/types/index.mjs +1 -0
  211. package/dist/types/storage.d.mts +2 -1
  212. package/dist/types/storage.mjs +1 -0
  213. package/dist/{types-Dmw-6Qeo.d.mts → types-B7XeLEgK.d.mts} +127 -90
  214. package/dist/{types-Cc91nXuA.d.mts → types-ByHn9rEO.d.mts} +1 -0
  215. package/dist/{types-C_ZZRcD6.d.mts → types-C4QE8qnm.d.mts} +1 -0
  216. package/dist/{types-Cu6vVJmh.d.mts → types-CBgvkp8O.d.mts} +82 -12
  217. package/dist/{types-DjC-KUCz.d.mts → types-ChuShpCP.d.mts} +1 -0
  218. package/dist/{types-QFGc3Cjv.d.mts → types-CwcUQ610.d.mts} +2 -6
  219. package/dist/{types-CSyCxl2V.mjs → types-Cys0ko9Z.mjs} +4 -3
  220. package/dist/usage/index.d.mts +3 -2
  221. package/dist/usage/index.mjs +0 -0
  222. package/dist/{userHelpers-Cg_y3fBz.mjs → userHelpers-ChYJ6CdK.mjs} +1 -0
  223. package/dist/utils/index.d.mts +16 -10
  224. package/dist/utils/index.mjs +10 -9
  225. package/dist/{utils-taUVD4p3.mjs → utils-vL8BrDE2.mjs} +3 -2
  226. package/dist/{validate-Bk44F2yT.mjs → validate-_KbifpHF.mjs} +2 -1
  227. package/dist/{versioning-gKWyryT3.mjs → versioning-CHDTor3P.mjs} +3 -2
  228. package/dist/{versioning-DXgY5BUm.d.mts → versioning-D_rhHfZm.d.mts} +5 -2
  229. package/dist/{websocket-_Pd0CgR0.d.mts → websocket-BOXVggMf.d.mts} +2 -1
  230. package/package.json +15 -7
  231. package/skills/arc/SKILL.md +22 -8
  232. package/skills/arc/references/api-reference.md +4 -0
  233. package/skills/arc/references/auth.md +3 -0
  234. package/skills/arc/references/integrations.md +33 -0
  235. package/skills/arc/references/mcp.md +6 -7
  236. package/skills/arc/references/production.md +24 -25
  237. package/skills/arc-code-review/references/anti-patterns.md +3 -3
  238. package/dist/index-CZY4EGga.d.mts +0 -107
  239. package/dist/module-_-M7C5ES.mjs +0 -29
@@ -0,0 +1,48 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ //#region src/core/aggregation/defineAggregation.ts
3
+ /**
4
+ * Declare a single resource aggregation. Exported configs flow into
5
+ * `defineResource({ aggregations: { ... } })` either as named keys or
6
+ * via auto-discovery patterns (loadAggregations — future).
7
+ *
8
+ * @example Inline
9
+ * ```ts
10
+ * defineResource({
11
+ * name: 'order',
12
+ * aggregations: {
13
+ * revenueByStatus: defineAggregation({
14
+ * groupBy: 'status',
15
+ * measures: { count: 'count', revenue: 'sum:totalPrice' },
16
+ * permissions: requireRoles(['admin']),
17
+ * }),
18
+ * },
19
+ * });
20
+ * ```
21
+ *
22
+ * @example Multi-file
23
+ * ```ts
24
+ * // orders/aggregations/revenue-by-status.ts
25
+ * import { defineAggregation } from '@classytic/arc';
26
+ *
27
+ * export const revenueByStatus = defineAggregation({
28
+ * groupBy: 'status',
29
+ * measures: { count: 'count', revenue: 'sum:totalPrice' },
30
+ * permissions: requireRoles(['admin']),
31
+ * timeout: 5000,
32
+ * cache: { staleTime: 60 },
33
+ * });
34
+ *
35
+ * // orders/order.resource.ts
36
+ * import * as aggregations from './aggregations/index.js';
37
+ *
38
+ * defineResource({
39
+ * name: 'order',
40
+ * aggregations, // 30+ entries flow in
41
+ * });
42
+ * ```
43
+ */
44
+ function defineAggregation(config) {
45
+ return config;
46
+ }
47
+ //#endregion
48
+ export { defineAggregation as t };
@@ -1,21 +1,22 @@
1
- import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-DNre0wRg.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-D3Dv4LAV.mjs";
2
3
  import { arcLog } from "./logger/index.mjs";
3
- import { r as ForbiddenError } from "./errors-DkO8Nk6-.mjs";
4
- import { n as getUserRoles } from "./userHelpers-Cg_y3fBz.mjs";
5
- import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-CSyCxl2V.mjs";
6
- import { d as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController } from "./BaseController-B65zbz9m.mjs";
7
- import { a as buildRouteHooks, c as buildAuthMiddleware, i as selectPluginMw, n as buildRouteConfig, o as resolveRoutePreHandlers, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-DrED-C4v.mjs";
8
- import { a as applyFieldWritePermissions, s as resolveEffectiveRoles } from "./applyPermissionResult-BnyVE9eD.mjs";
9
- import { r as buildCrudPermissionMw, t as tryRegisterRoute } from "./registerRoute-DTp18Ah_.mjs";
10
- import { c as getDefaultCrudSchemas } from "./utils-taUVD4p3.mjs";
11
- import { n as convertRouteSchema, r as ensureSchemaConverter, t as convertOpenApiSchemas } from "./schemaConverter-DJvodiHj.mjs";
12
- import { i as pipeUIMessageStreamToReply, r as isReadableStream } from "./streaming-BQcW6_Kq.mjs";
13
- import { t as hasEvents } from "./typeGuards-C9KXUly6.mjs";
14
- import { a as createFastifyHandler, i as createCrudHandlers, n as buildPipelineHandler, o as createRequestContext, r as resolvePipelineSteps, u as buildRequestScopeProjection } from "./pipeline-BGRnV-To.mjs";
15
- import { A as requireAuth } from "./permissions-BrtiBKGs.mjs";
16
- import { r as getAvailablePresets, t as applyPresets } from "./presets-DwFDVKP0.mjs";
17
- import { t as pluralize } from "./pluralize-BhrgwZb9.mjs";
18
- import { t as resolveActionPermission } from "./actionPermissions-CAphcmUG.mjs";
4
+ import { r as ForbiddenError } from "./errors-Cj42AntO.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-ChYJ6CdK.mjs";
6
+ import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-Cys0ko9Z.mjs";
7
+ import { d as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController } from "./BaseController-De7GqHck.mjs";
8
+ import { a as buildRouteHooks, c as buildAuthMiddleware, i as selectPluginMw, n as buildRouteConfig, o as resolveRoutePreHandlers, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-CMPY5Qms.mjs";
9
+ import { i as resolveEffectiveRoles, n as applyFieldWritePermissions } from "./fields-CB5Cuzk9.mjs";
10
+ import { r as buildCrudPermissionMw, t as tryRegisterRoute } from "./registerRoute-CBN84fc7.mjs";
11
+ import { c as getDefaultCrudSchemas } from "./utils-vL8BrDE2.mjs";
12
+ import { n as convertRouteSchema, r as ensureSchemaConverter, t as convertOpenApiSchemas } from "./schemaConverter-D--wdJM-.mjs";
13
+ import { i as pipeUIMessageStreamToReply, r as isReadableStream } from "./streaming-PSZwi8JV.mjs";
14
+ import { t as hasEvents } from "./typeGuards-B0ryPo3I.mjs";
15
+ import { a as createFastifyHandler, i as createCrudHandlers, n as buildPipelineHandler, o as createRequestContext, r as resolvePipelineSteps } from "./pipeline-UPQFatit.mjs";
16
+ import { I as requireAuth } from "./permissions-L--QDAir.mjs";
17
+ import { r as getAvailablePresets, t as applyPresets } from "./presets-C4-g4_4P.mjs";
18
+ import { t as pluralize } from "./pluralize-O0FZgESl.mjs";
19
+ import { t as resolveActionPermission } from "./actionPermissions-BE5NwaQk.mjs";
19
20
  //#region src/core/middlewares/fieldWrite.ts
20
21
  /**
21
22
  * Build a preHandler that enforces field-write permissions on the request body.
@@ -58,25 +59,30 @@ function methodCarriesBody(method) {
58
59
  //#region src/core/createCrudRouter.ts
59
60
  /**
60
61
  * Mount custom routes (from presets or user-defined `routes`) on Fastify.
61
- * `wrapHandler` is derived inline from `!route.raw`.
62
+ * `wrapHandler` is derived inline from whether `rawHandler` was set.
62
63
  */
63
64
  function createCustomRoutes(fastify, routes, controller, options) {
64
65
  const { tag, resourceName, arcDecorator, rateLimitConfig, pluginMw, pipeline, routeGuards, tenantScopeMw, fieldPermissions, onFieldWriteDenied, extensions } = options;
65
66
  for (const route of routes) {
67
+ if ("raw" in route) throw new Error(`Route ${route.method} ${route.path}: \`raw\` was removed in arc 2.31 — the FIELD now carries the intent. Move the function to \`rawHandler\` (Fastify-native \`(request, reply)\`) or leave it in \`handler\` (arc pipeline, \`(ctx)\`), and delete the flag. If this route comes from a dependency, that package needs a release built against arc >=2.31.`);
66
68
  const routeWithRefs = route;
67
- const hasHandler = route.handler !== void 0;
69
+ const hasHandler = route.handler !== void 0 || route.rawHandler !== void 0;
68
70
  const hasControllerMethod = typeof routeWithRefs.controllerMethod === "function";
69
71
  if (hasHandler && hasControllerMethod) throw new Error(`Route ${route.method} ${route.path}: pass either \`handler\` or \`controllerMethod\`, not both. Prefer \`controllerMethod: (c: MyController) => c.method\` for typed handler refs (TS catches typos).`);
70
- if (!hasHandler && !hasControllerMethod) throw new Error(`Route ${route.method} ${route.path}: must declare either \`handler\` (string / function) or \`controllerMethod: (c) => c.method\` (typed function-ref form).`);
72
+ if (!hasHandler && !hasControllerMethod) throw new Error(`Route ${route.method} ${route.path}: must declare one of \`handler\` (arc pipeline), \`rawHandler\` (Fastify-native), or \`controllerMethod: (c) => c.method\` (typed function-ref form).`);
71
73
  let resolvedHandler;
72
74
  if (hasControllerMethod) {
73
75
  if (!controller) throw new Error(`Route ${route.method} ${route.path}: \`controllerMethod\` requires a controller. Provide one via \`defineResource({ controller, … })\`, or use \`defineResource\` with an \`adapter\` so arc auto-creates a BaseController.`);
74
76
  const referenced = routeWithRefs.controllerMethod?.(controller);
75
77
  if (typeof referenced !== "function") throw new Error(`Route ${route.method} ${route.path}: \`controllerMethod\` did not return a function. Return the method itself: \`controllerMethod: (c) => c.myMethod\`.`);
76
78
  resolvedHandler = referenced.bind(controller);
77
- } else resolvedHandler = route.handler;
79
+ } else {
80
+ if (route.rawHandler && route.handler) throw new Error(`Route ${route.method} ${route.path}: set either \`handler\` (arc pipeline) or \`rawHandler\` (Fastify-native), not both.`);
81
+ resolvedHandler = route.rawHandler ?? route.handler;
82
+ }
78
83
  const opName = route.operation ?? (typeof resolvedHandler === "string" ? resolvedHandler : `${route.method.toLowerCase()}${route.path.replace(/[/:]/g, "_")}`);
79
- const wrapHandler = !route.raw;
84
+ const isRaw = route.rawHandler !== void 0;
85
+ const wrapHandler = !isRaw;
80
86
  let handler;
81
87
  if (typeof resolvedHandler === "string") {
82
88
  if (!controller) throw new Error(`Route ${route.method} ${route.path}: string handler '${resolvedHandler}' requires a controller. Either provide a controller or use a function handler instead.`);
@@ -104,7 +110,7 @@ function createCustomRoutes(fastify, routes, controller, options) {
104
110
  if (!tenantScopeMw || tenantScopeMw.length === 0) throw new Error(`Route ${route.method} ${route.path}: \`tenantScope: true\` requires a multi-tenant preset. Add \`multiTenantPreset()\` (or \`flexibleMultiTenantPreset()\`) to the resource's \`presets\`, or remove the \`tenantScope\` flag from this route.`);
105
111
  customPreHandlers.unshift(...tenantScopeMw);
106
112
  }
107
- if (route.raw !== true && route.fieldWrite !== false && methodCarriesBody(route.method)) {
113
+ if (!isRaw && route.fieldWrite !== false && methodCarriesBody(route.method)) {
108
114
  const fieldWriteMw = buildFieldWritePreHandler(fieldPermissions, onFieldWriteDenied);
109
115
  if (fieldWriteMw) customPreHandlers.push(fieldWriteMw);
110
116
  }
@@ -123,18 +129,18 @@ function createCustomRoutes(fastify, routes, controller, options) {
123
129
  url: route.path,
124
130
  schema,
125
131
  ...routeHookOptions(hooks),
126
- handler: isStream ? async (request, reply) => {
132
+ handler: isStream ? async function streamRoute(request, reply) {
127
133
  reply.raw.setHeader("Content-Type", "text/event-stream");
128
134
  reply.raw.setHeader("Cache-Control", "no-cache");
129
135
  reply.raw.setHeader("Connection", "keep-alive");
130
- const result = await handler(request, reply);
136
+ const result = await handler.call(this, request, reply);
131
137
  if (isReadableStream(result)) {
132
138
  await pipeUIMessageStreamToReply(reply, result);
133
139
  return reply;
134
140
  }
135
141
  return result;
136
142
  } : handler,
137
- ...buildRouteConfig(route.rateLimit !== void 0 ? buildRateLimitConfig(route.rateLimit) : rateLimitConfig, extensions)
143
+ ...buildRouteConfig(route.rateLimit !== void 0 ? buildRateLimitConfig(route.rateLimit) : rateLimitConfig, extensions, route.cors)
138
144
  }, {
139
145
  resourceName,
140
146
  op: opName
@@ -462,26 +468,6 @@ function buildBaseController(resolvedConfig, adapter, repository) {
462
468
  //#endregion
463
469
  //#region src/core/defineResource/hooks.ts
464
470
  /**
465
- * Phase 6 — wire preset hooks + inline `config.hooks` onto the
466
- * resource's `_pendingHooks`.
467
- *
468
- * Two sources feed the same array:
469
- * 1. Preset hooks collected during `applyPresets()` (raw `_hooks`
470
- * on the internal config). Already in the canonical
471
- * `{ operation, phase, handler, priority }` shape — copied
472
- * verbatim (priority defaults to 10).
473
- * 2. Inline `config.hooks.beforeCreate` / `afterCreate` / etc.
474
- * Authored by the user on the original `ResourceConfig`.
475
- * Wrapped in a `ResourceHookContext` projection (v2.10.8) so
476
- * authors can read `scope` / `context` without reaching into
477
- * internal request fields.
478
- *
479
- * The 6 inline hook keys (before/after × create/update/delete) used
480
- * to be 6 nearly-identical blocks; collapsed into a table + loop so
481
- * a future hook (e.g. `beforeRead`) is one row, not seven scattered
482
- * edits.
483
- */
484
- /**
485
471
  * Combined entry-point for Phase 6. Pushes preset-collected hooks
486
472
  * first, then inline `config.hooks` (so hosts can rely on
487
473
  * registration order if priorities tie).
@@ -544,19 +530,17 @@ const INLINE_HOOK_SPECS = [
544
530
  }
545
531
  ];
546
532
  /**
547
- * Project a raw HookSystem context into a `ResourceHookContext` for
548
- * inline `config.hooks.*` handlers. The projection lifts `scope`
549
- * out of `context._scope` so authors don't reach into internal
550
- * fields.
533
+ * Project a raw HookSystem context into a `ResourceHookContext` for inline
534
+ * `config.hooks.*` handlers. `scope` rides in already computed — `HookContext`
535
+ * carries the same projection — so the two surfaces cannot drift.
551
536
  */
552
537
  function buildHookContext(ctx) {
553
538
  const context = ctx.context;
554
- const rawScope = context?._scope;
555
539
  return {
556
540
  data: ctx.data ?? ctx.result ?? {},
557
541
  user: ctx.user,
558
542
  context,
559
- scope: buildRequestScopeProjection(rawScope),
543
+ scope: ctx.scope,
560
544
  meta: ctx.meta
561
545
  };
562
546
  }
@@ -662,8 +646,7 @@ function expandHistory(config) {
662
646
  method: "GET",
663
647
  path: "/:id/history",
664
648
  summary: `Change history for a ${resourceName} record (audit-backed timeline)`,
665
- raw: true,
666
- handler: async (request, reply) => {
649
+ rawHandler: async (request, reply) => {
667
650
  const audit = request.server.audit;
668
651
  if (!audit?.query || audit._noop === true) return reply.code(503).send({
669
652
  code: "history.audit_unavailable",
@@ -802,7 +785,7 @@ function stripFromRequired(schema, fieldName) {
802
785
  }
803
786
  /**
804
787
  * Strip framework-injected fields from the `required[]` list of every
805
- * body-shaped slot in an adapter's generated schemas (v2.11.0).
788
+ * body-shaped slot in an adapter's generated schemas.
806
789
  *
807
790
  * A "framework-injected field" is any field marked `systemManaged: true`
808
791
  * in `schemaOptions.fieldRules`. Arc populates those fields from the
@@ -957,22 +940,32 @@ const WRITE_OPERATIONS = /* @__PURE__ */ new Set([
957
940
  * wiring, ...) count as gates and don't false-positive.
958
941
  *
959
942
  * Severity ladder:
960
- * - `warn` when any enabled WRITE op (create/update/delete) is ungated —
961
- * this is real exposure the host must acknowledge.
943
+ * - `error` when any enabled WRITE op is ungated AND `strict` is on — the
944
+ * resource fails boot (`defineResource()` throws). This is the fail-closed
945
+ * production invariant: an unauthenticated write must never ship silently.
946
+ * - `warn` (default) when any enabled WRITE op (create/update/delete) is
947
+ * ungated — real exposure the host must acknowledge, but non-fatal so
948
+ * existing hosts are not broken.
962
949
  * - `info` when only reads are ungated — public catalogs
963
950
  * (`referenceData: true`) are a legitimate shape, but the host should
964
951
  * still state intent with `permissions.fullPublic()` / `allowPublic()`.
952
+ *
953
+ * `strict` is opt-in (resource `strictPermissions: true` or the
954
+ * `ARC_STRICT_PERMISSIONS` env), so the default behavior is unchanged.
965
955
  */
966
- function collectUngatedCrudDiagnostics(config) {
956
+ function collectUngatedCrudDiagnostics(config, strict = false) {
967
957
  if (config.disableDefaultRoutes) return [];
968
958
  const disabled = new Set(config.disabledRoutes ?? []);
969
959
  const permissions = config.permissions ?? {};
970
960
  const ungated = CRUD_OPERATIONS.filter((op) => !disabled.has(op) && typeof permissions[op] !== "function");
971
961
  if (ungated.length === 0) return [];
962
+ const severity = ungated.some((op) => WRITE_OPERATIONS.has(op)) ? strict ? "error" : "warn" : "info";
972
963
  return [{
973
- severity: ungated.some((op) => WRITE_OPERATIONS.has(op)) ? "warn" : "info",
964
+ severity,
974
965
  code: "crud-public-by-omission",
975
- message: `[Arc] Resource '${config.name}' mounts ${ungated.length} CRUD route(s) with no permission gate: ${ungated.join(", ")}.\nAn omitted permission mounts the route WITHOUT auth. State intent explicitly:\n permissions: permissions.fullPublic() // intentionally public\n permissions: permissions.authenticated() // require auth on every op\n permissions: { ${ungated[0]}: requireAuth(), ... } // per-operation`
966
+ message: `[Arc] Resource '${config.name}' mounts ${ungated.length} CRUD route(s) with no permission gate: ${ungated.join(", ")}.\n` + (severity === "error" ? "strictPermissions is on and an ungated WRITE is fatal. State intent explicitly:\n" : "An omitted permission mounts the route WITHOUT auth. State intent explicitly:\n") + ` permissions: permissions.fullPublic() // intentionally public
967
+ permissions: permissions.authenticated() // require auth on every op
968
+ permissions: { ${ungated[0]}: requireAuth(), ... } // per-operation`
976
969
  }];
977
970
  }
978
971
  //#endregion
@@ -1217,7 +1210,7 @@ function buildResourcePlugin(resource) {
1217
1210
  const isFirstMount = !resource._sharedStateRegisteredOn.has(sharedRoot);
1218
1211
  if (isFirstMount) resource._sharedStateRegisteredOn.add(sharedRoot);
1219
1212
  if (isFirstMount && resource._diagnostics?.length) for (const diagnostic of resource._diagnostics) {
1220
- const level = diagnostic.severity === "info" ? "info" : "warn";
1213
+ const level = diagnostic.severity === "info" ? "info" : diagnostic.severity === "error" ? "error" : "warn";
1221
1214
  fastify.log?.[level]?.(diagnostic.message);
1222
1215
  }
1223
1216
  const arc = fastify.arc;
@@ -1278,7 +1271,7 @@ function buildResourcePlugin(resource) {
1278
1271
  extensions: resource.extensions
1279
1272
  });
1280
1273
  if (resource.actions && Object.keys(resource.actions).length > 0) {
1281
- const { createActionRouter } = await import("./createActionRouter-C-N7z2EL.mjs").then((n) => n.n);
1274
+ const { createActionRouter } = await import("./createActionRouter-CDXEdasl.mjs").then((n) => n.n);
1282
1275
  createActionRouter(typedInstance, {
1283
1276
  ...normalizeActionsToRouterConfig(resource.actions, resource.actionPermissions, resource.tag, resource.permissions, resource.name, typedInstance.log),
1284
1277
  resourceName: resource.name,
@@ -1293,7 +1286,7 @@ function buildResourcePlugin(resource) {
1293
1286
  });
1294
1287
  }
1295
1288
  if (resource.aggregations && Object.keys(resource.aggregations).length > 0) {
1296
- const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-wzwFa_dW.mjs"), import("./validate-Bk44F2yT.mjs").then((n) => n.r)]);
1289
+ const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-KrQDzx-k.mjs"), import("./validate-_KbifpHF.mjs").then((n) => n.r)]);
1297
1290
  const repoForAgg = resource.controller?.repository ?? resource.repository;
1298
1291
  if (!adapterSupportsAggregate(repoForAgg)) {
1299
1292
  const undispatchable = Object.entries(resource.aggregations).filter(([, cfg]) => !cfg.materialized).map(([name]) => name);
@@ -1549,7 +1542,7 @@ var ResourceDefinition = class {
1549
1542
  summary: r.summary,
1550
1543
  description: r.description,
1551
1544
  permissions: r.permissions,
1552
- raw: r.raw,
1545
+ raw: r.rawHandler !== void 0,
1553
1546
  schema: r.schema
1554
1547
  })),
1555
1548
  routes: [],
@@ -1827,17 +1820,22 @@ function validateResourceConfig(config, options = {}) {
1827
1820
  }
1828
1821
  function validateRouteHandlers(controller, routes, errors) {
1829
1822
  const ctrl = controller;
1830
- for (const route of routes) if (typeof route.handler === "string") {
1831
- if (typeof ctrl[route.handler] !== "function") errors.push({
1823
+ for (const route of routes) {
1824
+ const named = typeof route.handler === "string" ? route.handler : route.rawHandler;
1825
+ if (typeof named !== "string") continue;
1826
+ if (typeof ctrl[named] !== "function") errors.push({
1832
1827
  field: `routes[${route.method} ${route.path}]`,
1833
- message: `Handler "${route.handler}" not found on controller`,
1834
- suggestion: `Add method "${route.handler}" to controller or use a function handler`
1828
+ message: `Handler "${named}" not found on controller`,
1829
+ suggestion: `Add method "${named}" to controller or use a function handler`
1835
1830
  });
1836
1831
  }
1837
1832
  }
1838
1833
  function validatePermissionKeys(config, options, _errors, warnings) {
1839
1834
  const validKeys = /* @__PURE__ */ new Set([...CRUD_OPERATIONS, ...options.additionalPermissionKeys ?? []]);
1840
- for (const route of config.routes ?? []) if (typeof route.handler === "string") validKeys.add(route.handler);
1835
+ for (const route of config.routes ?? []) {
1836
+ if (typeof route.handler === "string") validKeys.add(route.handler);
1837
+ if (typeof route.rawHandler === "string") validKeys.add(route.rawHandler);
1838
+ }
1841
1839
  for (const preset of config.presets ?? []) {
1842
1840
  const presetName = typeof preset === "string" ? preset : preset.name;
1843
1841
  if (presetName === "softDelete") {
@@ -1978,11 +1976,26 @@ function validateRoutes(routes, errors) {
1978
1976
  suggestion: `Change to "/${route.path}"`
1979
1977
  });
1980
1978
  const routeWithRefs = route;
1981
- if (!route.handler && typeof routeWithRefs.controllerMethod !== "function") errors.push({
1979
+ if (!route.handler && !route.rawHandler && typeof routeWithRefs.controllerMethod !== "function") errors.push({
1982
1980
  field: `routes[${i}].handler`,
1983
- message: "Route must declare either `handler` (string / function) or `controllerMethod`",
1981
+ message: "Route must declare one of `handler` (arc pipeline), `rawHandler` (Fastify-native), or `controllerMethod`",
1984
1982
  suggestion: "Prefer `controllerMethod: (c: MyController) => c.method` for typed handler refs."
1985
1983
  });
1984
+ if (route.handler && route.rawHandler) errors.push({
1985
+ field: `routes[${i}].rawHandler`,
1986
+ message: "Route declares BOTH `handler` and `rawHandler`",
1987
+ suggestion: "Use `handler` for the arc pipeline (receives IRequestContext) or `rawHandler` for a Fastify-native handler (receives request, reply) — not both."
1988
+ });
1989
+ if ("raw" in route) errors.push({
1990
+ field: `routes[${i}].raw`,
1991
+ message: "`raw` was removed in arc 2.31 — the field now carries the intent",
1992
+ suggestion: "Move the function to `rawHandler` (Fastify-native) or leave it in `handler` (arc pipeline), and delete the flag. If the route comes from a dependency, that package needs a release built against arc >=2.31."
1993
+ });
1994
+ if (route.streamResponse === true && route.rawHandler === void 0) errors.push({
1995
+ field: `routes[${i}].streamResponse`,
1996
+ message: "`streamResponse: true` requires `rawHandler`",
1997
+ suggestion: "Streaming routes are invoked with `(request, reply)` and own the socket — declare the function as `rawHandler` (not `handler` or `controllerMethod`)."
1998
+ });
1986
1999
  const routeKey = `${route.method} ${route.path}`;
1987
2000
  if (seenRoutes.has(routeKey)) errors.push({
1988
2001
  field: `routes[${i}]`,
@@ -2169,7 +2182,12 @@ function defineResource(config) {
2169
2182
  const configWithId = resolveIdField(normalisedConfig, repository);
2170
2183
  const resolvedConfig = applyPresetsAndAutoInject(configWithId);
2171
2184
  const hasCrudRoutes = computeHasCrudRoutes(resolvedConfig);
2172
- if (!normalisedConfig.skipValidation) diagnostics = diagnostics.concat(collectUngatedCrudDiagnostics(resolvedConfig));
2185
+ if (!normalisedConfig.skipValidation) {
2186
+ const strict = resolvedConfig.strictPermissions ?? process.env.ARC_STRICT_PERMISSIONS === "true";
2187
+ diagnostics = diagnostics.concat(collectUngatedCrudDiagnostics(resolvedConfig, strict));
2188
+ }
2189
+ const fatal = diagnostics.filter((d) => d.severity === "error");
2190
+ if (fatal.length > 0) throw new Error(fatal.map((d) => d.message).join("\n\n"));
2173
2191
  const narrowedConfig = resolvedConfig;
2174
2192
  const narrowedAdapter = configWithId.adapter;
2175
2193
  const controller = resolveOrAutoCreateController(narrowedConfig, narrowedAdapter, repository, hasCrudRoutes);
@@ -1,3 +1,4 @@
1
+
1
2
  import { FastifyPluginAsync } from "fastify";
2
3
  //#region src/discovery/index.d.ts
3
4
  /** A discovered resource — must have toPlugin() method */
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
2
  import { readdir } from "node:fs/promises";
2
3
  import { extname, join, resolve } from "node:path";
3
4
  import { pathToFileURL } from "node:url";
@@ -1,5 +1,6 @@
1
- import { p as RegistryEntry } from "../index-DPRH0Cme.mjs";
2
- import { t as ExternalOpenApiPaths } from "../externalPaths-BE6wFpYv.mjs";
1
+
2
+ import { p as RegistryEntry } from "../index-CpzxqePp.mjs";
3
+ import { t as ExternalOpenApiPaths } from "../externalPaths-CmGOxOtD.mjs";
3
4
  import { FastifyPluginAsync } from "fastify";
4
5
  //#region src/docs/openapi/types.d.ts
5
6
  /**
@@ -1,5 +1,6 @@
1
- import { n as getUserRoles } from "../userHelpers-Cg_y3fBz.mjs";
2
- import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-BLV4OMXb.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { n as getUserRoles } from "../userHelpers-ChYJ6CdK.mjs";
3
+ import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-B2L4js1v.mjs";
3
4
  import fp from "fastify-plugin";
4
5
  //#region src/docs/scalar.ts
5
6
  const scalarPlugin = async (fastify, opts = {}) => {
@@ -1,3 +1,4 @@
1
+
1
2
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
2
3
  //#region src/scope/elevation.d.ts
3
4
  interface ElevationOptions {
@@ -1,7 +1,8 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
2
3
  import { arcLog } from "./logger/index.mjs";
3
- import { n as requireSingleHeaderValue } from "./headers-BvlQSDMB.mjs";
4
- import { n as getUserRoles } from "./userHelpers-Cg_y3fBz.mjs";
4
+ import { n as requireSingleHeaderValue } from "./headers-3zvE0rM3.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-ChYJ6CdK.mjs";
5
6
  import fp from "fastify-plugin";
6
7
  //#region src/scope/elevation.ts
7
8
  var elevation_exports = /* @__PURE__ */ __exportAll({
@@ -1,4 +1,5 @@
1
- import { a as JweAlg, c as KeyMaterial, i as EncryptionOptions, l as KeyProvider, n as EncryptionDirective, o as JweEnc, r as EncryptionMode, s as KeyContext, t as ActiveKey } from "../types-Cc91nXuA.mjs";
1
+
2
+ import { a as JweAlg, c as KeyMaterial, i as EncryptionOptions, l as KeyProvider, n as EncryptionDirective, o as JweEnc, r as EncryptionMode, s as KeyContext, t as ActiveKey } from "../types-ByHn9rEO.mjs";
2
3
  import { FastifyPluginAsync } from "fastify";
3
4
  //#region src/encryption/encryptionPlugin.d.ts
4
5
  declare const encryptionPlugin: FastifyPluginAsync<EncryptionOptions>;
@@ -1,5 +1,6 @@
1
- import { t as ArcError } from "../errors-DkO8Nk6-.mjs";
2
- import { t as parseJsonBody } from "../jsonBody-BlzAoGCe.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as ArcError } from "../errors-Cj42AntO.mjs";
3
+ import { t as parseJsonBody } from "../jsonBody-BYbLDi5D.mjs";
3
4
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
4
5
  import fp from "fastify-plugin";
5
6
  //#region src/encryption/fieldCipher.ts
@@ -1,5 +1,6 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { m as statusToArcCode, p as isArcError } from "./errors-DkO8Nk6-.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
3
+ import { m as statusToArcCode, p as isArcError } from "./errors-Cj42AntO.mjs";
3
4
  import { isHttpError, toErrorContract } from "@classytic/repo-core/errors";
4
5
  import fp from "fastify-plugin";
5
6
  //#region src/plugins/errorHandler.ts
@@ -1,3 +1,4 @@
1
+
1
2
  import { ErrorDetail } from "@classytic/repo-core/errors";
2
3
  import { FastifyInstance, FastifyRequest } from "fastify";
3
4
  //#region src/plugins/errorHandler.d.ts
@@ -1,3 +1,4 @@
1
+
1
2
  import { HttpError } from "@classytic/repo-core/errors";
2
3
  //#region src/utils/errors.d.ts
3
4
  interface ErrorOptions {
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
2
  //#region src/utils/errors.ts
2
3
  /**
3
4
  * Base Arc Error. Implements the canonical `HttpError` contract — `status`
@@ -1,110 +1,10 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
2
3
  import { arcLog } from "./logger/index.mjs";
3
- import { d as createDomainError } from "./errors-DkO8Nk6-.mjs";
4
- import { n as requestContext } from "./requestContext-MrlJwECf.mjs";
4
+ import { d as createDomainError } from "./errors-Cj42AntO.mjs";
5
+ import { n as requestContext } from "./requestContext-2TxXOJ7T.mjs";
6
+ import { n as createEvent, t as MemoryEventTransport } from "./EventTransport-9mlTgqzE.mjs";
5
7
  import fp from "fastify-plugin";
6
- import { createEvent, matchEventPattern } from "@classytic/primitives/events";
7
- //#region src/events/EventTransport.ts
8
- /**
9
- * Internal arc events module — concrete in-memory transport.
10
- *
11
- * **Public type contracts moved out (arc 2.12).** `EventMeta`, `DomainEvent`,
12
- * `EventHandler`, `EventLogger`, `EventTransport`, `DeadLetteredEvent`,
13
- * `PublishManyResult`, plus the `createEvent` / `createChildEvent` /
14
- * `matchEventPattern` helpers, are now owned by `@classytic/primitives/events`.
15
- * Two reasons:
16
- *
17
- * 1. The shapes ARE the cross-package contract. arc, arc-next, mongokit's
18
- * audit-log plugin, future kits and downstream services all share them.
19
- * Owning them in `primitives` (pure types, zero runtime, zero deps)
20
- * eliminates the "manually mirror in two places" problem the previous
21
- * `primitives/src/events.ts` header explicitly called out.
22
- * 2. Inverting the dependency direction lets future packages (sqlitekit
23
- * audit, billing services) consume the contract without depending on
24
- * arc's HTTP-coupled stack.
25
- *
26
- * Hosts MUST import the types from primitives directly:
27
- *
28
- * ```typescript
29
- * import type {
30
- * EventMeta, DomainEvent, EventHandler, EventTransport,
31
- * DeadLetteredEvent, PublishManyResult,
32
- * } from '@classytic/primitives/events';
33
- * import { createEvent, createChildEvent } from '@classytic/primitives/events';
34
- * ```
35
- *
36
- * arc's `events/index.ts` barrel does NOT re-export these — by design, so
37
- * that consumer code is forced into the canonical import path and the org's
38
- * "no re-exports" rule holds at every public surface.
39
- *
40
- * What stays here:
41
- * - `MemoryEventTransport` — the in-memory `EventTransport` implementation
42
- * used as arc's default transport. Its handler-set state is process-local;
43
- * wrong layer for primitives.
44
- * - `MemoryEventTransportOptions` — its options shape.
45
- *
46
- * Inside arc, files that previously imported types from `./EventTransport.js`
47
- * keep working: this file re-exports them from primitives for arc's own
48
- * call sites. That re-export is an internal refactor convenience — the
49
- * public `events/index.ts` barrel stays clean.
50
- */
51
- /**
52
- * In-memory event transport (default).
53
- *
54
- * Events are delivered synchronously within the process. Not suitable for
55
- * multi-instance deployments — pair with `RedisEventTransport` /
56
- * `RedisStreamTransport` (subpath imports) for those.
57
- */
58
- var MemoryEventTransport = class {
59
- name = "memory";
60
- handlers = /* @__PURE__ */ new Map();
61
- logger;
62
- constructor(options) {
63
- this.logger = options?.logger ?? console;
64
- }
65
- async publish(event) {
66
- const allHandlers = /* @__PURE__ */ new Set();
67
- for (const [pattern, handlers] of this.handlers) if (matchEventPattern(pattern, event.type)) for (const h of handlers) allHandlers.add(h);
68
- for (const handler of allHandlers) try {
69
- await handler(event);
70
- } catch (err) {
71
- this.logger.error(`[EventTransport] Handler error for ${event.type}:`, err);
72
- }
73
- }
74
- /**
75
- * Reference `publishMany` implementation — delegates to `publish()` in order.
76
- *
77
- * Production transports (Kafka, Redis pipeline, SQS batch) should override
78
- * this with a single batched network call. Memory transport has nothing to
79
- * batch, so we just loop — the loop still returns a proper result map so
80
- * `EventOutbox.relay` can exercise the batched code path in tests.
81
- */
82
- async publishMany(events) {
83
- const results = /* @__PURE__ */ new Map();
84
- for (const event of events) try {
85
- await this.publish(event);
86
- results.set(event.meta.id, null);
87
- } catch (err) {
88
- results.set(event.meta.id, err instanceof Error ? err : new Error(String(err)));
89
- }
90
- return results;
91
- }
92
- async subscribe(pattern, handler) {
93
- if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
94
- this.handlers.get(pattern)?.add(handler);
95
- return () => {
96
- const set = this.handlers.get(pattern);
97
- if (set) {
98
- set.delete(handler);
99
- if (set.size === 0) this.handlers.delete(pattern);
100
- }
101
- };
102
- }
103
- async close() {
104
- this.handlers.clear();
105
- }
106
- };
107
- //#endregion
108
8
  //#region src/events/retry.ts
109
9
  /**
110
10
  * Wrap an event handler with retry logic and dead letter support.
@@ -338,4 +238,4 @@ var eventPlugin_default = fp(eventPlugin, {
338
238
  fastify: "5.x"
339
239
  });
340
240
  //#endregion
341
- export { MemoryEventTransport as a, withRetry as i, eventPlugin_exports as n, createEvent as o, createDeadLetterPublisher as r, eventPlugin as t };
241
+ export { withRetry as i, eventPlugin_exports as n, createDeadLetterPublisher as r, eventPlugin as t };
@@ -1,4 +1,5 @@
1
- import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-QmY7A258.mjs";
1
+
2
+ import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-2uVV34WU.mjs";
2
3
  import { FastifyPluginAsync } from "fastify";
3
4
  //#region src/events/defineEvent.d.ts
4
5
  interface EventSchema {
@@ -1,7 +1,8 @@
1
- import { a as EventTransport, i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions, t as DeadLetteredEvent } from "../EventTransport-QmY7A258.mjs";
2
- import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-Bg3cP2_u.mjs";
1
+
2
+ import { a as EventTransport, i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions, t as DeadLetteredEvent } from "../EventTransport-2uVV34WU.mjs";
3
+ import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-GF5nnBIq.mjs";
3
4
  import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
4
- import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-uIaauNpZ.mjs";
5
+ import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-qN6A-RFv.mjs";
5
6
  import { OutboxAcknowledgeOptions, OutboxClaimOptions, OutboxErrorInfo, OutboxFailOptions, OutboxFailurePolicy, OutboxStore, OutboxWriteOptions } from "@classytic/primitives/outbox";
6
7
  import { RepositoryLike } from "@classytic/repo-core/adapter";
7
8
  //#region src/events/eventTypes.d.ts