Completely updated React, fixed #11, (hopefully)

This commit is contained in:
2018-03-04 19:11:49 -05:00
parent 6e0afd6e2a
commit 34e5f5139a
13674 changed files with 333464 additions and 473223 deletions

View File

@@ -3,7 +3,7 @@ declare var ajv: {
new (options?: ajv.Options): ajv.Ajv;
ValidationError: ValidationError;
MissingRefError: MissingRefError;
$dataMetaSchema: Object;
$dataMetaSchema: object;
}
declare namespace ajv {
@@ -11,49 +11,51 @@ declare namespace ajv {
/**
* Validate data using schema
* Schema will be compiled and cached (using serialized JSON as key, [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used to serialize by default).
* @param {String|Object|Boolean} schemaKeyRef key, ref or schema object
* @param {string|object|Boolean} schemaKeyRef key, ref or schema object
* @param {Any} data to be validated
* @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`).
*/
validate(schemaKeyRef: Object | string | boolean, data: any): boolean | Thenable<any>;
validate(schemaKeyRef: object | string | boolean, data: any): boolean | Thenable<any>;
/**
* Create validating function for passed schema.
* @param {Object|Boolean} schema schema object
* @param {object|Boolean} schema schema object
* @return {Function} validating function
*/
compile(schema: Object | boolean): ValidateFunction;
compile(schema: object | boolean): ValidateFunction;
/**
* Creates validating function for passed schema with asynchronous loading of missing schemas.
* `loadSchema` option should be a function that accepts schema uri and node-style callback.
* @this Ajv
* @param {Object|Boolean} schema schema object
* @param {object|Boolean} schema schema object
* @param {Boolean} meta optional true to compile meta-schema; this parameter can be skipped
* @param {Function} callback optional node-style callback, it is always called with 2 parameters: error (or null) and validating function.
* @return {Thenable<ValidateFunction>} validating function
*/
compileAsync(schema: Object | boolean, meta?: Boolean, callback?: (err: Error, validate: ValidateFunction) => any): Thenable<ValidateFunction>;
compileAsync(schema: object | boolean, meta?: Boolean, callback?: (err: Error, validate: ValidateFunction) => any): Thenable<ValidateFunction>;
/**
* Adds schema to the instance.
* @param {Object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored.
* @param {String} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`.
* @param {object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored.
* @param {string} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`.
* @return {Ajv} this for method chaining
*/
addSchema(schema: Array<Object> | Object, key?: string): void;
addSchema(schema: Array<object> | object, key?: string): Ajv;
/**
* Add schema that will be used to validate other schemas
* options in META_IGNORE_OPTIONS are alway set to false
* @param {Object} schema schema object
* @param {String} key optional schema key
* @param {object} schema schema object
* @param {string} key optional schema key
* @return {Ajv} this for method chaining
*/
addMetaSchema(schema: Object, key?: string): void;
addMetaSchema(schema: object, key?: string): Ajv;
/**
* Validate schema
* @param {Object|Boolean} schema schema to validate
* @param {object|Boolean} schema schema to validate
* @return {Boolean} true if schema is valid
*/
validateSchema(schema: Object | boolean): boolean;
validateSchema(schema: object | boolean): boolean;
/**
* Get compiled schema from the instance by `key` or `ref`.
* @param {String} keyRef `key` that was passed to `addSchema` or full schema reference (`schema.id` or resolved id).
* @param {string} keyRef `key` that was passed to `addSchema` or full schema reference (`schema.id` or resolved id).
* @return {Function} schema validating function (with property `schema`).
*/
getSchema(keyRef: string): ValidateFunction;
@@ -62,40 +64,44 @@ declare namespace ajv {
* If no parameter is passed all schemas but meta-schemas are removed.
* If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
* Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
* @param {String|Object|RegExp|Boolean} schemaKeyRef key, ref, pattern to match key/ref or schema object
* @param {string|object|RegExp|Boolean} schemaKeyRef key, ref, pattern to match key/ref or schema object
* @return {Ajv} this for method chaining
*/
removeSchema(schemaKeyRef?: Object | string | RegExp | boolean): void;
removeSchema(schemaKeyRef?: object | string | RegExp | boolean): Ajv;
/**
* Add custom format
* @param {String} name format name
* @param {String|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
* @param {string} name format name
* @param {string|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
* @return {Ajv} this for method chaining
*/
addFormat(name: string, format: FormatValidator | FormatDefinition): void;
addFormat(name: string, format: FormatValidator | FormatDefinition): Ajv;
/**
* Define custom keyword
* @this Ajv
* @param {String} keyword custom keyword, should be a valid identifier, should be different from all standard, custom and macro keywords.
* @param {Object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`.
* @param {string} keyword custom keyword, should be a valid identifier, should be different from all standard, custom and macro keywords.
* @param {object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`.
* @return {Ajv} this for method chaining
*/
addKeyword(keyword: string, definition: KeywordDefinition): void;
addKeyword(keyword: string, definition: KeywordDefinition): Ajv;
/**
* Get keyword definition
* @this Ajv
* @param {String} keyword pre-defined or custom keyword.
* @return {Object|Boolean} custom keyword definition, `true` if it is a predefined keyword, `false` otherwise.
* @param {string} keyword pre-defined or custom keyword.
* @return {object|Boolean} custom keyword definition, `true` if it is a predefined keyword, `false` otherwise.
*/
getKeyword(keyword: string): Object | boolean;
getKeyword(keyword: string): object | boolean;
/**
* Remove keyword
* @this Ajv
* @param {String} keyword pre-defined or custom keyword.
* @param {string} keyword pre-defined or custom keyword.
* @return {Ajv} this for method chaining
*/
removeKeyword(keyword: string): void;
removeKeyword(keyword: string): Ajv;
/**
* Convert array of error message objects to string
* @param {Array<Object>} errors optional array of validation errors, if not passed errors from the instance are used.
* @param {Object} options optional options with properties `separator` and `dataVar`.
* @return {String} human readable string with all errors descriptions
* @param {Array<object>} errors optional array of validation errors, if not passed errors from the instance are used.
* @param {object} options optional options with properties `separator` and `dataVar`.
* @return {string} human readable string with all errors descriptions
*/
errorsText(errors?: Array<ErrorObject>, options?: ErrorsTextOptions): string;
errors?: Array<ErrorObject>;
@@ -109,17 +115,17 @@ declare namespace ajv {
(
data: any,
dataPath?: string,
parentData?: Object | Array<any>,
parentData?: object | Array<any>,
parentDataProperty?: string | number,
rootData?: Object | Array<any>
rootData?: object | Array<any>
): boolean | Thenable<any>;
schema?: Object | boolean;
schema?: object | boolean;
errors?: null | Array<ErrorObject>;
refs?: Object;
refs?: object;
refVal?: Array<any>;
root?: ValidateFunction | Object;
root?: ValidateFunction | object;
$async?: true;
source?: Object;
source?: object;
}
interface Options {
@@ -130,19 +136,19 @@ declare namespace ajv {
uniqueItems?: boolean;
unicode?: boolean;
format?: string;
formats?: Object;
formats?: object;
unknownFormats?: true | string[] | 'ignore';
schemas?: Array<Object> | Object;
schemas?: Array<object> | object;
schemaId?: '$id' | 'id';
missingRefs?: true | 'ignore' | 'fail';
extendRefs?: true | 'ignore' | 'fail';
loadSchema?: (uri: string, cb?: (err: Error, schema: Object) => void) => Thenable<Object | boolean>;
loadSchema?: (uri: string, cb?: (err: Error, schema: object) => void) => Thenable<object | boolean>;
removeAdditional?: boolean | 'all' | 'failing';
useDefaults?: boolean | 'shared';
coerceTypes?: boolean | 'array';
async?: boolean | string;
transpile?: string | ((code: string) => string);
meta?: boolean | Object;
meta?: boolean | object;
validateSchema?: boolean | 'log';
addUsedSchema?: boolean;
inlineRefs?: boolean | number;
@@ -154,7 +160,7 @@ declare namespace ajv {
messages?: boolean;
sourceCode?: boolean;
processCode?: (code: string) => string;
cache?: Object;
cache?: object;
}
type FormatValidator = string | RegExp | ((data: string) => boolean | Thenable<any>);
@@ -170,27 +176,57 @@ declare namespace ajv {
async?: boolean;
$data?: boolean;
errors?: boolean | string;
metaSchema?: Object;
metaSchema?: object;
// schema: false makes validate not to expect schema (ValidateFunction)
schema?: boolean;
modifying?: boolean;
valid?: boolean;
// one and only one of the following properties should be present
validate?: SchemaValidateFunction | ValidateFunction;
compile?: (schema: any, parentSchema: Object) => ValidateFunction;
macro?: (schema: any, parentSchema: Object) => Object | boolean;
inline?: (it: Object, keyword: string, schema: any, parentSchema: Object) => string;
compile?: (schema: any, parentSchema: object, it: CompilationContext) => ValidateFunction;
macro?: (schema: any, parentSchema: object, it: CompilationContext) => object | boolean;
inline?: (it: CompilationContext, keyword: string, schema: any, parentSchema: object) => string;
}
interface CompilationContext {
level: number;
dataLevel: number;
schema: any;
schemaPath: string;
baseId: string;
async: boolean;
opts: Options;
formats: {
[index: string]: FormatDefinition | undefined;
};
compositeRule: boolean;
validate: (schema: object) => boolean;
util: {
copy(obj: any, target?: any): any;
toHash(source: string[]): { [index: string]: true | undefined };
equal(obj: any, target: any): boolean;
getProperty(str: string): string;
schemaHasRules(schema: object, rules: any): string;
escapeQuotes(str: string): string;
toQuotedString(str: string): string;
getData(jsonPointer: string, dataLevel: number, paths: string[]): string;
escapeJsonPointer(str: string): string;
unescapeJsonPointer(str: string): string;
escapeFragment(str: string): string;
unescapeFragment(str: string): string;
};
self: Ajv;
}
interface SchemaValidateFunction {
(
schema: any,
data: any,
parentSchema?: Object,
parentSchema?: object,
dataPath?: string,
parentData?: Object | Array<any>,
parentData?: object | Array<any>,
parentDataProperty?: string | number,
rootData?: Object | Array<any>
rootData?: object | Array<any>
): boolean | Thenable<any>;
errors?: Array<ErrorObject>;
}
@@ -211,7 +247,7 @@ declare namespace ajv {
message?: string;
// These are added with the `verbose` option.
schema?: any;
parentSchema?: Object;
parentSchema?: object;
data?: any;
}

View File

@@ -52,6 +52,7 @@ var META_SUPPORT_DATA = ['/properties'];
function Ajv(opts) {
if (!(this instanceof Ajv)) return new Ajv(opts);
opts = this._opts = util.copy(opts) || {};
setLogger(this);
this._schemas = {};
this._refs = {};
this._fragments = {};
@@ -125,11 +126,12 @@ function compile(schema, _meta) {
* @param {String} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`.
* @param {Boolean} _skipValidation true to skip schema validation. Used internally, option validateSchema should be used instead.
* @param {Boolean} _meta true if schema is a meta-schema. Used internally, addMetaSchema should be used instead.
* @return {Ajv} this for method chaining
*/
function addSchema(schema, key, _skipValidation, _meta) {
if (Array.isArray(schema)){
for (var i=0; i<schema.length; i++) this.addSchema(schema[i], undefined, _skipValidation, _meta);
return;
return this;
}
var id = this._getId(schema);
if (id !== undefined && typeof id != 'string')
@@ -137,6 +139,7 @@ function addSchema(schema, key, _skipValidation, _meta) {
key = resolve.normalizeId(key || id);
checkUnique(this, key);
this._schemas[key] = this._addSchema(schema, _skipValidation, _meta, true);
return this;
}
@@ -147,9 +150,11 @@ function addSchema(schema, key, _skipValidation, _meta) {
* @param {Object} schema schema object
* @param {String} key optional schema key
* @param {Boolean} skipValidation true to skip schema validation, can be used to override validateSchema option for meta-schema
* @return {Ajv} this for method chaining
*/
function addMetaSchema(schema, key, skipValidation) {
this.addSchema(schema, key, skipValidation, true);
return this;
}
@@ -166,7 +171,7 @@ function validateSchema(schema, throwOrLogError) {
throw new Error('$schema must be a string');
$schema = $schema || this._opts.defaultMeta || defaultMeta(this);
if (!$schema) {
console.warn('meta-schema not available');
this.logger.warn('meta-schema not available');
this.errors = null;
return true;
}
@@ -179,7 +184,7 @@ function validateSchema(schema, throwOrLogError) {
finally { this._formats.uri = currentUriFormat; }
if (!valid && throwOrLogError) {
var message = 'schema is invalid: ' + this.errorsText();
if (this._opts.validateSchema == 'log') console.error(message);
if (this._opts.validateSchema == 'log') this.logger.error(message);
else throw new Error(message);
}
return valid;
@@ -246,25 +251,26 @@ function _getSchemaObj(self, keyRef) {
* Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
* @this Ajv
* @param {String|Object|RegExp} schemaKeyRef key, ref, pattern to match key/ref or schema object
* @return {Ajv} this for method chaining
*/
function removeSchema(schemaKeyRef) {
if (schemaKeyRef instanceof RegExp) {
_removeAllSchemas(this, this._schemas, schemaKeyRef);
_removeAllSchemas(this, this._refs, schemaKeyRef);
return;
return this;
}
switch (typeof schemaKeyRef) {
case 'undefined':
_removeAllSchemas(this, this._schemas);
_removeAllSchemas(this, this._refs);
this._cache.clear();
return;
return this;
case 'string':
var schemaObj = _getSchemaObj(this, schemaKeyRef);
if (schemaObj) this._cache.del(schemaObj.cacheKey);
delete this._schemas[schemaKeyRef];
delete this._refs[schemaKeyRef];
return;
return this;
case 'object':
var serialize = this._opts.serialize;
var cacheKey = serialize ? serialize(schemaKeyRef) : schemaKeyRef;
@@ -276,6 +282,7 @@ function removeSchema(schemaKeyRef) {
delete this._refs[id];
}
}
return this;
}
@@ -378,15 +385,15 @@ function chooseGetId(opts) {
}
}
/* @this Ajv */
function _getId(schema) {
if (schema.$id) console.warn('schema $id ignored', schema.$id);
if (schema.$id) this.logger.warn('schema $id ignored', schema.$id);
return schema.id;
}
/* @this Ajv */
function _get$Id(schema) {
if (schema.id) console.warn('schema id ignored', schema.id);
if (schema.id) this.logger.warn('schema id ignored', schema.id);
return schema.$id;
}
@@ -426,10 +433,12 @@ function errorsText(errors, options) {
* @this Ajv
* @param {String} name format name
* @param {String|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
* @return {Ajv} this for method chaining
*/
function addFormat(name, format) {
if (typeof format == 'string') format = new RegExp(format);
this._formats[name] = format;
return this;
}
@@ -475,3 +484,19 @@ function getMetaSchemaOptions(self) {
delete metaOpts[META_IGNORE_OPTIONS[i]];
return metaOpts;
}
function setLogger(self) {
var logger = self._opts.logger;
if (logger === false) {
self.logger = {log: noop, warn: noop, error: noop};
} else {
if (logger === undefined) logger = console;
if (!(typeof logger == 'object' && logger.log && logger.warn && logger.error))
throw new Error('logger must implement log, warn and error methods');
self.logger = logger;
}
}
function noop() {}

View File

@@ -104,6 +104,7 @@ function compile(schema, root, localRefs, baseId) {
useCustomRule: useCustomRule,
opts: opts,
formats: formats,
logger: self.logger,
self: self
});
@@ -146,7 +147,7 @@ function compile(schema, root, localRefs, baseId) {
refVal[0] = validate;
} catch(e) {
console.error('Error compiling schema, function code:', sourceCode);
self.logger.error('Error compiling schema, function code:', sourceCode);
throw e;
}
@@ -260,7 +261,7 @@ function compile(schema, root, localRefs, baseId) {
var valid = validateSchema(schema);
if (!valid) {
var message = 'keyword schema is invalid: ' + self.errorsText(validateSchema.errors);
if (self._opts.validateSchema == 'log') console.error(message);
if (self._opts.validateSchema == 'log') self.logger.error(message);
else throw new Error(message);
}
}

View File

@@ -20,7 +20,7 @@ module.exports = function rules() {
var ALL = [ 'type' ];
var KEYWORDS = [
'additionalItems', '$schema', 'id', 'title',
'additionalItems', '$schema', '$id', 'id', 'title',
'description', 'default', 'definitions'
];
var TYPES = [ 'number', 'integer', 'string', 'array', 'object', 'boolean', 'null' ];

View File

@@ -71,7 +71,7 @@
{{ var $format = it.formats[$schema]; }}
{{? !$format }}
{{? $unknownFormats == 'ignore' }}
{{ console.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"'); }}
{{ it.logger.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"'); }}
{{# def.skipFormat }}
{{?? $allowUnknown && $unknownFormats.indexOf($schema) >= 0 }}
{{# def.skipFormat }}

View File

@@ -27,11 +27,11 @@
{{? $refVal === undefined }}
{{ var $message = it.MissingRefError.message(it.baseId, $schema); }}
{{? it.opts.missingRefs == 'fail' }}
{{ console.error($message); }}
{{ it.logger.error($message); }}
{{# def.error:'$ref' }}
{{? $breakOnError }} if (false) { {{?}}
{{?? it.opts.missingRefs == 'ignore' }}
{{ console.warn($message); }}
{{ it.logger.warn($message); }}
{{? $breakOnError }} if (true) { {{?}}
{{??}}
{{ throw new it.MissingRefError(it.baseId, $schema, $message); }}

View File

@@ -140,7 +140,7 @@
{{?? it.opts.extendRefs !== true }}
{{
$refKeywords = false;
console.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"');
it.logger.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"');
}}
{{?}}
{{?}}
@@ -177,7 +177,7 @@
{{?}}
{{??}}
{{? it.opts.v5 && it.schema.patternGroups }}
{{ console.warn('keyword "patternGroups" is deprecated and disabled. Use option patternGroups: true to enable.'); }}
{{ it.logger.warn('keyword "patternGroups" is deprecated and disabled. Use option patternGroups: true to enable.'); }}
{{?}}
{{~ it.RULES:$rulesGroup }}
{{? $shouldUseGroup($rulesGroup) }}
@@ -260,10 +260,10 @@
function $shouldUseRule($rule) {
return it.schema[$rule.keyword] !== undefined ||
($rule.implements && $ruleImlementsSomeKeyword($rule));
($rule.implements && $ruleImplementsSomeKeyword($rule));
}
function $ruleImlementsSomeKeyword($rule) {
function $ruleImplementsSomeKeyword($rule) {
var impl = $rule.implements;
for (var i=0; i < impl.length; i++)
if (it.schema[impl[i]] !== undefined)

View File

@@ -55,7 +55,7 @@ module.exports = function generate_format(it, $keyword, $ruleType) {
var $format = it.formats[$schema];
if (!$format) {
if ($unknownFormats == 'ignore') {
console.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"');
it.logger.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"');
if ($breakOnError) {
out += ' if (true) { ';
}

View File

@@ -22,7 +22,7 @@ module.exports = function generate_ref(it, $keyword, $ruleType) {
if ($refVal === undefined) {
var $message = it.MissingRefError.message(it.baseId, $schema);
if (it.opts.missingRefs == 'fail') {
console.error($message);
it.logger.error($message);
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
@@ -53,7 +53,7 @@ module.exports = function generate_ref(it, $keyword, $ruleType) {
out += ' if (false) { ';
}
} else if (it.opts.missingRefs == 'ignore') {
console.warn($message);
it.logger.warn($message);
if ($breakOnError) {
out += ' if (true) { ';
}

View File

@@ -123,7 +123,7 @@ module.exports = function generate_validate(it, $keyword, $ruleType) {
throw new Error('$ref: validation keywords used in schema at path "' + it.errSchemaPath + '" (see option extendRefs)');
} else if (it.opts.extendRefs !== true) {
$refKeywords = false;
console.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"');
it.logger.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"');
}
}
if ($typeSchema) {
@@ -281,7 +281,7 @@ module.exports = function generate_validate(it, $keyword, $ruleType) {
}
} else {
if (it.opts.v5 && it.schema.patternGroups) {
console.warn('keyword "patternGroups" is deprecated and disabled. Use option patternGroups: true to enable.');
it.logger.warn('keyword "patternGroups" is deprecated and disabled. Use option patternGroups: true to enable.');
}
var arr2 = it.RULES;
if (arr2) {
@@ -446,10 +446,10 @@ module.exports = function generate_validate(it, $keyword, $ruleType) {
}
function $shouldUseRule($rule) {
return it.schema[$rule.keyword] !== undefined || ($rule.implements && $ruleImlementsSomeKeyword($rule));
return it.schema[$rule.keyword] !== undefined || ($rule.implements && $ruleImplementsSomeKeyword($rule));
}
function $ruleImlementsSomeKeyword($rule) {
function $ruleImplementsSomeKeyword($rule) {
var impl = $rule.implements;
for (var i = 0; i < impl.length; i++)
if (it.schema[impl[i]] !== undefined) return true;

View File

@@ -14,6 +14,7 @@ module.exports = {
* @this Ajv
* @param {String} keyword custom keyword, should be unique (including different from all standard, custom and macro keywords).
* @param {Object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`.
* @return {Ajv} this for method chaining
*/
function addKeyword(keyword, definition) {
/* jshint validthis: true */
@@ -91,6 +92,8 @@ function addKeyword(keyword, definition) {
function checkDataType(dataType) {
if (!RULES.types[dataType]) throw new Error('Unknown type ' + dataType);
}
return this;
}
@@ -111,6 +114,7 @@ function getKeyword(keyword) {
* Remove keyword
* @this Ajv
* @param {String} keyword pre-defined or custom keyword.
* @return {Ajv} this for method chaining
*/
function removeKeyword(keyword) {
/* jshint validthis: true */
@@ -127,4 +131,5 @@ function removeKeyword(keyword) {
}
}
}
return this;
}

View File

@@ -57,6 +57,10 @@
"type": "string"
},
"default": {},
"examples": {
"type": "array",
"items": {}
},
"multipleOf": {
"type": "number",
"exclusiveMinimum": 0