@classytic/arc 2.38.0 → 2.41.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 (196) hide show
  1. package/dist/{BaseController-CYaDvmOB.mjs → BaseController-DYJRZ0EJ.mjs} +114 -24
  2. package/dist/{EventTransport-Cx60_s-6.d.mts → EventTransport-CbUKDzZZ.d.mts} +33 -0
  3. package/dist/{EventTransport-Gq7JWbWw.mjs → EventTransport-n7qO5Cz3.mjs} +22 -2
  4. package/dist/{HookSystem-C0ikzqQf.mjs → HookSystem-CxvZBo77.mjs} +2 -2
  5. package/dist/{ResourceRegistry-DPcX--zk.mjs → ResourceRegistry-Cu7uTJp9.mjs} +2 -2
  6. package/dist/{actionPermissions-jlFZ1it4.mjs → actionPermissions-DPwPWPOV.mjs} +7 -6
  7. package/dist/audit/index.d.mts +2 -2
  8. package/dist/audit/index.mjs +10 -3
  9. package/dist/auth/audit.mjs +1 -1
  10. package/dist/auth/index.d.mts +2 -2
  11. package/dist/auth/index.mjs +12 -6
  12. package/dist/auth/redis-session.mjs +1 -1
  13. package/dist/{authorizationDecision-BP8GHtjc.mjs → authorizationDecision-2YY_Kaj1.mjs} +2 -2
  14. package/dist/{base-C-NL2fTi.d.mts → base-CxrV1LmG.d.mts} +10 -0
  15. package/dist/{buildHandler-DjXOqIvX.mjs → buildHandler-CUhjGHGZ.mjs} +4 -4
  16. package/dist/cache/index.d.mts +4 -2
  17. package/dist/cache/index.mjs +4 -4
  18. package/dist/{caching-a3ZEcJJs.mjs → caching-DsWDjIxx.mjs} +2 -2
  19. package/dist/cleanup/index.d.mts +2 -2
  20. package/dist/cleanup/index.mjs +21 -5
  21. package/dist/cli/commands/describe.d.mts +1 -1
  22. package/dist/cli/commands/describe.mjs +3 -3
  23. package/dist/cli/commands/docs.mjs +3 -3
  24. package/dist/cli/commands/doctor.mjs +1 -1
  25. package/dist/cli/commands/generate.mjs +2 -2
  26. package/dist/cli/commands/init.mjs +2 -2
  27. package/dist/cli/commands/introspect.mjs +2 -2
  28. package/dist/cli/index.mjs +3 -3
  29. package/dist/{constants-BONghE1Y.mjs → constants-BxLgNFF7.mjs} +1 -1
  30. package/dist/context/index.d.mts +34 -6
  31. package/dist/context/index.mjs +42 -24
  32. package/dist/core/index.d.mts +2 -2
  33. package/dist/core/index.mjs +7 -7
  34. package/dist/{core-8She7FgF.mjs → core-iNGqYerO.mjs} +3 -3
  35. package/dist/{createActionRouter-Bqi6Bhhx.mjs → createActionRouter-BBlbPs3k.mjs} +7 -7
  36. package/dist/{createAggregationRouter-BsYO7ktd.mjs → createAggregationRouter-Dv5SuK2x.mjs} +7 -7
  37. package/dist/createMcpServer-CbDWkZ1T.d.mts +48 -0
  38. package/dist/{defineAggregation-0KBvqEEC.mjs → defineAggregation-UyeurGkp.mjs} +1 -1
  39. package/dist/{defineResource-BMdyRelW.mjs → defineResource-DzGT-2LP.mjs} +20 -22
  40. package/dist/discovery/index.mjs +1 -1
  41. package/dist/docs/index.d.mts +1 -1
  42. package/dist/docs/index.mjs +3 -3
  43. package/dist/{elevation-C6woysGC.mjs → elevation-BF-vhGxY.mjs} +4 -4
  44. package/dist/encryption/index.mjs +3 -3
  45. package/dist/{errorHandler-DI5AN2b5.d.mts → errorHandler--4rSMMvq.d.mts} +7 -1
  46. package/dist/{errorHandler-BdmIWPba.mjs → errorHandler-CIMkCOWm.mjs} +3 -3
  47. package/dist/{errors-2ExmOgIJ.mjs → errors-C_YhELhe.mjs} +1 -1
  48. package/dist/{eventPlugin-DFvHa4Nf.d.mts → eventPlugin-B52abJ8W.d.mts} +1 -1
  49. package/dist/{eventPlugin-DJwpGMzx.mjs → eventPlugin-CmXaPWLv.mjs} +5 -5
  50. package/dist/events/index.d.mts +4 -4
  51. package/dist/events/index.mjs +5 -5
  52. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  53. package/dist/events/transports/redis-stream-entry.mjs +34 -24
  54. package/dist/events/transports/redis.d.mts +1 -1
  55. package/dist/events/transports/redis.mjs +11 -8
  56. package/dist/factory/index.d.mts +5 -5
  57. package/dist/factory/index.mjs +5 -5
  58. package/dist/{fastify-augmentation-jYA2oHyL.d.mts → fastify-augmentation-Cq2nHVaW.d.mts} +3 -3
  59. package/dist/{fields-Cha2QCKH.mjs → fields-BTyPLHK0.mjs} +1 -1
  60. package/dist/{generate-BUP4Oydg.mjs → generate-D_YmiCNf.mjs} +4 -3
  61. package/dist/{headers-DeXNifVj.mjs → headers-CNECDE6q.mjs} +2 -2
  62. package/dist/{health-Bh0N_FLk.mjs → health-CxQzbJmr.mjs} +10 -2
  63. package/dist/hooks/index.d.mts +1 -1
  64. package/dist/hooks/index.mjs +2 -2
  65. package/dist/idempotency/index.d.mts +1 -1
  66. package/dist/idempotency/index.mjs +4 -4
  67. package/dist/idempotency/redis.d.mts +1 -1
  68. package/dist/idempotency/redis.mjs +1 -1
  69. package/dist/{index-BtYoMip1.d.mts → index-BHdZD8zK.d.mts} +10 -2
  70. package/dist/{index-D2uIUSQk.d.mts → index-CFfLKMH4.d.mts} +2 -2
  71. package/dist/{index-eyg5WEcy.d.mts → index-CbJiYrfv.d.mts} +1 -1
  72. package/dist/{index-BRoDtjek.d.mts → index-D4u76eQW.d.mts} +3 -3
  73. package/dist/{index-B78WZom8.d.mts → index-DHbyPo5j.d.mts} +52 -12
  74. package/dist/index.d.mts +5 -5
  75. package/dist/index.mjs +11 -11
  76. package/dist/{init-Dg_Am2o_.mjs → init-Y2MlSN9n.mjs} +9 -9
  77. package/dist/integrations/event-gateway.d.mts +1 -1
  78. package/dist/integrations/event-gateway.mjs +2 -2
  79. package/dist/integrations/index.d.mts +2 -2
  80. package/dist/integrations/index.mjs +1 -1
  81. package/dist/integrations/jobs/index.d.mts +1 -1
  82. package/dist/integrations/jobs/index.mjs +2 -2
  83. package/dist/integrations/mcp/index.d.mts +4 -47
  84. package/dist/integrations/mcp/index.mjs +2 -2
  85. package/dist/integrations/mcp/testing.d.mts +22 -2
  86. package/dist/integrations/mcp/testing.mjs +55 -33
  87. package/dist/integrations/streamline.mjs +3 -3
  88. package/dist/integrations/webhooks.d.mts +2 -2
  89. package/dist/integrations/webhooks.mjs +3 -3
  90. package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
  91. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  92. package/dist/integrations/websocket-redis.mjs +1 -1
  93. package/dist/integrations/websocket.mjs +24 -6
  94. package/dist/{interface-DYPVscCU.mjs → interface-BIpgzbZl.mjs} +1 -1
  95. package/dist/{jsonBody-DVui0uJl.mjs → jsonBody-Cq9KYl2Z.mjs} +2 -2
  96. package/dist/{keys-BSuxGS-B.mjs → keys-Cmv4cBRa.mjs} +1 -1
  97. package/dist/{loadResources-CNd1DWnK.mjs → loadResources-CblF7xt2.mjs} +2 -2
  98. package/dist/{loadResourcesFromEntry-DNj8cpiY.mjs → loadResourcesFromEntry-99fIMC3p.mjs} +2 -2
  99. package/dist/logger/index.mjs +1 -1
  100. package/dist/{mcpPlugin-KWsezMx7.mjs → mcpPlugin-xF3Gw-HW.mjs} +75 -31
  101. package/dist/{memory-BiPVaCPg.mjs → memory-CpDZ9NPw.mjs} +2 -2
  102. package/dist/{metrics-CsWaIVTa.mjs → metrics-BaKnq8ag.mjs} +2 -2
  103. package/dist/middleware/index.d.mts +1 -1
  104. package/dist/middleware/index.mjs +3 -3
  105. package/dist/migrations/index.mjs +2 -2
  106. package/dist/{module-BQXHxMEk.mjs → module-BkQEesNQ.mjs} +1 -1
  107. package/dist/{multipartBody-u6VrS_iH.mjs → multipartBody-C92aJ8am.mjs} +1 -1
  108. package/dist/{openapi-Dxc8RLy_.mjs → openapi-C3LFRzPq.mjs} +6 -6
  109. package/dist/outbox-admin/index.d.mts +2 -2
  110. package/dist/outbox-admin/index.mjs +4 -4
  111. package/dist/{outbox-module-CQXu_O6o.d.mts → outbox-module-BHdUnuuK.d.mts} +15 -2
  112. package/dist/{outbox-module-DyIqA5vo.mjs → outbox-module-dsCyLxXH.mjs} +43 -21
  113. package/dist/permissions/index.d.mts +2 -2
  114. package/dist/permissions/index.mjs +5 -5
  115. package/dist/{permissions-H7Zcb82Z.mjs → permissions-DiHXy8Ck.mjs} +12 -6
  116. package/dist/{pipe-SunhEaZ6.mjs → pipe-CBVmUJ-j.mjs} +2 -2
  117. package/dist/pipeline/index.d.mts +1 -1
  118. package/dist/pipeline/index.mjs +2 -2
  119. package/dist/plugins/index.d.mts +7 -37
  120. package/dist/plugins/index.mjs +34 -22
  121. package/dist/plugins/response-cache.mjs +9 -2
  122. package/dist/plugins/tracing-entry.mjs +2 -2
  123. package/dist/{pluralize-Da7IT_qJ.mjs → pluralize-2_U6QZQg.mjs} +1 -1
  124. package/dist/{preloadResources-DlhH81py.mjs → preloadResources-Bbp4QJ8V.mjs} +82 -26
  125. package/dist/{preloadResources-BbBkNkqK.d.mts → preloadResources-CjS2OfpU.d.mts} +14 -9
  126. package/dist/presets/filesUpload.d.mts +2 -2
  127. package/dist/presets/filesUpload.mjs +5 -5
  128. package/dist/presets/index.d.mts +2 -2
  129. package/dist/presets/index.mjs +2 -2
  130. package/dist/presets/multiTenant.d.mts +38 -1
  131. package/dist/presets/multiTenant.mjs +24 -6
  132. package/dist/presets/search.d.mts +2 -2
  133. package/dist/presets/search.mjs +2 -2
  134. package/dist/{presets-CNyfaxGL.mjs → presets-BdlugYTc.mjs} +4 -4
  135. package/dist/{projection-DSfEoooA.mjs → projection-Uvgp-EEj.mjs} +2 -2
  136. package/dist/{queryCachePlugin-oTsmVyEQ.mjs → queryCachePlugin-B5F09bYr.mjs} +11 -5
  137. package/dist/rateLimitKey-CK-EU2L8.mjs +41 -0
  138. package/dist/{realtime-CPmjjgqd.mjs → realtime-FnnD0n3Z.mjs} +9 -9
  139. package/dist/{redis-CduhKsJi.d.mts → redis-Bzi1y3F9.d.mts} +10 -2
  140. package/dist/{redis-stream-eh0eOtjh.d.mts → redis-stream-BPKscsTB.d.mts} +12 -7
  141. package/dist/{registerRoute-XvcI_3sh.mjs → registerRoute-DRsSHPSM.mjs} +6 -6
  142. package/dist/registry/index.d.mts +2 -2
  143. package/dist/registry/index.mjs +3 -3
  144. package/dist/{registry-UFEJQN8R.mjs → registry-D3y8VEJ1.mjs} +2 -2
  145. package/dist/{renewingLease-DuRGVOMe.mjs → renewingLease-B3VYh5aU.mjs} +1 -1
  146. package/dist/{replyHelpers-BHebarf0.mjs → replyHelpers-DPHsdw-5.mjs} +2 -2
  147. package/dist/{requestContext-DpmntRZy.mjs → requestContext-cSVKnYPk.mjs} +1 -1
  148. package/dist/{rolldown-runtime-Add2L50I.mjs → rolldown-runtime-DjDuyglE.mjs} +1 -1
  149. package/dist/{runtimeCapabilities-D793Pxci.mjs → runtimeCapabilities-DSA_dH1_.mjs} +31 -5
  150. package/dist/{schedules-DthM8Qag.mjs → schedules-BktJb3Y3.mjs} +8 -4
  151. package/dist/{schemaConverter-Db-MMsH6.mjs → schemaConverter-BLCSmNbr.mjs} +1 -1
  152. package/dist/{schemaIR-CIXShch7.mjs → schemaIR-K16Bb5BX.mjs} +2 -2
  153. package/dist/schemas/index.mjs +1 -1
  154. package/dist/scim/index.mjs +2 -2
  155. package/dist/scope/index.mjs +5 -5
  156. package/dist/{scope-D03sk17n.mjs → scope-jSxuBTFM.mjs} +4 -4
  157. package/dist/{simpleEqualityMatcher-B7qVjQBv.mjs → simpleEqualityMatcher-BiOnyflP.mjs} +1 -1
  158. package/dist/{sse-D4MYqkic.mjs → sse-CH7Slxc1.mjs} +5 -5
  159. package/dist/{sseStream-BuMNPR6r.mjs → sseStream-CN-Lh1Tu.mjs} +2 -2
  160. package/dist/{store-helpers-CIF4RG8s.mjs → store-helpers-9DX9-1j_.mjs} +1 -1
  161. package/dist/{streaming-DkpW1HwJ.mjs → streaming-dvppnxsr.mjs} +1 -1
  162. package/dist/{subscribe-helpers-CBZOi6pk.mjs → subscribe-helpers-AVYPgqTl.mjs} +2 -2
  163. package/dist/sync/changelog.mjs +1 -1
  164. package/dist/testing/cleanupStoreContract.mjs +1 -1
  165. package/dist/testing/index.d.mts +5 -5
  166. package/dist/testing/index.mjs +10 -10
  167. package/dist/testing/outboxStoreContract.mjs +14 -3
  168. package/dist/testing/storageContract.mjs +1 -1
  169. package/dist/{transactionContext-DMmvcfdo.mjs → transactionContext-DCWMI6hV.mjs} +1 -1
  170. package/dist/{typeGuards-DHTnEs5X.mjs → typeGuards-D7tHFdH6.mjs} +1 -1
  171. package/dist/types/index.d.mts +2 -2
  172. package/dist/types/index.mjs +1 -1
  173. package/dist/types/storage.mjs +1 -1
  174. package/dist/{types-BqLyyH0o.mjs → types-CDy3-zw1.mjs} +4 -4
  175. package/dist/{types-LQFwC37d.d.mts → types-CWQn9-IC.d.mts} +46 -1
  176. package/dist/{types-BRU-Kd3t.d.mts → types-DfVDvkdP.d.mts} +20 -2
  177. package/dist/usage/index.d.mts +58 -2
  178. package/dist/usage/index.mjs +0 -0
  179. package/dist/{userHelpers-CXySQFRg.mjs → userHelpers-DDMOZ_Pm.mjs} +1 -1
  180. package/dist/utils/index.d.mts +110 -8
  181. package/dist/utils/index.mjs +12 -12
  182. package/dist/{utils-BbGG8XNT.mjs → utils-B-zj_b__.mjs} +61 -12
  183. package/dist/{validate-CidSeUrx.mjs → validate-R0G_JrnK.mjs} +2 -2
  184. package/dist/{versioning-B843jOYX.d.mts → versioning-D6JIK8Tk.d.mts} +58 -2
  185. package/dist/{versioning-C2r0eOZ4.mjs → versioning-DuVWcu-F.mjs} +3 -3
  186. package/dist/workScope-BhsWde4k.mjs +41 -0
  187. package/package.json +574 -565
  188. package/skills/arc/SKILL.md +8 -4
  189. package/skills/arc/references/mcp.md +20 -0
  190. package/skills/arc/references/production.md +94 -9
  191. package/skills/arc/references/testing.md +0 -12
  192. package/skills/arc-code-review/references/anti-patterns.md +1 -1
  193. package/skills/arc-code-review/references/migration-recipes.md +0 -60
  194. package/skills/arc-code-review/references/mongokit-migration.md +0 -27
  195. package/skills/arc-module-publishing/references/package-manifest.md +3 -1
  196. package/dist/rateLimitKey-CewdR-m6.mjs +0 -15
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DNj8cpiY.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-99fIMC3p.mjs";
3
3
  //#region src/cli/commands/introspect.ts
