elysia 1.4.30 → 1.4.32

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/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: ${value}`
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,11 +89,217 @@ const mapValueError = (error) => {
88
89
  default:
89
90
  return { summary: message, ...error };
90
91
  }
91
- }, MAX_ERRORS = 64, takeErrors = (iterator, limit = MAX_ERRORS) => {
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) => {
92
299
  const errors = [];
93
300
  for (const error of iterator) {
94
301
  if (!error) continue;
95
- const mapped = mapValueError(error);
302
+ const mapped = tryMapValueError(error);
96
303
  if (mapped && errors.push(mapped), errors.length >= limit) break;
97
304
  }
98
305
  return errors;
@@ -150,27 +357,39 @@ class ValidationError extends Error {
150
357
  const standard = (
151
358
  // @ts-ignore
152
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"
153
368
  );
154
- error = (errors ?? standard.validate(value).issues)?.[0], isProduction && !allowUnsafeValidationDetails ? message = JSON.stringify({
369
+ isProduction && !allowUnsafeValidationDetails ? message = stringifyValidationDetails({
155
370
  type: "validation",
156
371
  on: type,
157
372
  found: value
158
- }) : message = JSON.stringify(
373
+ }) : message = stringifyValidationDetails(
159
374
  {
160
375
  type: "validation",
161
376
  on: type,
162
- property: error.path?.[0] || "root",
163
- message: error?.message,
164
- summary: error?.problem,
377
+ property: readValidationDataProperty(standardErrorPath, 0) || "root",
378
+ message: standardErrorMessage,
379
+ summary: standardErrorProblem,
165
380
  expected,
166
381
  found: value,
167
382
  errors
168
383
  },
169
- null,
170
384
  2
171
- ), customError = error?.message;
385
+ ), customError = standardErrorMessage;
172
386
  } else {
173
- value && typeof value == "object" && value instanceof ElysiaCustomStatusResponse && (value = value.response), error = errors?.First() ?? ("Errors" in validator ? validator.Errors(value).First() : Value.Errors(validator, value).First());
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());
174
393
  const accessor = error?.path || "root", schema = validator?.schema ?? validator;
175
394
  if (!isProduction && !allowUnsafeValidationDetails)
176
395
  try {
@@ -194,7 +413,7 @@ class ValidationError extends Error {
194
413
  value,
195
414
  property: accessor,
196
415
  message: error?.message,
197
- summary: mapValueError(error)?.summary,
416
+ summary: tryMapValueError(error)?.summary,
198
417
  found: value,
199
418
  expected,
200
419
  errors: "Errors" in validator ? takeErrors(
@@ -209,22 +428,21 @@ class ValidationError extends Error {
209
428
  )
210
429
  },
211
430
  validator
212
- ) : error.schema.error : void 0, customError !== void 0 ? message = typeof customError == "object" ? JSON.stringify(customError) : customError + "" : isProduction && !allowUnsafeValidationDetails ? message = JSON.stringify({
431
+ ) : error.schema.error : void 0, customError !== void 0 ? message = stringifyCustomValidationError(customError) : isProduction && !allowUnsafeValidationDetails ? message = stringifyValidationDetails({
213
432
  type: "validation",
214
433
  on: type,
215
434
  found: value
216
- }) : message = JSON.stringify(
435
+ }) : message = stringifyValidationDetails(
217
436
  {
218
437
  type: "validation",
219
438
  on: type,
220
439
  property: accessor,
221
440
  message: error?.message,
222
- summary: mapValueError(error)?.summary,
441
+ summary: tryMapValueError(error)?.summary,
223
442
  expected,
224
443
  found: value,
225
444
  errors: "Errors" in validator ? takeErrors(validator.Errors(value)) : takeErrors(Value.Errors(validator, value))
226
445
  },
227
- null,
228
446
  2
229
447
  );
230
448
  }
@@ -252,12 +470,17 @@ class ValidationError extends Error {
252
470
  "~standard" in this.validator.schema ? /* @ts-ignore */ ("~standard" in this.validator ? this.validator : (
253
471
  // @ts-ignore
254
472
  this.validator.schema
255
- ))["~standard"].validate(this.value).issues?.slice(0, MAX_ERRORS).map((issue) => ({
256
- summary: issue.message,
257
- path: issue.path?.join(".") || "root",
258
- message: issue.message,
259
- value: this.value
260
- })) || [] : "Errors" in this.validator ? takeErrors(this.validator.Errors(this.value)) : (
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)) : (
261
484
  // @ts-ignore
262
485
  takeErrors(Value.Errors(this.validator, this.value))
263
486
  )
@@ -305,22 +528,30 @@ class ValidationError extends Error {
305
528
  */
306
529
  detail(message, allowUnsafeValidatorDetails = this.allowUnsafeValidationDetails) {
307
530
  if (!this.customError) return this.message;
308
- const value = this.value, expected = this.expected, errors = this.all;
309
- return isProduction && !allowUnsafeValidatorDetails ? {
310
- type: "validation",
311
- on: this.type,
312
- found: value,
313
- message
314
- } : {
315
- type: "validation",
316
- on: this.type,
317
- property: this.valueError?.path || "root",
318
- message,
319
- summary: mapValueError(this.valueError)?.summary,
320
- found: value,
321
- expected,
322
- errors
323
- };
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
+ );
324
555
  }
325
556
  }
326
557
  export {
@@ -331,6 +562,12 @@ export {
331
562
  InvalidCookieSignature,
332
563
  InvalidFileType,
333
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,
334
571
  NotFoundError,
335
572
  ParseError,
336
573
  ValidationError,
@@ -0,0 +1,3 @@
1
+ export declare const parseFormData: (form?: {
2
+ forEach(callback: (value: unknown, key: string, parent: unknown) => void): void;
3
+ }) => Record<string, unknown>;
@@ -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'] & {}>>>>>;