@classytic/arc 2.11.2 → 2.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +20 -21
  3. package/bin/arc.js +2 -2
  4. package/dist/{BaseController-JNV08qOT.mjs → BaseController-swXruJ2_.mjs} +2 -2
  5. package/dist/EventTransport-BFQjw9pB.mjs +133 -0
  6. package/dist/{QueryCache-DOBNHBE0.d.mts → QueryCache-D41bfdBB.d.mts} +1 -1
  7. package/dist/{actionPermissions-C8YYU92K.mjs → actionPermissions-sUUKDhtP.mjs} +4 -2
  8. package/dist/adapters/index.d.mts +3 -3
  9. package/dist/adapters/index.mjs +2 -2
  10. package/dist/{adapters-D0tT2Tyo.mjs → adapters-DUUiiimH.mjs} +17 -2
  11. package/dist/audit/index.d.mts +2 -2
  12. package/dist/auth/index.d.mts +4 -4
  13. package/dist/auth/index.mjs +1 -1
  14. package/dist/auth/redis-session.d.mts +1 -1
  15. package/dist/cache/index.d.mts +3 -3
  16. package/dist/cli/commands/docs.mjs +1 -1
  17. package/dist/cli/commands/generate.d.mts +0 -2
  18. package/dist/cli/commands/generate.mjs +16 -16
  19. package/dist/cli/commands/init.mjs +149 -65
  20. package/dist/context/index.mjs +1 -1
  21. package/dist/core/index.d.mts +2 -2
  22. package/dist/core/index.mjs +3 -3
  23. package/dist/{core-DXdSSFW-.mjs → core-CbcQRIch.mjs} +25 -8
  24. package/dist/{createActionRouter-BwaSM0No.mjs → createActionRouter-CIKOcNA7.mjs} +74 -14
  25. package/dist/{createApp-P1d6rjPy.mjs → createApp-C9bRrqlX.mjs} +4 -6
  26. package/dist/defineEvent-D1Ky9M1D.mjs +188 -0
  27. package/dist/docs/index.d.mts +2 -2
  28. package/dist/docs/index.mjs +1 -1
  29. package/dist/{eventPlugin--5HIkdPU.mjs → eventPlugin-Cts2-Tfj.mjs} +9 -135
  30. package/dist/{eventPlugin-CUNjYYRY.d.mts → eventPlugin-DDJoNEPL.d.mts} +34 -7
  31. package/dist/events/index.d.mts +164 -5
  32. package/dist/events/index.mjs +138 -182
  33. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  34. package/dist/events/transports/redis-stream-entry.mjs +204 -31
  35. package/dist/events/transports/redis.d.mts +1 -1
  36. package/dist/factory/index.d.mts +1 -1
  37. package/dist/factory/index.mjs +1 -1
  38. package/dist/{fields-C8Y0XLAu.d.mts → fields-BRjxOAFp.d.mts} +1 -1
  39. package/dist/hooks/index.d.mts +1 -1
  40. package/dist/idempotency/index.d.mts +3 -3
  41. package/dist/idempotency/index.mjs +1 -1
  42. package/dist/idempotency/redis.d.mts +1 -1
  43. package/dist/{index-6u4_Gg6G.d.mts → index-CXXRbnf8.d.mts} +51 -5
  44. package/dist/{index-DdQ3O9Pg.d.mts → index-D9t1KNaB.d.mts} +2 -2
  45. package/dist/{index-BbMrcvGp.d.mts → index-Rg8axYPz.d.mts} +12 -4
  46. package/dist/{index-BdXnTPRj.d.mts → index-m8mOOlFW.d.mts} +3 -3
  47. package/dist/{index-BYCqHCVu.d.mts → index-rHjXmJar.d.mts} +3 -3
  48. package/dist/index.d.mts +7 -7
  49. package/dist/index.mjs +7 -7
  50. package/dist/integrations/event-gateway.d.mts +2 -2
  51. package/dist/integrations/index.d.mts +2 -2
  52. package/dist/integrations/mcp/index.d.mts +2 -2
  53. package/dist/integrations/mcp/index.mjs +1 -1
  54. package/dist/integrations/mcp/testing.d.mts +1 -1
  55. package/dist/integrations/mcp/testing.mjs +1 -1
  56. package/dist/integrations/websocket-redis.d.mts +1 -1
  57. package/dist/integrations/websocket.d.mts +1 -1
  58. package/dist/middleware/index.d.mts +1 -1
  59. package/dist/{openapi-C0L9ar7m.mjs → openapi-D7G1V7ex.mjs} +2 -2
  60. package/dist/org/index.d.mts +2 -2
  61. package/dist/permissions/index.d.mts +2 -2
  62. package/dist/permissions/index.mjs +1 -1
  63. package/dist/{permissions-B4vU9L0Q.mjs → permissions-gd_aUWrR.mjs} +42 -0
  64. package/dist/pipeline/index.d.mts +1 -1
  65. package/dist/plugins/index.d.mts +5 -5
  66. package/dist/plugins/index.mjs +1 -1
  67. package/dist/plugins/tracing-entry.d.mts +1 -1
  68. package/dist/plugins/tracing-entry.mjs +1 -1
  69. package/dist/presets/filesUpload.d.mts +4 -4
  70. package/dist/presets/filesUpload.mjs +1 -1
  71. package/dist/presets/index.d.mts +1 -1
  72. package/dist/presets/index.mjs +1 -1
  73. package/dist/presets/multiTenant.d.mts +1 -1
  74. package/dist/presets/search.d.mts +2 -2
  75. package/dist/presets/search.mjs +1 -1
  76. package/dist/{presets-k604Lj99.mjs → presets-Z7P5w4gF.mjs} +1 -1
  77. package/dist/{queryCachePlugin-BUXBSm4F.d.mts → queryCachePlugin-CqMdLI2-.d.mts} +2 -2
  78. package/dist/{redis-Cm1gnRDf.d.mts → redis-DiMkdHEl.d.mts} +1 -1
  79. package/dist/redis-stream-xTGxB2bm.d.mts +232 -0
  80. package/dist/registry/index.d.mts +1 -1
  81. package/dist/{requestContext-CfRkaxwf.mjs → requestContext-C5XeK3VA.mjs} +15 -0
  82. package/dist/{resourceToTools--okX6QBr.mjs → resourceToTools-CxNmI6xF.mjs} +7 -6
  83. package/dist/{routerShared-DeESFp4a.mjs → routerShared-BqLRb5l7.mjs} +60 -3
  84. package/dist/scope/index.d.mts +2 -2
  85. package/dist/testing/index.d.mts +2 -2
  86. package/dist/testing/index.mjs +1 -1
  87. package/dist/testing/storageContract.d.mts +1 -1
  88. package/dist/types/index.d.mts +4 -4
  89. package/dist/types/storage.d.mts +1 -1
  90. package/dist/{types-9beEMe25.d.mts → types-BQ9TJQNy.d.mts} +1 -1
  91. package/dist/{types-BH7dEGvU.d.mts → types-D7KpfiL1.d.mts} +10 -10
  92. package/dist/utils/index.d.mts +1 -1
  93. package/dist/utils/index.mjs +1 -1
  94. package/dist/{utils-D3Yxnrwr.mjs → utils-CcYTj09l.mjs} +1 -1
  95. package/dist/{versioning-M9lNLhO8.d.mts → versioning-DsglKfM_.d.mts} +1 -1
  96. package/package.json +3 -1
  97. package/skills/arc/SKILL.md +409 -769
  98. package/skills/arc/references/events.md +489 -489
  99. package/dist/redis-stream-CM8TXTix.d.mts +0 -110
  100. /package/dist/{EventTransport-CfVEGaEl.d.mts → EventTransport-CYNUXdCJ.d.mts} +0 -0
  101. /package/dist/{elevation-s5ykdNHr.d.mts → elevation-BQQXZ_VR.d.mts} +0 -0
  102. /package/dist/{errorHandler-Co3lnVmJ.d.mts → errorHandler-DEWmGWPz.d.mts} +0 -0
  103. /package/dist/{externalPaths-Bapitwvd.d.mts → externalPaths-BD5nw6St.d.mts} +0 -0
  104. /package/dist/{interface-CkkWm5uR.d.mts → interface-DfLGcus7.d.mts} +0 -0
  105. /package/dist/{interface-Da0r7Lna.d.mts → interface-beEtJyWM.d.mts} +0 -0
  106. /package/dist/{pluralize-BneOJkpi.mjs → pluralize-CWP6MB39.mjs} +0 -0
  107. /package/dist/{schemaIR-BlG9bY7v.mjs → schemaIR-Dy2p4MxS.mjs} +0 -0
  108. /package/dist/{sessionManager-D-oNWHz3.d.mts → sessionManager-C4Le_UB3.d.mts} +0 -0
  109. /package/dist/{storage-BwGQXUpd.d.mts → storage-Dfzt4VTl.d.mts} +0 -0
  110. /package/dist/{store-helpers-BhrzxvyQ.mjs → store-helpers-Cp4uKC1U.mjs} +0 -0
  111. /package/dist/{tracing-DokiEsuz.d.mts → tracing-QJVprktp.d.mts} +0 -0
  112. /package/dist/{types-tgR4Pt8F.d.mts → types-DDyTPc6y.d.mts} +0 -0
  113. /package/dist/{websocket-CyJ1VIFI.d.mts → websocket-ChC2rqe1.d.mts} +0 -0
