@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.
- package/README.md +247 -794
- package/bin/arc.js +91 -52
- package/dist/EventTransport-BkUDYZEb.d.mts +99 -0
- package/dist/HookSystem-BsGV-j2l.mjs +404 -0
- package/dist/ResourceRegistry-7Ic20ZMw.mjs +249 -0
- package/dist/adapters/index.d.mts +5 -0
- package/dist/adapters/index.mjs +3 -0
- package/dist/audit/index.d.mts +81 -0
- package/dist/audit/index.mjs +275 -0
- package/dist/audit/mongodb.d.mts +5 -0
- package/dist/audit/mongodb.mjs +3 -0
- package/dist/audited-CGdLiSlE.mjs +140 -0
- package/dist/auth/index.d.mts +188 -0
- package/dist/auth/index.mjs +1096 -0
- package/dist/auth/redis-session.d.mts +43 -0
- package/dist/auth/redis-session.mjs +75 -0
- package/dist/betterAuthOpenApi-DjWDddNc.mjs +249 -0
- package/dist/cache/index.d.mts +145 -0
- package/dist/cache/index.mjs +91 -0
- package/dist/caching-GSDJcA6-.mjs +93 -0
- package/dist/chunk-C7Uep-_p.mjs +20 -0
- package/dist/circuitBreaker-DYhWBW_D.mjs +1096 -0
- package/dist/cli/commands/describe.d.mts +18 -0
- package/dist/cli/commands/describe.mjs +238 -0
- package/dist/cli/commands/docs.d.mts +13 -0
- package/dist/cli/commands/docs.mjs +52 -0
- package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -2
- package/dist/cli/commands/generate.mjs +357 -0
- package/dist/cli/commands/{init.d.ts → init.d.mts} +11 -8
- package/dist/cli/commands/{init.js → init.mjs} +807 -617
- package/dist/cli/commands/introspect.d.mts +10 -0
- package/dist/cli/commands/introspect.mjs +75 -0
- package/dist/cli/index.d.mts +16 -0
- package/dist/cli/index.mjs +156 -0
- package/dist/constants-DdXFXQtN.mjs +84 -0
- package/dist/core/index.d.mts +5 -0
- package/dist/core/index.mjs +4 -0
- package/dist/createApp-D2D5XXaV.mjs +559 -0
- package/dist/defineResource-PXzSJ15_.mjs +2197 -0
- package/dist/discovery/index.d.mts +46 -0
- package/dist/discovery/index.mjs +109 -0
- package/dist/docs/index.d.mts +162 -0
- package/dist/docs/index.mjs +74 -0
- package/dist/elevation-DGo5shaX.d.mts +87 -0
- package/dist/elevation-DSTbVvYj.mjs +113 -0
- package/dist/errorHandler-C3GY3_ow.mjs +108 -0
- package/dist/errorHandler-CW3OOeYq.d.mts +72 -0
- package/dist/errors-DAWRdiYP.d.mts +124 -0
- package/dist/errors-DBANPbGr.mjs +211 -0
- package/dist/eventPlugin-BEOvaDqo.mjs +229 -0
- package/dist/eventPlugin-H6wDDjGO.d.mts +124 -0
- package/dist/events/index.d.mts +53 -0
- package/dist/events/index.mjs +51 -0
- package/dist/events/transports/redis-stream-entry.d.mts +2 -0
- package/dist/events/transports/redis-stream-entry.mjs +177 -0
- package/dist/events/transports/redis.d.mts +76 -0
- package/dist/events/transports/redis.mjs +124 -0
- package/dist/externalPaths-SyPF2tgK.d.mts +50 -0
- package/dist/factory/index.d.mts +63 -0
- package/dist/factory/index.mjs +3 -0
- package/dist/fastifyAdapter-C8DlE0YH.d.mts +216 -0
- package/dist/fields-Bi_AVKSo.d.mts +109 -0
- package/dist/fields-CTd_CrKr.mjs +114 -0
- package/dist/hooks/index.d.mts +4 -0
- package/dist/hooks/index.mjs +3 -0
- package/dist/idempotency/index.d.mts +96 -0
- package/dist/idempotency/index.mjs +319 -0
- package/dist/idempotency/mongodb.d.mts +2 -0
- package/dist/idempotency/mongodb.mjs +114 -0
- package/dist/idempotency/redis.d.mts +2 -0
- package/dist/idempotency/redis.mjs +103 -0
- package/dist/index.d.mts +260 -0
- package/dist/index.mjs +104 -0
- package/dist/integrations/event-gateway.d.mts +46 -0
- package/dist/integrations/event-gateway.mjs +43 -0
- package/dist/integrations/index.d.mts +5 -0
- package/dist/integrations/index.mjs +1 -0
- package/dist/integrations/jobs.d.mts +103 -0
- package/dist/integrations/jobs.mjs +123 -0
- package/dist/integrations/streamline.d.mts +60 -0
- package/dist/integrations/streamline.mjs +125 -0
- package/dist/integrations/websocket.d.mts +82 -0
- package/dist/integrations/websocket.mjs +288 -0
- package/dist/interface-CSNjltAc.d.mts +77 -0
- package/dist/interface-DTbsvIWe.d.mts +54 -0
- package/dist/interface-e9XfSsUV.d.mts +1097 -0
- package/dist/introspectionPlugin-B3JkrjwU.mjs +53 -0
- package/dist/keys-DhqDRxv3.mjs +42 -0
- package/dist/logger-ByrvQWZO.mjs +78 -0
- package/dist/memory-B2v7KrCB.mjs +143 -0
- package/dist/migrations/index.d.mts +156 -0
- package/dist/migrations/index.mjs +260 -0
- package/dist/mongodb-ClykrfGo.d.mts +118 -0
- package/dist/mongodb-DNKEExbf.mjs +93 -0
- package/dist/mongodb-Dg8O_gvd.d.mts +71 -0
- package/dist/openapi-9nB_kiuR.mjs +525 -0
- package/dist/org/index.d.mts +68 -0
- package/dist/org/index.mjs +513 -0
- package/dist/org/types.d.mts +82 -0
- package/dist/org/types.mjs +1 -0
- package/dist/permissions/index.d.mts +278 -0
- package/dist/permissions/index.mjs +579 -0
- package/dist/plugins/index.d.mts +172 -0
- package/dist/plugins/index.mjs +522 -0
- package/dist/plugins/response-cache.d.mts +87 -0
- package/dist/plugins/response-cache.mjs +283 -0
- package/dist/plugins/tracing-entry.d.mts +2 -0
- package/dist/plugins/tracing-entry.mjs +185 -0
- package/dist/pluralize-CM-jZg7p.mjs +86 -0
- package/dist/policies/{index.d.ts → index.d.mts} +204 -170
- package/dist/policies/index.mjs +321 -0
- package/dist/presets/{index.d.ts → index.d.mts} +62 -131
- package/dist/presets/index.mjs +143 -0
- package/dist/presets/multiTenant.d.mts +24 -0
- package/dist/presets/multiTenant.mjs +113 -0
- package/dist/presets-BTeYbw7h.d.mts +57 -0
- package/dist/presets-CeFtfDR8.mjs +119 -0
- package/dist/prisma-C3iornoK.d.mts +274 -0
- package/dist/prisma-DJbMt3yf.mjs +627 -0
- package/dist/queryCachePlugin-B6R0d4av.mjs +138 -0
- package/dist/queryCachePlugin-Q6SYuHZ6.d.mts +71 -0
- package/dist/redis-UwjEp8Ea.d.mts +49 -0
- package/dist/redis-stream-CBg0upHI.d.mts +103 -0
- package/dist/registry/index.d.mts +11 -0
- package/dist/registry/index.mjs +4 -0
- package/dist/requestContext-xi6OKBL-.mjs +55 -0
- package/dist/schemaConverter-Dtg0Kt9T.mjs +98 -0
- package/dist/schemas/index.d.mts +63 -0
- package/dist/schemas/index.mjs +82 -0
- package/dist/scope/index.d.mts +21 -0
- package/dist/scope/index.mjs +65 -0
- package/dist/sessionManager-D_iEHjQl.d.mts +186 -0
- package/dist/sse-DkqQ1uxb.mjs +123 -0
- package/dist/testing/index.d.mts +907 -0
- package/dist/testing/index.mjs +1976 -0
- package/dist/tracing-8CEbhF0w.d.mts +70 -0
- package/dist/typeGuards-DwxA1t_L.mjs +9 -0
- package/dist/types/index.d.mts +946 -0
- package/dist/types/index.mjs +14 -0
- package/dist/types-B0dhNrnd.d.mts +445 -0
- package/dist/types-Beqn1Un7.mjs +38 -0
- package/dist/types-DelU6kln.mjs +25 -0
- package/dist/types-RLkFVgaw.d.mts +101 -0
- package/dist/utils/index.d.mts +747 -0
- package/dist/utils/index.mjs +6 -0
- package/package.json +194 -68
- package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
- package/dist/adapters/index.d.ts +0 -237
- package/dist/adapters/index.js +0 -668
- package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
- package/dist/audit/index.d.ts +0 -195
- package/dist/audit/index.js +0 -319
- package/dist/auth/index.d.ts +0 -47
- package/dist/auth/index.js +0 -174
- package/dist/cli/commands/docs.d.ts +0 -11
- package/dist/cli/commands/docs.js +0 -474
- package/dist/cli/commands/generate.js +0 -334
- package/dist/cli/commands/introspect.d.ts +0 -8
- package/dist/cli/commands/introspect.js +0 -338
- package/dist/cli/index.d.ts +0 -4
- package/dist/cli/index.js +0 -3269
- package/dist/core/index.d.ts +0 -220
- package/dist/core/index.js +0 -2786
- package/dist/createApp-Ce9wl8W9.d.ts +0 -77
- package/dist/docs/index.d.ts +0 -166
- package/dist/docs/index.js +0 -658
- package/dist/errors-8WIxGS_6.d.ts +0 -122
- package/dist/events/index.d.ts +0 -117
- package/dist/events/index.js +0 -89
- package/dist/factory/index.d.ts +0 -38
- package/dist/factory/index.js +0 -1652
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/index.js +0 -199
- package/dist/idempotency/index.d.ts +0 -323
- package/dist/idempotency/index.js +0 -500
- package/dist/index-B4t03KQ0.d.ts +0 -1366
- package/dist/index.d.ts +0 -135
- package/dist/index.js +0 -4756
- package/dist/migrations/index.d.ts +0 -185
- package/dist/migrations/index.js +0 -274
- package/dist/org/index.d.ts +0 -129
- package/dist/org/index.js +0 -220
- package/dist/permissions/index.d.ts +0 -144
- package/dist/permissions/index.js +0 -103
- package/dist/plugins/index.d.ts +0 -46
- package/dist/plugins/index.js +0 -1069
- package/dist/policies/index.js +0 -196
- package/dist/presets/index.js +0 -384
- package/dist/presets/multiTenant.d.ts +0 -39
- package/dist/presets/multiTenant.js +0 -112
- package/dist/registry/index.d.ts +0 -16
- package/dist/registry/index.js +0 -253
- package/dist/testing/index.d.ts +0 -618
- package/dist/testing/index.js +0 -48020
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.js +0 -8
- package/dist/types-B99TBmFV.d.ts +0 -76
- package/dist/types-BvckRbs2.d.ts +0 -143
- package/dist/utils/index.d.ts +0 -679
- package/dist/utils/index.js +0 -931
package/dist/utils/index.js
DELETED
|
@@ -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 };
|