@classytic/arc 1.1.0 → 2.1.3

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 (200) hide show
  1. package/README.md +247 -794
  2. package/bin/arc.js +91 -52
  3. package/dist/EventTransport-BkUDYZEb.d.mts +99 -0
  4. package/dist/HookSystem-BsGV-j2l.mjs +404 -0
  5. package/dist/ResourceRegistry-7Ic20ZMw.mjs +249 -0
  6. package/dist/adapters/index.d.mts +5 -0
  7. package/dist/adapters/index.mjs +3 -0
  8. package/dist/audit/index.d.mts +81 -0
  9. package/dist/audit/index.mjs +275 -0
  10. package/dist/audit/mongodb.d.mts +5 -0
  11. package/dist/audit/mongodb.mjs +3 -0
  12. package/dist/audited-CGdLiSlE.mjs +140 -0
  13. package/dist/auth/index.d.mts +188 -0
  14. package/dist/auth/index.mjs +1096 -0
  15. package/dist/auth/redis-session.d.mts +43 -0
  16. package/dist/auth/redis-session.mjs +75 -0
  17. package/dist/betterAuthOpenApi-DjWDddNc.mjs +249 -0
  18. package/dist/cache/index.d.mts +145 -0
  19. package/dist/cache/index.mjs +91 -0
  20. package/dist/caching-GSDJcA6-.mjs +93 -0
  21. package/dist/chunk-C7Uep-_p.mjs +20 -0
  22. package/dist/circuitBreaker-DYhWBW_D.mjs +1096 -0
  23. package/dist/cli/commands/describe.d.mts +18 -0
  24. package/dist/cli/commands/describe.mjs +238 -0
  25. package/dist/cli/commands/docs.d.mts +13 -0
  26. package/dist/cli/commands/docs.mjs +52 -0
  27. package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -2
  28. package/dist/cli/commands/generate.mjs +357 -0
  29. package/dist/cli/commands/{init.d.ts → init.d.mts} +11 -8
  30. package/dist/cli/commands/{init.js → init.mjs} +807 -617
  31. package/dist/cli/commands/introspect.d.mts +10 -0
  32. package/dist/cli/commands/introspect.mjs +75 -0
  33. package/dist/cli/index.d.mts +16 -0
  34. package/dist/cli/index.mjs +156 -0
  35. package/dist/constants-DdXFXQtN.mjs +84 -0
  36. package/dist/core/index.d.mts +5 -0
  37. package/dist/core/index.mjs +4 -0
  38. package/dist/createApp-D2D5XXaV.mjs +559 -0
  39. package/dist/defineResource-PXzSJ15_.mjs +2197 -0
  40. package/dist/discovery/index.d.mts +46 -0
  41. package/dist/discovery/index.mjs +109 -0
  42. package/dist/docs/index.d.mts +162 -0
  43. package/dist/docs/index.mjs +74 -0
  44. package/dist/elevation-DGo5shaX.d.mts +87 -0
  45. package/dist/elevation-DSTbVvYj.mjs +113 -0
  46. package/dist/errorHandler-C3GY3_ow.mjs +108 -0
  47. package/dist/errorHandler-CW3OOeYq.d.mts +72 -0
  48. package/dist/errors-DAWRdiYP.d.mts +124 -0
  49. package/dist/errors-DBANPbGr.mjs +211 -0
  50. package/dist/eventPlugin-BEOvaDqo.mjs +229 -0
  51. package/dist/eventPlugin-H6wDDjGO.d.mts +124 -0
  52. package/dist/events/index.d.mts +53 -0
  53. package/dist/events/index.mjs +51 -0
  54. package/dist/events/transports/redis-stream-entry.d.mts +2 -0
  55. package/dist/events/transports/redis-stream-entry.mjs +177 -0
  56. package/dist/events/transports/redis.d.mts +76 -0
  57. package/dist/events/transports/redis.mjs +124 -0
  58. package/dist/externalPaths-SyPF2tgK.d.mts +50 -0
  59. package/dist/factory/index.d.mts +63 -0
  60. package/dist/factory/index.mjs +3 -0
  61. package/dist/fastifyAdapter-C8DlE0YH.d.mts +216 -0
  62. package/dist/fields-Bi_AVKSo.d.mts +109 -0
  63. package/dist/fields-CTd_CrKr.mjs +114 -0
  64. package/dist/hooks/index.d.mts +4 -0
  65. package/dist/hooks/index.mjs +3 -0
  66. package/dist/idempotency/index.d.mts +96 -0
  67. package/dist/idempotency/index.mjs +319 -0
  68. package/dist/idempotency/mongodb.d.mts +2 -0
  69. package/dist/idempotency/mongodb.mjs +114 -0
  70. package/dist/idempotency/redis.d.mts +2 -0
  71. package/dist/idempotency/redis.mjs +103 -0
  72. package/dist/index.d.mts +260 -0
  73. package/dist/index.mjs +104 -0
  74. package/dist/integrations/event-gateway.d.mts +46 -0
  75. package/dist/integrations/event-gateway.mjs +43 -0
  76. package/dist/integrations/index.d.mts +5 -0
  77. package/dist/integrations/index.mjs +1 -0
  78. package/dist/integrations/jobs.d.mts +103 -0
  79. package/dist/integrations/jobs.mjs +123 -0
  80. package/dist/integrations/streamline.d.mts +60 -0
  81. package/dist/integrations/streamline.mjs +125 -0
  82. package/dist/integrations/websocket.d.mts +82 -0
  83. package/dist/integrations/websocket.mjs +288 -0
  84. package/dist/interface-CSNjltAc.d.mts +77 -0
  85. package/dist/interface-DTbsvIWe.d.mts +54 -0
  86. package/dist/interface-e9XfSsUV.d.mts +1097 -0
  87. package/dist/introspectionPlugin-B3JkrjwU.mjs +53 -0
  88. package/dist/keys-DhqDRxv3.mjs +42 -0
  89. package/dist/logger-ByrvQWZO.mjs +78 -0
  90. package/dist/memory-B2v7KrCB.mjs +143 -0
  91. package/dist/migrations/index.d.mts +156 -0
  92. package/dist/migrations/index.mjs +260 -0
  93. package/dist/mongodb-ClykrfGo.d.mts +118 -0
  94. package/dist/mongodb-DNKEExbf.mjs +93 -0
  95. package/dist/mongodb-Dg8O_gvd.d.mts +71 -0
  96. package/dist/openapi-9nB_kiuR.mjs +525 -0
  97. package/dist/org/index.d.mts +68 -0
  98. package/dist/org/index.mjs +513 -0
  99. package/dist/org/types.d.mts +82 -0
  100. package/dist/org/types.mjs +1 -0
  101. package/dist/permissions/index.d.mts +278 -0
  102. package/dist/permissions/index.mjs +579 -0
  103. package/dist/plugins/index.d.mts +172 -0
  104. package/dist/plugins/index.mjs +522 -0
  105. package/dist/plugins/response-cache.d.mts +87 -0
  106. package/dist/plugins/response-cache.mjs +283 -0
  107. package/dist/plugins/tracing-entry.d.mts +2 -0
  108. package/dist/plugins/tracing-entry.mjs +185 -0
  109. package/dist/pluralize-CM-jZg7p.mjs +86 -0
  110. package/dist/policies/{index.d.ts → index.d.mts} +204 -170
  111. package/dist/policies/index.mjs +321 -0
  112. package/dist/presets/{index.d.ts → index.d.mts} +62 -131
  113. package/dist/presets/index.mjs +143 -0
  114. package/dist/presets/multiTenant.d.mts +24 -0
  115. package/dist/presets/multiTenant.mjs +113 -0
  116. package/dist/presets-BTeYbw7h.d.mts +57 -0
  117. package/dist/presets-CeFtfDR8.mjs +119 -0
  118. package/dist/prisma-C3iornoK.d.mts +274 -0
  119. package/dist/prisma-DJbMt3yf.mjs +627 -0
  120. package/dist/queryCachePlugin-B6R0d4av.mjs +138 -0
  121. package/dist/queryCachePlugin-Q6SYuHZ6.d.mts +71 -0
  122. package/dist/redis-UwjEp8Ea.d.mts +49 -0
  123. package/dist/redis-stream-CBg0upHI.d.mts +103 -0
  124. package/dist/registry/index.d.mts +11 -0
  125. package/dist/registry/index.mjs +4 -0
  126. package/dist/requestContext-xi6OKBL-.mjs +55 -0
  127. package/dist/schemaConverter-Dtg0Kt9T.mjs +98 -0
  128. package/dist/schemas/index.d.mts +63 -0
  129. package/dist/schemas/index.mjs +82 -0
  130. package/dist/scope/index.d.mts +21 -0
  131. package/dist/scope/index.mjs +65 -0
  132. package/dist/sessionManager-D_iEHjQl.d.mts +186 -0
  133. package/dist/sse-DkqQ1uxb.mjs +123 -0
  134. package/dist/testing/index.d.mts +907 -0
  135. package/dist/testing/index.mjs +1976 -0
  136. package/dist/tracing-8CEbhF0w.d.mts +70 -0
  137. package/dist/typeGuards-DwxA1t_L.mjs +9 -0
  138. package/dist/types/index.d.mts +946 -0
  139. package/dist/types/index.mjs +14 -0
  140. package/dist/types-B0dhNrnd.d.mts +445 -0
  141. package/dist/types-Beqn1Un7.mjs +38 -0
  142. package/dist/types-DelU6kln.mjs +25 -0
  143. package/dist/types-RLkFVgaw.d.mts +101 -0
  144. package/dist/utils/index.d.mts +747 -0
  145. package/dist/utils/index.mjs +6 -0
  146. package/package.json +194 -68
  147. package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
  148. package/dist/adapters/index.d.ts +0 -237
  149. package/dist/adapters/index.js +0 -668
  150. package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
  151. package/dist/audit/index.d.ts +0 -195
  152. package/dist/audit/index.js +0 -319
  153. package/dist/auth/index.d.ts +0 -47
  154. package/dist/auth/index.js +0 -174
  155. package/dist/cli/commands/docs.d.ts +0 -11
  156. package/dist/cli/commands/docs.js +0 -474
  157. package/dist/cli/commands/generate.js +0 -334
  158. package/dist/cli/commands/introspect.d.ts +0 -8
  159. package/dist/cli/commands/introspect.js +0 -338
  160. package/dist/cli/index.d.ts +0 -4
  161. package/dist/cli/index.js +0 -3269
  162. package/dist/core/index.d.ts +0 -220
  163. package/dist/core/index.js +0 -2786
  164. package/dist/createApp-Ce9wl8W9.d.ts +0 -77
  165. package/dist/docs/index.d.ts +0 -166
  166. package/dist/docs/index.js +0 -658
  167. package/dist/errors-8WIxGS_6.d.ts +0 -122
  168. package/dist/events/index.d.ts +0 -117
  169. package/dist/events/index.js +0 -89
  170. package/dist/factory/index.d.ts +0 -38
  171. package/dist/factory/index.js +0 -1652
  172. package/dist/hooks/index.d.ts +0 -4
  173. package/dist/hooks/index.js +0 -199
  174. package/dist/idempotency/index.d.ts +0 -323
  175. package/dist/idempotency/index.js +0 -500
  176. package/dist/index-B4t03KQ0.d.ts +0 -1366
  177. package/dist/index.d.ts +0 -135
  178. package/dist/index.js +0 -4756
  179. package/dist/migrations/index.d.ts +0 -185
  180. package/dist/migrations/index.js +0 -274
  181. package/dist/org/index.d.ts +0 -129
  182. package/dist/org/index.js +0 -220
  183. package/dist/permissions/index.d.ts +0 -144
  184. package/dist/permissions/index.js +0 -103
  185. package/dist/plugins/index.d.ts +0 -46
  186. package/dist/plugins/index.js +0 -1069
  187. package/dist/policies/index.js +0 -196
  188. package/dist/presets/index.js +0 -384
  189. package/dist/presets/multiTenant.d.ts +0 -39
  190. package/dist/presets/multiTenant.js +0 -112
  191. package/dist/registry/index.d.ts +0 -16
  192. package/dist/registry/index.js +0 -253
  193. package/dist/testing/index.d.ts +0 -618
  194. package/dist/testing/index.js +0 -48020
  195. package/dist/types/index.d.ts +0 -4
  196. package/dist/types/index.js +0 -8
  197. package/dist/types-B99TBmFV.d.ts +0 -76
  198. package/dist/types-BvckRbs2.d.ts +0 -143
  199. package/dist/utils/index.d.ts +0 -679
  200. package/dist/utils/index.js +0 -931
