elysia 1.4.29 → 1.4.31
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/SECURITY.md +27 -0
- package/dist/adapter/bun/compose.js +9 -4
- package/dist/adapter/bun/compose.mjs +9 -4
- package/dist/adapter/bun/handler-native.js +22 -7
- package/dist/adapter/bun/handler-native.mjs +22 -7
- package/dist/adapter/bun/index.js +22 -13
- package/dist/adapter/bun/index.mjs +22 -13
- package/dist/adapter/utils.js +63 -18
- package/dist/adapter/utils.mjs +63 -18
- package/dist/adapter/web-standard/index.js +3 -55
- package/dist/adapter/web-standard/index.mjs +3 -55
- package/dist/compose.js +50 -90
- package/dist/compose.mjs +54 -90
- package/dist/dynamic-handle.js +135 -145
- package/dist/dynamic-handle.mjs +147 -146
- package/dist/error.d.ts +11 -19
- package/dist/error.js +296 -47
- package/dist/error.mjs +289 -47
- package/dist/form-data.d.ts +3 -0
- package/dist/form-data.js +124 -0
- package/dist/form-data.mjs +103 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +38 -35
- package/dist/index.mjs +40 -38
- package/dist/replace-schema.js +8 -3
- package/dist/replace-schema.mjs +8 -3
- package/dist/schema.d.ts +8 -3
- package/dist/schema.js +368 -7
- package/dist/schema.mjs +366 -7
- package/dist/types.d.ts +12 -1
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +62 -14
- package/dist/utils.mjs +60 -14
- package/dist/ws/index.d.ts +1 -1
- package/dist/ws/index.js +111 -55
- package/dist/ws/index.mjs +111 -55
- package/package.json +4 -4
package/dist/error.mjs
CHANGED
|
@@ -75,9 +75,10 @@ const mapValueError = (error) => {
|
|
|
75
75
|
summary: isRoot ? "Value should be an email" : `Property '${property}' should be ${format}`
|
|
76
76
|
};
|
|
77
77
|
case 54:
|
|
78
|
+
const found = formatValidationSummaryValue(value);
|
|
78
79
|
return {
|
|
79
80
|
...error,
|
|
80
|
-
summary: `${message.slice(0, 9).trim()} property '${property}' to be ${message.slice(8).trim()} but found: ${
|
|
81
|
+
summary: `${message.slice(0, 9).trim()} property '${property}' to be ${message.slice(8).trim()} but found: ${found}`
|
|
81
82
|
};
|
|
82
83
|
case 62:
|
|
83
84
|
const union = error.schema.anyOf.map((x) => `'${x?.format ?? x.type}'`).join(", ");
|
|
@@ -88,6 +89,220 @@ const mapValueError = (error) => {
|
|
|
88
89
|
default:
|
|
89
90
|
return { summary: message, ...error };
|
|
90
91
|
}
|
|
92
|
+
}, MAX_ERRORS = 64, MAX_VALIDATION_ERROR_DEPTH = 16, MAX_VALIDATION_ERROR_NODES = 8192, MAX_VALIDATION_ERROR_ENTRIES = 4096, MAX_VALIDATION_ERROR_CONTAINER_ENTRIES = 512, MAX_VALIDATION_ERROR_STRING_LENGTH = 4096, MAX_VALIDATION_ERROR_OUTPUT_LENGTH = 65536, VALIDATION_TRUNCATED = "[Truncated]", VALIDATION_UNSERIALIZABLE = "[Unserializable]", OMIT_VALIDATION_VALUE = Symbol("omitValidationValue"), boundValidationString = (value, state) => {
|
|
93
|
+
const remaining = state ? MAX_VALIDATION_ERROR_OUTPUT_LENGTH - state.strings : MAX_VALIDATION_ERROR_STRING_LENGTH, limit = Math.min(MAX_VALIDATION_ERROR_STRING_LENGTH, remaining);
|
|
94
|
+
return value.length <= limit ? (state && (state.strings += value.length), value) : (state && (state.strings += Math.max(limit, 0)), limit <= 0 ? "" : limit <= VALIDATION_TRUNCATED.length ? VALIDATION_TRUNCATED.slice(0, limit) : value.slice(0, limit - VALIDATION_TRUNCATED.length) + VALIDATION_TRUNCATED);
|
|
95
|
+
}, formatValidationSummaryValue = (value) => {
|
|
96
|
+
if (typeof value == "string") return boundValidationString(value);
|
|
97
|
+
if (value === null || typeof value == "number" || typeof value == "boolean" || typeof value == "bigint" || typeof value > "u")
|
|
98
|
+
return String(value);
|
|
99
|
+
try {
|
|
100
|
+
if (Array.isArray(value)) {
|
|
101
|
+
const length = Object.getOwnPropertyDescriptor(
|
|
102
|
+
value,
|
|
103
|
+
"length"
|
|
104
|
+
)?.value;
|
|
105
|
+
if (typeof length != "number" || length > MAX_VALIDATION_ERROR_CONTAINER_ENTRIES)
|
|
106
|
+
return "[object Object]";
|
|
107
|
+
const output = [];
|
|
108
|
+
let size = 0;
|
|
109
|
+
for (let index = 0; index < length; index++) {
|
|
110
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
111
|
+
value,
|
|
112
|
+
`${index}`
|
|
113
|
+
);
|
|
114
|
+
if (!descriptor || !("value" in descriptor)) {
|
|
115
|
+
output.push("");
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const item = descriptor.value;
|
|
119
|
+
if (item == null) output.push("");
|
|
120
|
+
else if (typeof item == "string" || typeof item == "number" || typeof item == "boolean" || typeof item == "bigint") {
|
|
121
|
+
const part = String(item);
|
|
122
|
+
if (size += part.length + 1, size > MAX_VALIDATION_ERROR_STRING_LENGTH)
|
|
123
|
+
return boundValidationString(output.join(","));
|
|
124
|
+
output.push(part);
|
|
125
|
+
} else return "[object Object]";
|
|
126
|
+
}
|
|
127
|
+
return boundValidationString(output.join(","));
|
|
128
|
+
}
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
return "[object Object]";
|
|
132
|
+
}, validationOutputFits = (value) => {
|
|
133
|
+
let bytes = 0;
|
|
134
|
+
for (let index = 0; index < value.length; index++) {
|
|
135
|
+
const code = value.charCodeAt(index);
|
|
136
|
+
if (code < 128 ? bytes++ : code < 2048 ? bytes += 2 : code >= 55296 && code <= 56319 && value.charCodeAt(index + 1) >= 56320 && value.charCodeAt(index + 1) <= 57343 ? (bytes += 4, index++) : bytes += 3, bytes > MAX_VALIDATION_ERROR_OUTPUT_LENGTH) return !1;
|
|
137
|
+
}
|
|
138
|
+
return !0;
|
|
139
|
+
}, projectValidationValue = (value, state, depth = 0) => {
|
|
140
|
+
if (state.nodes++ >= MAX_VALIDATION_ERROR_NODES) return VALIDATION_TRUNCATED;
|
|
141
|
+
switch (typeof value) {
|
|
142
|
+
case "string":
|
|
143
|
+
return boundValidationString(value, state);
|
|
144
|
+
case "number":
|
|
145
|
+
return Number.isFinite(value) ? value : null;
|
|
146
|
+
case "boolean":
|
|
147
|
+
return value;
|
|
148
|
+
case "bigint":
|
|
149
|
+
return "[BigInt]";
|
|
150
|
+
case "undefined":
|
|
151
|
+
case "function":
|
|
152
|
+
case "symbol":
|
|
153
|
+
return OMIT_VALIDATION_VALUE;
|
|
154
|
+
}
|
|
155
|
+
if (typeof value != "object" || value === null) return null;
|
|
156
|
+
if (depth >= MAX_VALIDATION_ERROR_DEPTH) return VALIDATION_TRUNCATED;
|
|
157
|
+
if (state.depth.has(value)) return "[Circular]";
|
|
158
|
+
try {
|
|
159
|
+
if (value instanceof Date) {
|
|
160
|
+
const timestamp = Date.prototype.getTime.call(value);
|
|
161
|
+
return Number.isFinite(timestamp) ? boundValidationString(
|
|
162
|
+
Date.prototype.toISOString.call(value),
|
|
163
|
+
state
|
|
164
|
+
) : null;
|
|
165
|
+
}
|
|
166
|
+
} catch {
|
|
167
|
+
}
|
|
168
|
+
state.depth.add(value);
|
|
169
|
+
try {
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
const output2 = [], lengthDescriptor = Object.getOwnPropertyDescriptor(
|
|
172
|
+
value,
|
|
173
|
+
"length"
|
|
174
|
+
), length = typeof lengthDescriptor?.value == "number" ? lengthDescriptor.value : 0;
|
|
175
|
+
let index = 0;
|
|
176
|
+
for (; index < length && index < MAX_VALIDATION_ERROR_CONTAINER_ENTRIES && state.entries < MAX_VALIDATION_ERROR_ENTRIES && state.nodes < MAX_VALIDATION_ERROR_NODES; index++) {
|
|
177
|
+
state.entries++;
|
|
178
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
179
|
+
value,
|
|
180
|
+
`${index}`
|
|
181
|
+
), projected = descriptor ? "value" in descriptor ? projectValidationValue(
|
|
182
|
+
descriptor.value,
|
|
183
|
+
state,
|
|
184
|
+
depth + 1
|
|
185
|
+
) : VALIDATION_UNSERIALIZABLE : OMIT_VALIDATION_VALUE;
|
|
186
|
+
output2.push(
|
|
187
|
+
projected === OMIT_VALIDATION_VALUE ? null : projected
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
return index < length && output2.push(VALIDATION_TRUNCATED), state.preservePrototype || Object.setPrototypeOf(output2, null), output2;
|
|
191
|
+
}
|
|
192
|
+
const output = state.preservePrototype ? {} : /* @__PURE__ */ Object.create(null);
|
|
193
|
+
let truncated = !1, entries = 0, inspected = 0;
|
|
194
|
+
for (const key in value) {
|
|
195
|
+
if (inspected++ >= MAX_VALIDATION_ERROR_CONTAINER_ENTRIES) {
|
|
196
|
+
truncated = !0;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
200
|
+
if (!descriptor?.enumerable) continue;
|
|
201
|
+
if (entries >= MAX_VALIDATION_ERROR_CONTAINER_ENTRIES || state.entries >= MAX_VALIDATION_ERROR_ENTRIES || state.nodes >= MAX_VALIDATION_ERROR_NODES) {
|
|
202
|
+
truncated = !0;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
entries++, state.entries++;
|
|
206
|
+
const projected = "value" in descriptor ? projectValidationValue(descriptor.value, state, depth + 1) : VALIDATION_UNSERIALIZABLE;
|
|
207
|
+
projected !== OMIT_VALIDATION_VALUE && Object.defineProperty(output, boundValidationString(key, state), {
|
|
208
|
+
value: projected,
|
|
209
|
+
enumerable: !0,
|
|
210
|
+
configurable: !0,
|
|
211
|
+
writable: !0
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return truncated && Object.defineProperty(output, VALIDATION_TRUNCATED, {
|
|
215
|
+
value: !0,
|
|
216
|
+
enumerable: !0
|
|
217
|
+
}), output;
|
|
218
|
+
} catch {
|
|
219
|
+
return VALIDATION_UNSERIALIZABLE;
|
|
220
|
+
} finally {
|
|
221
|
+
state.depth.delete(value);
|
|
222
|
+
}
|
|
223
|
+
}, validationSerializationFallback = () => {
|
|
224
|
+
const fallback = /* @__PURE__ */ Object.create(null);
|
|
225
|
+
return fallback.type = "validation", fallback.message = "Validation details exceeded serialization limit", fallback;
|
|
226
|
+
}, projectValidationDetails = (value, preservePrototype = !1) => {
|
|
227
|
+
const projected = projectValidationValue(value, {
|
|
228
|
+
depth: /* @__PURE__ */ new WeakSet(),
|
|
229
|
+
nodes: 0,
|
|
230
|
+
entries: 0,
|
|
231
|
+
strings: 0,
|
|
232
|
+
preservePrototype
|
|
233
|
+
}), result = projected === OMIT_VALIDATION_VALUE ? null : projected;
|
|
234
|
+
try {
|
|
235
|
+
const serialized = JSON.stringify(result);
|
|
236
|
+
if (typeof serialized == "string" && validationOutputFits(serialized))
|
|
237
|
+
return result;
|
|
238
|
+
} catch {
|
|
239
|
+
}
|
|
240
|
+
return validationSerializationFallback();
|
|
241
|
+
}, stringifyValidationDetails = (value, space) => {
|
|
242
|
+
const projected = projectValidationDetails(value);
|
|
243
|
+
try {
|
|
244
|
+
const serialized = JSON.stringify(projected, null, space);
|
|
245
|
+
if (validationOutputFits(serialized)) return serialized;
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
return JSON.stringify(validationSerializationFallback(), null, space);
|
|
249
|
+
}, stringifyCustomValidationError = (value) => {
|
|
250
|
+
if (value !== null && typeof value == "object")
|
|
251
|
+
return stringifyValidationDetails(value);
|
|
252
|
+
try {
|
|
253
|
+
return boundValidationString(String(value));
|
|
254
|
+
} catch {
|
|
255
|
+
return VALIDATION_UNSERIALIZABLE;
|
|
256
|
+
}
|
|
257
|
+
}, tryMapValueError = (error) => {
|
|
258
|
+
try {
|
|
259
|
+
return mapValueError(error);
|
|
260
|
+
} catch {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
}, readValidationDataProperty = (value, key) => {
|
|
264
|
+
if (!(value === null || typeof value != "object"))
|
|
265
|
+
try {
|
|
266
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
267
|
+
if (descriptor && "value" in descriptor) return descriptor.value;
|
|
268
|
+
} catch {
|
|
269
|
+
}
|
|
270
|
+
}, formatStandardValidationPath = (value) => {
|
|
271
|
+
try {
|
|
272
|
+
if (!Array.isArray(value)) return "root";
|
|
273
|
+
const length = Object.getOwnPropertyDescriptor(value, "length")?.value;
|
|
274
|
+
if (typeof length != "number") return "root";
|
|
275
|
+
const output = [];
|
|
276
|
+
let size = 0;
|
|
277
|
+
const limit = Math.min(length, MAX_VALIDATION_ERROR_CONTAINER_ENTRIES);
|
|
278
|
+
for (let index = 0; index < limit; index++) {
|
|
279
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
280
|
+
value,
|
|
281
|
+
`${index}`
|
|
282
|
+
);
|
|
283
|
+
if (!descriptor || !("value" in descriptor)) continue;
|
|
284
|
+
const part = descriptor.value;
|
|
285
|
+
if (typeof part == "string" || typeof part == "number" || typeof part == "boolean" || typeof part == "bigint") {
|
|
286
|
+
const formatted = boundValidationString(String(part));
|
|
287
|
+
if (size += formatted.length + 1, size > MAX_VALIDATION_ERROR_STRING_LENGTH) {
|
|
288
|
+
output.push(VALIDATION_TRUNCATED);
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
output.push(formatted);
|
|
292
|
+
} else output.push(VALIDATION_UNSERIALIZABLE);
|
|
293
|
+
}
|
|
294
|
+
return limit < length && output.push(VALIDATION_TRUNCATED), boundValidationString(output.join(".")) || "root";
|
|
295
|
+
} catch {
|
|
296
|
+
return "root";
|
|
297
|
+
}
|
|
298
|
+
}, takeErrors = (iterator, limit = MAX_ERRORS) => {
|
|
299
|
+
const errors = [];
|
|
300
|
+
for (const error of iterator) {
|
|
301
|
+
if (!error) continue;
|
|
302
|
+
const mapped = tryMapValueError(error);
|
|
303
|
+
if (mapped && errors.push(mapped), errors.length >= limit) break;
|
|
304
|
+
}
|
|
305
|
+
return errors;
|
|
91
306
|
};
|
|
92
307
|
class InvalidFileType extends Error {
|
|
93
308
|
constructor(property, expected, message = `"${property}" has invalid file type`) {
|
|
@@ -142,27 +357,39 @@ class ValidationError extends Error {
|
|
|
142
357
|
const standard = (
|
|
143
358
|
// @ts-ignore
|
|
144
359
|
("~standard" in validator ? validator : validator.schema)["~standard"]
|
|
360
|
+
), _errors = errors ?? standard.validate(value).issues;
|
|
361
|
+
error = readValidationDataProperty(_errors, 0);
|
|
362
|
+
const standardErrorPath = readValidationDataProperty(error, "path"), standardErrorMessage = readValidationDataProperty(
|
|
363
|
+
error,
|
|
364
|
+
"message"
|
|
365
|
+
), standardErrorProblem = readValidationDataProperty(
|
|
366
|
+
error,
|
|
367
|
+
"problem"
|
|
145
368
|
);
|
|
146
|
-
|
|
369
|
+
isProduction && !allowUnsafeValidationDetails ? message = stringifyValidationDetails({
|
|
147
370
|
type: "validation",
|
|
148
371
|
on: type,
|
|
149
372
|
found: value
|
|
150
|
-
}) : message =
|
|
373
|
+
}) : message = stringifyValidationDetails(
|
|
151
374
|
{
|
|
152
375
|
type: "validation",
|
|
153
376
|
on: type,
|
|
154
|
-
property:
|
|
155
|
-
message:
|
|
156
|
-
summary:
|
|
377
|
+
property: readValidationDataProperty(standardErrorPath, 0) || "root",
|
|
378
|
+
message: standardErrorMessage,
|
|
379
|
+
summary: standardErrorProblem,
|
|
157
380
|
expected,
|
|
158
381
|
found: value,
|
|
159
382
|
errors
|
|
160
383
|
},
|
|
161
|
-
null,
|
|
162
384
|
2
|
|
163
|
-
), customError =
|
|
385
|
+
), customError = standardErrorMessage;
|
|
164
386
|
} else {
|
|
165
|
-
value && typeof value == "object"
|
|
387
|
+
if (value && typeof value == "object")
|
|
388
|
+
try {
|
|
389
|
+
value instanceof ElysiaCustomStatusResponse && (value = value.response);
|
|
390
|
+
} catch {
|
|
391
|
+
}
|
|
392
|
+
error = errors?.First() ?? ("Errors" in validator ? validator.Errors(value).First() : Value.Errors(validator, value).First());
|
|
166
393
|
const accessor = error?.path || "root", schema = validator?.schema ?? validator;
|
|
167
394
|
if (!isProduction && !allowUnsafeValidationDetails)
|
|
168
395
|
try {
|
|
@@ -186,41 +413,36 @@ class ValidationError extends Error {
|
|
|
186
413
|
value,
|
|
187
414
|
property: accessor,
|
|
188
415
|
message: error?.message,
|
|
189
|
-
summary:
|
|
416
|
+
summary: tryMapValueError(error)?.summary,
|
|
190
417
|
found: value,
|
|
191
418
|
expected,
|
|
192
|
-
errors: "Errors" in validator ?
|
|
193
|
-
|
|
419
|
+
errors: "Errors" in validator ? takeErrors(
|
|
420
|
+
validator.Errors(
|
|
194
421
|
value
|
|
195
422
|
)
|
|
196
|
-
|
|
197
|
-
|
|
423
|
+
) : takeErrors(
|
|
424
|
+
Value.Errors(
|
|
198
425
|
validator,
|
|
199
426
|
value
|
|
200
427
|
)
|
|
201
|
-
|
|
428
|
+
)
|
|
202
429
|
},
|
|
203
430
|
validator
|
|
204
|
-
) : error.schema.error : void 0, customError !== void 0 ? message =
|
|
431
|
+
) : error.schema.error : void 0, customError !== void 0 ? message = stringifyCustomValidationError(customError) : isProduction && !allowUnsafeValidationDetails ? message = stringifyValidationDetails({
|
|
205
432
|
type: "validation",
|
|
206
433
|
on: type,
|
|
207
434
|
found: value
|
|
208
|
-
}) : message =
|
|
435
|
+
}) : message = stringifyValidationDetails(
|
|
209
436
|
{
|
|
210
437
|
type: "validation",
|
|
211
438
|
on: type,
|
|
212
439
|
property: accessor,
|
|
213
440
|
message: error?.message,
|
|
214
|
-
summary:
|
|
441
|
+
summary: tryMapValueError(error)?.summary,
|
|
215
442
|
expected,
|
|
216
443
|
found: value,
|
|
217
|
-
errors: "Errors" in validator ?
|
|
218
|
-
mapValueError
|
|
219
|
-
) : [...Value.Errors(validator, value)].map(
|
|
220
|
-
mapValueError
|
|
221
|
-
)
|
|
444
|
+
errors: "Errors" in validator ? takeErrors(validator.Errors(value)) : takeErrors(Value.Errors(validator, value))
|
|
222
445
|
},
|
|
223
|
-
null,
|
|
224
446
|
2
|
|
225
447
|
);
|
|
226
448
|
}
|
|
@@ -248,14 +470,19 @@ class ValidationError extends Error {
|
|
|
248
470
|
"~standard" in this.validator.schema ? /* @ts-ignore */ ("~standard" in this.validator ? this.validator : (
|
|
249
471
|
// @ts-ignore
|
|
250
472
|
this.validator.schema
|
|
251
|
-
))["~standard"].validate(this.value).issues?.map((issue) =>
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
473
|
+
))["~standard"].validate(this.value).issues?.slice(0, MAX_ERRORS).map((issue) => {
|
|
474
|
+
const message = readValidationDataProperty(issue, "message");
|
|
475
|
+
return {
|
|
476
|
+
summary: message,
|
|
477
|
+
path: formatStandardValidationPath(
|
|
478
|
+
readValidationDataProperty(issue, "path")
|
|
479
|
+
),
|
|
480
|
+
message,
|
|
481
|
+
value: this.value
|
|
482
|
+
};
|
|
483
|
+
}) || [] : "Errors" in this.validator ? takeErrors(this.validator.Errors(this.value)) : (
|
|
257
484
|
// @ts-ignore
|
|
258
|
-
|
|
485
|
+
takeErrors(Value.Errors(this.validator, this.value))
|
|
259
486
|
)
|
|
260
487
|
);
|
|
261
488
|
}
|
|
@@ -301,22 +528,30 @@ class ValidationError extends Error {
|
|
|
301
528
|
*/
|
|
302
529
|
detail(message, allowUnsafeValidatorDetails = this.allowUnsafeValidationDetails) {
|
|
303
530
|
if (!this.customError) return this.message;
|
|
304
|
-
const value = this.value, expected = this.expected
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
531
|
+
const value = this.value, expected = this.expected;
|
|
532
|
+
let errors = [], property = "root", summary;
|
|
533
|
+
try {
|
|
534
|
+
errors = this.all, property = this.valueError?.path || "root", summary = tryMapValueError(this.valueError)?.summary;
|
|
535
|
+
} catch {
|
|
536
|
+
}
|
|
537
|
+
return projectValidationDetails(
|
|
538
|
+
isProduction && !allowUnsafeValidatorDetails ? {
|
|
539
|
+
type: "validation",
|
|
540
|
+
on: this.type,
|
|
541
|
+
found: value,
|
|
542
|
+
message
|
|
543
|
+
} : {
|
|
544
|
+
type: "validation",
|
|
545
|
+
on: this.type,
|
|
546
|
+
property,
|
|
547
|
+
message,
|
|
548
|
+
summary,
|
|
549
|
+
found: value,
|
|
550
|
+
expected,
|
|
551
|
+
errors
|
|
552
|
+
},
|
|
553
|
+
!0
|
|
554
|
+
);
|
|
320
555
|
}
|
|
321
556
|
}
|
|
322
557
|
export {
|
|
@@ -326,6 +561,13 @@ export {
|
|
|
326
561
|
InternalServerError,
|
|
327
562
|
InvalidCookieSignature,
|
|
328
563
|
InvalidFileType,
|
|
564
|
+
MAX_ERRORS,
|
|
565
|
+
MAX_VALIDATION_ERROR_CONTAINER_ENTRIES,
|
|
566
|
+
MAX_VALIDATION_ERROR_DEPTH,
|
|
567
|
+
MAX_VALIDATION_ERROR_ENTRIES,
|
|
568
|
+
MAX_VALIDATION_ERROR_NODES,
|
|
569
|
+
MAX_VALIDATION_ERROR_OUTPUT_LENGTH,
|
|
570
|
+
MAX_VALIDATION_ERROR_STRING_LENGTH,
|
|
329
571
|
NotFoundError,
|
|
330
572
|
ParseError,
|
|
331
573
|
ValidationError,
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: !0 });
|
|
9
|
+
}, __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from == "object" || typeof from == "function")
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
!__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
|
|
16
|
+
var form_data_exports = {};
|
|
17
|
+
__export(form_data_exports, {
|
|
18
|
+
parseFormData: () => parseFormData
|
|
19
|
+
});
|
|
20
|
+
module.exports = __toCommonJS(form_data_exports);
|
|
21
|
+
const ARRAY_INDEX_REGEX = /^(.+)\[(\d+)\]$/, DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]), MAX_PATH_DEPTH = 32, MAX_ARRAY_INDEX = 1e4, MAX_ASSIGNMENTS = 2e4, spend = (budget, cost = 1) => budget.remaining < cost ? !1 : (budget.remaining -= cost, !0), growArray = (array, index, budget) => index < array.length || spend(budget, index - array.length + 1), isDangerousKey = (key) => {
|
|
22
|
+
if (DANGEROUS_KEYS.has(key)) return !0;
|
|
23
|
+
const match = key.match(ARRAY_INDEX_REGEX);
|
|
24
|
+
return match ? DANGEROUS_KEYS.has(match[1]) : !1;
|
|
25
|
+
}, parseArrayKey = (key) => {
|
|
26
|
+
const match = key.match(ARRAY_INDEX_REGEX);
|
|
27
|
+
if (!match) return;
|
|
28
|
+
const index = Number(match[2]);
|
|
29
|
+
return !Number.isSafeInteger(index) || index > MAX_ARRAY_INDEX ? null : {
|
|
30
|
+
name: match[1],
|
|
31
|
+
index
|
|
32
|
+
};
|
|
33
|
+
}, parseObjectString = (entry) => {
|
|
34
|
+
if (!(typeof entry != "string" || entry.charCodeAt(0) !== 123))
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(entry);
|
|
37
|
+
if (parsed && typeof parsed == "object" && !Array.isArray(parsed))
|
|
38
|
+
return parsed;
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}, normalizeFormValue = (value) => {
|
|
42
|
+
if (value.length === 1) {
|
|
43
|
+
const stringValue2 = value[0];
|
|
44
|
+
if (typeof stringValue2 == "string" && (stringValue2.charCodeAt(0) === 123 || stringValue2.charCodeAt(0) === 91))
|
|
45
|
+
try {
|
|
46
|
+
const parsed2 = JSON.parse(stringValue2);
|
|
47
|
+
if (parsed2 && typeof parsed2 == "object") return parsed2;
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
return value[0];
|
|
51
|
+
}
|
|
52
|
+
const stringValue = value.find(
|
|
53
|
+
(entry) => typeof entry == "string"
|
|
54
|
+
);
|
|
55
|
+
if (!stringValue || typeof File > "u") return value;
|
|
56
|
+
const files = value.filter((entry) => entry instanceof File);
|
|
57
|
+
if (!files.length || stringValue.charCodeAt(0) !== 123) return value;
|
|
58
|
+
const parsed = parseObjectString(stringValue);
|
|
59
|
+
return parsed ? (!("file" in parsed) && files.length === 1 ? parsed.file = files[0] : !("files" in parsed) && files.length > 1 && (parsed.files = files), parsed) : value;
|
|
60
|
+
}, setNestedValue = (obj, path, value, budget) => {
|
|
61
|
+
const keys = path.split(".");
|
|
62
|
+
if (keys.length > MAX_PATH_DEPTH) return;
|
|
63
|
+
const lastKey = keys.pop();
|
|
64
|
+
if (isDangerousKey(lastKey) || keys.some(isDangerousKey)) return;
|
|
65
|
+
let current = obj;
|
|
66
|
+
for (const key of keys) {
|
|
67
|
+
const arrayInfo2 = parseArrayKey(key);
|
|
68
|
+
if (arrayInfo2 === null) return;
|
|
69
|
+
if (arrayInfo2) {
|
|
70
|
+
if (!Array.isArray(current[arrayInfo2.name])) {
|
|
71
|
+
if (!spend(budget)) return;
|
|
72
|
+
current[arrayInfo2.name] = [];
|
|
73
|
+
}
|
|
74
|
+
const array = current[arrayInfo2.name];
|
|
75
|
+
if (!growArray(array, arrayInfo2.index, budget)) return;
|
|
76
|
+
const existing = array[arrayInfo2.index], isFile = typeof File < "u" && existing instanceof File;
|
|
77
|
+
if (!existing || typeof existing != "object" || Array.isArray(existing) || isFile) {
|
|
78
|
+
if (!spend(budget)) return;
|
|
79
|
+
array[arrayInfo2.index] = parseObjectString(existing) ?? {};
|
|
80
|
+
}
|
|
81
|
+
current = array[arrayInfo2.index];
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (!current[key] || typeof current[key] != "object") {
|
|
85
|
+
if (!spend(budget)) return;
|
|
86
|
+
current[key] = {};
|
|
87
|
+
}
|
|
88
|
+
current = current[key];
|
|
89
|
+
}
|
|
90
|
+
const arrayInfo = parseArrayKey(lastKey);
|
|
91
|
+
if (arrayInfo !== null) {
|
|
92
|
+
if (arrayInfo) {
|
|
93
|
+
if (!Array.isArray(current[arrayInfo.name])) {
|
|
94
|
+
if (!spend(budget)) return;
|
|
95
|
+
current[arrayInfo.name] = [];
|
|
96
|
+
}
|
|
97
|
+
const array = current[arrayInfo.name];
|
|
98
|
+
if (!growArray(array, arrayInfo.index, budget) || !spend(budget)) return;
|
|
99
|
+
array[arrayInfo.index] = value;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
spend(budget) && (current[lastKey] = value);
|
|
103
|
+
}
|
|
104
|
+
}, parseFormData = (form) => {
|
|
105
|
+
const body = {};
|
|
106
|
+
if (!form) return body;
|
|
107
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
108
|
+
form.forEach((value, key) => {
|
|
109
|
+
const entries = grouped.get(key);
|
|
110
|
+
entries ? entries.push(value) : grouped.set(key, [value]);
|
|
111
|
+
});
|
|
112
|
+
const budget = { remaining: MAX_ASSIGNMENTS };
|
|
113
|
+
for (const [key, value] of grouped) {
|
|
114
|
+
if (isDangerousKey(key) || Object.prototype.hasOwnProperty.call(body, key))
|
|
115
|
+
continue;
|
|
116
|
+
const finalValue = normalizeFormValue(value);
|
|
117
|
+
key.includes(".") || key.includes("[") ? setNestedValue(body, key, finalValue, budget) : spend(budget) && (body[key] = finalValue);
|
|
118
|
+
}
|
|
119
|
+
return body;
|
|
120
|
+
};
|
|
121
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
122
|
+
0 && (module.exports = {
|
|
123
|
+
parseFormData
|
|
124
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const ARRAY_INDEX_REGEX = /^(.+)\[(\d+)\]$/, DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]), MAX_PATH_DEPTH = 32, MAX_ARRAY_INDEX = 1e4, MAX_ASSIGNMENTS = 2e4, spend = (budget, cost = 1) => budget.remaining < cost ? !1 : (budget.remaining -= cost, !0), growArray = (array, index, budget) => index < array.length || spend(budget, index - array.length + 1), isDangerousKey = (key) => {
|
|
2
|
+
if (DANGEROUS_KEYS.has(key)) return !0;
|
|
3
|
+
const match = key.match(ARRAY_INDEX_REGEX);
|
|
4
|
+
return match ? DANGEROUS_KEYS.has(match[1]) : !1;
|
|
5
|
+
}, parseArrayKey = (key) => {
|
|
6
|
+
const match = key.match(ARRAY_INDEX_REGEX);
|
|
7
|
+
if (!match) return;
|
|
8
|
+
const index = Number(match[2]);
|
|
9
|
+
return !Number.isSafeInteger(index) || index > MAX_ARRAY_INDEX ? null : {
|
|
10
|
+
name: match[1],
|
|
11
|
+
index
|
|
12
|
+
};
|
|
13
|
+
}, parseObjectString = (entry) => {
|
|
14
|
+
if (!(typeof entry != "string" || entry.charCodeAt(0) !== 123))
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(entry);
|
|
17
|
+
if (parsed && typeof parsed == "object" && !Array.isArray(parsed))
|
|
18
|
+
return parsed;
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
}, normalizeFormValue = (value) => {
|
|
22
|
+
if (value.length === 1) {
|
|
23
|
+
const stringValue2 = value[0];
|
|
24
|
+
if (typeof stringValue2 == "string" && (stringValue2.charCodeAt(0) === 123 || stringValue2.charCodeAt(0) === 91))
|
|
25
|
+
try {
|
|
26
|
+
const parsed2 = JSON.parse(stringValue2);
|
|
27
|
+
if (parsed2 && typeof parsed2 == "object") return parsed2;
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
return value[0];
|
|
31
|
+
}
|
|
32
|
+
const stringValue = value.find(
|
|
33
|
+
(entry) => typeof entry == "string"
|
|
34
|
+
);
|
|
35
|
+
if (!stringValue || typeof File > "u") return value;
|
|
36
|
+
const files = value.filter((entry) => entry instanceof File);
|
|
37
|
+
if (!files.length || stringValue.charCodeAt(0) !== 123) return value;
|
|
38
|
+
const parsed = parseObjectString(stringValue);
|
|
39
|
+
return parsed ? (!("file" in parsed) && files.length === 1 ? parsed.file = files[0] : !("files" in parsed) && files.length > 1 && (parsed.files = files), parsed) : value;
|
|
40
|
+
}, setNestedValue = (obj, path, value, budget) => {
|
|
41
|
+
const keys = path.split(".");
|
|
42
|
+
if (keys.length > MAX_PATH_DEPTH) return;
|
|
43
|
+
const lastKey = keys.pop();
|
|
44
|
+
if (isDangerousKey(lastKey) || keys.some(isDangerousKey)) return;
|
|
45
|
+
let current = obj;
|
|
46
|
+
for (const key of keys) {
|
|
47
|
+
const arrayInfo2 = parseArrayKey(key);
|
|
48
|
+
if (arrayInfo2 === null) return;
|
|
49
|
+
if (arrayInfo2) {
|
|
50
|
+
if (!Array.isArray(current[arrayInfo2.name])) {
|
|
51
|
+
if (!spend(budget)) return;
|
|
52
|
+
current[arrayInfo2.name] = [];
|
|
53
|
+
}
|
|
54
|
+
const array = current[arrayInfo2.name];
|
|
55
|
+
if (!growArray(array, arrayInfo2.index, budget)) return;
|
|
56
|
+
const existing = array[arrayInfo2.index], isFile = typeof File < "u" && existing instanceof File;
|
|
57
|
+
if (!existing || typeof existing != "object" || Array.isArray(existing) || isFile) {
|
|
58
|
+
if (!spend(budget)) return;
|
|
59
|
+
array[arrayInfo2.index] = parseObjectString(existing) ?? {};
|
|
60
|
+
}
|
|
61
|
+
current = array[arrayInfo2.index];
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!current[key] || typeof current[key] != "object") {
|
|
65
|
+
if (!spend(budget)) return;
|
|
66
|
+
current[key] = {};
|
|
67
|
+
}
|
|
68
|
+
current = current[key];
|
|
69
|
+
}
|
|
70
|
+
const arrayInfo = parseArrayKey(lastKey);
|
|
71
|
+
if (arrayInfo !== null) {
|
|
72
|
+
if (arrayInfo) {
|
|
73
|
+
if (!Array.isArray(current[arrayInfo.name])) {
|
|
74
|
+
if (!spend(budget)) return;
|
|
75
|
+
current[arrayInfo.name] = [];
|
|
76
|
+
}
|
|
77
|
+
const array = current[arrayInfo.name];
|
|
78
|
+
if (!growArray(array, arrayInfo.index, budget) || !spend(budget)) return;
|
|
79
|
+
array[arrayInfo.index] = value;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
spend(budget) && (current[lastKey] = value);
|
|
83
|
+
}
|
|
84
|
+
}, parseFormData = (form) => {
|
|
85
|
+
const body = {};
|
|
86
|
+
if (!form) return body;
|
|
87
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
88
|
+
form.forEach((value, key) => {
|
|
89
|
+
const entries = grouped.get(key);
|
|
90
|
+
entries ? entries.push(value) : grouped.set(key, [value]);
|
|
91
|
+
});
|
|
92
|
+
const budget = { remaining: MAX_ASSIGNMENTS };
|
|
93
|
+
for (const [key, value] of grouped) {
|
|
94
|
+
if (isDangerousKey(key) || Object.prototype.hasOwnProperty.call(body, key))
|
|
95
|
+
continue;
|
|
96
|
+
const finalValue = normalizeFormValue(value);
|
|
97
|
+
key.includes(".") || key.includes("[") ? setNestedValue(body, key, finalValue, budget) : spend(budget) && (body[key] = finalValue);
|
|
98
|
+
}
|
|
99
|
+
return body;
|
|
100
|
+
};
|
|
101
|
+
export {
|
|
102
|
+
parseFormData
|
|
103
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ export default class Elysia<const in out BasePath extends string = '', const in
|
|
|
61
61
|
'~Ephemeral': Ephemeral;
|
|
62
62
|
'~Volatile': Volatile;
|
|
63
63
|
'~Routes': Routes;
|
|
64
|
+
'~cookieConfig': ElysiaConfig<any>['cookie'] | undefined;
|
|
64
65
|
protected singleton: SingletonBase;
|
|
65
66
|
get store(): Singleton['store'];
|
|
66
67
|
get decorator(): Singleton['decorator'];
|
|
@@ -1736,6 +1737,7 @@ export default class Elysia<const in out BasePath extends string = '', const in
|
|
|
1736
1737
|
config?: {
|
|
1737
1738
|
allowMeta?: boolean;
|
|
1738
1739
|
mount?: Function;
|
|
1740
|
+
cookie?: ElysiaConfig<any>['cookie'];
|
|
1739
1741
|
};
|
|
1740
1742
|
}): Elysia<BasePath, Singleton, Definitions, Metadata, Routes & CreateEden<JoinPath<BasePath, Path>, {
|
|
1741
1743
|
[method in Method]: CreateEdenResponse<Path, Schema, MacroContext, ComposeElysiaResponse<Schema & MacroContext & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Handle, UnionResponseStatus<Metadata['response'], UnionResponseStatus<Ephemeral['response'], UnionResponseStatus<Volatile['response'], MacroContext['return'] & {}>>>>>;
|