ts-fortress 2.2.0 → 2.2.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 (128) hide show
  1. package/README.md +135 -0
  2. package/dist/array/array-of-length.d.mts.map +1 -1
  3. package/dist/array/array-of-length.mjs +8 -6
  4. package/dist/array/array-of-length.mjs.map +1 -1
  5. package/dist/array/array.d.mts.map +1 -1
  6. package/dist/array/array.mjs +8 -6
  7. package/dist/array/array.mjs.map +1 -1
  8. package/dist/array/non-empty-array.d.mts.map +1 -1
  9. package/dist/array/non-empty-array.mjs +8 -6
  10. package/dist/array/non-empty-array.mjs.map +1 -1
  11. package/dist/array/tuple.d.mts.map +1 -1
  12. package/dist/array/tuple.mjs +8 -6
  13. package/dist/array/tuple.mjs.map +1 -1
  14. package/dist/compose/intersection.d.mts.map +1 -1
  15. package/dist/compose/intersection.mjs +10 -10
  16. package/dist/compose/intersection.mjs.map +1 -1
  17. package/dist/compose/merge-records.d.mts.map +1 -1
  18. package/dist/compose/merge-records.mjs +10 -10
  19. package/dist/compose/merge-records.mjs.map +1 -1
  20. package/dist/compose/union.d.mts.map +1 -1
  21. package/dist/compose/union.mjs.map +1 -1
  22. package/dist/enum/enum.d.mts.map +1 -1
  23. package/dist/enum/enum.mjs.map +1 -1
  24. package/dist/enum/uint-range.d.mts.map +1 -1
  25. package/dist/enum/uint-range.mjs.map +1 -1
  26. package/dist/index.d.mts +0 -1
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +1 -1
  29. package/dist/record/key-value-record.d.mts.map +1 -1
  30. package/dist/record/key-value-record.mjs +21 -24
  31. package/dist/record/key-value-record.mjs.map +1 -1
  32. package/dist/record/omit.d.mts.map +1 -1
  33. package/dist/record/omit.mjs +3 -2
  34. package/dist/record/omit.mjs.map +1 -1
  35. package/dist/record/partial.d.mts.map +1 -1
  36. package/dist/record/partial.mjs +2 -2
  37. package/dist/record/partial.mjs.map +1 -1
  38. package/dist/record/pick.d.mts.map +1 -1
  39. package/dist/record/pick.mjs +2 -2
  40. package/dist/record/pick.mjs.map +1 -1
  41. package/dist/record/record.d.mts +6 -2
  42. package/dist/record/record.d.mts.map +1 -1
  43. package/dist/record/record.mjs +23 -21
  44. package/dist/record/record.mjs.map +1 -1
  45. package/dist/type.d.mts +1 -1
  46. package/dist/type.d.mts.map +1 -1
  47. package/dist/utils/create-assert-fn.mjs +1 -1
  48. package/dist/utils/create-cast-fn.mjs +1 -1
  49. package/dist/utils/create-primitive-type.mjs +1 -1
  50. package/dist/utils/index.d.mts +1 -0
  51. package/dist/utils/index.d.mts.map +1 -1
  52. package/dist/utils/index.mjs +1 -0
  53. package/dist/utils/index.mjs.map +1 -1
  54. package/dist/utils/validation-error.d.mts.map +1 -0
  55. package/dist/utils/validation-error.mjs.map +1 -0
  56. package/package.json +4 -2
  57. package/src/array/array-of-length.mts +12 -7
  58. package/src/array/array-of-length.test.mts +10 -1
  59. package/src/array/array.mts +12 -7
  60. package/src/array/array.test.mts +10 -1
  61. package/src/array/non-empty-array.mts +11 -7
  62. package/src/array/non-empty-array.test.mts +10 -1
  63. package/src/array/tuple.mts +11 -9
  64. package/src/array/tuple.test.mts +14 -1
  65. package/src/branded/brand.mts +2 -2
  66. package/src/branded/number/finite-number.test.mts +10 -1
  67. package/src/branded/number/int.test.mts +10 -1
  68. package/src/branded/number/int16.test.mts +10 -1
  69. package/src/branded/number/int32.test.mts +10 -1
  70. package/src/branded/number/non-negative-finite-number.test.mts +10 -1
  71. package/src/branded/number/non-zero-finite-number.test.mts +10 -1
  72. package/src/branded/number/non-zero-int.test.mts +10 -1
  73. package/src/branded/number/non-zero-safe-int.test.mts +10 -1
  74. package/src/branded/number/positive-finite-number.test.mts +10 -1
  75. package/src/branded/number/positive-int.test.mts +10 -1
  76. package/src/branded/number/positive-safe-int.test.mts +10 -1
  77. package/src/branded/number/safe-int.test.mts +10 -1
  78. package/src/branded/number/safe-uint.test.mts +10 -1
  79. package/src/branded/number/uint.test.mts +10 -1
  80. package/src/branded/number/uint16.test.mts +10 -1
  81. package/src/branded/number/uint32.test.mts +10 -1
  82. package/src/branded/simple-branded-number.test.mts +19 -1
  83. package/src/branded/simple-branded-string.test.mts +19 -1
  84. package/src/compose/intersection.mts +23 -19
  85. package/src/compose/intersection.test.mts +28 -1
  86. package/src/compose/merge-records.mts +22 -19
  87. package/src/compose/merge-records.test.mts +10 -1
  88. package/src/compose/union.mts +6 -2
  89. package/src/compose/union.test.mts +10 -1
  90. package/src/enum/enum.mts +6 -2
  91. package/src/enum/enum.test.mts +10 -1
  92. package/src/enum/uint-range.mts +6 -2
  93. package/src/enum/uint-range.test.mts +10 -1
  94. package/src/index.mts +0 -1
  95. package/src/primitives/bigint.test.mts +19 -1
  96. package/src/primitives/boolean.test.mts +28 -1
  97. package/src/primitives/null.test.mts +9 -0
  98. package/src/primitives/number.test.mts +18 -0
  99. package/src/primitives/string.test.mts +18 -0
  100. package/src/primitives/symbol.test.mts +10 -1
  101. package/src/primitives/undefined.test.mts +9 -0
  102. package/src/record/key-value-record.mts +34 -36
  103. package/src/record/key-value-record.test.mts +14 -1
  104. package/src/record/keyof.test.mts +10 -1
  105. package/src/record/omit.mts +8 -5
  106. package/src/record/omit.test.mts +46 -1
  107. package/src/record/partial.mts +7 -5
  108. package/src/record/partial.test.mts +71 -1
  109. package/src/record/pick.mts +7 -5
  110. package/src/record/pick.test.mts +46 -1
  111. package/src/record/record-allow-excess-properties.test.mts +28 -1
  112. package/src/record/record-strict-composition-simple.test.mts +38 -0
  113. package/src/record/record-strict-composition.test.mts +71 -0
  114. package/src/record/record.mts +50 -36
  115. package/src/record/record.test.mts +26 -1
  116. package/src/record/strict-record.test.mts +10 -1
  117. package/src/type.mts +1 -1
  118. package/src/utils/create-assert-fn.mts +1 -1
  119. package/src/utils/create-cast-fn.mts +1 -1
  120. package/src/utils/create-primitive-type.mts +1 -1
  121. package/src/utils/index.mts +1 -0
  122. package/dist/validation-error.d.mts.map +0 -1
  123. package/dist/validation-error.mjs.map +0 -1
  124. package/src/combination.test.mts +0 -544
  125. /package/dist/{validation-error.d.mts → utils/validation-error.d.mts} +0 -0
  126. /package/dist/{validation-error.mjs → utils/validation-error.mjs} +0 -0
  127. /package/src/{validation-error.mts → utils/validation-error.mts} +0 -0
  128. /package/src/{validation-error.test.mts → utils/validation-error.test.mts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { asInt, expectType, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { int } from './int.mjs';
5
5
 
6
6
  describe('int', () => {
@@ -102,6 +102,15 @@ describe('int', () => {
102
102
  ]);
103
103
  }
104
104
  });
105
+
106
+ test('validate returns input as-is for OK cases', () => {
107
+ const input = 123;
108
+ const result = targetType.validate(input);
109
+ expect(Result.isOk(result)).toBe(true);
110
+ if (Result.isOk(result)) {
111
+ expect(result.value).toBe(input); // ✅ same reference
112
+ }
113
+ });
105
114
  });
