typia 15.0.0 → 15.0.1

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 (110) hide show
  1. package/lib/http.d.ts +49 -24
  2. package/lib/http.js.map +1 -1
  3. package/lib/http.mjs.map +1 -1
  4. package/lib/internal/_httpFormDataReadBigint.js +7 -5
  5. package/lib/internal/_httpFormDataReadBigint.js.map +1 -1
  6. package/lib/internal/_httpFormDataReadBigint.mjs +1 -1
  7. package/lib/internal/_httpFormDataReadBigint.mjs.map +1 -1
  8. package/lib/internal/_httpFormDataReadBoolean.js +12 -10
  9. package/lib/internal/_httpFormDataReadBoolean.js.map +1 -1
  10. package/lib/internal/_httpFormDataReadBoolean.mjs +1 -1
  11. package/lib/internal/_httpFormDataReadBoolean.mjs.map +1 -1
  12. package/lib/internal/_httpFormDataReadNumber.js +7 -5
  13. package/lib/internal/_httpFormDataReadNumber.js.map +1 -1
  14. package/lib/internal/_httpFormDataReadNumber.mjs +1 -1
  15. package/lib/internal/_httpFormDataReadNumber.mjs.map +1 -1
  16. package/lib/internal/_httpFormDataReadString.d.ts +9 -1
  17. package/lib/internal/_httpFormDataReadString.js +10 -2
  18. package/lib/internal/_httpFormDataReadString.js.map +1 -1
  19. package/lib/internal/_httpFormDataReadString.mjs +9 -1
  20. package/lib/internal/_httpFormDataReadString.mjs.map +1 -1
  21. package/lib/internal/_httpHeaderReadBigint.js +5 -1
  22. package/lib/internal/_httpHeaderReadBigint.js.map +1 -1
  23. package/lib/internal/_httpHeaderReadBigint.mjs +2 -1
  24. package/lib/internal/_httpHeaderReadBigint.mjs.map +1 -1
  25. package/lib/internal/_httpHeaderReadNumber.js +5 -1
  26. package/lib/internal/_httpHeaderReadNumber.js.map +1 -1
  27. package/lib/internal/_httpHeaderReadNumber.mjs +2 -1
  28. package/lib/internal/_httpHeaderReadNumber.mjs.map +1 -1
  29. package/lib/internal/_httpParameterReadBigint.js +4 -0
  30. package/lib/internal/_httpParameterReadBigint.js.map +1 -1
  31. package/lib/internal/_httpParameterReadBigint.mjs +1 -0
  32. package/lib/internal/_httpParameterReadBigint.mjs.map +1 -1
  33. package/lib/internal/_httpParameterReadNumber.js +4 -0
  34. package/lib/internal/_httpParameterReadNumber.js.map +1 -1
  35. package/lib/internal/_httpParameterReadNumber.mjs +1 -0
  36. package/lib/internal/_httpParameterReadNumber.mjs.map +1 -1
  37. package/lib/internal/_httpParameterReadString.d.ts +9 -1
  38. package/lib/internal/_httpParameterReadString.js +9 -1
  39. package/lib/internal/_httpParameterReadString.js.map +1 -1
  40. package/lib/internal/_httpParameterReadString.mjs +9 -1
  41. package/lib/internal/_httpParameterReadString.mjs.map +1 -1
  42. package/lib/internal/_httpQueryReadBigint.js +8 -1
  43. package/lib/internal/_httpQueryReadBigint.js.map +1 -1
  44. package/lib/internal/_httpQueryReadBigint.mjs +1 -1
  45. package/lib/internal/_httpQueryReadBigint.mjs.map +1 -1
  46. package/lib/internal/_httpQueryReadBoolean.js +4 -1
  47. package/lib/internal/_httpQueryReadBoolean.js.map +1 -1
  48. package/lib/internal/_httpQueryReadBoolean.mjs +1 -1
  49. package/lib/internal/_httpQueryReadBoolean.mjs.map +1 -1
  50. package/lib/internal/_httpQueryReadNumber.js +8 -1
  51. package/lib/internal/_httpQueryReadNumber.js.map +1 -1
  52. package/lib/internal/_httpQueryReadNumber.mjs +1 -1
  53. package/lib/internal/_httpQueryReadNumber.mjs.map +1 -1
  54. package/lib/internal/_httpQueryReadString.d.ts +9 -1
  55. package/lib/internal/_httpQueryReadString.js +9 -1
  56. package/lib/internal/_httpQueryReadString.js.map +1 -1
  57. package/lib/internal/_httpQueryReadString.mjs +9 -1
  58. package/lib/internal/_httpQueryReadString.mjs.map +1 -1
  59. package/lib/internal/_randomBigint.d.ts +12 -1
  60. package/lib/internal/_randomBigint.js +90 -2
  61. package/lib/internal/_randomBigint.js.map +1 -1
  62. package/lib/internal/_randomBigint.mjs +70 -2
  63. package/lib/internal/_randomBigint.mjs.map +1 -1
  64. package/lib/internal/_randomInteger.js +21 -12
  65. package/lib/internal/_randomInteger.js.map +1 -1
  66. package/lib/internal/_randomInteger.mjs +21 -16
  67. package/lib/internal/_randomInteger.mjs.map +1 -1
  68. package/lib/internal/_randomNumber.js +19 -10
  69. package/lib/internal/_randomNumber.js.map +1 -1
  70. package/lib/internal/_randomNumber.mjs +19 -14
  71. package/lib/internal/_randomNumber.mjs.map +1 -1
  72. package/native/cmd/ttsc-typia/llm_evaluation_rejects_invalid_probability_test.go +9 -0
  73. package/native/cmd/ttsc-typia/random_recursive_min_items_diagnostic_test.go +18 -1
  74. package/native/core/factories/ExpressionFactory.go +16 -1
  75. package/native/core/factories/MetadataCommentTagFactory.go +177 -29
  76. package/native/core/factories/expression_factory_number_spells_non_finite_values_test.go +69 -0
  77. package/native/core/factories/metadata_comment_tag_factory_holds_bigint_tags_exact_test.go +168 -0
  78. package/native/core/factories/metadata_comment_tag_factory_reads_javascript_numbers_test.go +158 -0
  79. package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +1 -3
  80. package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +107 -9
  81. package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +1 -3
  82. package/native/core/programmers/http/HttpFormDataProgrammer.go +41 -2
  83. package/native/core/programmers/http/HttpHeadersProgrammer.go +56 -4
  84. package/native/core/programmers/http/HttpParameterProgrammer.go +1 -3
  85. package/native/core/programmers/http/HttpQueryProgrammer.go +26 -43
  86. package/native/core/programmers/iterate/json_schema_jsDocTags.go +10 -3
  87. package/native/core/programmers/iterate/json_schema_jsdoc_tags_cast_reads_javascript_numbers_test.go +64 -0
  88. package/native/core/programmers/llm/LlmEvaluationProgrammer.go +6 -2
  89. package/native/core/programmers/llm/LlmSchemaProgrammer.go +34 -4
  90. package/native/core/utils/NumberUtil.go +195 -0
  91. package/native/core/utils/number_util_rational_keeps_written_value_test.go +62 -0
  92. package/native/core/utils/number_util_reads_javascript_number_grammar_test.go +147 -0
  93. package/package.json +3 -3
  94. package/src/http.ts +61 -34
  95. package/src/internal/_httpFormDataReadBigint.ts +3 -1
  96. package/src/internal/_httpFormDataReadBoolean.ts +3 -1
  97. package/src/internal/_httpFormDataReadNumber.ts +3 -1
  98. package/src/internal/_httpFormDataReadString.ts +10 -1
  99. package/src/internal/_httpHeaderReadBigint.ts +6 -1
  100. package/src/internal/_httpHeaderReadNumber.ts +6 -1
  101. package/src/internal/_httpParameterReadBigint.ts +3 -0
  102. package/src/internal/_httpParameterReadNumber.ts +3 -0
  103. package/src/internal/_httpParameterReadString.ts +12 -2
  104. package/src/internal/_httpQueryReadBigint.ts +7 -1
  105. package/src/internal/_httpQueryReadBoolean.ts +3 -1
  106. package/src/internal/_httpQueryReadNumber.ts +7 -1
  107. package/src/internal/_httpQueryReadString.ts +10 -1
  108. package/src/internal/_randomBigint.ts +111 -3
  109. package/src/internal/_randomInteger.ts +31 -16
  110. package/src/internal/_randomNumber.ts +23 -12
