@livon/schema 0.27.0-rc.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 (169) hide show
  1. package/PROMPT.md +21 -0
  2. package/README.md +13 -0
  3. package/SCHEMA.md +13 -0
  4. package/dist/SchemaValidationError.cjs +41 -0
  5. package/dist/SchemaValidationError.d.ts +20 -0
  6. package/dist/SchemaValidationError.js +7 -0
  7. package/dist/SchemaValidationError.spec.cjs +65 -0
  8. package/dist/SchemaValidationError.spec.d.ts +1 -0
  9. package/dist/SchemaValidationError.spec.js +59 -0
  10. package/dist/after.cjs +36 -0
  11. package/dist/after.d.ts +30 -0
  12. package/dist/after.js +2 -0
  13. package/dist/after.spec.cjs +54 -0
  14. package/dist/after.spec.d.ts +1 -0
  15. package/dist/after.spec.js +48 -0
  16. package/dist/and.cjs +36 -0
  17. package/dist/and.d.ts +26 -0
  18. package/dist/and.js +2 -0
  19. package/dist/and.spec.cjs +57 -0
  20. package/dist/and.spec.d.ts +1 -0
  21. package/dist/and.spec.js +51 -0
  22. package/dist/api.cjs +317 -0
  23. package/dist/api.d.ts +107 -0
  24. package/dist/api.js +277 -0
  25. package/dist/api.spec.cjs +512 -0
  26. package/dist/api.spec.d.ts +1 -0
  27. package/dist/api.spec.js +506 -0
  28. package/dist/array.cjs +74 -0
  29. package/dist/array.d.ts +25 -0
  30. package/dist/array.js +40 -0
  31. package/dist/array.spec.cjs +167 -0
  32. package/dist/array.spec.d.ts +1 -0
  33. package/dist/array.spec.js +161 -0
  34. package/dist/before.cjs +36 -0
  35. package/dist/before.d.ts +30 -0
  36. package/dist/before.js +2 -0
  37. package/dist/before.spec.cjs +54 -0
  38. package/dist/before.spec.d.ts +1 -0
  39. package/dist/before.spec.js +48 -0
  40. package/dist/binary.cjs +53 -0
  41. package/dist/binary.d.ts +24 -0
  42. package/dist/binary.js +19 -0
  43. package/dist/binary.spec.cjs +107 -0
  44. package/dist/binary.spec.d.ts +1 -0
  45. package/dist/binary.spec.js +101 -0
  46. package/dist/boolean.cjs +53 -0
  47. package/dist/boolean.d.ts +24 -0
  48. package/dist/boolean.js +19 -0
  49. package/dist/boolean.spec.cjs +96 -0
  50. package/dist/boolean.spec.d.ts +1 -0
  51. package/dist/boolean.spec.js +90 -0
  52. package/dist/context.cjs +125 -0
  53. package/dist/context.d.ts +101 -0
  54. package/dist/context.js +76 -0
  55. package/dist/context.spec.cjs +244 -0
  56. package/dist/context.spec.d.ts +1 -0
  57. package/dist/context.spec.js +238 -0
  58. package/dist/date.cjs +53 -0
  59. package/dist/date.d.ts +24 -0
  60. package/dist/date.js +19 -0
  61. package/dist/date.spec.cjs +97 -0
  62. package/dist/date.spec.d.ts +1 -0
  63. package/dist/date.spec.js +91 -0
  64. package/dist/doc.cjs +54 -0
  65. package/dist/doc.d.ts +25 -0
  66. package/dist/doc.js +17 -0
  67. package/dist/doc.spec.cjs +99 -0
  68. package/dist/doc.spec.d.ts +1 -0
  69. package/dist/doc.spec.js +93 -0
  70. package/dist/enumeration.cjs +74 -0
  71. package/dist/enumeration.d.ts +50 -0
  72. package/dist/enumeration.js +40 -0
  73. package/dist/enumeration.spec.cjs +110 -0
  74. package/dist/enumeration.spec.d.ts +1 -0
  75. package/dist/enumeration.spec.js +104 -0
  76. package/dist/hydrate.cjs +18 -0
  77. package/dist/hydrate.d.ts +1 -0
  78. package/dist/hydrate.js +0 -0
  79. package/dist/index.cjs +145 -0
  80. package/dist/index.d.ts +34 -0
  81. package/dist/index.js +24 -0
  82. package/dist/index.spec.cjs +43 -0
  83. package/dist/index.spec.d.ts +1 -0
  84. package/dist/index.spec.js +37 -0
  85. package/dist/literal.cjs +55 -0
  86. package/dist/literal.d.ts +25 -0
  87. package/dist/literal.js +21 -0
  88. package/dist/literal.spec.cjs +93 -0
  89. package/dist/literal.spec.d.ts +1 -0
  90. package/dist/literal.spec.js +87 -0
  91. package/dist/number.cjs +89 -0
  92. package/dist/number.d.ts +84 -0
  93. package/dist/number.js +55 -0
  94. package/dist/number.spec.cjs +155 -0
  95. package/dist/number.spec.d.ts +1 -0
  96. package/dist/number.spec.js +149 -0
  97. package/dist/object.cjs +66 -0
  98. package/dist/object.d.ts +37 -0
  99. package/dist/object.js +32 -0
  100. package/dist/object.spec.cjs +171 -0
  101. package/dist/object.spec.d.ts +1 -0
  102. package/dist/object.spec.js +165 -0
  103. package/dist/operation.cjs +182 -0
  104. package/dist/operation.d.ts +197 -0
  105. package/dist/operation.js +133 -0
  106. package/dist/operation.spec.cjs +454 -0
  107. package/dist/operation.spec.d.ts +1 -0
  108. package/dist/operation.spec.js +448 -0
  109. package/dist/or.cjs +85 -0
  110. package/dist/or.d.ts +37 -0
  111. package/dist/or.js +51 -0
  112. package/dist/or.spec.cjs +204 -0
  113. package/dist/or.spec.d.ts +1 -0
  114. package/dist/or.spec.js +198 -0
  115. package/dist/schema.cjs +285 -0
  116. package/dist/schema.d.ts +132 -0
  117. package/dist/schema.js +233 -0
  118. package/dist/schema.spec.cjs +587 -0
  119. package/dist/schema.spec.d.ts +1 -0
  120. package/dist/schema.spec.js +581 -0
  121. package/dist/schemaFactory.cjs +125 -0
  122. package/dist/schemaFactory.d.ts +97 -0
  123. package/dist/schemaFactory.js +88 -0
  124. package/dist/schemaFactory.spec.cjs +197 -0
  125. package/dist/schemaFactory.spec.d.ts +1 -0
  126. package/dist/schemaFactory.spec.js +191 -0
  127. package/dist/schemaModule.cjs +280 -0
  128. package/dist/schemaModule.d.ts +97 -0
  129. package/dist/schemaModule.js +243 -0
  130. package/dist/schemaModule.spec.cjs +355 -0
  131. package/dist/schemaModule.spec.d.ts +1 -0
  132. package/dist/schemaModule.spec.js +349 -0
  133. package/dist/string.cjs +93 -0
  134. package/dist/string.d.ts +85 -0
  135. package/dist/string.js +59 -0
  136. package/dist/string.spec.cjs +158 -0
  137. package/dist/string.spec.d.ts +1 -0
  138. package/dist/string.spec.js +152 -0
  139. package/dist/testing/mocks/assertions.mock.cjs +48 -0
  140. package/dist/testing/mocks/assertions.mock.d.ts +5 -0
  141. package/dist/testing/mocks/assertions.mock.js +14 -0
  142. package/dist/testing/mocks/index.cjs +52 -0
  143. package/dist/testing/mocks/index.d.ts +4 -0
  144. package/dist/testing/mocks/index.js +3 -0
  145. package/dist/testing/mocks/schema.mock.cjs +120 -0
  146. package/dist/testing/mocks/schema.mock.d.ts +37 -0
  147. package/dist/testing/mocks/schema.mock.js +74 -0
  148. package/dist/tuple.cjs +58 -0
  149. package/dist/tuple.d.ts +33 -0
  150. package/dist/tuple.js +24 -0
  151. package/dist/tuple.spec.cjs +162 -0
  152. package/dist/tuple.spec.d.ts +1 -0
  153. package/dist/tuple.spec.js +156 -0
  154. package/dist/typeGuards.cjs +60 -0
  155. package/dist/typeGuards.d.ts +93 -0
  156. package/dist/typeGuards.js +8 -0
  157. package/dist/typeGuards.spec.cjs +101 -0
  158. package/dist/typeGuards.spec.d.ts +1 -0
  159. package/dist/typeGuards.spec.js +95 -0
  160. package/dist/types.cjs +18 -0
  161. package/dist/types.d.ts +289 -0
  162. package/dist/types.js +0 -0
  163. package/dist/union.cjs +74 -0
  164. package/dist/union.d.ts +33 -0
  165. package/dist/union.js +40 -0
  166. package/dist/union.spec.cjs +159 -0
  167. package/dist/union.spec.d.ts +1 -0
  168. package/dist/union.spec.js +153 -0
  169. package/package.json +47 -0
