@classytic/arc 2.41.1 → 2.43.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 (230) hide show
  1. package/dist/{EventTransport-CbUKDzZZ.d.mts → EventTransport-CiicKz2Z.d.mts} +1 -1
  2. package/dist/{EventTransport-DSqD_Xsg.mjs → EventTransport-tzA7CAB4.mjs} +22 -17
  3. package/dist/{HookSystem-CMF94SEA.mjs → HookSystem-B6UaKRbF.mjs} +2 -2
  4. package/dist/{QueryCache-DFA-QrU9.d.mts → QueryCache--5uAuYPW.d.mts} +7 -3
  5. package/dist/{ResourceRegistry-MGpXoxHZ.mjs → ResourceRegistry-CuCARu2B.mjs} +44 -13
  6. package/dist/actionPermissions-BotX1YOa.mjs +776 -0
  7. package/dist/audit/index.d.mts +43 -5
  8. package/dist/audit/index.mjs +48 -26
  9. package/dist/auth/audit.mjs +1 -1
  10. package/dist/auth/index.d.mts +43 -13
  11. package/dist/auth/index.mjs +130 -155
  12. package/dist/auth/redis-session.mjs +1 -1
  13. package/dist/{authorizationDecision-DawKGoXb.mjs → authorizationDecision-DQYrkl5f.mjs} +7 -102
  14. package/dist/{base-CxrV1LmG.d.mts → base-CZyixEQR.d.mts} +27 -5
  15. package/dist/boundedMap-BULzfXYU.mjs +57 -0
  16. package/dist/{buildHandler-CvxKOc0m.mjs → buildHandler-CRQ8EcX5.mjs} +4 -4
  17. package/dist/cache/index.d.mts +22 -34
  18. package/dist/cache/index.mjs +4 -4
  19. package/dist/{caching-DbCBxlgw.mjs → caching-Cc2M1DwO.mjs} +3 -3
  20. package/dist/claimed-B10RTfkM.mjs +8 -0
  21. package/dist/cleanup/index.d.mts +6 -10
  22. package/dist/cleanup/index.mjs +27 -73
  23. package/dist/cli/commands/describe.d.mts +4 -2
  24. package/dist/cli/commands/describe.mjs +7 -4
  25. package/dist/cli/commands/docs.mjs +3 -3
  26. package/dist/cli/commands/doctor.mjs +1 -1
  27. package/dist/cli/commands/generate.mjs +2 -2
  28. package/dist/cli/commands/init.mjs +2 -2
  29. package/dist/cli/commands/introspect.mjs +2 -2
  30. package/dist/cli/index.mjs +3 -3
  31. package/dist/{constants-D5Ubn1fe.mjs → constants-Cu7Mx7_U.mjs} +4 -2
  32. package/dist/context/index.d.mts +2 -5
  33. package/dist/context/index.mjs +18 -38
  34. package/dist/core/index.d.mts +3 -3
  35. package/dist/core/index.mjs +8 -8
  36. package/dist/{core-5lazhva9.mjs → core-Cb0LjccA.mjs} +5 -4
  37. package/dist/{createActionRouter-DNqoaK81.mjs → createActionRouter-xjqonMRO.mjs} +87 -39
  38. package/dist/{createAggregationRouter-BcbQJf10.mjs → createAggregationRouter-zRYWw_5D.mjs} +11 -8
  39. package/dist/{preloadResources-f3boenVZ.mjs → createApp-D-953ZAq.mjs} +299 -390
  40. package/dist/{createMcpServer-CbDWkZ1T.d.mts → createMcpServer-C9cxS8zt.d.mts} +1 -1
  41. package/dist/{defineAggregation-D_eJjm5A.mjs → defineAggregation-Bm8RjMbq.mjs} +1 -1
  42. package/dist/{defineResource-DxkMTjRn.mjs → defineResource-DIC7JZGU.mjs} +118 -1024
  43. package/dist/discovery/index.mjs +1 -1
  44. package/dist/docs/index.d.mts +10 -4
  45. package/dist/docs/index.mjs +4 -4
  46. package/dist/{elevation-BXCfVcNG.d.mts → elevation-BW2J3tNj.d.mts} +1 -2
  47. package/dist/{elevation-CkvG0LG2.mjs → elevation-DG8SrLN-.mjs} +41 -12
  48. package/dist/encryption/index.mjs +3 -3
  49. package/dist/{errorHandler-D1GHKGlV.mjs → errorHandler-BnfDviL1.mjs} +26 -5
  50. package/dist/{errors-BH7YU_9O.mjs → errors-CtrywMHP.mjs} +58 -23
  51. package/dist/{errors-BGdVwP25.d.mts → errors-JYc9vwqE.d.mts} +9 -0
  52. package/dist/{eventPlugin-B52abJ8W.d.mts → eventPlugin-BtmA4-3P.d.mts} +65 -9
  53. package/dist/{eventPlugin-zZY-unhr.mjs → eventPlugin-Q6BhzHzs.mjs} +82 -21
  54. package/dist/{subscribe-helpers-DatDkcuG.mjs → eventTypes-Cdhm6ZlV.mjs} +151 -17
  55. package/dist/events/index.d.mts +33 -8
  56. package/dist/events/index.mjs +49 -53
  57. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  58. package/dist/events/transports/redis-stream-entry.mjs +139 -157
  59. package/dist/events/transports/redis.d.mts +1 -1
  60. package/dist/events/transports/redis.mjs +2 -2
  61. package/dist/factory/index.d.mts +32 -17
  62. package/dist/factory/index.mjs +213 -32
  63. package/dist/{fastify-augmentation-Cq2nHVaW.d.mts → fastify-augmentation-DhUJ-mvo.d.mts} +11 -25
  64. package/dist/{fields-I_EeRWND.d.mts → fields-BBSpf8pS.d.mts} +1 -1
  65. package/dist/{fields-BHrkoF5y.mjs → fields-ToPYpMqS.mjs} +1 -1
  66. package/dist/filter-merge-IpGywvym.mjs +99 -0
  67. package/dist/{generate-BLRf2m3y.mjs → generate-DRTkLlIl.mjs} +2 -2
  68. package/dist/{headers-BIXWKrzQ.mjs → headers-BbkIF6vA.mjs} +2 -2
  69. package/dist/health-D-Ft6JM6.mjs +22 -0
  70. package/dist/{health-ZRHeDHXH.mjs → health-DqbsG-_w.mjs} +115 -55
  71. package/dist/hooks/index.d.mts +2 -2
  72. package/dist/hooks/index.mjs +2 -2
  73. package/dist/idempotency/index.d.mts +31 -7
  74. package/dist/idempotency/index.mjs +155 -98
  75. package/dist/idempotency/redis.d.mts +1 -1
  76. package/dist/idempotency/redis.mjs +48 -11
  77. package/dist/{index-BHdZD8zK.d.mts → index-Bxriq3so.d.mts} +84 -21
  78. package/dist/{preloadResources-CjS2OfpU.d.mts → index-C8zVGYsk.d.mts} +37 -38
  79. package/dist/{index-D4u76eQW.d.mts → index-CRoPtISf.d.mts} +23 -73
  80. package/dist/{index-CbJiYrfv.d.mts → index-Chgz3d0i.d.mts} +1 -1
  81. package/dist/index-JdbZAIsm.d.mts +510 -0
  82. package/dist/{index-DHbyPo5j.d.mts → index-mqaqZNpe.d.mts} +253 -254
  83. package/dist/index.d.mts +8 -8
  84. package/dist/index.mjs +11 -11
  85. package/dist/{init-CpLkjU18.mjs → init-B_oUYDXI.mjs} +1 -1
  86. package/dist/integrations/event-gateway.d.mts +8 -3
  87. package/dist/integrations/event-gateway.mjs +4 -4
  88. package/dist/integrations/index.d.mts +3 -3
  89. package/dist/integrations/index.mjs +1 -1
  90. package/dist/integrations/jobs/index.d.mts +1 -1
  91. package/dist/integrations/jobs/index.mjs +18 -5
  92. package/dist/integrations/mcp/index.d.mts +72 -59
  93. package/dist/integrations/mcp/index.mjs +19 -4
  94. package/dist/integrations/mcp/testing.d.mts +2 -2
  95. package/dist/integrations/mcp/testing.mjs +2 -2
  96. package/dist/integrations/streamline.d.mts +78 -136
  97. package/dist/integrations/streamline.mjs +116 -54
  98. package/dist/integrations/webhooks.d.mts +60 -120
  99. package/dist/integrations/webhooks.mjs +36 -80
  100. package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
  101. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  102. package/dist/integrations/websocket-redis.d.mts +1 -1
  103. package/dist/integrations/websocket-redis.mjs +1 -1
  104. package/dist/integrations/websocket.d.mts +3 -3
  105. package/dist/integrations/websocket.mjs +2 -2
  106. package/dist/{interface-DEWNOMza.d.mts → interface-C0395yUN.d.mts} +13 -1
  107. package/dist/{jsonBody-ELR9lfeU.mjs → jsonBody-B4YVGcql.mjs} +2 -2
  108. package/dist/{keys-cpZCtcIE.mjs → keys-B2KtgMLJ.mjs} +7 -18
  109. package/dist/{loadResources-BPfWiI5s.mjs → loadResources-Dn4lalw2.mjs} +3 -3
  110. package/dist/{loadResourcesFromEntry-ixtfL3J2.mjs → loadResourcesFromEntry-3sLYbuse.mjs} +2 -2
  111. package/dist/logger/index.d.mts +1 -8
  112. package/dist/logger/index.mjs +3 -153
  113. package/dist/logger-DXjfIqjV.mjs +160 -0
  114. package/dist/{mcpPlugin-BX5PujI0.mjs → mcpPlugin-C08HalN5.mjs} +433 -170
  115. package/dist/{memory-Iotz0cCx.mjs → memory-9Cp7611C.mjs} +36 -34
  116. package/dist/{metrics-NMsmpRmY.mjs → metrics-CWI11eRu.mjs} +39 -72
  117. package/dist/middleware/index.d.mts +2 -2
  118. package/dist/middleware/index.mjs +3 -3
  119. package/dist/migrations/index.mjs +2 -2
  120. package/dist/{module-DpLJG2_N.mjs → module-BSvOQC7E.mjs} +8 -8
  121. package/dist/multiTenant-cY0FkDiA.d.mts +104 -0
  122. package/dist/{multipartBody-DtRWM6_U.mjs → multipartBody-CXM2a-Dy.mjs} +46 -7
  123. package/dist/{openapi-CmFf3yq_.mjs → openapi-DT_G4VhY.mjs} +48 -10
  124. package/dist/outbox-admin/index.d.mts +3 -3
  125. package/dist/outbox-admin/index.mjs +6 -18
  126. package/dist/{outbox-module-D2z5WkDY.mjs → outbox-module-Bjgzl6tg.mjs} +203 -33
  127. package/dist/{outbox-module-BHdUnuuK.d.mts → outbox-module-gZCHoE4H.d.mts} +79 -6
  128. package/dist/permissions/index.d.mts +5 -4
  129. package/dist/permissions/index.mjs +8 -6
  130. package/dist/{permissions-D8TBH44E.mjs → permissions-Cm0uYHvd.mjs} +149 -33
  131. package/dist/{pipe-FMWNheSO.mjs → pipe-BqeGT6UO.mjs} +2 -2
  132. package/dist/pipeline/index.d.mts +2 -2
  133. package/dist/pipeline/index.mjs +2 -2
  134. package/dist/plan-FVR6LP59.mjs +565 -0
  135. package/dist/{BaseController-CYEwjyjN.mjs → plugin-BccET1tL.mjs} +1256 -345
  136. package/dist/plugins/index.d.mts +14 -11
  137. package/dist/plugins/index.mjs +44 -22
  138. package/dist/plugins/response-cache.mjs +8 -14
  139. package/dist/plugins/tracing-entry.mjs +2 -2
  140. package/dist/{pluralize-CXWZIzTv.mjs → pluralize-CVIOcgMF.mjs} +1 -1
  141. package/dist/presets/filesUpload.d.mts +2 -2
  142. package/dist/presets/filesUpload.mjs +5 -5
  143. package/dist/presets/index.d.mts +26 -31
  144. package/dist/presets/index.mjs +4 -4
  145. package/dist/presets/multiTenant.d.mts +2 -107
  146. package/dist/presets/multiTenant.mjs +22 -162
  147. package/dist/presets/search.d.mts +2 -2
  148. package/dist/presets/search.mjs +2 -2
  149. package/dist/{presets-ZJSPgmT2.mjs → presets-Cpvj6fGO.mjs} +99 -107
  150. package/dist/{projection-BzIgzoKZ.mjs → projection-Ce4aQhQk.mjs} +2 -2
  151. package/dist/{pushref-registry-Dov9l4qE.d.mts → pushref-registry-UxCkoA4C.d.mts} +1 -1
  152. package/dist/{queryCachePlugin-BzqxconG.d.mts → queryCachePlugin-C2lZjTxk.d.mts} +1 -1
  153. package/dist/{queryCachePlugin-DZHPOm9p.mjs → queryCachePlugin-CFWNH8aT.mjs} +12 -14
  154. package/dist/{rateLimitKey-BvOvcBDi.mjs → rateLimitKey-C4O-kPm0.mjs} +1 -1
  155. package/dist/{realtime-8tIQWZz4.mjs → realtime-DmPE9S54.mjs} +25 -21
  156. package/dist/redis-stream-BMk-bpQS.d.mts +219 -0
  157. package/dist/{redis-Bzi1y3F9.d.mts → redis-vLvtcGy_.d.mts} +13 -24
  158. package/dist/redisShapes-CQksY67q.d.mts +55 -0
  159. package/dist/registry/index.d.mts +9 -4
  160. package/dist/registry/index.mjs +4 -4
  161. package/dist/{registry-DNkgGQcK.mjs → registry-Bcz9G1bh.mjs} +10 -8
  162. package/dist/{renewingLease-yF8BdW4b.mjs → renewingLease-qODa7KJQ.mjs} +1 -1
  163. package/dist/{replyHelpers-CNdvMfM4.mjs → replyHelpers-CG_VtVgS.mjs} +2 -2
  164. package/dist/{requestContext-cDkAUr-P.mjs → requestContext-Dsu9P1bV.mjs} +1 -1
  165. package/dist/requirement-CbiLdQ1n.d.mts +22 -0
  166. package/dist/requirement-KDdoRcOP.mjs +35 -0
  167. package/dist/resourceRateLimit-Wf6d6FL9.d.mts +30 -0
  168. package/dist/resourceRateLimit-dSjVr1pk.mjs +180 -0
  169. package/dist/{rolldown-runtime-eysyzFAF.mjs → rolldown-runtime-D1w9Y1VJ.mjs} +1 -1
  170. package/dist/routeValidator-D36SW8qt.mjs +70 -0
  171. package/dist/{runtimeCapabilities-CkhS6jn6.mjs → runtimeCapabilities-0tccjRlj.mjs} +1 -1
  172. package/dist/{schedules-j6uXXAeJ.mjs → schedules-C-OpmHBq.mjs} +46 -37
  173. package/dist/{schemaConverter-BVA7cFRG.mjs → schemaConverter-BORek3O-.mjs} +2 -2
  174. package/dist/{schemaIR-CTvPDoPB.mjs → schemaIR-C7Vbp71I.mjs} +2 -2
  175. package/dist/schemas/index.d.mts +10 -0
  176. package/dist/schemas/index.mjs +8 -3
  177. package/dist/scim/index.mjs +2 -2
  178. package/dist/scope/index.d.mts +2 -2
  179. package/dist/scope/index.mjs +6 -6
  180. package/dist/{scope-BUi1xV1I.mjs → scope-DQthe88b.mjs} +4 -4
  181. package/dist/shutdown-MqA81z_P.mjs +59 -0
  182. package/dist/{simpleEqualityMatcher-C9bzq2gO.mjs → simpleEqualityMatcher-auW8QjXN.mjs} +1 -1
  183. package/dist/{sse-BeqVKQKu.mjs → sse-CYzQBVFe.mjs} +11 -15
  184. package/dist/{sseStream-Ppzo-WUH.mjs → sseStream-B5_Afiqn.mjs} +2 -2
  185. package/dist/{store-helpers-dW71XVWL.mjs → store-helpers-BOzk-CuX.mjs} +1 -1
  186. package/dist/{streaming-IcRFjWQU.mjs → streaming-DjTQhZrN.mjs} +1 -1
  187. package/dist/subscriberIdentity-CW39uA8G.mjs +28 -0
  188. package/dist/tenancy--ed9eH_z.mjs +43 -0
  189. package/dist/tenantPreparation-BKon6Yox.mjs +67 -0
  190. package/dist/testing/cleanupStoreContract.mjs +1 -1
  191. package/dist/testing/index.d.mts +193 -175
  192. package/dist/testing/index.mjs +286 -212
  193. package/dist/testing/outboxStoreContract.mjs +137 -2
  194. package/dist/testing/requiredPorts.d.mts +17 -0
  195. package/dist/testing/requiredPorts.mjs +65 -0
  196. package/dist/testing/storageContract.mjs +1 -1
  197. package/dist/timing-qczZ0YC-.mjs +46 -0
  198. package/dist/{transactionContext-CPbdlnVw.mjs → transactionContext-DjFkrNG6.mjs} +1 -1
  199. package/dist/{typeGuards-BLjPgVBm.mjs → typeGuards-CySF12G-.mjs} +1 -1
  200. package/dist/types/index.d.mts +4 -4
  201. package/dist/types/index.mjs +1 -1
  202. package/dist/types/storage.mjs +1 -1
  203. package/dist/{types-CWQn9-IC.d.mts → types-B4Aq4Sdj.d.mts} +22 -9
  204. package/dist/{types-DfVDvkdP.d.mts → types-BJ-2XqVF.d.mts} +189 -204
  205. package/dist/{types-CgenB1gv.mjs → types-Bk9NOgOC.mjs} +4 -4
  206. package/dist/usage/index.d.mts +2 -3
  207. package/dist/usage/index.mjs +5 -5
  208. package/dist/{userHelpers-ChRvkuSZ.mjs → userHelpers-aklawRaK.mjs} +1 -1
  209. package/dist/utils/index.d.mts +84 -223
  210. package/dist/utils/index.mjs +13 -12
  211. package/dist/{utils-CxcctrAh.mjs → utils-ec1oTo1n.mjs} +315 -404
  212. package/dist/{validate-DrYWnOzI.mjs → validate-9yzHC1e2.mjs} +6 -14
  213. package/dist/{versioning-D6JIK8Tk.d.mts → versioning-Bsb51gGT.d.mts} +28 -13
  214. package/dist/{versioning-DKkT4hNJ.mjs → versioning-fhhWHV74.mjs} +4 -4
  215. package/dist/{websocket-BOXVggMf.d.mts → websocket-Cs4awVyD.d.mts} +1 -1
  216. package/dist/{workScope-CxKqoIFn.mjs → workScope-zpPyge4t.mjs} +2 -2
  217. package/package.json +16 -12
  218. package/skills/arc/SKILL.md +13 -4
  219. package/skills/arc/references/auth.md +8 -5
  220. package/skills/arc/references/integrations.md +1 -1
  221. package/skills/arc/references/mcp.md +8 -6
  222. package/skills/arc/references/multi-tenancy.md +19 -14
  223. package/skills/arc/references/production.md +27 -10
  224. package/dist/actionPermissions-BoPGQ5-4.mjs +0 -350
  225. package/dist/index-CFfLKMH4.d.mts +0 -290
  226. package/dist/interface-YzIbF7Ii.mjs +0 -17
  227. package/dist/redis-stream-BPKscsTB.d.mts +0 -260
  228. package/dist/registerRoute-Bsnk6NiZ.mjs +0 -364
  229. package/dist/sync/changelog.d.mts +0 -3
  230. package/dist/sync/changelog.mjs +0 -3
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.41.1 | MIT | https://classytic.com */
2
- import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "../constants-D5Ubn1fe.mjs";
3
- import { a as BulkMixin, c as collectReadBlockedFields, f as BodySanitizer, h as nativePolicyFilter, i as SlugMixin, l as isFieldReadable, m as AccessControl, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController } from "../BaseController-CYEwjyjN.mjs";
4
- import { t as defineAggregation } from "../defineAggregation-D_eJjm5A.mjs";
5
- import { a as createCrudHandlers, c as getControllerContext, l as getControllerScope, o as createFastifyHandler, s as createRequestContext, u as sendControllerResponse } from "../actionPermissions-BoPGQ5-4.mjs";
6
- import { a as ResourceDefinition, i as validateResourceConfig, n as assertValidConfig, o as createCrudRouter, r as formatValidationErrors, s as createPermissionMiddleware, t as defineResource } from "../defineResource-DxkMTjRn.mjs";
7
- import { a as mergeResourceConfig, i as defineResourceVariants, n as getEntityIdField, o as defineAction, r as getEntityQuery, t as getEntityId } from "../core-5lazhva9.mjs";
8
- export { AccessControl, BaseController, BaseCrudController, BodySanitizer, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, nativePolicyFilter, sendControllerResponse, validateResourceConfig };
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { a as DEFAULT_SORT, c as DEFAULT_VERSION_FIELD, d as MAX_FILTER_DEPTH, f as MAX_REGEX_LENGTH, g as SYSTEM_FIELDS, h as RESERVED_QUERY_PARAMS, i as DEFAULT_MAX_LIMIT, l as HOOK_OPERATIONS, m as MUTATION_OPERATIONS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MAX_SEARCH_LENGTH, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as HOOK_PHASES } from "../constants-Cu7Mx7_U.mjs";
3
+ import { S as nativePolicyFilter, b as BodySanitizer, c as BaseController, d as SlugMixin, f as BulkMixin, g as isFieldReadable, h as collectReadBlockedFields, l as TreeMixin, m as QueryResolver, o as createCrudRouter, p as BaseCrudController, s as createPermissionMiddleware, u as SoftDeleteMixin, x as AccessControl } from "../plugin-BccET1tL.mjs";
4
+ import { t as defineAggregation } from "../defineAggregation-Bm8RjMbq.mjs";
5
+ import { C as sendControllerResponse, S as getControllerScope, b as createRequestContext, x as getControllerContext, y as createFastifyHandler } from "../actionPermissions-BotX1YOa.mjs";
6
+ import { a as mergeResourceConfig, i as defineResourceVariants, n as getEntityIdField, o as defineAction, r as getEntityQuery, t as getEntityId } from "../core-Cb0LjccA.mjs";
7
+ import { a as ResourceDefinition, i as validateResourceConfig, n as assertValidConfig, r as formatValidationErrors, t as defineResource } from "../defineResource-DIC7JZGU.mjs";
8
+ export { AccessControl, BaseController, BaseCrudController, BodySanitizer, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, DEFAULT_VERSION_FIELD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, assertValidConfig, collectReadBlockedFields, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, nativePolicyFilter, sendControllerResponse, validateResourceConfig };
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.41.1 | MIT | https://classytic.com */
2
- import "./constants-D5Ubn1fe.mjs";
3
- import { t as defineResource } from "./defineResource-DxkMTjRn.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import "./constants-Cu7Mx7_U.mjs";
3
+ import { t as defineResource } from "./defineResource-DIC7JZGU.mjs";
4
4
  //#region src/core/defineAction.ts