@@ -1,6 +1,114 @@
1
1
  import { OpenApi } from "@typia/interface";
2
2
 
3
- import { _randomInteger } from "./_randomInteger";
3
+ import { _decimalIntegerStep } from "./_decimal";
4
4
 
5
- export const _randomBigint = (props: OpenApi.IJsonSchema.IInteger): bigint =>
6
- BigInt(_randomInteger(props));
5
+ /**
6
+ * Generates a random `bigint` satisfying an integer schema.
7
+ *
8
+ * The schema carries its bounds and step as numbers, but the value is a
9
+ * `bigint`, so the draw runs on integers. Drawing through doubles rounded every
10
+ * value past 2^53, and it checked `multipleOf` against a double's shortest
11
+ * decimal text rather than the integer `BigInt` makes of it, so `random`
12
+ * returned values the validator rejects, or gave up on a range that holds one
13
+ * (#2457). An integral bound or step is read as the integer the double holds,
14
+ * which is the integer the validator compares with.
15
+ */
16
+ export const _randomBigint = (schema: OpenApi.IJsonSchema.IInteger): bigint => {
17
+ const lower: bigint | null = boundary(
18
+ schema.minimum,
19
+ schema.exclusiveMinimum,
20
+ "lower",
21
+ );
22
+ const upper: bigint | null = boundary(
23
+ schema.maximum,
24
+ schema.exclusiveMaximum,
25
+ "upper",
26
+ );
27
+ const minimum: bigint =
28
+ lower ?? (upper === null ? BigInt(0) : upper - BigInt(100));
29
+ const maximum: bigint =
30
+ upper ?? (lower === null ? BigInt(100) : lower + BigInt(100));
31
+ if (minimum > maximum)
32
+ throw new Error("Minimum value is greater than maximum value.");
33
+ if (schema.multipleOf === undefined) return between(minimum, maximum);
34
+
35
+ const step: bigint | null = integerStep(schema.multipleOf);
36
+ if (step === null || step <= BigInt(0))
37
+ throw new Error("The multipleOf value must be a positive finite number.");
38
+ const first: bigint = ceilDivide(minimum, step);
39
+ const last: bigint = floorDivide(maximum, step);
40
+ if (first > last)
41
+ throw new Error("The range does not contain a multipleOf value.");
42
+ return between(first, last) * step;
43
+ };
44
+
45
+ /**
46
+ * Reads one side's inclusive integer bound.
47
+ *
48
+ * `-Infinity` below or `Infinity` above excludes no integer, so it is no bound
49
+ * at all; `Infinity` below or `-Infinity` above excludes every integer.
50
+ */
51
+ const boundary = (
52
+ inclusive: number | undefined,
53
+ exclusive: number | undefined,
54
+ side: "lower" | "upper",
55
+ ): bigint | null => {
56
+ const candidates: bigint[] = [];
57
+ for (const [value, open] of [
58
+ [inclusive, false],
59
+ [exclusive, true],
60
+ ] as const) {
61
+ if (value === undefined) continue;
62
+ if (Number.isFinite(value) === false) {
63
+ if (value === (side === "lower" ? -Infinity : Infinity)) continue;
64
+ throw new Error("Numeric range has no finite value.");
65
+ }
66
+ candidates.push(
67
+ side === "lower"
68
+ ? open
69
+ ? BigInt(Math.floor(value)) + BigInt(1)
70
+ : BigInt(Math.ceil(value))
71
+ : open
72
+ ? BigInt(Math.ceil(value)) - BigInt(1)
73
+ : BigInt(Math.floor(value)),
74
+ );
75
+ }
76
+ if (candidates.length === 0) return null;
77
+ return candidates.reduce((x, y) =>
78
+ side === "lower" ? (x > y ? x : y) : x < y ? x : y,
79
+ );
80
+ };
81
+
82
+ /**
83
+ * The smallest positive integer a `multipleOf` divides.
84
+ *
85
+ * An integral step is the integer its double holds; a fractional one, such as
86
+ * `1.5`, steps by its smallest integer multiple (`3`).
87
+ */
88
+ const integerStep = (multipleOf: number): bigint | null => {
89
+ if (Number.isFinite(multipleOf) === false) return null;
90
+ if (Number.isInteger(multipleOf)) return BigInt(multipleOf);
91
+ return _decimalIntegerStep(multipleOf)?.coefficient ?? null;
92
+ };
93
+
94
+ const ceilDivide = (x: bigint, y: bigint): bigint => {
95
+ const quotient: bigint = x / y;
96
+ return x % y > BigInt(0) ? quotient + BigInt(1) : quotient;
97
+ };
98
+
99
+ const floorDivide = (x: bigint, y: bigint): bigint => {
100
+ const quotient: bigint = x / y;
101
+ return x % y < BigInt(0) ? quotient - BigInt(1) : quotient;
102
+ };
103
+
104
+ /** Draws an integer in `[minimum, maximum]`, scaling one 53-bit sample. */
105
+ const between = (minimum: bigint, maximum: bigint): bigint => {
106
+ const scale: bigint = BigInt(1) << BigInt(53);
107
+ const sample: bigint = BigInt(
108
+ Math.min(
109
+ Number(scale - BigInt(1)),
110
+ Math.floor(Math.max(0, Math.random()) * Number(scale)),
111
+ ),
112
+ );
113
+ return minimum + ((maximum - minimum + BigInt(1)) * sample) / scale;
114
+ };
@@ -35,14 +35,12 @@ const scalar = (props: { minimum: number; maximum: number }): number => {
35
35
  const getLowerBoundary = (
36
36
  schema: OpenApi.IJsonSchema.IInteger,
37
37
  ): IBoundary | null => {
38
- const inclusive: IBoundary | null =
39
- schema.minimum === undefined
40
- ? null
41
- : { value: schema.minimum, exclusive: false };
42
- const exclusive: IBoundary | null =
43
- schema.exclusiveMinimum === undefined
44
- ? null
45
- : { value: schema.exclusiveMinimum, exclusive: true };
38
+ const inclusive: IBoundary | null = boundary(schema.minimum, false, "lower");
39
+ const exclusive: IBoundary | null = boundary(
40
+ schema.exclusiveMinimum,
41
+ true,
42
+ "lower",
43
+ );
46
44
  const selected: IBoundary | null = selectBoundary(
47
45
  inclusive,
48
46
  exclusive,
@@ -60,14 +58,12 @@ const getLowerBoundary = (
60
58
  const getUpperBoundary = (
61
59
  schema: OpenApi.IJsonSchema.IInteger,
62
60
  ): IBoundary | null => {
63
- const inclusive: IBoundary | null =
64
- schema.maximum === undefined
65
- ? null
66
- : { value: schema.maximum, exclusive: false };
67
- const exclusive: IBoundary | null =
68
- schema.exclusiveMaximum === undefined
69
- ? null
70
- : { value: schema.exclusiveMaximum, exclusive: true };
61
+ const inclusive: IBoundary | null = boundary(schema.maximum, false, "upper");
62
+ const exclusive: IBoundary | null = boundary(
63
+ schema.exclusiveMaximum,
64
+ true,
65
+ "upper",
66
+ );
71
67
  const selected: IBoundary | null = selectBoundary(
72
68
  inclusive,
73
69
  exclusive,
@@ -82,6 +78,25 @@ const getUpperBoundary = (
82
78
  };
83
79
  };
84
80
 
81
+ /**
82
+ * Reads one bound, which may be infinite.
83
+ *
84
+ * A type tag built from an overflowing literal (`Maximum<1e400>`) carries an
85
+ * infinite bound (#2452). `-Infinity` below or `Infinity` above excludes no
86
+ * finite number, so it is no bound at all; `Infinity` below or `-Infinity`
87
+ * above excludes every finite number, so no value can be generated.
88
+ */
89
+ const boundary = (
90
+ value: number | undefined,
91
+ exclusive: boolean,
92
+ side: "lower" | "upper",
93
+ ): IBoundary | null => {
94
+ if (value === undefined) return null;
95
+ if (Number.isFinite(value)) return { value, exclusive };
96
+ if (value === (side === "lower" ? -Infinity : Infinity)) return null;
97
+ throw new Error("Numeric range has no finite value.");
98
+ };
99
+
85
100
  const selectBoundary = (
86
101
  x: IBoundary | null,
87
102
  y: IBoundary | null,
@@ -57,12 +57,8 @@ const getLowerBoundary = (
57
57
  schema: OpenApi.IJsonSchema.INumber,
58
58
  ): IBoundary | null =>
59
59
  selectBoundary(
60
- schema.minimum === undefined
61
- ? null
62
- : { value: schema.minimum, exclusive: false },
63
- schema.exclusiveMinimum === undefined
64
- ? null
65
- : { value: schema.exclusiveMinimum, exclusive: true },
60
+ boundary(schema.minimum, false, "lower"),
61
+ boundary(schema.exclusiveMinimum, true, "lower"),
66
62
  Math.max,
67
63
  );
68
64
 
@@ -70,15 +66,30 @@ const getUpperBoundary = (
70
66
  schema: OpenApi.IJsonSchema.INumber,
71
67
  ): IBoundary | null =>
72
68
  selectBoundary(
73
- schema.maximum === undefined
74
- ? null
75
- : { value: schema.maximum, exclusive: false },
76
- schema.exclusiveMaximum === undefined
77
- ? null
78
- : { value: schema.exclusiveMaximum, exclusive: true },
69
+ boundary(schema.maximum, false, "upper"),
70
+ boundary(schema.exclusiveMaximum, true, "upper"),
79
71
  Math.min,
80
72
  );
81
73
 
74
+ /**
75
+ * Reads one bound, which may be infinite.
76
+ *
77
+ * A type tag built from an overflowing literal (`Maximum<1e400>`) carries an
78
+ * infinite bound (#2452). `-Infinity` below or `Infinity` above excludes no
79
+ * finite number, so it is no bound at all; `Infinity` below or `-Infinity`
80
+ * above excludes every finite number, so no value can be generated.
81
+ */
82
+ const boundary = (
83
+ value: number | undefined,
84
+ exclusive: boolean,
85
+ side: "lower" | "upper",
86
+ ): IBoundary | null => {
87
+ if (value === undefined) return null;
88
+ if (Number.isFinite(value)) return { value, exclusive };
89
+ if (value === (side === "lower" ? -Infinity : Infinity)) return null;
90
+ throw new Error("Numeric range has no finite value.");
91
+ };
92
+
82
93
  const selectBoundary = (
83
94
  x: IBoundary | null,
84
95
  y: IBoundary | null,