@@ -0,0 +1,581 @@
1
+ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { createSchemaContext } from "./context.js";
3
+ import { createGuardSchema, createIssueForPath, createPrimitiveSchema, createSchema, ensureSchemaContext, fail, ok } from "./schema.js";
4
+ describe('schema core utilities', ()=>{
5
+ let context;
6
+ beforeAll(()=>{
7
+ context = createSchemaContext();
8
+ });
9
+ beforeEach(()=>{
10
+ context = createSchemaContext();
11
+ });
12
+ afterEach(()=>{
13
+ vi.clearAllMocks();
14
+ });
15
+ afterAll(()=>{
16
+ vi.restoreAllMocks();
17
+ });
18
+ describe('createIssueForPath()', ()=>{
19
+ describe('happy', ()=>{
20
+ it('should create schema issue object when issue input is provided', ()=>{
21
+ const issue = createIssueForPath({
22
+ path: [
23
+ 'user',
24
+ 'name'
25
+ ],
26
+ message: 'Expected non-empty value',
27
+ code: 'string.min',
28
+ context: {
29
+ min: 1
30
+ }
31
+ });
32
+ expect(issue).toEqual({
33
+ path: [
34
+ 'user',
35
+ 'name'
36
+ ],
37
+ message: 'Expected non-empty value',
38
+ code: 'string.min',
39
+ context: {
40
+ min: 1
41
+ }
42
+ });
43
+ });
44
+ });
45
+ describe('sad', ()=>{
46
+ it('should keep optional fields undefined when optional values are omitted', ()=>{
47
+ const issue = createIssueForPath({
48
+ path: [],
49
+ message: 'Invalid value'
50
+ });
51
+ expect(issue.code).toBeUndefined();
52
+ expect(issue.context).toBeUndefined();
53
+ });
54
+ });
55
+ });
56
+ describe('ok()', ()=>{
57
+ describe('happy', ()=>{
58
+ it('should wrap value in ok result when value is provided', ()=>{
59
+ const result = ok({
60
+ value: 'value'
61
+ });
62
+ expect(result).toEqual({
63
+ ok: true,
64
+ value: 'value'
65
+ });
66
+ });
67
+ });
68
+ describe('sad', ()=>{
69
+ it('should keep undefined value when undefined is passed', ()=>{
70
+ const result = ok({
71
+ value: void 0
72
+ });
73
+ expect(result).toEqual({
74
+ ok: true,
75
+ value: void 0
76
+ });
77
+ });
78
+ });
79
+ });
80
+ describe('fail()', ()=>{
81
+ describe('happy', ()=>{
82
+ it('should wrap issues and meta in fail result when both are provided', ()=>{
83
+ const issues = [
84
+ createIssueForPath({
85
+ path: [],
86
+ message: 'invalid'
87
+ })
88
+ ];
89
+ const result = fail({
90
+ issues,
91
+ meta: {
92
+ type: 'string',
93
+ name: 'UserName'
94
+ }
95
+ });
96
+ expect(result).toEqual({
97
+ ok: false,
98
+ issues,
99
+ meta: {
100
+ type: 'string',
101
+ name: 'UserName'
102
+ }
103
+ });
104
+ });
105
+ });
106
+ describe('sad', ()=>{
107
+ it('should keep meta undefined when meta is omitted', ()=>{
108
+ const result = fail({
109
+ issues: [
110
+ createIssueForPath({
111
+ path: [],
112
+ message: 'invalid'
113
+ })
114
+ ]
115
+ });
116
+ expect(result.ok).toBe(false);
117
+ if (!result.ok) expect(result.meta).toBeUndefined();
118
+ });
119
+ });
120
+ });
121
+ describe('ensureSchemaContext()', ()=>{
122
+ describe('happy', ()=>{
123
+ it('should return provided context when context is provided', ()=>{
124
+ const providedContext = createSchemaContext();
125
+ const ensured = ensureSchemaContext(providedContext);
126
+ expect(ensured).toBe(providedContext);
127
+ });
128
+ it('should create context with request when context is omitted', ()=>{
129
+ const ensured = ensureSchemaContext();
130
+ expect(ensured.getRequestContext()).toBeDefined();
131
+ });
132
+ });
133
+ describe('sad', ()=>{
134
+ it('should still return usable context when context is omitted', ()=>{
135
+ const ensured = ensureSchemaContext();
136
+ expect(()=>ensured.state.snapshot()).not.toThrow();
137
+ });
138
+ });
139
+ });
140
+ describe('createSchema()', ()=>{
141
+ describe('happy', ()=>{
142
+ it('should parse value when validate returns ok result', ()=>{
143
+ const schema = createSchema({
144
+ name: 'StringSchema',
145
+ type: 'string',
146
+ ast: ()=>({
147
+ type: 'string'
148
+ }),
149
+ validate: (input)=>ok({
150
+ value: String(input)
151
+ })
152
+ });
153
+ const parsed = schema.parse(123, context);
154
+ expect(parsed).toBe('123');
155
+ });
156
+ it('should type value when typed is called', ()=>{
157
+ const schema = createSchema({
158
+ name: 'StringSchema',
159
+ type: 'string',
160
+ ast: ()=>({
161
+ type: 'string'
162
+ }),
163
+ validate: (input)=>ok({
164
+ value: String(input)
165
+ })
166
+ });
167
+ const typed = schema.typed('abc', context);
168
+ expect(typed).toBe('abc');
169
+ });
170
+ it('should return undefined when optional schema parses undefined', ()=>{
171
+ const schema = createSchema({
172
+ name: 'StringSchema',
173
+ type: 'string',
174
+ ast: ()=>({
175
+ type: 'string'
176
+ }),
177
+ validate: (input)=>'string' == typeof input ? ok({
178
+ value: input
179
+ }) : fail({
180
+ issues: [
181
+ createIssueForPath({
182
+ path: [],
183
+ message: 'Expected string'
184
+ })
185
+ ]
186
+ })
187
+ });
188
+ const optionalSchema = schema.optional();
189
+ const parsed = optionalSchema.parse(void 0, context);
190
+ expect(parsed).toBeUndefined();
191
+ });
192
+ it('should return null when nullable schema parses null', ()=>{
193
+ const schema = createSchema({
194
+ name: 'StringSchema',
195
+ type: 'string',
196
+ ast: ()=>({
197
+ type: 'string'
198
+ }),
199
+ validate: (input)=>'string' == typeof input ? ok({
200
+ value: input
201
+ }) : fail({
202
+ issues: [
203
+ createIssueForPath({
204
+ path: [],
205
+ message: 'Expected string'
206
+ })
207
+ ]
208
+ })
209
+ });
210
+ const nullableSchema = schema.nullable();
211
+ const parsed = nullableSchema.parse(null, context);
212
+ expect(parsed).toBeNull();
213
+ });
214
+ it('should merge doc into ast when describe is used', ()=>{
215
+ const schema = createSchema({
216
+ name: 'StringSchema',
217
+ type: 'string',
218
+ ast: ()=>({
219
+ type: 'string',
220
+ name: 'StringSchema',
221
+ doc: {
222
+ source: 'base'
223
+ }
224
+ }),
225
+ validate: (input)=>ok({
226
+ value: String(input)
227
+ })
228
+ });
229
+ const described = schema.describe({
230
+ summary: "description doc"
231
+ });
232
+ const ast = described.ast();
233
+ expect(ast.doc).toEqual({
234
+ source: 'base',
235
+ summary: "description doc"
236
+ });
237
+ });
238
+ it('should keep value when refine predicate returns true', ()=>{
239
+ const schema = createSchema({
240
+ name: 'NumberSchema',
241
+ type: 'number',
242
+ ast: ()=>({
243
+ type: 'number'
244
+ }),
245
+ validate: (input)=>ok({
246
+ value: Number(input)
247
+ })
248
+ });
249
+ const refined = schema.refine({
250
+ predicate: (value)=>value > 0,
251
+ message: 'Expected positive number',
252
+ code: 'number.positive'
253
+ });
254
+ const parsed = refined.parse(10, context);
255
+ expect(parsed).toBe(10);
256
+ });
257
+ it('should pass transformed input to base validator when before hook returns input object', ()=>{
258
+ const schema = createSchema({
259
+ name: 'StringSchema',
260
+ type: 'string',
261
+ ast: ()=>({
262
+ type: 'string'
263
+ }),
264
+ validate: (input)=>ok({
265
+ value: String(input)
266
+ })
267
+ });
268
+ const transformed = schema.before((input)=>({
269
+ input: String(input).trim()
270
+ }));
271
+ const parsed = transformed.parse(' Alice ', context);
272
+ expect(parsed).toBe('Alice');
273
+ });
274
+ it('should transform value when after hook returns value object', ()=>{
275
+ const schema = createSchema({
276
+ name: 'StringSchema',
277
+ type: 'string',
278
+ ast: ()=>({
279
+ type: 'string'
280
+ }),
281
+ validate: (input)=>ok({
282
+ value: String(input)
283
+ })
284
+ });
285
+ const transformed = schema.after((value)=>({
286
+ value: value.toUpperCase()
287
+ }));
288
+ const parsed = transformed.parse('alice', context);
289
+ expect(parsed).toBe('ALICE');
290
+ });
291
+ it('should merge schemas when and schemas both validate successfully', ()=>{
292
+ const left = createSchema({
293
+ name: 'Left',
294
+ type: 'left',
295
+ ast: ()=>({
296
+ type: 'left',
297
+ name: 'Left'
298
+ }),
299
+ validate: ()=>ok({
300
+ value: {
301
+ id: 'u-1'
302
+ }
303
+ })
304
+ });
305
+ const right = createSchema({
306
+ name: 'Right',
307
+ type: 'right',
308
+ ast: ()=>({
309
+ type: 'right',
310
+ name: 'Right'
311
+ }),
312
+ validate: ()=>ok({
313
+ value: {
314
+ role: 'admin'
315
+ }
316
+ })
317
+ });
318
+ const merged = left.and(right);
319
+ const parsed = merged.parse('raw', context);
320
+ const ast = merged.ast();
321
+ expect(parsed).toEqual({
322
+ id: 'u-1'
323
+ });
324
+ expect(ast.type).toBe('and');
325
+ expect(ast.children).toHaveLength(2);
326
+ });
327
+ it('should set fallback node name when ast result has no name', ()=>{
328
+ const schema = createSchema({
329
+ name: 'FallbackName',
330
+ type: 'custom',
331
+ ast: ()=>({
332
+ type: 'custom'
333
+ }),
334
+ validate: (input)=>ok({
335
+ value: input
336
+ })
337
+ });
338
+ const ast = schema.ast();
339
+ expect(ast.name).toBe('FallbackName');
340
+ });
341
+ });
342
+ describe('sad', ()=>{
343
+ it('should throw validation error when validate returns fail result', ()=>{
344
+ const schema = createSchema({
345
+ name: 'StringSchema',
346
+ type: 'string',
347
+ ast: ()=>({
348
+ type: 'string'
349
+ }),
350
+ validate: ()=>fail({
351
+ issues: [
352
+ createIssueForPath({
353
+ path: [],
354
+ message: 'Expected string',
355
+ code: 'string.type'
356
+ })
357
+ ]
358
+ })
359
+ });
360
+ expect(()=>schema.parse(1, context)).toThrowError('Schema validation failed');
361
+ });
362
+ it('should fail refine when predicate returns false', ()=>{
363
+ const schema = createSchema({
364
+ name: 'NumberSchema',
365
+ type: 'number',
366
+ ast: ()=>({
367
+ type: 'number'
368
+ }),
369
+ validate: (input)=>ok({
370
+ value: Number(input)
371
+ })
372
+ });
373
+ const refined = schema.refine({
374
+ predicate: (value)=>value > 10,
375
+ message: 'Expected value greater than ten',
376
+ code: 'number.greaterThanTen'
377
+ });
378
+ const result = refined.validate(5, context);
379
+ expect(result).toEqual({
380
+ ok: false,
381
+ issues: [
382
+ {
383
+ path: [],
384
+ message: 'Expected value greater than ten',
385
+ code: 'number.greaterThanTen'
386
+ }
387
+ ],
388
+ meta: expect.any(Object)
389
+ });
390
+ });
391
+ it('should fail before validation when before hook returns issues', ()=>{
392
+ const schema = createSchema({
393
+ name: 'StringSchema',
394
+ type: 'string',
395
+ ast: ()=>({
396
+ type: 'string'
397
+ }),
398
+ validate: (input)=>ok({
399
+ value: String(input)
400
+ })
401
+ });
402
+ const withBefore = schema.before(()=>({
403
+ issues: [
404
+ createIssueForPath({
405
+ path: [],
406
+ message: 'blocked by before hook'
407
+ })
408
+ ]
409
+ }));
410
+ const result = withBefore.validate('value', context);
411
+ expect(result).toEqual({
412
+ ok: false,
413
+ issues: [
414
+ {
415
+ path: [],
416
+ message: 'blocked by before hook'
417
+ }
418
+ ],
419
+ meta: expect.any(Object)
420
+ });
421
+ });
422
+ it('should fail after validation when after hook returns issues', ()=>{
423
+ const schema = createSchema({
424
+ name: 'StringSchema',
425
+ type: 'string',
426
+ ast: ()=>({
427
+ type: 'string'
428
+ }),
429
+ validate: (input)=>ok({
430
+ value: String(input)
431
+ })
432
+ });
433
+ const withAfter = schema.after(()=>({
434
+ issues: [
435
+ createIssueForPath({
436
+ path: [],
437
+ message: 'blocked by after hook'
438
+ })
439
+ ]
440
+ }));
441
+ const result = withAfter.validate('value', context);
442
+ expect(result).toEqual({
443
+ ok: false,
444
+ issues: [
445
+ {
446
+ path: [],
447
+ message: 'blocked by after hook'
448
+ }
449
+ ],
450
+ meta: expect.any(Object)
451
+ });
452
+ });
453
+ it('should combine issues when and schema has failing left and right branches', ()=>{
454
+ const leftIssue = createIssueForPath({
455
+ path: [
456
+ 'left'
457
+ ],
458
+ message: 'left failed'
459
+ });
460
+ const rightIssue = createIssueForPath({
461
+ path: [
462
+ 'right'
463
+ ],
464
+ message: 'right failed'
465
+ });
466
+ const left = createSchema({
467
+ name: 'Left',
468
+ type: 'left',
469
+ ast: ()=>({
470
+ type: 'left',
471
+ name: 'Left'
472
+ }),
473
+ validate: ()=>fail({
474
+ issues: [
475
+ leftIssue
476
+ ]
477
+ })
478
+ });
479
+ const right = createSchema({
480
+ name: 'Right',
481
+ type: 'right',
482
+ ast: ()=>({
483
+ type: 'right',
484
+ name: 'Right'
485
+ }),
486
+ validate: ()=>fail({
487
+ issues: [
488
+ rightIssue
489
+ ]
490
+ })
491
+ });
492
+ const merged = left.and(right);
493
+ const result = merged.validate('raw', context);
494
+ expect(result).toEqual({
495
+ ok: false,
496
+ issues: [
497
+ leftIssue,
498
+ rightIssue
499
+ ],
500
+ meta: expect.any(Object)
501
+ });
502
+ });
503
+ });
504
+ });
505
+ describe('createGuardSchema()', ()=>{
506
+ describe('happy', ()=>{
507
+ it('should parse value when guard returns true', ()=>{
508
+ const schema = createGuardSchema({
509
+ name: 'GuardedString',
510
+ type: 'string',
511
+ guard: (input)=>'string' == typeof input,
512
+ message: 'Expected string',
513
+ code: 'string.type'
514
+ });
515
+ const parsed = schema.parse('ok', context);
516
+ expect(parsed).toBe('ok');
517
+ });
518
+ });
519
+ describe('sad', ()=>{
520
+ it('should fail when guard returns false', ()=>{
521
+ const schema = createGuardSchema({
522
+ name: 'GuardedString',
523
+ type: 'string',
524
+ guard: (input)=>'string' == typeof input,
525
+ message: 'Expected string',
526
+ code: 'string.type'
527
+ });
528
+ const result = schema.validate(1, context);
529
+ expect(result).toEqual({
530
+ ok: false,
531
+ issues: [
532
+ {
533
+ path: [],
534
+ message: 'Expected string',
535
+ code: 'string.type'
536
+ }
537
+ ],
538
+ meta: expect.any(Object)
539
+ });
540
+ });
541
+ });
542
+ });
543
+ describe('createPrimitiveSchema()', ()=>{
544
+ describe('happy', ()=>{
545
+ it('should parse value when primitive guard returns true', ()=>{
546
+ const schema = createPrimitiveSchema({
547
+ name: 'PrimitiveString',
548
+ type: 'string',
549
+ guard: (input)=>'string' == typeof input,
550
+ message: 'Expected string',
551
+ code: 'string.type'
552
+ });
553
+ const parsed = schema.parse('ok', context);
554
+ expect(parsed).toBe('ok');
555
+ });
556
+ });
557
+ describe('sad', ()=>{
558
+ it('should fail when primitive guard returns false', ()=>{
559
+ const schema = createPrimitiveSchema({
560
+ name: 'PrimitiveString',
561
+ type: 'string',
562
+ guard: (input)=>'string' == typeof input,
563
+ message: 'Expected string',
564
+ code: 'string.type'
565
+ });
566
+ const result = schema.validate(1, context);
567
+ expect(result).toEqual({
568
+ ok: false,
569
+ issues: [
570
+ {
571
+ path: [],
572
+ message: 'Expected string',
573
+ code: 'string.type'
574
+ }
575
+ ],
576
+ meta: expect.any(Object)
577
+ });
578
+ });
579
+ });
580
+ });
581
+ });
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ schemaFactory: ()=>schemaFactory,
28
+ guardFactory: ()=>guardFactory
29
+ });
30
+ const external_schema_cjs_namespaceObject = require("./schema.cjs");
31
+ const external_doc_cjs_namespaceObject = require("./doc.cjs");
32
+ const normalizeError = (error)=>{
33
+ if (error && 'object' == typeof error && 'message' in error) {
34
+ const err = error;
35
+ return {
36
+ message: err.message,
37
+ code: err.code,
38
+ context: err.context
39
+ };
40
+ }
41
+ return {
42
+ message: 'Schema validation failed'
43
+ };
44
+ };
45
+ const schemaFactory = ({ name, type, validate, ast, doc, chain })=>{
46
+ const docRecord = (0, external_doc_cjs_namespaceObject.normalizeDoc)(doc);
47
+ const astWithDoc = docRecord ? (ctx)=>{
48
+ const node = ast(ctx);
49
+ const merged = (0, external_doc_cjs_namespaceObject.mergeDoc)(node.doc, docRecord);
50
+ return merged ? {
51
+ ...node,
52
+ doc: merged
53
+ } : node;
54
+ } : ast;
55
+ const base = (0, external_schema_cjs_namespaceObject.createSchema)({
56
+ name,
57
+ type,
58
+ ast: astWithDoc,
59
+ validate: (input, ctx)=>{
60
+ const context = (0, external_schema_cjs_namespaceObject.ensureSchemaContext)(ctx);
61
+ try {
62
+ const value = validate(input, context);
63
+ return (0, external_schema_cjs_namespaceObject.ok)({
64
+ value
65
+ });
66
+ } catch (error) {
67
+ const normalized = normalizeError(error);
68
+ return (0, external_schema_cjs_namespaceObject.fail)({
69
+ issues: [
70
+ (0, external_schema_cjs_namespaceObject.createIssueForPath)({
71
+ path: [],
72
+ message: normalized.message,
73
+ code: normalized.code,
74
+ context: normalized.context
75
+ })
76
+ ]
77
+ });
78
+ }
79
+ }
80
+ });
81
+ const result = base;
82
+ if (!chain) return result;
83
+ Object.entries(chain).forEach(([key, operation])=>{
84
+ result[key] = (...args)=>schemaFactory({
85
+ name: `${name}.${key}`,
86
+ type,
87
+ ast,
88
+ validate: (input, ctx)=>{
89
+ const context = (0, external_schema_cjs_namespaceObject.ensureSchemaContext)(ctx);
90
+ const value = base.parse(input, context);
91
+ const next = operation(value, context)(...args);
92
+ return next;
93
+ },
94
+ chain: chain
95
+ });
96
+ });
97
+ return result;
98
+ };
99
+ const guardFactory = ({ name, type, guard, message, code })=>schemaFactory({
100
+ name,
101
+ type,
102
+ ast: ()=>({
103
+ type,
104
+ name
105
+ }),
106
+ validate: (input)=>{
107
+ if (!guard(input)) {
108
+ const error = {
109
+ message,
110
+ code
111
+ };
112
+ throw error;
113
+ }
114
+ return input;
115
+ }
116
+ });
117
+ exports.guardFactory = __webpack_exports__.guardFactory;
118
+ exports.schemaFactory = __webpack_exports__.schemaFactory;
119
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
120
+ "guardFactory",
121
+ "schemaFactory"
122
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
123
+ Object.defineProperty(exports, '__esModule', {
124
+ value: true
125
+ });