Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@develar/schema-utils

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@develar/schema-utils - npm Package Compare versions

Comparing version 2.1.0 to 2.6.5

declarations/index.d.ts

105

CHANGELOG.md

@@ -5,2 +5,107 @@ # Changelog

### [2.6.5](https://github.com/webpack/schema-utils/compare/v2.6.4...v2.6.5) (2020-03-11)
### Bug Fixes
* typo ([#88](https://github.com/webpack/schema-utils/issues/88)) ([52fc92b](https://github.com/webpack/schema-utils/commit/52fc92b531b7503b7bbe1bf9b21bfa26dffbc8f5))
### [2.6.4](https://github.com/webpack/schema-utils/compare/v2.6.3...v2.6.4) (2020-01-17)
### Bug Fixes
* change `initialised` to `initialized` ([#87](https://github.com/webpack/schema-utils/issues/87)) ([70f12d3](https://github.com/webpack/schema-utils/commit/70f12d33a8eaa27249bc9c1a27f886724cf91ea7))
### [2.6.3](https://github.com/webpack/schema-utils/compare/v2.6.2...v2.6.3) (2020-01-17)
### Bug Fixes
* prefer the `baseDataPath` option from arguments ([#86](https://github.com/webpack/schema-utils/issues/86)) ([e236859](https://github.com/webpack/schema-utils/commit/e236859e85b28e35e1294f86fc1ff596a5031cea))
### [2.6.2](https://github.com/webpack/schema-utils/compare/v2.6.1...v2.6.2) (2020-01-14)
### Bug Fixes
* better handle Windows absolute paths ([#85](https://github.com/webpack/schema-utils/issues/85)) ([1fa2930](https://github.com/webpack/schema-utils/commit/1fa2930a161e907b9fc53a7233d605910afdb883))
### [2.6.1](https://github.com/webpack/schema-utils/compare/v2.6.0...v2.6.1) (2019-11-28)
### Bug Fixes
* typescript declarations ([#84](https://github.com/webpack/schema-utils/issues/84)) ([89d55a9](https://github.com/webpack/schema-utils/commit/89d55a9a8edfa6a8ac8b112f226bb3154e260319))
## [2.6.0](https://github.com/webpack/schema-utils/compare/v2.5.0...v2.6.0) (2019-11-27)
### Features
* support configuration via title ([#81](https://github.com/webpack/schema-utils/issues/81)) ([afddc10](https://github.com/webpack/schema-utils/commit/afddc109f6891cd37a9f1835d50862d119a072bf))
### Bug Fixes
* typescript definitions ([#70](https://github.com/webpack/schema-utils/issues/70)) ([f38158d](https://github.com/webpack/schema-utils/commit/f38158d6d040e2c701622778ae8122fb26a4f990))
## [2.5.0](https://github.com/webpack/schema-utils/compare/v2.4.1...v2.5.0) (2019-10-15)
### Bug Fixes
* rework format for maxLength, minLength ([#67](https://github.com/webpack/schema-utils/issues/67)) ([0d12259](https://github.com/webpack/schema-utils/commit/0d12259))
* support all cases with one number in range ([#64](https://github.com/webpack/schema-utils/issues/64)) ([7fc8069](https://github.com/webpack/schema-utils/commit/7fc8069))
* typescript definition and export naming ([#69](https://github.com/webpack/schema-utils/issues/69)) ([a435b79](https://github.com/webpack/schema-utils/commit/a435b79))
### Features
* "smart" numbers range ([62fb107](https://github.com/webpack/schema-utils/commit/62fb107))
### [2.4.1](https://github.com/webpack/schema-utils/compare/v2.4.0...v2.4.1) (2019-09-27)
### Bug Fixes
* publish definitions ([#58](https://github.com/webpack/schema-utils/issues/58)) ([1885faa](https://github.com/webpack/schema-utils/commit/1885faa))
## [2.4.0](https://github.com/webpack/schema-utils/compare/v2.3.0...v2.4.0) (2019-09-26)
### Features
* better errors when the `type` keyword doesn't exist ([0988be2](https://github.com/webpack/schema-utils/commit/0988be2))
* support $data reference ([#56](https://github.com/webpack/schema-utils/issues/56)) ([d2f11d6](https://github.com/webpack/schema-utils/commit/d2f11d6))
* types definitions ([#52](https://github.com/webpack/schema-utils/issues/52)) ([facb431](https://github.com/webpack/schema-utils/commit/facb431))
## [2.3.0](https://github.com/webpack/schema-utils/compare/v2.2.0...v2.3.0) (2019-09-26)
### Features
* support `not` keyword ([#53](https://github.com/webpack/schema-utils/issues/53)) ([765f458](https://github.com/webpack/schema-utils/commit/765f458))
## [2.2.0](https://github.com/webpack/schema-utils/compare/v2.1.0...v2.2.0) (2019-09-02)
### Features
* better error output for `oneOf` and `anyOf` ([#48](https://github.com/webpack/schema-utils/issues/48)) ([#50](https://github.com/webpack/schema-utils/issues/50)) ([332242f](https://github.com/webpack/schema-utils/commit/332242f))
## [2.1.0](https://github.com/webpack-contrib/schema-utils/compare/v2.0.1...v2.1.0) (2019-08-07)
### Bug Fixes
* throw error on sparse arrays ([#47](https://github.com/webpack-contrib/schema-utils/issues/47)) ([b85ac38](https://github.com/webpack-contrib/schema-utils/commit/b85ac38))
### Features
* export `ValidateError` ([#46](https://github.com/webpack-contrib/schema-utils/issues/46)) ([ff781d7](https://github.com/webpack-contrib/schema-utils/commit/ff781d7))
### [2.0.1](https://github.com/webpack-contrib/schema-utils/compare/v2.0.0...v2.0.1) (2019-07-18)

@@ -7,0 +112,0 @@

86

dist/keywords/absolutePath.js

@@ -8,3 +8,14 @@ "use strict";

function errorMessage(schema, data, message) {
/** @typedef {import("ajv").Ajv} Ajv */
/** @typedef {import("../validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
/**
*
* @param {string} data
* @param {object} schema
* @param {string} message
* @returns {object} // Todo `returns` should be `SchemaUtilErrorObject`
*/
function errorMessage(message, schema, data) {
return {

@@ -19,37 +30,64 @@ keyword: 'absolutePath',

}
/**
* @param {boolean} shouldBeAbsolute
* @param {object} schema
* @param {string} data
* @returns {object}
*/
function getErrorFor(shouldBeAbsolute, data, schema) {
function getErrorFor(shouldBeAbsolute, schema, data) {
const message = shouldBeAbsolute ? `The provided value ${JSON.stringify(data)} is not an absolute path!` : `A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
return errorMessage(schema, data, message);
return errorMessage(message, schema, data);
}
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
var _default = ajv => ajv.addKeyword('absolutePath', {
errors: true,
type: 'string',
compile(expected, schema) {
function callback(data) {
let passes = true;
const isExclamationMarkPresent = data.includes('!');
const isCorrectAbsoluteOrRelativePath = expected === /^(?:[A-Za-z]:\\|\/)/.test(data);
function addAbsolutePathKeyword(ajv) {
ajv.addKeyword('absolutePath', {
errors: true,
type: 'string',
if (isExclamationMarkPresent) {
callback.errors = [errorMessage(schema, data, `The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`)];
passes = false;
}
compile(schema, parentSchema) {
/**
* @param {any} data
* @returns {boolean}
*/
function callback(data) {
let passes = true;
const isExclamationMarkPresent = data.includes('!');
if (!isCorrectAbsoluteOrRelativePath) {
callback.errors = [getErrorFor(expected, data, schema)];
passes = false;
if (isExclamationMarkPresent) {
callback.errors = [errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`, parentSchema, data)];
passes = false;
} // ?:[A-Za-z]:\\ - Windows absolute path
// \\\\ - Windows network absolute path
// \/ - Unix-like OS absolute path
const isCorrectAbsolutePath = schema === /^(?:[A-Za-z]:(\\|\/)|\\\\|\/)/.test(data);
if (!isCorrectAbsolutePath) {
callback.errors = [getErrorFor(schema, parentSchema, data)];
passes = false;
}
return passes;
}
/** @type {null | Array<SchemaUtilErrorObject>}*/
return passes;
callback.errors = [];
return callback;
}
callback.errors = [];
return callback;
}
});
return ajv;
}
});
var _default = addAbsolutePathKeyword;
exports.default = _default;

@@ -18,5 +18,31 @@ "use strict";

/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("ajv").ErrorObject} ErrorObject */
/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7)} Schema */
/** @typedef {ErrorObject & { children?: Array<ErrorObject>}} SchemaUtilErrorObject */
/**
* @callback PostFormatter
* @param {string} formattedError
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
/**
* @typedef {Object} ValidationErrorConfiguration
* @property {string=} name
* @property {string=} baseDataPath
* @property {PostFormatter=} postFormatter
*/
const ajv = new _ajv.default({
allErrors: true,
verbose: true,
$data: true,
coerceTypes: true

@@ -27,10 +53,20 @@ });

(0, _absolutePath.default)(ajv);
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
function validate(schema, options, configuration = {}) {
function validate(schema, options, configuration) {
let errors = [];
if (Array.isArray(options)) {
errors = options.map(nestedOptions => validateObject(schema, nestedOptions));
errors = Array.from(options).map(nestedOptions => validateObject(schema, nestedOptions));
errors.forEach((list, idx) => {
const applyPrefix = error => {
const applyPrefix =
/**
* @param {SchemaUtilErrorObject} error
*/
error => {
// eslint-disable-next-line no-param-reassign

@@ -54,19 +90,38 @@ error.dataPath = `[${idx}]${error.dataPath}`;

}
return errors;
}
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @returns {Array<SchemaUtilErrorObject>}
*/
function validateObject(schema, options) {
const compiledSchema = ajv.compile(schema);
const valid = compiledSchema(options);
if (!compiledSchema.errors) {
return [];
}
return valid ? [] : filterErrors(compiledSchema.errors);
}
/**
* @param {Array<ErrorObject>} errors
* @returns {Array<SchemaUtilErrorObject>}
*/
function filterErrors(errors) {
/** @type {Array<SchemaUtilErrorObject>} */
let newErrors = [];
for (const error of errors) {
for (const error of
/** @type {Array<SchemaUtilErrorObject>} */
errors) {
const {
dataPath
} = error;
/** @type {Array<SchemaUtilErrorObject>} */
let children = [];

@@ -96,5 +151,8 @@ newErrors = newErrors.filter(oldError => {

return newErrors;
}
} // TODO change after resolve https://github.com/microsoft/TypeScript/issues/34994
validate.ValidationError = _ValidationError.default;
validate.ValidateError = _ValidationError.default;
var _default = validate;
exports.default = _default;

@@ -7,2 +7,19 @@ "use strict";

exports.default = void 0;
const Range = require('./util/Range');
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("./validate").Schema} Schema */
/** @typedef {import("./validate").ValidationErrorConfiguration} ValidationErrorConfiguration */
/** @typedef {import("./validate").PostFormatter} PostFormatter */
/** @typedef {import("./validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
/** @enum {number} */
const SPECIFICITY = {

@@ -42,2 +59,8 @@ type: 1,

};
/**
*
* @param {Array<SchemaUtilErrorObject>} array
* @param {(item: SchemaUtilErrorObject) => number} fn
* @returns {Array<SchemaUtilErrorObject>}
*/

@@ -48,46 +71,205 @@ function filterMax(array, fn) {

}
/**
*
* @param {Array<SchemaUtilErrorObject>} children
* @returns {Array<SchemaUtilErrorObject>}
*/
function filterChildren(children) {
let newChildren = children;
newChildren = filterMax(newChildren, error => error.dataPath ? error.dataPath.length : 0);
newChildren = filterMax(newChildren, error => SPECIFICITY[error.keyword] || 2);
newChildren = filterMax(newChildren,
/**
*
* @param {SchemaUtilErrorObject} error
* @returns {number}
*/
error => error.dataPath ? error.dataPath.length : 0);
newChildren = filterMax(newChildren,
/**
* @param {SchemaUtilErrorObject} error
* @returns {number}
*/
error => SPECIFICITY[
/** @type {keyof typeof SPECIFICITY} */
error.keyword] || 2);
return newChildren;
}
/**
* Find all children errors
* @param {Array<SchemaUtilErrorObject>} children
* @param {Array<string>} schemaPaths
* @return {number} returns index of first child
*/
function findAllChildren(children, schemaPaths) {
let i = children.length - 1;
const predicate =
/**
* @param {string} schemaPath
* @returns {boolean}
*/
schemaPath => children[i].schemaPath.indexOf(schemaPath) !== 0;
while (i > -1 && !schemaPaths.every(predicate)) {
if (children[i].keyword === 'anyOf' || children[i].keyword === 'oneOf') {
const refs = extractRefs(children[i]);
const childrenStart = findAllChildren(children.slice(0, i), refs.concat(children[i].schemaPath));
i = childrenStart - 1;
} else {
i -= 1;
}
}
return i + 1;
}
/**
* Extracts all refs from schema
* @param {SchemaUtilErrorObject} error
* @return {Array<string>}
*/
function extractRefs(error) {
const {
schema
} = error;
if (!Array.isArray(schema)) {
return [];
}
return schema.map(({
$ref
}) => $ref).filter(s => s);
}
/**
* Groups children by their first level parent (assuming that error is root)
* @param {Array<SchemaUtilErrorObject>} children
* @return {Array<SchemaUtilErrorObject>}
*/
function groupChildrenByFirstChild(children) {
const result = [];
let i = children.length - 1;
while (i > 0) {
const child = children[i];
if (child.keyword === 'anyOf' || child.keyword === 'oneOf') {
const refs = extractRefs(child);
const childrenStart = findAllChildren(children.slice(0, i), refs.concat(child.schemaPath));
if (childrenStart !== i) {
result.push(Object.assign({}, child, {
children: children.slice(childrenStart, i)
}));
i = childrenStart;
} else {
result.push(child);
}
} else {
result.push(child);
}
i -= 1;
}
if (i === 0) {
result.push(children[i]);
}
return result.reverse();
}
/**
* @param {string} str
* @param {string} prefix
* @returns {string}
*/
function indent(str, prefix) {
return str.replace(/\n(?!$)/g, `\n${prefix}`);
}
/**
* @param {any} maybeObj
* @returns {boolean}
*/
function isObject(maybyObj) {
return typeof maybyObj === 'object' && maybyObj !== null;
function isObject(maybeObj) {
return typeof maybeObj === 'object' && maybeObj !== null;
}
/**
* @param {Schema} schema
* @returns {boolean}
*/
function likeNumber(schema) {
return schema.type === 'number' || typeof schema.minimum !== 'undefined' || typeof schema.exclusiveMinimum !== 'undefined' || typeof schema.maximum !== 'undefined' || typeof schema.exclusiveMaximum !== 'undefined' || typeof schema.multipleOf !== 'undefined';
}
/**
* @param {Schema} schema
* @returns {boolean}
*/
function likeInteger(schema) {
return schema.type === 'integer' || typeof schema.minimum !== 'undefined' || typeof schema.exclusiveMinimum !== 'undefined' || typeof schema.maximum !== 'undefined' || typeof schema.exclusiveMaximum !== 'undefined' || typeof schema.multipleOf !== 'undefined';
}
/**
* @param {Schema & {formatMinimum?: string; formatMaximum?: string;}} schema
* @returns {boolean}
*/
function likeString(schema) {
return schema.type === 'string' || typeof schema.minLength !== 'undefined' || typeof schema.maxLength !== 'undefined' || typeof schema.pattern !== 'undefined' || typeof schema.format !== 'undefined' || typeof schema.formatMinimum !== 'undefined' || typeof schema.formatMaximum !== 'undefined';
}
/**
* @param {Schema} schema
* @returns {boolean}
*/
function likeBoolean(schema) {
return schema.type === 'boolean';
}
/**
* @param {Schema} schema
* @returns {boolean}
*/
function likeArray(schema) {
return schema.type === 'array' || typeof schema.minItems === 'number' || typeof schema.maxItems === 'number' || typeof schema.uniqueItems !== 'undefined' || typeof schema.items !== 'undefined' || typeof schema.additionalItems !== 'undefined' || typeof schema.contains !== 'undefined';
}
/**
* @param {Schema & {patternRequired?: Array<string>}} schema
* @returns {boolean}
*/
function likeObject(schema) {
return schema.type === 'object' || typeof schema.minProperties !== 'undefined' || typeof schema.maxProperties !== 'undefined' || typeof schema.required !== 'undefined' || typeof schema.properties !== 'undefined' || typeof schema.patternProperties !== 'undefined' || typeof schema.additionalProperties !== 'undefined' || typeof schema.dependencies !== 'undefined' || typeof schema.propertyNames !== 'undefined' || typeof schema.patternRequired !== 'undefined';
}
/**
* @param {Schema} schema
* @returns {boolean}
*/
function likeNull(schema) {
return schema.type === 'null';
}
/**
* @param {string} type
* @returns {string}
*/
function getArticle(type) {

@@ -100,17 +282,153 @@ if (/^[aeiou]/i.test(type)) {

}
/**
* @param {Schema=} schema
* @returns {string}
*/
function getSchemaNonTypes(schema) {
if (!schema) {
return '';
}
if (!schema.type) {
if (likeNumber(schema) || likeInteger(schema)) {
return ' | should be any non-number';
}
if (likeString(schema)) {
return ' | should be any non-string';
}
if (likeArray(schema)) {
return ' | should be any non-array';
}
if (likeObject(schema)) {
return ' | should be any non-object';
}
}
return '';
}
/**
* @param {Schema=} schema
* @returns {Array<string>}
*/
function numberHints(schema) {
if (!schema) {
return [];
}
const hints = [];
const range = new Range();
if (typeof schema.minimum === 'number') {
range.left(schema.minimum);
}
if (typeof schema.exclusiveMinimum === 'number') {
range.left(schema.exclusiveMinimum, true);
}
if (typeof schema.maximum === 'number') {
range.right(schema.maximum);
}
if (typeof schema.exclusiveMaximum === 'number') {
range.right(schema.exclusiveMaximum, true);
}
const rangeFormat = range.format();
if (rangeFormat) {
hints.push(rangeFormat);
}
if (typeof schema.multipleOf === 'number') {
hints.push(`should be multiple of ${schema.multipleOf}`);
}
return hints;
}
/**
* @param {Array<string>} hints
* @returns {string}
*/
function formatHints(hints) {
return hints.length > 0 ? `(${hints.join(', ')})` : '';
}
/**
* @param {Schema} schema
* @returns {string}
*/
function getHints(schema) {
if (likeNumber(schema) || likeInteger(schema)) {
return formatHints(numberHints(schema));
}
return '';
}
class ValidationError extends Error {
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @param {Schema} schema
* @param {ValidationErrorConfiguration} configuration
*/
constructor(errors, schema, configuration = {}) {
super();
/** @type {string} */
this.name = 'ValidationError';
/** @type {Array<SchemaUtilErrorObject>} */
this.errors = errors;
/** @type {Schema} */
this.schema = schema;
this.headerName = configuration.name || 'Object';
this.baseDataPath = configuration.baseDataPath || 'configuration';
let headerNameFromSchema;
let baseDataPathFromSchema;
if (schema.title && (!configuration.name || !configuration.baseDataPath)) {
const splittedTitleFromSchema = schema.title.match(/^(.+) (.+)$/);
if (splittedTitleFromSchema) {
if (!configuration.name) {
[, headerNameFromSchema] = splittedTitleFromSchema;
}
if (!configuration.baseDataPath) {
[,, baseDataPathFromSchema] = splittedTitleFromSchema;
}
}
}
/** @type {string} */
this.headerName = configuration.name || headerNameFromSchema || 'Object';
/** @type {string} */
this.baseDataPath = configuration.baseDataPath || baseDataPathFromSchema || 'configuration';
/** @type {PostFormatter | null} */
this.postFormatter = configuration.postFormatter || null;
const header = `Invalid ${this.baseDataPath} object. ${this.headerName} has been initialised using ${getArticle(this.baseDataPath)} ${this.baseDataPath} object that does not match the API schema.\n`;
const header = `Invalid ${this.baseDataPath} object. ${this.headerName} has been initialized using ${getArticle(this.baseDataPath)} ${this.baseDataPath} object that does not match the API schema.\n`;
/** @type {string} */
this.message = `${header}${this.formatValidationErrors(errors)}`;
Error.captureStackTrace(this, this.constructor);
}
/**
* @param {string} path
* @returns {Schema}
*/
getSchemaPart(path) {

@@ -121,3 +439,5 @@ const newPath = path.split('/');

for (let i = 1; i < newPath.length; i++) {
const inner = schemaPart[newPath[i]];
const inner = schemaPart[
/** @type {keyof Schema} */
newPath[i]];

@@ -133,5 +453,18 @@ if (!inner) {

}
/**
* @param {Schema} schema
* @param {Array<Object>} prevSchemas
* @returns {string}
*/
formatSchema(schema, prevSchemas = []) {
const formatInnerSchema = (innerSchema, addSelf) => {
const formatInnerSchema =
/**
*
* @param {Object} innerSchema
* @param {boolean=} addSelf
* @returns {string}
*/
(innerSchema, addSelf) => {
if (!addSelf) {

@@ -146,15 +479,30 @@ return this.formatSchema(innerSchema, prevSchemas);

return this.formatSchema(innerSchema, prevSchemas.concat(schema));
}; // eslint-disable-next-line default-case
};
if (schema.not && !likeObject(schema)) {
return `non ${formatInnerSchema(schema.not)}`;
}
switch (schema.instanceof) {
case 'Function':
return 'function';
case 'RegExp':
return 'RegExp';
if (
/** @type {Schema & {instanceof: string | Array<string>}} */
schema.instanceof) {
const {
instanceof: value
} =
/** @type {Schema & {instanceof: string | Array<string>}} */
schema;
const values = !Array.isArray(value) ? [value] : value;
return values.map(
/**
* @param {string} item
* @returns {string}
*/
item => item === 'Function' ? 'function' : item).join(' | ');
}
if (schema.enum) {
return schema.enum.map(item => JSON.stringify(item)).join(' | ');
return (
/** @type {Array<any>} */
schema.enum.map(item => JSON.stringify(item)).join(' | ')
);
}

@@ -167,15 +515,33 @@

if (schema.oneOf) {
return schema.oneOf.map(formatInnerSchema).join(' | ');
return (
/** @type {Array<Schema>} */
schema.oneOf.map(item => formatInnerSchema(item, true)).join(' | ')
);
}
if (schema.anyOf) {
return schema.anyOf.map(formatInnerSchema).join(' | ');
return (
/** @type {Array<Schema>} */
schema.anyOf.map(item => formatInnerSchema(item, true)).join(' | ')
);
}
if (schema.allOf) {
return schema.allOf.map(formatInnerSchema).join(' & ');
return (
/** @type {Array<Schema>} */
schema.allOf.map(item => formatInnerSchema(item, true)).join(' & ')
);
}
if (schema.if) {
return `if ${formatInnerSchema(schema.if)} then ${formatInnerSchema(schema.then)}${schema.else ? ` else ${formatInnerSchema(schema.else)}` : ''}`;
if (
/** @type {JSONSchema7} */
schema.if) {
const {
if: ifValue,
then: thenValue,
else: elseValue
} =
/** @type {JSONSchema7} */
schema;
return `${ifValue ? `if ${formatInnerSchema(ifValue)}` : ''}${thenValue ? ` then ${formatInnerSchema(thenValue)}` : ''}${elseValue ? ` else ${formatInnerSchema(elseValue)}` : ''}`;
}

@@ -188,26 +554,5 @@

if (likeNumber(schema) || likeInteger(schema)) {
const hints = [];
if (typeof schema.minimum === 'number') {
hints.push(`should be >= ${schema.minimum}`);
}
if (typeof schema.exclusiveMinimum === 'number') {
hints.push(`should be > ${schema.exclusiveMinimum}`);
}
if (typeof schema.maximum === 'number') {
hints.push(`should be <= ${schema.maximum}`);
}
if (typeof schema.exclusiveMaximum === 'number') {
hints.push(`should be > ${schema.exclusiveMaximum}`);
}
if (typeof schema.multipleOf === 'number') {
hints.push(`should be multiple of ${schema.multipleOf}`);
}
const type = schema.type === 'integer' ? 'integer' : 'number';
return `${type}${hints.length > 0 ? ` (${hints.join(', ')})` : ''}`;
const hints = getHints(schema);
return `${type}${hints.length > 0 ? ` ${hints}` : ''}`;
}

@@ -222,4 +567,6 @@

type = 'non-empty string';
} else {
hints.push(`should not be shorter than ${schema.minLength} characters`);
} else if (schema.minLength !== 0) {
/* if min length === 0 it does not make hint for user */
const length = schema.minLength - 1;
hints.push(`should be longer than ${length} character${length > 1 ? 's' : ''}`);
}

@@ -229,3 +576,7 @@ }

if (typeof schema.maxLength === 'number') {
hints.push(`should not be longer than ${schema.maxLength} character${schema.maxLength > 1 ? 's' : ''}`);
if (schema.maxLength === 0) {
type = 'empty string';
} else {
hints.push(`should be shorter than ${schema.maxLength + 1} characters`);
}
}

@@ -241,8 +592,24 @@

if (schema.formatMinimum) {
hints.push(`should be ${schema.formatExclusiveMinimum ? '>' : '>='} ${JSON.stringify(schema.formatMinimum)}`);
if (
/** @type {Schema & {formatMinimum?: string; formatExclusiveMinimum?: boolean;}} */
schema.formatMinimum) {
const {
formatExclusiveMinimum,
formatMinimum
} =
/** @type {Schema & {formatMinimum?: string; formatExclusiveMinimum?: boolean;}} */
schema;
hints.push(`should be ${formatExclusiveMinimum ? '>' : '>='} ${JSON.stringify(formatMinimum)}`);
}
if (schema.formatMaximum) {
hints.push(`should be ${schema.formatExclusiveMaximum ? '<' : '<='} ${JSON.stringify(schema.formatMaximum)}`);
if (
/** @type {Schema & {formatMaximum?: string; formatExclusiveMaximum?: boolean;}} */
schema.formatMaximum) {
const {
formatExclusiveMaximum,
formatMaximum
} =
/** @type {Schema & {formatMaximum?: string; formatExclusiveMaximum?: boolean;}} */
schema;
hints.push(`should be ${formatExclusiveMaximum ? '<' : '<='} ${JSON.stringify(formatMaximum)}`);
}

@@ -277,6 +644,8 @@

if (Array.isArray(schema.items) && schema.items.length > 0) {
items = `${schema.items.map(formatInnerSchema).join(', ')}`;
items = `${
/** @type {Array<Schema>} */
schema.items.map(item => formatInnerSchema(item)).join(', ')}`;
if (hasAdditionalItems) {
if (isObject(schema.additionalItems) && Object.keys(schema.additionalItems).length > 0) {
if (schema.additionalItems && isObject(schema.additionalItems) && Object.keys(schema.additionalItems).length > 0) {
hints.push(`additional items should be ${formatInnerSchema(schema.additionalItems)}`);

@@ -312,3 +681,3 @@ }

if (typeof schema.maxProperties === 'number') {
hints.push(`should not have more than ${schema.maxProperties} ${schema.minProperties > 1 ? 'properties' : 'property'}`);
hints.push(`should not have more than ${schema.maxProperties} ${schema.minProperties && schema.minProperties > 1 ? 'properties' : 'property'}`);
}

@@ -323,4 +692,5 @@

const required = schema.required ? schema.required : [];
const allProperties = [...new Set([].concat(required).concat(properties))];
const hasAdditionalProperties = typeof schema.additionalProperties === 'undefined' || Boolean(schema.additionalProperties);
const allProperties = [...new Set(
/** @type {Array<string>} */
[].concat(required).concat(properties))];
const objectStructure = allProperties.map(property => {

@@ -331,7 +701,14 @@ const isRequired = required.includes(property); // Some properties need quotes, maybe we should add check

return `${property}${isRequired ? '' : '?'}`;
}).concat(hasAdditionalProperties ? isObject(schema.additionalProperties) ? [`<key>: ${formatInnerSchema(schema.additionalProperties)}`] : ['…'] : []).join(', ');
}).concat(typeof schema.additionalProperties === 'undefined' || Boolean(schema.additionalProperties) ? schema.additionalProperties && isObject(schema.additionalProperties) ? [`<key>: ${formatInnerSchema(schema.additionalProperties)}`] : ['…'] : []).join(', ');
const {
dependencies,
propertyNames,
patternRequired
} =
/** @type {Schema & {patternRequired?: Array<string>;}} */
schema;
if (schema.dependencies) {
Object.keys(schema.dependencies).forEach(dependencyName => {
const dependency = schema.dependencies[dependencyName];
if (dependencies) {
Object.keys(dependencies).forEach(dependencyName => {
const dependency = dependencies[dependencyName];

@@ -346,8 +723,13 @@ if (Array.isArray(dependency)) {

if (schema.propertyNames && Object.keys(schema.propertyNames).length > 0) {
if (propertyNames && Object.keys(propertyNames).length > 0) {
hints.push(`each property name should match format ${JSON.stringify(schema.propertyNames.format)}`);
}
if (schema.patternRequired && schema.patternRequired.length > 0) {
hints.push(`should have property matching pattern ${schema.patternRequired.map(item => JSON.stringify(item))}`);
if (patternRequired && patternRequired.length > 0) {
hints.push(`should have property matching pattern ${patternRequired.map(
/**
* @param {string} item
* @returns {string}
*/
item => JSON.stringify(item))}`);
}

@@ -363,3 +745,3 @@

if (Array.isArray(schema.type)) {
return `${schema.type.map(item => item).join(' | ')}`;
return `${schema.type.join(' | ')}`;
} // Fallback for unknown keywords

@@ -372,7 +754,21 @@

}
/**
* @param {Schema=} schemaPart
* @param {(boolean | Array<string>)=} additionalPath
* @param {boolean=} needDot
* @returns {string}
*/
getSchemaPartText(schemaPart, additionalPath, needDot = false) {
if (additionalPath) {
if (!schemaPart) {
return '';
}
if (Array.isArray(additionalPath)) {
for (let i = 0; i < additionalPath.length; i++) {
const inner = schemaPart[additionalPath[i]];
/** @type {Schema | undefined} */
const inner = schemaPart[
/** @type {keyof Schema} */
additionalPath[i]];

@@ -401,4 +797,13 @@ if (inner) {

}
/**
* @param {Schema=} schemaPart
* @returns {string}
*/
getSchemaPartDescription(schemaPart) {
if (!schemaPart) {
return '';
}
while (schemaPart.$ref) {

@@ -415,47 +820,103 @@ // eslint-disable-next-line no-param-reassign

}
/**
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
formatValidationError(error) {
const dataPath = `${this.baseDataPath}${error.dataPath}`;
const {
keyword,
dataPath: errorDataPath
} = error;
const dataPath = `${this.baseDataPath}${errorDataPath}`;
switch (error.keyword) {
switch (keyword) {
case 'type':
// eslint-disable-next-line default-case
switch (error.params.type) {
case 'number':
return `${dataPath} should be a ${this.getSchemaPartText(error.parentSchema, false, true)}`;
{
const {
parentSchema,
params
} = error; // eslint-disable-next-line default-case
case 'integer':
return `${dataPath} should be a ${this.getSchemaPartText(error.parentSchema, false, true)}`;
switch (
/** @type {import("ajv").TypeParams} */
params.type) {
case 'number':
return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
case 'string':
return `${dataPath} should be a ${this.getSchemaPartText(error.parentSchema, false, true)}`;
case 'integer':
return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
case 'boolean':
return `${dataPath} should be a ${this.getSchemaPartText(error.parentSchema, false, true)}`;
case 'string':
return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
case 'array':
return `${dataPath} should be an array:\n${this.getSchemaPartText(error.parentSchema)}`;
case 'boolean':
return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
case 'object':
return `${dataPath} should be an object:\n${this.getSchemaPartText(error.parentSchema)}`;
case 'array':
return `${dataPath} should be an array:\n${this.getSchemaPartText(parentSchema)}`;
case 'null':
return `${dataPath} should be a ${this.getSchemaPartText(error.parentSchema, false, true)}`;
case 'object':
return `${dataPath} should be an object:\n${this.getSchemaPartText(parentSchema)}`;
default:
return `${dataPath} should be:\n${this.getSchemaPartText(error.parentSchema)}`;
case 'null':
return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
default:
return `${dataPath} should be:\n${this.getSchemaPartText(parentSchema)}`;
}
}
case 'instanceof':
return `${dataPath} should be an instance of ${this.getSchemaPartText(error.parentSchema)}.`;
{
const {
parentSchema
} = error;
return `${dataPath} should be an instance of ${this.getSchemaPartText(parentSchema)}.`;
}
case 'pattern':
return `${dataPath} should match pattern ${JSON.stringify(error.params.pattern)}.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
pattern
} =
/** @type {import("ajv").PatternParams} */
params;
return `${dataPath} should match pattern ${JSON.stringify(pattern)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'format':
return `${dataPath} should match format ${JSON.stringify(error.params.format)}.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
format
} =
/** @type {import("ajv").FormatParams} */
params;
return `${dataPath} should match format ${JSON.stringify(format)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'formatMinimum':
case 'formatMaximum':
return `${dataPath} should be ${error.params.comparison} ${JSON.stringify(error.params.limit)}.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
comparison,
limit
} =
/** @type {import("ajv").ComparisonParams} */
params;
return `${dataPath} should be ${comparison} ${JSON.stringify(limit)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}

@@ -466,17 +927,68 @@ case 'minimum':

case 'exclusiveMaximum':
return `${dataPath} should be ${error.params.comparison} ${error.params.limit}.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
parentSchema,
params
} = error;
const {
comparison,
limit
} =
/** @type {import("ajv").ComparisonParams} */
params;
const hints = numberHints(parentSchema);
if (hints.length === 0) {
hints.push(`should be ${comparison} ${limit}`);
}
return `${dataPath} ${hints.join(' ')}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'multipleOf':
return `${dataPath} should be multiple of ${error.params.multipleOf}.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
multipleOf
} =
/** @type {import("ajv").MultipleOfParams} */
params;
return `${dataPath} should be multiple of ${multipleOf}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'patternRequired':
return `${dataPath} should have property matching pattern ${JSON.stringify(error.params.missingPattern)}.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
missingPattern
} =
/** @type {import("ajv").PatternRequiredParams} */
params;
return `${dataPath} should have property matching pattern ${JSON.stringify(missingPattern)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'minLength':
{
if (error.params.limit === 1) {
return `${dataPath} should be an non-empty string.${this.getSchemaPartDescription(error.parentSchema)}`;
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
if (limit === 1) {
return `${dataPath} should be an non-empty string${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
return `${dataPath} should not be shorter than ${error.params.limit} characters.${this.getSchemaPartDescription(error.parentSchema)}`;
const length = limit - 1;
return `${dataPath} should be longer than ${length} character${length > 1 ? 's' : ''}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}

@@ -486,7 +998,17 @@

{
if (error.params.limit === 1) {
return `${dataPath} should be an non-empty array.${this.getSchemaPartDescription(error.parentSchema)}`;
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
if (limit === 1) {
return `${dataPath} should be an non-empty array${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
return `${dataPath} should not have fewer than ${error.params.limit} items.${this.getSchemaPartDescription(error.parentSchema)}`;
return `${dataPath} should not have fewer than ${limit} items${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}

@@ -496,41 +1018,147 @@

{
if (error.params.limit === 1) {
return `${dataPath} should be an non-empty object.${this.getSchemaPartDescription(error.parentSchema)}`;
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
if (limit === 1) {
return `${dataPath} should be an non-empty object${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
return `${dataPath} should not have fewer than ${error.params.limit} properties.${this.getSchemaPartDescription(error.parentSchema)}`;
return `${dataPath} should not have fewer than ${limit} properties${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'maxLength':
return `${dataPath} should not be longer than ${error.params.limit} characters.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
return `${dataPath} should be shorter than ${limit + 1} characters${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'maxItems':
return `${dataPath} should not have more than ${error.params.limit} items.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
return `${dataPath} should not have more than ${limit} items${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'maxProperties':
return `${dataPath} should not have more than ${error.params.limit} properties.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
return `${dataPath} should not have more than ${limit} properties${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'uniqueItems':
return `${dataPath} should not contain the item '${error.data[error.params.i]}' twice.${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
i
} =
/** @type {import("ajv").UniqueItemsParams} */
params;
return `${dataPath} should not contain the item '${error.data[i]}' twice${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}
case 'additionalItems':
return `${dataPath} should not have more than ${error.params.limit} items. These items are valid:\n${this.getSchemaPartText(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
limit
} =
/** @type {import("ajv").LimitParams} */
params;
return `${dataPath} should not have more than ${limit} items${getSchemaNonTypes(parentSchema)}. These items are valid:\n${this.getSchemaPartText(parentSchema)}`;
}
case 'contains':
return `${dataPath} should contains at least one ${this.getSchemaPartText(error.parentSchema, ['contains'])} item.`;
{
const {
parentSchema
} = error;
return `${dataPath} should contains at least one ${this.getSchemaPartText(parentSchema, ['contains'])} item${getSchemaNonTypes(parentSchema)}.`;
}
case 'required':
{
const missingProperty = error.params.missingProperty.replace(/^\./, '');
const hasProperty = Boolean(error.parentSchema.properties && error.parentSchema.properties[missingProperty]);
return `${dataPath} misses the property '${missingProperty}'.${hasProperty ? ` Should be:\n${this.getSchemaPartText(error.parentSchema, ['properties', missingProperty])}` : this.getSchemaPartDescription(error.parentSchema)}`;
const {
parentSchema,
params
} = error;
const missingProperty =
/** @type {import("ajv").DependenciesParams} */
params.missingProperty.replace(/^\./, '');
const hasProperty = parentSchema && Boolean(
/** @type {Schema} */
parentSchema.properties &&
/** @type {Schema} */
parentSchema.properties[missingProperty]);
return `${dataPath} misses the property '${missingProperty}'${getSchemaNonTypes(parentSchema)}.${hasProperty ? ` Should be:\n${this.getSchemaPartText(parentSchema, ['properties', missingProperty])}` : this.getSchemaPartDescription(parentSchema)}`;
}
case 'additionalProperties':
return `${dataPath} has an unknown property '${error.params.additionalProperty}'. These properties are valid:\n${this.getSchemaPartText(error.parentSchema)}`;
{
const {
params,
parentSchema
} = error;
const {
additionalProperty
} =
/** @type {import("ajv").AdditionalPropertiesParams} */
params;
return `${dataPath} has an unknown property '${additionalProperty}'${getSchemaNonTypes(parentSchema)}. These properties are valid:\n${this.getSchemaPartText(parentSchema)}`;
}
case 'dependencies':
{
const dependencies = error.params.deps.split(',').map(dep => `'${dep.trim()}'`).join(', ');
return `${dataPath} should have properties ${dependencies} when property '${error.params.property}' is present.${this.getSchemaPartDescription(error.parentSchema)}`;
const {
params,
parentSchema
} = error;
const {
property,
deps
} =
/** @type {import("ajv").DependenciesParams} */
params;
const dependencies = deps.split(',').map(
/**
* @param {string} dep
* @returns {string}
*/
dep => `'${dep.trim()}'`).join(', ');
return `${dataPath} should have properties ${dependencies} when property '${property}' is present${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
}

@@ -540,4 +1168,13 @@

{
const invalidProperty = error.params.propertyName;
return `${dataPath} property name '${invalidProperty}' is invalid. Property names should be match format ${JSON.stringify(error.schema.format)}.${this.getSchemaPartDescription(error.parentSchema)}`;
const {
params,
parentSchema,
schema
} = error;
const {
propertyName
} =
/** @type {import("ajv").PropertyNamesParams} */
params;
return `${dataPath} property name '${propertyName}' is invalid${getSchemaNonTypes(parentSchema)}. Property names should be match format ${JSON.stringify(schema.format)}.${this.getSchemaPartDescription(parentSchema)}`;
}

@@ -547,55 +1184,117 @@

{
if (error.parentSchema && error.parentSchema.enum && error.parentSchema.enum.length === 1) {
return `${dataPath} should be ${this.getSchemaPartText(error.parentSchema, false, true)}`;
const {
parentSchema
} = error;
if (parentSchema &&
/** @type {Schema} */
parentSchema.enum &&
/** @type {Schema} */
parentSchema.enum.length === 1) {
return `${dataPath} should be ${this.getSchemaPartText(parentSchema, false, true)}`;
}
return `${dataPath} should be one of these:\n${this.getSchemaPartText(error.parentSchema)}`;
return `${dataPath} should be one of these:\n${this.getSchemaPartText(parentSchema)}`;
}
case 'const':
return `${dataPath} should be equal to constant ${this.getSchemaPartText(error.parentSchema)}`;
{
const {
parentSchema
} = error;
return `${dataPath} should be equal to constant ${this.getSchemaPartText(parentSchema)}`;
}
case 'not':
{
const {
schema,
parentSchema
} = error;
return `${dataPath} should not be ${this.getSchemaPartText(schema)}${parentSchema && likeObject(parentSchema) ? `\n${this.getSchemaPartText(parentSchema)}` : ''}`;
}
case 'oneOf':
case 'anyOf':
{
if (error.children && error.children.length > 0) {
const {
parentSchema,
children
} = error;
if (children && children.length > 0) {
if (error.schema.length === 1) {
const lastChild = error.children[error.children.length - 1];
const remainingChildren = error.children.slice(0, error.children.length - 1);
const lastChild = children[children.length - 1];
const remainingChildren = children.slice(0, children.length - 1);
return this.formatValidationError(Object.assign({}, lastChild, {
children: remainingChildren,
parentSchema: Object.assign({}, error.parentSchema, lastChild.parentSchema)
parentSchema: Object.assign({}, parentSchema, lastChild.parentSchema)
}));
}
const children = filterChildren(error.children);
let filteredChildren = filterChildren(children);
if (children.length === 1) {
return this.formatValidationError(children[0]);
if (filteredChildren.length === 1) {
return this.formatValidationError(filteredChildren[0]);
}
return `${dataPath} should be one of these:\n${this.getSchemaPartText(error.parentSchema)}\nDetails:\n${children.map(nestedError => ` * ${indent(this.formatValidationError(nestedError), ' ')}`).join('\n')}`;
filteredChildren = groupChildrenByFirstChild(filteredChildren);
return `${dataPath} should be one of these:\n${this.getSchemaPartText(parentSchema)}\nDetails:\n${filteredChildren.map(
/**
* @param {SchemaUtilErrorObject} nestedError
* @returns {string}
*/
nestedError => ` * ${indent(this.formatValidationError(nestedError), ' ')}`).join('\n')}`;
}
return `${dataPath} should be one of these:\n${this.getSchemaPartText(error.parentSchema)}`;
return `${dataPath} should be one of these:\n${this.getSchemaPartText(parentSchema)}`;
}
case 'if':
return `${dataPath} should match "${error.params.failingKeyword}" schema:\n${this.getSchemaPartText(error.parentSchema, [error.params.failingKeyword])}`;
{
const {
params,
parentSchema
} = error;
const {
failingKeyword
} =
/** @type {import("ajv").IfParams} */
params;
return `${dataPath} should match "${failingKeyword}" schema:\n${this.getSchemaPartText(parentSchema, [failingKeyword])}`;
}
case 'absolutePath':
return `${dataPath}: ${error.message}${this.getSchemaPartDescription(error.parentSchema)}`;
{
const {
message,
parentSchema
} = error;
return `${dataPath}: ${message}${this.getSchemaPartDescription(parentSchema)}`;
}
/* istanbul ignore next */
default:
// For `custom`, `false schema`, `$ref` keywords
// Fallback for unknown keywords
{
const {
message,
parentSchema
} = error;
const ErrorInJSON = JSON.stringify(error, null, 2); // For `custom`, `false schema`, `$ref` keywords
// Fallback for unknown keywords
/* istanbul ignore next */
return `${dataPath} ${error.message} (${JSON.stringify(error, null, 2)}).\n${this.getSchemaPartText(error.parentSchema)}`;
return `${dataPath} ${message} (${ErrorInJSON}).\n${this.getSchemaPartText(parentSchema, false)}`;
}
}
}
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @returns {string}
*/
formatValidationErrors(errors) {
return errors.map(error => {
let formattedError = this.formatValidationError(error, this.schema);
let formattedError = this.formatValidationError(error);

@@ -602,0 +1301,0 @@ if (this.postFormatter) {

{
"name": "@develar/schema-utils",
"version": "2.1.0",
"version": "2.6.5",
"description": "webpack Validation Utils",
"license": "MIT",
"repository": "webpack-contrib/schema-utils",
"repository": "webpack/schema-utils",
"author": "webpack Contrib (https://github.com/webpack-contrib)",
"homepage": "https://github.com/webpack-contrib/schema-utils",
"bugs": "https://github.com/webpack-contrib/schema-utils/issues",
"homepage": "https://github.com/webpack/schema-utils",
"bugs": "https://github.com/webpack/schema-utils/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"main": "dist/index.js",
"types": "declarations/index.d.ts",
"engines": {

@@ -16,49 +21,55 @@ "node": ">= 8.9.0"

"start": "npm run build -- -w",
"clean": "del-cli dist declarations",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production babel src -d dist --ignore \"src/**/*.test.js\" --copy-files",
"clean": "del-cli dist",
"build:types": "tsc --declaration --emitDeclarationOnly --outDir declarations && prettier \"declarations/**/*.ts\" --write",
"build:code": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"build": "npm-run-all -p \"build:**\"",
"commitlint": "commitlint --from=master",
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css}\" --list-different",
"lint:js": "eslint --cache src test",
"security": "npm audit",
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css,ts}\" --list-different",
"lint:js": "eslint --cache .",
"lint:types": "tsc --pretty --noEmit",
"lint": "npm-run-all -l -p \"lint:**\"",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"prepare": "npm run build",
"release": "standard-version",
"security": "npm audit",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "cross-env NODE_ENV=test jest --watch",
"test:coverage": "cross-env NODE_ENV=test jest --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "cross-env NODE_ENV=test npm run test:coverage",
"defaults": "webpack-defaults"
},
"files": [
"dist"
"dist",
"declarations"
],
"dependencies": {
"ajv": "^6.1.0",
"ajv-keywords": "^3.1.0"
"ajv": "^6.12.0",
"ajv-keywords": "^3.4.1"
},
"devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@commitlint/cli": "^8.0.0",
"@commitlint/config-conventional": "^8.0.0",
"@webpack-contrib/defaults": "^5.0.0",
"@babel/cli": "^7.8.3",
"@babel/core": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@types/json-schema": "^7.0.4",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^24.8.0",
"commitlint-azure-pipelines-cli": "^1.0.2",
"cross-env": "^5.2.0",
"del": "^5.0.0",
"del-cli": "^2.0.0",
"eslint": "^6.0.1",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-import": "^2.0.0",
"husky": "^3.0.0",
"jest": "^24.8.0",
"jest-junit": "^6.4.0",
"lint-staged": "^9.2.0",
"babel-jest": "^24.9.0",
"commitlint-azure-pipelines-cli": "^1.0.3",
"cross-env": "^6.0.3",
"del": "^5.1.0",
"del-cli": "^3.0.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.9.0",
"eslint-plugin-import": "^2.20.0",
"husky": "^4.0.10",
"jest": "^24.9.0",
"jest-junit": "^10.0.0",
"lint-staged": "^9.5.0",
"npm-run-all": "^4.1.5",
"prettier": "^1.0.0",
"standard-version": "^6.0.1"
"prettier": "^1.19.1",
"standard-version": "^7.0.1",
"typescript": "^3.7.5"
},

@@ -65,0 +76,0 @@ "keywords": [

@@ -99,2 +99,22 @@ <div align="center">

There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
For example:
```json
{
"title": "My Loader options",
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
The last word used for the `baseDataPath` option, other words used for the `name` option.
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
#### `name`

@@ -153,3 +173,3 @@

```shell
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
- options.optionName should be a integer.

@@ -156,0 +176,0 @@ Additional Information.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc