Comparing version 1.0.16 to 1.0.17
@@ -0,0 +0,0 @@ tv4.addLanguage('de', { |
@@ -0,0 +0,0 @@ /* |
{ | ||
"name": "tv4", | ||
"version": "1.0.16", | ||
"version": "1.0.17", | ||
"author": "Geraint Luff", | ||
@@ -52,3 +52,4 @@ "description": "A public domain JSON Schema validator for JavaScript", | ||
"grunt-push-release": "~0.1.1", | ||
"grunt-regex-replace": "~0.2.5" | ||
"grunt-regex-replace": "~0.2.5", | ||
"requirejs": "~2.1.11" | ||
}, | ||
@@ -55,0 +56,0 @@ "engines": { |
@@ -265,2 +265,38 @@ # Tiny Validator (for v4 JSON Schema) | ||
##### defineKeyword(keyword, validationFunction) | ||
Add a custom keyword validator. | ||
* `keyword` is a string, corresponding to a schema keyword | ||
* `validationFunction` is a function that either returns: | ||
* `null` (meaning no error) | ||
* an error string (explaining the reason for failure) | ||
* an error object (containing some of: `code`/`message`/`dataPath`/`schemaPath`) | ||
```` | ||
tv4.defineKeyword('my-custom-keyword', function (data, value, schema) { | ||
if (simpleFailure()) { | ||
return "Failure"; | ||
} else if (detailedFailure()) { | ||
return {code: tv4.errorCodes.MY_CUSTOM_CODE, message: {param1: 'a', param2: 'b'}}; | ||
} else { | ||
return null; | ||
} | ||
}); | ||
```` | ||
`schema` is the schema upon which the keyword is defined. In the above example, `value === schema['my-custom-keyword']`. | ||
If an object is returned from the custom validator, and its `message` is a string, then that is used as the message result. If `message` is an object, then that is used to populate the (localisable) error template. | ||
##### defineError(codeName, codeNumber, defaultMessage) | ||
Defines a custom error code. | ||
* `codeName` is a string, all-caps underscore separated, e.g. `"MY_CUSTOM_ERROR"` | ||
* `codeNumber` is an integer > 10000, which will be stored in `tv4.errorCodes` (e.g. `tv4.errorCodes.MY_CUSTOM_ERROR`) | ||
* `defaultMessage` is an error message template to use (assuming translations have not been provided for this code) | ||
An example of `defaultMessage` might be: `"Incorrect moon (expected {expected}, got {actual}"`). This is filled out if a custom keyword returns a object `message` (see above). Translations will be used, if associated with the correct code name/number. | ||
## Demos | ||
@@ -350,2 +386,10 @@ | ||
or as an AMD module (e.g. with requirejs): | ||
```js | ||
require('tv4', function(tv4){ | ||
//use tv4 here | ||
}); | ||
``` | ||
#### npm | ||
@@ -352,0 +396,0 @@ |
@@ -0,0 +0,0 @@ // Provides support for asynchronous validation (fetching schemas) using jQuery |
97
tv4.js
@@ -9,4 +9,14 @@ /* | ||
*/ | ||
(function (global) { | ||
'use strict'; | ||
(function (global, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
// AMD. Register as an anonymous module. | ||
define([], factory); | ||
} else if (typeof module !== 'undefined' && module.exports){ | ||
// CommonJS. Define export. | ||
module.exports = factory(); | ||
} else { | ||
// Browser globals | ||
global.tv4 = factory(); | ||
} | ||
}(this, function () { | ||
@@ -146,3 +156,13 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FObject%2Fkeys | ||
this.errorMessages = errorMessages; | ||
this.definedKeywords = {}; | ||
if (parent) { | ||
for (var key in parent.definedKeywords) { | ||
this.definedKeywords[key] = parent.definedKeywords[key].slice(0); | ||
} | ||
} | ||
}; | ||
ValidatorContext.prototype.defineKeyword = function (keyword, keywordFunction) { | ||
this.definedKeywords[keyword] = this.definedKeywords[keyword] || []; | ||
this.definedKeywords[keyword].push(keywordFunction); | ||
}; | ||
ValidatorContext.prototype.createError = function (code, messageParams, dataPath, schemaPath, subErrors) { | ||
@@ -399,2 +419,3 @@ var messageTemplate = this.errorMessages[code] || ErrorMessagesDefault[code]; | ||
|| this.validateFormat(data, schema, dataPointerPath) | ||
|| this.validateDefinedKeywords(data, schema, dataPointerPath) | ||
|| null; | ||
@@ -442,2 +463,26 @@ | ||
}; | ||
ValidatorContext.prototype.validateDefinedKeywords = function (data, schema) { | ||
for (var key in this.definedKeywords) { | ||
var validationFunctions = this.definedKeywords[key]; | ||
for (var i = 0; i < validationFunctions.length; i++) { | ||
var func = validationFunctions[i]; | ||
var result = func(data, schema[key], schema); | ||
if (typeof result === 'string' || typeof result === 'number') { | ||
return this.createError(ErrorCodes.KEYWORD_CUSTOM, {key: key, message: result}).prefixWith(null, "format"); | ||
} else if (result && typeof result === 'object') { | ||
var code = result.code || ErrorCodes.KEYWORD_CUSTOM; | ||
if (typeof code === 'string') { | ||
if (!ErrorCodes[code]) { | ||
throw new Error('Undefined error code (use defineError): ' + code); | ||
} | ||
code = ErrorCodes[code]; | ||
} | ||
var messageParams = (typeof result.message === 'object') ? result.message : {key: key, message: result.message || "?"}; | ||
var schemaPath = result.schemaPath ||( "/" + key.replace(/~/g, '~0').replace(/\//g, '~1')); | ||
return this.createError(code, messageParams, result.dataPath || null, schemaPath); | ||
} | ||
} | ||
} | ||
return null; | ||
}; | ||
@@ -1043,5 +1088,6 @@ function recursiveCompare(A, B) { | ||
} | ||
} else if (typeof schema['$ref'] === "string") { | ||
schema['$ref'] = resolveUrl(baseUri, schema['$ref']); | ||
} else { | ||
if (typeof schema['$ref'] === "string") { | ||
schema['$ref'] = resolveUrl(baseUri, schema['$ref']); | ||
} | ||
for (var key in schema) { | ||
@@ -1084,4 +1130,5 @@ if (key !== "enum") { | ||
ARRAY_ADDITIONAL_ITEMS: 403, | ||
// Format errors | ||
// Custom/user-defined errors | ||
FORMAT_CUSTOM: 500, | ||
KEYWORD_CUSTOM: 501, | ||
// Schema structure | ||
@@ -1092,2 +1139,6 @@ CIRCULAR_REFERENCE: 600, | ||
}; | ||
var ErrorCodeLookup = {}; | ||
for (var key in ErrorCodes) { | ||
ErrorCodeLookup[ErrorCodes[key]] = key; | ||
} | ||
var ErrorMessagesDefault = { | ||
@@ -1123,2 +1174,3 @@ INVALID_TYPE: "invalid type: {type} (expected {expected})", | ||
FORMAT_CUSTOM: "Format validation failed ({message})", | ||
KEYWORD_CUSTOM: "Keyword failed: {key} ({message})", | ||
// Schema structure | ||
@@ -1289,2 +1341,28 @@ CIRCULAR_REFERENCE: "Circular $refs: {urls}", | ||
}, | ||
defineKeyword: function () { | ||
globalContext.defineKeyword.apply(globalContext, arguments); | ||
}, | ||
defineError: function (codeName, codeNumber, defaultMessage) { | ||
if (typeof codeName !== 'string' || !/^[A-Z]+(_[A-Z]+)*$/.test(codeName)) { | ||
throw new Error('Code name must be a string in UPPER_CASE_WITH_UNDERSCORES'); | ||
} | ||
if (typeof codeNumber !== 'number' || codeNumber%1 !== 0 || codeNumber < 10000) { | ||
throw new Error('Code number must be an integer > 10000'); | ||
} | ||
if (typeof ErrorCodes[codeName] !== 'undefined') { | ||
throw new Error('Error already defined: ' + codeName + ' as ' + ErrorCodes[codeName]); | ||
} | ||
if (typeof ErrorCodeLookup[codeNumber] !== 'undefined') { | ||
throw new Error('Error code already used: ' + ErrorCodeLookup[codeNumber] + ' as ' + codeNumber); | ||
} | ||
ErrorCodes[codeName] = codeNumber; | ||
ErrorCodeLookup[codeNumber] = codeName; | ||
ErrorMessagesDefault[codeName] = ErrorMessagesDefault[codeNumber] = defaultMessage; | ||
for (var langCode in languages) { | ||
var language = languages[langCode]; | ||
if (language[codeName]) { | ||
language[codeNumber] = language[codeNumber] || language[codeName]; | ||
} | ||
} | ||
}, | ||
reset: function () { | ||
@@ -1313,9 +1391,4 @@ globalContext.reset(); | ||
if (typeof module !== 'undefined' && module.exports){ | ||
module.exports = tv4; | ||
} | ||
else { | ||
global.tv4 = tv4; | ||
} | ||
return tv4; // used by _header.js to globalise. | ||
})(this); | ||
})); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
66144
1377
447
19