class-validator-jsonschema
Version:
Convert class-validator-decorated classes into JSON schema
77 lines (67 loc) • 1.92 kB
text/typescript
import {
getMetadataStorage,
Validate,
ValidationArguments,
ValidatorConstraint,
ValidatorConstraintInterface,
} from 'class-validator'
import { validationMetadatasToSchemas } from '../src'
@ValidatorConstraint()
export class CustomTextLength implements ValidatorConstraintInterface {
validate(text: string, validationArguments: ValidationArguments) {
const [min, max] = validationArguments.constraints
return text.length > min && text.length < max
}
}
// @ts-ignore: not referenced
class Post {
@Validate(CustomTextLength, [0, 11])
title: string
}
// @ts-ignore: not referenced
class InvalidPost {
@Validate(CustomTextLength, [0, 11])
titleNumber: number
@Validate(CustomTextLength, [0, 11])
titleBoolean: boolean
}
describe('custom validation classes', () => {
it('uses property type if no additional converter is supplied', () => {
const schemas = validationMetadatasToSchemas({
classValidatorMetadataStorage: getMetadataStorage(),
})
expect(schemas.Post).toEqual({
properties: {
title: { type: 'string' },
},
required: ['title'],
type: 'object',
})
expect(schemas.InvalidPost).toEqual({
properties: {
titleBoolean: { type: 'boolean' },
titleNumber: { type: 'number' },
},
required: ['titleNumber', 'titleBoolean'],
type: 'object',
})
})
it('uses additionalConverter to generate schema when supplied', () => {
const schemas = validationMetadatasToSchemas({
additionalConverters: {
CustomTextLength: (meta) => ({
maxLength: meta.constraints[1] - 1,
minLength: meta.constraints[0] + 1,
type: 'string',
}),
},
})
expect(schemas.Post).toEqual({
properties: {
title: { maxLength: 10, minLength: 1, type: 'string' },
},
required: ['title'],
type: 'object',
})
})
})