@@ -0,0 +1,232 @@
1
+ import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "./EventTransport-CYNUXdCJ.mjs";
2
+
3
+ //#region src/events/transports/redis-stream.d.ts
4
+ interface RedisStreamLike {
5
+ xadd(key: string, id: string, ...fieldValues: string[]): Promise<string | null>;
6
+ xreadgroup(command: "GROUP", group: string, consumer: string, ...args: (string | number)[]): Promise<Array<[string, Array<[string, string[]]>]> | null>;
7
+ xack(key: string, group: string, ...ids: string[]): Promise<number>;
8
+ xgroup(command: string, key: string, group: string, ...args: string[]): Promise<unknown>;
9
+ xpending(key: string, group: string, ...args: (string | number)[]): Promise<Array<[string, string, number, number]>>;
10
+ xclaim(key: string, group: string, consumer: string, minIdleTime: number, ...ids: string[]): Promise<Array<[string, string[]]>>;
11
+ xlen(key: string): Promise<number>;
12
+ /**
13
+ * Read a range of entries by id. When present, the DLQ writer uses this
14
+ * to fetch the original message payload so dead-lettered events are
15
+ * **fully replayable** (a re-publish of `envelope.event` is sufficient).
16
+ *
17
+ * Optional to preserve back-compat with custom Redis wrappers that
18
+ * satisfied the pre-2.11.3 shape. When missing, the DLQ envelope still
19
+ * carries the **error reason + attempt accounting** (operator-grade
20
+ * triage info survives), but `envelope.event.payload` is `null` and
21
+ * `envelope.event.type` is `<unknown>` — replay is NOT possible without
22
+ * upgrading the client. A one-shot warning fires per process so this
23
+ * isn't silent.
24
+ */
25
+ xrange?(key: string, start: string, end: string): Promise<Array<[string, string[]]>>;
26
+ /** Graceful close — flushes queued commands then closes. ioredis-style. */
27
+ quit(): Promise<unknown>;
28
+ /**
29
+ * Force-disconnect — closes the socket immediately, abandoning any
30
+ * pending command (including a live `XREADGROUP BLOCK`). Optional because
31
+ * non-ioredis clients may not expose a force path; `close()` falls back
32
+ * to `quit()` when this is missing, accepting a longer shutdown wait.
33
+ */
34
+ disconnect?(): void;
35
+ }
36
+ interface RedisStreamTransportOptions {
37
+ /**
38
+ * Redis stream key name.
39
+ * @default 'arc:events'
40
+ */
41
+ stream?: string;
42
+ /**
43
+ * Consumer group name. Each group receives every event independently.
44
+ * Multiple instances of the same service should share a group name.
45
+ * @default 'default'
46
+ */
47
+ group?: string;
48
+ /**
49
+ * Consumer name within the group. Must be unique per instance.
50
+ * @default 'consumer-<random>'
51
+ */
52
+ consumer?: string;
53
+ /**
54
+ * Block time in ms when waiting for new events.
55
+ * @default 5000
56
+ */
57
+ blockTimeMs?: number;
58
+ /**
59
+ * Max events to read per batch.
60
+ * @default 10
61
+ */
62
+ batchSize?: number;
63
+ /**
64
+ * Max delivery attempts before moving to dead letter stream.
65
+ * @default 5
66
+ */
67
+ maxRetries?: number;
68
+ /**
69
+ * Idle time in ms before pending entries are claimed by this consumer.
70
+ * Handles crash recovery — if a consumer dies mid-processing, another
71
+ * consumer will claim its pending entries after this timeout.
72
+ * @default 30000
73
+ */
74
+ claimTimeoutMs?: number;
75
+ /**
76
+ * Dead letter stream name. Failed events are moved here after maxRetries.
77
+ * Set to `false` to disable DLQ (failed events are acked and dropped).
78
+ * @default 'arc:events:dlq'
79
+ */
80
+ deadLetterStream?: string | false;
81
+ /**
82
+ * Max stream length (approximate). Uses XADD MAXLEN ~ to trim old entries.
83
+ * Set to 0 to disable trimming.
84
+ * @default 10000
85
+ */
86
+ maxLen?: number;
87
+ /**
88
+ * Max event payload size in bytes. Publish rejects events exceeding this limit
89
+ * to prevent Redis memory exhaustion from oversized payloads.
90
+ * @default 1_000_000 (1 MB)
91
+ */
92
+ maxPayloadBytes?: number;
93
+ /**
94
+ * If `true`, `close()` does NOT call `redis.quit()` — useful when the host
95
+ * manages the Redis connection lifecycle externally (shared client across
96
+ * multiple transports / cache stores). Without this, every transport
97
+ * `close()` would tear down a shared client and break siblings.
98
+ *
99
+ * Mirror of `RedisEventTransportOptions.externalLifecycle`.
100
+ * @default false
101
+ */
102
+ externalLifecycle?: boolean;
103
+ /**
104
+ * Hard cap on how long `close()` waits for the in-flight `XREADGROUP BLOCK`
105
+ * iteration to drain. Tests and serverless shutdowns would otherwise hang
106
+ * up to `blockTimeMs` (default 5s) per close.
107
+ *
108
+ * Behaviour after timeout:
109
+ * - `externalLifecycle: false` (default) — `redis.disconnect()` (or
110
+ * `quit()` if the client lacks `disconnect`) breaks the BLOCK
111
+ * immediately. Strict bounded close.
112
+ * - `externalLifecycle: true` — arc CANNOT touch the host's connection,
113
+ * so the poll loop is left to drain in the background when its
114
+ * XREADGROUP returns. `close()` returns within `closeTimeoutMs` but
115
+ * the loop's eventual completion is silently absorbed (no log spam,
116
+ * no unhandled rejection). The contract here is "bounded return,
117
+ * background drain" — set `blockTimeMs` low (e.g. 500ms) under
118
+ * externalLifecycle to keep the drain window short.
119
+ *
120
+ * @default 1000
121
+ */
122
+ closeTimeoutMs?: number;
123
+ /**
124
+ * Logger for error messages (default: console).
125
+ * Pass `fastify.log` to integrate with your application logger.
126
+ */
127
+ logger?: EventLogger;
128
+ }
129
+ declare class RedisStreamTransport implements EventTransport {
130
+ readonly name = "redis-stream";
131
+ private redis;
132
+ private stream;
133
+ private group;
134
+ private consumer;
135
+ private blockTimeMs;
136
+ private batchSize;
137
+ private maxRetries;
138
+ private claimTimeoutMs;
139
+ private deadLetterStream;
140
+ private maxLen;
141
+ private maxPayloadBytes;
142
+ private logger;
143
+ /** Tracks the lifecycle policy — set in constructor, read in close(). */
144
+ private externalLifecycle;
145
+ private closeTimeoutMs;
146
+ private handlers;
147
+ private running;
148
+ private pollPromise;
149
+ /**
150
+ * Monotonic counter bumped every time the poll loop should stop —
151
+ * `unsubscribe` (last handler removed) and `close()` increment it. Each
152
+ * `pollLoop` instance captures its generation at start and exits when
153
+ * `this.generation` no longer matches. Prevents the
154
+ * subscribe → unsubscribe → fast-resubscribe race where the old loop
155
+ * would still be in `XREADGROUP BLOCK` while a new loop started, leading
156
+ * to two concurrent poll loops on the same consumer name.
157
+ */
158
+ private generation;
159
+ private groupCreated;
160
+ /**
161
+ * Last-seen failure context per message id, populated when an in-process
162
+ * handler throws in {@link processEntry}. Consumed (and cleared) by
163
+ * {@link moveToDlq} so the dead-letter envelope carries the actual error
164
+ * message instead of opaque "reclaimed without context". Bounded by
165
+ * `maxRetries × consumer-throughput` — entries are deleted on ack and
166
+ * on DLQ write, so the map naturally drains.
167
+ */
168
+ private failureContext;
169
+ /** One-shot guard so the "client lacks xrange" warning fires once per process. */
170
+ private xrangeWarningEmitted;
171
+ constructor(redis: RedisStreamLike, options?: RedisStreamTransportOptions);
172
+ publish(event: DomainEvent): Promise<void>;
173
+ subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
174
+ /**
175
+ * Stop polling and release transport state.
176
+ *
177
+ * **Two close contracts** — pick the one that matches your deployment:
178
+ *
179
+ * 1. **Default (`externalLifecycle: false`) — strict bounded close.**
180
+ * `close()` waits up to `closeTimeoutMs` for the in-flight
181
+ * `XREADGROUP BLOCK` to drain. On timeout it calls `redis.disconnect()`
182
+ * (or `quit()` if the client lacks `disconnect`) to break the BLOCK
183
+ * immediately, then awaits the loop's exit. After `close()` returns
184
+ * the transport is fully closed and the connection is released.
185
+ *
186
+ * 2. **`externalLifecycle: true` — bounded RETURN, background drain.**
187
+ * Arc must NOT touch a connection it doesn't own. `close()` returns
188
+ * within `closeTimeoutMs`, but the poll loop is left to drain on its
189
+ * own when its outstanding `XREADGROUP BLOCK` returns (up to
190
+ * `blockTimeMs`). Arc silently absorbs the loop's eventual completion
191
+ * so the host doesn't see unhandled rejections / log spam against a
192
+ * transport it considers closed. The host's own `redis.quit()` /
193
+ * process exit is what ultimately tears the connection down.
194
+ *
195
+ * Practical implication: under `externalLifecycle: true`, set
196
+ * `blockTimeMs` low (e.g. 500ms) so the background drain window is
197
+ * short. The transport is "closed enough" to stop dispatching to
198
+ * handlers (handlers map is cleared and generation is bumped) but is
199
+ * not "fully closed" in the connection-lifecycle sense until the host
200
+ * closes the underlying client.
201
+ *
202
+ * In both modes the generation counter is bumped, so a follow-up
203
+ * `subscribe()` spawns a fresh poll loop with a new generation — the
204
+ * stale loop exits on its next iteration and never overlaps the new one.
205
+ */
206
+ close(): Promise<void>;
207
+ private ensureGroup;
208
+ private pollLoop;
209
+ private readNewMessages;
210
+ private claimPending;
211
+ private processEntry;
212
+ private getMatchingHandlers;
213
+ private matchesPattern;
214
+ private moveToDlq;
215
+ /**
216
+ * Reconstruct a `DeadLetteredEvent` for a message id. Reads the original
217
+ * entry via `xrange` (when the client supports it) and merges in any
218
+ * in-process failure context. Returns `null` only when BOTH sources are
219
+ * missing — callers ack-and-drop rather than re-queuing a ghost.
220
+ *
221
+ * Graceful degradation paths:
222
+ * - Client lacks `xrange` (older custom wrappers) → log once, build the
223
+ * envelope from `failureContext` alone. Payload is absent but the
224
+ * error reason + attempt accounting still survive.
225
+ * - `xrange` throws (network blip, ACL) → same fallback.
226
+ * - Source entry trimmed before DLQ write → same fallback.
227
+ */
228
+ private buildDlqEnvelope;
229
+ private sleep;
230
+ }
231
+ //#endregion
232
+ export { RedisStreamTransport as n, RedisStreamTransportOptions as r, RedisStreamLike as t };
@@ -1,4 +1,4 @@
1
- import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-6u4_Gg6G.mjs";
1
+ import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-CXXRbnf8.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
 