@@ -0,0 +1,747 @@
1
+ import "../elevation-DGo5shaX.mjs";
2
+ import "../interface-e9XfSsUV.mjs";
3
+ import "../types-RLkFVgaw.mjs";
4
+ import { AnyRecord, OpenApiSchemas, ParsedQuery, QueryParserInterface } from "../types/index.mjs";
5
+ import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createError, i as ForbiddenError, l as ServiceUnavailableError, n as ConflictError, o as OrgAccessDeniedError, p as isArcError, r as ErrorDetails, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-DAWRdiYP.mjs";
6
+ import { FastifyInstance } from "fastify";
7
+
8
+ //#region src/utils/responseSchemas.d.ts
9
+ interface JsonSchema {
10
+ type: string;
11
+ properties?: Record<string, JsonSchema | AnyRecord>;
12
+ required?: string[];
13
+ items?: JsonSchema | AnyRecord;
14
+ additionalProperties?: boolean | JsonSchema;
15
+ description?: string;
16
+ example?: unknown;
17
+ [key: string]: unknown;
18
+ }
19
+ /**
20
+ * Base success response schema
21
+ */
22
+ declare const successResponseSchema: JsonSchema;
23
+ /**
24
+ * Error response schema
25
+ */
26
+ declare const errorResponseSchema: JsonSchema;
27
+ /**
28
+ * Pagination schema - matches MongoKit/Arc runtime format
29
+ *
30
+ * Runtime format (flat fields):
31
+ * { page, limit, total, pages, hasNext, hasPrev }
32
+ */
33
+ declare const paginationSchema: JsonSchema;
34
+ /**
35
+ * Wrap a data schema in a success response
36
+ */
37
+ declare function wrapResponse(dataSchema: JsonSchema): JsonSchema;
38
+ /**
39
+ * Create a list response schema with pagination - matches MongoKit/Arc runtime format
40
+ *
41
+ * Runtime format:
42
+ * { success, docs: [...], page, limit, total, pages, hasNext, hasPrev }
43
+ *
44
+ * Note: Uses 'docs' array (not 'data') with flat pagination fields
45
+ */
46
+ declare function listResponse(itemSchema: JsonSchema): JsonSchema;
47
+ /**
48
+ * Alias for listResponse - matches local responseSchemas.js naming
49
+ */
50
+ declare const paginateWrapper: typeof listResponse;
51
+ /**
52
+ * Create a single item response schema
53
+ *
54
+ * Runtime format: { success, data: {...} }
55
+ */
56
+ declare function itemResponse(itemSchema: JsonSchema): JsonSchema;
57
+ /**
58
+ * Alias for itemResponse - matches local responseSchemas.js naming
59
+ */
60
+ declare const itemWrapper: typeof itemResponse;
61
+ /**
62
+ * Create a create/update response schema
63
+ */
64
+ declare function mutationResponse(itemSchema: JsonSchema): JsonSchema;
65
+ /**
66
+ * Create a delete response schema
67
+ *
68
+ * Runtime format: { success, message }
69
+ */
70
+ declare function deleteResponse(): JsonSchema;
71
+ /**
72
+ * Alias for deleteResponse - matches local responseSchemas.js naming
73
+ */
74
+ declare const messageWrapper: typeof deleteResponse;
75
+ declare const responses: {
76
+ 200: (schema: JsonSchema) => {
77
+ description: string;
78
+ content: {
79
+ 'application/json': {
80
+ schema: JsonSchema;
81
+ };
82
+ };
83
+ };
84
+ 201: (schema: JsonSchema) => {
85
+ description: string;
86
+ content: {
87
+ 'application/json': {
88
+ schema: JsonSchema;
89
+ };
90
+ };
91
+ };
92
+ 400: {
93
+ description: string;
94
+ content: {
95
+ 'application/json': {
96
+ schema: {
97
+ properties: {
98
+ code: {
99
+ type: string;
100
+ example: string;
101
+ };
102
+ details: {
103
+ type: string;
104
+ properties: {
105
+ errors: {
106
+ type: string;
107
+ items: {
108
+ type: string;
109
+ properties: {
110
+ field: {
111
+ type: string;
112
+ };
113
+ message: {
114
+ type: string;
115
+ };
116
+ };
117
+ };
118
+ };
119
+ };
120
+ };
121
+ };
122
+ type: string;
123
+ required?: string[];
124
+ items?: JsonSchema | AnyRecord;
125
+ additionalProperties?: boolean | JsonSchema;
126
+ description?: string;
127
+ example?: unknown;
128
+ };
129
+ };
130
+ };
131
+ };
132
+ 401: {
133
+ description: string;
134
+ content: {
135
+ 'application/json': {
136
+ schema: {
137
+ properties: {
138
+ code: {
139
+ type: string;
140
+ example: string;
141
+ };
142
+ };
143
+ type: string;
144
+ required?: string[];
145
+ items?: JsonSchema | AnyRecord;
146
+ additionalProperties?: boolean | JsonSchema;
147
+ description?: string;
148
+ example?: unknown;
149
+ };
150
+ };
151
+ };
152
+ };
153
+ 403: {
154
+ description: string;
155
+ content: {
156
+ 'application/json': {
157
+ schema: {
158
+ properties: {
159
+ code: {
160
+ type: string;
161
+ example: string;
162
+ };
163
+ };
164
+ type: string;
165
+ required?: string[];
166
+ items?: JsonSchema | AnyRecord;
167
+ additionalProperties?: boolean | JsonSchema;
168
+ description?: string;
169
+ example?: unknown;
170
+ };
171
+ };
172
+ };
173
+ };
174
+ 404: {
175
+ description: string;
176
+ content: {
177
+ 'application/json': {
178
+ schema: {
179
+ properties: {
180
+ code: {
181
+ type: string;
182
+ example: string;
183
+ };
184
+ };
185
+ type: string;
186
+ required?: string[];
187
+ items?: JsonSchema | AnyRecord;
188
+ additionalProperties?: boolean | JsonSchema;
189
+ description?: string;
190
+ example?: unknown;
191
+ };
192
+ };
193
+ };
194
+ };
195
+ 409: {
196
+ description: string;
197
+ content: {
198
+ 'application/json': {
199
+ schema: {
200
+ properties: {
201
+ code: {
202
+ type: string;
203
+ example: string;
204
+ };
205
+ };
206
+ type: string;
207
+ required?: string[];
208
+ items?: JsonSchema | AnyRecord;
209
+ additionalProperties?: boolean | JsonSchema;
210
+ description?: string;
211
+ example?: unknown;
212
+ };
213
+ };
214
+ };
215
+ };
216
+ 500: {
217
+ description: string;
218
+ content: {
219
+ 'application/json': {
220
+ schema: {
221
+ properties: {
222
+ code: {
223
+ type: string;
224
+ example: string;
225
+ };
226
+ };
227
+ type: string;
228
+ required?: string[];
229
+ items?: JsonSchema | AnyRecord;
230
+ additionalProperties?: boolean | JsonSchema;
231
+ description?: string;
232
+ example?: unknown;
233
+ };
234
+ };
235
+ };
236
+ };
237
+ };
238
+ declare const queryParams: {
239
+ pagination: {
240
+ page: {
241
+ type: string;
242
+ minimum: number;
243
+ default: number;
244
+ description: string;
245
+ };
246
+ limit: {
247
+ type: string;
248
+ minimum: number;
249
+ maximum: number;
250
+ default: number;
251
+ description: string;
252
+ };
253
+ };
254
+ sorting: {
255
+ sort: {
256
+ type: string;
257
+ description: string;
258
+ example: string;
259
+ };
260
+ };
261
+ filtering: {
262
+ select: {
263
+ description: string;
264
+ example: string;
265
+ };
266
+ populate: {
267
+ description: string;
268
+ example: string;
269
+ };
270
+ };
271
+ };
272
+ /**
273
+ * Get standard list query parameters schema
274
+ */
275
+ declare function getListQueryParams(): AnyRecord;
276
+ /**
277
+ * Get default response schemas for all CRUD operations.
278
+ *
279
+ * When routes have response schemas, Fastify compiles them with
280
+ * fast-json-stringify for 2-3x faster serialization and prevents
281
+ * accidental field disclosure.
282
+ *
283
+ * These defaults use `additionalProperties: true` so all fields pass through.
284
+ * Override with specific schemas for full serialization performance + safety.
285
+ *
286
+ * Note: `example` properties are stripped from defaults so they work with
287
+ * any Fastify instance (not just createApp which adds `keywords: ['example']`).
288
+ */
289
+ declare function getDefaultCrudSchemas(): Record<string, Record<string, unknown>>;
290
+ //#endregion
291
+ //#region src/utils/stateMachine.d.ts
292
+ /**
293
+ * State Machine Utility
294
+ *
295
+ * Pure utility for validating state transitions in workflow systems.
296
+ * Zero dependencies, framework-agnostic.
297
+ *
298
+ * @example
299
+ * const orderState = createStateMachine('Order', {
300
+ * approve: ['pending', 'draft'],
301
+ * cancel: ['pending', 'approved'],
302
+ * fulfill: ['approved'],
303
+ * });
304
+ *
305
+ * // Check if transition is allowed
306
+ * if (orderState.can('approve', currentStatus)) {
307
+ * // Perform approval
308
+ * }
309
+ *
310
+ * // Assert transition (throws if invalid)
311
+ * orderState.assert('approve', currentStatus, ValidationError);
312
+ */
313
+ interface StateMachine {
314
+ /**
315
+ * Synchronously check if action can be performed from current status.
316
+ * Only checks the transition map — does NOT evaluate guards.
317
+ * Use `canAsync()` when guards need to be evaluated.
318
+ */
319
+ can(action: string, status: string | null | undefined): boolean;
320
+ /**
321
+ * Asynchronously check if action can be performed, including guard evaluation.
322
+ * Falls back to simple transition check when no guard is defined.
323
+ */
324
+ canAsync(action: string, status: string | null | undefined, context?: any): Promise<boolean>;
325
+ /**
326
+ * Assert action can be performed, throw error if invalid
327
+ * @param action - Action to perform
328
+ * @param status - Current status
329
+ * @param errorFactory - Optional error constructor
330
+ * @param message - Optional custom error message
331
+ */
332
+ assert(action: string, status: string | null | undefined, errorFactory?: (msg: string) => Error, message?: string): void;
333
+ /**
334
+ * Get transition history
335
+ */
336
+ getHistory?(): TransitionHistoryEntry[];
337
+ /**
338
+ * Record a transition
339
+ */
340
+ recordTransition?(from: string, to: string, action: string, metadata?: any): void;
341
+ /**
342
+ * Clear history
343
+ */
344
+ clearHistory?(): void;
345
+ /**
346
+ * Get available actions for current status
347
+ */
348
+ getAvailableActions?(status: string): string[];
349
+ }
350
+ interface TransitionHistoryEntry {
351
+ from: string;
352
+ to: string;
353
+ action: string;
354
+ timestamp: Date;
355
+ metadata?: any;
356
+ }
357
+ interface TransitionGuard {
358
+ (context: {
359
+ from: string;
360
+ to: string;
361
+ action: string;
362
+ data?: any;
363
+ }): boolean | Promise<boolean>;
364
+ }
365
+ interface TransitionAction {
366
+ (context: {
367
+ from: string;
368
+ to: string;
369
+ action: string;
370
+ data?: any;
371
+ }): void | Promise<void>;
372
+ }
373
+ type TransitionConfig = Record<string, string[] | {
374
+ from: string[];
375
+ to?: string;
376
+ guard?: TransitionGuard;
377
+ before?: TransitionAction;
378
+ after?: TransitionAction;
379
+ }>;
380
+ /**
381
+ * Create a state machine for validating transitions
382
+ *
383
+ * @param name - Name of the state machine (used in error messages)
384
+ * @param transitions - Map of actions to allowed source statuses
385
+ * @param options - Additional options (history, guards, actions)
386
+ * @returns State machine with can() and assert() methods
387
+ *
388
+ * @example
389
+ * // Basic usage
390
+ * const transferState = createStateMachine('Transfer', {
391
+ * approve: ['draft'],
392
+ * dispatch: ['approved'],
393
+ * receive: ['dispatched', 'in_transit'],
394
+ * cancel: ['draft', 'approved'],
395
+ * });
396
+ *
397
+ * @example
398
+ * // With guards and actions
399
+ * const orderState = createStateMachine('Order', {
400
+ * approve: {
401
+ * from: ['pending'],
402
+ * to: 'approved',
403
+ * guard: ({ data }) => data.paymentConfirmed,
404
+ * before: ({ from, to }) => console.log(`Approving order from ${from} to ${to}`),
405
+ * after: ({ data }) => sendApprovalEmail(data.customerId),
406
+ * },
407
+ * }, { trackHistory: true });
408
+ */
409
+ declare function createStateMachine(name: string, transitions?: TransitionConfig, options?: {
410
+ trackHistory?: boolean;
411
+ }): StateMachine;
412
+ //#endregion
413
+ //#region src/utils/circuitBreaker.d.ts
414
+ /**
415
+ * Circuit Breaker Pattern
416
+ *
417
+ * Wraps external service calls with failure protection.
418
+ * Prevents cascading failures by "opening" the circuit when
419
+ * a service is failing, allowing it time to recover.
420
+ *
421
+ * States:
422
+ * - CLOSED: Normal operation, requests pass through
423
+ * - OPEN: Too many failures, all requests fail fast
424
+ * - HALF_OPEN: Testing if service recovered, limited requests
425
+ *
426
+ * @example
427
+ * import { CircuitBreaker } from '@classytic/arc/utils';
428
+ *
429
+ * const paymentBreaker = new CircuitBreaker(async (amount) => {
430
+ * return await stripe.charges.create({ amount });
431
+ * }, {
432
+ * failureThreshold: 5,
433
+ * resetTimeout: 30000,
434
+ * timeout: 5000,
435
+ * });
436
+ *
437
+ * try {
438
+ * const result = await paymentBreaker.call(100);
439
+ * } catch (error) {
440
+ * // Handle failure or circuit open
441
+ * }
442
+ */
443
+ declare const CircuitState: {
444
+ readonly CLOSED: "CLOSED";
445
+ readonly OPEN: "OPEN";
446
+ readonly HALF_OPEN: "HALF_OPEN";
447
+ };
448
+ type CircuitState = (typeof CircuitState)[keyof typeof CircuitState];
449
+ interface CircuitBreakerOptions {
450
+ /**
451
+ * Number of failures before opening circuit
452
+ * @default 5
453
+ */
454
+ failureThreshold?: number;
455
+ /**
456
+ * Time in ms before attempting to close circuit
457
+ * @default 60000 (60 seconds)
458
+ */
459
+ resetTimeout?: number;
460
+ /**
461
+ * Request timeout in ms
462
+ * @default 10000 (10 seconds)
463
+ */
464
+ timeout?: number;
465
+ /**
466
+ * Number of successful requests in HALF_OPEN before closing
467
+ * @default 1
468
+ */
469
+ successThreshold?: number;
470
+ /**
471
+ * Fallback function when circuit is open
472
+ */
473
+ fallback?: (...args: any[]) => Promise<any>;
474
+ /**
475
+ * Callback when state changes
476
+ */
477
+ onStateChange?: (from: CircuitState, to: CircuitState) => void;
478
+ /**
479
+ * Callback on error
480
+ */
481
+ onError?: (error: Error) => void;
482
+ /**
483
+ * Name for logging/monitoring
484
+ */
485
+ name?: string;
486
+ }
487
+ interface CircuitBreakerStats {
488
+ name?: string;
489
+ state: CircuitState;
490
+ failures: number;
491
+ successes: number;
492
+ totalCalls: number;
493
+ openedAt: number | null;
494
+ lastCallAt: number | null;
495
+ }
496
+ declare class CircuitBreakerError extends Error {
497
+ state: CircuitState;
498
+ constructor(message: string, state: CircuitState);
499
+ }
500
+ declare class CircuitBreaker<T extends (...args: any[]) => Promise<any>> {
501
+ private state;
502
+ private failures;
503
+ private successes;
504
+ private totalCalls;
505
+ private nextAttempt;
506
+ private lastCallAt;
507
+ private openedAt;
508
+ private readonly failureThreshold;
509
+ private readonly resetTimeout;
510
+ private readonly timeout;
511
+ private readonly successThreshold;
512
+ private readonly fallback?;
513
+ private readonly onStateChange?;
514
+ private readonly onError?;
515
+ private readonly name;
516
+ private readonly fn;
517
+ constructor(fn: T, options?: CircuitBreakerOptions);
518
+ /**
519
+ * Call the wrapped function with circuit breaker protection
520
+ */
521
+ call(...args: Parameters<T>): Promise<ReturnType<T>>;
522
+ /**
523
+ * Execute function with timeout
524
+ */
525
+ private executeWithTimeout;
526
+ /**
527
+ * Handle successful call
528
+ */
529
+ private onSuccess;
530
+ /**
531
+ * Handle failed call
532
+ */
533
+ private onFailure;
534
+ /**
535
+ * Change circuit state
536
+ */
537
+ private setState;
538
+ /**
539
+ * Manually open the circuit
540
+ */
541
+ open(): void;
542
+ /**
543
+ * Manually close the circuit
544
+ */
545
+ close(): void;
546
+ /**
547
+ * Get current statistics
548
+ */
549
+ getStats(): CircuitBreakerStats;
550
+ /**
551
+ * Get current state
552
+ */
553
+ getState(): CircuitState;
554
+ /**
555
+ * Check if circuit is open
556
+ */
557
+ isOpen(): boolean;
558
+ /**
559
+ * Check if circuit is closed
560
+ */
561
+ isClosed(): boolean;
562
+ /**
563
+ * Reset statistics
564
+ */
565
+ reset(): void;
566
+ }
567
+ /**
568
+ * Create a circuit breaker with sensible defaults
569
+ *
570
+ * @example
571
+ * const emailBreaker = createCircuitBreaker(
572
+ * async (to, subject, body) => sendEmail(to, subject, body),
573
+ * { name: 'email-service' }
574
+ * );
575
+ */
576
+ declare function createCircuitBreaker<T extends (...args: any[]) => Promise<any>>(fn: T, options?: CircuitBreakerOptions): CircuitBreaker<T>;
577
+ /**
578
+ * Circuit breaker registry for managing multiple breakers
579
+ */
580
+ declare class CircuitBreakerRegistry {
581
+ private breakers;
582
+ /**
583
+ * Register a circuit breaker
584
+ */
585
+ register<T extends (...args: any[]) => Promise<any>>(name: string, fn: T, options?: Omit<CircuitBreakerOptions, 'name'>): CircuitBreaker<T>;
586
+ /**
587
+ * Get a circuit breaker by name
588
+ */
589
+ get(name: string): CircuitBreaker<any> | undefined;
590
+ /**
591
+ * Get all breakers
592
+ */
593
+ getAll(): Map<string, CircuitBreaker<any>>;
594
+ /**
595
+ * Get statistics for all breakers
596
+ */
597
+ getAllStats(): Record<string, CircuitBreakerStats>;
598
+ /**
599
+ * Reset all breakers
600
+ */
601
+ resetAll(): void;
602
+ /**
603
+ * Open all breakers
604
+ */
605
+ openAll(): void;
606
+ /**
607
+ * Close all breakers
608
+ */
609
+ closeAll(): void;
610
+ }
611
+ /**
612
+ * Create a new CircuitBreakerRegistry instance.
613
+ * Use this instead of a global singleton — attach to fastify.arc or pass explicitly.
614
+ */
615
+ declare function createCircuitBreakerRegistry(): CircuitBreakerRegistry;
616
+ //#endregion
617
+ //#region src/utils/queryParser.d.ts
618
+ interface ArcQueryParserOptions {
619
+ /** Maximum allowed limit value (default: 1000) */
620
+ maxLimit?: number;
621
+ /** Default limit for pagination (default: 20) */
622
+ defaultLimit?: number;
623
+ /** Maximum regex pattern length (default: 500) */
624
+ maxRegexLength?: number;
625
+ /** Maximum search query length (default: 200) */
626
+ maxSearchLength?: number;
627
+ /** Maximum filter nesting depth (default: 10) */
628
+ maxFilterDepth?: number;
629
+ }
630
+ /**
631
+ * Arc's default query parser
632
+ *
633
+ * Converts URL query parameters to a structured query format:
634
+ * - Pagination: ?page=1&limit=20
635
+ * - Sorting: ?sort=-createdAt,name (- prefix = descending)
636
+ * - Filtering: ?status=active&price[gte]=100&price[lte]=500
637
+ * - Search: ?search=keyword
638
+ * - Populate: ?populate=author,category
639
+ * - Field selection: ?select=name,price,status
640
+ * - Keyset pagination: ?after=cursor_value
641
+ *
642
+ * For advanced MongoDB features ($lookup, aggregations), use MongoKit's QueryParser.
643
+ */
644
+ declare class ArcQueryParser implements QueryParserInterface {
645
+ private readonly maxLimit;
646
+ private readonly defaultLimit;
647
+ private readonly maxRegexLength;
648
+ private readonly maxSearchLength;
649
+ private readonly maxFilterDepth;
650
+ /** Supported filter operators */
651
+ private readonly operators;
652
+ constructor(options?: ArcQueryParserOptions);
653
+ /**
654
+ * Parse URL query parameters into structured query options
655
+ */
656
+ parse(query: Record<string, unknown> | null | undefined): ParsedQuery;
657
+ private parseNumber;
658
+ private parseString;
659
+ /**
660
+ * Parse populate parameter — handles both simple string and bracket notation.
661
+ *
662
+ * Simple: ?populate=author,category → { populate: 'author,category' }
663
+ * Bracket: ?populate[author][select]=name,email → { populateOptions: [{ path: 'author', select: 'name email' }] }
664
+ */
665
+ private parsePopulate;
666
+ private parseSort;
667
+ private parseSearch;
668
+ private parseSelect;
669
+ /**
670
+ * Check if a value exceeds the maximum nesting depth.
671
+ * Prevents filter bombs where deeply nested objects consume excessive memory/CPU.
672
+ */
673
+ private exceedsDepth;
674
+ private parseFilters;
675
+ private parseFilterValue;
676
+ private coerceValue;
677
+ /**
678
+ * Generate OpenAPI-compatible JSON Schema for query parameters.
679
+ * Arc's defineResource() auto-detects this method and uses it
680
+ * to document list endpoint query parameters in OpenAPI/Swagger.
681
+ */
682
+ getQuerySchema(): {
683
+ type: 'object';
684
+ properties: Record<string, unknown>;
685
+ required?: string[];
686
+ };
687
+ private sanitizeRegex;
688
+ }
689
+ /**
690
+ * Create a new ArcQueryParser instance
691
+ */
692
+ declare function createQueryParser(options?: ArcQueryParserOptions): ArcQueryParser;
693
+ //#endregion
694
+ //#region src/utils/typeGuards.d.ts
695
+ interface EventsDecorator {
696
+ publish: <T>(type: string, payload: T, meta?: Record<string, unknown>) => Promise<void>;
697
+ subscribe: (pattern: string, handler: (event: {
698
+ type: string;
699
+ payload: unknown;
700
+ meta: Record<string, unknown>;
701
+ }) => Promise<void>) => Promise<() => void>;
702
+ transportName: string;
703
+ }
704
+ /** Check if fastify has the events plugin registered */
705
+ declare function hasEvents(instance: FastifyInstance): instance is FastifyInstance & {
706
+ events: EventsDecorator;
707
+ };
708
+ //#endregion
709
+ //#region src/utils/schemaConverter.d.ts
710
+ /**
711
+ * Check if an object is already a plain JSON Schema.
712
+ * Returns true if it has JSON Schema markers (`type`, `properties`, `$ref`,
713
+ * `allOf`, `anyOf`, `oneOf`, `items`, `enum`) and does NOT have Zod markers.
714
+ */
715
+ declare function isJsonSchema(input: unknown): input is Record<string, unknown>;
716
+ /**
717
+ * Check if an object is a Zod schema (has `_zod` marker from Zod v4).
718
+ */
719
+ declare function isZodSchema(input: unknown): boolean;
720
+ /**
721
+ * Convert any schema input to JSON Schema.
722
+ *
723
+ * Detection order:
724
+ * 1. `null`/`undefined` → `undefined`
725
+ * 2. Already JSON Schema → pass through as-is (zero overhead)
726
+ * 3. Zod v4 schema → `z.toJSONSchema(schema, { target: 'openapi-3.0' })`
727
+ * 4. Unrecognized object → return as-is (treat as opaque schema)
728
+ */
729
+ declare function toJsonSchema(input: unknown): Record<string, unknown> | undefined;
730
+ /**
731
+ * Convert all schema fields in an OpenApiSchemas object.
732
+ * JSON Schema values pass through unchanged. Only Zod schemas are converted.
733
+ */
734
+ declare function convertOpenApiSchemas(schemas: OpenApiSchemas): OpenApiSchemas;
735
+ /**
736
+ * Convert schema values in a Fastify route schema record.
737
+ *
738
+ * Handles `body`, `querystring`, `params`, `headers` (top-level conversion)
739
+ * and `response` (iterates by status code — each value converted individually).
740
+ *
741
+ * JSON Schema values pass through unchanged. Only Zod schemas are converted.
742
+ *
743
+ * Used for both additionalRoutes and customSchemas (CRUD overrides).
744
+ */
745
+ declare function convertRouteSchema(schema: Record<string, unknown>): Record<string, unknown>;
746
+ //#endregion
747
+ export { ArcError, ArcQueryParser, type ArcQueryParserOptions, CircuitBreaker, CircuitBreakerError, type CircuitBreakerOptions, CircuitBreakerRegistry, type CircuitBreakerStats, CircuitState, ConflictError, type ErrorDetails, type EventsDecorator, ForbiddenError, type JsonSchema, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, type StateMachine, type TransitionConfig, UnauthorizedError, ValidationError, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createError, createQueryParser, createStateMachine, deleteResponse, errorResponseSchema, getDefaultCrudSchemas, getListQueryParams, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, itemWrapper, listResponse, messageWrapper, mutationResponse, paginateWrapper, paginationSchema, queryParams, responses, successResponseSchema, toJsonSchema, wrapResponse };