From 0d72afa9ef734f7f8432f3e29f4264311204aee3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 21 Jan 2021 00:51:22 +0000 Subject: [PATCH] build(deps): bump ajv from 6.12.6 to 7.0.3 Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.6 to 7.0.3. - [Release notes](https://github.com/ajv-validator/ajv/releases) - [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v7.0.3) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 87 ++++++++++++++++--- package.json | 2 +- src/test-helpers.ts | 3 + src/validation/errors.ts | 11 +-- .../type-validator.integration.spec.ts | 24 ++--- src/validation/type-validator.spec.ts | 52 +++-------- src/validation/type-validator.ts | 2 +- 7 files changed, 109 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50351d60..8a4a832a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2927,6 +2927,18 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -2945,6 +2957,12 @@ "type-fest": "^0.8.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4892,13 +4910,13 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", + "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, @@ -6916,6 +6934,18 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -6984,6 +7014,12 @@ "type-fest": "^0.8.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8033,7 +8069,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true + "dev": true, + "optional": true }, "handlebars": { "version": "4.7.6", @@ -8070,6 +8107,26 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "hard-rejection": { @@ -8979,6 +9036,7 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "optional": true, "requires": { "is-docker": "^2.0.0" } @@ -10778,9 +10836,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-stable-stringify": { "version": "1.0.1", @@ -11755,6 +11813,7 @@ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", "dev": true, + "optional": true, "requires": { "growly": "^1.3.0", "is-wsl": "^2.2.0", @@ -11769,6 +11828,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, + "optional": true, "requires": { "lru-cache": "^6.0.0" } @@ -16744,8 +16804,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", @@ -17387,7 +17446,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "dev": true, + "optional": true }, "signal-exit": { "version": "3.0.3", @@ -18784,7 +18844,8 @@ "version": "8.3.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", - "dev": true + "dev": true, + "optional": true }, "v8-compile-cache": { "version": "2.2.0", diff --git a/package.json b/package.json index fd7193c0..6a7b177b 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ }, "dependencies": { "@hapi/joi": "^17.1.1", - "ajv": "^6.10.2", + "ajv": "^7.0.3", "bottleneck": "^2.19.5", "chalk": "^4.0.0", "chokidar": "^3.4.0", diff --git a/src/test-helpers.ts b/src/test-helpers.ts index b061b41f..895a1829 100644 --- a/src/test-helpers.ts +++ b/src/test-helpers.ts @@ -26,6 +26,9 @@ type MockFn ReturnType> = ( ) & MockExtensions +export type MockedFn ReturnType> = jest.Mock, Parameters> & + MockExtensions + export function mockFn ReturnType>(): jest.Mock< ReturnType, Parameters diff --git a/src/validation/errors.ts b/src/validation/errors.ts index 46e417b0..d9aad802 100644 --- a/src/validation/errors.ts +++ b/src/validation/errors.ts @@ -1,16 +1,17 @@ -import ajv from 'ajv' +import { ErrorObject } from 'ajv' import { blue } from 'chalk' import { inspect } from 'util' export class TypeValidationMismatchError extends Error { - constructor(errors: ajv.ErrorObject[]) { + constructor(errors: ErrorObject[]) { super(errors.map(TypeValidationMismatchError.mapErrorMessage).join('\n')) this.name = 'TypeValidationError' Object.setPrototypeOf(this, TypeValidationMismatchError.prototype) } - private static mapErrorMessage(err: ajv.ErrorObject): string { - const baseMessage = `${blue.bold('' + err.dataPath)} ${err.message?.replace(/'(.*)'/, blue('$&'))}` + private static mapErrorMessage(err: ErrorObject): string { + const dataPath = err.dataPath.replace(/\//g, '.') + const baseMessage = `${blue.bold('' + dataPath)} ${err.message?.replace(/'(.*)'/, blue('$&'))}` if (err.keyword === 'enum' && 'allowedValues' in err.params) { return `${baseMessage} ${TypeValidationMismatchError.formatData( @@ -31,7 +32,7 @@ export class TypeValidationMismatchError extends Error { return typeof data } - private static formatData(data: Data): string { + private static formatData(data: Data | unknown): string { return inspect(data, false, 1, true) } } diff --git a/src/validation/type-validator.integration.spec.ts b/src/validation/type-validator.integration.spec.ts index 603aa26a..5a26ac5c 100644 --- a/src/validation/type-validator.integration.spec.ts +++ b/src/validation/type-validator.integration.spec.ts @@ -6,18 +6,6 @@ import '../jest-extensions' import { TypeBuilder } from '~config/resource/builders' describe('error messages', () => { - function createTestDeps() { - const ajv = new Ajv({ allErrors: true, verbose: true }) - const mockSchemaRetriever = mockObj({ load: jest.fn() }) - const typeValidator = new TypeValidator(ajv, mockSchemaRetriever) - - return { - mockSchemaRetriever, - typeValidator, - type: TypeBuilder.random(), - } - } - test('missing required properties', async () => { const { mockSchemaRetriever, typeValidator, type } = createTestDeps() mockSchemaRetriever.load.mockResolvedValue({ @@ -126,3 +114,15 @@ describe('error messages', () => { ) }) }) + +function createTestDeps() { + const ajv = new Ajv({ allErrors: true, verbose: true }) + const mockSchemaRetriever = mockObj({ load: jest.fn() }) + const typeValidator = new TypeValidator(ajv, mockSchemaRetriever) + + return { + mockSchemaRetriever, + typeValidator, + type: TypeBuilder.random(), + } +} diff --git a/src/validation/type-validator.spec.ts b/src/validation/type-validator.spec.ts index c8e07ee2..cb981873 100644 --- a/src/validation/type-validator.spec.ts +++ b/src/validation/type-validator.spec.ts @@ -1,7 +1,7 @@ import TypeValidator from './type-validator' -import { Ajv, ValidateFunction, ErrorObject } from 'ajv' +import Ajv, { ValidateFunction } from 'ajv' import { SchemaRetriever } from '~schema' -import { mockObj, randomString, mockFn } from '~test-helpers' +import { mockObj, randomString } from '~test-helpers' import '../jest-extensions' import { TypeBuilder } from '~config/resource/builders' @@ -10,6 +10,7 @@ jest.disableAutomock() describe('validate', () => { function createTestDeps() { const stubValidator = mockObj({ compile: jest.fn() }) + const stubValidateFn = mockObj({}) const stubSchemaRetriever = mockObj({ load: jest.fn() }) const typeValidator = new TypeValidator(stubValidator, stubSchemaRetriever) @@ -17,15 +18,17 @@ describe('validate', () => { stubValidator, stubSchemaRetriever, typeValidator, + stubValidateFn, + spyValidateFn: stubValidateFn, } } afterEach(() => jest.resetAllMocks()) it('calls the schema retriver with the correct args', async () => { - const { stubSchemaRetriever, typeValidator, stubValidator } = createTestDeps() + const { stubSchemaRetriever, typeValidator, stubValidator, stubValidateFn } = createTestDeps() const expectedType = TypeBuilder.random() - stubValidator.compile.mockReturnValue(jest.fn()) + stubValidator.compile.mockReturnValue(stubValidateFn) await typeValidator.assert(randomString('body'), expectedType) @@ -33,10 +36,10 @@ describe('validate', () => { }) it('creates a validator function using the correct args', async () => { - const { stubSchemaRetriever, typeValidator, stubValidator } = createTestDeps() + const { stubSchemaRetriever, typeValidator, stubValidator, stubValidateFn } = createTestDeps() const schema = { [randomString('key')]: randomString('value') } stubSchemaRetriever.load.mockResolvedValue(schema) - stubValidator.compile.mockReturnValue(jest.fn()) + stubValidator.compile.mockReturnValue(stubValidateFn) await typeValidator.assert(randomString('body'), TypeBuilder.random()) @@ -44,43 +47,12 @@ describe('validate', () => { }) it('calls the validator func with the correct args', async () => { - const { typeValidator, stubValidator } = createTestDeps() - const validateFn = mockFn() - stubValidator.compile.mockReturnValue(validateFn) + const { typeValidator, stubValidator, stubValidateFn } = createTestDeps() + stubValidator.compile.mockReturnValue(stubValidateFn) const expectedBody = randomString('body') await typeValidator.assert(expectedBody, TypeBuilder.random()) - expect(validateFn).toBeCalledWith(expectedBody) - }) - - it('does not throw if the data does match the type', async () => { - const { typeValidator, stubValidator } = createTestDeps() - stubValidator.compile.mockReturnValue(mockFn().mockReturnValue(true)) - - await typeValidator.assert(randomString('body'), TypeBuilder.random()) - }) - - it('returns validation messages if the data does not match the type', async () => { - const { typeValidator, stubValidator } = createTestDeps() - const error1: Partial = { - dataPath: randomString('.datapath1'), - message: randomString('error-message1'), - } - const error2: Partial = { - dataPath: '', - message: randomString('error-message2'), - } - - const validatorFn: ValidateFunction = mockFn().mockReturnValue(false) - validatorFn.errors = [error1, error2] as ErrorObject[] - stubValidator.compile.mockReturnValue(validatorFn) - - const body = randomString('body') - const type = TypeBuilder.random() - - await expect(typeValidator.assert(body, type)).rejects.toThrowColouredError( - `${error1.dataPath} ${error1.message}\n ${error2.message}`, - ) + expect(stubValidateFn).toBeCalledWith(expectedBody) }) }) diff --git a/src/validation/type-validator.ts b/src/validation/type-validator.ts index 574e7ce8..2cdb8e60 100644 --- a/src/validation/type-validator.ts +++ b/src/validation/type-validator.ts @@ -1,4 +1,4 @@ -import { Ajv } from 'ajv' +import Ajv from 'ajv' import { Type } from '~config/resource/type' import { SchemaRetriever } from '~schema' import { TypeValidationMismatchError } from './errors'