106
115
 
107
116
  describe('assertIs', () => {
@@ -1,6 +1,6 @@
1
1
  import { asInt16, expectType, isInt16, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { int16 } from './int16.mjs';
5
5
 
6
6
  describe('int16', () => {
@@ -61,6 +61,15 @@ describe('int16', () => {
61
61
  }
62
62
  });
63
63
 
64
+ test('validate returns input as-is for OK cases', () => {
65
+ const input = 15000;
66
+ const result = targetType.validate(input);
67
+ expect(Result.isOk(result)).toBe(true);
68
+ if (Result.isOk(result)) {
69
+ expect(result.value).toBe(input); // ✅ same reference
70
+ }
71
+ });
72
+
64
73
  test('falsy case - out of range', () => {
65
74
  const result = targetType.validate(50000);
66
75
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asInt32, expectType, isInt32, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { int32 } from './int32.mjs';
5
5
 
6
6
  describe('int32', () => {
@@ -55,6 +55,15 @@ describe('int32', () => {
55
55
  }
56
56
  });
57
57
 
58
+ test('validate returns input as-is for OK cases', () => {
59
+ const input = 1000000;
60
+ const result = targetType.validate(input);
61
+ expect(Result.isOk(result)).toBe(true);
62
+ if (Result.isOk(result)) {
63
+ expect(result.value).toBe(input); // ✅ same reference
64
+ }
65
+ });
66
+
58
67
  test('falsy case - out of range', () => {
59
68
  const result = targetType.validate(3000000000);
60
69
  expect(Result.isErr(result)).toBe(true);
@@ -5,7 +5,7 @@ import {
5
5
  Result,
6
6
  } from 'ts-data-forge';
7
7
  import { type TypeOf } from '../../type.mjs';
8
- import { validationErrorsToMessages } from '../../validation-error.mjs';
8
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
9
9
  import { nonNegativeFiniteNumber } from './non-negative-finite-number.mjs';
10
10
 
11
11
  describe('nonNegativeFiniteNumber', () => {
@@ -72,6 +72,15 @@ describe('nonNegativeFiniteNumber', () => {
72
72
  }
73
73
  });
74
74
 
75
+ test('validate returns input as-is for OK cases', () => {
76
+ const input = 123.456;
77
+ const result = targetType.validate(input);
78
+ expect(Result.isOk(result)).toBe(true);
79
+ if (Result.isOk(result)) {
80
+ expect(result.value).toBe(input); // ✅ same reference
81
+ }
82
+ });
83
+
75
84
  test('falsy case - negative', () => {
76
85
  const result = targetType.validate(-5.5);
77
86
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { expectType, isNonZeroFiniteNumber, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { nonZeroFiniteNumber } from './non-zero-finite-number.mjs';
5
5
 
6
6
  describe('nonZeroFiniteNumber', () => {
@@ -68,6 +68,15 @@ describe('nonZeroFiniteNumber', () => {
68
68
  }
69
69
  });
70
70
 
71
+ test('validate returns input as-is for OK cases', () => {
72
+ const input = 123.456;
73
+ const result = targetType.validate(input);
74
+ expect(Result.isOk(result)).toBe(true);
75
+ if (Result.isOk(result)) {
76
+ expect(result.value).toBe(input); // ✅ same reference
77
+ }
78
+ });
79
+
71
80
  test('falsy case - zero', () => {
72
81
  const result = targetType.validate(0);
73
82
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asNonZeroInt, expectType, isNonZeroInt, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { nonZeroInt } from './non-zero-int.mjs';
5
5
 
6
6
  describe('nonZeroInt', () => {
@@ -61,6 +61,15 @@ describe('nonZeroInt', () => {
61
61
  }
62
62
  });
63
63
 
64
+ test('validate returns input as-is for OK cases', () => {
65
+ const input = 123;
66
+ const result = targetType.validate(input);
67
+ expect(Result.isOk(result)).toBe(true);
68
+ if (Result.isOk(result)) {
69
+ expect(result.value).toBe(input); // ✅ same reference
70
+ }
71
+ });
72
+
64
73
  test('falsy case - zero', () => {
65
74
  const result = targetType.validate(0);
66
75
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { expectType, isNonZeroSafeInt, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { nonZeroSafeInt } from './non-zero-safe-int.mjs';
5
5
 
6
6
  describe('nonZeroSafeInt', () => {
@@ -68,6 +68,15 @@ describe('nonZeroSafeInt', () => {
68
68
  }
69
69
  });
70
70
 
71
+ test('validate returns input as-is for OK cases', () => {
72
+ const input = 123;
73
+ const result = targetType.validate(input);
74
+ expect(Result.isOk(result)).toBe(true);
75
+ if (Result.isOk(result)) {
76
+ expect(result.value).toBe(input); // ✅ same reference
77
+ }
78
+ });
79
+
71
80
  test('falsy case - zero', () => {
72
81
  const result = targetType.validate(0);
73
82
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { expectType, isPositiveFiniteNumber, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { positiveFiniteNumber } from './positive-finite-number.mjs';
5
5
 
6
6
  describe('positiveFiniteNumber', () => {
@@ -68,6 +68,15 @@ describe('positiveFiniteNumber', () => {
68
68
  }
69
69
  });
70
70
 
71
+ test('validate returns input as-is for OK cases', () => {
72
+ const input = 123.456;
73
+ const result = targetType.validate(input);
74
+ expect(Result.isOk(result)).toBe(true);
75
+ if (Result.isOk(result)) {
76
+ expect(result.value).toBe(input); // ✅ same reference
77
+ }
78
+ });
79
+
71
80
  test('falsy case - zero', () => {
72
81
  const result = targetType.validate(0);
73
82
  expect(Result.isErr(result)).toBe(true);
@@ -5,7 +5,7 @@ import {
5
5
  Result,
6
6
  } from 'ts-data-forge';
7
7
  import { type TypeOf } from '../../type.mjs';
8
- import { validationErrorsToMessages } from '../../validation-error.mjs';
8
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
9
9
  import { positiveInt } from './positive-int.mjs';
10
10
 
11
11
  describe('positiveInt', () => {
@@ -78,6 +78,15 @@ describe('positiveInt', () => {
78
78
  }
79
79
  });
80
80
 
81
+ test('validate returns input as-is for OK cases', () => {
82
+ const input = 123;
83
+ const result = targetType.validate(input);
84
+ expect(Result.isOk(result)).toBe(true);
85
+ if (Result.isOk(result)) {
86
+ expect(result.value).toBe(input); // ✅ same reference
87
+ }
88
+ });
89
+
81
90
  test('falsy case - negative', () => {
82
91
  const result = targetType.validate(-5);
83
92
  expect(Result.isErr(result)).toBe(true);
@@ -5,7 +5,7 @@ import {
5
5
  Result,
6
6
  } from 'ts-data-forge';
7
7
  import { type TypeOf } from '../../type.mjs';
8
- import { validationErrorsToMessages } from '../../validation-error.mjs';
8
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
9
9
  import { positiveSafeInt } from './positive-safe-int.mjs';
10
10
 
11
11
  describe('positiveSafeInt', () => {
@@ -72,6 +72,15 @@ describe('positiveSafeInt', () => {
72
72
  }
73
73
  });
74
74
 
75
+ test('validate returns input as-is for OK cases', () => {
76
+ const input = 123456;
77
+ const result = targetType.validate(input);
78
+ expect(Result.isOk(result)).toBe(true);
79
+ if (Result.isOk(result)) {
80
+ expect(result.value).toBe(input); // ✅ same reference
81
+ }
82
+ });
83
+
75
84
  test('falsy case - zero', () => {
76
85
  const result = targetType.validate(0);
77
86
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asSafeInt, expectType, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { safeInt } from './safe-int.mjs';
5
5
 
6
6
  describe('safeInt', () => {
@@ -60,6 +60,15 @@ describe('safeInt', () => {
60
60
  }
61
61
  });
62
62
 
63
+ test('validate returns input as-is for OK cases', () => {
64
+ const input = 123;
65
+ const result = targetType.validate(input);
66
+ expect(Result.isOk(result)).toBe(true);
67
+ if (Result.isOk(result)) {
68
+ expect(result.value).toBe(input); // ✅ same reference
69
+ }
70
+ });
71
+
63
72
  test('falsy case - unsafe integer', () => {
64
73
  const result = targetType.validate(Number.MAX_SAFE_INTEGER + 1);
65
74
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asSafeUint, expectType, isSafeUint, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { safeUint } from './safe-uint.mjs';
5
5
 
6
6
  describe('safeUint', () => {
@@ -67,6 +67,15 @@ describe('safeUint', () => {
67
67
  }
68
68
  });
69
69
 
70
+ test('validate returns input as-is for OK cases', () => {
71
+ const input = 123456;
72
+ const result = targetType.validate(input);
73
+ expect(Result.isOk(result)).toBe(true);
74
+ if (Result.isOk(result)) {
75
+ expect(result.value).toBe(input); // ✅ same reference
76
+ }
77
+ });
78
+
70
79
  test('falsy case - negative', () => {
71
80
  const result = targetType.validate(-5);
72
81
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asUint, expectType, isUint, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { uint } from './uint.mjs';
5
5
 
6
6
  describe('uint', () => {
@@ -73,6 +73,15 @@ describe('uint', () => {
73
73
  }
74
74
  });
75
75
 
76
+ test('validate returns input as-is for OK cases', () => {
77
+ const input = 123;
78
+ const result = targetType.validate(input);
79
+ expect(Result.isOk(result)).toBe(true);
80
+ if (Result.isOk(result)) {
81
+ expect(result.value).toBe(input); // ✅ same reference
82
+ }
83
+ });
84
+
76
85
  test('falsy case - negative', () => {
77
86
  const result = targetType.validate(-5);
78
87
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asUint16, expectType, isUint16, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { uint16 } from './uint16.mjs';
5
5
 
6
6
  describe('uint16', () => {
@@ -67,6 +67,15 @@ describe('uint16', () => {
67
67
  }
68
68
  });
69
69
 
70
+ test('validate returns input as-is for OK cases', () => {
71
+ const input = 30000;
72
+ const result = targetType.validate(input);
73
+ expect(Result.isOk(result)).toBe(true);
74
+ if (Result.isOk(result)) {
75
+ expect(result.value).toBe(input); // ✅ same reference
76
+ }
77
+ });
78
+
70
79
  test('falsy case - negative', () => {
71
80
  const result = targetType.validate(-5);
72
81
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { asUint32, expectType, isUint32, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../../type.mjs';
3
- import { validationErrorsToMessages } from '../../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../../utils/index.mjs';
4
4
  import { uint32 } from './uint32.mjs';
5
5
 
6
6
  describe('uint32', () => {
@@ -67,6 +67,15 @@ describe('uint32', () => {
67
67
  }
68
68
  });
69
69
 
70
+ test('validate returns input as-is for OK cases', () => {
71
+ const input = 2000000000;
72
+ const result = targetType.validate(input);
73
+ expect(Result.isOk(result)).toBe(true);
74
+ if (Result.isOk(result)) {
75
+ expect(result.value).toBe(input); // ✅ same reference
76
+ }
77
+ });
78
+
70
79
  test('falsy case - negative', () => {
71
80
  const result = targetType.validate(-5);
72
81
  expect(Result.isErr(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { expectType, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../type.mjs';
3
- import { validationErrorsToMessages } from '../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../utils/index.mjs';
4
4
  import { simpleBrandedNumber } from './simple-branded-number.mjs';
5
5
 
6
6
  describe('simpleBrandedNumber', () => {
@@ -36,6 +36,15 @@ describe('simpleBrandedNumber', () => {
36
36
  });
37
37
 
38
38
  describe('validate', () => {
39
+ test('validate returns input as-is for OK cases', () => {
40
+ const input = 42;
41
+ const result = userIdType.validate(input);
42
+ expect(Result.isOk(result)).toBe(true);
43
+ if (Result.isOk(result)) {
44
+ expect(result.value).toBe(input); // ✅ same reference
45
+ }
46
+ });
47
+
39
48
  test('succeeds for valid numbers', () => {
40
49
  const result = userIdType.validate(42);
41
50
  expect(Result.isOk(result)).toBe(true);
@@ -100,6 +109,15 @@ describe('simpleBrandedNumber', () => {
100
109
  });
101
110
 
102
111
  describe('validate', () => {
112
+ test('validate returns input as-is for OK cases', () => {
113
+ const input = 85;
114
+ const result = scoreType.validate(input);
115
+ expect(Result.isOk(result)).toBe(true);
116
+ if (Result.isOk(result)) {
117
+ expect(result.value).toBe(input); // ✅ same reference
118
+ }
119
+ });
120
+
103
121
  test('succeeds for valid numbers', () => {
104
122
  const result = scoreType.validate(85);
105
123
  expect(Result.isOk(result)).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import { expectType, Result } from 'ts-data-forge';
2
2
  import { type TypeOf } from '../type.mjs';
3
- import { validationErrorsToMessages } from '../validation-error.mjs';
3
+ import { validationErrorsToMessages } from '../utils/index.mjs';
4
4
  import { simpleBrandedString } from './simple-branded-string.mjs';
5
5
 
6
6
  describe('simpleBrandedString', () => {
@@ -37,6 +37,15 @@ describe('simpleBrandedString', () => {
37
37
  });
38
38
 
39
39
  describe('validate', () => {
40
+ test('validate returns input as-is for OK cases', () => {
41
+ const input = 'john_doe';
42
+ const result = userNameType.validate(input);
43
+ expect(Result.isOk(result)).toBe(true);
44
+ if (Result.isOk(result)) {
45
+ expect(result.value).toBe(input); // ✅ same reference
46
+ }
47
+ });
48
+
40
49
  test('succeeds for valid strings', () => {
41
50
  const result = userNameType.validate('john_doe');
42
51
  expect(Result.isOk(result)).toBe(true);
@@ -101,6 +110,15 @@ describe('simpleBrandedString', () => {
101
110
  });
102
111
 
103
112
  describe('validate', () => {
113
+ test('validate returns input as-is for OK cases', () => {
114
+ const input = 'technology';
115
+ const result = categoryType.validate(input);
116
+ expect(Result.isOk(result)).toBe(true);
117
+ if (Result.isOk(result)) {
118
+ expect(result.value).toBe(input); // ✅ same reference
119
+ }
120
+ });
121
+
104
122
  test('succeeds for valid strings', () => {
105
123
  const result = categoryType.validate('technology');
106
124
  expect(Result.isOk(result)).toBe(true);
@@ -1,10 +1,12 @@
1
- import { expectType, Result } from 'ts-data-forge';
1
+ import { Arr, expectType, Result } from 'ts-data-forge';
2
2
  import { type Type, type TypeOf } from '../type.mjs';
3
- import { createAssertFn, createCastFn, createIsFn } from '../utils/index.mjs';
4
3
  import {
4
+ createAssertFn,
5
+ createCastFn,
6
+ createIsFn,
5
7
  type ValidationError,
6
8
  type ValidationErrorWithMessage,
7
- } from '../validation-error.mjs';
9
+ } from '../utils/index.mjs';
8
10
 
9
11
  export const intersection = <const Types extends NonEmptyArray<Type<unknown>>>(
10
12
  types: Types,
@@ -22,22 +24,24 @@ export const intersection = <const Types extends NonEmptyArray<Type<unknown>>>(
22
24
  `Intersection<${types.map((a) => a.typeName).join(', ')}>`;
23
25
 
24
26
  const validate: Type<T>['validate'] = (a) => {
25
- const errors: readonly ValidationError[] = types.flatMap((type) => {
26
- const r = type.validate(a);
27
- return Result.isErr(r)
28
- ? [
29
- {
30
- path: [],
31
- actualValue: a,
32
- expectedType: typeNameFilled,
33
- message: `The type of value is expected to match all types of { ${types
34
- .map((t) => t.typeName)
35
- .join(', ')} }`,
36
- typeName: typeNameFilled,
37
- } satisfies ValidationErrorWithMessage,
38
- ...r.value,
39
- ]
40
- : [];
27
+ const errors: readonly ValidationError[] = Arr.generate(function* () {
28
+ for (const type of types) {
29
+ const res = type.validate(a);
30
+
31
+ if (Result.isErr(res)) {
32
+ yield {
33
+ path: [],
34
+ actualValue: a,
35
+ expectedType: typeNameFilled,
36
+ message: `The type of value is expected to match all types of { ${types
37
+ .map((t) => t.typeName)
38
+ .join(', ')} }`,
39
+ typeName: typeNameFilled,
40
+ } satisfies ValidationErrorWithMessage;
41
+
42
+ yield* res.value;
43
+ }
44
+ }
41
45
  });
42
46
 
43
47
  if (errors.length > 0) {
@@ -6,7 +6,7 @@ import { type TypeOf } from '../type.mjs';
6
6
  import {
7
7
  type ValidationError,
8
8
  validationErrorsToMessages,
9
- } from '../validation-error.mjs';
9
+ } from '../utils/index.mjs';
10
10
  import { intersection } from './intersection.mjs';
11
11
 
12
12
  describe('intersection', () => {
@@ -90,6 +90,15 @@ describe('intersection', () => {
90
90
  }
91
91
  });
92
92
 
93
+ test('validate returns input as-is for OK cases', () => {
94
+ const input = { x: 0, y: 1, z: 2, w: 3 };
95
+ const result = targetType.validate(input);
96
+ expect(Result.isOk(result)).toBe(true);
97
+ if (Result.isOk(result)) {
98
+ expect(result.value).toBe(input); // ✅ same reference
99
+ }
100
+ });
101
+
93
102
  test('falsy case', () => {
94
103
  const result = targetType.validate({ x: 0, y: 1 });
95
104
  expect(Result.isErr(result)).toBe(true);
@@ -194,6 +203,15 @@ describe('intersection', () => {
194
203
  }
195
204
  });
196
205
 
206
+ test('validate returns input as-is for OK cases', () => {
207
+ const input = 0;
208
+ const result = targetType.validate(input);
209
+ expect(Result.isOk(result)).toBe(true);
210
+ if (Result.isOk(result)) {
211
+ expect(result.value).toBe(input); // ✅ same reference
212
+ }
213
+ });
214
+
197
215
  test('falsy case', () => {
198
216
  const result = targetType.validate('aaa');
199
217
  expect(Result.isErr(result)).toBe(true);
@@ -320,6 +338,15 @@ describe('intersection', () => {
320
338
  }
321
339
  });
322
340
 
341
+ test('validate returns input as-is for OK cases', () => {
342
+ const input = 3;
343
+ const result = targetType.validate(input);
344
+ expect(Result.isOk(result)).toBe(true);
345
+ if (Result.isOk(result)) {
346
+ expect(result.value).toBe(input); // ✅ same reference
347
+ }
348
+ });
349
+
323
350
  test('falsy case', () => {
324
351
  const result = targetType.validate(7);
325
352
  expect(Result.isErr(result)).toBe(true);
@@ -1,10 +1,12 @@
1
- import { expectType, isRecord, Result } from 'ts-data-forge';
1
+ import { Arr, expectType, isRecord, Result } from 'ts-data-forge';
2
2
  import { type Type, type TypeOf } from '../type.mjs';
3
- import { createAssertFn, createCastFn, createIsFn } from '../utils/index.mjs';
4
3
  import {
4
+ createAssertFn,
5
+ createCastFn,
6
+ createIsFn,
5
7
  type ValidationError,
6
8
  type ValidationErrorWithMessage,
7
- } from '../validation-error.mjs';
9
+ } from '../utils/index.mjs';
8
10
 
9
11
  export const mergeRecords = <
10
12
  const Types extends NonEmptyArray<Type<UnknownRecord>>,
@@ -24,22 +26,23 @@ export const mergeRecords = <
24
26
  `Intersection<${types.map((a) => a.typeName).join(', ')}>`;
25
27
 
26
28
  const validate: Type<T>['validate'] = (a) => {
27
- const errors: readonly ValidationError[] = types.flatMap((type) => {
28
- const r = type.validate(a);
29
- return Result.isErr(r)
30
- ? [
31
- {
32
- path: [],
33
- actualValue: a,
34
- expectedType: typeNameFilled,
35
- message: `The type of value is expected to match all types of { ${types
36
- .map((t) => t.typeName)
37
- .join(', ')} }`,
38
- typeName: typeNameFilled,
39
- } satisfies ValidationErrorWithMessage,
40
- ...r.value,
41
- ]
42
- : [];
29
+ const errors: readonly ValidationError[] = Arr.generate(function* () {
30
+ for (const type of types) {
31
+ const res = type.validate(a);
32
+ if (Result.isErr(res)) {
33
+ yield {
34
+ path: [],
35
+ actualValue: a,
36
+ expectedType: typeNameFilled,
37
+ message: `The type of value is expected to match all types of { ${types
38
+ .map((t) => t.typeName)
39
+ .join(', ')} }`,
40
+ typeName: typeNameFilled,
41
+ } satisfies ValidationErrorWithMessage;
42
+
43
+ yield* res.value;
44
+ }
45
+ }
43
46
  });
44
47
 
45
48
  if (errors.length > 0) {
@@ -5,7 +5,7 @@ import { type TypeOf } from '../type.mjs';
5
5
  import {
6
6
  type ValidationError,
7
7
  validationErrorsToMessages,
8
- } from '../validation-error.mjs';
8
+ } from '../utils/index.mjs';
9
9
  import { mergeRecords } from './merge-records.mjs';
10
10
 
11
11
  describe('mergeRecords', () => {
@@ -82,6 +82,15 @@ describe('mergeRecords', () => {
82
82
  }
83
83
  });
84
84
 
85
+ test('validate returns input as-is for OK cases', () => {
86
+ const input = { x: 0, y: 1, z: 2, w: 3 };
87
+ const result = targetType.validate(input);
88
+ expect(Result.isOk(result)).toBe(true);
89
+ if (Result.isOk(result)) {
90
+ expect(result.value).toBe(input); // ✅ same reference
91
+ }
92
+ });
93
+
85
94
  test('falsy case', () => {
86
95
  const result = targetType.validate({ x: 0, y: 1 });
87
96
  expect(Result.isErr(result)).toBe(true);
@@ -1,7 +1,11 @@
1
1
  import { Result, expectType } from 'ts-data-forge';
2
2
  import { type Type, type TypeOf } from '../type.mjs';
3
- import { createAssertFn, createCastFn, createIsFn } from '../utils/index.mjs';
4
- import { type ValidationErrorWithMessage } from '../validation-error.mjs';
3
+ import {
4
+ createAssertFn,
5
+ createCastFn,
6
+ createIsFn,
7
+ type ValidationErrorWithMessage,
8
+ } from '../utils/index.mjs';
5
9
 
6
10
  export const union = <const Types extends NonEmptyArray<Type<unknown>>>(
7
11
  types: Types,