4
4
  function describePermission(value) {
5
5
  if (!value) return "none";
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
2
  import { describe } from "./commands/describe.mjs";
3
3
  import { exportDocs } from "./commands/docs.mjs";
4
4
  import { doctor } from "./commands/doctor.mjs";
5
- import { t as generate } from "../generate-BUP4Oydg.mjs";
6
- import { t as init } from "../init-Dg_Am2o_.mjs";
5
+ import { t as generate } from "../generate-D_YmiCNf.mjs";
6
+ import { t as init } from "../init-Y2MlSN9n.mjs";
7
7
  import { introspect } from "./commands/introspect.mjs";
8
8
  export { describe, doctor, exportDocs, generate, init, introspect };
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
2
  //#region src/constants.ts
3
3
  /**
4
4
  * Arc Framework Constants — Single Source of Truth
@@ -1,13 +1,19 @@
1
1
 
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
3
  import { CacheAdapter } from "@classytic/repo-core/cache";
4
+ import { DomainEvent } from "@classytic/primitives/events";
4
5
  //#region src/context/requestContext.d.ts
6
+ /** What started this unit of work. See `workScope.ts`. */
7
+ type WorkKind = "request" | "event" | "job";
5
8
  /**
6
9
  * Shape of the request-scoped context store.
7
- * Populated by Arc's onRequest hook in arcCorePlugin.
10
+ * Populated by Arc's onRequest hook in arcCorePlugin, or by `runWorkScope`
11
+ * for an event dispatch or a job run.
8
12
  */
9
13
  interface RequestStore {
10
- /** Unique request identifier */
14
+ /** Absent on stores created before scopes had kinds; treat as `'request'`. */
15
+ kind?: WorkKind;
16
+ /** Unique request identifier — the correlation key of an event or job scope. */
11
17
  requestId?: string;
12
18
  /** Authenticated user (if any) */
13
19
  user?: {
@@ -88,14 +94,15 @@ declare function getTraceHeaders(): Record<string, string> | undefined;
88
94
  //#endregion
89
95
  //#region src/context/requestScopedCache.d.ts
90
96
  /**
91
- * The cache for the CURRENT request, or `undefined` outside one.
97
+ * The cache for the CURRENT unit of work — a request, an event dispatch or a
98
+ * job run (see `runWorkScope`) — or `undefined` outside one.
92
99
  *
93
- * Lazily created on first use, so a request that never touches a cached
100
+ * Lazily created on first use, so a scope that never touches a cached
94
101
  * repository allocates nothing.
95
102
  */
96
103
  declare function requestScopedCache(): CacheAdapter | undefined;
97
104
  /**
98
- * Whether the current request has allocated a cache yet. Diagnostics and
105
+ * Whether the current scope has allocated a cache yet. Diagnostics and
99
106
  * tests only — never branch application behaviour on this.
100
107
  */
101
108
  declare function hasRequestScopedCache(): boolean;
@@ -124,4 +131,25 @@ declare const transactionContext: {
124
131
  storage: AsyncLocalStorage<unknown>;
125
132
  };
126
133
  //#endregion
127
- export { type DbSession, type RequestStore, getTraceHeaders, hasRequestScopedCache, requestContext, requestScopedCache, transactionContext };
134
+ //#region src/context/workScope.d.ts
135
+ interface WorkSeed {
136
+ readonly kind: WorkKind;
137
+ /** Becomes `requestId` — the correlation key for anything published inside. */
138
+ readonly id: string;
139
+ readonly organizationId?: string;
140
+ }
141
+ /** Enter a scope for `fn`, or run it inside the active one. */
142
+ declare function runWorkScope<T>(seed: WorkSeed, fn: () => T): T;
143
+ /**
144
+ * A per-scope memo slot: created once on first use, the same instance after.
145
+ * `undefined` outside a scope.
146
+ */
147
+ declare function scopedValue<T>(slot: symbol, create: () => T): T | undefined;
148
+ /**
149
+ * The scope an event dispatch runs in. The correlation id is the scope id so a
150
+ * child event published from a handler chains to the same correlation; the
151
+ * tenant rides `meta`, never the payload.
152
+ */
153
+ declare function workSeedFromEvent(event: DomainEvent): WorkSeed;
154
+ //#endregion
155
+ export { type DbSession, type RequestStore, type WorkKind, type WorkSeed, getTraceHeaders, hasRequestScopedCache, requestContext, requestScopedCache, runWorkScope, scopedValue, transactionContext, workSeedFromEvent };
@@ -1,29 +1,52 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as transactionContext } from "../transactionContext-DMmvcfdo.mjs";
3
- import { n as requestContext, t as getTraceHeaders } from "../requestContext-DpmntRZy.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as transactionContext } from "../transactionContext-DCWMI6hV.mjs";
3
+ import { n as requestContext, t as getTraceHeaders } from "../requestContext-cSVKnYPk.mjs";
4
+ import { n as scopedValue, r as workSeedFromEvent, t as runWorkScope } from "../workScope-BhsWde4k.mjs";
4
5
  //#region src/context/requestScopedCache.ts
6
+ /** The memo slot the per-scope store hangs off. */
7
+ const SLOT = Symbol.for("arc.requestScopedCache");
5
8
  /**
6
- * The slot the per-request store hangs off. Underscore-prefixed to sit apart
7
- * from the fields arc's own hooks populate on `RequestStore`.
9
+ * Entry cap for one scope's cache. A request touching this many distinct keys
10
+ * is already pathological; a JOB RUN reaching it is ordinary, and that is the
11
+ * case this exists for (see the eviction note below).
8
12
  */
9
- const SLOT = "_requestCache";
13
+ const MAX_ENTRIES = 1e4;
10
14
  /**
11
- * A `Map`-backed `CacheAdapter` with NO eviction and NO TTL — both deliberate.
15
+ * A `Map`-backed `CacheAdapter` with NO TTL and LRU eviction above
16
+ * {@link MAX_ENTRIES}.
12
17
  *
13
- * The store is unreachable once the request's async context ends, so it is
14
- * garbage in milliseconds and bounded by what one request touches; an LRU
15
- * would guard a lifetime that cannot occur. TTL is accepted and ignored
16
- * because repo-core stamps freshness INTO the envelope and re-checks on read —
17
- * honouring it here too would put two clocks on one question.
18
+ * TTL is accepted and ignored because repo-core stamps freshness INTO the
19
+ * envelope and re-checks on read — honouring it here too would put two clocks
20
+ * on one question.
21
+ *
22
+ * Eviction is newer than the rest of this file and the reason is worth
23
+ * keeping. Unbounded was correct while a scope meant an HTTP REQUEST: the
24
+ * store is unreachable once that async context ends, so it was garbage in
25
+ * milliseconds and bounded by what one request touched, and an LRU would have
26
+ * guarded a lifetime that could not occur. 2.40 extended scopes to job runs
27
+ * and event dispatches — and `schedulesPlugin` wraps the WHOLE handler in one
28
+ * scope, so a nightly job sweeping a million rows holds a single cache for the
29
+ * duration. That is now a lifetime that occurs, and the old premise no longer
30
+ * holds. Evicting is always safe here: this is a cache, so the worst a miss
31
+ * costs is the re-read it was avoiding.
18
32
  */
19
33
  function createRequestCacheAdapter() {
20
34
  const map = /* @__PURE__ */ new Map();
21
35
  return {
22
36
  async get(key) {
23
- return map.get(key);
37
+ if (!map.has(key)) return void 0;
38
+ const value = map.get(key);
39
+ map.delete(key);
40
+ map.set(key, value);
41
+ return value;
24
42
  },
25
43
  async set(key, value, _ttlSeconds) {
44
+ map.delete(key);
26
45
  map.set(key, value);
46
+ if (map.size > MAX_ENTRIES) {
47
+ const oldest = map.keys().next();
48
+ if (!oldest.done) map.delete(oldest.value);
49
+ }
27
50
  },
28
51
  async delete(key) {
29
52
  map.delete(key);
@@ -39,26 +62,21 @@ function createRequestCacheAdapter() {
39
62
  };
40
63
  }
41
64
  /**
42
- * The cache for the CURRENT request, or `undefined` outside one.
65
+ * The cache for the CURRENT unit of work — a request, an event dispatch or a
66
+ * job run (see `runWorkScope`) — or `undefined` outside one.
43
67
  *
44
- * Lazily created on first use, so a request that never touches a cached
68
+ * Lazily created on first use, so a scope that never touches a cached
45
69
  * repository allocates nothing.
46
70
  */
47
71
  function requestScopedCache() {
48
- const store = requestContext.get();
49
- if (!store) return void 0;
50
- const existing = store[SLOT];
51
- if (existing) return existing;
52
- const created = createRequestCacheAdapter();
53
- store[SLOT] = created;
54
- return created;
72
+ return scopedValue(SLOT, createRequestCacheAdapter);
55
73
  }
56
74
  /**
57
- * Whether the current request has allocated a cache yet. Diagnostics and
75
+ * Whether the current scope has allocated a cache yet. Diagnostics and
58
76
  * tests only — never branch application behaviour on this.
59
77
  */
60
78
  function hasRequestScopedCache() {
61
79
  return requestContext.get()?.[SLOT] !== void 0;
62
80
  }
63
81
  //#endregion
64
- export { getTraceHeaders, hasRequestScopedCache, requestContext, requestScopedCache, transactionContext };
82
+ export { getTraceHeaders, hasRequestScopedCache, requestContext, requestScopedCache, runWorkScope, scopedValue, transactionContext, workSeedFromEvent };
@@ -1,4 +1,4 @@
1
1
 
2
- import { $t as AccessControlConfig, B as defineResource, Bt as BaseController, Cn as ControllerConstructionOptions, En as BodySanitizerConfig, Gt as SlugExt, Ht as SoftDeleteMixin, Jt as BulkMixin, Kt as SlugMixin, Qt as AccessControl, Sn as ControllerConfigurableOptions, Tn as BodySanitizer, Ut as TreeExt, V as ResourceDefinition, Vt as SoftDeleteExt, Wt as TreeMixin, Xt as QueryResolver, Yt as BaseCrudController, Zt as QueryResolverConfig, ct as AggMeasureShorthand, dt as AggregationDateRangeRequirement, ft as AggregationIndexHint, gt as AggregationsMap, ht as AggregationRateLimit, lt as AggregationCacheConfig, mt as AggregationMaterializedResult, pt as AggregationMaterializedContext, qt as BulkExt, st as AggMeasureInput, ut as AggregationConfig, wn as ListResult, xn as BaseControllerOptions } from "../index-B78WZom8.mjs";
3
- import { A as CRUD_OPERATIONS, B as HookOperation, C as SeamedResourceConfig, D as createCrudRouter, E as defineAction, F as DEFAULT_SORT, G as MUTATION_OPERATIONS, H as MAX_FILTER_DEPTH, I as DEFAULT_TENANT_FIELD, J as SYSTEM_FIELDS, K as MutationOperation, L as DEFAULT_UPDATE_METHOD, M as DEFAULT_ID_FIELD, N as DEFAULT_LIMIT, O as createPermissionMiddleware, P as DEFAULT_MAX_LIMIT, R as HOOK_OPERATIONS, S as ResourceSeams, T as DefineActionConfig, U as MAX_REGEX_LENGTH, V as HookPhase, W as MAX_SEARCH_LENGTH, _ as getEntityId, a as formatValidationErrors, b as defineResourceVariants, c as nativePolicyFilter, d as createCrudHandlers, f as createFastifyHandler, g as sendControllerResponse, h as getControllerScope, i as assertValidConfig, j as CrudOperation, k as defineAggregation, l as collectReadBlockedFields, m as getControllerContext, n as ValidateOptions, o as validateResourceConfig, p as createRequestContext, q as RESERVED_QUERY_PARAMS, r as ValidationResult, s as NativePolicyFilter, t as ConfigError, u as isFieldReadable, v as getEntityIdField, w as mergeResourceConfig, x as AdapterLike, y as getEntityQuery, z as HOOK_PHASES } from "../index-BRoDtjek.mjs";
2
+ import { $t as AccessControlConfig, B as defineResource, Bt as BaseController, Cn as ControllerConstructionOptions, En as BodySanitizerConfig, Gt as SlugExt, Ht as SoftDeleteMixin, Jt as BulkMixin, Kt as SlugMixin, Qt as AccessControl, Sn as ControllerConfigurableOptions, Tn as BodySanitizer, Ut as TreeExt, V as ResourceDefinition, Vt as SoftDeleteExt, Wt as TreeMixin, Xt as QueryResolver, Yt as BaseCrudController, Zt as QueryResolverConfig, ct as AggMeasureShorthand, dt as AggregationDateRangeRequirement, ft as AggregationIndexHint, gt as AggregationsMap, ht as AggregationRateLimit, lt as AggregationCacheConfig, mt as AggregationMaterializedResult, pt as AggregationMaterializedContext, qt as BulkExt, st as AggMeasureInput, ut as AggregationConfig, wn as ListResult, xn as BaseControllerOptions } from "../index-DHbyPo5j.mjs";
3
+ import { A as CRUD_OPERATIONS, B as HookOperation, C as SeamedResourceConfig, D as createCrudRouter, E as defineAction, F as DEFAULT_SORT, G as MUTATION_OPERATIONS, H as MAX_FILTER_DEPTH, I as DEFAULT_TENANT_FIELD, J as SYSTEM_FIELDS, K as MutationOperation, L as DEFAULT_UPDATE_METHOD, M as DEFAULT_ID_FIELD, N as DEFAULT_LIMIT, O as createPermissionMiddleware, P as DEFAULT_MAX_LIMIT, R as HOOK_OPERATIONS, S as ResourceSeams, T as DefineActionConfig, U as MAX_REGEX_LENGTH, V as HookPhase, W as MAX_SEARCH_LENGTH, _ as getEntityId, a as formatValidationErrors, b as defineResourceVariants, c as nativePolicyFilter, d as createCrudHandlers, f as createFastifyHandler, g as sendControllerResponse, h as getControllerScope, i as assertValidConfig, j as CrudOperation, k as defineAggregation, l as collectReadBlockedFields, m as getControllerContext, n as ValidateOptions, o as validateResourceConfig, p as createRequestContext, q as RESERVED_QUERY_PARAMS, r as ValidationResult, s as NativePolicyFilter, t as ConfigError, u as isFieldReadable, v as getEntityIdField, w as mergeResourceConfig, x as AdapterLike, y as getEntityQuery, z as HOOK_PHASES } from "../index-D4u76eQW.mjs";
4
4
  export { AccessControl, type AccessControlConfig, type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, BaseController, type BaseControllerOptions, BaseCrudController, BodySanitizer, type BodySanitizerConfig, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, type NativePolicyFilter, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, type ResourceSeams, SYSTEM_FIELDS, type SeamedResourceConfig, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type ValidateOptions, type ValidationResult, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, nativePolicyFilter, sendControllerResponse, validateResourceConfig };
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.38.0 | 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-BONghE1Y.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-CYaDvmOB.mjs";
4
- import { t as defineAggregation } from "../defineAggregation-0KBvqEEC.mjs";
5
- import { a as createCrudHandlers, c as getControllerContext, l as getControllerScope, o as createFastifyHandler, s as createRequestContext, u as sendControllerResponse } from "../actionPermissions-jlFZ1it4.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-BMdyRelW.mjs";
7
- import { a as mergeResourceConfig, i as defineResourceVariants, n as getEntityIdField, o as defineAction, r as getEntityQuery, t as getEntityId } from "../core-8She7FgF.mjs";
1
+ /*! @classytic/arc v2.41.0 | 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-BxLgNFF7.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-DYJRZ0EJ.mjs";
4
+ import { t as defineAggregation } from "../defineAggregation-UyeurGkp.mjs";
5
+ import { a as createCrudHandlers, c as getControllerContext, l as getControllerScope, o as createFastifyHandler, s as createRequestContext, u as sendControllerResponse } from "../actionPermissions-DPwPWPOV.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-DzGT-2LP.mjs";
7
+ import { a as mergeResourceConfig, i as defineResourceVariants, n as getEntityIdField, o as defineAction, r as getEntityQuery, t as getEntityId } from "../core-iNGqYerO.mjs";
8
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,6 +1,6 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import "./constants-BONghE1Y.mjs";
3
- import { t as defineResource } from "./defineResource-BMdyRelW.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import "./constants-BxLgNFF7.mjs";
3
+ import { t as defineResource } from "./defineResource-DzGT-2LP.mjs";
4
4
  //#region src/core/defineAction.ts
5
5
  /**
6
6
  * Build an `ActionDefinition` with a typed handler. The literal schema
@@ -1,10 +1,10 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-Add2L50I.mjs";
3
- import "./constants-BONghE1Y.mjs";
4
- import { f as createError } from "./errors-2ExmOgIJ.mjs";
5
- import { i as resolvePipelineSteps, n as buildActionPipelineHandler, u as sendControllerResponse } from "./actionPermissions-jlFZ1it4.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-XvcI_3sh.mjs";
7
- import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-CIXShch7.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-DjDuyglE.mjs";
3
+ import "./constants-BxLgNFF7.mjs";
4
+ import { f as createError } from "./errors-C_YhELhe.mjs";
5
+ import { i as resolvePipelineSteps, n as buildActionPipelineHandler, u as sendControllerResponse } from "./actionPermissions-DPwPWPOV.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-DRsSHPSM.mjs";
7
+ import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-K16Bb5BX.mjs";
8
8
  //#region src/core/createActionRouter.ts
9
9
  var createActionRouter_exports = /* @__PURE__ */ __exportAll({
10
10
  buildActionBodySchema: () => buildActionBodySchema,
@@ -1,10 +1,10 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { n as evaluateAndApplyPermission } from "./authorizationDecision-BP8GHtjc.mjs";
3
- import { f as createError } from "./errors-2ExmOgIJ.mjs";
4
- import { u as getRequestScope } from "./types-BqLyyH0o.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-XvcI_3sh.mjs";
6
- import { n as validateAggregations } from "./validate-CidSeUrx.mjs";
7
- import { t as buildAggregationHandler } from "./buildHandler-DjXOqIvX.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { n as evaluateAndApplyPermission } from "./authorizationDecision-2YY_Kaj1.mjs";
3
+ import { f as createError } from "./errors-C_YhELhe.mjs";
4
+ import { u as getRequestScope } from "./types-CDy3-zw1.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-DRsSHPSM.mjs";
6
+ import { n as validateAggregations } from "./validate-R0G_JrnK.mjs";
7
+ import { t as buildAggregationHandler } from "./buildHandler-CUhjGHGZ.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
@@ -0,0 +1,48 @@
1
+
2
+ import { _ as ToolDefinition, c as McpAuthResult, r as CreateMcpServerConfig } from "./types-CWQn9-IC.mjs";
3
+ //#region src/integrations/mcp/createMcpServer.d.ts
4
+ /**
5
+ * Mutable auth ref — updated per-request by mcpPlugin.
6
+ * Tool handlers read from this to get the current request's auth context.
7
+ */
8
+ interface AuthRef {
9
+ current: McpAuthResult | null;
10
+ }
11
+ /**
12
+ * Create a configured MCP server from declarative config.
13
+ *
14
+ * @param config - Server name, version, tools, prompts
15
+ * @returns McpServer instance (not yet connected to a transport)
16
+ */
17
+ declare function createMcpServer(config: CreateMcpServerConfig, authRef?: AuthRef): Promise<McpServerInstance>;
18
+ /**
19
+ * Detect and resolve duplicate MCP tool names across the assembled tool list.
20
+ *
21
+ * Two outcomes:
22
+ *
23
+ * 1. **Auto-namespace** — when one tool's `source` carries a `preset:<name>`
24
+ * prefix and the other doesn't, the preset tool is renamed to
25
+ * `<presetName>_<originalName>` (e.g. softDelete's `restore_post`
26
+ * becomes `softdelete_restore_post` when the user defines
27
+ * `actions.restore`). The user's tool wins the canonical name because
28
+ * it's the more-specific intent.
29
+ *
30
+ * 2. **Typed throw** — every other collision (two user actions, two
31
+ * custom routes, two presets) raises `ArcError('arc.mcp.tool_name_collision')`
32
+ * naming both sources so the host's stack trace points at the
33
+ * resource definitions, not the MCP SDK internals.
34
+ *
35
+ * Exported for the testing harness so collision behaviour can be exercised
36
+ * without a full server boot.
37
+ */
38
+ declare function resolveToolCollisions(tools: readonly ToolDefinition[]): ToolDefinition[];
39
+ /** Minimal interface for McpServer — avoids hard SDK type dependency */
40
+ interface McpServerInstance {
41
+ connect: (transport: unknown) => Promise<void>;
42
+ registerTool: (name: string, config: Record<string, unknown>, handler: (input: Record<string, unknown>, extra: Record<string, unknown>) => unknown) => unknown;
43
+ registerPrompt: (name: string, config: Record<string, unknown>, handler: (args: Record<string, unknown>) => unknown) => void;
44
+ /** v2 name. v1 called this `resource()` — same four arguments. */
45
+ registerResource: (...args: unknown[]) => void;
46
+ }
47
+ //#endregion
48
+ export { resolveToolCollisions as i, McpServerInstance as n, createMcpServer as r, AuthRef as t };
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
2
  //#region src/core/aggregation/defineAggregation.ts
3
3
  /**
4
4
  * Declare a single resource aggregation. Exported configs flow into
@@ -1,20 +1,20 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { p as MUTATION_OPERATIONS, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-BONghE1Y.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { p as MUTATION_OPERATIONS, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-BxLgNFF7.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { r as ForbiddenError } from "./errors-2ExmOgIJ.mjs";
5
- import { n as getUserRoles } from "./userHelpers-CXySQFRg.mjs";
6
- import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-BqLyyH0o.mjs";
7
- import { d as isWriteVerbCapable, p as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController, u as detectOverriddenWriteSlots } from "./BaseController-CYaDvmOB.mjs";
8
- import { v as getDefaultCrudSchemas } from "./utils-BbGG8XNT.mjs";
9
- import { a as resolveEffectiveRoles, n as applyFieldWritePermissions } from "./fields-Cha2QCKH.mjs";
10
- import { n as convertRouteSchema, r as ensureSchemaConverter, t as convertOpenApiSchemas } from "./schemaConverter-Db-MMsH6.mjs";
11
- import { i as pipeUIMessageStreamToReply, r as isReadableStream } from "./streaming-DkpW1HwJ.mjs";
12
- import { a as createCrudHandlers, i as resolvePipelineSteps, o as createFastifyHandler, r as buildPipelineHandler, s as createRequestContext, t as resolveActionPermission } from "./actionPermissions-jlFZ1it4.mjs";
13
- import { a as selectPluginMw, c as buildRouteHooks, d as buildAuthMiddleware, i as resolveRouterPluginMw, l as resolveRoutePreHandlers, n as buildRateLimitConfig, p as buildArcDecorator, r as buildRouteConfig, s as buildCrudPermissionMw, t as tryRegisterRoute, u as routeHookOptions } from "./registerRoute-XvcI_3sh.mjs";
14
- import { t as hasEvents } from "./typeGuards-DHTnEs5X.mjs";
15
- import { B as requireAuth } from "./permissions-H7Zcb82Z.mjs";
16
- import { r as getAvailablePresets, t as applyPresets } from "./presets-CNyfaxGL.mjs";
17
- import { t as pluralize } from "./pluralize-Da7IT_qJ.mjs";
4
+ import { r as ForbiddenError } from "./errors-C_YhELhe.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-DDMOZ_Pm.mjs";
6
+ import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-CDy3-zw1.mjs";
7
+ import { d as isWriteVerbCapable, p as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController, u as detectOverriddenWriteSlots } from "./BaseController-DYJRZ0EJ.mjs";
8
+ import { y as getDefaultCrudSchemas } from "./utils-B-zj_b__.mjs";
9
+ import { a as resolveEffectiveRoles, n as applyFieldWritePermissions } from "./fields-BTyPLHK0.mjs";
10
+ import { n as convertRouteSchema, r as ensureSchemaConverter, t as convertOpenApiSchemas } from "./schemaConverter-BLCSmNbr.mjs";
11
+ import { i as pipeUIMessageStreamToReply, r as isReadableStream } from "./streaming-dvppnxsr.mjs";
12
+ import { a as createCrudHandlers, i as resolvePipelineSteps, o as createFastifyHandler, r as buildPipelineHandler, s as createRequestContext, t as resolveActionPermission } from "./actionPermissions-DPwPWPOV.mjs";
13
+ import { a as selectPluginMw, c as buildRouteHooks, d as buildAuthMiddleware, i as resolveRouterPluginMw, l as resolveRoutePreHandlers, n as buildRateLimitConfig, p as buildArcDecorator, r as buildRouteConfig, s as buildCrudPermissionMw, t as tryRegisterRoute, u as routeHookOptions } from "./registerRoute-DRsSHPSM.mjs";
14
+ import { t as hasEvents } from "./typeGuards-D7tHFdH6.mjs";
15
+ import { B as requireAuth } from "./permissions-DiHXy8Ck.mjs";
16
+ import { r as getAvailablePresets, t as applyPresets } from "./presets-BdlugYTc.mjs";
17
+ import { t as pluralize } from "./pluralize-2_U6QZQg.mjs";
18
18
  import { isReadOnlyRepo } from "@classytic/repo-core/repository";
19
19
  //#region src/core/middlewares/fieldWrite.ts
20
20
  /**
@@ -1425,7 +1425,7 @@ function buildResourcePlugin(resource) {
1425
1425
  extensions: resource.extensions
1426
1426
  });
1427
1427
  if (resource.actions && Object.keys(resource.actions).length > 0) {
1428
- const { createActionRouter } = await import("./createActionRouter-Bqi6Bhhx.mjs").then((n) => n.n);
1428
+ const { createActionRouter } = await import("./createActionRouter-BBlbPs3k.mjs").then((n) => n.n);
1429
1429
  createActionRouter(typedInstance, {
1430
1430
  ...normalizeActionsToRouterConfig(resource.actions, resource.actionPermissions, resource.tag, resource.permissions, resource.name, typedInstance.log),
1431
1431
  resourceName: resource.name,
@@ -1440,7 +1440,7 @@ function buildResourcePlugin(resource) {
1440
1440
  });
1441
1441
  }
1442
1442
  if (resource.aggregations && Object.keys(resource.aggregations).length > 0) {
1443
- const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-BsYO7ktd.mjs"), import("./validate-CidSeUrx.mjs").then((n) => n.r)]);
1443
+ const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-Dv5SuK2x.mjs"), import("./validate-R0G_JrnK.mjs").then((n) => n.r)]);
1444
1444
  const repoForAgg = resource.controller?.repository ?? resource.repository;
1445
1445
  if (!adapterSupportsAggregate(repoForAgg)) {
1446
1446
  const undispatchable = Object.entries(resource.aggregations).filter(([, cfg]) => !cfg.materialized).map(([name]) => name);
@@ -2457,10 +2457,8 @@ function defineResource(config) {
2457
2457
  const configWithId = resolveIdField(normalisedConfig, repository);
2458
2458
  const resolvedConfig = applyPresetsAndAutoInject(configWithId);
2459
2459
  const hasCrudRoutes = computeHasCrudRoutes(resolvedConfig);
2460
- if (!normalisedConfig.skipValidation) {
2461
- const strict = resolvedConfig.strictPermissions ?? process.env.ARC_STRICT_PERMISSIONS === "true";
2462
- diagnostics = diagnostics.concat(collectUngatedCrudDiagnostics(resolvedConfig, strict));
2463
- }
2460
+ const strict = resolvedConfig.strictPermissions ?? process.env.ARC_STRICT_PERMISSIONS === "true";
2461
+ diagnostics = diagnostics.concat(collectUngatedCrudDiagnostics(resolvedConfig, strict));
2464
2462
  const fatal = diagnostics.filter((d) => d.severity === "error");
2465
2463
  if (fatal.length > 0) throw new Error(fatal.map((d) => d.message).join("\n\n"));
2466
2464
  const narrowedConfig = resolvedConfig;
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
2
  import { readdir } from "node:fs/promises";
3
3
  import { extname, join, resolve } from "node:path";
4
4
  import { pathToFileURL } from "node:url";
@@ -1,5 +1,5 @@
1
1
 
2
- import { p as RegistryEntry } from "../index-B78WZom8.mjs";
2
+ import { p as RegistryEntry } from "../index-DHbyPo5j.mjs";
3
3
  import { t as ExternalOpenApiPaths } from "../externalPaths-CmGOxOtD.mjs";
4
4
  import { FastifyPluginAsync } from "fastify";
5
5
  //#region src/docs/openapi/types.d.ts
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { n as getUserRoles } from "../userHelpers-CXySQFRg.mjs";
3
- import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-Dxc8RLy_.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { n as getUserRoles } from "../userHelpers-DDMOZ_Pm.mjs";
3
+ import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-C3LFRzPq.mjs";
4
4
  import fp from "fastify-plugin";
5
5
  //#region src/docs/scalar.ts
6
6
  const scalarPlugin = async (fastify, opts = {}) => {
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-Add2L50I.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-DjDuyglE.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { n as requireSingleHeaderValue } from "./headers-DeXNifVj.mjs";
5
- import { n as getUserRoles } from "./userHelpers-CXySQFRg.mjs";
4
+ import { n as requireSingleHeaderValue } from "./headers-CNECDE6q.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-DDMOZ_Pm.mjs";
6
6
  import fp from "fastify-plugin";
7
7
  //#region src/scope/elevation.ts
8
8
  var elevation_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as ArcError } from "../errors-2ExmOgIJ.mjs";
3
- import { t as parseJsonBody } from "../jsonBody-DVui0uJl.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as ArcError } from "../errors-C_YhELhe.mjs";
3
+ import { t as parseJsonBody } from "../jsonBody-Cq9KYl2Z.mjs";
4
4
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
5
5
  import fp from "fastify-plugin";
6
6
  //#region src/encryption/fieldCipher.ts
@@ -7,7 +7,13 @@ import { FastifyInstance, FastifyRequest } from "fastify";
7
7
  * to a partial `ErrorContract`. Highest-priority dispatch in the handler.
8
8
  */
9
9
  interface ErrorMapper<T extends Error = Error> {
10
- type: abstract new (...args: any[]) => T;
10
+ /**
11
+ * Only ever used as `error instanceof mapper.type` — the constructor is never
12
+ * CALLED through this interface, so `never[]` is the sound parameter type:
13
+ * every real class assigns to it (constructor parameters are contravariant),
14
+ * and nothing can invoke it. `any[]` here was a permission nothing used.
15
+ */
16
+ type: abstract new (...args: never[]) => T;
11
17
  toResponse: (error: T) => {
12
18
  status: number;
13
19
  code?: string;
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-Add2L50I.mjs";
3
- import { m as statusToArcCode, p as isArcError } from "./errors-2ExmOgIJ.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-DjDuyglE.mjs";
3
+ import { m as statusToArcCode, p as isArcError } from "./errors-C_YhELhe.mjs";
4
4
  import { isProductionEnv } from "@classytic/primitives/environment";
5
5
  import { isHttpError, toErrorContract } from "@classytic/repo-core/errors";
6
6
  import fp from "fastify-plugin";
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
2
  //#region src/utils/errors.ts
3
3
  /**
4
4
  * Base Arc Error. Implements the canonical `HttpError` contract — `status`
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler, s as MemoryEventTransportOptions } from "./EventTransport-Cx60_s-6.mjs";
2
+ import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler, s as MemoryEventTransportOptions } from "./EventTransport-CbUKDzZZ.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
  //#region src/events/defineEvent.d.ts
5
5
  interface EventSchema {
@@ -1,9 +1,9 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-Add2L50I.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-DjDuyglE.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { d as createDomainError } from "./errors-2ExmOgIJ.mjs";
5
- import { n as requestContext } from "./requestContext-DpmntRZy.mjs";
6
- import { n as MemoryEventTransport, r as createEvent, t as ARC_EVENT_TRANSPORT } from "./EventTransport-Gq7JWbWw.mjs";
4
+ import { d as createDomainError } from "./errors-C_YhELhe.mjs";
5
+ import { n as requestContext } from "./requestContext-cSVKnYPk.mjs";
6
+ import { n as MemoryEventTransport, r as createEvent, t as ARC_EVENT_TRANSPORT } from "./EventTransport-n7qO5Cz3.mjs";
7
7
  import { isProductionEnv } from "@classytic/primitives/environment";
8
8
  import fp from "fastify-plugin";
9
9
  //#region src/events/retry.ts
@@ -1,9 +1,9 @@
1
1
 
2
- import { i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions } from "../EventTransport-Cx60_s-6.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-DFvHa4Nf.mjs";
4
- import { a as EventOutbox, c as OutboxRelayErrorKind, i as MemoryOutboxStore, l as RelayResult, n as OutboxModuleOptions, o as EventOutboxOptions, r as createOutboxModule, s as OutboxRelayErrorHandler, t as OutboxModuleExports } from "../outbox-module-CQXu_O6o.mjs";
2
+ import { i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions } from "../EventTransport-CbUKDzZZ.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-B52abJ8W.mjs";
4
+ import { a as EventOutbox, c as OutboxRelayErrorKind, i as MemoryOutboxStore, l as RelayResult, n as OutboxModuleOptions, o as EventOutboxOptions, r as createOutboxModule, s as OutboxRelayErrorHandler, t as OutboxModuleExports } from "../outbox-module-BHdUnuuK.mjs";
5
5
  import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
6
- import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-eh0eOtjh.mjs";
6
+ import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-BPKscsTB.mjs";
7
7
  import { OutboxStore } from "@classytic/primitives/outbox";
8
8
  import { RepositoryLike } from "@classytic/repo-core/adapter";
9
9
  //#region src/events/eventTypes.d.ts
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.38.0 | MIT | https://classytic.com */
2
- import { n as MemoryEventTransport } from "../EventTransport-Gq7JWbWw.mjs";
3
- import { a as createEventRegistry, i as wrapWithSchema, n as subscribeWithSchema, o as defineEvent, r as wrapWithBoundary, t as subscribeWithBoundary } from "../subscribe-helpers-CBZOi6pk.mjs";
4
- import { i as withRetry, r as createDeadLetterPublisher, t as eventPlugin } from "../eventPlugin-DJwpGMzx.mjs";
5
- import { i as exponentialBackoff, n as EventOutbox, r as repositoryAsOutboxStore, t as createOutboxModule } from "../outbox-module-DyIqA5vo.mjs";
1
+ /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
+ import { n as MemoryEventTransport } from "../EventTransport-n7qO5Cz3.mjs";
3
+ import { a as createEventRegistry, i as wrapWithSchema, n as subscribeWithSchema, o as defineEvent, r as wrapWithBoundary, t as subscribeWithBoundary } from "../subscribe-helpers-AVYPgqTl.mjs";
4
+ import { i as withRetry, r as createDeadLetterPublisher, t as eventPlugin } from "../eventPlugin-CmXaPWLv.mjs";
5
+ import { i as exponentialBackoff, n as EventOutbox, r as repositoryAsOutboxStore, t as createOutboxModule } from "../outbox-module-dsCyLxXH.mjs";
6
6
  import { MemoryOutboxStore } from "@classytic/primitives/memory-outbox";
7
7
  //#region src/events/eventTypes.ts
8
8
  /**
@@ -1,3 +1,3 @@
1
1
 
2
- import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-eh0eOtjh.mjs";
2
+ import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-BPKscsTB.mjs";
3
3
  export { type RedisStreamLike, RedisStreamTransport, type RedisStreamTransportOptions };