4
4
  //#region src/registry/introspectionPlugin.d.ts
@@ -38,15 +38,30 @@ const storage = new AsyncLocalStorage();
38
38
  * - `getStore()` — alias for get() (matches Node.js API naming)
39
39
  */
40
40
  const requestContext = {
41
+ /**
42
+ * Get the current request context.
43
+ * Returns undefined if called outside a request lifecycle.
44
+ */
41
45
  get() {
42
46
  return storage.getStore();
43
47
  },
48
+ /**
49
+ * Alias for get() — matches Node.js AsyncLocalStorage API naming.
50
+ */
44
51
  getStore() {
45
52
  return storage.getStore();
46
53
  },
54
+ /**
55
+ * Run a function within a specific request context.
56
+ * Used internally by Arc's onRequest hook.
57
+ */
47
58
  run(store, fn) {
48
59
  return storage.run(store, fn);
49
60
  },
61
+ /**
62
+ * The underlying AsyncLocalStorage instance.
63
+ * Exposed for advanced use cases (testing, custom integrations).
64
+ */
50
65
  storage
51
66
  };
52
67
  //#endregion
@@ -1,10 +1,10 @@
1
- import { t as BaseController } from "./BaseController-JNV08qOT.mjs";
2
- import { A as normalizePermissionResult } from "./permissions-B4vU9L0Q.mjs";
3
- import { u as resolvePipelineSteps } from "./routerShared-DeESFp4a.mjs";
1
+ import { t as BaseController } from "./BaseController-swXruJ2_.mjs";
2
+ import { A as normalizePermissionResult } from "./permissions-gd_aUWrR.mjs";
3
+ import { u as resolvePipelineSteps } from "./routerShared-BqLRb5l7.mjs";
4
4
  import { t as executePipeline } from "./pipe-DVoIheVC.mjs";
