@classytic/arc 2.10.3 → 2.11.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 (153) hide show
  1. package/README.md +1 -1
  2. package/dist/{BaseController-CbKKIflT.mjs → BaseController-JNV08qOT.mjs} +595 -537
  3. package/dist/{queryCachePlugin-BKbWjgDG.d.mts → QueryCache-DOBNHBE0.d.mts} +2 -32
  4. package/dist/actionPermissions-C8YYU92K.mjs +22 -0
  5. package/dist/adapters/index.d.mts +2 -2
  6. package/dist/adapters/index.mjs +1 -1
  7. package/dist/{adapters-BXY4i-hw.mjs → adapters-D0tT2Tyo.mjs} +54 -0
  8. package/dist/audit/index.d.mts +2 -2
  9. package/dist/audit/index.mjs +15 -17
  10. package/dist/auth/index.d.mts +4 -4
  11. package/dist/auth/index.mjs +3 -3
  12. package/dist/auth/redis-session.d.mts +1 -1
  13. package/dist/{betterAuthOpenApi-BBRVhjQN.mjs → betterAuthOpenApi-DwxtK3uG.mjs} +1 -1
  14. package/dist/cache/index.d.mts +3 -2
  15. package/dist/cache/index.mjs +3 -3
  16. package/dist/cli/commands/docs.mjs +2 -2
  17. package/dist/cli/commands/generate.mjs +37 -27
  18. package/dist/cli/commands/init.mjs +47 -34
  19. package/dist/cli/commands/introspect.mjs +1 -1
  20. package/dist/context/index.d.mts +58 -0
  21. package/dist/context/index.mjs +2 -0
  22. package/dist/core/index.d.mts +3 -3
  23. package/dist/core/index.mjs +4 -3
  24. package/dist/core-DXdSSFW-.mjs +1037 -0
  25. package/dist/createActionRouter-BwaSM0No.mjs +166 -0
  26. package/dist/{createApp-BuvPma24.mjs → createApp-DvNYEhpb.mjs} +118 -36
  27. package/dist/docs/index.d.mts +2 -2
  28. package/dist/docs/index.mjs +1 -1
  29. package/dist/{elevation-C7hgL_aI.mjs → elevation-DOFoxoDs.mjs} +1 -1
  30. package/dist/errorHandler-Co3lnVmJ.d.mts +114 -0
  31. package/dist/{eventPlugin-DCUjuiQT.mjs → eventPlugin--5HIkdPU.mjs} +1 -1
  32. package/dist/{eventPlugin-CxWgpd6K.d.mts → eventPlugin-CUNjYYRY.d.mts} +1 -1
  33. package/dist/events/index.d.mts +4 -4
  34. package/dist/events/index.mjs +69 -51
  35. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  36. package/dist/events/transports/redis.d.mts +1 -1
  37. package/dist/factory/index.d.mts +1 -1
  38. package/dist/factory/index.mjs +2 -2
  39. package/dist/{fields-Lo1VUDpt.d.mts → fields-C8Y0XLAu.d.mts} +1 -1
  40. package/dist/hooks/index.d.mts +1 -1
  41. package/dist/hooks/index.mjs +1 -1
  42. package/dist/idempotency/index.d.mts +3 -3
  43. package/dist/idempotency/index.mjs +38 -27
  44. package/dist/idempotency/redis.d.mts +1 -1
  45. package/dist/{index-ChIw3776.d.mts → index-BYCqHCVu.d.mts} +4 -4
  46. package/dist/{index-Cl0uoKd5.d.mts → index-Cm0vUrr_.d.mts} +2100 -1688
  47. package/dist/{index-DStwgFUK.d.mts → index-DAushRTt.d.mts} +29 -10
  48. package/dist/index-DsJ1MNfC.d.mts +1179 -0
  49. package/dist/{index-8qw4y6ff.d.mts → index-t8pLpPFW.d.mts} +13 -10
  50. package/dist/index.d.mts +7 -251
  51. package/dist/index.mjs +8 -128
  52. package/dist/integrations/event-gateway.d.mts +2 -2
  53. package/dist/integrations/event-gateway.mjs +1 -1
  54. package/dist/integrations/index.d.mts +2 -2
  55. package/dist/integrations/mcp/index.d.mts +2 -2
  56. package/dist/integrations/mcp/index.mjs +1 -1
  57. package/dist/integrations/mcp/testing.d.mts +1 -1
  58. package/dist/integrations/mcp/testing.mjs +1 -1
  59. package/dist/integrations/streamline.d.mts +46 -5
  60. package/dist/integrations/streamline.mjs +50 -21
  61. package/dist/integrations/websocket-redis.d.mts +1 -1
  62. package/dist/integrations/websocket.d.mts +2 -154
  63. package/dist/integrations/websocket.mjs +292 -224
  64. package/dist/{keys-qcD-TVJl.mjs → keys-CARyUjiR.mjs} +2 -0
  65. package/dist/{loadResources-BAzJItAJ.mjs → loadResources-YNwKHvRA.mjs} +3 -1
  66. package/dist/logger/index.d.mts +81 -0
  67. package/dist/{logger-DLg8-Ueg.mjs → logger/index.mjs} +1 -6
  68. package/dist/middleware/index.d.mts +109 -0
  69. package/dist/middleware/index.mjs +70 -0
  70. package/dist/multipartBody-CvTR1Un6.mjs +123 -0
  71. package/dist/{openapi-B5F8AddX.mjs → openapi-C0L9ar7m.mjs} +9 -7
  72. package/dist/org/index.d.mts +2 -2
  73. package/dist/permissions/index.d.mts +2 -2
  74. package/dist/permissions/index.mjs +1 -3
  75. package/dist/{permissions-Dk6mshja.mjs → permissions-B4vU9L0Q.mjs} +220 -2
  76. package/dist/pipe-DVoIheVC.mjs +62 -0
  77. package/dist/pipeline/index.d.mts +62 -0
  78. package/dist/pipeline/index.mjs +53 -0
  79. package/dist/plugins/index.d.mts +25 -5
  80. package/dist/plugins/index.mjs +10 -10
  81. package/dist/plugins/response-cache.mjs +1 -1
  82. package/dist/plugins/tracing-entry.d.mts +1 -1
  83. package/dist/plugins/tracing-entry.mjs +42 -24
  84. package/dist/presets/filesUpload.d.mts +4 -4
  85. package/dist/presets/filesUpload.mjs +255 -1
  86. package/dist/presets/index.d.mts +1 -1
  87. package/dist/presets/index.mjs +2 -2
  88. package/dist/presets/multiTenant.d.mts +1 -1
  89. package/dist/presets/multiTenant.mjs +48 -8
  90. package/dist/presets/search.d.mts +2 -2
  91. package/dist/presets/search.mjs +1 -1
  92. package/dist/{presets-fLJVXdVn.mjs → presets-k604Lj99.mjs} +1 -1
  93. package/dist/queryCachePlugin-BUXBSm4F.d.mts +34 -0
  94. package/dist/{queryCachePlugin-DQCEfJis.mjs → queryCachePlugin-Bq6bO6vc.mjs} +3 -3
  95. package/dist/{redis-DqyeggCa.d.mts → redis-Cm1gnRDf.d.mts} +1 -1
  96. package/dist/{redis-stream-CakIQmwR.d.mts → redis-stream-CM8TXTix.d.mts} +1 -1
  97. package/dist/registry/index.d.mts +1 -1
  98. package/dist/registry/index.mjs +2 -2
  99. package/dist/{requestContext-xHIKedG6.mjs → requestContext-CfRkaxwf.mjs} +1 -1
  100. package/dist/{resourceToTools-BElv3xPT.mjs → resourceToTools--okX6QBr.mjs} +534 -415
  101. package/dist/routerShared-DeESFp4a.mjs +515 -0
  102. package/dist/schemaIR-BlG9bY7v.mjs +137 -0
  103. package/dist/scope/index.d.mts +2 -2
  104. package/dist/scope/index.mjs +1 -1
  105. package/dist/{sse-yBCgOLGu.mjs → sse-V7aXc3bW.mjs} +1 -1
  106. package/dist/{store-helpers-ZCSMJJAX.mjs → store-helpers-BhrzxvyQ.mjs} +4 -0
  107. package/dist/testing/index.d.mts +367 -711
  108. package/dist/testing/index.mjs +646 -1434
  109. package/dist/testing/storageContract.d.mts +1 -1
  110. package/dist/{tracing-65B51Dw3.d.mts → tracing-DokiEsuz.d.mts} +9 -4
  111. package/dist/types/index.d.mts +5 -5
  112. package/dist/types/index.mjs +1 -3
  113. package/dist/types/storage.d.mts +1 -1
  114. package/dist/{types-Co8k3NyS.d.mts → types-CgikqKAj.d.mts} +133 -21
  115. package/dist/{types-Btdda02s.d.mts → types-D9NqiYIw.d.mts} +1 -1
  116. package/dist/utils/index.d.mts +2 -898
  117. package/dist/utils/index.mjs +4 -5
  118. package/dist/utils-D3Yxnrwr.mjs +1639 -0
  119. package/dist/versioning-M9lNLhO8.d.mts +117 -0
  120. package/dist/websocket-CyJ1VIFI.d.mts +186 -0
  121. package/package.json +26 -8
  122. package/skills/arc/SKILL.md +124 -39
  123. package/skills/arc/references/testing.md +212 -183
  124. package/dist/applyPermissionResult-QhV1Pa-g.mjs +0 -37
  125. package/dist/core-CcR01lup.mjs +0 -1411
  126. package/dist/createActionRouter-Bp_5c_2b.mjs +0 -249
  127. package/dist/errorHandler-DRQ3EqfL.d.mts +0 -218
  128. package/dist/errors-CCSsMpXE.d.mts +0 -140
  129. package/dist/fields-bxkeltzz.mjs +0 -126
  130. package/dist/filesUpload-t21LS-py.mjs +0 -377
  131. package/dist/queryParser-DBqBB6AC.mjs +0 -352
  132. package/dist/types-Csi3FLfq.mjs +0 -27
  133. package/dist/utils-B2fNOD_i.mjs +0 -929
  134. /package/dist/{EventTransport-CUw5NNWe.d.mts → EventTransport-CfVEGaEl.d.mts} +0 -0
  135. /package/dist/{HookSystem-BNYKnrXF.mjs → HookSystem-CGsMd6oK.mjs} +0 -0
  136. /package/dist/{ResourceRegistry-BPd6NQDm.mjs → ResourceRegistry-DkAeAuTX.mjs} +0 -0
  137. /package/dist/{caching-CBpK_SCM.mjs → caching-CheW3m-S.mjs} +0 -0
  138. /package/dist/{elevation-C5SwtkAn.d.mts → elevation-s5ykdNHr.d.mts} +0 -0
  139. /package/dist/{errorHandler-Bb49BvPD.mjs → errorHandler-BQm8ZxTK.mjs} +0 -0
  140. /package/dist/{externalPaths-BQ8QijNH.d.mts → externalPaths-Bapitwvd.d.mts} +0 -0
  141. /package/dist/{interface-CSbZdv_3.d.mts → interface-CkkWm5uR.d.mts} +0 -0
  142. /package/dist/{interface-D218ikEo.d.mts → interface-Da0r7Lna.d.mts} +0 -0
  143. /package/dist/{memory-B5Amv9A1.mjs → memory-DikHSvWa.mjs} +0 -0
  144. /package/dist/{metrics-DuhiSEZI.mjs → metrics-Csh4nsvv.mjs} +0 -0
  145. /package/dist/{pluralize-A0tWEl1K.mjs → pluralize-BneOJkpi.mjs} +0 -0
  146. /package/dist/{registry-B3lRFBWo.mjs → registry-D63ee7fl.mjs} +0 -0
  147. /package/dist/{replyHelpers-CXtJDAZ0.mjs → replyHelpers-ByllIXXV.mjs} +0 -0
  148. /package/dist/{schemaConverter-BxFDdtXu.mjs → schemaConverter-B0oKLuqI.mjs} +0 -0
  149. /package/dist/{sessionManager-BkzVU8h2.d.mts → sessionManager-D-oNWHz3.d.mts} +0 -0
  150. /package/dist/{storage-CVk_SEn2.d.mts → storage-BwGQXUpd.d.mts} +0 -0
  151. /package/dist/{typeGuards-Cj5Rgvlg.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
  152. /package/dist/{types-BD85MlEK.d.mts → types-tgR4Pt8F.d.mts} +0 -0
  153. /package/dist/{versioning-C2U_bLY0.mjs → versioning-CGPjkqAg.mjs} +0 -0
@@ -1,898 +1,2 @@
1
- import { Kt as QueryParserInterface, Wt as ParsedQuery, dn as AnyRecord, rt as OpenApiSchemas } from "../index-Cl0uoKd5.mjs";
2
- import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createDomainError, i as ForbiddenError, l as ServiceUnavailableError, m as isArcError, n as ConflictError, o as OrgAccessDeniedError, p as createError, r as ErrorDetails, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-CCSsMpXE.mjs";
3
- import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
4
-
5
- //#region src/utils/circuitBreaker.d.ts
6
- /**
7
- * Circuit Breaker Pattern
8
- *
9
- * Wraps external service calls with failure protection.
10
- * Prevents cascading failures by "opening" the circuit when
11
- * a service is failing, allowing it time to recover.
12
- *
13
- * States:
14
- * - CLOSED: Normal operation, requests pass through
15
- * - OPEN: Too many failures, all requests fail fast
16
- * - HALF_OPEN: Testing if service recovered, limited requests
17
- *
18
- * @example
19
- * import { CircuitBreaker } from '@classytic/arc/utils';
20
- *
21
- * const paymentBreaker = new CircuitBreaker(async (amount) => {
22
- * return await stripe.charges.create({ amount });
23
- * }, {
24
- * failureThreshold: 5,
25
- * resetTimeout: 30000,
26
- * timeout: 5000,
27
- * });
28
- *
29
- * try {
30
- * const result = await paymentBreaker.call(100);
31
- * } catch (error) {
32
- * // Handle failure or circuit open
33
- * }
34
- */
35
- declare const CircuitState: {
36
- readonly CLOSED: "CLOSED";
37
- readonly OPEN: "OPEN";
38
- readonly HALF_OPEN: "HALF_OPEN";
39
- };
40
- type CircuitState = (typeof CircuitState)[keyof typeof CircuitState];
41
- interface CircuitBreakerOptions {
42
- /**
43
- * Number of failures before opening circuit
44
- * @default 5
45
- */
46
- failureThreshold?: number;
47
- /**
48
- * Time in ms before attempting to close circuit
49
- * @default 60000 (60 seconds)
50
- */
51
- resetTimeout?: number;
52
- /**
53
- * Request timeout in ms
54
- * @default 10000 (10 seconds)
55
- */
56
- timeout?: number;
57
- /**
58
- * Number of successful requests in HALF_OPEN before closing
59
- * @default 1
60
- */
61
- successThreshold?: number;
62
- /**
63
- * Fallback function when circuit is open.
64
- * Receives the same arguments as the wrapped function.
65
- */
66
- fallback?: (...args: unknown[]) => Promise<unknown>;
67
- /**
68
- * Callback when state changes
69
- */
70
- onStateChange?: (from: CircuitState, to: CircuitState) => void;
71
- /**
72
- * Callback on error
73
- */
74
- onError?: (error: Error) => void;
75
- /**
76
- * Name for logging/monitoring
77
- */
78
- name?: string;
79
- }
80
- interface CircuitBreakerStats {
81
- name?: string;
82
- state: CircuitState;
83
- failures: number;
84
- successes: number;
85
- totalCalls: number;
86
- openedAt: number | null;
87
- lastCallAt: number | null;
88
- }
89
- declare class CircuitBreakerError extends Error {
90
- state: CircuitState;
91
- constructor(message: string, state: CircuitState);
92
- }
93
- declare class CircuitBreaker<T extends (...args: any[]) => Promise<any>> {
94
- private state;
95
- private failures;
96
- private successes;
97
- private totalCalls;
98
- private nextAttempt;
99
- private lastCallAt;
100
- private openedAt;
101
- private readonly failureThreshold;
102
- private readonly resetTimeout;
103
- private readonly timeout;
104
- private readonly successThreshold;
105
- private readonly fallback?;
106
- private readonly onStateChange?;
107
- private readonly onError?;
108
- private readonly name;
109
- private readonly fn;
110
- constructor(fn: T, options?: CircuitBreakerOptions);
111
- /**
112
- * Call the wrapped function with circuit breaker protection
113
- */
114
- call(...args: Parameters<T>): Promise<ReturnType<T>>;
115
- /**
116
- * Execute function with timeout
117
- */
118
- private executeWithTimeout;
119
- /**
120
- * Handle successful call
121
- */
122
- private onSuccess;
123
- /**
124
- * Handle failed call
125
- */
126
- private onFailure;
127
- /**
128
- * Change circuit state
129
- */
130
- private setState;
131
- /**
132
- * Manually open the circuit
133
- */
134
- open(): void;
135
- /**
136
- * Manually close the circuit
137
- */
138
- close(): void;
139
- /**
140
- * Get current statistics
141
- */
142
- getStats(): CircuitBreakerStats;
143
- /**
144
- * Get current state
145
- */
146
- getState(): CircuitState;
147
- /**
148
- * Check if circuit is open
149
- */
150
- isOpen(): boolean;
151
- /**
152
- * Check if circuit is closed
153
- */
154
- isClosed(): boolean;
155
- /**
156
- * Reset statistics
157
- */
158
- reset(): void;
159
- }
160
- /**
161
- * Create a circuit breaker with sensible defaults
162
- *
163
- * @example
164
- * const emailBreaker = createCircuitBreaker(
165
- * async (to, subject, body) => sendEmail(to, subject, body),
166
- * { name: 'email-service' }
167
- * );
168
- */
169
- declare function createCircuitBreaker<T extends (...args: any[]) => Promise<any>>(fn: T, options?: CircuitBreakerOptions): CircuitBreaker<T>;
170
- /**
171
- * Circuit breaker registry for managing multiple breakers
172
- */
173
- declare class CircuitBreakerRegistry {
174
- private breakers;
175
- /**
176
- * Register a circuit breaker
177
- */
178
- register<T extends (...args: any[]) => Promise<any>>(name: string, fn: T, options?: Omit<CircuitBreakerOptions, "name">): CircuitBreaker<T>;
179
- /**
180
- * Get a circuit breaker by name
181
- */
182
- get(name: string): CircuitBreaker<any> | undefined;
183
- /**
184
- * Get all breakers
185
- */
186
- getAll(): Map<string, CircuitBreaker<any>>;
187
- /**
188
- * Get statistics for all breakers
189
- */
190
- getAllStats(): Record<string, CircuitBreakerStats>;
191
- /**
192
- * Reset all breakers
193
- */
194
- resetAll(): void;
195
- /**
196
- * Open all breakers
197
- */
198
- openAll(): void;
199
- /**
200
- * Close all breakers
201
- */
202
- closeAll(): void;
203
- }
204
- /**
205
- * Create a new CircuitBreakerRegistry instance.
206
- * Use this instead of a global singleton — attach to fastify.arc or pass explicitly.
207
- */
208
- declare function createCircuitBreakerRegistry(): CircuitBreakerRegistry;
209
- //#endregion
210
- //#region src/utils/compensation.d.ts
211
- /**
212
- * Compensating Transaction — In-Process Rollback Primitive
213
- *
214
- * Runs steps in order. If any step fails, runs compensating actions
215
- * for already-completed steps in reverse. Zero dependencies.
216
- *
217
- * Type-safe: generic context type gives autocomplete across steps.
218
- * Discriminated union result: compiler enforces checking success before
219
- * accessing failedStep/error.
220
- *
221
- * For distributed sagas across services, use Temporal, Inngest, or Streamline.
222
- *
223
- * @example
224
- * ```typescript
225
- * interface CheckoutCtx {
226
- * orderId: string;
227
- * reservationId?: string;
228
- * }
229
- *
230
- * const result = await withCompensation<CheckoutCtx>('checkout', [
231
- * {
232
- * name: 'reserve',
233
- * execute: async (ctx) => {
234
- * const res = await inventoryService.reserve(ctx.orderId);
235
- * ctx.reservationId = res.id;
236
- * return res;
237
- * },
238
- * compensate: async (ctx) => {
239
- * await inventoryService.release(ctx.reservationId!);
240
- * },
241
- * },
242
- * { name: 'notify', execute: sendEmail, fireAndForget: true },
243
- * ], { orderId: 'ord-123' });
244
- *
245
- * if (result.success) {
246
- * // result.results available, no failedStep
247
- * } else {
248
- * // result.failedStep and result.error guaranteed
249
- * }
250
- * ```
251
- */
252
- /** Step definition with typed context and typed result */
253
- interface CompensationStep<TCtx = Record<string, unknown>, TResult = unknown> {
254
- /** Step name — used in results, logs, and hooks */
255
- readonly name: string;
256
- /** Execute the step — return value stored in results[name] */
257
- readonly execute: (ctx: TCtx) => Promise<TResult>;
258
- /** Rollback on failure — receives context and this step's own result */
259
- readonly compensate?: (ctx: TCtx, stepResult: TResult) => Promise<void>;
260
- /** Fire-and-forget — don't await, don't block, swallow errors, skip in rollback */
261
- readonly fireAndForget?: boolean;
262
- }
263
- /** Lifecycle hooks for observability — wire to Arc events, metrics, or logging */
264
- interface CompensationHooks {
265
- readonly onStepComplete?: (stepName: string, result: unknown) => void;
266
- readonly onStepFailed?: (stepName: string, error: Error) => void;
267
- readonly onCompensate?: (stepName: string) => void;
268
- }
269
- /** Error from a compensation action that failed during rollback */
270
- interface CompensationError {
271
- readonly step: string;
272
- readonly error: string;
273
- }
274
- /** Discriminated union — success and failure are mutually exclusive */
275
- type CompensationResult = {
276
- readonly success: true;
277
- readonly completedSteps: readonly string[];
278
- readonly results: Readonly<Record<string, unknown>>;
279
- } | {
280
- readonly success: false;
281
- readonly completedSteps: readonly string[];
282
- readonly results: Readonly<Record<string, unknown>>;
283
- readonly failedStep: string;
284
- readonly error: string;
285
- readonly compensationErrors?: readonly CompensationError[];
286
- };
287
- /**
288
- * Run steps in order with automatic compensation on failure.
289
- *
290
- * @typeParam TCtx - Context type shared across steps (defaults to Record<string, unknown>)
291
- */
292
- declare function withCompensation<TCtx extends Record<string, unknown> = Record<string, unknown>>(_name: string, steps: readonly CompensationStep<TCtx>[], initialContext?: TCtx, hooks?: CompensationHooks): Promise<CompensationResult>;
293
- interface CompensationDefinition<TCtx extends Record<string, unknown> = Record<string, unknown>> {
294
- readonly name: string;
295
- readonly execute: (initialContext?: TCtx, hooks?: CompensationHooks) => Promise<CompensationResult>;
296
- }
297
- declare function defineCompensation<TCtx extends Record<string, unknown> = Record<string, unknown>>(name: string, steps: readonly CompensationStep<TCtx>[]): CompensationDefinition<TCtx>;
298
- //#endregion
299
- //#region src/utils/defineGuard.d.ts
300
- interface GuardConfig<T> {
301
- /** Unique name — used as the storage key on the request. */
302
- readonly name: string;
303
- /**
304
- * Resolve the guard context from the request. Throw to abort the request
305
- * (Fastify's error handler will produce the appropriate HTTP response).
306
- * Return a value to stash it for `from()` extraction.
307
- */
308
- readonly resolve: (req: FastifyRequest, reply: FastifyReply) => T | Promise<T>;
309
- }
310
- interface Guard<T> {
311
- /** Use in `routeGuards` or per-route `preHandler` arrays. */
312
- readonly preHandler: RouteHandlerMethod;
313
- /**
314
- * Extract the resolved context from a request. Throws if the guard
315
- * hasn't run yet (i.e. not in the preHandler chain).
316
- */
317
- from(req: FastifyRequest): T;
318
- /** The guard name (for debugging). */
319
- readonly name: string;
320
- }
321
- /**
322
- * Create a typed guard. See module JSDoc for usage.
323
- */
324
- declare function defineGuard<T>(config: GuardConfig<T>): Guard<T>;
325
- //#endregion
326
- //#region src/utils/handleRaw.d.ts
327
- /**
328
- * Wrap a raw Fastify handler with Arc's response envelope and error handling.
329
- *
330
- * @param handler - Async function that receives `(request, reply)` and returns data.
331
- * The return value is sent as `{ success: true, data }`. If it returns
332
- * `undefined` or `null`, `{ success: true }` is sent (no `data` field).
333
- * @param statusCode - HTTP status code for successful responses (default: 200)
334
- */
335
- declare function handleRaw<T>(handler: (request: FastifyRequest, reply: FastifyReply) => Promise<T>, statusCode?: number): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
336
- //#endregion
337
- //#region src/utils/queryParser.d.ts
338
- interface ArcQueryParserOptions {
339
- /** Maximum allowed limit value (default: 1000) */
340
- maxLimit?: number;
341
- /** Default limit for pagination (default: 20) */
342
- defaultLimit?: number;
343
- /** Maximum regex pattern length (default: 500) */
344
- maxRegexLength?: number;
345
- /** Maximum search query length (default: 200) */
346
- maxSearchLength?: number;
347
- /** Maximum filter nesting depth (default: 10) */
348
- maxFilterDepth?: number;
349
- /**
350
- * Whitelist of fields that can be filtered on.
351
- * When set, only these fields are accepted as filters — all others are silently dropped.
352
- * Also used by MCP to auto-derive filterable fields in tool schemas.
353
- */
354
- allowedFilterFields?: string[];
355
- /**
356
- * Whitelist of fields that can be sorted on.
357
- * When set, sort fields not in this list are silently dropped.
358
- * Also used by MCP to describe available sort options.
359
- */
360
- allowedSortFields?: string[];
361
- /**
362
- * Whitelist of filter operators (e.g. ['eq', 'ne', 'gt', 'lt', 'in']).
363
- * When set, only these operators are accepted — all others are dropped.
364
- * Also used by MCP to enrich list tool descriptions.
365
- */
366
- allowedOperators?: string[];
367
- }
368
- /**
369
- * Arc's default query parser
370
- *
371
- * Converts URL query parameters to a structured query format:
372
- * - Pagination: ?page=1&limit=20
373
- * - Sorting: ?sort=-createdAt,name (- prefix = descending)
374
- * - Filtering: ?status=active&price[gte]=100&price[lte]=500
375
- * - Search: ?search=keyword
376
- * - Populate: ?populate=author,category
377
- * - Field selection: ?select=name,price,status
378
- * - Keyset pagination: ?after=cursor_value
379
- *
380
- * For advanced MongoDB features ($lookup, aggregations), use MongoKit's QueryParser.
381
- */
382
- declare class ArcQueryParser implements QueryParserInterface {
383
- private readonly maxLimit;
384
- private readonly defaultLimit;
385
- private readonly maxRegexLength;
386
- private readonly maxSearchLength;
387
- private readonly maxFilterDepth;
388
- private readonly _allowedFilterFields?;
389
- private readonly _allowedSortFields?;
390
- private readonly _allowedOperators?;
391
- /** Allowed filter fields (used by MCP for auto-derive) */
392
- readonly allowedFilterFields?: readonly string[];
393
- /** Allowed sort fields (used by MCP for sort descriptions) */
394
- readonly allowedSortFields?: readonly string[];
395
- /** Allowed operators (used by MCP for operator descriptions) */
396
- readonly allowedOperators?: readonly string[];
397
- /** Supported filter operators */
398
- private readonly operators;
399
- constructor(options?: ArcQueryParserOptions);
400
- /**
401
- * Parse URL query parameters into structured query options
402
- */
403
- parse(query: Record<string, unknown> | null | undefined): ParsedQuery;
404
- private parseNumber;
405
- private parseString;
406
- /**
407
- * Parse populate parameter — handles both simple string and bracket notation.
408
- *
409
- * Simple: ?populate=author,category → { populate: 'author,category' }
410
- * Bracket: ?populate[author][select]=name,email → { populateOptions: [{ path: 'author', select: 'name email' }] }
411
- */
412
- private parsePopulate;
413
- private parseSort;
414
- private parseSearch;
415
- private parseSelect;
416
- /**
417
- * Check if a value exceeds the maximum nesting depth.
418
- * Prevents filter bombs where deeply nested objects consume excessive memory/CPU.
419
- */
420
- private exceedsDepth;
421
- private parseFilters;
422
- private parseFilterValue;
423
- private coerceValue;
424
- /**
425
- * Generate OpenAPI-compatible JSON Schema for query parameters.
426
- * Arc's defineResource() auto-detects this method and uses it
427
- * to document list endpoint query parameters in OpenAPI/Swagger.
428
- */
429
- getQuerySchema(): {
430
- type: "object";
431
- properties: Record<string, unknown>;
432
- required?: string[];
433
- };
434
- private sanitizeRegex;
435
- }
436
- /**
437
- * Create a new ArcQueryParser instance
438
- */
439
- declare function createQueryParser(options?: ArcQueryParserOptions): ArcQueryParser;
440
- //#endregion
441
- //#region src/utils/responseSchemas.d.ts
442
- interface JsonSchema {
443
- type: string;
444
- properties?: Record<string, JsonSchema | AnyRecord>;
445
- required?: string[];
446
- items?: JsonSchema | AnyRecord;
447
- additionalProperties?: boolean | JsonSchema;
448
- description?: string;
449
- example?: unknown;
450
- [key: string]: unknown;
451
- }
452
- /**
453
- * Base success response schema
454
- */
455
- declare const successResponseSchema: JsonSchema;
456
- /**
457
- * Error response schema
458
- */
459
- declare const errorResponseSchema: JsonSchema;
460
- /**
461
- * Pagination schema - matches MongoKit/Arc runtime format
462
- *
463
- * Runtime format (flat fields):
464
- * { page, limit, total, pages, hasNext, hasPrev }
465
- */
466
- declare const paginationSchema: JsonSchema;
467
- /**
468
- * Wrap a data schema in a success response
469
- */
470
- declare function wrapResponse(dataSchema: JsonSchema): JsonSchema;
471
- /**
472
- * Create a list response schema with pagination - matches MongoKit/Arc runtime format
473
- *
474
- * Runtime format:
475
- * { success, docs: [...], page, limit, total, pages, hasNext, hasPrev }
476
- *
477
- * Note: Uses 'docs' array (not 'data') with flat pagination fields
478
- */
479
- declare function listResponse(itemSchema: JsonSchema): JsonSchema;
480
- /**
481
- * Create a single item response schema
482
- *
483
- * Runtime format: { success, data: {...} }
484
- */
485
- declare function itemResponse(itemSchema: JsonSchema): JsonSchema;
486
- /**
487
- * Create a create/update response schema
488
- */
489
- declare function mutationResponse(itemSchema: JsonSchema): JsonSchema;
490
- /**
491
- * Create a delete response schema
492
- *
493
- * Runtime format: { success, data: { message, id?, soft? } }
494
- */
495
- declare function deleteResponse(): JsonSchema;
496
- declare const responses: {
497
- 200: (schema: JsonSchema) => {
498
- description: string;
499
- content: {
500
- "application/json": {
501
- schema: JsonSchema;
502
- };
503
- };
504
- };
505
- 201: (schema: JsonSchema) => {
506
- description: string;
507
- content: {
508
- "application/json": {
509
- schema: JsonSchema;
510
- };
511
- };
512
- };
513
- 400: {
514
- description: string;
515
- content: {
516
- "application/json": {
517
- schema: {
518
- properties: {
519
- code: {
520
- type: string;
521
- example: string;
522
- };
523
- details: {
524
- type: string;
525
- properties: {
526
- errors: {
527
- type: string;
528
- items: {
529
- type: string;
530
- properties: {
531
- field: {
532
- type: string;
533
- };
534
- message: {
535
- type: string;
536
- };
537
- };
538
- };
539
- };
540
- };
541
- };
542
- };
543
- type: string;
544
- required?: string[];
545
- items?: JsonSchema | AnyRecord;
546
- additionalProperties?: boolean | JsonSchema;
547
- description?: string;
548
- example?: unknown;
549
- };
550
- };
551
- };
552
- };
553
- 401: {
554
- description: string;
555
- content: {
556
- "application/json": {
557
- schema: {
558
- properties: {
559
- code: {
560
- type: string;
561
- example: string;
562
- };
563
- };
564
- type: string;
565
- required?: string[];
566
- items?: JsonSchema | AnyRecord;
567
- additionalProperties?: boolean | JsonSchema;
568
- description?: string;
569
- example?: unknown;
570
- };
571
- };
572
- };
573
- };
574
- 403: {
575
- description: string;
576
- content: {
577
- "application/json": {
578
- schema: {
579
- properties: {
580
- code: {
581
- type: string;
582
- example: string;
583
- };
584
- };
585
- type: string;
586
- required?: string[];
587
- items?: JsonSchema | AnyRecord;
588
- additionalProperties?: boolean | JsonSchema;
589
- description?: string;
590
- example?: unknown;
591
- };
592
- };
593
- };
594
- };
595
- 404: {
596
- description: string;
597
- content: {
598
- "application/json": {
599
- schema: {
600
- properties: {
601
- code: {
602
- type: string;
603
- example: string;
604
- };
605
- };
606
- type: string;
607
- required?: string[];
608
- items?: JsonSchema | AnyRecord;
609
- additionalProperties?: boolean | JsonSchema;
610
- description?: string;
611
- example?: unknown;
612
- };
613
- };
614
- };
615
- };
616
- 409: {
617
- description: string;
618
- content: {
619
- "application/json": {
620
- schema: {
621
- properties: {
622
- code: {
623
- type: string;
624
- example: string;
625
- };
626
- };
627
- type: string;
628
- required?: string[];
629
- items?: JsonSchema | AnyRecord;
630
- additionalProperties?: boolean | JsonSchema;
631
- description?: string;
632
- example?: unknown;
633
- };
634
- };
635
- };
636
- };
637
- 500: {
638
- description: string;
639
- content: {
640
- "application/json": {
641
- schema: {
642
- properties: {
643
- code: {
644
- type: string;
645
- example: string;
646
- };
647
- };
648
- type: string;
649
- required?: string[];
650
- items?: JsonSchema | AnyRecord;
651
- additionalProperties?: boolean | JsonSchema;
652
- description?: string;
653
- example?: unknown;
654
- };
655
- };
656
- };
657
- };
658
- };
659
- declare const queryParams: {
660
- pagination: {
661
- page: {
662
- type: string;
663
- minimum: number;
664
- default: number;
665
- description: string;
666
- };
667
- limit: {
668
- type: string;
669
- minimum: number;
670
- maximum: number;
671
- default: number;
672
- description: string;
673
- };
674
- };
675
- sorting: {
676
- sort: {
677
- type: string;
678
- description: string;
679
- example: string;
680
- };
681
- };
682
- filtering: {
683
- select: {
684
- description: string;
685
- example: string;
686
- };
687
- populate: {
688
- description: string;
689
- example: string;
690
- };
691
- };
692
- };
693
- /**
694
- * Get standard list query parameters schema
695
- */
696
- declare function getListQueryParams(): AnyRecord;
697
- /**
698
- * Get default response schemas for all CRUD operations.
699
- *
700
- * When routes have response schemas, Fastify compiles them with
701
- * fast-json-stringify for 2-3x faster serialization and prevents
702
- * accidental field disclosure.
703
- *
704
- * These defaults use `additionalProperties: true` so all fields pass through.
705
- * Override with specific schemas for full serialization performance + safety.
706
- *
707
- * Note: `example` properties are stripped from defaults so they work with
708
- * any Fastify instance (not just createApp which adds `keywords: ['example']`).
709
- */
710
- declare function getDefaultCrudSchemas(): Record<string, Record<string, unknown>>;
711
- //#endregion
712
- //#region src/utils/schemaConverter.d.ts
713
- /**
714
- * Supported JSON Schema output targets for Zod v4's `toJSONSchema()`.
715
- * - `draft-7`: Fastify/AJV validation (default)
716
- * - `draft-2020-12`: AJV 2020 (opt-in, requires ajv/dist/2020)
717
- * - `openapi-3.0`: OpenAPI 3.0 document generation
718
- * - `openapi-3.1`: OpenAPI 3.1 document generation
719
- */
720
- type JsonSchemaTarget = "draft-7" | "draft-2020-12" | "openapi-3.0" | "openapi-3.1";
721
- /**
722
- * Check if an object is already a plain JSON Schema.
723
- * Returns true if it has JSON Schema markers (`type`, `properties`, `$ref`,
724
- * `allOf`, `anyOf`, `oneOf`, `items`, `enum`) and does NOT have Zod markers.
725
- */
726
- declare function isJsonSchema(input: unknown): input is Record<string, unknown>;
727
- /**
728
- * Check if an object is a Zod schema (has `_zod` marker from Zod v4).
729
- */
730
- declare function isZodSchema(input: unknown): boolean;
731
- /**
732
- * Convert any schema input to JSON Schema.
733
- *
734
- * Detection order:
735
- * 1. `null`/`undefined` → `undefined`
736
- * 2. Already JSON Schema → pass through as-is (zero overhead)
737
- * 3. Zod v4 schema → `z.toJSONSchema(schema, { target })`
738
- * 4. Unrecognized object → return as-is (treat as opaque schema)
739
- *
740
- * @param input Schema (Zod, plain JSON Schema, or opaque object)
741
- * @param target Output target — defaults to `draft-7` for Fastify compatibility.
742
- * Pass `openapi-3.0`/`openapi-3.1` for OpenAPI document generation.
743
- */
744
- declare function toJsonSchema(input: unknown, target?: JsonSchemaTarget): Record<string, unknown> | undefined;
745
- /**
746
- * Convert all schema fields in an OpenApiSchemas object.
747
- * JSON Schema values pass through unchanged. Only Zod schemas are converted.
748
- *
749
- * Defaults to the `openapi-3.0` target since this function feeds OpenAPI doc
750
- * generation, not Fastify route validation.
751
- */
752
- declare function convertOpenApiSchemas(schemas: OpenApiSchemas, target?: JsonSchemaTarget): OpenApiSchemas;
753
- /**
754
- * Convert schema values in a Fastify route schema record.
755
- *
756
- * Handles `body`, `querystring`, `params`, `headers` (top-level conversion)
757
- * and `response` (iterates by status code — each value converted individually).
758
- *
759
- * JSON Schema values pass through unchanged. Only Zod schemas are converted.
760
- *
761
- * Used for both custom routes and customSchemas (CRUD overrides).
762
- *
763
- * Defaults to `draft-7` so Fastify v5's bundled AJV 8 accepts the output.
764
- * Pass `openapi-3.0` (or `openapi-3.1`) when generating OpenAPI documents.
765
- */
766
- declare function convertRouteSchema(schema: Record<string, unknown>, target?: JsonSchemaTarget): Record<string, unknown>;
767
- //#endregion
768
- //#region src/utils/stateMachine.d.ts
769
- /**
770
- * State Machine Utility
771
- *
772
- * Pure utility for validating state transitions in workflow systems.
773
- * Zero dependencies, framework-agnostic.
774
- *
775
- * @example
776
- * const orderState = createStateMachine('Order', {
777
- * approve: ['pending', 'draft'],
778
- * cancel: ['pending', 'approved'],
779
- * fulfill: ['approved'],
780
- * });
781
- *
782
- * // Check if transition is allowed
783
- * if (orderState.can('approve', currentStatus)) {
784
- * // Perform approval
785
- * }
786
- *
787
- * // Assert transition (throws if invalid)
788
- * orderState.assert('approve', currentStatus, ValidationError);
789
- */
790
- interface StateMachine {
791
- /**
792
- * Synchronously check if action can be performed from current status.
793
- * Only checks the transition map — does NOT evaluate guards.
794
- * Use `canAsync()` when guards need to be evaluated.
795
- */
796
- can(action: string, status: string | null | undefined): boolean;
797
- /**
798
- * Asynchronously check if action can be performed, including guard evaluation.
799
- * Falls back to simple transition check when no guard is defined.
800
- */
801
- canAsync(action: string, status: string | null | undefined, context?: Record<string, unknown>): Promise<boolean>;
802
- /**
803
- * Assert action can be performed, throw error if invalid
804
- * @param action - Action to perform
805
- * @param status - Current status
806
- * @param errorFactory - Optional error constructor
807
- * @param message - Optional custom error message
808
- */
809
- assert(action: string, status: string | null | undefined, errorFactory?: (msg: string) => Error, message?: string): void;
810
- /**
811
- * Get transition history
812
- */
813
- getHistory?(): TransitionHistoryEntry[];
814
- /**
815
- * Record a transition
816
- */
817
- recordTransition?(from: string, to: string, action: string, metadata?: Record<string, unknown>): void;
818
- /**
819
- * Clear history
820
- */
821
- clearHistory?(): void;
822
- /**
823
- * Get available actions for current status
824
- */
825
- getAvailableActions?(status: string): string[];
826
- }
827
- interface TransitionHistoryEntry {
828
- from: string;
829
- to: string;
830
- action: string;
831
- timestamp: Date;
832
- metadata?: Record<string, unknown>;
833
- }
834
- /** Context passed to transition guards and actions */
835
- interface TransitionContext {
836
- from: string;
837
- to: string;
838
- action: string;
839
- data?: Record<string, unknown>;
840
- }
841
- type TransitionGuard = (context: TransitionContext) => boolean | Promise<boolean>;
842
- type TransitionAction = (context: TransitionContext) => void | Promise<void>;
843
- type TransitionConfig = Record<string, string[] | {
844
- from: string[];
845
- to?: string;
846
- guard?: TransitionGuard;
847
- before?: TransitionAction;
848
- after?: TransitionAction;
849
- }>;
850
- /**
851
- * Create a state machine for validating transitions
852
- *
853
- * @param name - Name of the state machine (used in error messages)
854
- * @param transitions - Map of actions to allowed source statuses
855
- * @param options - Additional options (history, guards, actions)
856
- * @returns State machine with can() and assert() methods
857
- *
858
- * @example
859
- * // Basic usage
860
- * const transferState = createStateMachine('Transfer', {
861
- * approve: ['draft'],
862
- * dispatch: ['approved'],
863
- * receive: ['dispatched', 'in_transit'],
864
- * cancel: ['draft', 'approved'],
865
- * });
866
- *
867
- * @example
868
- * // With guards and actions
869
- * const orderState = createStateMachine('Order', {
870
- * approve: {
871
- * from: ['pending'],
872
- * to: 'approved',
873
- * guard: ({ data }) => data.paymentConfirmed,
874
- * before: ({ from, to }) => console.log(`Approving order from ${from} to ${to}`),
875
- * after: ({ data }) => sendApprovalEmail(data.customerId),
876
- * },
877
- * }, { trackHistory: true });
878
- */
879
- declare function createStateMachine(name: string, transitions?: TransitionConfig, options?: {
880
- trackHistory?: boolean;
881
- }): StateMachine;
882
- //#endregion
883
- //#region src/utils/typeGuards.d.ts
884
- interface EventsDecorator {
885
- publish: <T>(type: string, payload: T, meta?: Record<string, unknown>) => Promise<void>;
886
- subscribe: (pattern: string, handler: (event: {
887
- type: string;
888
- payload: unknown;
889
- meta: Record<string, unknown>;
890
- }) => Promise<void>) => Promise<() => void>;
891
- transportName: string;
892
- }
893
- /** Check if fastify has the events plugin registered */
894
- declare function hasEvents(instance: FastifyInstance): instance is FastifyInstance & {
895
- events: EventsDecorator;
896
- };
897
- //#endregion
898
- export { ArcError, ArcQueryParser, type ArcQueryParserOptions, CircuitBreaker, CircuitBreakerError, type CircuitBreakerOptions, CircuitBreakerRegistry, type CircuitBreakerStats, CircuitState, type CompensationDefinition, type CompensationError, type CompensationHooks, type CompensationResult, type CompensationStep, ConflictError, type ErrorDetails, type EventsDecorator, ForbiddenError, type Guard, type GuardConfig, type JsonSchema, type JsonSchemaTarget, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, type StateMachine, type TransitionConfig, UnauthorizedError, ValidationError, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createDomainError, createError, createQueryParser, createStateMachine, defineCompensation, defineGuard, deleteResponse, errorResponseSchema, getDefaultCrudSchemas, getListQueryParams, handleRaw, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, listResponse, mutationResponse, paginationSchema, queryParams, responses, successResponseSchema, toJsonSchema, withCompensation, wrapResponse };
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-DsJ1MNfC.mjs";
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 };