import { AnySchemaObject, ValidateFunction } from 'ajv' import { AnyValidateFunction } from 'ajv/dist/core' import { expect } from 'tstyche' import AjvCompiler, { AjvReference, ValidatorFactory, StandaloneValidator, RouteDefinition, ErrorObject, BuildCompilerFromPool, BuildSerializerFromPool, ValidatorCompiler } from '..' import type Ajv from 'ajv' { const compiler = AjvCompiler({}) expect(compiler).type.toBe() } { const compiler = AjvCompiler() expect(compiler).type.toBe() } { const compiler = AjvCompiler({ jtdSerializer: false }) expect(compiler).type.toBe() } { const factory = AjvCompiler({ jtdSerializer: false }) expect(factory).type.toBe() factory( {}, { onCreate (ajv) { expect(ajv).type.toBe() } } ) } { const compiler = AjvCompiler({ jtdSerializer: true }) expect(compiler).type.toBe() } const reader = StandaloneValidator({ readMode: true, restoreFunction: (route) => { expect(route).type.toBe() return {} as ValidateFunction } }) expect(reader).type.toBeAssignableTo() const writer = StandaloneValidator({ readMode: false, storeFunction: (route, code: string) => { expect(route).type.toBe() expect(code).type.toBe() } }) expect(writer).type.toBeAssignableTo() expect(({} as ErrorObject).data).type.toBe() expect(({} as ErrorObject).instancePath).type.toBe() expect(({} as ErrorObject).keyword).type.toBe() expect(({} as ErrorObject).message).type.toBe() expect(({} as ErrorObject).params).type.toBe>() expect(({} as ErrorObject).parentSchema).type.toBe< AnySchemaObject | undefined >() expect(({} as ErrorObject).propertyName).type.toBe() expect(({} as ErrorObject).schema).type.toBe() expect(({} as ErrorObject).schemaPath).type.toBe() expect(AjvReference).type.toBe() { const jtdSchema = { discriminator: 'version', mapping: { 1: { properties: { foo: { type: 'uint8' } } }, 2: { properties: { foo: { type: 'string' } } } } } const externalSchemas1 = { foo: { definitions: { coordinates: { properties: { lat: { type: 'float32' }, lng: { type: 'float32' } } } } } } const factory = AjvCompiler({ jtdSerializer: true }) expect(factory).type.toBe() const compiler = factory(externalSchemas1, {}) expect(compiler).type.toBeAssignableTo() const serializeFunc = compiler({ schema: jtdSchema }) expect(serializeFunc).type.toBe<(data: unknown) => string>() expect(serializeFunc({ version: '1', foo: 42 })).type.toBe() } // JTD { const factory = AjvCompiler() expect(factory).type.toBe() const jtdSchema = { discriminator: 'version', mapping: { 1: { properties: { foo: { type: 'uint8' } } }, 2: { properties: { foo: { type: 'string' } } } } } const compiler = factory( {}, { customOptions: {}, mode: 'JTD' } ) expect(compiler).type.toBeAssignableTo() const validatorFunc = compiler({ schema: jtdSchema }) expect(validatorFunc).type.toBeAssignableTo() expect( validatorFunc({ version: '2', foo: [] }) ).type.toBe>() } // generate standalone code { const base = { $id: 'urn:schema:base', definitions: { hello: { type: 'string' } }, type: 'object', properties: { hello: { $ref: '#/definitions/hello' } } } const refSchema = { $id: 'urn:schema:ref', type: 'object', properties: { hello: { $ref: 'urn:schema:base#/definitions/hello' } } } const endpointSchema = { schema: { $id: 'urn:schema:endpoint', $ref: 'urn:schema:ref' } } const schemaMap = { [base.$id]: base, [refSchema.$id]: refSchema } const factory = StandaloneValidator({ readMode: false, storeFunction (routeOpts, schemaValidationCode) { expect(routeOpts).type.toBe() expect(schemaValidationCode).type.toBe() } }) expect(factory).type.toBeAssignableTo() const compiler = factory(schemaMap) expect(compiler).type.toBeAssignableTo() expect(compiler(endpointSchema)).type.toBe() } { const base = { $id: 'urn:schema:base', definitions: { hello: { type: 'string' } }, type: 'object', properties: { hello: { $ref: '#/definitions/hello' } } } const refSchema = { $id: 'urn:schema:ref', type: 'object', properties: { hello: { $ref: 'urn:schema:base#/definitions/hello' } } } const endpointSchema = { schema: { $id: 'urn:schema:endpoint', $ref: 'urn:schema:ref' } } const schemaMap = { [base.$id]: base, [refSchema.$id]: refSchema } const factory = StandaloneValidator({ readMode: true, restoreFunction (routeOpts) { expect(routeOpts).type.toBe() return {} as ValidateFunction } }) expect(factory).type.toBeAssignableTo() const compiler = factory(schemaMap) expect(compiler).type.toBeAssignableTo() expect(compiler(endpointSchema)).type.toBe() } // Plugins { const factory = AjvCompiler() const compilerFactoryParams = { customOptions: {}, plugins: [ (ajv: Ajv) => { expect(ajv).type.toBe() return ajv }, (ajv: Ajv, options: unknown) => { expect(ajv).type.toBe() expect(options).type.toBe() return ajv } ] } expect([ {}, compilerFactoryParams ] as Parameters).type.toBeAssignableTo< Parameters >() const compiler = factory( {}, { customOptions: {}, plugins: [ (ajv) => { expect(ajv).type.toBe() return ajv }, (ajv, options) => { expect(ajv).type.toBe() expect(options).type.toBe() return ajv } ] } ) expect(compiler).type.toBeAssignableTo() } // Compiler factory should allow both signatures (mode: JTD and mode omitted) { expect().type.toBeCallableWith({}, {}) const ajvPlugin = (ajv: Ajv): Ajv => { expect(ajv).type.toBe() return ajv } expect() .type.toBeCallableWith( {}, { plugins: [ajvPlugin] } ) expect() .type.toBeCallableWith( {}, { mode: 'JTD', customOptions: { removeAdditional: 'all' }, plugins: [ajvPlugin] } ) expect() .type.toBeCallableWith( {}, { mode: 'JTD', customOptions: { removeAdditional: 'all' }, plugins: [[ajvPlugin, ['string1', 'string2']]] } ) expect() .type.toBeCallableWith( {}, { plugins: [ ajvPlugin, (ajv: Ajv, options: unknown): Ajv => { expect(ajv).type.toBe() expect(options).type.toBe() return ajv }, [ajvPlugin, ['keyword1', 'keyword2']], [ajvPlugin, [{ key: 'value' }]] ] } ) }