5
- import { t as resolveActionPermission } from "./actionPermissions-C8YYU92K.mjs";
6
- import { i as shouldRejectAdditionalProperties, r as schemaIRToZodShape, t as normalizeSchemaIR } from "./schemaIR-BlG9bY7v.mjs";
7
- import { t as pluralize } from "./pluralize-BneOJkpi.mjs";
5
+ import { t as resolveActionPermission } from "./actionPermissions-sUUKDhtP.mjs";
6
+ import { i as shouldRejectAdditionalProperties, r as schemaIRToZodShape, t as normalizeSchemaIR } from "./schemaIR-Dy2p4MxS.mjs";
7
+ import { t as pluralize } from "./pluralize-CWP6MB39.mjs";
8
8
  import { z } from "zod";
9
9
  //#region src/integrations/mcp/createMcpServer.ts
10
10
  /**
@@ -1145,6 +1145,7 @@ function resourceToTools(resource, config = {}) {
1145
1145
  resourcePermissions: resource.permissions,
1146
1146
  resourceActionPermissions: resource.actionPermissions
1147
1147
  });
1148
+ if (!actionPerms) throw new Error(`[Arc/MCP] Resource '${resource.name}': action '${actionName}' has no permission gate and the resource defines no \`permissions.update\` fallback. Declare one of:\n - \`actions.${actionName}.permissions: <PermissionCheck>\` (per-action)\n - \`actionPermissions: <PermissionCheck>\` (resource-wide)\n - \`permissions.update: <PermissionCheck>\` (inherited by actions)\nUse \`allowPublic()\` if you genuinely want the action unauthenticated.`);
1148
1149
  tools.push({
1149
1150
  name: toolName,
1150
1151
  description: String(description),
@@ -1,7 +1,7 @@
1
1
  import { _ as isElevated, n as PUBLIC_SCOPE, o as getOrgId, p as getUserId, v as isMember } from "./types-AOD8fxIw.mjs";
2
- import { P as resolveEffectiveRoles, j as applyFieldReadPermissions, k as evaluateAndApplyPermission } from "./permissions-B4vU9L0Q.mjs";
2
+ import { P as resolveEffectiveRoles, j as applyFieldReadPermissions, k as evaluateAndApplyPermission } from "./permissions-gd_aUWrR.mjs";
3
3
  import { t as getUserRoles } from "./types-DV9WDfeg.mjs";
4
- import { t as requestContext } from "./requestContext-CfRkaxwf.mjs";
4
+ import { t as requestContext } from "./requestContext-C5XeK3VA.mjs";
5
5
  import { t as executePipeline } from "./pipe-DVoIheVC.mjs";
6
6
  //#region src/scope/projection.ts
7
7
  /**
@@ -511,5 +511,62 @@ function buildPreHandlerChain(parts) {
511
511
  ...parts.customMws ?? []
512
512
  ].filter(Boolean);
513
513
  }
514
+ /**
515
+ * `RouteDefinition.preHandler` accepts two shapes:
516
+ *
517
+ * 1. **Array form** — `RouteHandlerMethod[]`. Used directly.
518
+ * 2. **Factory form** — `(fastify) => RouteHandlerMethod[]`. Called once at
519
+ * route-registration time with the Fastify instance, so handlers can
520
+ * capture decorators (`fastify.authenticate`, `fastify.events`, etc.)
521
+ * that aren't on the request.
522
+ *
523
+ * The two forms are equally idiomatic, but the discrimination is by
524
+ * `typeof preHandler === "function"`. Single-function shapes such as
525
+ * `multipartBody({...})` (a `RouteHandlerMethod`) **structurally satisfy
526
+ * the factory branch** at the call site, then fail with a cryptic
527
+ * `Cannot read properties of undefined (reading 'content-type')` once the
528
+ * handler runs with `fastify` in the request slot.
529
+ *
530
+ * This resolver:
531
+ * 1. Distinguishes the two valid shapes.
532
+ * 2. Validates the factory's RETURN — must be an array of functions.
533
+ * 3. Throws an actionable error pointing at the route + the fix when
534
+ * a single `RouteHandlerMethod` was passed instead of an array, OR
535
+ * when a factory returned the wrong shape.
536
+ *
537
+ * The error message names the route (`{method} {path}`) and the
538
+ * canonical fix (`preHandler: [yourHandler]`) so the failure mode is
539
+ * obvious instead of debug-archaeology.
540
+ *
541
+ * @param preHandler The `route.preHandler` value (any of the valid shapes
542
+ * plus the common bare-handler mistake).
543
+ * @param fastify Passed to factory-form preHandlers.
544
+ * @param routeId `"GET /todos/:id/attach"` (or similar) — used in the
545
+ * error message so a multi-route file points at the
546
+ * actual offender.
547
+ */
548
+ function resolveRoutePreHandlers(preHandler, fastify, routeId) {
549
+ if (preHandler === void 0 || preHandler === null) return [];
550
+ if (Array.isArray(preHandler)) return preHandler.filter((h) => typeof h === "function");
551
+ if (typeof preHandler === "function") {
552
+ let result;
553
+ try {
554
+ result = preHandler(fastify);
555
+ } catch (err) {
556
+ const msg = err instanceof Error ? err.message : String(err);
557
+ throw new TypeError(`Route ${routeId}: preHandler factory threw during route registration: ${msg}.\nIf you intended to pass a single handler (e.g. \`multipartBody({...})\`), wrap it in an array: \`preHandler: [yourHandler]\`. The factory form is \`(fastify) => RouteHandlerMethod[]\` — it must return an array.`, { cause: err instanceof Error ? err : void 0 });
558
+ }
559
+ if (!Array.isArray(result)) throw new TypeError(`Route ${routeId}: preHandler factory must return an array of handlers, got ${describeValue(result)}.\nCommon cause: passing a single \`RouteHandlerMethod\` (e.g. \`multipartBody({...})\`) where an array was expected. Wrap it: \`preHandler: [yourHandler]\`. The factory form \`(fastify) => RouteHandlerMethod[]\` is for cases that need the Fastify instance — e.g. \`(fastify) => [fastify.authenticate, myHandler]\`.`);
560
+ return result.filter((h) => typeof h === "function");
561
+ }
562
+ throw new TypeError(`Route ${routeId}: preHandler must be an array of handlers OR a factory \`(fastify) => RouteHandlerMethod[]\`. Got ${describeValue(preHandler)}.`);
563
+ }
564
+ function describeValue(v) {
565
+ if (v === null) return "null";
566
+ if (v === void 0) return "undefined";
567
+ if (typeof v === "function") return "a function (single handler — wrap in array)";
568
+ if (Array.isArray(v)) return `an array of length ${v.length}`;
569
+ return `${typeof v} (${JSON.stringify(v).slice(0, 80)})`;
570
+ }
514
571
  //#endregion
