Skip to content

Commit

Permalink
feat: incorporate better-ajv-errors
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed Jun 22, 2019
1 parent c1e0840 commit e58f8f4
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 83 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@stoplight/yaml": "^2.5",
"ajv": "^6.7",
"ajv-oai": "^1.1.1",
"better-ajv-errors": "^0.6.4",
"chalk": "^2.4.2",
"jsonpath-plus": "~0.20",
"lodash": ">=4.17.5",
Expand Down
1 change: 0 additions & 1 deletion src/functions/__tests__/schema-path.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ Array [
test('will error formats', () => {
const target = {
schema: {
type: 'string',
format: 'url',
},
example: 'turtle',
Expand Down
67 changes: 22 additions & 45 deletions src/functions/schema.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { decodePointerFragment } from '@stoplight/json';
import * as AJV from 'ajv';
import * as jsonSpecv4 from 'ajv/lib/refs/json-schema-draft-04.json';
const oasFormatValidator = require('ajv-oai/lib/format-validator');
import { ValidateFunction } from 'ajv';
import { IOutputError } from 'better-ajv-errors';
import { IFunction, IFunctionResult, ISchemaOptions } from '../types';
const betterAjvErrors = require('better-ajv-errors');

const ajv = new AJV({
meta: false,
Expand All @@ -22,25 +24,17 @@ ajv.addFormat('float', { type: 'number', validate: oasFormatValidator.float });
ajv.addFormat('double', { type: 'number', validate: oasFormatValidator.double });
ajv.addFormat('byte', { type: 'string', validate: oasFormatValidator.byte });

const formatPath = (path: string) =>
path
.split('/')
.slice(1)
.map(decodePointerFragment);

const mergeErrors = (existingError: IFunctionResult, newError: AJV.ErrorObject) => {
switch (newError.keyword) {
case 'additionalProperties': {
const { additionalProperty } = newError.params as AJV.AdditionalPropertiesParams;
if (!new RegExp(`[:,] ${additionalProperty}`).test(existingError.message)) {
existingError.message += `, ${(newError.params as AJV.AdditionalPropertiesParams).additionalProperty}`;
}
return true;
const validators = new class extends WeakMap<object, ValidateFunction> {
public get(schemaObj: object) {
let validator = super.get(schemaObj);
if (validator === void 0) {
validator = ajv.compile(schemaObj);
super.set(schemaObj, validator);
}
default:
return existingError.message === newError.message;

return validator;
}
};
}();

export const schema: IFunction<ISchemaOptions> = (targetVal, opts, paths) => {
const results: IFunctionResult[] = [];
Expand All @@ -59,33 +53,16 @@ export const schema: IFunction<ISchemaOptions> = (targetVal, opts, paths) => {
const { schema: schemaObj } = opts;

try {
if (!ajv.validate(schemaObj, targetVal) && ajv.errors) {
// TODO: potential performance improvements (compile, etc)?
const collectedErrors: string[] = [];

for (const error of ajv.errors) {
if (collectedErrors.length > 0) {
const index = collectedErrors.indexOf(error.keyword);
if (index !== -1) {
if (mergeErrors(results[index], error)) continue;
}
}

let message = error.message || '';

if (
error.keyword === 'additionalProperties' &&
(error.params as AJV.AdditionalPropertiesParams).additionalProperty
) {
message += `: ${(error.params as AJV.AdditionalPropertiesParams).additionalProperty}`;
}

collectedErrors.push(error.keyword);
results.push({
path: [...path, ...formatPath(error.dataPath)],
message,
});
}
const validator = validators.get(schemaObj);
if (!validator(targetVal) && validator.errors) {
results.push(
...(betterAjvErrors(schemaObj, targetVal, validator.errors, { format: 'js' }) as IOutputError[]).map(
({ error }) => ({
message: error.trim(),
path,
}),
),
);
}
} catch (ex) {
if (ex instanceof AJV.MissingRefError) {
Expand Down
78 changes: 41 additions & 37 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
dependencies:
regenerator-runtime "^0.12.0"

"@babel/runtime@^7.4.5", "@babel/runtime@~7.4.4":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.4.5", "@babel/runtime@~7.4.4":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
Expand Down Expand Up @@ -1495,6 +1495,19 @@ before-after-hook@^1.4.0:
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d"
integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==

better-ajv-errors@^0.6.4:
version "0.6.4"
resolved "https://registry.yarnpkg.com/better-ajv-errors/-/better-ajv-errors-0.6.4.tgz#1e3c6b93dc11e72c94a0b042594515eb917f2957"
integrity sha512-+spBhtcCzovXWeHpt5dGylFsn3p5l9w+KcUqh/b4MFdLV+q1sT1olxD9izvwi0D3WuP06eVgeZAGLtxtTnUIDg==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/runtime" "^7.0.0"
chalk "^2.4.1"
core-js "^2.5.7"
json-to-ast "^2.0.3"
jsonpointer "^4.0.1"
leven "^2.1.0"

bin-links@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757"
Expand Down Expand Up @@ -2047,6 +2060,11 @@ co@^4.6.0:
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=

code-error-fragment@0.0.230:
version "0.0.230"
resolved "https://registry.yarnpkg.com/code-error-fragment/-/code-error-fragment-0.0.230.tgz#d736d75c832445342eca1d1fedbf17d9618b14d7"
integrity sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==

code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
Expand Down Expand Up @@ -2288,7 +2306,7 @@ copyfiles@^2.1.0:
through2 "^2.0.1"
yargs "^11.0.0"

core-js@^2.4.0, core-js@^2.5.0:
core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7:
version "2.6.9"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
Expand Down Expand Up @@ -2436,7 +2454,7 @@ debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "^2.1.1"

debuglog@*, debuglog@^1.0.1:
debuglog@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
Expand Down Expand Up @@ -3597,6 +3615,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==

grapheme-splitter@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==

growly@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
Expand Down Expand Up @@ -3865,7 +3888,7 @@ import-local@^2.0.0:
pkg-dir "^3.0.0"
resolve-cwd "^2.0.0"

imurmurhash@*, imurmurhash@^0.1.4:
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
Expand Down Expand Up @@ -4932,6 +4955,14 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=

json-to-ast@^2.0.3:
version "2.1.0"
resolved "https://registry.yarnpkg.com/json-to-ast/-/json-to-ast-2.1.0.tgz#041a9fcd03c0845036acb670d29f425cea4faaf9"
integrity sha512-W9Lq347r8tA1DfMvAGn9QNcgYm4Wm7Yc+k8e6vezpMnRT+NHbtlxgNBXRVjXe9YM6eTn6+p/MKOlV/aABJcSnQ==
dependencies:
code-error-fragment "0.0.230"
grapheme-splitter "^1.0.4"

json5@2.x, json5@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
Expand Down Expand Up @@ -4966,6 +4997,11 @@ jsonpath-plus@~0.20:
resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-0.20.1.tgz#5358b8e8a5df569c541de64908d54bca55550e1c"
integrity sha512-8O4tBeXh9XGma2x2aPVwvpo9lXJAd4bx0XA0eRjYs4Cpz7e5PQy7sPttk2YmhvROJhEUu4DNUxmtLueicCqyZg==

jsonpointer@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk=

jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
Expand Down Expand Up @@ -5343,11 +5379,6 @@ lockfile@^1.0.4:
dependencies:
signal-exit "^3.0.2"

lodash._baseindexof@*:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=

lodash._baseuniq@~4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
Expand All @@ -5356,33 +5387,11 @@ lodash._baseuniq@~4.6.0:
lodash._createset "~4.0.0"
lodash._root "~3.0.0"

lodash._bindcallback@*:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=

lodash._cacheindexof@*:
version "3.0.2"
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=

lodash._createcache@*:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=
dependencies:
lodash._getnative "^3.0.0"

lodash._createset@~4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=

lodash._getnative@*, lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=

lodash._reinterpolate@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
Expand Down Expand Up @@ -5428,11 +5437,6 @@ lodash.map@^4.5.1:
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=

lodash.restparam@*:
version "3.6.1"
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=

lodash.set@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
Expand Down Expand Up @@ -7519,7 +7523,7 @@ readable-stream@~1.1.10:
isarray "0.0.1"
string_decoder "~0.10.x"

readdir-scoped-modules@*, readdir-scoped-modules@^1.0.0:
readdir-scoped-modules@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747"
integrity sha1-n6+jfShr5dksuuve4DDcm19AZ0c=
Expand Down

0 comments on commit e58f8f4

Please sign in to comment.