elysia 2.0.0-beta.1 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/adapter/utils.d.ts +2 -2
  2. package/dist/adapter/web-standard/handler.js +11 -7
  3. package/dist/adapter/web-standard/handler.mjs +12 -8
  4. package/dist/base.d.ts +18 -3
  5. package/dist/base.js +31 -15
  6. package/dist/base.mjs +31 -15
  7. package/dist/compile/aot-capture.js +1 -1
  8. package/dist/compile/aot-capture.mjs +2 -2
  9. package/dist/compile/handler/descriptor.d.ts +1 -1
  10. package/dist/compile/handler/frozen-validator.d.ts +2 -1
  11. package/dist/compile/handler/frozen-validator.js +33 -3
  12. package/dist/compile/handler/frozen-validator.mjs +33 -4
  13. package/dist/compile/handler/index.d.ts +1 -1
  14. package/dist/compile/handler/jit.js +5 -8
  15. package/dist/compile/handler/jit.mjs +6 -9
  16. package/dist/compile/handler/params.js +3 -3
  17. package/dist/compile/handler/params.mjs +4 -4
  18. package/dist/compile/handler/utils.d.ts +1 -1
  19. package/dist/compile/handler/utils.js +5 -2
  20. package/dist/compile/handler/utils.mjs +5 -2
  21. package/dist/context.d.ts +2 -2
  22. package/dist/cookie/cookie.js +1 -0
  23. package/dist/cookie/cookie.mjs +1 -0
  24. package/dist/error.d.ts +139 -6
  25. package/dist/error.js +73 -0
  26. package/dist/error.mjs +73 -1
  27. package/dist/handler/error.d.ts +20 -1
  28. package/dist/handler/error.js +120 -8
  29. package/dist/handler/error.mjs +119 -9
  30. package/dist/handler/fetch.js +9 -5
  31. package/dist/handler/fetch.mjs +9 -5
  32. package/dist/index.d.ts +4 -4
  33. package/dist/index.js +1 -0
  34. package/dist/index.mjs +2 -2
  35. package/dist/package.js +1 -1
  36. package/dist/package.mjs +1 -1
  37. package/dist/plugin/aot/core.d.ts +4 -3
  38. package/dist/plugin/aot/core.js +1 -1
  39. package/dist/plugin/aot/core.mjs +1 -1
  40. package/dist/route-table.d.ts +1 -1
  41. package/dist/sucrose.js +118 -16
  42. package/dist/sucrose.mjs +118 -16
  43. package/dist/type/bridge.d.ts +6 -6
  44. package/dist/type/coerce.js +9 -4
  45. package/dist/type/coerce.mjs +9 -4
  46. package/dist/type/elysia/array-string.js +29 -2
  47. package/dist/type/elysia/array-string.mjs +30 -3
  48. package/dist/type/elysia/file-type.js +11 -1
  49. package/dist/type/elysia/file-type.mjs +11 -1
  50. package/dist/type/elysia/form.js +2 -1
  51. package/dist/type/elysia/form.mjs +2 -1
  52. package/dist/type/elysia/object-string.js +26 -2
  53. package/dist/type/elysia/object-string.mjs +27 -3
  54. package/dist/type/validator/index.js +11 -13
  55. package/dist/type/validator/index.mjs +12 -14
  56. package/dist/types.d.ts +104 -18
  57. package/dist/universal/file.js +1 -0
  58. package/dist/universal/file.mjs +1 -0
  59. package/dist/universal/index.d.ts +1 -1
  60. package/dist/utils.d.ts +3 -5
  61. package/dist/utils.js +7 -9
  62. package/dist/utils.mjs +6 -10
  63. package/dist/ws/route.js +1 -1
  64. package/dist/ws/route.mjs +1 -1
  65. package/package.json +2 -2
