@amritk/generate-validators 0.6.0 → 0.8.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.
@@ -1,550 +0,0 @@
1
- import { escapeRegexPattern } from '@amritk/helpers/escape-regex-pattern'
2
- import { getMjstInstanceOf, getMjstPrimitive } from '@amritk/helpers/mjst-extension'
3
- import { refToName } from '@amritk/helpers/ref-to-name'
4
- import {
5
- hasAdditionalProperties,
6
- hasConst,
7
- hasDependentRequired,
8
- hasEnum,
9
- hasExclusiveMaximum,
10
- hasExclusiveMinimum,
11
- hasItems,
12
- hasMaximum,
13
- hasMaxLength,
14
- hasMinimum,
15
- hasMinLength,
16
- hasMultipleOf,
17
- hasOneOf,
18
- hasPattern,
19
- hasProperties,
20
- hasPropertyNames,
21
- hasRef,
22
- hasRequired,
23
- hasType,
24
- isObjectSchema,
25
- isSchemaObject,
26
- } from '@amritk/helpers/schema-guards'
27
- import type { JSONSchema } from 'json-schema-typed/draft-2020-12'
28
-
29
- /**
30
- * Derives the validator function name from a type name.
31
- * e.g. "InfoObject" → "validateInfoObject"
32
- */
33
- const validatorName = (typeName: string): string => `validate${typeName}`
34
-
35
- /**
36
- * Returns the TypeScript typeof string for a JSON Schema primitive type.
37
- */
38
- const typeofString = (type: string): string => {
39
- if (type === 'integer') return 'number'
40
- return type
41
- }
42
-
43
- /**
44
- * Generates the inline condition that is TRUE when `accessor` does NOT equal the
45
- * `const` value. Primitives compare with `!==`; objects/arrays compare by their
46
- * canonical JSON serialization (sufficient for the literal, fixed shapes `const`
47
- * is used for).
48
- */
49
- const constMismatchCondition = (accessor: string, value: unknown): string => {
50
- if (value === null || typeof value !== 'object') {
51
- return `${accessor} !== ${JSON.stringify(value)}`
52
- }
53
- return `JSON.stringify(${accessor}) !== ${JSON.stringify(JSON.stringify(value))}`
54
- }
55
-
56
- /**
57
- * Generates the inline condition that is TRUE when a value is the wrong type.
58
- */
59
- const wrongTypeCondition = (accessor: string, type: string): string => {
60
- switch (type) {
61
- case 'string':
62
- return `typeof ${accessor} !== 'string'`
63
- case 'number':
64
- case 'integer':
65
- return `typeof ${accessor} !== 'number'`
66
- case 'boolean':
67
- return `typeof ${accessor} !== 'boolean'`
68
- case 'array':
69
- return `!Array.isArray(${accessor})`
70
- case 'object':
71
- return `typeof ${accessor} !== 'object' || ${accessor} === null || Array.isArray(${accessor})`
72
- default:
73
- return ''
74
- }
75
- }
76
-
77
- /**
78
- * Generates validation lines for a single property in an object schema.
79
- * Handles $ref delegation, enum checks, type checks, and string/number constraints.
80
- */
81
- const generatePropertyChecks = (key: string, propSchema: JSONSchema, isRequired: boolean, suffix: string): string[] => {
82
- if (!isSchemaObject(propSchema)) return []
83
-
84
- const raw = `obj[${JSON.stringify(key)}]`
85
- const path = `\`\${_path}/${key}\``
86
- const lines: string[] = []
87
-
88
- // $ref — delegate to the imported validator
89
- if (hasRef(propSchema)) {
90
- const ref = propSchema.$ref
91
- const vName = validatorName(refToName(ref, suffix))
92
-
93
- if (isRequired) {
94
- lines.push(` if (!(${JSON.stringify(key)} in obj)) {`)
95
- lines.push(` errors.push({ message: "must have required property '${key}'", path: _path })`)
96
- lines.push(` } else {`)
97
- lines.push(` const _r = ${vName}(${raw}, ${path})`)
98
- lines.push(` if (_r !== true) errors.push(..._r.errors)`)
99
- lines.push(` }`)
100
- } else {
101
- lines.push(` if (${raw} !== undefined) {`)
102
- lines.push(` const _r = ${vName}(${raw}, ${path})`)
103
- lines.push(` if (_r !== true) errors.push(..._r.errors)`)
104
- lines.push(` }`)
105
- }
106
- return lines
107
- }
108
-
109
- // x-mjst instanceOf (e.g. Date) — value must be an instance of the class
110
- const instanceOf = getMjstInstanceOf(propSchema)
111
- if (instanceOf) {
112
- if (isRequired) {
113
- lines.push(` if (!(${JSON.stringify(key)} in obj)) {`)
114
- lines.push(` errors.push({ message: "must have required property '${key}'", path: _path })`)
115
- lines.push(` } else if (!(${raw} instanceof ${instanceOf})) {`)
116
- lines.push(` errors.push({ message: 'must be ${instanceOf}', path: ${path} })`)
117
- lines.push(` }`)
118
- } else {
119
- lines.push(` if (${raw} !== undefined && !(${raw} instanceof ${instanceOf})) {`)
120
- lines.push(` errors.push({ message: 'must be ${instanceOf}', path: ${path} })`)
121
- lines.push(` }`)
122
- }
123
- return lines
124
- }
125
-
126
- // x-mjst primitive (e.g. bigint) — value must satisfy a typeof check
127
- const primitive = getMjstPrimitive(propSchema)
128
- if (primitive) {
129
- if (isRequired) {
130
- lines.push(` if (!(${JSON.stringify(key)} in obj)) {`)
131
- lines.push(` errors.push({ message: "must have required property '${key}'", path: _path })`)
132
- lines.push(` } else if (typeof ${raw} !== "${primitive}") {`)
133
- lines.push(` errors.push({ message: 'must be ${primitive}', path: ${path} })`)
134
- lines.push(` }`)
135
- } else {
136
- lines.push(` if (${raw} !== undefined && typeof ${raw} !== "${primitive}") {`)
137
- lines.push(` errors.push({ message: 'must be ${primitive}', path: ${path} })`)
138
- lines.push(` }`)
139
- }
140
- return lines
141
- }
142
-
143
- // const — value must equal the fixed value exactly
144
- if (hasConst(propSchema)) {
145
- const mismatch = constMismatchCondition(raw, propSchema.const)
146
- const msg = JSON.stringify(`must be ${JSON.stringify(propSchema.const)}`)
147
- if (isRequired) {
148
- lines.push(` if (!(${JSON.stringify(key)} in obj)) {`)
149
- lines.push(` errors.push({ message: "must have required property '${key}'", path: _path })`)
150
- lines.push(` } else if (${mismatch}) {`)
151
- lines.push(` errors.push({ message: ${msg}, path: ${path} })`)
152
- lines.push(` }`)
153
- } else {
154
- lines.push(` if (${raw} !== undefined && ${mismatch}) {`)
155
- lines.push(` errors.push({ message: ${msg}, path: ${path} })`)
156
- lines.push(` }`)
157
- }
158
- return lines
159
- }
160
-
161
- // enum
162
- if (hasEnum(propSchema)) {
163
- const allowed = JSON.stringify(propSchema.enum)
164
- const label = (propSchema.enum as unknown[]).map((v) => JSON.stringify(v)).join(', ')
165
-
166
- if (isRequired) {
167
- lines.push(` if (!(${JSON.stringify(key)} in obj)) {`)
168
- lines.push(` errors.push({ message: "must have required property '${key}'", path: _path })`)
169
- lines.push(` } else if (!(${allowed} as unknown[]).includes(${raw})) {`)
170
- lines.push(` errors.push({ message: \`must be one of: ${label}\`, path: ${path} })`)
171
- lines.push(` }`)
172
- } else {
173
- lines.push(` if (${raw} !== undefined && !(${allowed} as unknown[]).includes(${raw})) {`)
174
- lines.push(` errors.push({ message: \`must be one of: ${label}\`, path: ${path} })`)
175
- lines.push(` }`)
176
- }
177
- return lines
178
- }
179
-
180
- // typed property
181
- if (hasType(propSchema)) {
182
- const t = propSchema.type as string
183
- const wrongType = wrongTypeCondition(raw, t)
184
- const typLabel = typeofString(t)
185
-
186
- if (isRequired) {
187
- lines.push(` if (!(${JSON.stringify(key)} in obj)) {`)
188
- lines.push(` errors.push({ message: "must have required property '${key}'", path: _path })`)
189
- if (wrongType) {
190
- lines.push(` } else if (${wrongType}) {`)
191
- lines.push(` errors.push({ message: 'must be ${typLabel}', path: ${path} })`)
192
- }
193
- lines.push(` }`)
194
- } else if (wrongType) {
195
- lines.push(` if (${raw} !== undefined && (${wrongType})) {`)
196
- lines.push(` errors.push({ message: 'must be ${typLabel}', path: ${path} })`)
197
- lines.push(` }`)
198
- }
199
-
200
- // String constraints
201
- if (t === 'string') {
202
- if (hasPattern(propSchema)) {
203
- const re = escapeRegexPattern(propSchema.pattern)
204
- const msg = JSON.stringify(`must match pattern ${propSchema.pattern}`)
205
- lines.push(` if (typeof ${raw} === 'string' && !/${re}/.test(${raw})) {`)
206
- lines.push(` errors.push({ message: ${msg}, path: ${path} })`)
207
- lines.push(` }`)
208
- }
209
- if (hasMinLength(propSchema)) {
210
- lines.push(` if (typeof ${raw} === 'string' && ${raw}.length < ${propSchema.minLength}) {`)
211
- lines.push(
212
- ` errors.push({ message: 'must have at least ${propSchema.minLength} characters', path: ${path} })`,
213
- )
214
- lines.push(` }`)
215
- }
216
- if (hasMaxLength(propSchema)) {
217
- lines.push(` if (typeof ${raw} === 'string' && ${raw}.length > ${propSchema.maxLength}) {`)
218
- lines.push(
219
- ` errors.push({ message: 'must have at most ${propSchema.maxLength} characters', path: ${path} })`,
220
- )
221
- lines.push(` }`)
222
- }
223
- }
224
-
225
- // Number constraints
226
- if (t === 'number' || t === 'integer') {
227
- if (hasMinimum(propSchema)) {
228
- lines.push(` if (typeof ${raw} === 'number' && ${raw} < ${propSchema.minimum}) {`)
229
- lines.push(` errors.push({ message: 'must be >= ${propSchema.minimum}', path: ${path} })`)
230
- lines.push(` }`)
231
- }
232
- if (hasMaximum(propSchema)) {
233
- lines.push(` if (typeof ${raw} === 'number' && ${raw} > ${propSchema.maximum}) {`)
234
- lines.push(` errors.push({ message: 'must be <= ${propSchema.maximum}', path: ${path} })`)
235
- lines.push(` }`)
236
- }
237
- if (hasExclusiveMinimum(propSchema)) {
238
- lines.push(` if (typeof ${raw} === 'number' && ${raw} <= ${propSchema.exclusiveMinimum}) {`)
239
- lines.push(` errors.push({ message: 'must be > ${propSchema.exclusiveMinimum}', path: ${path} })`)
240
- lines.push(` }`)
241
- }
242
- if (hasExclusiveMaximum(propSchema)) {
243
- lines.push(` if (typeof ${raw} === 'number' && ${raw} >= ${propSchema.exclusiveMaximum}) {`)
244
- lines.push(` errors.push({ message: 'must be < ${propSchema.exclusiveMaximum}', path: ${path} })`)
245
- lines.push(` }`)
246
- }
247
- if (hasMultipleOf(propSchema)) {
248
- lines.push(` if (typeof ${raw} === 'number' && ${raw} % ${propSchema.multipleOf} !== 0) {`)
249
- lines.push(` errors.push({ message: 'must be a multiple of ${propSchema.multipleOf}', path: ${path} })`)
250
- lines.push(` }`)
251
- }
252
- }
253
-
254
- // Array with typed items
255
- if (t === 'array' && hasItems(propSchema)) {
256
- const itemSchema = propSchema.items
257
- if (hasRef(itemSchema)) {
258
- const vName = validatorName(refToName(itemSchema.$ref, suffix))
259
- lines.push(` if (Array.isArray(${raw})) {`)
260
- lines.push(` for (let _i = 0; _i < ${raw}.length; _i++) {`)
261
- lines.push(` const _ir = ${vName}(${raw}[_i], \`${path.slice(1, -1)}/${key}/\${_i}\`)`)
262
- lines.push(` if (_ir !== true) errors.push(..._ir.errors)`)
263
- lines.push(` }`)
264
- lines.push(` }`)
265
- } else if (hasType(itemSchema)) {
266
- const itemType = itemSchema.type as string
267
- const itemWrong = wrongTypeCondition('_item', itemType)
268
- const itemLabel = typeofString(itemType)
269
- if (itemWrong) {
270
- lines.push(` if (Array.isArray(${raw})) {`)
271
- lines.push(` for (let _i = 0; _i < ${raw}.length; _i++) {`)
272
- lines.push(` const _item = ${raw}[_i]`)
273
- lines.push(
274
- ` if (${itemWrong}) errors.push({ message: 'items must be ${itemLabel}', path: \`${path.slice(1, -1)}/${key}/\${_i}\` })`,
275
- )
276
- lines.push(` }`)
277
- lines.push(` }`)
278
- }
279
- }
280
- }
281
- }
282
-
283
- return lines
284
- }
285
-
286
- /**
287
- * Generates a validator function body for an object schema, checking each
288
- * property's presence and type and collecting all errors.
289
- */
290
- const generateObjectValidator = (schema: JSONSchema, typeName: string, suffix: string): string => {
291
- const vName = validatorName(typeName)
292
- const required = new Set(hasRequired(schema) ? schema.required : [])
293
- const properties = hasProperties(schema) ? schema.properties : {}
294
-
295
- const propertyLines: string[] = []
296
-
297
- for (const [key, propSchema] of Object.entries(properties)) {
298
- const checks = generatePropertyChecks(key, propSchema as JSONSchema, required.has(key), suffix)
299
- if (checks.length > 0) {
300
- propertyLines.push(...checks)
301
- }
302
- }
303
-
304
- // additionalProperties with a $ref schema validates all extra keys
305
- if (
306
- hasAdditionalProperties(schema) &&
307
- isSchemaObject(schema.additionalProperties) &&
308
- hasRef(schema.additionalProperties)
309
- ) {
310
- const vRefName = validatorName(refToName(schema.additionalProperties.$ref, suffix))
311
- propertyLines.push(` for (const _key of Object.keys(obj)) {`)
312
- propertyLines.push(` if (${JSON.stringify(Object.keys(properties))}.includes(_key)) continue`)
313
- propertyLines.push(` const _r = ${vRefName}(obj[_key as keyof typeof obj], \`\${_path}/\${_key}\`)`)
314
- propertyLines.push(` if (_r !== true) errors.push(..._r.errors)`)
315
- propertyLines.push(` }`)
316
- }
317
-
318
- // dependentRequired — when a trigger property is present, its dependencies must be too.
319
- if (hasDependentRequired(schema)) {
320
- for (const [trigger, deps] of Object.entries(schema.dependentRequired)) {
321
- if (!Array.isArray(deps)) continue
322
- for (const dep of deps) {
323
- const msg = JSON.stringify(`must have property '${dep}' when '${trigger}' is present`)
324
- propertyLines.push(` if (${JSON.stringify(trigger)} in obj && !(${JSON.stringify(dep)} in obj)) {`)
325
- propertyLines.push(` errors.push({ message: ${msg}, path: _path })`)
326
- propertyLines.push(` }`)
327
- }
328
- }
329
- }
330
-
331
- // propertyNames with a pattern — every key must match. (Only the pattern form
332
- // is emitted; a $ref/complex propertyNames schema is left to runtime validation.)
333
- if (hasPropertyNames(schema) && isSchemaObject(schema.propertyNames) && hasPattern(schema.propertyNames)) {
334
- const re = escapeRegexPattern(schema.propertyNames.pattern)
335
- const msg = JSON.stringify(`property name must match pattern ${schema.propertyNames.pattern}`)
336
- propertyLines.push(` for (const _name of Object.keys(obj)) {`)
337
- propertyLines.push(` if (!/${re}/.test(_name)) {`)
338
- propertyLines.push(` errors.push({ message: ${msg}, path: \`\${_path}/\${_name}\` })`)
339
- propertyLines.push(` }`)
340
- propertyLines.push(` }`)
341
- }
342
-
343
- const body = propertyLines.length > 0 ? '\n' + propertyLines.join('\n') + '\n' : ''
344
-
345
- return [
346
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
347
- ` if (typeof input !== 'object' || input === null || Array.isArray(input)) {`,
348
- ` return { valid: false, errors: [{ message: 'must be object', path: _path }] }`,
349
- ` }`,
350
- ``,
351
- ` const errors: ValidationError[] = []`,
352
- ` const obj = input as Record<string, unknown>`,
353
- body,
354
- ` return errors.length > 0 ? { valid: false, errors } : true`,
355
- `}`,
356
- ].join('\n')
357
- }
358
-
359
- /**
360
- * Generates a validator function for a non-object schema (primitive, array, enum, $ref).
361
- */
362
- const generateScalarValidator = (schema: JSONSchema, typeName: string, suffix: string): string => {
363
- const vName = validatorName(typeName)
364
-
365
- if (!isSchemaObject(schema)) {
366
- return [`export const ${vName} = (_input: unknown, _path = ''): ValidationResult => {`, ` return true`, `}`].join(
367
- '\n',
368
- )
369
- }
370
-
371
- // Top-level $ref — delegate entirely
372
- if (hasRef(schema)) {
373
- const delegateName = validatorName(refToName(schema.$ref, suffix))
374
- return [
375
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
376
- ` return ${delegateName}(input, _path)`,
377
- `}`,
378
- ].join('\n')
379
- }
380
-
381
- // Top-level x-mjst instanceOf (e.g. a schema that is itself a Date)
382
- const instanceOf = getMjstInstanceOf(schema)
383
- if (instanceOf) {
384
- return [
385
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
386
- ` if (!(input instanceof ${instanceOf})) {`,
387
- ` return { valid: false, errors: [{ message: 'must be ${instanceOf}', path: _path }] }`,
388
- ` }`,
389
- ` return true`,
390
- `}`,
391
- ].join('\n')
392
- }
393
-
394
- // Top-level x-mjst primitive (e.g. a schema that is itself a bigint)
395
- const primitive = getMjstPrimitive(schema)
396
- if (primitive) {
397
- return [
398
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
399
- ` if (typeof input !== "${primitive}") {`,
400
- ` return { valid: false, errors: [{ message: 'must be ${primitive}', path: _path }] }`,
401
- ` }`,
402
- ` return true`,
403
- `}`,
404
- ].join('\n')
405
- }
406
-
407
- // Top-level const
408
- if (hasConst(schema)) {
409
- const mismatch = constMismatchCondition('input', schema.const)
410
- const msg = JSON.stringify(`must be ${JSON.stringify(schema.const)}`)
411
- return [
412
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
413
- ` if (${mismatch}) {`,
414
- ` return { valid: false, errors: [{ message: ${msg}, path: _path }] }`,
415
- ` }`,
416
- ` return true`,
417
- `}`,
418
- ].join('\n')
419
- }
420
-
421
- // Top-level enum
422
- if (hasEnum(schema)) {
423
- const allowed = JSON.stringify(schema.enum)
424
- const label = (schema.enum as unknown[]).map((v) => JSON.stringify(v)).join(', ')
425
- return [
426
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
427
- ` if (!(${allowed} as unknown[]).includes(input)) {`,
428
- ` return { valid: false, errors: [{ message: \`must be one of: ${label}\`, path: _path }] }`,
429
- ` }`,
430
- ` return true`,
431
- `}`,
432
- ].join('\n')
433
- }
434
-
435
- // oneOf — try each branch, return errors from all if none match
436
- if (hasOneOf(schema)) {
437
- const branches = schema.oneOf
438
- .map((branch, i) => {
439
- if (!hasRef(branch)) return null
440
- const bName = validatorName(refToName((branch as { $ref: string }).$ref, suffix))
441
- return ` const _r${i} = ${bName}(input, _path)\n if (_r${i} === true) return true`
442
- })
443
- .filter(Boolean)
444
- .join('\n')
445
-
446
- return [
447
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
448
- branches,
449
- ` return { valid: false, errors: [{ message: 'must match one of the expected schemas', path: _path }] }`,
450
- `}`,
451
- ].join('\n')
452
- }
453
-
454
- // Top-level typed schema (string, number, boolean, array)
455
- if (hasType(schema)) {
456
- const t = schema.type as string
457
- const wrongType = wrongTypeCondition('input', t)
458
- const typLabel = typeofString(t)
459
-
460
- const constraintLines: string[] = []
461
-
462
- if (t === 'string') {
463
- if (hasPattern(schema)) {
464
- const re = escapeRegexPattern(schema.pattern)
465
- const msg = JSON.stringify(`must match pattern ${schema.pattern}`)
466
- constraintLines.push(` if (typeof input === 'string' && !/${re}/.test(input)) {`)
467
- constraintLines.push(` errors.push({ message: ${msg}, path: _path })`)
468
- constraintLines.push(` }`)
469
- }
470
- if (hasMinLength(schema)) {
471
- constraintLines.push(` if (typeof input === 'string' && input.length < ${schema.minLength}) {`)
472
- constraintLines.push(
473
- ` errors.push({ message: 'must have at least ${schema.minLength} characters', path: _path })`,
474
- )
475
- constraintLines.push(` }`)
476
- }
477
- if (hasMaxLength(schema)) {
478
- constraintLines.push(` if (typeof input === 'string' && input.length > ${schema.maxLength}) {`)
479
- constraintLines.push(
480
- ` errors.push({ message: 'must have at most ${schema.maxLength} characters', path: _path })`,
481
- )
482
- constraintLines.push(` }`)
483
- }
484
- }
485
-
486
- if (!wrongType) {
487
- return [
488
- `export const ${vName} = (_input: unknown, _path = ''): ValidationResult => {`,
489
- ` return true`,
490
- `}`,
491
- ].join('\n')
492
- }
493
-
494
- if (constraintLines.length === 0) {
495
- return [
496
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
497
- ` if (${wrongType}) {`,
498
- ` return { valid: false, errors: [{ message: 'must be ${typLabel}', path: _path }] }`,
499
- ` }`,
500
- ` return true`,
501
- `}`,
502
- ].join('\n')
503
- }
504
-
505
- return [
506
- `export const ${vName} = (input: unknown, _path = ''): ValidationResult => {`,
507
- ` if (${wrongType}) {`,
508
- ` return { valid: false, errors: [{ message: 'must be ${typLabel}', path: _path }] }`,
509
- ` }`,
510
- ` const errors: ValidationError[] = []`,
511
- constraintLines.join('\n'),
512
- ` return errors.length > 0 ? { valid: false, errors } : true`,
513
- `}`,
514
- ].join('\n')
515
- }
516
-
517
- return [`export const ${vName} = (_input: unknown, _path = ''): ValidationResult => {`, ` return true`, `}`].join(
518
- '\n',
519
- )
520
- }
521
-
522
- /**
523
- * Generates a TypeScript validator function from a JSON Schema.
524
- *
525
- * The generated function accepts `unknown` input and returns `true` if valid,
526
- * or `{ valid: false, errors }` with a list of errors if not.
527
- *
528
- * Object schemas check that required properties are present and that all
529
- * provided properties match their declared types. Non-object schemas (strings,
530
- * numbers, enums, $refs) emit an inline type check.
531
- *
532
- * @example
533
- * ```typescript
534
- * generateValidatorFunction({ type: 'object', properties: { name: { type: 'string' } }, required: ['name'] }, 'Info')
535
- * // export const validateInfo = (input: unknown, _path = ''): ValidationResult => {
536
- * // if (typeof input !== 'object' || ...) return { valid: false, ... }
537
- * // const errors: ValidationError[] = []
538
- * // const obj = input as Record<string, unknown>
539
- * // if (!('name' in obj)) { errors.push(...) } else if (typeof obj['name'] !== 'string') { errors.push(...) }
540
- * // return errors.length > 0 ? { valid: false, errors } : true
541
- * // }
542
- * ```
543
- */
544
- export const generateValidatorFunction = (schema: JSONSchema, typeName: string, suffix = ''): string => {
545
- if (isObjectSchema(schema)) {
546
- return generateObjectValidator(schema, typeName, suffix)
547
- }
548
-
549
- return generateScalarValidator(schema, typeName, suffix)
550
- }
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export type { GeneratedFile } from './generators/build-schema'
2
- export { buildValidatorSchema } from './generators/build-schema'