@kravc/schema 2.7.5 → 2.8.0-alpha.0

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 (170) hide show
  1. package/README.md +19 -14
  2. package/dist/CredentialFactory.d.ts +345 -0
  3. package/dist/CredentialFactory.d.ts.map +1 -0
  4. package/dist/CredentialFactory.js +381 -0
  5. package/dist/CredentialFactory.js.map +1 -0
  6. package/dist/Schema.d.ts +448 -0
  7. package/dist/Schema.d.ts.map +1 -0
  8. package/dist/Schema.js +506 -0
  9. package/dist/Schema.js.map +1 -0
  10. package/dist/ValidationError.d.ts +70 -0
  11. package/dist/ValidationError.d.ts.map +1 -0
  12. package/dist/ValidationError.js +78 -0
  13. package/dist/ValidationError.js.map +1 -0
  14. package/dist/Validator.d.ts +483 -0
  15. package/dist/Validator.d.ts.map +1 -0
  16. package/dist/Validator.js +570 -0
  17. package/dist/Validator.js.map +1 -0
  18. package/dist/helpers/JsonSchema.d.ts +99 -0
  19. package/dist/helpers/JsonSchema.d.ts.map +1 -0
  20. package/dist/helpers/JsonSchema.js +3 -0
  21. package/dist/helpers/JsonSchema.js.map +1 -0
  22. package/dist/helpers/cleanupAttributes.d.ts +34 -0
  23. package/dist/helpers/cleanupAttributes.d.ts.map +1 -0
  24. package/dist/helpers/cleanupAttributes.js +113 -0
  25. package/dist/helpers/cleanupAttributes.js.map +1 -0
  26. package/dist/helpers/cleanupNulls.d.ts +27 -0
  27. package/dist/helpers/cleanupNulls.d.ts.map +1 -0
  28. package/dist/helpers/cleanupNulls.js +96 -0
  29. package/dist/helpers/cleanupNulls.js.map +1 -0
  30. package/dist/helpers/getReferenceIds.d.ts +169 -0
  31. package/dist/helpers/getReferenceIds.d.ts.map +1 -0
  32. package/dist/helpers/getReferenceIds.js +241 -0
  33. package/dist/helpers/getReferenceIds.js.map +1 -0
  34. package/dist/helpers/got.d.ts +60 -0
  35. package/dist/helpers/got.d.ts.map +1 -0
  36. package/dist/helpers/got.js +72 -0
  37. package/dist/helpers/got.js.map +1 -0
  38. package/dist/helpers/mapObjectProperties.d.ts +150 -0
  39. package/dist/helpers/mapObjectProperties.d.ts.map +1 -0
  40. package/dist/helpers/mapObjectProperties.js +229 -0
  41. package/dist/helpers/mapObjectProperties.js.map +1 -0
  42. package/dist/helpers/normalizeAttributes.d.ts +213 -0
  43. package/dist/helpers/normalizeAttributes.d.ts.map +1 -0
  44. package/dist/helpers/normalizeAttributes.js +243 -0
  45. package/dist/helpers/normalizeAttributes.js.map +1 -0
  46. package/dist/helpers/normalizeProperties.d.ts +168 -0
  47. package/dist/helpers/normalizeProperties.d.ts.map +1 -0
  48. package/dist/helpers/normalizeProperties.js +223 -0
  49. package/dist/helpers/normalizeProperties.js.map +1 -0
  50. package/dist/helpers/normalizeRequired.d.ts +159 -0
  51. package/dist/helpers/normalizeRequired.d.ts.map +1 -0
  52. package/dist/helpers/normalizeRequired.js +206 -0
  53. package/dist/helpers/normalizeRequired.js.map +1 -0
  54. package/dist/helpers/normalizeType.d.ts +81 -0
  55. package/dist/helpers/normalizeType.d.ts.map +1 -0
  56. package/dist/helpers/normalizeType.js +210 -0
  57. package/dist/helpers/normalizeType.js.map +1 -0
  58. package/dist/helpers/nullifyEmptyValues.d.ts +139 -0
  59. package/dist/helpers/nullifyEmptyValues.d.ts.map +1 -0
  60. package/dist/helpers/nullifyEmptyValues.js +191 -0
  61. package/dist/helpers/nullifyEmptyValues.js.map +1 -0
  62. package/dist/helpers/removeRequiredAndDefault.d.ts +106 -0
  63. package/dist/helpers/removeRequiredAndDefault.d.ts.map +1 -0
  64. package/dist/helpers/removeRequiredAndDefault.js +138 -0
  65. package/dist/helpers/removeRequiredAndDefault.js.map +1 -0
  66. package/dist/helpers/validateId.d.ts +39 -0
  67. package/dist/helpers/validateId.d.ts.map +1 -0
  68. package/dist/helpers/validateId.js +51 -0
  69. package/dist/helpers/validateId.js.map +1 -0
  70. package/dist/index.d.ts +7 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +17 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/ld/documentLoader.d.ts +8 -0
  75. package/dist/ld/documentLoader.d.ts.map +1 -0
  76. package/dist/ld/documentLoader.js +24 -0
  77. package/dist/ld/documentLoader.js.map +1 -0
  78. package/dist/ld/getLinkedDataAttributeType.d.ts +10 -0
  79. package/dist/ld/getLinkedDataAttributeType.d.ts.map +1 -0
  80. package/dist/ld/getLinkedDataAttributeType.js +32 -0
  81. package/dist/ld/getLinkedDataAttributeType.js.map +1 -0
  82. package/dist/ld/getLinkedDataContext.d.ts +19 -0
  83. package/dist/ld/getLinkedDataContext.d.ts.map +1 -0
  84. package/dist/ld/getLinkedDataContext.js +50 -0
  85. package/dist/ld/getLinkedDataContext.js.map +1 -0
  86. package/eslint.config.mjs +32 -52
  87. package/examples/credentials/createAccountCredential.ts +27 -0
  88. package/examples/credentials/createMineSweeperScoreCredential.ts +115 -0
  89. package/examples/index.ts +7 -0
  90. package/examples/schemas/FavoriteItemSchema.ts +27 -0
  91. package/examples/{Preferences.yaml → schemas/Preferences.yaml} +2 -0
  92. package/examples/schemas/PreferencesSchema.ts +29 -0
  93. package/examples/schemas/ProfileSchema.ts +91 -0
  94. package/examples/schemas/Status.yaml +3 -0
  95. package/examples/schemas/StatusSchema.ts +12 -0
  96. package/jest.config.mjs +5 -0
  97. package/package.json +28 -21
  98. package/src/CredentialFactory.ts +392 -0
  99. package/src/Schema.ts +583 -0
  100. package/src/ValidationError.ts +90 -0
  101. package/src/Validator.ts +603 -0
  102. package/src/__tests__/CredentialFactory.test.ts +588 -0
  103. package/src/__tests__/Schema.test.ts +371 -0
  104. package/src/__tests__/ValidationError.test.ts +235 -0
  105. package/src/__tests__/Validator.test.ts +787 -0
  106. package/src/helpers/JsonSchema.ts +119 -0
  107. package/src/helpers/__tests__/cleanupAttributes.test.ts +943 -0
  108. package/src/helpers/__tests__/cleanupNulls.test.ts +772 -0
  109. package/src/helpers/__tests__/getReferenceIds.test.ts +975 -0
  110. package/src/helpers/__tests__/got.test.ts +193 -0
  111. package/src/helpers/__tests__/mapObjectProperties.test.ts +1126 -0
  112. package/src/helpers/__tests__/normalizeAttributes.test.ts +1435 -0
  113. package/src/helpers/__tests__/normalizeProperties.test.ts +727 -0
  114. package/src/helpers/__tests__/normalizeRequired.test.ts +669 -0
  115. package/src/helpers/__tests__/normalizeType.test.ts +772 -0
  116. package/src/helpers/__tests__/nullifyEmptyValues.test.ts +735 -0
  117. package/src/helpers/__tests__/removeRequiredAndDefault.test.ts +734 -0
  118. package/src/helpers/__tests__/validateId.test.ts +118 -0
  119. package/src/helpers/cleanupAttributes.ts +151 -0
  120. package/src/helpers/cleanupNulls.ts +106 -0
  121. package/src/helpers/getReferenceIds.ts +273 -0
  122. package/src/helpers/got.ts +73 -0
  123. package/src/helpers/mapObjectProperties.ts +272 -0
  124. package/src/helpers/normalizeAttributes.ts +247 -0
  125. package/src/helpers/normalizeProperties.ts +249 -0
  126. package/src/helpers/normalizeRequired.ts +233 -0
  127. package/src/helpers/normalizeType.ts +235 -0
  128. package/src/helpers/nullifyEmptyValues.ts +207 -0
  129. package/src/helpers/removeRequiredAndDefault.ts +151 -0
  130. package/src/helpers/validateId.ts +53 -0
  131. package/src/index.ts +13 -0
  132. package/src/ld/__tests__/documentLoader.test.ts +57 -0
  133. package/src/ld/__tests__/getLinkedDataAttributeType.test.ts +212 -0
  134. package/src/ld/__tests__/getLinkedDataContext.test.ts +378 -0
  135. package/src/ld/documentLoader.ts +28 -0
  136. package/src/ld/getLinkedDataAttributeType.ts +46 -0
  137. package/src/ld/getLinkedDataContext.ts +80 -0
  138. package/tsconfig.json +27 -0
  139. package/types/credentials-context.d.ts +14 -0
  140. package/types/security-context.d.ts +6 -0
  141. package/examples/Status.yaml +0 -3
  142. package/examples/createAccountCredential.js +0 -27
  143. package/examples/createMineSweeperScoreCredential.js +0 -63
  144. package/examples/index.js +0 -9
  145. package/src/CredentialFactory.js +0 -67
  146. package/src/CredentialFactory.spec.js +0 -131
  147. package/src/Schema.js +0 -104
  148. package/src/Schema.spec.js +0 -172
  149. package/src/ValidationError.js +0 -31
  150. package/src/Validator.js +0 -128
  151. package/src/Validator.spec.js +0 -355
  152. package/src/helpers/cleanupAttributes.js +0 -71
  153. package/src/helpers/cleanupNulls.js +0 -42
  154. package/src/helpers/getReferenceIds.js +0 -71
  155. package/src/helpers/mapObject.js +0 -65
  156. package/src/helpers/normalizeAttributes.js +0 -28
  157. package/src/helpers/normalizeProperties.js +0 -61
  158. package/src/helpers/normalizeRequired.js +0 -37
  159. package/src/helpers/normalizeType.js +0 -41
  160. package/src/helpers/nullifyEmptyValues.js +0 -57
  161. package/src/helpers/removeRequiredAndDefault.js +0 -30
  162. package/src/helpers/validateId.js +0 -19
  163. package/src/index.d.ts +0 -25
  164. package/src/index.js +0 -8
  165. package/src/ld/documentLoader.js +0 -25
  166. package/src/ld/documentLoader.spec.js +0 -12
  167. package/src/ld/getLinkedDataContext.js +0 -63
  168. package/src/ld/getLinkedDataType.js +0 -38
  169. /package/examples/{FavoriteItem.yaml → schemas/FavoriteItem.yaml} +0 -0
  170. /package/examples/{Profile.yaml → schemas/Profile.yaml} +0 -0
