@amritk/generate-parsers 0.7.2 → 0.9.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.
- package/README.md +1 -1
- package/dist/generators/build-schema.d.ts +0 -1
- package/dist/generators/generate-default-from-pattern.d.ts +0 -1
- package/dist/generators/generate-discriminated-union-validation.d.ts +0 -1
- package/dist/generators/generate-enum-check.d.ts +0 -1
- package/dist/generators/generate-files.d.ts +0 -1
- package/dist/generators/generate-non-discriminated-union-validation.d.ts +0 -1
- package/dist/generators/generate-parser-function.d.ts +3 -3
- package/dist/generators/generate-parser-function.js +267 -32
- package/dist/generators/generate-schema-checks.d.ts +0 -1
- package/dist/generators/generate-strict-assertion.d.ts +0 -1
- package/dist/generators/generate-validation-expression.d.ts +0 -1
- package/dist/helpers/apply-schema-extensions.d.ts +0 -1
- package/dist/helpers/collect-helpers.d.ts +0 -1
- package/dist/helpers/collect-imports.d.ts +0 -1
- package/dist/helpers/find-discriminator.d.ts +0 -1
- package/dist/helpers/get-default-value.d.ts +0 -1
- package/dist/helpers/get-discriminator-value.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/types/schema-extensions.d.ts +0 -1
- package/package.json +3 -5
- package/dist/generators/build-schema.d.ts.map +0 -1
- package/dist/generators/generate-default-from-pattern.d.ts.map +0 -1
- package/dist/generators/generate-discriminated-union-validation.d.ts.map +0 -1
- package/dist/generators/generate-enum-check.d.ts.map +0 -1
- package/dist/generators/generate-files.d.ts.map +0 -1
- package/dist/generators/generate-non-discriminated-union-validation.d.ts.map +0 -1
- package/dist/generators/generate-parser-function.d.ts.map +0 -1
- package/dist/generators/generate-schema-checks.d.ts.map +0 -1
- package/dist/generators/generate-strict-assertion.d.ts.map +0 -1
- package/dist/generators/generate-validation-expression.d.ts.map +0 -1
- package/dist/helpers/apply-schema-extensions.d.ts.map +0 -1
- package/dist/helpers/collect-helpers.d.ts.map +0 -1
- package/dist/helpers/collect-imports.d.ts.map +0 -1
- package/dist/helpers/find-discriminator.d.ts.map +0 -1
- package/dist/helpers/get-default-value.d.ts.map +0 -1
- package/dist/helpers/get-discriminator-value.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types/schema-extensions.d.ts.map +0 -1
- package/src/generators/build-schema.test.ts +0 -854
- package/src/generators/build-schema.ts +0 -147
- package/src/generators/generate-default-from-pattern.test.ts +0 -81
- package/src/generators/generate-default-from-pattern.ts +0 -39
- package/src/generators/generate-discriminated-union-validation.test.ts +0 -84
- package/src/generators/generate-discriminated-union-validation.ts +0 -54
- package/src/generators/generate-enum-check.test.ts +0 -45
- package/src/generators/generate-enum-check.ts +0 -8
- package/src/generators/generate-files.test.ts +0 -448
- package/src/generators/generate-files.ts +0 -155
- package/src/generators/generate-non-discriminated-union-validation.test.ts +0 -74
- package/src/generators/generate-non-discriminated-union-validation.ts +0 -40
- package/src/generators/generate-parser-function.test.ts +0 -1794
- package/src/generators/generate-parser-function.ts +0 -1340
- package/src/generators/generate-schema-checks.test.ts +0 -330
- package/src/generators/generate-schema-checks.ts +0 -128
- package/src/generators/generate-strict-assertion.test.ts +0 -67
- package/src/generators/generate-strict-assertion.ts +0 -243
- package/src/generators/generate-validation-expression.test.ts +0 -831
- package/src/generators/generate-validation-expression.ts +0 -327
- package/src/helpers/apply-schema-extensions.test.ts +0 -194
- package/src/helpers/apply-schema-extensions.ts +0 -63
- package/src/helpers/collect-helpers.test.ts +0 -115
- package/src/helpers/collect-helpers.ts +0 -79
- package/src/helpers/collect-imports.test.ts +0 -547
- package/src/helpers/collect-imports.ts +0 -275
- package/src/helpers/find-discriminator.test.ts +0 -88
- package/src/helpers/find-discriminator.ts +0 -39
- package/src/helpers/get-default-value.test.ts +0 -139
- package/src/helpers/get-default-value.ts +0 -95
- package/src/helpers/get-discriminator-value.test.ts +0 -83
- package/src/helpers/get-discriminator-value.ts +0 -21
- package/src/index.ts +0 -1
- package/src/types/schema-extensions.ts +0 -35
|
@@ -1,831 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { generateValidationExpression } from './generate-validation-expression'
|
|
4
|
-
|
|
5
|
-
describe('generate-validation-expression', () => {
|
|
6
|
-
it('returns accessor with nullish coalescing for non-schema objects when required', () => {
|
|
7
|
-
const result = generateValidationExpression('name', true, '""', true)
|
|
8
|
-
expect(result).toBe('input?.name ?? ""')
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
it('returns accessor without default for non-schema objects when optional', () => {
|
|
12
|
-
const result = generateValidationExpression('name', true, '""', false)
|
|
13
|
-
expect(result).toBe('input?.name')
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('generates string type validation', () => {
|
|
17
|
-
const schema = { type: 'string' as const }
|
|
18
|
-
const result = generateValidationExpression('name', schema, '""', true)
|
|
19
|
-
|
|
20
|
-
expect(result).toContain('typeof input?.name === "string"')
|
|
21
|
-
expect(result).toContain('String(input?.name)')
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('generates string validation with pattern', () => {
|
|
25
|
-
const schema = { type: 'string' as const, pattern: '^[A-Z]' }
|
|
26
|
-
const result = generateValidationExpression('code', schema, '""', true)
|
|
27
|
-
|
|
28
|
-
expect(result).toContain('typeof input?.code === "string"')
|
|
29
|
-
expect(result).toContain('/^[A-Z]/.test(input?.code)')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('generates string validation with minLength', () => {
|
|
33
|
-
const schema = { type: 'string' as const, minLength: 5 }
|
|
34
|
-
const result = generateValidationExpression('name', schema, '""', true)
|
|
35
|
-
|
|
36
|
-
expect(result).toContain('typeof input?.name === "string"')
|
|
37
|
-
expect(result).toContain('input?.name.length >= 5')
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('generates string validation with maxLength', () => {
|
|
41
|
-
const schema = { type: 'string' as const, maxLength: 100 }
|
|
42
|
-
const result = generateValidationExpression('name', schema, '""', true)
|
|
43
|
-
|
|
44
|
-
expect(result).toContain('typeof input?.name === "string"')
|
|
45
|
-
expect(result).toContain('input?.name.length <= 100')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('generates string validation with minLength and maxLength', () => {
|
|
49
|
-
const schema = { type: 'string' as const, minLength: 5, maxLength: 100 }
|
|
50
|
-
const result = generateValidationExpression('name', schema, '""', true)
|
|
51
|
-
|
|
52
|
-
expect(result).toContain('input?.name.length >= 5')
|
|
53
|
-
expect(result).toContain('input?.name.length <= 100')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('generates number type validation', () => {
|
|
57
|
-
const schema = { type: 'number' as const }
|
|
58
|
-
const result = generateValidationExpression('age', schema, '0', true)
|
|
59
|
-
|
|
60
|
-
expect(result).toContain('typeof input?.age === "number"')
|
|
61
|
-
expect(result).toContain('Number(input?.age)')
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('generates number validation with minimum', () => {
|
|
65
|
-
const schema = { type: 'number' as const, minimum: 0 }
|
|
66
|
-
const result = generateValidationExpression('age', schema, '0', true)
|
|
67
|
-
|
|
68
|
-
expect(result).toContain('typeof input?.age === "number"')
|
|
69
|
-
expect(result).toContain('input?.age >= 0')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('generates number validation with maximum', () => {
|
|
73
|
-
const schema = { type: 'number' as const, maximum: 100 }
|
|
74
|
-
const result = generateValidationExpression('score', schema, '0', true)
|
|
75
|
-
|
|
76
|
-
expect(result).toContain('typeof input?.score === "number"')
|
|
77
|
-
expect(result).toContain('input?.score <= 100')
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('generates number validation with exclusiveMinimum', () => {
|
|
81
|
-
const schema = { type: 'number' as const, exclusiveMinimum: 0 }
|
|
82
|
-
const result = generateValidationExpression('price', schema, '0', true)
|
|
83
|
-
|
|
84
|
-
expect(result).toContain('typeof input?.price === "number"')
|
|
85
|
-
expect(result).toContain('input?.price > 0')
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('generates number validation with exclusiveMaximum', () => {
|
|
89
|
-
const schema = { type: 'number' as const, exclusiveMaximum: 100 }
|
|
90
|
-
const result = generateValidationExpression('percentage', schema, '0', true)
|
|
91
|
-
|
|
92
|
-
expect(result).toContain('typeof input?.percentage === "number"')
|
|
93
|
-
expect(result).toContain('input?.percentage < 100')
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('generates number validation with multipleOf', () => {
|
|
97
|
-
const schema = { type: 'number' as const, multipleOf: 5 }
|
|
98
|
-
const result = generateValidationExpression('quantity', schema, '0', true)
|
|
99
|
-
|
|
100
|
-
expect(result).toContain('typeof input?.quantity === "number"')
|
|
101
|
-
expect(result).toContain('input?.quantity % 5 === 0')
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('generates integer type validation', () => {
|
|
105
|
-
const schema = { type: 'integer' as const }
|
|
106
|
-
const result = generateValidationExpression('count', schema, '0', true)
|
|
107
|
-
|
|
108
|
-
expect(result).toContain('typeof input?.count === "number"')
|
|
109
|
-
expect(result).toContain('Number(input?.count)')
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
it('generates boolean type validation', () => {
|
|
113
|
-
const schema = { type: 'boolean' as const }
|
|
114
|
-
const result = generateValidationExpression('isActive', schema, 'false', true)
|
|
115
|
-
|
|
116
|
-
expect(result).toContain('typeof input?.isActive === "boolean"')
|
|
117
|
-
expect(result).toContain('Boolean(input?.isActive)')
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('generates array type validation', () => {
|
|
121
|
-
const schema = { type: 'array' as const }
|
|
122
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
123
|
-
|
|
124
|
-
expect(result).toContain('Array.isArray(input?.tags) ? input?.tags :')
|
|
125
|
-
expect(result).not.toContain('Array.isArray(input?.tags) ? input?.tags : Array.isArray')
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it('generates array validation with minItems', () => {
|
|
129
|
-
const schema = { type: 'array' as const, minItems: 1 }
|
|
130
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
131
|
-
|
|
132
|
-
expect(result).toContain('Array.isArray(input?.tags)')
|
|
133
|
-
expect(result).toContain('input?.tags.length >= 1')
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it('generates array validation with maxItems', () => {
|
|
137
|
-
const schema = { type: 'array' as const, maxItems: 10 }
|
|
138
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
139
|
-
|
|
140
|
-
expect(result).toContain('Array.isArray(input?.tags)')
|
|
141
|
-
expect(result).toContain('input?.tags.length <= 10')
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
it('generates array validation with uniqueItems', () => {
|
|
145
|
-
const schema = { type: 'array' as const, uniqueItems: true }
|
|
146
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
147
|
-
|
|
148
|
-
expect(result).toContain('Array.isArray(input?.tags)')
|
|
149
|
-
expect(result).toContain('new Set(input?.tags).size === input?.tags.length')
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
it('generates object type validation', () => {
|
|
153
|
-
const schema = { type: 'object' as const }
|
|
154
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
155
|
-
|
|
156
|
-
expect(result).toContain('isObject(input?.user)')
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
it('generates object validation with required properties', () => {
|
|
160
|
-
const schema = {
|
|
161
|
-
type: 'object' as const,
|
|
162
|
-
properties: {
|
|
163
|
-
id: { type: 'number' as const },
|
|
164
|
-
name: { type: 'string' as const },
|
|
165
|
-
},
|
|
166
|
-
required: ['id', 'name'],
|
|
167
|
-
}
|
|
168
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
169
|
-
|
|
170
|
-
expect(result).toContain('"id" in input?.user')
|
|
171
|
-
expect(result).toContain('"name" in input?.user')
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it('generates object validation with minProperties', () => {
|
|
175
|
-
const schema = { type: 'object' as const, minProperties: 2 }
|
|
176
|
-
const result = generateValidationExpression('data', schema, '{}', true)
|
|
177
|
-
|
|
178
|
-
expect(result).toContain('Object.keys(input?.data).length >= 2')
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
it('generates object validation with maxProperties', () => {
|
|
182
|
-
const schema = { type: 'object' as const, maxProperties: 5 }
|
|
183
|
-
const result = generateValidationExpression('data', schema, '{}', true)
|
|
184
|
-
|
|
185
|
-
expect(result).toContain('Object.keys(input?.data).length <= 5')
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
it('generates object validation with additionalProperties false', () => {
|
|
189
|
-
const schema = {
|
|
190
|
-
type: 'object' as const,
|
|
191
|
-
properties: {
|
|
192
|
-
id: { type: 'number' as const },
|
|
193
|
-
name: { type: 'string' as const },
|
|
194
|
-
},
|
|
195
|
-
additionalProperties: false,
|
|
196
|
-
}
|
|
197
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
198
|
-
|
|
199
|
-
expect(result).toContain('Object.keys(input?.user).every(k => ["id","name"].includes(k))')
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
it('generates enum validation', () => {
|
|
203
|
-
const schema = { enum: ['red', 'green', 'blue'] }
|
|
204
|
-
const result = generateValidationExpression('color', schema, '"red"', true)
|
|
205
|
-
|
|
206
|
-
expect(result).toContain('["red","green","blue"].includes(input?.color as never)')
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
it('generates enum validation with type', () => {
|
|
210
|
-
const schema = { type: 'string' as const, enum: ['active', 'inactive'] }
|
|
211
|
-
const result = generateValidationExpression('status', schema, '"active"', true)
|
|
212
|
-
|
|
213
|
-
expect(result).toContain('typeof input?.status === "string"')
|
|
214
|
-
expect(result).toContain('["active","inactive"].includes(input?.status as never)')
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
it('handles $ref resolution', () => {
|
|
218
|
-
const rootSchema = {
|
|
219
|
-
$defs: {
|
|
220
|
-
Address: {
|
|
221
|
-
type: 'object' as const,
|
|
222
|
-
properties: {
|
|
223
|
-
street: { type: 'string' as const },
|
|
224
|
-
city: { type: 'string' as const },
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
}
|
|
229
|
-
const schema = { $ref: '#/$defs/Address' }
|
|
230
|
-
const result = generateValidationExpression('address', schema, '{}', true, rootSchema)
|
|
231
|
-
|
|
232
|
-
expect(result).toContain('typeof input?.address === "object"')
|
|
233
|
-
expect(result).toContain('input?.address !== null')
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
it('handles circular $ref by breaking cycle', () => {
|
|
237
|
-
const rootSchema = {
|
|
238
|
-
$defs: {
|
|
239
|
-
Node: {
|
|
240
|
-
type: 'object' as const,
|
|
241
|
-
properties: {
|
|
242
|
-
value: { type: 'string' as const },
|
|
243
|
-
next: { $ref: '#/$defs/Node' },
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
}
|
|
248
|
-
const schema = { $ref: '#/$defs/Node' }
|
|
249
|
-
const visitedRefs = new Set(['#/$defs/Node'])
|
|
250
|
-
const result = generateValidationExpression('node', schema, '{}', true, rootSchema, visitedRefs)
|
|
251
|
-
|
|
252
|
-
expect(result).toBe('input?.node ?? {}')
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
it('handles unresolvable $ref', () => {
|
|
256
|
-
const rootSchema = {}
|
|
257
|
-
const schema = { $ref: '#/$defs/NonExistent' }
|
|
258
|
-
const result = generateValidationExpression('data', schema, '{}', true, rootSchema)
|
|
259
|
-
|
|
260
|
-
expect(result).toBe('input?.data ?? {}')
|
|
261
|
-
})
|
|
262
|
-
|
|
263
|
-
it('generates oneOf validation without discriminator', () => {
|
|
264
|
-
const schema = {
|
|
265
|
-
oneOf: [{ type: 'string' as const }, { type: 'number' as const }],
|
|
266
|
-
}
|
|
267
|
-
const result = generateValidationExpression('value', schema, '""', true)
|
|
268
|
-
|
|
269
|
-
expect(result).toContain('typeof input?.value === "string"')
|
|
270
|
-
expect(result).toContain('typeof input?.value === "number"')
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
it('generates oneOf validation with discriminator', () => {
|
|
274
|
-
const schema = {
|
|
275
|
-
oneOf: [
|
|
276
|
-
{
|
|
277
|
-
type: 'object' as const,
|
|
278
|
-
properties: {
|
|
279
|
-
type: { const: 'circle' },
|
|
280
|
-
radius: { type: 'number' as const },
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
type: 'object' as const,
|
|
285
|
-
properties: {
|
|
286
|
-
type: { const: 'square' },
|
|
287
|
-
side: { type: 'number' as const },
|
|
288
|
-
},
|
|
289
|
-
},
|
|
290
|
-
],
|
|
291
|
-
}
|
|
292
|
-
const result = generateValidationExpression('shape', schema, '{}', true)
|
|
293
|
-
|
|
294
|
-
expect(result).toContain('input?.shape?.type')
|
|
295
|
-
})
|
|
296
|
-
|
|
297
|
-
it('generates anyOf validation without discriminator', () => {
|
|
298
|
-
const schema = {
|
|
299
|
-
anyOf: [{ type: 'string' as const }, { type: 'number' as const }],
|
|
300
|
-
}
|
|
301
|
-
const result = generateValidationExpression('value', schema, '""', true)
|
|
302
|
-
|
|
303
|
-
expect(result).toContain('typeof input?.value === "string"')
|
|
304
|
-
expect(result).toContain('typeof input?.value === "number"')
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
it('generates anyOf validation with discriminator', () => {
|
|
308
|
-
const schema = {
|
|
309
|
-
anyOf: [
|
|
310
|
-
{
|
|
311
|
-
type: 'object' as const,
|
|
312
|
-
properties: {
|
|
313
|
-
kind: { const: 'A' },
|
|
314
|
-
valueA: { type: 'string' as const },
|
|
315
|
-
},
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
type: 'object' as const,
|
|
319
|
-
properties: {
|
|
320
|
-
kind: { const: 'B' },
|
|
321
|
-
valueB: { type: 'number' as const },
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
],
|
|
325
|
-
}
|
|
326
|
-
const result = generateValidationExpression('data', schema, '{}', true)
|
|
327
|
-
|
|
328
|
-
expect(result).toContain('input?.data?.kind')
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
it('generates allOf validation', () => {
|
|
332
|
-
const schema = {
|
|
333
|
-
allOf: [{ type: 'object' as const }, { properties: { id: { type: 'number' as const } } }],
|
|
334
|
-
}
|
|
335
|
-
const result = generateValidationExpression('entity', schema, '{}', true)
|
|
336
|
-
|
|
337
|
-
expect(result).toContain('typeof input?.entity === "object"')
|
|
338
|
-
expect(result).toContain('input?.entity !== null')
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
it('generates not validation', () => {
|
|
342
|
-
const schema = {
|
|
343
|
-
not: { type: 'string' as const },
|
|
344
|
-
}
|
|
345
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
346
|
-
|
|
347
|
-
expect(result).toContain('!(typeof input?.value === "string")')
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
it('handles schema without type or enum for required field', () => {
|
|
351
|
-
const schema = { description: 'Any value' }
|
|
352
|
-
const result = generateValidationExpression('data', schema, 'null', true)
|
|
353
|
-
|
|
354
|
-
expect(result).toBe('input?.data ?? null')
|
|
355
|
-
})
|
|
356
|
-
|
|
357
|
-
it('handles schema without type or enum for optional field', () => {
|
|
358
|
-
const schema = { description: 'Any value' }
|
|
359
|
-
const result = generateValidationExpression('data', schema, 'null', false)
|
|
360
|
-
|
|
361
|
-
expect(result).toBe('input?.data ?? null')
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
it('returns default value for required field when validation fails', () => {
|
|
365
|
-
const schema = { type: 'string' as const }
|
|
366
|
-
const result = generateValidationExpression('name', schema, '""', true)
|
|
367
|
-
|
|
368
|
-
expect(result).toContain('? input?.name')
|
|
369
|
-
expect(result).toContain(': ""')
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
it('returns undefined for optional field when validation fails', () => {
|
|
373
|
-
const schema = { type: 'string' as const }
|
|
374
|
-
const result = generateValidationExpression('name', schema, '""', false)
|
|
375
|
-
|
|
376
|
-
expect(result).toContain('? input?.name')
|
|
377
|
-
expect(result).toContain(': undefined')
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
it('includes type coercion for required string field', () => {
|
|
381
|
-
const schema = { type: 'string' as const }
|
|
382
|
-
const result = generateValidationExpression('name', schema, '""', true)
|
|
383
|
-
|
|
384
|
-
expect(result).toContain('String(input?.name)')
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
it('includes type coercion for required number field', () => {
|
|
388
|
-
const schema = { type: 'number' as const }
|
|
389
|
-
const result = generateValidationExpression('age', schema, '0', true)
|
|
390
|
-
|
|
391
|
-
expect(result).toContain('Number(input?.age)')
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
it('includes type coercion for required boolean field', () => {
|
|
395
|
-
const schema = { type: 'boolean' as const }
|
|
396
|
-
const result = generateValidationExpression('isActive', schema, 'false', true)
|
|
397
|
-
|
|
398
|
-
expect(result).toContain('Boolean(input?.isActive)')
|
|
399
|
-
})
|
|
400
|
-
|
|
401
|
-
it('includes type coercion for required array field', () => {
|
|
402
|
-
const schema = { type: 'array' as const }
|
|
403
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
404
|
-
|
|
405
|
-
expect(result).toContain('Array.isArray(input?.tags) ? input?.tags :')
|
|
406
|
-
expect(result).not.toContain('Array.isArray(input?.tags) ? input?.tags : Array.isArray')
|
|
407
|
-
})
|
|
408
|
-
|
|
409
|
-
it('includes type coercion for required object field', () => {
|
|
410
|
-
const schema = { type: 'object' as const }
|
|
411
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
412
|
-
|
|
413
|
-
expect(result).toContain('typeof input?.user === "object" && input?.user !== null ? input?.user : {}')
|
|
414
|
-
})
|
|
415
|
-
|
|
416
|
-
it('includes type coercion for optional string field', () => {
|
|
417
|
-
const schema = { type: 'string' as const }
|
|
418
|
-
const result = generateValidationExpression('name', schema, '""', false)
|
|
419
|
-
|
|
420
|
-
expect(result).toContain('String(input?.name)')
|
|
421
|
-
})
|
|
422
|
-
|
|
423
|
-
it('includes type coercion for optional number field', () => {
|
|
424
|
-
const schema = { type: 'number' as const }
|
|
425
|
-
const result = generateValidationExpression('age', schema, '0', false)
|
|
426
|
-
|
|
427
|
-
expect(result).toContain('Number(input?.age)')
|
|
428
|
-
})
|
|
429
|
-
|
|
430
|
-
// Number() of a non-numeric string produces NaN, which silently poisons arithmetic.
|
|
431
|
-
// The coercion must guard against it and fall back to the schema default instead.
|
|
432
|
-
it('generates NaN-safe coercion for required number field', () => {
|
|
433
|
-
const schema = { type: 'number' as const }
|
|
434
|
-
const result = generateValidationExpression('age', schema, '0', true)
|
|
435
|
-
|
|
436
|
-
expect(result).toBe(
|
|
437
|
-
'typeof input?.age === "number" ? input?.age : (input?.age !== undefined ? (Number.isFinite(Number(input?.age)) ? Number(input?.age) : 0) : 0)',
|
|
438
|
-
)
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
it('generates NaN-safe coercion for required integer field', () => {
|
|
442
|
-
const schema = { type: 'integer' as const }
|
|
443
|
-
const result = generateValidationExpression('count', schema, '0', true)
|
|
444
|
-
|
|
445
|
-
expect(result).toBe(
|
|
446
|
-
'typeof input?.count === "number" ? input?.count : (input?.count !== undefined ? (Number.isFinite(Number(input?.count)) ? Number(input?.count) : 0) : 0)',
|
|
447
|
-
)
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
it('generates NaN-safe coercion for optional number field', () => {
|
|
451
|
-
const schema = { type: 'number' as const }
|
|
452
|
-
const result = generateValidationExpression('age', schema, '0', false)
|
|
453
|
-
|
|
454
|
-
expect(result).toBe(
|
|
455
|
-
'typeof input?.age === "number" ? input?.age : (input?.age !== undefined ? (Number.isFinite(Number(input?.age)) ? Number(input?.age) : 0) : undefined)',
|
|
456
|
-
)
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
it('generates NaN-safe coercion for required number field when knownNotUndefined', () => {
|
|
460
|
-
const schema = { type: 'number' as const }
|
|
461
|
-
const result = generateValidationExpression('age', schema, '0', true, undefined, undefined, undefined, true)
|
|
462
|
-
|
|
463
|
-
expect(result).toBe(
|
|
464
|
-
'typeof input?.age === "number" ? input?.age : (Number.isFinite(Number(input?.age)) ? Number(input?.age) : 0)',
|
|
465
|
-
)
|
|
466
|
-
})
|
|
467
|
-
|
|
468
|
-
it('handles empty oneOf array', () => {
|
|
469
|
-
const schema = { oneOf: [] }
|
|
470
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
471
|
-
|
|
472
|
-
expect(result).toBe('input?.value ?? null')
|
|
473
|
-
})
|
|
474
|
-
|
|
475
|
-
it('handles empty anyOf array', () => {
|
|
476
|
-
const schema = { anyOf: [] }
|
|
477
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
478
|
-
|
|
479
|
-
expect(result).toBe('input?.value ?? null')
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
it('handles empty allOf array', () => {
|
|
483
|
-
const schema = { allOf: [] }
|
|
484
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
485
|
-
|
|
486
|
-
expect(result).toBe('input?.value ?? null')
|
|
487
|
-
})
|
|
488
|
-
|
|
489
|
-
it('handles empty enum array', () => {
|
|
490
|
-
const schema = { enum: [] }
|
|
491
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
492
|
-
|
|
493
|
-
expect(result).toBe('input?.value ?? null')
|
|
494
|
-
})
|
|
495
|
-
|
|
496
|
-
it('combines multiple string constraints', () => {
|
|
497
|
-
const schema = {
|
|
498
|
-
type: 'string' as const,
|
|
499
|
-
pattern: '^[A-Z]',
|
|
500
|
-
minLength: 3,
|
|
501
|
-
maxLength: 10,
|
|
502
|
-
}
|
|
503
|
-
const result = generateValidationExpression('code', schema, '""', true)
|
|
504
|
-
|
|
505
|
-
expect(result).toContain('typeof input?.code === "string"')
|
|
506
|
-
expect(result).toContain('/^[A-Z]/.test(input?.code)')
|
|
507
|
-
expect(result).toContain('input?.code.length >= 3')
|
|
508
|
-
expect(result).toContain('input?.code.length <= 10')
|
|
509
|
-
})
|
|
510
|
-
|
|
511
|
-
it('combines multiple number constraints', () => {
|
|
512
|
-
const schema = {
|
|
513
|
-
type: 'number' as const,
|
|
514
|
-
minimum: 0,
|
|
515
|
-
maximum: 100,
|
|
516
|
-
multipleOf: 5,
|
|
517
|
-
}
|
|
518
|
-
const result = generateValidationExpression('score', schema, '0', true)
|
|
519
|
-
|
|
520
|
-
expect(result).toContain('typeof input?.score === "number"')
|
|
521
|
-
expect(result).toContain('input?.score >= 0')
|
|
522
|
-
expect(result).toContain('input?.score <= 100')
|
|
523
|
-
expect(result).toContain('input?.score % 5 === 0')
|
|
524
|
-
})
|
|
525
|
-
|
|
526
|
-
it('combines multiple array constraints', () => {
|
|
527
|
-
const schema = {
|
|
528
|
-
type: 'array' as const,
|
|
529
|
-
minItems: 1,
|
|
530
|
-
maxItems: 10,
|
|
531
|
-
uniqueItems: true,
|
|
532
|
-
}
|
|
533
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
534
|
-
|
|
535
|
-
expect(result).toContain('Array.isArray(input?.tags)')
|
|
536
|
-
expect(result).toContain('input?.tags.length >= 1')
|
|
537
|
-
expect(result).toContain('input?.tags.length <= 10')
|
|
538
|
-
expect(result).toContain('new Set(input?.tags).size === input?.tags.length')
|
|
539
|
-
})
|
|
540
|
-
|
|
541
|
-
it('combines multiple object constraints', () => {
|
|
542
|
-
const schema = {
|
|
543
|
-
type: 'object' as const,
|
|
544
|
-
properties: {
|
|
545
|
-
id: { type: 'number' as const },
|
|
546
|
-
name: { type: 'string' as const },
|
|
547
|
-
},
|
|
548
|
-
required: ['id'],
|
|
549
|
-
minProperties: 1,
|
|
550
|
-
maxProperties: 5,
|
|
551
|
-
additionalProperties: false,
|
|
552
|
-
}
|
|
553
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
554
|
-
|
|
555
|
-
expect(result).toContain('typeof input?.user === "object"')
|
|
556
|
-
expect(result).toContain('"id" in input?.user')
|
|
557
|
-
expect(result).toContain('Object.keys(input?.user).length >= 1')
|
|
558
|
-
expect(result).toContain('Object.keys(input?.user).length <= 5')
|
|
559
|
-
expect(result).toContain('Object.keys(input?.user).every(k => ["id","name"].includes(k))')
|
|
560
|
-
})
|
|
561
|
-
|
|
562
|
-
it('handles object without properties but with additionalProperties false', () => {
|
|
563
|
-
const schema = {
|
|
564
|
-
type: 'object' as const,
|
|
565
|
-
additionalProperties: false,
|
|
566
|
-
}
|
|
567
|
-
const result = generateValidationExpression('data', schema, '{}', true)
|
|
568
|
-
|
|
569
|
-
expect(result).toContain('typeof input?.data === "object"')
|
|
570
|
-
expect(result).not.toContain('every')
|
|
571
|
-
})
|
|
572
|
-
|
|
573
|
-
it('handles uniqueItems set to false', () => {
|
|
574
|
-
const schema = {
|
|
575
|
-
type: 'array' as const,
|
|
576
|
-
uniqueItems: false,
|
|
577
|
-
}
|
|
578
|
-
const result = generateValidationExpression('tags', schema, '[]', true)
|
|
579
|
-
|
|
580
|
-
expect(result).toContain('Array.isArray(input?.tags)')
|
|
581
|
-
expect(result).not.toContain('new Set')
|
|
582
|
-
})
|
|
583
|
-
|
|
584
|
-
it('handles complex nested validation with allOf', () => {
|
|
585
|
-
const schema = {
|
|
586
|
-
allOf: [
|
|
587
|
-
{ type: 'object' as const },
|
|
588
|
-
{
|
|
589
|
-
properties: {
|
|
590
|
-
id: { type: 'number' as const, minimum: 1 },
|
|
591
|
-
name: { type: 'string' as const, minLength: 1 },
|
|
592
|
-
},
|
|
593
|
-
},
|
|
594
|
-
],
|
|
595
|
-
}
|
|
596
|
-
const result = generateValidationExpression('entity', schema, '{}', true)
|
|
597
|
-
|
|
598
|
-
expect(result).toContain('typeof input?.entity === "object"')
|
|
599
|
-
})
|
|
600
|
-
|
|
601
|
-
it('handles not with complex schema', () => {
|
|
602
|
-
const schema = {
|
|
603
|
-
not: {
|
|
604
|
-
type: 'object' as const,
|
|
605
|
-
properties: {
|
|
606
|
-
banned: { const: true },
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
}
|
|
610
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
611
|
-
|
|
612
|
-
expect(result).toContain('!(typeof input?.user === "object"')
|
|
613
|
-
})
|
|
614
|
-
|
|
615
|
-
it('handles $ref without rootSchema', () => {
|
|
616
|
-
const schema = { $ref: '#/$defs/Something' }
|
|
617
|
-
const result = generateValidationExpression('data', schema, '{}', true)
|
|
618
|
-
|
|
619
|
-
expect(result).toBe('input?.data ?? {}')
|
|
620
|
-
})
|
|
621
|
-
|
|
622
|
-
it('generates validation for integer with all numeric constraints', () => {
|
|
623
|
-
const schema = {
|
|
624
|
-
type: 'integer' as const,
|
|
625
|
-
minimum: 10,
|
|
626
|
-
maximum: 100,
|
|
627
|
-
exclusiveMinimum: 5,
|
|
628
|
-
exclusiveMaximum: 105,
|
|
629
|
-
multipleOf: 10,
|
|
630
|
-
}
|
|
631
|
-
const result = generateValidationExpression('count', schema, '0', true)
|
|
632
|
-
|
|
633
|
-
expect(result).toContain('typeof input?.count === "number"')
|
|
634
|
-
expect(result).toContain('input?.count >= 10')
|
|
635
|
-
expect(result).toContain('input?.count <= 100')
|
|
636
|
-
expect(result).toContain('input?.count > 5')
|
|
637
|
-
expect(result).toContain('input?.count < 105')
|
|
638
|
-
expect(result).toContain('input?.count % 10 === 0')
|
|
639
|
-
})
|
|
640
|
-
|
|
641
|
-
it('handles empty required array', () => {
|
|
642
|
-
const schema = {
|
|
643
|
-
type: 'object' as const,
|
|
644
|
-
properties: {
|
|
645
|
-
id: { type: 'number' as const },
|
|
646
|
-
},
|
|
647
|
-
required: [],
|
|
648
|
-
}
|
|
649
|
-
const result = generateValidationExpression('user', schema, '{}', true)
|
|
650
|
-
|
|
651
|
-
expect(result).toContain('typeof input?.user === "object"')
|
|
652
|
-
expect(result).not.toContain('" in input?.user')
|
|
653
|
-
})
|
|
654
|
-
|
|
655
|
-
it('uses bracket notation for hyphenated property keys', () => {
|
|
656
|
-
const schema = { type: 'string' as const }
|
|
657
|
-
const result = generateValidationExpression('x-linkedin', schema, '""', true)
|
|
658
|
-
|
|
659
|
-
expect(result).toContain("input?.['x-linkedin']")
|
|
660
|
-
expect(result).not.toContain('input?.x-linkedin')
|
|
661
|
-
})
|
|
662
|
-
|
|
663
|
-
it('removes redundant undefined check when knownNotUndefined is true for required field', () => {
|
|
664
|
-
const schema = { type: 'string' as const }
|
|
665
|
-
const result = generateValidationExpression('name', schema, '""', true, undefined, undefined, undefined, true)
|
|
666
|
-
|
|
667
|
-
// Should not have nested undefined check
|
|
668
|
-
expect(result).not.toContain('!== undefined ? String')
|
|
669
|
-
// Should have direct coercion
|
|
670
|
-
expect(result).toContain('String(input?.name)')
|
|
671
|
-
})
|
|
672
|
-
|
|
673
|
-
it('removes redundant undefined check when knownNotUndefined is true for optional field', () => {
|
|
674
|
-
const schema = { type: 'string' as const }
|
|
675
|
-
const result = generateValidationExpression('name', schema, '""', false, undefined, undefined, undefined, true)
|
|
676
|
-
|
|
677
|
-
// Should not have nested undefined check
|
|
678
|
-
expect(result).not.toContain('!== undefined ? String')
|
|
679
|
-
// Should have direct coercion
|
|
680
|
-
expect(result).toContain('String(input?.name)')
|
|
681
|
-
})
|
|
682
|
-
|
|
683
|
-
it('keeps undefined check when knownNotUndefined is false for required field', () => {
|
|
684
|
-
const schema = { type: 'string' as const }
|
|
685
|
-
const result = generateValidationExpression('name', schema, '""', true, undefined, undefined, undefined, false)
|
|
686
|
-
|
|
687
|
-
// Should have nested undefined check
|
|
688
|
-
expect(result).toContain('!== undefined ? String')
|
|
689
|
-
})
|
|
690
|
-
|
|
691
|
-
it('removes redundant check for number coercion when knownNotUndefined is true', () => {
|
|
692
|
-
const schema = { type: 'number' as const }
|
|
693
|
-
const result = generateValidationExpression('age', schema, '0', true, undefined, undefined, undefined, true)
|
|
694
|
-
|
|
695
|
-
// Should not have nested undefined check
|
|
696
|
-
expect(result).not.toContain('!== undefined ? Number')
|
|
697
|
-
// Should have direct coercion
|
|
698
|
-
expect(result).toContain('Number(input?.age)')
|
|
699
|
-
})
|
|
700
|
-
|
|
701
|
-
it('removes redundant check for boolean coercion when knownNotUndefined is true', () => {
|
|
702
|
-
const schema = { type: 'boolean' as const }
|
|
703
|
-
const result = generateValidationExpression(
|
|
704
|
-
'isActive',
|
|
705
|
-
schema,
|
|
706
|
-
'false',
|
|
707
|
-
true,
|
|
708
|
-
undefined,
|
|
709
|
-
undefined,
|
|
710
|
-
undefined,
|
|
711
|
-
true,
|
|
712
|
-
)
|
|
713
|
-
|
|
714
|
-
// Should not have nested undefined check
|
|
715
|
-
expect(result).not.toContain('!== undefined ? Boolean')
|
|
716
|
-
// Should have direct coercion
|
|
717
|
-
expect(result).toContain('Boolean(input?.isActive)')
|
|
718
|
-
})
|
|
719
|
-
|
|
720
|
-
it('removes redundant check for array coercion when knownNotUndefined is true', () => {
|
|
721
|
-
const schema = { type: 'array' as const }
|
|
722
|
-
const result = generateValidationExpression('tags', schema, '[]', true, undefined, undefined, undefined, true)
|
|
723
|
-
|
|
724
|
-
// Should still have the array check but not nested undefined
|
|
725
|
-
expect(result).toContain('Array.isArray(input?.tags) ? input?.tags : []')
|
|
726
|
-
})
|
|
727
|
-
|
|
728
|
-
it('removes redundant check for object coercion when knownNotUndefined is true', () => {
|
|
729
|
-
const schema = { type: 'object' as const }
|
|
730
|
-
const result = generateValidationExpression('user', schema, '{}', true, undefined, undefined, undefined, true)
|
|
731
|
-
|
|
732
|
-
// Should have object check but not nested undefined
|
|
733
|
-
expect(result).toContain('typeof input?.user === "object" && input?.user !== null ? input?.user : {}')
|
|
734
|
-
})
|
|
735
|
-
|
|
736
|
-
it('uses accessor override when provided', () => {
|
|
737
|
-
const schema = { type: 'string' as const }
|
|
738
|
-
const result = generateValidationExpression('name', schema, '""', true, undefined, undefined, '_name')
|
|
739
|
-
|
|
740
|
-
// Should use the provided accessor instead of input?.name
|
|
741
|
-
expect(result).toContain('typeof _name === "string"')
|
|
742
|
-
expect(result).toContain('String(_name)')
|
|
743
|
-
expect(result).not.toContain('input?.name')
|
|
744
|
-
})
|
|
745
|
-
|
|
746
|
-
it('combines accessor override with knownNotUndefined optimization', () => {
|
|
747
|
-
const schema = { type: 'string' as const }
|
|
748
|
-
const result = generateValidationExpression('name', schema, '""', true, undefined, undefined, '_name', true)
|
|
749
|
-
|
|
750
|
-
// Should use cached variable and skip redundant check
|
|
751
|
-
expect(result).toContain('typeof _name === "string"')
|
|
752
|
-
expect(result).toContain('String(_name)')
|
|
753
|
-
expect(result).not.toContain('!== undefined ? String')
|
|
754
|
-
expect(result).not.toContain('input?.name')
|
|
755
|
-
})
|
|
756
|
-
|
|
757
|
-
it('combines multiple allOf sub-schema checks with &&', () => {
|
|
758
|
-
// Each sub-schema independently produces a type check, so allChecks has 2 items
|
|
759
|
-
// and the loop body that appends ' && check[i]' (line 128) is exercised.
|
|
760
|
-
const schema = { allOf: [{ type: 'string' as const }, { type: 'number' as const }] }
|
|
761
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
762
|
-
|
|
763
|
-
expect(result).toContain('typeof input?.value === "string"')
|
|
764
|
-
expect(result).toContain('&&')
|
|
765
|
-
expect(result).toContain('typeof input?.value === "number"')
|
|
766
|
-
})
|
|
767
|
-
|
|
768
|
-
it('falls back to nullish coalescing when allOf sub-schemas produce no checks', () => {
|
|
769
|
-
// Empty sub-schemas produce no checks so allChecks.length === 0 (line 132)
|
|
770
|
-
const schema = { allOf: [{}, {}] }
|
|
771
|
-
const result = generateValidationExpression('value', schema, '"default"', true)
|
|
772
|
-
|
|
773
|
-
expect(result).toBe('input?.value ?? "default"')
|
|
774
|
-
})
|
|
775
|
-
|
|
776
|
-
it('combines multiple not-schema checks with && inside negation', () => {
|
|
777
|
-
// A not schema with two checks causes the not-loop body (line 141) to run
|
|
778
|
-
const schema = { not: { type: 'string' as const, minLength: 1 } }
|
|
779
|
-
const result = generateValidationExpression('value', schema, 'null', true)
|
|
780
|
-
|
|
781
|
-
expect(result).toContain('!(')
|
|
782
|
-
expect(result).toContain('typeof input?.value === "string"')
|
|
783
|
-
expect(result).toContain('&&')
|
|
784
|
-
expect(result).toContain('input?.value.length >= 1')
|
|
785
|
-
})
|
|
786
|
-
|
|
787
|
-
it('returns conditional undefined for optional enum-only field without type coercion', () => {
|
|
788
|
-
// An enum schema with no type and no coercion hits the final optional branch (line 270)
|
|
789
|
-
const schema = { enum: ['active', 'inactive'] }
|
|
790
|
-
const result = generateValidationExpression('status', schema, 'undefined', false)
|
|
791
|
-
|
|
792
|
-
expect(result).toContain('? input?.status : undefined')
|
|
793
|
-
})
|
|
794
|
-
|
|
795
|
-
it('checks instanceof and coerces a required x-mjst Date field', () => {
|
|
796
|
-
const schema = { 'x-mjst': { instanceOf: 'Date' } }
|
|
797
|
-
const result = generateValidationExpression('createdAt', schema, '{}', true)
|
|
798
|
-
|
|
799
|
-
expect(result).toContain('input?.createdAt instanceof Date')
|
|
800
|
-
expect(result).toContain('new Date(input?.createdAt as string | number | Date)')
|
|
801
|
-
})
|
|
802
|
-
|
|
803
|
-
it('checks instanceof and coerces an optional x-mjst Date field', () => {
|
|
804
|
-
const schema = { 'x-mjst': { instanceOf: 'Date' } }
|
|
805
|
-
const result = generateValidationExpression('createdAt', schema, 'undefined', false)
|
|
806
|
-
|
|
807
|
-
expect(result).toContain('input?.createdAt instanceof Date')
|
|
808
|
-
expect(result).toContain('? input?.createdAt : (input?.createdAt !== undefined ? new Date')
|
|
809
|
-
})
|
|
810
|
-
|
|
811
|
-
it('falls back to the default for an unknown instanceOf with no coercion', () => {
|
|
812
|
-
const schema = { 'x-mjst': { instanceOf: 'CustomThing' } }
|
|
813
|
-
const result = generateValidationExpression('value', schema, '{}', true)
|
|
814
|
-
|
|
815
|
-
expect(result).toBe('input?.value instanceof CustomThing ? input?.value : {}')
|
|
816
|
-
})
|
|
817
|
-
|
|
818
|
-
it('checks typeof bigint for a required x-mjst primitive field', () => {
|
|
819
|
-
const schema = { 'x-mjst': { primitive: 'bigint' } }
|
|
820
|
-
const result = generateValidationExpression('balance', schema, '0n', true)
|
|
821
|
-
|
|
822
|
-
expect(result).toBe('typeof input?.balance === "bigint" ? input?.balance : 0n')
|
|
823
|
-
})
|
|
824
|
-
|
|
825
|
-
it('checks typeof bigint for an optional x-mjst primitive field', () => {
|
|
826
|
-
const schema = { 'x-mjst': { primitive: 'bigint' } }
|
|
827
|
-
const result = generateValidationExpression('balance', schema, '0n', false)
|
|
828
|
-
|
|
829
|
-
expect(result).toBe('typeof input?.balance === "bigint" ? input?.balance : undefined')
|
|
830
|
-
})
|
|
831
|
-
})
|