5
5
  /**
6
6
  * Build an `ActionDefinition` with a typed handler. The literal schema
@@ -19,7 +19,8 @@ function defineAction(config) {
19
19
  schema: config.schema,
20
20
  description: config.description,
21
21
  id: config.id,
22
- mcp: config.mcp
22
+ mcp: config.mcp,
23
+ ...config.idempotency ? { idempotency: config.idempotency } : {}
23
24
  };
24
25
  }
25
26
  //#endregion
@@ -1,16 +1,34 @@
1
- /*! @classytic/arc v2.41.1 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-eysyzFAF.mjs";
3
- import "./constants-D5Ubn1fe.mjs";
4
- import { f as createError } from "./errors-BH7YU_9O.mjs";
5
- import { i as resolvePipelineSteps, n as buildActionPipelineHandler, u as sendControllerResponse } from "./actionPermissions-BoPGQ5-4.mjs";
6
- import { a as selectPluginMw, c as buildRouteHooks, f as buildAuthMiddlewareForPermissions, i as resolveRouterPluginMw, n as buildRateLimitConfig, o as buildActionPermissionMw, p as buildArcDecorator, r as buildRouteConfig, t as tryRegisterRoute, u as routeHookOptions } from "./registerRoute-Bsnk6NiZ.mjs";
7
- import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-CTvPDoPB.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-D1w9Y1VJ.mjs";
3
+ import "./constants-Cu7Mx7_U.mjs";
4
+ import { f as createError, i as NotFoundError, u as ValidationError } from "./errors-CtrywMHP.mjs";
5
+ import { C as sendControllerResponse, _ as buildArcDecorator, a as resolveRouterPluginMw, f as buildRouteHooks, g as buildAuthMiddlewareForPermissions, i as buildRouteConfig, l as resolvePipelineSteps, m as routeHookOptions, n as tryRegisterRoute, o as selectPluginMw, r as buildRateLimitConfig, s as buildActionPipelineHandler, u as buildActionPermissionMw } from "./actionPermissions-BotX1YOa.mjs";
6
+ import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-C7Vbp71I.mjs";
8
7
  //#region src/core/createActionRouter.ts
9
8
  var createActionRouter_exports = /* @__PURE__ */ __exportAll({
10
9
  buildActionBodySchema: () => buildActionBodySchema,
11
10
  createActionRouter: () => createActionRouter
12
11
  });