515
- export { getControllerScope as _, buildAuthMiddlewareForPermissions as a, buildPreHandlerChain as c, resolveRouterPluginMw as d, selectPluginMw as f, getControllerContext as g, createRequestContext as h, buildAuthMiddleware as i, buildRateLimitConfig as l, createFastifyHandler as m, buildActionPipelineHandler as n, buildCrudPermissionMw as o, createCrudHandlers as p, buildArcDecorator as r, buildPipelineHandler as s, buildActionPermissionMw as t, resolvePipelineSteps as u, sendControllerResponse as v, buildRequestScopeProjection as y };
572
+ export { getControllerContext as _, buildAuthMiddlewareForPermissions as a, buildRequestScopeProjection as b, buildPreHandlerChain as c, resolveRoutePreHandlers as d, resolveRouterPluginMw as f, createRequestContext as g, createFastifyHandler as h, buildAuthMiddleware as i, buildRateLimitConfig as l, createCrudHandlers as m, buildActionPipelineHandler as n, buildCrudPermissionMw as o, selectPluginMw as p, buildArcDecorator as r, buildPipelineHandler as s, buildActionPermissionMw as t, resolvePipelineSteps as u, getControllerScope as v, sendControllerResponse as y };
@@ -1,5 +1,5 @@
1
- import { _ as isAuthenticated, a as getClientId, b as isOrgInScope, c as getOrgRoles, d as getScopeContextMap, f as getServiceScopes, g as hasOrgAccess, h as getUserRoles, i as getAncestorOrgIds, l as getRequestScope, m as getUserId, n as PUBLIC_SCOPE, o as getOrgContext, p as getTeamId, r as RequestScope, s as getOrgId, t as AUTHENTICATED_SCOPE, u as getScopeContext, v as isElevated, x as isService, y as isMember } from "../types-tgR4Pt8F.mjs";
2
- import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-s5ykdNHr.mjs";
1
+ import { _ as isAuthenticated, a as getClientId, b as isOrgInScope, c as getOrgRoles, d as getScopeContextMap, f as getServiceScopes, g as hasOrgAccess, h as getUserRoles, i as getAncestorOrgIds, l as getRequestScope, m as getUserId, n as PUBLIC_SCOPE, o as getOrgContext, p as getTeamId, r as RequestScope, s as getOrgId, t as AUTHENTICATED_SCOPE, u as getScopeContext, v as isElevated, x as isService, y as isMember } from "../types-DDyTPc6y.mjs";
2
+ import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-BQQXZ_VR.mjs";
3
3
  import { FastifyReply, FastifyRequest } from "fastify";
