UNPKG

4.09 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.validate = validate;
7Object.defineProperty(exports, "ValidationError", {
8 enumerable: true,
9 get: function () {
10 return _ValidationError.default;
11 }
12});
13
14var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));
15
16var _ValidationError = _interopRequireDefault(require("./ValidationError"));
17
18function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
20// Use CommonJS require for ajv libs so TypeScript consumers aren't locked into esModuleInterop (see #110).
21const Ajv = require('ajv');
22
23const ajvKeywords = require('ajv-keywords');
24/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
25
26/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
27
28/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
29
30/** @typedef {import("ajv").ErrorObject} ErrorObject */
31
32/**
33 * @typedef {Object} Extend
34 * @property {number=} formatMinimum
35 * @property {number=} formatMaximum
36 * @property {boolean=} formatExclusiveMinimum
37 * @property {boolean=} formatExclusiveMaximum
38 */
39
40/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend} Schema */
41
42/** @typedef {ErrorObject & { children?: Array<ErrorObject>}} SchemaUtilErrorObject */
43
44/**
45 * @callback PostFormatter
46 * @param {string} formattedError
47 * @param {SchemaUtilErrorObject} error
48 * @returns {string}
49 */
50
51/**
52 * @typedef {Object} ValidationErrorConfiguration
53 * @property {string=} name
54 * @property {string=} baseDataPath
55 * @property {PostFormatter=} postFormatter
56 */
57
58
59const ajv = new Ajv({
60 allErrors: true,
61 verbose: true,
62 $data: true
63});
64ajvKeywords(ajv, ['instanceof', 'formatMinimum', 'formatMaximum', 'patternRequired']); // Custom keywords
65
66(0, _absolutePath.default)(ajv);
67/**
68 * @param {Schema} schema
69 * @param {Array<object> | object} options
70 * @param {ValidationErrorConfiguration=} configuration
71 * @returns {void}
72 */
73
74function validate(schema, options, configuration) {
75 let errors = [];
76
77 if (Array.isArray(options)) {
78 errors = Array.from(options, nestedOptions => validateObject(schema, nestedOptions));
79 errors.forEach((list, idx) => {
80 const applyPrefix =
81 /**
82 * @param {SchemaUtilErrorObject} error
83 */
84 error => {
85 // eslint-disable-next-line no-param-reassign
86 error.dataPath = `[${idx}]${error.dataPath}`;
87
88 if (error.children) {
89 error.children.forEach(applyPrefix);
90 }
91 };
92
93 list.forEach(applyPrefix);
94 });
95 errors = errors.reduce((arr, items) => {
96 arr.push(...items);
97 return arr;
98 }, []);
99 } else {
100 errors = validateObject(schema, options);
101 }
102
103 if (errors.length > 0) {
104 throw new _ValidationError.default(errors, schema, configuration);
105 }
106}
107/**
108 * @param {Schema} schema
109 * @param {Array<object> | object} options
110 * @returns {Array<SchemaUtilErrorObject>}
111 */
112
113
114function validateObject(schema, options) {
115 const compiledSchema = ajv.compile(schema);
116 const valid = compiledSchema(options);
117 if (valid) return [];
118 return compiledSchema.errors ? filterErrors(compiledSchema.errors) : [];
119}
120/**
121 * @param {Array<ErrorObject>} errors
122 * @returns {Array<SchemaUtilErrorObject>}
123 */
124
125
126function filterErrors(errors) {
127 /** @type {Array<SchemaUtilErrorObject>} */
128 let newErrors = [];
129
130 for (const error of
131 /** @type {Array<SchemaUtilErrorObject>} */
132 errors) {
133 const {
134 dataPath
135 } = error;
136 /** @type {Array<SchemaUtilErrorObject>} */
137
138 let children = [];
139 newErrors = newErrors.filter(oldError => {
140 if (oldError.dataPath.includes(dataPath)) {
141 if (oldError.children) {
142 children = children.concat(oldError.children.slice(0));
143 } // eslint-disable-next-line no-undefined, no-param-reassign
144
145
146 oldError.children = undefined;
147 children.push(oldError);
148 return false;
149 }
150
151 return true;
152 });
153
154 if (children.length) {
155 error.children = children;
156 }
157
158 newErrors.push(error);
159 }
160
161 return newErrors;
162}
\No newline at end of file