@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
@@ -1,931 +0,0 @@
1
- // src/utils/errors.ts
2
- var ArcError = class extends Error {
3
- name;
4
- code;
5
- statusCode;
6
- details;
7
- cause;
8
- timestamp;
9
- requestId;
10
- constructor(message, options = {}) {
11
- super(message);
12
- this.name = "ArcError";
13
- this.code = options.code ?? "ARC_ERROR";
14
- this.statusCode = options.statusCode ?? 500;
15
- this.details = options.details;
16
- this.cause = options.cause;
17
- this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
18
- this.requestId = options.requestId;
19
- if (Error.captureStackTrace) {
20
- Error.captureStackTrace(this, this.constructor);
21
- }
22
- }
23
- /**
24
- * Set request ID (typically from request context)
25
- */
26
- withRequestId(requestId) {
27
- this.requestId = requestId;
28
- return this;
29
- }
30
- /**
31
- * Convert to JSON response
32
- */
33
- toJSON() {
34
- return {
35
- success: false,
36
- error: this.message,
37
- code: this.code,
38
- timestamp: this.timestamp,
39
- ...this.requestId && { requestId: this.requestId },
40
- ...this.details && { details: this.details }
41
- };
42
- }
43
- };
44
- var NotFoundError = class extends ArcError {
45
- constructor(resource, identifier) {
46
- const message = identifier ? `${resource} with identifier '${identifier}' not found` : `${resource} not found`;
47
- super(message, {
48
- code: "NOT_FOUND",
49
- statusCode: 404,
50
- details: { resource, identifier }
51
- });
52
- this.name = "NotFoundError";
53
- }
54
- };
55
- var ValidationError = class extends ArcError {
56
- errors;
57
- constructor(message, errors = []) {
58
- super(message, {
59
- code: "VALIDATION_ERROR",
60
- statusCode: 400,
61
- details: { errors }
62
- });
63
- this.name = "ValidationError";
64
- this.errors = errors;
65
- }
66
- };
67
- var UnauthorizedError = class extends ArcError {
68
- constructor(message = "Authentication required") {
69
- super(message, {
70
- code: "UNAUTHORIZED",
71
- statusCode: 401
72
- });
73
- this.name = "UnauthorizedError";
74
- }
75
- };
76
- var ForbiddenError = class extends ArcError {
77
- constructor(message = "Access denied") {
78
- super(message, {
79
- code: "FORBIDDEN",
80
- statusCode: 403
81
- });
82
- this.name = "ForbiddenError";
83
- }
84
- };
85
- var ConflictError = class extends ArcError {
86
- constructor(message, field) {
87
- super(message, {
88
- code: "CONFLICT",
89
- statusCode: 409,
90
- details: field ? { field } : void 0
91
- });
92
- this.name = "ConflictError";
93
- }
94
- };
95
- var OrgRequiredError = class extends ArcError {
96
- organizations;
97
- constructor(message, organizations) {
98
- super(message, {
99
- code: "ORG_SELECTION_REQUIRED",
100
- statusCode: 403,
101
- details: organizations ? { organizations } : void 0
102
- });
103
- this.name = "OrgRequiredError";
104
- this.organizations = organizations;
105
- }
106
- };
107
- var OrgAccessDeniedError = class extends ArcError {
108
- constructor(orgId) {
109
- super("Organization access denied", {
110
- code: "ORG_ACCESS_DENIED",
111
- statusCode: 403,
112
- details: orgId ? { organizationId: orgId } : void 0
113
- });
114
- this.name = "OrgAccessDeniedError";
115
- }
116
- };
117
- var RateLimitError = class extends ArcError {
118
- retryAfter;
119
- constructor(message = "Too many requests", retryAfter) {
120
- super(message, {
121
- code: "RATE_LIMITED",
122
- statusCode: 429,
123
- details: retryAfter ? { retryAfter } : void 0
124
- });
125
- this.name = "RateLimitError";
126
- this.retryAfter = retryAfter;
127
- }
128
- };
129
- var ServiceUnavailableError = class extends ArcError {
130
- constructor(message = "Service temporarily unavailable") {
131
- super(message, {
132
- code: "SERVICE_UNAVAILABLE",
133
- statusCode: 503
134
- });
135
- this.name = "ServiceUnavailableError";
136
- }
137
- };
138
- function createError(statusCode, message, details) {
139
- const codes = {
140
- 400: "BAD_REQUEST",
141
- 401: "UNAUTHORIZED",
142
- 403: "FORBIDDEN",
143
- 404: "NOT_FOUND",
144
- 409: "CONFLICT",
145
- 429: "RATE_LIMITED",
146
- 500: "INTERNAL_ERROR",
147
- 503: "SERVICE_UNAVAILABLE"
148
- };
149
- return new ArcError(message, {
150
- code: codes[statusCode] ?? "ERROR",
151
- statusCode,
152
- details
153
- });
154
- }
155
- function isArcError(error) {
156
- return error instanceof ArcError;
157
- }
158
-
159
- // src/utils/responseSchemas.ts
160
- var successResponseSchema = {
161
- type: "object",
162
- properties: {
163
- success: { type: "boolean", example: true }
164
- },
165
- required: ["success"]
166
- };
167
- var errorResponseSchema = {
168
- type: "object",
169
- properties: {
170
- success: { type: "boolean", example: false },
171
- error: { type: "string", description: "Error message" },
172
- code: { type: "string", description: "Error code" },
173
- message: { type: "string", description: "Detailed message" }
174
- },
175
- required: ["success", "error"]
176
- };
177
- var paginationSchema = {
178
- type: "object",
179
- properties: {
180
- page: { type: "integer", example: 1 },
181
- limit: { type: "integer", example: 20 },
182
- total: { type: "integer", example: 100 },
183
- pages: { type: "integer", example: 5 },
184
- hasNext: { type: "boolean", example: true },
185
- hasPrev: { type: "boolean", example: false }
186
- },
187
- required: ["page", "limit", "total", "pages", "hasNext", "hasPrev"]
188
- };
189
- function wrapResponse(dataSchema) {
190
- return {
191
- type: "object",
192
- properties: {
193
- success: { type: "boolean", example: true },
194
- data: dataSchema
195
- },
196
- required: ["success", "data"]
197
- };
198
- }
199
- function listResponse(itemSchema) {
200
- return {
201
- type: "object",
202
- properties: {
203
- success: { type: "boolean", example: true },
204
- docs: {
205
- type: "array",
206
- items: itemSchema
207
- },
208
- // Flat pagination fields (not nested)
209
- page: { type: "integer", example: 1 },
210
- limit: { type: "integer", example: 20 },
211
- total: { type: "integer", example: 100 },
212
- pages: { type: "integer", example: 5 },
213
- hasNext: { type: "boolean", example: false },
214
- hasPrev: { type: "boolean", example: false }
215
- },
216
- required: ["success", "docs"]
217
- };
218
- }
219
- var paginateWrapper = listResponse;
220
- function itemResponse(itemSchema) {
221
- return wrapResponse(itemSchema);
222
- }
223
- var itemWrapper = itemResponse;
224
- function mutationResponse(itemSchema) {
225
- return {
226
- type: "object",
227
- properties: {
228
- success: { type: "boolean", example: true },
229
- data: itemSchema,
230
- message: { type: "string", example: "Created successfully" }
231
- },
232
- required: ["success", "data"]
233
- };
234
- }
235
- function deleteResponse() {
236
- return {
237
- type: "object",
238
- properties: {
239
- success: { type: "boolean", example: true },
240
- message: { type: "string", example: "Deleted successfully" }
241
- },
242
- required: ["success"]
243
- };
244
- }
245
- var messageWrapper = deleteResponse;
246
- var responses = {
247
- 200: (schema) => ({
248
- description: "Successful response",
249
- content: {
250
- "application/json": { schema }
251
- }
252
- }),
253
- 201: (schema) => ({
254
- description: "Created successfully",
255
- content: {
256
- "application/json": { schema: mutationResponse(schema) }
257
- }
258
- }),
259
- 400: {
260
- description: "Bad Request",
261
- content: {
262
- "application/json": {
263
- schema: {
264
- ...errorResponseSchema,
265
- properties: {
266
- ...errorResponseSchema.properties,
267
- code: { type: "string", example: "VALIDATION_ERROR" },
268
- details: {
269
- type: "object",
270
- properties: {
271
- errors: {
272
- type: "array",
273
- items: {
274
- type: "object",
275
- properties: {
276
- field: { type: "string" },
277
- message: { type: "string" }
278
- }
279
- }
280
- }
281
- }
282
- }
283
- }
284
- }
285
- }
286
- }
287
- },
288
- 401: {
289
- description: "Unauthorized",
290
- content: {
291
- "application/json": {
292
- schema: {
293
- ...errorResponseSchema,
294
- properties: {
295
- ...errorResponseSchema.properties,
296
- code: { type: "string", example: "UNAUTHORIZED" }
297
- }
298
- }
299
- }
300
- }
301
- },
302
- 403: {
303
- description: "Forbidden",
304
- content: {
305
- "application/json": {
306
- schema: {
307
- ...errorResponseSchema,
308
- properties: {
309
- ...errorResponseSchema.properties,
310
- code: { type: "string", example: "FORBIDDEN" }
311
- }
312
- }
313
- }
314
- }
315
- },
316
- 404: {
317
- description: "Not Found",
318
- content: {
319
- "application/json": {
320
- schema: {
321
- ...errorResponseSchema,
322
- properties: {
323
- ...errorResponseSchema.properties,
324
- code: { type: "string", example: "NOT_FOUND" }
325
- }
326
- }
327
- }
328
- }
329
- },
330
- 409: {
331
- description: "Conflict",
332
- content: {
333
- "application/json": {
334
- schema: {
335
- ...errorResponseSchema,
336
- properties: {
337
- ...errorResponseSchema.properties,
338
- code: { type: "string", example: "CONFLICT" }
339
- }
340
- }
341
- }
342
- }
343
- },
344
- 500: {
345
- description: "Internal Server Error",
346
- content: {
347
- "application/json": {
348
- schema: {
349
- ...errorResponseSchema,
350
- properties: {
351
- ...errorResponseSchema.properties,
352
- code: { type: "string", example: "INTERNAL_ERROR" }
353
- }
354
- }
355
- }
356
- }
357
- }
358
- };
359
- var queryParams = {
360
- pagination: {
361
- page: {
362
- type: "integer",
363
- minimum: 1,
364
- default: 1,
365
- description: "Page number"
366
- },
367
- limit: {
368
- type: "integer",
369
- minimum: 1,
370
- maximum: 100,
371
- default: 20,
372
- description: "Items per page"
373
- }
374
- },
375
- sorting: {
376
- sort: {
377
- type: "string",
378
- description: "Sort field (prefix with - for descending)",
379
- example: "-createdAt"
380
- }
381
- },
382
- filtering: {
383
- select: {
384
- type: "string",
385
- description: "Fields to include (space-separated)",
386
- example: "name email createdAt"
387
- },
388
- populate: {
389
- type: "string",
390
- description: "Relations to populate (comma-separated)",
391
- example: "author,category"
392
- }
393
- }
394
- };
395
- function getListQueryParams() {
396
- return {
397
- type: "object",
398
- properties: {
399
- ...queryParams.pagination,
400
- ...queryParams.sorting,
401
- ...queryParams.filtering
402
- }
403
- };
404
- }
405
-
406
- // src/utils/stateMachine.ts
407
- function createStateMachine(name, transitions = {}, options = {}) {
408
- const normalized = /* @__PURE__ */ new Map();
409
- const history = options.trackHistory ? [] : void 0;
410
- Object.entries(transitions).forEach(([action, allowed]) => {
411
- if (Array.isArray(allowed)) {
412
- normalized.set(action, { from: new Set(allowed) });
413
- } else if (typeof allowed === "object" && "from" in allowed) {
414
- normalized.set(action, {
415
- from: new Set(Array.isArray(allowed.from) ? allowed.from : [allowed.from]),
416
- to: allowed.to,
417
- guard: allowed.guard,
418
- before: allowed.before,
419
- after: allowed.after
420
- });
421
- }
422
- });
423
- const canSync = (action, status) => {
424
- const transition = normalized.get(action);
425
- if (!transition || !status) return false;
426
- return transition.from.has(status);
427
- };
428
- const assert = (action, status, errorFactory, message) => {
429
- if (canSync(action, status)) return;
430
- const errorMessage = message || `${name} cannot '${action}' when status is '${status || "unknown"}'`;
431
- if (typeof errorFactory === "function") {
432
- throw errorFactory(errorMessage);
433
- }
434
- throw new Error(errorMessage);
435
- };
436
- const recordTransition = (from, to, action, metadata) => {
437
- if (history) {
438
- history.push({
439
- from,
440
- to,
441
- action,
442
- timestamp: /* @__PURE__ */ new Date(),
443
- metadata
444
- });
445
- }
446
- };
447
- const getHistory = () => {
448
- return history ? [...history] : [];
449
- };
450
- const clearHistory = () => {
451
- if (history) {
452
- history.length = 0;
453
- }
454
- };
455
- const getAvailableActions = (status) => {
456
- const actions = [];
457
- for (const [action, transition] of normalized.entries()) {
458
- if (transition.from.has(status)) {
459
- actions.push(action);
460
- }
461
- }
462
- return actions;
463
- };
464
- return {
465
- can: canSync,
466
- // Return sync version for backward compatibility
467
- assert,
468
- recordTransition,
469
- getHistory,
470
- clearHistory,
471
- getAvailableActions
472
- };
473
- }
474
-
475
- // src/utils/circuitBreaker.ts
476
- var CircuitState = /* @__PURE__ */ ((CircuitState2) => {
477
- CircuitState2["CLOSED"] = "CLOSED";
478
- CircuitState2["OPEN"] = "OPEN";
479
- CircuitState2["HALF_OPEN"] = "HALF_OPEN";
480
- return CircuitState2;
481
- })(CircuitState || {});
482
- var CircuitBreakerError = class extends Error {
483
- constructor(message, state) {
484
- super(message);
485
- this.state = state;
486
- this.name = "CircuitBreakerError";
487
- }
488
- };
489
- var CircuitBreaker = class {
490
- constructor(fn, options = {}) {
491
- this.fn = fn;
492
- this.failureThreshold = options.failureThreshold ?? 5;
493
- this.resetTimeout = options.resetTimeout ?? 6e4;
494
- this.timeout = options.timeout ?? 1e4;
495
- this.successThreshold = options.successThreshold ?? 1;
496
- this.fallback = options.fallback;
497
- this.onStateChange = options.onStateChange;
498
- this.onError = options.onError;
499
- this.name = options.name ?? "CircuitBreaker";
500
- }
501
- state = "CLOSED" /* CLOSED */;
502
- failures = 0;
503
- successes = 0;
504
- totalCalls = 0;
505
- nextAttempt = 0;
506
- lastCallAt = null;
507
- openedAt = null;
508
- failureThreshold;
509
- resetTimeout;
510
- timeout;
511
- successThreshold;
512
- fallback;
513
- onStateChange;
514
- onError;
515
- name;
516
- /**
517
- * Call the wrapped function with circuit breaker protection
518
- */
519
- async call(...args) {
520
- this.totalCalls++;
521
- this.lastCallAt = Date.now();
522
- if (this.state === "OPEN" /* OPEN */) {
523
- if (Date.now() < this.nextAttempt) {
524
- const error = new CircuitBreakerError(
525
- `Circuit breaker is OPEN for ${this.name}`,
526
- "OPEN" /* OPEN */
527
- );
528
- if (this.fallback) {
529
- return this.fallback(...args);
530
- }
531
- throw error;
532
- }
533
- this.setState("HALF_OPEN" /* HALF_OPEN */);
534
- }
535
- try {
536
- const result = await this.executeWithTimeout(args);
537
- this.onSuccess();
538
- return result;
539
- } catch (error) {
540
- this.onFailure(error);
541
- throw error;
542
- }
543
- }
544
- /**
545
- * Execute function with timeout
546
- */
547
- async executeWithTimeout(args) {
548
- return new Promise((resolve, reject) => {
549
- const timeoutId = setTimeout(() => {
550
- reject(new Error(`Request timeout after ${this.timeout}ms`));
551
- }, this.timeout);
552
- this.fn(...args).then((result) => {
553
- clearTimeout(timeoutId);
554
- resolve(result);
555
- }).catch((error) => {
556
- clearTimeout(timeoutId);
557
- reject(error);
558
- });
559
- });
560
- }
561
- /**
562
- * Handle successful call
563
- */
564
- onSuccess() {
565
- this.failures = 0;
566
- this.successes++;
567
- if (this.state === "HALF_OPEN" /* HALF_OPEN */) {
568
- if (this.successes >= this.successThreshold) {
569
- this.setState("CLOSED" /* CLOSED */);
570
- this.successes = 0;
571
- }
572
- }
573
- }
574
- /**
575
- * Handle failed call
576
- */
577
- onFailure(error) {
578
- this.failures++;
579
- this.successes = 0;
580
- if (this.onError) {
581
- this.onError(error);
582
- }
583
- if (this.state === "HALF_OPEN" /* HALF_OPEN */ || this.failures >= this.failureThreshold) {
584
- this.setState("OPEN" /* OPEN */);
585
- this.nextAttempt = Date.now() + this.resetTimeout;
586
- this.openedAt = Date.now();
587
- }
588
- }
589
- /**
590
- * Change circuit state
591
- */
592
- setState(newState) {
593
- const oldState = this.state;
594
- if (oldState !== newState) {
595
- this.state = newState;
596
- if (this.onStateChange) {
597
- this.onStateChange(oldState, newState);
598
- }
599
- }
600
- }
601
- /**
602
- * Manually open the circuit
603
- */
604
- open() {
605
- this.setState("OPEN" /* OPEN */);
606
- this.nextAttempt = Date.now() + this.resetTimeout;
607
- this.openedAt = Date.now();
608
- }
609
- /**
610
- * Manually close the circuit
611
- */
612
- close() {
613
- this.failures = 0;
614
- this.successes = 0;
615
- this.setState("CLOSED" /* CLOSED */);
616
- this.openedAt = null;
617
- }
618
- /**
619
- * Get current statistics
620
- */
621
- getStats() {
622
- return {
623
- name: this.name,
624
- state: this.state,
625
- failures: this.failures,
626
- successes: this.successes,
627
- totalCalls: this.totalCalls,
628
- openedAt: this.openedAt,
629
- lastCallAt: this.lastCallAt
630
- };
631
- }
632
- /**
633
- * Get current state
634
- */
635
- getState() {
636
- return this.state;
637
- }
638
- /**
639
- * Check if circuit is open
640
- */
641
- isOpen() {
642
- return this.state === "OPEN" /* OPEN */;
643
- }
644
- /**
645
- * Check if circuit is closed
646
- */
647
- isClosed() {
648
- return this.state === "CLOSED" /* CLOSED */;
649
- }
650
- /**
651
- * Reset statistics
652
- */
653
- reset() {
654
- this.failures = 0;
655
- this.successes = 0;
656
- this.totalCalls = 0;
657
- this.lastCallAt = null;
658
- this.openedAt = null;
659
- this.setState("CLOSED" /* CLOSED */);
660
- }
661
- };
662
- function createCircuitBreaker(fn, options) {
663
- return new CircuitBreaker(fn, options);
664
- }
665
- var CircuitBreakerRegistry = class {
666
- breakers = /* @__PURE__ */ new Map();
667
- /**
668
- * Register a circuit breaker
669
- */
670
- register(name, fn, options) {
671
- const breaker = new CircuitBreaker(fn, { ...options, name });
672
- this.breakers.set(name, breaker);
673
- return breaker;
674
- }
675
- /**
676
- * Get a circuit breaker by name
677
- */
678
- get(name) {
679
- return this.breakers.get(name);
680
- }
681
- /**
682
- * Get all breakers
683
- */
684
- getAll() {
685
- return this.breakers;
686
- }
687
- /**
688
- * Get statistics for all breakers
689
- */
690
- getAllStats() {
691
- const stats = {};
692
- for (const [name, breaker] of this.breakers.entries()) {
693
- stats[name] = breaker.getStats();
694
- }
695
- return stats;
696
- }
697
- /**
698
- * Reset all breakers
699
- */
700
- resetAll() {
701
- for (const breaker of this.breakers.values()) {
702
- breaker.reset();
703
- }
704
- }
705
- /**
706
- * Open all breakers
707
- */
708
- openAll() {
709
- for (const breaker of this.breakers.values()) {
710
- breaker.open();
711
- }
712
- }
713
- /**
714
- * Close all breakers
715
- */
716
- closeAll() {
717
- for (const breaker of this.breakers.values()) {
718
- breaker.close();
719
- }
720
- }
721
- };
722
- var circuitBreakerRegistry = new CircuitBreakerRegistry();
723
-
724
- // src/utils/queryParser.ts
725
- var DANGEROUS_REGEX_PATTERNS = /(\{[0-9,]+\}|\*\+|\+\+|\?\+|(\(.+\))\+|\(\?\:|\\[0-9]|(\[.+\]).+(\[.+\]))/;
726
- var MAX_REGEX_LENGTH = 500;
727
- var MAX_SEARCH_LENGTH = 200;
728
- var MAX_FILTER_DEPTH = 10;
729
- var MAX_LIMIT = 1e3;
730
- var DEFAULT_LIMIT = 20;
731
- var ArcQueryParser = class {
732
- maxLimit;
733
- defaultLimit;
734
- maxRegexLength;
735
- maxSearchLength;
736
- maxFilterDepth;
737
- /** Supported filter operators */
738
- operators = {
739
- eq: "$eq",
740
- ne: "$ne",
741
- gt: "$gt",
742
- gte: "$gte",
743
- lt: "$lt",
744
- lte: "$lte",
745
- in: "$in",
746
- nin: "$nin",
747
- like: "$regex",
748
- contains: "$regex",
749
- regex: "$regex",
750
- exists: "$exists"
751
- };
752
- constructor(options = {}) {
753
- this.maxLimit = options.maxLimit ?? MAX_LIMIT;
754
- this.defaultLimit = options.defaultLimit ?? DEFAULT_LIMIT;
755
- this.maxRegexLength = options.maxRegexLength ?? MAX_REGEX_LENGTH;
756
- this.maxSearchLength = options.maxSearchLength ?? MAX_SEARCH_LENGTH;
757
- this.maxFilterDepth = options.maxFilterDepth ?? MAX_FILTER_DEPTH;
758
- }
759
- /**
760
- * Parse URL query parameters into structured query options
761
- */
762
- parse(query) {
763
- const q = query ?? {};
764
- const page = this.parseNumber(q.page, 1);
765
- const limit = Math.min(this.parseNumber(q.limit, this.defaultLimit), this.maxLimit);
766
- const after = this.parseString(q.after ?? q.cursor);
767
- const sort = this.parseSort(q.sort);
768
- const populate = this.parseString(q.populate);
769
- const search = this.parseSearch(q.search);
770
- const select = this.parseSelect(q.select);
771
- const filters = this.parseFilters(q);
772
- return {
773
- filters,
774
- limit,
775
- sort,
776
- populate,
777
- search,
778
- page: after ? void 0 : page,
779
- after,
780
- select
781
- };
782
- }
783
- // ============================================================================
784
- // Parse Helpers
785
- // ============================================================================
786
- parseNumber(value, defaultValue) {
787
- if (value === void 0 || value === null) return defaultValue;
788
- const num = parseInt(String(value), 10);
789
- return Number.isNaN(num) ? defaultValue : Math.max(1, num);
790
- }
791
- parseString(value) {
792
- if (value === void 0 || value === null) return void 0;
793
- const str = String(value).trim();
794
- return str.length > 0 ? str : void 0;
795
- }
796
- parseSort(value) {
797
- if (!value) return void 0;
798
- const sortStr = String(value);
799
- const result = {};
800
- for (const field of sortStr.split(",")) {
801
- const trimmed = field.trim();
802
- if (!trimmed) continue;
803
- if (!/^-?[a-zA-Z_][a-zA-Z0-9_.]*$/.test(trimmed)) continue;
804
- if (trimmed.startsWith("-")) {
805
- result[trimmed.slice(1)] = -1;
806
- } else {
807
- result[trimmed] = 1;
808
- }
809
- }
810
- return Object.keys(result).length > 0 ? result : void 0;
811
- }
812
- parseSearch(value) {
813
- if (!value) return void 0;
814
- const search = String(value).trim();
815
- if (search.length === 0) return void 0;
816
- if (search.length > this.maxSearchLength) {
817
- return search.slice(0, this.maxSearchLength);
818
- }
819
- return search;
820
- }
821
- parseSelect(value) {
822
- if (!value) return void 0;
823
- const selectStr = String(value);
824
- const result = {};
825
- for (const field of selectStr.split(",")) {
826
- const trimmed = field.trim();
827
- if (!trimmed) continue;
828
- if (!/^-?[a-zA-Z_][a-zA-Z0-9_.]*$/.test(trimmed)) continue;
829
- if (trimmed.startsWith("-")) {
830
- result[trimmed.slice(1)] = 0;
831
- } else {
832
- result[trimmed] = 1;
833
- }
834
- }
835
- return Object.keys(result).length > 0 ? result : void 0;
836
- }
837
- parseFilters(query) {
838
- const reservedKeys = /* @__PURE__ */ new Set([
839
- "page",
840
- "limit",
841
- "sort",
842
- "populate",
843
- "search",
844
- "select",
845
- "after",
846
- "cursor",
847
- "lean",
848
- "_policyFilters"
849
- ]);
850
- const filters = {};
851
- for (const [key, value] of Object.entries(query)) {
852
- if (reservedKeys.has(key)) continue;
853
- if (value === void 0 || value === null) continue;
854
- if (!/^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(key)) continue;
855
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
856
- const operatorObj = value;
857
- const operatorKeys = Object.keys(operatorObj);
858
- const allOperators = operatorKeys.every((op) => this.operators[op]);
859
- if (allOperators && operatorKeys.length > 0) {
860
- const mongoFilters = {};
861
- for (const [op, opValue] of Object.entries(operatorObj)) {
862
- const mongoOp = this.operators[op];
863
- if (mongoOp) {
864
- mongoFilters[mongoOp] = this.parseFilterValue(opValue, op);
865
- }
866
- }
867
- filters[key] = mongoFilters;
868
- continue;
869
- }
870
- }
871
- const match = key.match(/^([a-zA-Z_][a-zA-Z0-9_.]*)(?:\[([a-z]+)\])?$/);
872
- if (!match) continue;
873
- const [, fieldName, operator] = match;
874
- if (!fieldName) continue;
875
- if (operator && this.operators[operator]) {
876
- const mongoOp = this.operators[operator];
877
- const parsedValue = this.parseFilterValue(value, operator);
878
- if (!filters[fieldName]) {
879
- filters[fieldName] = {};
880
- }
881
- filters[fieldName][mongoOp] = parsedValue;
882
- } else if (!operator) {
883
- filters[fieldName] = this.parseFilterValue(value);
884
- }
885
- }
886
- return filters;
887
- }
888
- parseFilterValue(value, operator) {
889
- if (operator === "in" || operator === "nin") {
890
- if (Array.isArray(value)) {
891
- return value.map((v) => this.coerceValue(v));
892
- }
893
- if (typeof value === "string" && value.includes(",")) {
894
- return value.split(",").map((v) => this.coerceValue(v.trim()));
895
- }
896
- return [this.coerceValue(value)];
897
- }
898
- if (operator === "like" || operator === "contains" || operator === "regex") {
899
- return this.sanitizeRegex(String(value));
900
- }
901
- if (operator === "exists") {
902
- const str = String(value).toLowerCase();
903
- return str === "true" || str === "1";
904
- }
905
- return this.coerceValue(value);
906
- }
907
- coerceValue(value) {
908
- if (value === "true") return true;
909
- if (value === "false") return false;
910
- if (value === "null") return null;
911
- if (typeof value === "string") {
912
- const num = Number(value);
913
- if (!Number.isNaN(num) && value.trim() !== "") {
914
- return num;
915
- }
916
- }
917
- return value;
918
- }
919
- sanitizeRegex(pattern) {
920
- let sanitized = pattern.slice(0, this.maxRegexLength);
921
- if (DANGEROUS_REGEX_PATTERNS.test(sanitized)) {
922
- sanitized = sanitized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
923
- }
924
- return sanitized;
925
- }
926
- };
927
- function createQueryParser(options) {
928
- return new ArcQueryParser(options);
929
- }
930
-
931
- export { ArcError, ArcQueryParser, CircuitBreaker, CircuitBreakerError, CircuitBreakerRegistry, CircuitState, ConflictError, ForbiddenError, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, UnauthorizedError, ValidationError, circuitBreakerRegistry, createCircuitBreaker, createError, createQueryParser, createStateMachine, deleteResponse, errorResponseSchema, getListQueryParams, isArcError, itemResponse, itemWrapper, listResponse, messageWrapper, mutationResponse, paginateWrapper, paginationSchema, queryParams, responses, successResponseSchema, wrapResponse };