4
4
 
5
5
  //#region src/scope/rateLimitKey.d.ts
@@ -1,5 +1,5 @@
1
- import { B as ResourceDefinition, Pt as AnyRecord } from "../index-6u4_Gg6G.mjs";
2
- import { d as ResourceLike, r as CreateAppOptions } from "../types-BH7dEGvU.mjs";
1
+ import { B as ResourceDefinition, Pt as AnyRecord } from "../index-CXXRbnf8.mjs";
2
+ import { d as ResourceLike, r as CreateAppOptions } from "../types-D7KpfiL1.mjs";
3
3
  import { StorageContractSetup, StorageContractSetupResult, runStorageContract } from "./storageContract.mjs";
4
4
  import { FastifyInstance, FastifyServerOptions } from "fastify";
5
5
  import { Mock } from "vitest";
@@ -1081,7 +1081,7 @@ function pickDefaultAuth(authMode, callerAuth) {
1081
1081
  };
1082
1082
  }
1083
1083
  async function createTestApp(options = {}) {
1084
- const { createApp } = await import("../createApp-P1d6rjPy.mjs").then((n) => n.r);
1084
+ const { createApp } = await import("../createApp-C9bRrqlX.mjs").then((n) => n.r);
1085
1085
  const { resources = [], db = "in-memory", connectMongoose = false, authMode = "jwt", defaultOrgId, plugins, auth: callerAuth, ...appOptions } = options;
1086
1086
  let dbHandle;
1087
1087
  let dbUri;
@@ -1,4 +1,4 @@
1
- import { t as Storage } from "../storage-BwGQXUpd.mjs";
1
+ import { t as Storage } from "../storage-Dfzt4VTl.mjs";
2
2
 
3
3
  //#region src/testing/storageContract.d.ts
4
4
  interface StorageContractSetupResult {
@@ -1,5 +1,5 @@
1
- import { $ as OpenApiSchemas, A as RequestIdOptions, At as Authenticator, Bt as UserOrganization, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, G as ActionsMap, H as ActionDefinition, I as MiddlewareHandler, It as ArcRequest, J as CrudRouteKey, K as ArcFieldRule, L as RequestWithExtras, Lt as JWTPayload, M as EventsDecorator, Mt as JwtContext, N as FastifyRequestExtras, Nt as TokenPair, O as HealthOptions, Ot as AuthHelpers, P as FastifyWithAuth, Pt as AnyRecord, Q as MiddlewareConfig, Rt as ObjectId, S as QueryParserInterface, T as CrudRouterOptions, U as ActionEntry, W as ActionHandlerFn, X as EventDefinition, Y as CrudSchemas, Z as FieldRule, _ as ControllerQueryOptions, _t as IControllerResponse, a as InferAdapterDoc, at as ResourceConfig, b as ParsedQuery, c as TypedController, ct as ResourcePermissions, d as PaginationResult, dt as RouteMethod, et as PresetFunction, f as IntrospectionData, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, ht as FastifyHandler, i as ValidationResult, it as ResourceCacheConfig, j as ArcDecorator, jt as AuthenticatorContext, k as IntrospectionPluginOptions, kt as AuthPluginOptions, l as TypedRepository, lt as RouteDefinition, m as RegistryStats, mt as ControllerLike, n as ConfigError, nt as PresetResult, o as InferDocType, ot as ResourceHookContext, p as RegistryEntry, pt as ControllerHandler, q as CrudController, r as ValidateOptions, rt as RateLimitConfig, s as InferResourceDoc, st as ResourceHooks, t as RouteHandlerMethod, tn as BaseControllerOptions, tt as PresetHook, u as TypedResourceConfig, ut as RouteMcpConfig, v as LookupOption, vt as IRequestContext, w as ServiceContext, x as PopulateOption, y as OwnershipCheck, yt as RouteHandler, zt as UserLike } from "../index-6u4_Gg6G.mjs";
2
- import { r as RequestScope } from "../types-tgR4Pt8F.mjs";
3
- import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-C8Y0XLAu.mjs";
4
- import { n as ElevationOptions, t as ElevationEvent } from "../elevation-s5ykdNHr.mjs";
1
+ import { $ as OpenApiSchemas, A as RequestIdOptions, At as Authenticator, Bt as UserOrganization, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, G as ActionsMap, H as ActionDefinition, I as MiddlewareHandler, It as ArcRequest, J as CrudRouteKey, K as ArcFieldRule, L as RequestWithExtras, Lt as JWTPayload, M as EventsDecorator, Mt as JwtContext, N as FastifyRequestExtras, Nt as TokenPair, O as HealthOptions, Ot as AuthHelpers, P as FastifyWithAuth, Pt as AnyRecord, Q as MiddlewareConfig, Rt as ObjectId, S as QueryParserInterface, T as CrudRouterOptions, U as ActionEntry, W as ActionHandlerFn, X as EventDefinition, Y as CrudSchemas, Z as FieldRule, _ as ControllerQueryOptions, _t as IControllerResponse, a as InferAdapterDoc, at as ResourceConfig, b as ParsedQuery, c as TypedController, ct as ResourcePermissions, d as PaginationResult, dt as RouteMethod, et as PresetFunction, f as IntrospectionData, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, ht as FastifyHandler, i as ValidationResult, it as ResourceCacheConfig, j as ArcDecorator, jt as AuthenticatorContext, k as IntrospectionPluginOptions, kt as AuthPluginOptions, l as TypedRepository, lt as RouteDefinition, m as RegistryStats, mt as ControllerLike, n as ConfigError, nt as PresetResult, o as InferDocType, ot as ResourceHookContext, p as RegistryEntry, pt as ControllerHandler, q as CrudController, r as ValidateOptions, rt as RateLimitConfig, s as InferResourceDoc, st as ResourceHooks, t as RouteHandlerMethod, tn as BaseControllerOptions, tt as PresetHook, u as TypedResourceConfig, ut as RouteMcpConfig, v as LookupOption, vt as IRequestContext, w as ServiceContext, x as PopulateOption, y as OwnershipCheck, yt as RouteHandler, zt as UserLike } from "../index-CXXRbnf8.mjs";
2
+ import { r as RequestScope } from "../types-DDyTPc6y.mjs";
3
+ import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-BRjxOAFp.mjs";
4
+ import { n as ElevationOptions, t as ElevationEvent } from "../elevation-BQQXZ_VR.mjs";
5
5
  export { ActionDefinition, ActionEntry, ActionHandlerFn, ActionsMap, AnyRecord, ApiResponse, ArcDecorator, ArcFieldRule, ArcInternalMetadata, ArcRequest, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, BaseControllerOptions, ConfigError, ControllerHandler, ControllerLike, ControllerQueryOptions, CrudController, CrudRouteKey, CrudRouterOptions, CrudSchemas, ElevationEvent, ElevationOptions, EventDefinition, EventsDecorator, FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, IController, IControllerResponse, IRequestContext, InferAdapterDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, LookupOption, MiddlewareConfig, MiddlewareHandler, ObjectId, OpenApiSchemas, OwnershipCheck, PaginationResult, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHookContext, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteDefinition, RouteHandler, RouteHandlerMethod, RouteMcpConfig, RouteMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult };
@@ -1,2 +1,2 @@
1
- import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-BwGQXUpd.mjs";
1
+ import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-Dfzt4VTl.mjs";
2
2
  export { Storage, StorageContext, StorageFile, StorageReadRange, StorageReadResult, StorageUploadInput };
@@ -1,4 +1,4 @@
1
- import { B as ResourceDefinition } from "./index-6u4_Gg6G.mjs";
1
+ import { B as ResourceDefinition } from "./index-CXXRbnf8.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/integrations/mcp/types.d.ts
@@ -1,13 +1,13 @@
1
- import { At as Authenticator } from "./index-6u4_Gg6G.mjs";
2
- import { r as CacheStore } from "./interface-Da0r7Lna.mjs";
3
- import { n as ElevationOptions } from "./elevation-s5ykdNHr.mjs";
4
- import { o as EventTransport } from "./EventTransport-CfVEGaEl.mjs";
5
- import { t as ExternalOpenApiPaths } from "./externalPaths-Bapitwvd.mjs";
6
- import { r as QueryCachePluginOptions } from "./queryCachePlugin-BUXBSm4F.mjs";
7
- import { t as EventPluginOptions } from "./eventPlugin-CUNjYYRY.mjs";
8
- import { f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-M9lNLhO8.mjs";
9
- import { t as ErrorHandlerOptions } from "./errorHandler-Co3lnVmJ.mjs";
10
- import { r as IdempotencyStore } from "./interface-CkkWm5uR.mjs";
1
+ import { At as Authenticator } from "./index-CXXRbnf8.mjs";
2
+ import { r as CacheStore } from "./interface-beEtJyWM.mjs";
3
+ import { n as ElevationOptions } from "./elevation-BQQXZ_VR.mjs";
4
+ import { o as EventTransport } from "./EventTransport-CYNUXdCJ.mjs";
5
+ import { t as ExternalOpenApiPaths } from "./externalPaths-BD5nw6St.mjs";
6
+ import { r as QueryCachePluginOptions } from "./queryCachePlugin-CqMdLI2-.mjs";
7
+ import { t as EventPluginOptions } from "./eventPlugin-DDJoNEPL.mjs";
8
+ import { f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-DsglKfM_.mjs";
9
+ import { t as ErrorHandlerOptions } from "./errorHandler-DEWmGWPz.mjs";
10
+ import { r as IdempotencyStore } from "./interface-DfLGcus7.mjs";
11
11
  import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
12
12
 
13
13
  //#region src/factory/loadResources.d.ts
@@ -1,2 +1,2 @@
1
- import { $ as ValidationResult, A as handleRaw, B as CompensationStep, C as queryParams, D as ArcQueryParser, E as wrapResponse, F as defineErrorMapper, G as CircuitBreakerOptions, H as withCompensation, I as CompensationDefinition, J as CircuitState, K as CircuitBreakerRegistry, L as CompensationError, M as Guard, N as GuardConfig, O as ArcQueryParserOptions, P as defineGuard, Q as ValidateOptions, R as CompensationHooks, S as paginationSchema, T as successResponseSchema, U as CircuitBreaker, V as defineCompensation, W as CircuitBreakerError, X as createCircuitBreakerRegistry, Y as createCircuitBreaker, Z as ConfigError, _ as getDefaultCrudSchemas, a as TransitionConfig, at as ErrorDetails, b as listResponse, c as JsonSchemaTarget, ct as OrgAccessDeniedError, d as isJsonSchema, dt as ServiceUnavailableError, et as assertValidConfig, f as isZodSchema, ft as UnauthorizedError, g as errorResponseSchema, gt as isArcError, h as deleteResponse, ht as createError, i as StateMachine, it as ConflictError, j as envelope, k as createQueryParser, l as convertOpenApiSchemas, lt as OrgRequiredError, m as JsonSchema, mt as createDomainError, n as EventsDecorator, nt as validateResourceConfig, o as createStateMachine, ot as ForbiddenError, p as toJsonSchema, pt as ValidationError, q as CircuitBreakerStats, r as hasEvents, rt as ArcError, s as simpleEqualityMatcher, st as NotFoundError, t as getUserId, tt as formatValidationErrors, u as convertRouteSchema, ut as RateLimitError, v as getListQueryParams, w as responses, x as mutationResponse, y as itemResponse, z as CompensationResult } from "../index-DdQ3O9Pg.mjs";
1
+ import { $ as ValidationResult, A as handleRaw, B as CompensationStep, C as queryParams, D as ArcQueryParser, E as wrapResponse, F as defineErrorMapper, G as CircuitBreakerOptions, H as withCompensation, I as CompensationDefinition, J as CircuitState, K as CircuitBreakerRegistry, L as CompensationError, M as Guard, N as GuardConfig, O as ArcQueryParserOptions, P as defineGuard, Q as ValidateOptions, R as CompensationHooks, S as paginationSchema, T as successResponseSchema, U as CircuitBreaker, V as defineCompensation, W as CircuitBreakerError, X as createCircuitBreakerRegistry, Y as createCircuitBreaker, Z as ConfigError, _ as getDefaultCrudSchemas, a as TransitionConfig, at as ErrorDetails, b as listResponse, c as JsonSchemaTarget, ct as OrgAccessDeniedError, d as isJsonSchema, dt as ServiceUnavailableError, et as assertValidConfig, f as isZodSchema, ft as UnauthorizedError, g as errorResponseSchema, gt as isArcError, h as deleteResponse, ht as createError, i as StateMachine, it as ConflictError, j as envelope, k as createQueryParser, l as convertOpenApiSchemas, lt as OrgRequiredError, m as JsonSchema, mt as createDomainError, n as EventsDecorator, nt as validateResourceConfig, o as createStateMachine, ot as ForbiddenError, p as toJsonSchema, pt as ValidationError, q as CircuitBreakerStats, r as hasEvents, rt as ArcError, s as simpleEqualityMatcher, st as NotFoundError, t as getUserId, tt as formatValidationErrors, u as convertRouteSchema, ut as RateLimitError, v as getListQueryParams, w as responses, x as mutationResponse, y as itemResponse, z as CompensationResult } from "../index-D9t1KNaB.mjs";
2
2
  export { ArcError, ArcQueryParser, ArcQueryParserOptions, CircuitBreaker, CircuitBreakerError, CircuitBreakerOptions, CircuitBreakerRegistry, CircuitBreakerStats, CircuitState, CompensationDefinition, CompensationError, CompensationHooks, CompensationResult, CompensationStep, ConfigError, ConflictError, ErrorDetails, EventsDecorator, ForbiddenError, Guard, GuardConfig, JsonSchema, JsonSchemaTarget, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, StateMachine, TransitionConfig, UnauthorizedError, ValidateOptions, ValidationError, ValidationResult, assertValidConfig, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createDomainError, createError, createQueryParser, createStateMachine, defineCompensation, defineErrorMapper, defineGuard, deleteResponse, envelope, errorResponseSchema, formatValidationErrors, getDefaultCrudSchemas, getListQueryParams, getUserId, handleRaw, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, listResponse, mutationResponse, paginationSchema, queryParams, responses, simpleEqualityMatcher, successResponseSchema, toJsonSchema, validateResourceConfig, withCompensation, wrapResponse };
@@ -1,4 +1,4 @@
1
- import { A as createQueryParser, C as mutationResponse, D as successResponseSchema, E as responses, M as simpleEqualityMatcher, O as wrapResponse, S as listResponse, T as queryParams, _ as deleteResponse, a as defineErrorMapper, b as getListQueryParams, c as CircuitBreaker, d as CircuitState, f as createCircuitBreaker, g as validateResourceConfig, h as formatValidationErrors, i as defineGuard, j as getUserId, k as ArcQueryParser, l as CircuitBreakerError, m as assertValidConfig, n as handleRaw, o as defineCompensation, p as createCircuitBreakerRegistry, r as envelope, s as withCompensation, t as createStateMachine, u as CircuitBreakerRegistry, v as errorResponseSchema, w as paginationSchema, x as itemResponse, y as getDefaultCrudSchemas } from "../utils-D3Yxnrwr.mjs";
1
+ import { A as createQueryParser, C as mutationResponse, D as successResponseSchema, E as responses, M as simpleEqualityMatcher, O as wrapResponse, S as listResponse, T as queryParams, _ as deleteResponse, a as defineErrorMapper, b as getListQueryParams, c as CircuitBreaker, d as CircuitState, f as createCircuitBreaker, g as validateResourceConfig, h as formatValidationErrors, i as defineGuard, j as getUserId, k as ArcQueryParser, l as CircuitBreakerError, m as assertValidConfig, n as handleRaw, o as defineCompensation, p as createCircuitBreakerRegistry, r as envelope, s as withCompensation, t as createStateMachine, u as CircuitBreakerRegistry, v as errorResponseSchema, w as paginationSchema, x as itemResponse, y as getDefaultCrudSchemas } from "../utils-CcYTj09l.mjs";
2
2
  import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createDomainError, f as createError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, p as isArcError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-D5c-5BJL.mjs";
3
3
  import { a as toJsonSchema, i as isZodSchema, n as convertRouteSchema, r as isJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-B0oKLuqI.mjs";
4
4
  import { t as hasEvents } from "../typeGuards-CcFZXgU7.mjs";
@@ -1,7 +1,7 @@
1
1
  import { m as RESERVED_QUERY_PARAMS, t as CRUD_OPERATIONS } from "./constants-BhY1OHoH.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
3
  import { t as ArcError } from "./errors-D5c-5BJL.mjs";
4
- import { r as getAvailablePresets } from "./presets-k604Lj99.mjs";
4
+ import { r as getAvailablePresets } from "./presets-Z7P5w4gF.mjs";
5
5
  //#region src/utils/simpleEqualityMatcher.ts
6
6
  /**
7
7
  * `simpleEqualityMatcher` — a minimal, dialect-agnostic flat-key equality
@@ -1,4 +1,4 @@
1
- import { n as DomainEvent } from "./EventTransport-CfVEGaEl.mjs";
1
+ import { n as DomainEvent } from "./EventTransport-CYNUXdCJ.mjs";
2
2
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
3
3
 
4
4
  //#region src/plugins/caching.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.11.2",
3
+ "version": "2.11.4",
4
4
  "description": "Resource-oriented backend framework for Fastify — clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {
@@ -255,6 +255,7 @@
255
255
  "@fastify/under-pressure": ">=9.0.0",
256
256
  "@fastify/websocket": ">=11.0.0",
257
257
  "@modelcontextprotocol/sdk": ">=1.28.0",
258
+ "@opentelemetry/api": ">=1.9.0",
258
259
  "@opentelemetry/auto-instrumentations-node": ">=0.40.0",
259
260
  "@opentelemetry/exporter-trace-otlp-http": ">=0.50.0",
260
261
  "@opentelemetry/instrumentation-http": ">=0.50.0",
@@ -381,6 +382,7 @@
381
382
  "@fastify/under-pressure": "^9.0.3",
382
383
  "@fastify/websocket": "^11.0.0",
383
384
  "@modelcontextprotocol/sdk": "^1.29.0",
385
+ "@opentelemetry/api": "^1.9.1",
384
386
  "@sinclair/typebox": "^0.34.0",
385
387
  "@types/node": "^22.10.0",
386
388
  "@types/qs": "^6.14.0",