13
12
  /**
13
+ * Record a successful action. The actor and organization come from the request's
14
+ * validated scope (`auditContext`); a failed write is logged, never turned into a 500
15
+ * after the action has already happened.
16
+ */
17
+ async function auditAction(req, resource, id, action) {
18
+ const audit = req.server.audit;
19
+ if (!audit?.custom || audit._noop === true) return;
20
+ try {
21
+ await audit.custom(resource, id, action, { ...req.auditMetadata ?? {} }, req.auditContext);
22
+ } catch (err) {
23
+ req.log.error({
24
+ err,
25
+ resource,
26
+ id,
27
+ action
28
+ }, "[arc] action audit write failed");
29
+ }
30
+ }
31
+ /**
14
32
  * Register the unified action endpoint: `POST /:id/action`.
15
33
  *
16
34
  * Shares every lifecycle primitive with the CRUD router — the preHandler
@@ -19,7 +37,8 @@ var createActionRouter_exports = /* @__PURE__ */ __exportAll({
19
37
  * (keyed by `body.action` at request time).
20
38
  */
21
39
  function createActionRouter(fastify, config) {
22
- const { tag, resourceName = tag ?? "action", actions, actionPermissions = {}, actionSchemas = {}, globalAuth, onError, fields: fieldPermissions, schemaOptions, idField = "_id", permissions: resourcePermissions, routeGuards = [], pipeline, rateLimit, idLessActionNames = [], extensions } = config;
40
+ const { tag, resourceName = tag ?? "action", actions, actionPermissions = {}, actionSchemas = {}, globalAuth, onError, fields: fieldPermissions, schemaOptions, idField = "_id", permissions: resourcePermissions, routeGuards = [], tenantMiddlewares = [], pipeline, rateLimit, idLessActionNames = [], extensions, isTargetVisible, handlerScopedActionNames = [], idempotentActionNames = [], handlerDedupOwners = {}, auditActions = false } = config;
41
+ const handlerScoped = new Set(handlerScopedActionNames);
23
42
  const allActionNames = Object.keys(actions);
24
43
  if (allActionNames.length === 0) {
25
44
  fastify.log.warn("[createActionRouter] No actions defined, skipping route creation");
@@ -82,23 +101,26 @@ function createActionRouter(fastify, config) {
82
101
  } },
83
102
  required: ["id"]
84
103
  };
104
+ const actionDispatchCheck = async (req, _reply) => {
105
+ if (!req.validationError) return;
106
+ const body = req.body;
107
+ const submitted = typeof body?.action === "string" ? body.action : void 0;
108
+ if (submitted && subsetSet.has(submitted)) return;
109
+ const wrongMount = submitted && allActionNames.includes(submitted) ? submitted : void 0;
110
+ const otherMount = hasId ? "/action" : "/:id/action";
111
+ const message = wrongMount ? `Action '${wrongMount}' on '${resourceName}' is mounted at 'POST ${otherMount}', not 'POST ${urlPath}'` : submitted ? `Unknown action '${submitted}' on '${resourceName}'. Valid at 'POST ${urlPath}': ${actionSubset.join(", ")}` : `Missing 'action' field on '${resourceName}'. Valid at 'POST ${urlPath}': ${actionSubset.join(", ")}`;
112
+ throw createError(400, message, {
113
+ code: "arc.invalid_action",
114
+ validActions: actionSubset,
115
+ mount: urlPath,
116
+ ...submitted ? { submitted } : {},
117
+ ...wrongMount ? { mountedAt: otherMount } : {}
118
+ });
119
+ };
85
120
  const actionValidationFormatter = async (req, _reply) => {
86
121
  const validationError = req.validationError;
87
122
  if (!validationError) return;
88
- const body = req.body;
89
- const submitted = typeof body?.action === "string" ? body.action : void 0;
90
- if (!submitted || !subsetSet.has(submitted)) {
91
- const wrongMount = submitted && allActionNames.includes(submitted) ? submitted : void 0;
92
- const otherMount = hasId ? "/action" : "/:id/action";
93
- const message = wrongMount ? `Action '${wrongMount}' on '${resourceName}' is mounted at 'POST ${otherMount}', not 'POST ${urlPath}'` : submitted ? `Unknown action '${submitted}' on '${resourceName}'. Valid at 'POST ${urlPath}': ${actionSubset.join(", ")}` : `Missing 'action' field on '${resourceName}'. Valid at 'POST ${urlPath}': ${actionSubset.join(", ")}`;
94
- throw createError(400, message, {
95
- code: "arc.invalid_action",
96
- validActions: actionSubset,
97
- mount: urlPath,
98
- ...submitted ? { submitted } : {},
99
- ...wrongMount ? { mountedAt: otherMount } : {}
100
- });
101
- }
123
+ const submitted = req.body.action;
102
124
  const branchPath = `/oneOf/${actionSubset.indexOf(submitted)}/`;
103
125
  const ajvErrors = validationError.validation ?? [];
104
126
  const scoped = ajvErrors.filter((e) => e.keyword !== "oneOf" && (e.schemaPath?.includes(branchPath) || !e.schemaPath?.includes("/oneOf/")));
@@ -111,24 +133,30 @@ function createActionRouter(fastify, config) {
111
133
  scopedError.meta = { action: submitted };
112
134
  throw scopedError;
113
135
  };
136
+ const requiredActions = actionSubset.filter((name) => idempotentActionNames.includes(name));
137
+ const handlerDedup = Object.fromEntries(requiredActions.flatMap((name) => {
138
+ const owner = handlerDedupOwners[name];
139
+ return owner === void 0 ? [] : [[name, owner]];
140
+ }));
114
141
  const hooks = buildRouteHooks({
115
142
  arcDecorator,
116
143
  authMw,
144
+ prePermission: actionDispatchCheck,
117
145
  permissionMw,
146
+ validationFormatter: actionValidationFormatter,
118
147
  pluginMw: selectPluginMw("POST", pluginMw),
119
- routeGuards
148
+ routeGuards,
149
+ customMws: tenantMiddlewares
120
150
  });
121
- const preHandler = [actionValidationFormatter, ...hooks.preHandler];
122
151
  tryRegisterRoute(fastify, {
123
152
  method: "POST",
124
153
  url: urlPath,
125
154
  schema: routeSchema,
126
- attachValidation: true,
127
- ...routeHookOptions({
128
- onRequest: hooks.onRequest,
129
- preHandler
130
- }),
131
- ...buildRouteConfig(rateLimitConfig, extensions),
155
+ ...routeHookOptions(hooks),
156
+ ...buildRouteConfig(rateLimitConfig, extensions, void 0, requiredActions.length > 0 ? {
157
+ requiredActions,
158
+ ...Object.keys(handlerDedup).length > 0 ? { handlerDedup } : {}
159
+ } : void 0),
132
160
  handler: async (req, reply) => {
133
161
  const { action, ...data } = req.body;
134
162
  const id = hasId ? req.params.id : "";
@@ -141,8 +169,10 @@ function createActionRouter(fastify, config) {
141
169
  }
142
170
  const handler = wrappedHandlers.get(action);
143
171
  if (!handler) throw createError(400, `Invalid action '${action}'. Valid actions: ${actionSubset.join(", ")}`, { validActions: actionSubset });
172
+ if (hasId && isTargetVisible && !handlerScoped.has(action) && !await isTargetVisible(id, req)) throw new NotFoundError(resourceName);
144
173
  try {
145
174
  const response = await handler(id, data, req);
175
+ if (auditActions && (response.status ?? 200) < 400) await auditAction(req, resourceName, id, action);
146
176
  sendControllerResponse(reply, response, req);
147
177
  return reply;
148
178
  } catch (error) {
@@ -150,6 +180,8 @@ function createActionRouter(fastify, config) {
150
180
  const { statusCode, error: errorMsg, code } = onError(error, action, id);
151
181
  throw createError(statusCode, errorMsg, code ? { code } : void 0);
152
182
  }
183
+ const validation = zodIssues(error);
184
+ if (validation) throw new ValidationError(`Invalid '${action}' payload`, validation);
153
185
  const err = error;
154
186
  const statusCode = err.statusCode || err.status || 500;
155
187
  const errorCode = err.code || "ACTION_FAILED";
@@ -190,7 +222,7 @@ function createActionRouter(fastify, config) {
190
222
  * `action: { const }` and carrying its own `required`.
191
223
  *
192
224
  * EVERY BRANCH LISTS THE FULL PROPERTY UNION — the non-obvious part. AJV's
193
- * `removeAdditional: 'all'` (Fastify's default) strips a field during a
225
+ * `removeAdditional` (Fastify's default strips) strips a field during a
194
226
  * branch's evaluation when that branch's `properties` omits it, EVEN IF
195
227
  * another branch would have allowed it. The strip mutates the body before
196
228
  * `oneOf` finishes discriminating, so the winning branch receives a body that
@@ -199,11 +231,10 @@ function createActionRouter(fastify, config) {
199
231
  * every branch makes each walk see every field as its own, so nothing is
200
232
  * stripped; `required` stays per-action, so dispatch still gates correctly.
201
233
  *
202
- * Per-branch `additionalProperties: false` survives but cannot reject
203
- * sibling-action fields under host `removeAdditional: 'all'` — those strip at
204
- * top level instead. That is the host's opt-in; arc's job is only to stop
205
- * losing an action's OWN declared fields. Under arc's `createApp`
206
- * (`removeAdditional: false`) strict rejection works normally.
234
+ * Arc compiles this route with its own validator (`removeAdditional: false`, see
235
+ * `./routeValidator.ts`), whatever the host's AJV says — so per-branch
236
+ * `additionalProperties: false` rejects unknown fields on every host. The full
237
+ * property union stays because a host-supplied `validatorCompiler` may still strip.
207
238
  *
208
239
  * Pinned by `tests/core/action-discriminator-strip.test.ts` and
209
240
  * `action-strict-schema-parity.test.ts`. Exported so OpenAPI and MCP tool
@@ -211,6 +242,7 @@ function createActionRouter(fastify, config) {
211
242
  */
212
243
  function buildActionBodySchema(actionEnum, actionSchemas = {}) {
213
244
  const unionProperties = {};
245
+ const conflicting = /* @__PURE__ */ new Set();
214
246
  const irs = [];
215
247
  for (const actionName of actionEnum) {
216
248
  const ir = normalizeSchemaIR(actionSchemas[actionName]);
@@ -218,13 +250,19 @@ function buildActionBodySchema(actionEnum, actionSchemas = {}) {
218
250
  name: actionName,
219
251
  ir
220
252
  });
221
- for (const [key, val] of Object.entries(ir.properties)) unionProperties[key] = val;
253
+ for (const [key, val] of Object.entries(ir.properties)) {
254
+ const prior = unionProperties[key];
255
+ if (prior !== void 0 && JSON.stringify(prior) !== JSON.stringify(val)) conflicting.add(key);
256
+ unionProperties[key] = val;
257
+ }
222
258
  }
259
+ const topLevelProperties = { ...unionProperties };
260
+ for (const key of conflicting) topLevelProperties[key] = {};
223
261
  const branches = [];
224
262
  for (const { name, ir } of irs) branches.push(schemaIRToJsonSchemaBranch({
225
263
  ...ir,
226
264
  properties: {
227
- ...unionProperties,
265
+ ...topLevelProperties,
228
266
  ...ir.properties
229
267
  }
230
268
  }, {
@@ -242,7 +280,7 @@ function buildActionBodySchema(actionEnum, actionSchemas = {}) {
242
280
  type: "string",
243
281
  enum: [...actionEnum]
244
282
  },
245
- ...unionProperties
283
+ ...topLevelProperties
246
284
  },
247
285
  oneOf: branches
248
286
  };
@@ -261,5 +299,15 @@ function buildActionDescription(actions, actionPermissions) {
261
299
  }
262
300
  return lines.join("\n");
263
301
  }
302
+ /** A ZodError's issues as `{ field, message }`, or `undefined` for any other error. */
303
+ function zodIssues(error) {
304
+ if (!(error instanceof Error) || error.name !== "ZodError" || !("issues" in error)) return void 0;
305
+ const issues = error.issues;
306
+ if (!Array.isArray(issues)) return void 0;
307
+ return issues.map((issue) => ({
308
+ field: Array.isArray(issue.path) ? issue.path.map(String).join(".") || "(payload)" : "(payload)",
309
+ message: typeof issue.message === "string" ? issue.message : "invalid"
310
+ }));
311
+ }
264
312
  //#endregion
265
313
  export { createActionRouter_exports as n, buildActionBodySchema as t };
@@ -1,10 +1,10 @@
1
- /*! @classytic/arc v2.41.1 | MIT | https://classytic.com */
2
- import { n as evaluateAndApplyPermission } from "./authorizationDecision-DawKGoXb.mjs";
3
- import { f as createError } from "./errors-BH7YU_9O.mjs";
4
- import { u as getRequestScope } from "./types-CgenB1gv.mjs";
5
- import { a as selectPluginMw, c as buildRouteHooks, d as buildAuthMiddleware, i as resolveRouterPluginMw, n as buildRateLimitConfig, p as buildArcDecorator, u as routeHookOptions } from "./registerRoute-Bsnk6NiZ.mjs";
6
- import { n as validateAggregations } from "./validate-DrYWnOzI.mjs";
7
- import { t as buildAggregationHandler } from "./buildHandler-CvxKOc0m.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { f as createError } from "./errors-CtrywMHP.mjs";
3
+ import { u as getRequestScope } from "./types-Bk9NOgOC.mjs";
4
+ import { _ as buildArcDecorator, a as resolveRouterPluginMw, f as buildRouteHooks, h as buildAuthMiddleware, m as routeHookOptions, n as tryRegisterRoute, o as selectPluginMw, r as buildRateLimitConfig } from "./actionPermissions-BotX1YOa.mjs";
5
+ import { n as evaluateAndApplyPermission } from "./authorizationDecision-DQYrkl5f.mjs";
6
+ import { n as validateAggregations } from "./validate-9yzHC1e2.mjs";
7
+ import { t as buildAggregationHandler } from "./buildHandler-CRQ8EcX5.mjs";
8
8
  //#region src/core/aggregation/createAggregationRouter.ts
9
9
  /**
10
10
  * Register one Fastify route per aggregation. No-op when the map is
@@ -68,7 +68,7 @@ function registerOne(fastify, normalized, ctx) {
68
68
  summary: config.summary ?? `Aggregation: ${name}`,
69
69
  description: config.description ?? "Portable aggregation generated by arc. Filters from query string compose with the declaration's base filter + tenant scope."
70
70
  };
71
- fastify.route({
71
+ tryRegisterRoute(fastify, {
72
72
  method: "GET",
73
73
  url: `/aggregations/${name}`,
74
74
  schema: routeSchema,
@@ -86,6 +86,9 @@ function registerOne(fastify, normalized, ctx) {
86
86
  throw createError(500, `Aggregation "${name}" failed: ${message}`);
87
87
  }
88
88
  }
89
+ }, {
90
+ resourceName: tag ?? name,
91
+ op: `aggregation:${name}`
89
92
  });
90
93
  }
91
94
  /**