package/dist/sucrose.js CHANGED
@@ -135,29 +135,31 @@ function removeColonAlias(parameter) {
135
135
  function retrieveRootparameters(parameter) {
136
136
  let hasParenthesis = false;
137
137
  if (parameter.charCodeAt(0) === 40) parameter = parameter.slice(1, -1);
138
+ parameter = parameter.trim();
139
+ if (parameter.indexOf("=") !== -1) parameter = removeDefaultParameter(parameter);
138
140
  if (parameter.charCodeAt(0) === 123) {
139
141
  hasParenthesis = true;
140
142
  const [, end] = bracketPairRange(parameter);
141
143
  parameter = parameter.slice(1, end - 1);
142
144
  }
143
- parameter = parameter.replace(/[ \t\n]/g, "");
144
- let parameters = [];
145
+ parameter = parameter.replace(/\s+/g, "");
146
+ const parameters = [];
145
147
  while (true) {
146
148
  let [start, end] = bracketPairRange(parameter);
147
149
  if (start === -1) break;
148
- parameters.push(parameter.slice(0, start - 1));
150
+ parameters.push(removeColonAlias(parameter.slice(0, start - 1)));
149
151
  if (parameter.charCodeAt(end) === 44) end++;
150
152
  parameter = parameter.slice(end);
151
153
  }
152
154
  parameter = removeColonAlias(parameter);
153
- if (parameter) parameters = parameters.concat(parameter.split(","));
155
+ if (parameter) parameters.push(parameter);
154
156
  const parameterMap = Object.create(null);
155
157
  for (const p of parameters) {
156
158
  if (p.indexOf(",") === -1) {
157
- parameterMap[removeDefaultParameter(p)] = true;
159
+ parameterMap[p] = true;
158
160
  continue;
159
161
  }
160
- for (const q of p.split(",")) parameterMap[removeDefaultParameter(q.trim())] = true;
162
+ for (const q of p.split(",")) parameterMap[q] = true;
161
163
  }
162
164
  return {
163
165
  hasParenthesis,
@@ -255,18 +257,118 @@ function findAlias(type, body, seen = /* @__PURE__ */ new Set()) {
255
257
  }
256
258
  return aliases;
257
259
  }
260
+ /**
261
+ * Whitespace as JavaScript defines it, which is what `\s` matches: everything
262
+ * `String.prototype.trim` removes, not just the three characters that happen to
263
+ * appear in LF-formatted source.
264
+ */
265
+ const isWhitespace = (char) => char === 32 || char >= 9 && char <= 13 || char === 160 || char === 5760 || char >= 8192 && char <= 8202 || char === 8232 || char === 8233 || char === 8239 || char === 8287 || char === 12288 || char === 65279;
266
+ /**
267
+ * Words that lex as an identifier but are operators, so a `/` after one opens a
268
+ * regex instead of dividing. Padded so a lookup cannot match a substring.
269
+ */
270
+ const operatorKeyword = " typeof void delete in of instanceof new return case do else yield await throw ";
271
+ /**
272
+ * Skip a regular expression literal, so a `,`, `}` or quote inside it is not
273
+ * mistaken for structure.
274
+ */
275
+ function skipRegexLiteral(parameter, start, regexEnd) {
276
+ let previous = start - 1;
277
+ while (previous >= 0 && isWhitespace(parameter.charCodeAt(previous))) previous--;
278
+ if (previous >= 0) {
279
+ const char = parameter.charCodeAt(previous);
280
+ if (isIdentifierPart(char)) {
281
+ let identifier = previous;
282
+ while (identifier >= 0 && isIdentifierPart(parameter.charCodeAt(identifier))) identifier--;
283
+ if (parameter.charCodeAt(identifier) === 46 || !operatorKeyword.includes(" " + parameter.slice(identifier + 1, previous + 1) + " ")) return start;
284
+ } else if (char === 41 || char === 93 || char === 125 || char === 39 || char === 34 || char === 96 || char === 47 && previous === regexEnd) return start;
285
+ }
286
+ let inCharacterClass = false;
287
+ for (let index = start + 1; index < parameter.length; index++) {
288
+ const char = parameter.charCodeAt(index);
289
+ if (char === 92) index++;
290
+ else if (char === 91) inCharacterClass = true;
291
+ else if (char === 93) inCharacterClass = false;
292
+ else if (char === 47 && !inCharacterClass) return index;
293
+ }
294
+ return start;
295
+ }
296
+ /**
297
+ * Find where a default parameter value ends: the first `,` or `}` that is
298
+ * outside a string or regex literal and not nested inside `()`, `[]`, or `{}`
299
+ *
300
+ * Returns -1 when the value runs until the end of the string
301
+ */
302
+ function findDefaultValueEnd(parameter, start) {
303
+ let deep = 0;
304
+ let quote = 0;
305
+ let regexEnd = -1;
306
+ let template;
307
+ for (let index = start; index < parameter.length; index++) {
308
+ const char = parameter.charCodeAt(index);
309
+ if (quote !== 0) {
310
+ if (char === 92) index++;
311
+ else if (char === quote) quote = 0;
312
+ else if (quote === 96 && char === 36 && parameter.charCodeAt(index + 1) === 123) {
313
+ (template ??= []).push(deep);
314
+ quote = 0;
315
+ deep++;
316
+ index++;
317
+ }
318
+ continue;
319
+ }
320
+ switch (char) {
321
+ case 39:
322
+ case 34:
323
+ case 96:
324
+ quote = char;
325
+ break;
326
+ case 47: {
327
+ const closing = skipRegexLiteral(parameter, index, regexEnd);
328
+ if (closing !== index) regexEnd = closing;
329
+ index = closing;
330
+ break;
331
+ }
332
+ case 40:
333
+ case 91:
334
+ case 123:
335
+ deep++;
336
+ break;
337
+ case 41:
338
+ case 93:
339
+ if (deep !== 0) deep--;
340
+ break;
341
+ case 125:
342
+ if (deep === 0) return index;
343
+ deep--;
344
+ if (template !== void 0 && template[template.length - 1] === deep) {
345
+ template.pop();
346
+ quote = 96;
347
+ }
348
+ break;
349
+ case 44:
350
+ if (deep === 0) return index;
351
+ break;
352
+ }
353
+ }
354
+ return -1;
355
+ }
258
356
  function removeDefaultParameter(parameter) {
259
- while (true) {
260
- const index = parameter.indexOf("=");
261
- if (index === -1) break;
262
- const commaIndex = parameter.indexOf(",", index);
263
- const bracketIndex = parameter.indexOf("}", index);
264
- const end = commaIndex === -1 ? bracketIndex : bracketIndex === -1 ? commaIndex : Math.min(commaIndex, bracketIndex);
265
- if (end === -1) {
266
- parameter = parameter.slice(0, index);
267
- break;
357
+ let index = parameter.indexOf("=");
358
+ if (index !== -1) {
359
+ let kept = "";
360
+ let copyFrom = 0;
361
+ for (; index < parameter.length; index++) {
362
+ if (parameter.charCodeAt(index) !== 61) continue;
363
+ kept += parameter.slice(copyFrom, index);
364
+ const end = findDefaultValueEnd(parameter, index + 1);
365
+ if (end === -1) {
366
+ copyFrom = parameter.length;
367
+ break;
368
+ }
369
+ copyFrom = index = end;
268
370
  }
269
- parameter = parameter.slice(0, index) + parameter.slice(end);
371
+ parameter = kept + parameter.slice(copyFrom);
270
372
  }
271
373
  return parameter.split(",").map((i) => i.trim()).join(", ");
272
374
  }
package/dist/sucrose.mjs CHANGED
@@ -134,29 +134,31 @@ function removeColonAlias(parameter) {
134
134
  function retrieveRootparameters(parameter) {
135
135
  let hasParenthesis = false;
136
136
  if (parameter.charCodeAt(0) === 40) parameter = parameter.slice(1, -1);
137
+ parameter = parameter.trim();
138
+ if (parameter.indexOf("=") !== -1) parameter = removeDefaultParameter(parameter);
137
139
  if (parameter.charCodeAt(0) === 123) {
138
140
  hasParenthesis = true;
139
141
  const [, end] = bracketPairRange(parameter);
140
142
  parameter = parameter.slice(1, end - 1);
141
143
  }
142
- parameter = parameter.replace(/[ \t\n]/g, "");
143
- let parameters = [];
144
+ parameter = parameter.replace(/\s+/g, "");
145
+ const parameters = [];
144
146
  while (true) {
145
147
  let [start, end] = bracketPairRange(parameter);
146
148
  if (start === -1) break;
147
- parameters.push(parameter.slice(0, start - 1));
149
+ parameters.push(removeColonAlias(parameter.slice(0, start - 1)));
148
150
  if (parameter.charCodeAt(end) === 44) end++;
149
151
  parameter = parameter.slice(end);
150
152
  }
151
153
  parameter = removeColonAlias(parameter);
152
- if (parameter) parameters = parameters.concat(parameter.split(","));
154
+ if (parameter) parameters.push(parameter);
153
155
  const parameterMap = Object.create(null);
154
156
  for (const p of parameters) {
155
157
  if (p.indexOf(",") === -1) {
156
- parameterMap[removeDefaultParameter(p)] = true;
158
+ parameterMap[p] = true;
157
159
  continue;
158
160
  }
159
- for (const q of p.split(",")) parameterMap[removeDefaultParameter(q.trim())] = true;
161
+ for (const q of p.split(",")) parameterMap[q] = true;
160
162
  }
161
163
  return {
162
164
  hasParenthesis,
@@ -254,18 +256,118 @@ function findAlias(type, body, seen = /* @__PURE__ */ new Set()) {
254
256
  }
255
257
  return aliases;
256
258
  }
259
+ /**
260
+ * Whitespace as JavaScript defines it, which is what `\s` matches: everything
261
+ * `String.prototype.trim` removes, not just the three characters that happen to
262
+ * appear in LF-formatted source.
263
+ */
264
+ const isWhitespace = (char) => char === 32 || char >= 9 && char <= 13 || char === 160 || char === 5760 || char >= 8192 && char <= 8202 || char === 8232 || char === 8233 || char === 8239 || char === 8287 || char === 12288 || char === 65279;
265
+ /**
266
+ * Words that lex as an identifier but are operators, so a `/` after one opens a
267
+ * regex instead of dividing. Padded so a lookup cannot match a substring.
268
+ */
269
+ const operatorKeyword = " typeof void delete in of instanceof new return case do else yield await throw ";
270
+ /**
271
+ * Skip a regular expression literal, so a `,`, `}` or quote inside it is not
272
+ * mistaken for structure.
273
+ */
274
+ function skipRegexLiteral(parameter, start, regexEnd) {
275
+ let previous = start - 1;
276
+ while (previous >= 0 && isWhitespace(parameter.charCodeAt(previous))) previous--;
277
+ if (previous >= 0) {
278
+ const char = parameter.charCodeAt(previous);
279
+ if (isIdentifierPart(char)) {
280
+ let identifier = previous;
281
+ while (identifier >= 0 && isIdentifierPart(parameter.charCodeAt(identifier))) identifier--;
282
+ if (parameter.charCodeAt(identifier) === 46 || !operatorKeyword.includes(" " + parameter.slice(identifier + 1, previous + 1) + " ")) return start;
283
+ } else if (char === 41 || char === 93 || char === 125 || char === 39 || char === 34 || char === 96 || char === 47 && previous === regexEnd) return start;
284
+ }
285
+ let inCharacterClass = false;
286
+ for (let index = start + 1; index < parameter.length; index++) {
287
+ const char = parameter.charCodeAt(index);
288
+ if (char === 92) index++;
289
+ else if (char === 91) inCharacterClass = true;
290
+ else if (char === 93) inCharacterClass = false;
291
+ else if (char === 47 && !inCharacterClass) return index;
292
+ }
293
+ return start;
294
+ }
295
+ /**
296
+ * Find where a default parameter value ends: the first `,` or `}` that is
297
+ * outside a string or regex literal and not nested inside `()`, `[]`, or `{}`
298
+ *
299
+ * Returns -1 when the value runs until the end of the string
300
+ */
301
+ function findDefaultValueEnd(parameter, start) {
302
+ let deep = 0;
303
+ let quote = 0;
304
+ let regexEnd = -1;
305
+ let template;
306
+ for (let index = start; index < parameter.length; index++) {
307
+ const char = parameter.charCodeAt(index);
308
+ if (quote !== 0) {
309
+ if (char === 92) index++;
310
+ else if (char === quote) quote = 0;
311
+ else if (quote === 96 && char === 36 && parameter.charCodeAt(index + 1) === 123) {
312
+ (template ??= []).push(deep);
313
+ quote = 0;
314
+ deep++;
315
+ index++;
316
+ }
317
+ continue;
318
+ }
319
+ switch (char) {
320
+ case 39:
321
+ case 34:
322
+ case 96:
323
+ quote = char;
324
+ break;
325
+ case 47: {
326
+ const closing = skipRegexLiteral(parameter, index, regexEnd);
327
+ if (closing !== index) regexEnd = closing;
328
+ index = closing;
329
+ break;
330
+ }
331
+ case 40:
332
+ case 91:
333
+ case 123:
334
+ deep++;
335
+ break;
336
+ case 41:
337
+ case 93:
338
+ if (deep !== 0) deep--;
339
+ break;
340
+ case 125:
341
+ if (deep === 0) return index;
342
+ deep--;
343
+ if (template !== void 0 && template[template.length - 1] === deep) {
344
+ template.pop();
345
+ quote = 96;
346
+ }
347
+ break;
348
+ case 44:
349
+ if (deep === 0) return index;
350
+ break;
351
+ }
352
+ }
353
+ return -1;
354
+ }
257
355
  function removeDefaultParameter(parameter) {
258
- while (true) {
259
- const index = parameter.indexOf("=");
260
- if (index === -1) break;
261
- const commaIndex = parameter.indexOf(",", index);
262
- const bracketIndex = parameter.indexOf("}", index);
263
- const end = commaIndex === -1 ? bracketIndex : bracketIndex === -1 ? commaIndex : Math.min(commaIndex, bracketIndex);
264
- if (end === -1) {
265
- parameter = parameter.slice(0, index);
266
- break;
356
+ let index = parameter.indexOf("=");
357
+ if (index !== -1) {
358
+ let kept = "";
359
+ let copyFrom = 0;
360
+ for (; index < parameter.length; index++) {
361
+ if (parameter.charCodeAt(index) !== 61) continue;
362
+ kept += parameter.slice(copyFrom, index);
363
+ const end = findDefaultValueEnd(parameter, index + 1);
364
+ if (end === -1) {
365
+ copyFrom = parameter.length;
366
+ break;
367
+ }
368
+ copyFrom = index = end;
267
369
  }
268
- parameter = parameter.slice(0, index) + parameter.slice(end);
370
+ parameter = kept + parameter.slice(copyFrom);
269
371
  }
270
372
  return parameter.split(",").map((i) => i.trim()).join(", ");
271
373
  }
@@ -1,17 +1,17 @@
1
- import { Intersect as Intersect$1 } from "./elysia/intersect.js";
1
+ import { Intersect as Intersect$2 } from "./elysia/intersect.js";
2
2
  import { hasTypes as hasTypes$1 } from "./utils.js";
3
3
  import { TypeBoxValidatorCache as TypeBoxValidatorCache$1, mayHaveFileType as mayHaveFileType$1 } from "./validator/validator-cache.js";
4
4
  import { TypeBoxValidator as TypeBoxValidator$1 } from "./validator/index.js";
5
5
  import { applyCoercions as applyCoercions$1, coerceBody as coerceBody$1, coerceFormData as coerceFormData$1, coerceQuery as coerceQuery$1, coerceRoot as coerceRoot$1, coerceStringToStructure as coerceStringToStructure$1 } from "./coerce.js";
6
6
  import { Ref as Ref$1, TAny, TSchema } from "typebox/type";
7
7
  import { Compile as Compile$1 } from "typebox/compile";
8
- import { Check as Check$1, Clone as Clone$1, Create as Create$1, Decode as Decode$1, Default as Default$1, HasCodec as HasCodec$1 } from "typebox/value";
8
+ import { Check as Check$1, Clone as Clone$1, Create as Create$1, Decode as Decode$2, Default as Default$1, HasCodec as HasCodec$1 } from "typebox/value";
9
9
 
10
10
  //#region src/type/bridge.d.ts
11
11
  interface TypeboxModule {
12
12
  Compile: typeof Compile$1;
13
13
  Create: typeof Create$1;
14
- Decode: typeof Decode$1;
14
+ Decode: typeof Decode$2;
15
15
  applyCoercions: typeof applyCoercions$1;
16
16
  TypeBoxValidator: TypeBoxValidator$1;
17
17
  TypeBoxValidatorCache: TypeBoxValidatorCache$1;
@@ -23,7 +23,7 @@ interface TypeboxModule {
23
23
  hasTypes: typeof hasTypes$1;
24
24
  mayHaveFileType: typeof mayHaveFileType$1;
25
25
  HasCodec: typeof HasCodec$1;
26
- Intersect: typeof Intersect$1;
26
+ Intersect: typeof Intersect$2;
27
27
  Default: typeof Default$1;
28
28
  Ref: typeof Ref$1;
29
29
  Clone: typeof Clone$1;
@@ -31,7 +31,7 @@ interface TypeboxModule {
31
31
  }
32
32
  declare let Compile: typeof Compile$1;
33
33
  declare let Create: typeof Create$1;
34
- declare let Decode: typeof Decode$1;
34
+ declare let Decode: typeof Decode$2;
35
35
  declare let applyCoercions: typeof applyCoercions$1;
36
36
  declare let TypeBoxValidator: TypeBoxValidator$1;
37
37
  type TypeBoxValidator<T extends TSchema = TAny> = TypeBoxValidator$1<T>;
@@ -45,7 +45,7 @@ declare let coerceBody: typeof coerceBody$1;
45
45
  declare let hasTypes: typeof hasTypes$1;
46
46
  declare let mayHaveFileType: typeof mayHaveFileType$1;
47
47
  declare let HasCodec: typeof HasCodec$1;
48
- declare let Intersect: typeof Intersect$1;
48
+ declare let Intersect: typeof Intersect$2;
49
49
  declare let Default: typeof Default$1;
50
50
  declare let Ref: typeof Ref$1;
51
51
  declare let Clone: typeof Clone$1;
@@ -227,10 +227,15 @@ const coerceQuery = () => _coerceQuery ??= [[[["Object", toObjectString], ["Arra
227
227
  let _coerceBody;
228
228
  const coerceBody = () => _coerceBody ??= [[[["Number", require_type_elysia_numeric.Numeric], ["Boolean", require_type_elysia_boolean_string.BooleanString]], { root: true }], [[["Integer", require_type_elysia_integer_string.IntegerString]]]];
229
229
  let _coerceFormData;
230
- const coerceFormData = () => _coerceFormData ??= [[[["Object", toObjectString]], { rootPropertiesOnly: true }], [[["Array", toArrayString]], {
231
- root: false,
232
- onlyFirst: "array"
233
- }]];
230
+ const coerceFormData = () => _coerceFormData ??= [
231
+ [[["Integer", require_type_elysia_integer_string.IntegerString]]],
232
+ ...coerceRoot(),
233
+ [[["Object", toObjectString]], { rootPropertiesOnly: true }],
234
+ [[["Array", toArrayString]], {
235
+ root: false,
236
+ onlyFirst: "array"
237
+ }]
238
+ ];
234
239
  let _coerceStringToStructure;
235
240
  const coerceStringToStructure = () => _coerceStringToStructure ??= [[[["Object", toObjectString], ["Array", toArrayString]], { rootPropertiesOnly: true }], ...coerceRoot()];
236
241
  function applyCoercions(schema, coerces) {
@@ -226,10 +226,15 @@ const coerceQuery = () => _coerceQuery ??= [[[["Object", toObjectString], ["Arra
226
226
  let _coerceBody;
227
227
  const coerceBody = () => _coerceBody ??= [[[["Number", Numeric], ["Boolean", BooleanString]], { root: true }], [[["Integer", IntegerString]]]];
228
228
  let _coerceFormData;
229
- const coerceFormData = () => _coerceFormData ??= [[[["Object", toObjectString]], { rootPropertiesOnly: true }], [[["Array", toArrayString]], {
230
- root: false,
231
- onlyFirst: "array"
232
- }]];
229
+ const coerceFormData = () => _coerceFormData ??= [
230
+ [[["Integer", IntegerString]]],
231
+ ...coerceRoot(),
232
+ [[["Object", toObjectString]], { rootPropertiesOnly: true }],
233
+ [[["Array", toArrayString]], {
234
+ root: false,
235
+ onlyFirst: "array"
236
+ }]
237
+ ];
233
238
  let _coerceStringToStructure;
234
239
  const coerceStringToStructure = () => _coerceStringToStructure ??= [[[["Object", toObjectString], ["Array", toArrayString]], { rootPropertiesOnly: true }], ...coerceRoot()];
235
240
  function applyCoercions(schema, coerces) {
@@ -10,17 +10,44 @@ const require_type_elysia_utils = require('./utils.js');
10
10
  let typebox_type = require("typebox/type");
11
11
 
12
12
  //#region src/type/elysia/array-string.ts
13
+ const MEMO_LIMIT = 8192;
13
14
  function ArrayString(property, _options) {
14
15
  const [constraints, meta] = require_type_elysia_utils.getMeta(_options ?? require_utils.nullObject());
15
16
  const array = require_type_elysia_array.ArrayType(property, constraints);
17
+ let check;
18
+ const checkInner = (value) => {
19
+ if (!check) try {
20
+ const compiled = require_type_bridge.Compile(array);
21
+ if (compiled.evaluateResult) compiled.evaluateResult.code = void 0;
22
+ if (compiled.buildResult) compiled.buildResult.functions = void 0;
23
+ check = (v) => compiled.Check(v);
24
+ } catch {
25
+ check = (v) => require_type_bridge.Check(array, v);
26
+ }
27
+ return check(value);
28
+ };
29
+ let raw;
30
+ let parsed;
16
31
  const arrayString = (0, typebox_type.Decode)((0, typebox_type.Refine)(require_type_elysia_string.StringType(), (value) => {
17
32
  if (value.charCodeAt(0) !== 91) return false;
33
+ if (value === raw) return true;
18
34
  try {
19
- return require_type_bridge.Check(array, JSON.parse(value));
35
+ const next = JSON.parse(value);
36
+ if (!checkInner(next)) return false;
37
+ if (value.length <= MEMO_LIMIT) {
38
+ raw = value;
39
+ parsed = next;
40
+ }
41
+ return true;
20
42
  } catch {
21
43
  return false;
22
44
  }
23
- }, () => "must be an array"), (value) => require_type_bridge.Decode(array, JSON.parse(value)));
45
+ }, () => "must be an array"), (value) => {
46
+ const decoded = value === raw ? parsed : JSON.parse(value);
47
+ raw = void 0;
48
+ parsed = void 0;
49
+ return require_type_bridge.Decode(array, decoded);
50
+ });
24
51
  return require_type_elysia_utils.elyType(require_type_constants.ELYSIA_TYPES.ArrayString, require_type_elysia_union.Union([array, arrayString], meta));
25
52
  }
26
53
 
@@ -1,5 +1,5 @@
1
1
  import { nullObject } from "../../utils.mjs";
2
- import { Check, Decode as Decode$1 } from "../bridge.mjs";
2
+ import { Check, Compile, Decode as Decode$1 } from "../bridge.mjs";
3
3
  import { ELYSIA_TYPES } from "../constants.mjs";
4
4
  import { ArrayType } from "./array.mjs";
5
5
  import { StringType } from "./string.mjs";
@@ -8,17 +8,44 @@ import { elyType, getMeta } from "./utils.mjs";
8
8
  import { Decode, Refine } from "typebox/type";
9
9
 
10
10
  //#region src/type/elysia/array-string.ts
11
+ const MEMO_LIMIT = 8192;
11
12
  function ArrayString(property, _options) {
12
13
  const [constraints, meta] = getMeta(_options ?? nullObject());
13
14
  const array = ArrayType(property, constraints);
15
+ let check;
16
+ const checkInner = (value) => {
17
+ if (!check) try {
18
+ const compiled = Compile(array);
19
+ if (compiled.evaluateResult) compiled.evaluateResult.code = void 0;
20
+ if (compiled.buildResult) compiled.buildResult.functions = void 0;
21
+ check = (v) => compiled.Check(v);
22
+ } catch {
23
+ check = (v) => Check(array, v);
24
+ }
25
+ return check(value);
26
+ };
27
+ let raw;
28
+ let parsed;
14
29
  const arrayString = Decode(Refine(StringType(), (value) => {
15
30
  if (value.charCodeAt(0) !== 91) return false;
31
+ if (value === raw) return true;
16
32
  try {
17
- return Check(array, JSON.parse(value));
33
+ const next = JSON.parse(value);
34
+ if (!checkInner(next)) return false;
35
+ if (value.length <= MEMO_LIMIT) {
36
+ raw = value;
37
+ parsed = next;
38
+ }
39
+ return true;
18
40
  } catch {
19
41
  return false;
20
42
  }
21
- }, () => "must be an array"), (value) => Decode$1(array, JSON.parse(value)));
43
+ }, () => "must be an array"), (value) => {
44
+ const decoded = value === raw ? parsed : JSON.parse(value);
45
+ raw = void 0;
46
+ parsed = void 0;
47
+ return Decode$1(array, decoded);
48
+ });
22
49
  return elyType(ELYSIA_TYPES.ArrayString, Union([array, arrayString], meta));
23
50
  }
24
51
 
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_universal_is_production = require('../../universal/is-production.js');
2
3
  const require_compile_utils = require('../../compile/utils.js');
3
4
 
4
5
  //#region src/type/elysia/file-type.ts
@@ -6,6 +7,11 @@ let fileTypeDetectors;
6
7
  function setFileTypeDetector(detector) {
7
8
  fileTypeDetectors = Array.isArray(detector) ? detector : [detector];
8
9
  }
10
+ let warnedMissingDetector = false;
11
+ function warnMissingFileTypeDetector() {
12
+ warnedMissingDetector = true;
13
+ console.warn("[elysia] missing file type detector");
14
+ }
9
15
  async function detectFileType(file) {
10
16
  for (let i = 0; i < fileTypeDetectors.length; i++) {
11
17
  const result = await fileTypeDetectors[i](file);
@@ -18,7 +24,10 @@ async function fileType(file, type) {
18
24
  if (!file) return false;
19
25
  const types = typeof type === "string" ? [type] : type;
20
26
  if (!matchesAnyFileType(file.type, types)) return false;
21
- if (!fileTypeDetectors) return false;
27
+ if (!fileTypeDetectors) {
28
+ if (!require_universal_is_production.isProduction() && !warnedMissingDetector) warnMissingFileTypeDetector();
29
+ return false;
30
+ }
22
31
  const mime = await detectFileType(file);
23
32
  if (mime && matchesAnyFileType(mime, types)) return true;
24
33
  return false;
@@ -39,6 +48,7 @@ function takeFileTypeChecks() {
39
48
  function maybeQueueFileTypeCheck(value, types, message) {
40
49
  if (!collecting) return;
41
50
  if (!fileTypeDetectors) {
51
+ if (!require_universal_is_production.isProduction() && !warnedMissingDetector) warnMissingFileTypeDetector();
42
52
  (pendingFileTypeChecks ??= []).push({
43
53
  file: value,
44
54
  check: Promise.resolve(message)
@@ -1,3 +1,4 @@
1
+ import { isProduction } from "../../universal/is-production.mjs";
1
2
  import { isAsyncFunction } from "../../compile/utils.mjs";
2
3
 
3
4
  //#region src/type/elysia/file-type.ts
@@ -5,6 +6,11 @@ let fileTypeDetectors;
5
6
  function setFileTypeDetector(detector) {
6
7
  fileTypeDetectors = Array.isArray(detector) ? detector : [detector];
7
8
  }
9
+ let warnedMissingDetector = false;
10
+ function warnMissingFileTypeDetector() {
11
+ warnedMissingDetector = true;
12
+ console.warn("[elysia] missing file type detector");
13
+ }
8
14
  async function detectFileType(file) {
9
15
  for (let i = 0; i < fileTypeDetectors.length; i++) {
10
16
  const result = await fileTypeDetectors[i](file);
@@ -17,7 +23,10 @@ async function fileType(file, type) {
17
23
  if (!file) return false;
18
24
  const types = typeof type === "string" ? [type] : type;
19
25
  if (!matchesAnyFileType(file.type, types)) return false;
20
- if (!fileTypeDetectors) return false;
26
+ if (!fileTypeDetectors) {
27
+ if (!isProduction() && !warnedMissingDetector) warnMissingFileTypeDetector();
28
+ return false;
29
+ }
21
30
  const mime = await detectFileType(file);
22
31
  if (mime && matchesAnyFileType(mime, types)) return true;
23
32
  return false;
@@ -38,6 +47,7 @@ function takeFileTypeChecks() {
38
47
  function maybeQueueFileTypeCheck(value, types, message) {
39
48
  if (!collecting) return;
40
49
  if (!fileTypeDetectors) {
50
+ if (!isProduction() && !warnedMissingDetector) warnMissingFileTypeDetector();
41
51
  (pendingFileTypeChecks ??= []).push({
42
52
  file: value,
43
53
  check: Promise.resolve(message)
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../../_virtual/_rolldown/runtime.js');
3
+ const require_utils = require('../../utils.js');
3
4
  const require_type_constants = require('../constants.js');
4
5
  const require_type_elysia_utils = require('./utils.js');
5
6
  const require_type_elysia_object = require('./object.js');
@@ -9,7 +10,7 @@ let typebox_type = require("typebox/type");
9
10
  //#region src/type/elysia/form.ts
10
11
  let BaseForm;
11
12
  const Form = (property, options) => {
12
- BaseForm ??= Object.freeze((0, typebox_type.Decode)((0, typebox_type.Refine)((0, typebox_type.Unsafe)({ "~kind": "FormData" }), (value) => typeof value === "object" && value !== null && "~ely-form" in value, () => "must be instance of Elysia.form"), (value) => value));
13
+ BaseForm ??= Object.freeze((0, typebox_type.Decode)((0, typebox_type.Refine)((0, typebox_type.Unsafe)({ "~kind": "FormData" }), (value) => require_utils.isElysiaForm(value), () => "must be instance of Elysia.form"), (value) => value));
13
14
  return require_type_elysia_utils.elyType(require_type_constants.ELYSIA_TYPES.Form, require_type_elysia_intersect.Intersect([BaseForm, require_type_elysia_object.ObjectType(property, options)]));
14
15
  };
15
16
 
@@ -1,3 +1,4 @@
1
+ import { isElysiaForm } from "../../utils.mjs";
1
2
  import { ELYSIA_TYPES } from "../constants.mjs";
2
3
  import { elyType } from "./utils.mjs";
3
4
  import { ObjectType } from "./object.mjs";
@@ -7,7 +8,7 @@ import { Decode, Refine, Unsafe } from "typebox/type";
7
8
  //#region src/type/elysia/form.ts
8
9
  let BaseForm;
9
10
  const Form = (property, options) => {
10
- BaseForm ??= Object.freeze(Decode(Refine(Unsafe({ "~kind": "FormData" }), (value) => typeof value === "object" && value !== null && "~ely-form" in value, () => "must be instance of Elysia.form"), (value) => value));
11
+ BaseForm ??= Object.freeze(Decode(Refine(Unsafe({ "~kind": "FormData" }), (value) => isElysiaForm(value), () => "must be instance of Elysia.form"), (value) => value));
11
12
  return elyType(ELYSIA_TYPES.Form, Intersect$1([BaseForm, ObjectType(property, options)]));
12
13
  };
13
14