UNPKG

fluent-json-schema

Version:
128 lines (116 loc) 3.41 kB
'use strict' const S = require('./FluentJSONSchema') const Ajv = require('ajv') const ROLES = { ADMIN: 'ADMIN', USER: 'USER' } const schema = S.object() .id('http://foo/user') .title('My First Fluent JSON Schema') .description('A simple user') .prop( 'email', S.string() .format(S.FORMATS.EMAIL) .required() ) .prop( 'password', S.string() .minLength(8) .required() ) .prop( 'role', S.string() .enum(Object.values(ROLES)) .default(ROLES.USER) ) .prop( 'birthday', S.raw({ type: 'string', format: 'date', formatMaximum: '2020-01-01' }) // formatMaximum is an AJV custom keywords ) .definition( 'address', S.object() .id('#address') .prop('line1', S.anyOf([S.string(), S.null()])) // JSON Schema nullable .prop('line2', S.string().raw({ nullable: true })) // Open API / Swagger nullable .prop('country', S.string()) .prop('city', S.string()) .prop('zipcode', S.string()) .required(['line1', 'country', 'city', 'zipcode']) ) .prop('address', S.ref('#address')) console.log(JSON.stringify(schema.valueOf(), undefined, 2)) const ajv = new Ajv({ allErrors: true }) const validate = ajv.compile(schema.valueOf()) let user = {} let valid = validate(user) console.log({ valid }) //= > {valid: false} console.log(validate.errors) /* [ { keyword: 'required', dataPath: '', schemaPath: '#/required', params: { missingProperty: 'email' }, message: "should have required property 'email'", }, { keyword: 'required', dataPath: '', schemaPath: '#/required', params: { missingProperty: 'password' }, message: "should have required property 'password'", }, ] */ user = { email: 'test', password: 'password' } valid = validate(user) console.log({ valid }) //= > {valid: false} console.log(validate.errors) /* [ { keyword: 'format', dataPath: '.email', schemaPath: '#/properties/email/format', params: { format: 'email' }, message: 'should match format "email"' } ] */ user = { email: 'test@foo.com', password: 'password' } valid = validate(user) console.log({ valid }) //= > {valid: true} console.log(validate.errors) // => null user = { email: 'test@foo.com', password: 'password', address: { line1: '' } } valid = validate(user) console.log({ valid }) //= > {valid: false} console.log(validate.errors) /* { valid: false } [ { keyword: 'required', dataPath: '.address', schemaPath: '#definitions/address/required', params: { missingProperty: 'country' }, message: 'should have required property \'country\'' }, { keyword: 'required', dataPath: '.address', schemaPath: '#definitions/address/required', params: { missingProperty: 'city' }, message: 'should have required property \'city\'' }, { keyword: 'required', dataPath: '.address', schemaPath: '#definitions/address/required', params: { missingProperty: 'zipcoce' }, message: 'should have required property \'zipcode\'' } ] */ const userBaseSchema = S.object() .additionalProperties(false) .prop('username', S.string()) .prop('password', S.string()) const userSchema = S.object() .prop('id', S.string().format('uuid')) .prop('createdAt', S.string().format('time')) .prop('updatedAt', S.string().format('time')) .extend(userBaseSchema) .valueOf() console.log(userSchema.valueOf())