@@ -0,0 +1,772 @@
1
+ import normalizeType from '../normalizeType';
2
+
3
+ describe('normalizeType(type, value)', () => {
4
+ describe('number type', () => {
5
+ describe('string to number conversion', () => {
6
+ it('should convert positive integer strings to numbers', () => {
7
+ expect(normalizeType('number', '123')).toBe(123);
8
+ expect(normalizeType('number', '0')).toBe(0);
9
+ expect(normalizeType('number', '999')).toBe(999);
10
+ expect(normalizeType('number', '1000000')).toBe(1000000);
11
+ });
12
+
13
+ it('should convert negative integer strings to numbers', () => {
14
+ expect(normalizeType('number', '-10')).toBe(-10);
15
+ expect(normalizeType('number', '-0')).toBe(-0);
16
+ expect(normalizeType('number', '-999')).toBe(-999);
17
+ });
18
+
19
+ it('should convert decimal strings to numbers', () => {
20
+ expect(normalizeType('number', '45.67')).toBe(45.67);
21
+ expect(normalizeType('number', '0.5')).toBe(0.5);
22
+ expect(normalizeType('number', '-0.5')).toBe(-0.5);
23
+ expect(normalizeType('number', '123.456')).toBe(123.456);
24
+ expect(normalizeType('number', '.5')).toBe(0.5);
25
+ expect(normalizeType('number', '-.5')).toBe(-0.5);
26
+ });
27
+
28
+ it('should convert scientific notation strings to numbers', () => {
29
+ expect(normalizeType('number', '1e2')).toBe(100);
30
+ expect(normalizeType('number', '1e-2')).toBe(0.01);
31
+ expect(normalizeType('number', '1.5e2')).toBe(150);
32
+ expect(normalizeType('number', '-1e2')).toBe(-100);
33
+ });
34
+
35
+ it('should convert special number strings', () => {
36
+ expect(normalizeType('number', 'Infinity')).toBe(Infinity);
37
+ expect(normalizeType('number', '-Infinity')).toBe(-Infinity);
38
+ expect(normalizeType('number', '+Infinity')).toBe(Infinity);
39
+ });
40
+
41
+ it('should convert string numbers with leading/trailing whitespace', () => {
42
+ expect(normalizeType('number', ' 123')).toBe(123);
43
+ expect(normalizeType('number', '123 ')).toBe(123);
44
+ expect(normalizeType('number', ' 123 ')).toBe(123);
45
+ expect(normalizeType('number', '\t123\n')).toBe(123);
46
+ });
47
+ });
48
+
49
+ describe('number preservation', () => {
50
+ it('should keep positive numbers as-is', () => {
51
+ expect(normalizeType('number', 123)).toBe(123);
52
+ expect(normalizeType('number', 45.67)).toBe(45.67);
53
+ expect(normalizeType('number', 0)).toBe(0);
54
+ expect(normalizeType('number', 0.5)).toBe(0.5);
55
+ });
56
+
57
+ it('should keep negative numbers as-is', () => {
58
+ expect(normalizeType('number', -10)).toBe(-10);
59
+ expect(normalizeType('number', -0)).toBe(-0);
60
+ expect(normalizeType('number', -45.67)).toBe(-45.67);
61
+ });
62
+
63
+ it('should keep special number values as-is', () => {
64
+ expect(normalizeType('number', Infinity)).toBe(Infinity);
65
+ expect(normalizeType('number', -Infinity)).toBe(-Infinity);
66
+ expect(normalizeType('number', NaN)).toBeNaN();
67
+ expect(normalizeType('number', Number.MAX_VALUE)).toBe(Number.MAX_VALUE);
68
+ expect(normalizeType('number', Number.MIN_VALUE)).toBe(Number.MIN_VALUE);
69
+ });
70
+ });
71
+
72
+ describe('boolean to number conversion', () => {
73
+ it('should convert boolean true to 1', () => {
74
+ expect(normalizeType('number', true)).toBe(1);
75
+ });
76
+
77
+ it('should convert boolean false to 0', () => {
78
+ expect(normalizeType('number', false)).toBe(0);
79
+ });
80
+ });
81
+
82
+ describe('non-convertible values', () => {
83
+ it('should return original value for invalid string numbers', () => {
84
+ expect(normalizeType('number', 'abc')).toBe('abc');
85
+ expect(normalizeType('number', 'not a number')).toBe('not a number');
86
+ expect(normalizeType('number', '123abc')).toBe('123abc');
87
+ expect(normalizeType('number', 'abc123')).toBe('abc123');
88
+ });
89
+
90
+ it('should preserve empty and whitespace-only strings', () => {
91
+ expect(normalizeType('number', '')).toBe('');
92
+ expect(normalizeType('number', ' ')).toBe(' ');
93
+ expect(normalizeType('number', '\t\n')).toBe('\t\n');
94
+ });
95
+
96
+ it('should preserve null and undefined', () => {
97
+ expect(normalizeType('number', null)).toBe(null);
98
+ expect(normalizeType('number', undefined)).toBe(undefined);
99
+ });
100
+
101
+ it('should preserve objects', () => {
102
+ const obj = { a: 1 };
103
+ expect(normalizeType('number', obj)).toBe(obj);
104
+ expect(normalizeType('number', {})).toEqual({});
105
+ expect(normalizeType('number', { x: 1, y: 2 })).toEqual({ x: 1, y: 2 });
106
+ });
107
+
108
+ it('should preserve arrays', () => {
109
+ const arr = [1, 2, 3];
110
+ expect(normalizeType('number', arr)).toBe(arr);
111
+ expect(normalizeType('number', [])).toEqual([]);
112
+ expect(normalizeType('number', [1, 2, 3])).toEqual([1, 2, 3]);
113
+ });
114
+
115
+ it('should preserve functions', () => {
116
+ /**
117
+ *
118
+ */
119
+ const fn = () => {};
120
+ expect(normalizeType('number', fn)).toBe(fn);
121
+ });
122
+
123
+ it('should preserve symbols', () => {
124
+ const sym = Symbol('test');
125
+ expect(normalizeType('number', sym)).toBe(sym);
126
+ });
127
+
128
+ it('should preserve dates', () => {
129
+ const date = new Date();
130
+ expect(normalizeType('number', date)).toBe(date);
131
+ });
132
+
133
+ it('should preserve regexp', () => {
134
+ const regex = /test/;
135
+ expect(normalizeType('number', regex)).toBe(regex);
136
+ });
137
+ });
138
+ });
139
+
140
+ describe('integer type', () => {
141
+ describe('string to number conversion', () => {
142
+ it('should convert positive integer strings to numbers', () => {
143
+ expect(normalizeType('integer', '123')).toBe(123);
144
+ expect(normalizeType('integer', '0')).toBe(0);
145
+ expect(normalizeType('integer', '999')).toBe(999);
146
+ expect(normalizeType('integer', '1000000')).toBe(1000000);
147
+ });
148
+
149
+ it('should convert negative integer strings to numbers', () => {
150
+ expect(normalizeType('integer', '-10')).toBe(-10);
151
+ expect(normalizeType('integer', '-0')).toBe(-0);
152
+ expect(normalizeType('integer', '-999')).toBe(-999);
153
+ });
154
+
155
+ it('should convert decimal strings to numbers (preserves decimal)', () => {
156
+ expect(normalizeType('integer', '45.67')).toBe(45.67);
157
+ expect(normalizeType('integer', '0.5')).toBe(0.5);
158
+ expect(normalizeType('integer', '-0.5')).toBe(-0.5);
159
+ expect(normalizeType('integer', '123.456')).toBe(123.456);
160
+ });
161
+
162
+ it('should convert scientific notation strings to numbers', () => {
163
+ expect(normalizeType('integer', '1e2')).toBe(100);
164
+ expect(normalizeType('integer', '1e-2')).toBe(0.01);
165
+ expect(normalizeType('integer', '1.5e2')).toBe(150);
166
+ });
167
+
168
+ it('should convert special number strings', () => {
169
+ expect(normalizeType('integer', 'Infinity')).toBe(Infinity);
170
+ expect(normalizeType('integer', '-Infinity')).toBe(-Infinity);
171
+ });
172
+
173
+ it('should convert string numbers with leading/trailing whitespace', () => {
174
+ expect(normalizeType('integer', ' 123')).toBe(123);
175
+ expect(normalizeType('integer', '123 ')).toBe(123);
176
+ expect(normalizeType('integer', ' 123 ')).toBe(123);
177
+ });
178
+ });
179
+
180
+ describe('number preservation', () => {
181
+ it('should keep positive integers as-is', () => {
182
+ expect(normalizeType('integer', 123)).toBe(123);
183
+ expect(normalizeType('integer', 0)).toBe(0);
184
+ expect(normalizeType('integer', 999)).toBe(999);
185
+ });
186
+
187
+ it('should keep negative integers as-is', () => {
188
+ expect(normalizeType('integer', -10)).toBe(-10);
189
+ expect(normalizeType('integer', -0)).toBe(-0);
190
+ expect(normalizeType('integer', -999)).toBe(-999);
191
+ });
192
+
193
+ it('should keep decimal numbers as-is', () => {
194
+ expect(normalizeType('integer', 45.67)).toBe(45.67);
195
+ expect(normalizeType('integer', 0.5)).toBe(0.5);
196
+ });
197
+
198
+ it('should keep special number values as-is', () => {
199
+ expect(normalizeType('integer', Infinity)).toBe(Infinity);
200
+ expect(normalizeType('integer', -Infinity)).toBe(-Infinity);
201
+ expect(normalizeType('integer', NaN)).toBeNaN();
202
+ });
203
+ });
204
+
205
+ describe('boolean to number conversion', () => {
206
+ it('should convert boolean true to 1', () => {
207
+ expect(normalizeType('integer', true)).toBe(1);
208
+ });
209
+
210
+ it('should convert boolean false to 0', () => {
211
+ expect(normalizeType('integer', false)).toBe(0);
212
+ });
213
+ });
214
+
215
+ describe('non-convertible values', () => {
216
+ it('should return original value for invalid string numbers', () => {
217
+ expect(normalizeType('integer', 'abc')).toBe('abc');
218
+ expect(normalizeType('integer', 'not a number')).toBe('not a number');
219
+ expect(normalizeType('integer', '123abc')).toBe('123abc');
220
+ });
221
+
222
+ it('should preserve empty and whitespace-only strings', () => {
223
+ expect(normalizeType('integer', '')).toBe('');
224
+ expect(normalizeType('integer', ' ')).toBe(' ');
225
+ });
226
+
227
+ it('should preserve null and undefined', () => {
228
+ expect(normalizeType('integer', null)).toBe(null);
229
+ expect(normalizeType('integer', undefined)).toBe(undefined);
230
+ });
231
+
232
+ it('should preserve objects and arrays', () => {
233
+ const obj = { a: 1 };
234
+ const arr = [1, 2];
235
+ expect(normalizeType('integer', obj)).toBe(obj);
236
+ expect(normalizeType('integer', arr)).toBe(arr);
237
+ });
238
+ });
239
+ });
240
+
241
+ describe('boolean type', () => {
242
+ describe('number to boolean conversion', () => {
243
+ it('should convert zero to false', () => {
244
+ expect(normalizeType('boolean', 0)).toBe(false);
245
+ expect(normalizeType('boolean', -0)).toBe(false);
246
+ expect(normalizeType('boolean', 0.0)).toBe(false);
247
+ });
248
+
249
+ it('should convert positive integers to true', () => {
250
+ expect(normalizeType('boolean', 1)).toBe(true);
251
+ expect(normalizeType('boolean', 100)).toBe(true);
252
+ expect(normalizeType('boolean', 999)).toBe(true);
253
+ expect(normalizeType('boolean', Number.MAX_SAFE_INTEGER)).toBe(true);
254
+ });
255
+
256
+ it('should convert negative integers to true', () => {
257
+ expect(normalizeType('boolean', -1)).toBe(true);
258
+ expect(normalizeType('boolean', -100)).toBe(true);
259
+ expect(normalizeType('boolean', -999)).toBe(true);
260
+ expect(normalizeType('boolean', Number.MIN_SAFE_INTEGER)).toBe(true);
261
+ });
262
+
263
+ it('should convert positive decimals to true', () => {
264
+ expect(normalizeType('boolean', 0.1)).toBe(true);
265
+ expect(normalizeType('boolean', 0.5)).toBe(true);
266
+ expect(normalizeType('boolean', 0.0001)).toBe(true);
267
+ expect(normalizeType('boolean', 45.67)).toBe(true);
268
+ });
269
+
270
+ it('should convert negative decimals to true', () => {
271
+ expect(normalizeType('boolean', -0.1)).toBe(true);
272
+ expect(normalizeType('boolean', -0.5)).toBe(true);
273
+ expect(normalizeType('boolean', -45.67)).toBe(true);
274
+ });
275
+
276
+ it('should convert special number values', () => {
277
+ expect(normalizeType('boolean', Infinity)).toBe(true);
278
+ expect(normalizeType('boolean', -Infinity)).toBe(true);
279
+ expect(normalizeType('boolean', NaN)).toBe(false);
280
+ expect(normalizeType('boolean', Number.MAX_VALUE)).toBe(true);
281
+ expect(normalizeType('boolean', Number.MIN_VALUE)).toBe(true);
282
+ });
283
+ });
284
+
285
+ describe('string to boolean conversion', () => {
286
+ it('should convert true string values (lowercase) to true', () => {
287
+ expect(normalizeType('boolean', 'yes')).toBe(true);
288
+ expect(normalizeType('boolean', 'true')).toBe(true);
289
+ expect(normalizeType('boolean', '1')).toBe(true);
290
+ });
291
+
292
+ it('should convert true string values (uppercase) to true', () => {
293
+ expect(normalizeType('boolean', 'YES')).toBe(true);
294
+ expect(normalizeType('boolean', 'TRUE')).toBe(true);
295
+ });
296
+
297
+ it('should convert true string values (mixed case) to true', () => {
298
+ expect(normalizeType('boolean', 'Yes')).toBe(true);
299
+ expect(normalizeType('boolean', 'True')).toBe(true);
300
+ expect(normalizeType('boolean', 'YeS')).toBe(true);
301
+ expect(normalizeType('boolean', 'TrUe')).toBe(true);
302
+ });
303
+
304
+ it('should convert false string values (lowercase) to false', () => {
305
+ expect(normalizeType('boolean', 'no')).toBe(false);
306
+ expect(normalizeType('boolean', 'false')).toBe(false);
307
+ expect(normalizeType('boolean', '0')).toBe(false);
308
+ });
309
+
310
+ it('should convert false string values (uppercase) to false', () => {
311
+ expect(normalizeType('boolean', 'NO')).toBe(false);
312
+ expect(normalizeType('boolean', 'FALSE')).toBe(false);
313
+ });
314
+
315
+ it('should convert false string values (mixed case) to false', () => {
316
+ expect(normalizeType('boolean', 'No')).toBe(false);
317
+ expect(normalizeType('boolean', 'False')).toBe(false);
318
+ expect(normalizeType('boolean', 'No')).toBe(false);
319
+ expect(normalizeType('boolean', 'FaLsE')).toBe(false);
320
+ });
321
+
322
+ it('should return original value for unrecognized string values', () => {
323
+ expect(normalizeType('boolean', 'maybe')).toBe('maybe');
324
+ expect(normalizeType('boolean', '2')).toBe('2');
325
+ expect(normalizeType('boolean', 'abc')).toBe('abc');
326
+ expect(normalizeType('boolean', 'y')).toBe('y');
327
+ expect(normalizeType('boolean', 'n')).toBe('n');
328
+ expect(normalizeType('boolean', 't')).toBe('t');
329
+ expect(normalizeType('boolean', 'f')).toBe('f');
330
+ expect(normalizeType('boolean', 'yesno')).toBe('yesno');
331
+ expect(normalizeType('boolean', 'truely')).toBe('truely');
332
+ });
333
+
334
+ it('should preserve empty and whitespace-only strings', () => {
335
+ expect(normalizeType('boolean', '')).toBe('');
336
+ expect(normalizeType('boolean', ' ')).toBe(' ');
337
+ expect(normalizeType('boolean', '\t\n')).toBe('\t\n');
338
+ });
339
+ });
340
+
341
+ describe('boolean preservation', () => {
342
+ it('should keep boolean true as-is', () => {
343
+ expect(normalizeType('boolean', true)).toBe(true);
344
+ });
345
+
346
+ it('should keep boolean false as-is', () => {
347
+ expect(normalizeType('boolean', false)).toBe(false);
348
+ });
349
+ });
350
+
351
+ describe('non-convertible values', () => {
352
+ it('should preserve null and undefined', () => {
353
+ expect(normalizeType('boolean', null)).toBe(null);
354
+ expect(normalizeType('boolean', undefined)).toBe(undefined);
355
+ });
356
+
357
+ it('should preserve objects', () => {
358
+ expect(normalizeType('boolean', {})).toEqual({});
359
+ expect(normalizeType('boolean', { a: 1 })).toEqual({ a: 1 });
360
+ expect(normalizeType('boolean', { x: 1, y: 2 })).toEqual({ x: 1, y: 2 });
361
+ });
362
+
363
+ it('should preserve arrays', () => {
364
+ expect(normalizeType('boolean', [])).toEqual([]);
365
+ expect(normalizeType('boolean', [1, 2, 3])).toEqual([1, 2, 3]);
366
+ expect(normalizeType('boolean', ['a', 'b'])).toEqual(['a', 'b']);
367
+ });
368
+
369
+ it('should preserve functions', () => {
370
+ /**
371
+ *
372
+ */
373
+ const fn = () => {};
374
+ expect(normalizeType('boolean', fn)).toBe(fn);
375
+ });
376
+
377
+ it('should preserve symbols', () => {
378
+ const sym = Symbol('test');
379
+ expect(normalizeType('boolean', sym)).toBe(sym);
380
+ });
381
+
382
+ it('should preserve dates', () => {
383
+ const date = new Date();
384
+ expect(normalizeType('boolean', date)).toBe(date);
385
+ });
386
+
387
+ it('should preserve regexp', () => {
388
+ const regex = /test/;
389
+ expect(normalizeType('boolean', regex)).toBe(regex);
390
+ });
391
+ });
392
+ });
393
+
394
+ describe('string type', () => {
395
+ it('should return string values as-is', () => {
396
+ expect(normalizeType('string', 'hello')).toBe('hello');
397
+ expect(normalizeType('string', '')).toBe('');
398
+ expect(normalizeType('string', '123')).toBe('123');
399
+ expect(normalizeType('string', 'true')).toBe('true');
400
+ expect(normalizeType('string', ' ')).toBe(' ');
401
+ });
402
+
403
+ it('should return number values as-is', () => {
404
+ expect(normalizeType('string', 123)).toBe(123);
405
+ expect(normalizeType('string', 0)).toBe(0);
406
+ expect(normalizeType('string', -10)).toBe(-10);
407
+ expect(normalizeType('string', 45.67)).toBe(45.67);
408
+ expect(normalizeType('string', Infinity)).toBe(Infinity);
409
+ expect(normalizeType('string', NaN)).toBeNaN();
410
+ });
411
+
412
+ it('should return boolean values as-is', () => {
413
+ expect(normalizeType('string', true)).toBe(true);
414
+ expect(normalizeType('string', false)).toBe(false);
415
+ });
416
+
417
+ it('should return null and undefined as-is', () => {
418
+ expect(normalizeType('string', null)).toBe(null);
419
+ expect(normalizeType('string', undefined)).toBe(undefined);
420
+ });
421
+
422
+ it('should return objects as-is', () => {
423
+ const obj = { key: 'value' };
424
+ expect(normalizeType('string', obj)).toBe(obj);
425
+ expect(normalizeType('string', {})).toEqual({});
426
+ expect(normalizeType('string', { a: 1, b: 2 })).toEqual({ a: 1, b: 2 });
427
+ });
428
+
429
+ it('should return arrays as-is', () => {
430
+ const arr = [1, 2, 3];
431
+ expect(normalizeType('string', arr)).toBe(arr);
432
+ expect(normalizeType('string', [])).toEqual([]);
433
+ expect(normalizeType('string', ['a', 'b'])).toEqual(['a', 'b']);
434
+ });
435
+
436
+ it('should return functions as-is', () => {
437
+ /**
438
+ *
439
+ */
440
+ const fn = () => {};
441
+ expect(normalizeType('string', fn)).toBe(fn);
442
+ });
443
+
444
+ it('should return symbols as-is', () => {
445
+ const sym = Symbol('test');
446
+ expect(normalizeType('string', sym)).toBe(sym);
447
+ });
448
+
449
+ it('should return dates as-is', () => {
450
+ const date = new Date();
451
+ expect(normalizeType('string', date)).toBe(date);
452
+ });
453
+
454
+ it('should return regexp as-is', () => {
455
+ const regex = /test/;
456
+ expect(normalizeType('string', regex)).toBe(regex);
457
+ });
458
+ });
459
+
460
+ describe('object type', () => {
461
+ it('should return objects as-is', () => {
462
+ const obj = { key: 'value' };
463
+ expect(normalizeType('object', obj)).toBe(obj);
464
+ expect(normalizeType('object', {})).toEqual({});
465
+ expect(normalizeType('object', { a: 1 })).toEqual({ a: 1 });
466
+ expect(normalizeType('object', { x: 1, y: 2, z: 3 })).toEqual({ x: 1, y: 2, z: 3 });
467
+ });
468
+
469
+ it('should return null as-is', () => {
470
+ expect(normalizeType('object', null)).toBe(null);
471
+ });
472
+
473
+ it('should return string values as-is', () => {
474
+ expect(normalizeType('object', 'string')).toBe('string');
475
+ expect(normalizeType('object', '')).toBe('');
476
+ expect(normalizeType('object', '123')).toBe('123');
477
+ });
478
+
479
+ it('should return number values as-is', () => {
480
+ expect(normalizeType('object', 123)).toBe(123);
481
+ expect(normalizeType('object', 0)).toBe(0);
482
+ expect(normalizeType('object', -10)).toBe(-10);
483
+ expect(normalizeType('object', 45.67)).toBe(45.67);
484
+ });
485
+
486
+ it('should return boolean values as-is', () => {
487
+ expect(normalizeType('object', true)).toBe(true);
488
+ expect(normalizeType('object', false)).toBe(false);
489
+ });
490
+
491
+ it('should return undefined as-is', () => {
492
+ expect(normalizeType('object', undefined)).toBe(undefined);
493
+ });
494
+
495
+ it('should return arrays as-is', () => {
496
+ expect(normalizeType('object', [])).toEqual([]);
497
+ expect(normalizeType('object', [1, 2, 3])).toEqual([1, 2, 3]);
498
+ });
499
+
500
+ it('should return functions as-is', () => {
501
+ /**
502
+ *
503
+ */
504
+ const fn = () => {};
505
+ expect(normalizeType('object', fn)).toBe(fn);
506
+ });
507
+ });
508
+
509
+ describe('array type', () => {
510
+ it('should return arrays as-is', () => {
511
+ const arr = [1, 2, 3];
512
+ expect(normalizeType('array', arr)).toBe(arr);
513
+ expect(normalizeType('array', [])).toEqual([]);
514
+ expect(normalizeType('array', ['a', 'b'])).toEqual(['a', 'b']);
515
+ expect(normalizeType('array', [1, 'two', true])).toEqual([1, 'two', true]);
516
+ });
517
+
518
+ it('should return null as-is', () => {
519
+ expect(normalizeType('array', null)).toBe(null);
520
+ });
521
+
522
+ it('should return string values as-is', () => {
523
+ expect(normalizeType('array', 'string')).toBe('string');
524
+ expect(normalizeType('array', '')).toBe('');
525
+ });
526
+
527
+ it('should return number values as-is', () => {
528
+ expect(normalizeType('array', 123)).toBe(123);
529
+ expect(normalizeType('array', 0)).toBe(0);
530
+ expect(normalizeType('array', 45.67)).toBe(45.67);
531
+ });
532
+
533
+ it('should return boolean values as-is', () => {
534
+ expect(normalizeType('array', true)).toBe(true);
535
+ expect(normalizeType('array', false)).toBe(false);
536
+ });
537
+
538
+ it('should return undefined as-is', () => {
539
+ expect(normalizeType('array', undefined)).toBe(undefined);
540
+ });
541
+
542
+ it('should return objects as-is', () => {
543
+ const obj = { a: 1 };
544
+ expect(normalizeType('array', obj)).toBe(obj);
545
+ expect(normalizeType('array', {})).toEqual({});
546
+ });
547
+
548
+ it('should return functions as-is', () => {
549
+ /**
550
+ *
551
+ */
552
+ const fn = () => {};
553
+ expect(normalizeType('array', fn)).toBe(fn);
554
+ });
555
+ });
556
+
557
+ describe('edge cases', () => {
558
+ describe('null and undefined preservation', () => {
559
+ it('should preserve null for all types', () => {
560
+ expect(normalizeType('number', null)).toBe(null);
561
+ expect(normalizeType('integer', null)).toBe(null);
562
+ expect(normalizeType('boolean', null)).toBe(null);
563
+ expect(normalizeType('string', null)).toBe(null);
564
+ expect(normalizeType('object', null)).toBe(null);
565
+ expect(normalizeType('array', null)).toBe(null);
566
+ });
567
+
568
+ it('should preserve undefined for all types', () => {
569
+ expect(normalizeType('number', undefined)).toBe(undefined);
570
+ expect(normalizeType('integer', undefined)).toBe(undefined);
571
+ expect(normalizeType('boolean', undefined)).toBe(undefined);
572
+ expect(normalizeType('string', undefined)).toBe(undefined);
573
+ expect(normalizeType('object', undefined)).toBe(undefined);
574
+ expect(normalizeType('array', undefined)).toBe(undefined);
575
+ });
576
+ });
577
+
578
+ describe('NaN handling', () => {
579
+ it('should preserve NaN for number and integer types', () => {
580
+ expect(normalizeType('number', NaN)).toBeNaN();
581
+ expect(normalizeType('integer', NaN)).toBeNaN();
582
+ });
583
+
584
+ it('should convert NaN to false for boolean type', () => {
585
+ expect(normalizeType('boolean', NaN)).toBe(false);
586
+ });
587
+
588
+ it('should preserve NaN for string, object, and array types', () => {
589
+ expect(normalizeType('string', NaN)).toBeNaN();
590
+ expect(normalizeType('object', NaN)).toBeNaN();
591
+ expect(normalizeType('array', NaN)).toBeNaN();
592
+ });
593
+ });
594
+
595
+ describe('empty and whitespace string handling', () => {
596
+ it('should preserve empty strings for all types', () => {
597
+ expect(normalizeType('number', '')).toBe('');
598
+ expect(normalizeType('integer', '')).toBe('');
599
+ expect(normalizeType('boolean', '')).toBe('');
600
+ expect(normalizeType('string', '')).toBe('');
601
+ expect(normalizeType('object', '')).toBe('');
602
+ expect(normalizeType('array', '')).toBe('');
603
+ });
604
+
605
+ it('should preserve whitespace-only strings for all types', () => {
606
+ expect(normalizeType('number', ' ')).toBe(' ');
607
+ expect(normalizeType('integer', ' ')).toBe(' ');
608
+ expect(normalizeType('boolean', ' ')).toBe(' ');
609
+ expect(normalizeType('string', ' ')).toBe(' ');
610
+ expect(normalizeType('object', ' ')).toBe(' ');
611
+ expect(normalizeType('array', ' ')).toBe(' ');
612
+ });
613
+
614
+ it('should preserve various whitespace characters', () => {
615
+ expect(normalizeType('number', '\t')).toBe('\t');
616
+ expect(normalizeType('number', '\n')).toBe('\n');
617
+ expect(normalizeType('number', '\r')).toBe('\r');
618
+ expect(normalizeType('number', '\t\n\r')).toBe('\t\n\r');
619
+ expect(normalizeType('number', ' \t \n ')).toBe(' \t \n ');
620
+ });
621
+ });
622
+
623
+ describe('special number values', () => {
624
+ it('should preserve Infinity for number and integer types', () => {
625
+ expect(normalizeType('number', Infinity)).toBe(Infinity);
626
+ expect(normalizeType('number', -Infinity)).toBe(-Infinity);
627
+ expect(normalizeType('integer', Infinity)).toBe(Infinity);
628
+ expect(normalizeType('integer', -Infinity)).toBe(-Infinity);
629
+ });
630
+
631
+ it('should convert Infinity to true for boolean type', () => {
632
+ expect(normalizeType('boolean', Infinity)).toBe(true);
633
+ expect(normalizeType('boolean', -Infinity)).toBe(true);
634
+ });
635
+
636
+ it('should preserve Infinity for string, object, and array types', () => {
637
+ expect(normalizeType('string', Infinity)).toBe(Infinity);
638
+ expect(normalizeType('object', Infinity)).toBe(Infinity);
639
+ expect(normalizeType('array', Infinity)).toBe(Infinity);
640
+ });
641
+
642
+ it('should handle Number.MAX_VALUE and Number.MIN_VALUE', () => {
643
+ expect(normalizeType('number', Number.MAX_VALUE)).toBe(Number.MAX_VALUE);
644
+ expect(normalizeType('number', Number.MIN_VALUE)).toBe(Number.MIN_VALUE);
645
+ expect(normalizeType('boolean', Number.MAX_VALUE)).toBe(true);
646
+ expect(normalizeType('boolean', Number.MIN_VALUE)).toBe(true);
647
+ });
648
+
649
+ it('should handle Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER', () => {
650
+ expect(normalizeType('number', Number.MAX_SAFE_INTEGER)).toBe(Number.MAX_SAFE_INTEGER);
651
+ expect(normalizeType('number', Number.MIN_SAFE_INTEGER)).toBe(Number.MIN_SAFE_INTEGER);
652
+ expect(normalizeType('boolean', Number.MAX_SAFE_INTEGER)).toBe(true);
653
+ expect(normalizeType('boolean', Number.MIN_SAFE_INTEGER)).toBe(true);
654
+ });
655
+ });
656
+
657
+ describe('string number edge cases', () => {
658
+ it('should handle string numbers with leading zeros', () => {
659
+ expect(normalizeType('number', '0123')).toBe(123);
660
+ expect(normalizeType('number', '000')).toBe(0);
661
+ expect(normalizeType('number', '00123')).toBe(123);
662
+ });
663
+
664
+ it('should handle string numbers with multiple decimal points', () => {
665
+ expect(normalizeType('number', '12.34.56')).toBe('12.34.56'); // Invalid, preserved
666
+ expect(normalizeType('number', '12..34')).toBe('12..34'); // Invalid, preserved
667
+ });
668
+
669
+ it('should handle string numbers with invalid characters', () => {
670
+ expect(normalizeType('number', '12abc')).toBe('12abc'); // Invalid, preserved
671
+ expect(normalizeType('number', 'abc12')).toBe('abc12'); // Invalid, preserved
672
+ expect(normalizeType('number', '12-34')).toBe('12-34'); // Invalid, preserved
673
+ });
674
+ });
675
+
676
+ describe('object and array preservation', () => {
677
+ it('should preserve objects for number type', () => {
678
+ const obj = { a: 1 };
679
+ expect(normalizeType('number', obj)).toBe(obj);
680
+ expect(normalizeType('number', {})).toEqual({});
681
+ expect(normalizeType('number', { x: 1, y: 2 })).toEqual({ x: 1, y: 2 });
682
+ });
683
+
684
+ it('should preserve arrays for number type', () => {
685
+ const arr = [1, 2];
686
+ expect(normalizeType('number', arr)).toBe(arr);
687
+ expect(normalizeType('number', [])).toEqual([]);
688
+ expect(normalizeType('number', [1, 2, 3])).toEqual([1, 2, 3]);
689
+ });
690
+
691
+ it('should preserve nested objects and arrays', () => {
692
+ const nestedObj = { a: { b: { c: 1 } } };
693
+ const nestedArr = [[1, 2], [3, 4]];
694
+ expect(normalizeType('number', nestedObj)).toBe(nestedObj);
695
+ expect(normalizeType('number', nestedArr)).toBe(nestedArr);
696
+ });
697
+ });
698
+
699
+ describe('function and symbol preservation', () => {
700
+ it('should preserve functions for all types', () => {
701
+ /**
702
+ *
703
+ */
704
+ const fn = () => {};
705
+ /**
706
+ *
707
+ */
708
+ const fnWithArgs = (x: number) => x * 2;
709
+ expect(normalizeType('number', fn)).toBe(fn);
710
+ expect(normalizeType('boolean', fn)).toBe(fn);
711
+ expect(normalizeType('string', fn)).toBe(fn);
712
+ expect(normalizeType('object', fn)).toBe(fn);
713
+ expect(normalizeType('array', fn)).toBe(fn);
714
+ expect(normalizeType('number', fnWithArgs)).toBe(fnWithArgs);
715
+ });
716
+
717
+ it('should preserve symbols for all types', () => {
718
+ const sym = Symbol('test');
719
+ const symDesc = Symbol('description');
720
+ expect(normalizeType('number', sym)).toBe(sym);
721
+ expect(normalizeType('boolean', sym)).toBe(sym);
722
+ expect(normalizeType('string', sym)).toBe(sym);
723
+ expect(normalizeType('object', sym)).toBe(sym);
724
+ expect(normalizeType('array', sym)).toBe(sym);
725
+ expect(normalizeType('number', symDesc)).toBe(symDesc);
726
+ });
727
+ });
728
+
729
+ describe('date and regexp preservation', () => {
730
+ it('should preserve Date objects for all types', () => {
731
+ const date = new Date();
732
+ const dateStr = new Date('2023-01-01');
733
+ expect(normalizeType('number', date)).toBe(date);
734
+ expect(normalizeType('boolean', date)).toBe(date);
735
+ expect(normalizeType('string', date)).toBe(date);
736
+ expect(normalizeType('object', date)).toBe(date);
737
+ expect(normalizeType('array', date)).toBe(date);
738
+ expect(normalizeType('number', dateStr)).toBe(dateStr);
739
+ });
740
+
741
+ it('should preserve RegExp objects for all types', () => {
742
+ const regex = /test/;
743
+ const regexGlobal = /test/g;
744
+ expect(normalizeType('number', regex)).toBe(regex);
745
+ expect(normalizeType('boolean', regex)).toBe(regex);
746
+ expect(normalizeType('string', regex)).toBe(regex);
747
+ expect(normalizeType('object', regex)).toBe(regex);
748
+ expect(normalizeType('array', regex)).toBe(regex);
749
+ expect(normalizeType('number', regexGlobal)).toBe(regexGlobal);
750
+ });
751
+ });
752
+
753
+ describe('very large and very small numbers', () => {
754
+ it('should handle very large numbers', () => {
755
+ const largeNum = 1e308;
756
+ expect(normalizeType('number', largeNum)).toBe(largeNum);
757
+ expect(normalizeType('boolean', largeNum)).toBe(true);
758
+ });
759
+
760
+ it('should handle very small numbers', () => {
761
+ const smallNum = 1e-308;
762
+ expect(normalizeType('number', smallNum)).toBe(smallNum);
763
+ expect(normalizeType('boolean', smallNum)).toBe(true);
764
+ });
765
+
766
+ it('should handle string representations of very large numbers', () => {
767
+ expect(normalizeType('number', '1e308')).toBe(1e308);
768
+ expect(normalizeType('number', '1e-308')).toBe(1e-308);
769
+ });
770
+ });
771
+ });
772
+ });