UNPKG

thingy-schema-validate

Version:

JSON schema validation for the thingy ecosystem - more simple than othr JSON schemas.

1,340 lines (1,161 loc) 31.6 kB
// Generated by CoffeeScript 2.7.0 //########################################################### // log = console.log // olog = (arg) -> console.log(JSON.stringify(arg, null, 4)) //########################################################### //region Basic Schema Type Enumeration //########################################################### //# Notice: NUMBER validation // Due to JSON limitations NaN and (-)Infinity are invalid // This means that NUMBER type already excludes these values // Previously we had FINITENUMBER and NONANNUMBER // These types are gone now :-) var ErrorToMessage, createArrayValidator, createObjectValidator, createStaticStringValidator, createThrower, dirtyCharMap, dirtyChars, domainCharMap, domainChars, getTypeValidator, getTypeValidatorsForArray, getValidatorEntriesForObject, hexChars, hexMap, i, invalidEmailSmallRegex, isDirtyObject, locked, numericOnlyRegex, staticValidatorOrThrow, typeArraySize, typeValidatorFunctions; export var BOOLEAN = 1; export var NUMBER = 2; export var ARRAY = 3; export var OBJECT = 4; export var STRING = 5; export var STRINGEMAIL = 6; export var STRINGHEX = 7; export var STRINGHEX32 = 8; export var STRINGHEX64 = 9; export var STRINGHEX128 = 10; export var STRINGHEX256 = 11; export var STRINGHEX512 = 12; export var STRINGCLEAN = 13; export var NONEMPTYSTRING = 14; export var NONEMPTYSTRINGHEX = 15; export var NONEMPTYSTRINGCLEAN = 16; export var NONEMPTYARRAY = 17; export var OBJECTCLEAN = 18; export var NONNULLOBJECT = 19; export var NONNULLOBJECTCLEAN = 20; export var STRINGORNOTHING = 21; export var STRINGEMAILORNOTHING = 22; export var STRINGHEXORNOTHING = 23; export var STRINGHEX32ORNOTHING = 24; export var STRINGHEX64ORNOTHING = 25; export var STRINGHEX128ORNOTHING = 26; export var STRINGHEX256ORNOTHING = 27; export var STRINGHEX512ORNOTHING = 28; export var STRINGCLEANORNOTHING = 29; export var NUMBERORNOTHING = 30; export var BOOLEANORNOTHING = 31; export var ARRAYORNOTHING = 32; export var OBJECTORNOTHING = 33; export var OBJECTCLEANORNOTHING = 34; export var STRINGORNULL = 35; export var STRINGEMAILORNULL = 36; export var STRINGHEXORNULL = 37; export var STRINGHEX32ORNULL = 38; export var STRINGHEX64ORNULL = 39; export var STRINGHEX128ORNULL = 40; export var STRINGHEX256ORNULL = 41; export var STRINGHEX512ORNULL = 42; export var STRINGCLEANORNULL = 43; export var NUMBERORNULL = 44; export var BOOLEANORNULL = 45; export var ARRAYORNULL = 46; typeArraySize = 47; //endregion //########################################################### //region Local Variables staticValidatorOrThrow = null; locked = false; //########################################################### numericOnlyRegex = /^\d+$/; invalidEmailSmallRegex = /(\.\.|--|-\.)|\.-/; //########################################################### hexChars = "0123456789abcdefABCDEF"; hexMap = new Array(103); i = 0; while (i < hexChars.length) { hexMap[hexChars.charCodeAt(i)] = true; i++; } // Object.freeze(hexMap) # creates minor performance penalty //########################################################### domainChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."; domainCharMap = new Array(123); i = 0; while (i < domainChars.length) { domainCharMap[domainChars.charCodeAt(i)] = true; i++; } // Object.freeze(domainCharMap) # creates minor performance penalty //########################################################### // \t = \x09 Horizontal Tab -> not dirty :-) // \n = \x0A Line Feed -> not dirty :-) // PAD = \x80 Padding Character -> not dirty :-) // NEL = \x85 Next Line -> not dirty :-) dirtyChars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + "\x7F" + "\x81\x82\x83\x84\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F" + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"; // C0 controls //C1 controls // all chars > \u02ff will be cut off manually dirtyCharMap = new Array(160); i = 0; while (i < dirtyChars.length) { dirtyCharMap[dirtyChars.charCodeAt(i)] = true; i++; } // Object.freeze(dirtyCharMap) # creates minor performance penalty //endregion //########################################################### //region Local Functions //########################################################### isDirtyObject = function(obj) { var j, k, keys, len; if (obj === null) { return; } //# as the inputs come from an object which was originalled paref from a JSON string we assume to not fall into an infinite loop keys = Object.keys(obj); for (j = 0, len = keys.length; j < len; j++) { k = keys[j]; if (k === "__proto__" || k === "constructor" || k === "prototype") { return true; } if (typeof obj[k] === "object") { if (isDirtyObject(obj[k])) { return true; } } } return false; }; //########################################################### createStaticStringValidator = function(str) { return function(arg) { if (arg !== str) { return ISINVALID; } }; }; createThrower = function(msg) { return function() { throw new Error(msg); }; }; //########################################################### //region Validator Creation Helpers getTypeValidator = function(type) { var fun; fun = typeValidatorFunctions[type]; if (fun == null) { throw new Error(`Unrecognized Schematype! (${type})`); } return fun; }; //########################################################### getTypeValidatorsForArray = function(arr) { var el, funcs, j, len; funcs = new Array(arr.length); for (i = j = 0, len = arr.length; j < len; i = ++j) { el = arr[i]; switch (false) { case typeof el !== "number": funcs[i] = getTypeValidator(el); break; case typeof el !== "string": funcs[i] = staticValidatorOrThrow(el); break; case typeof el === "object": throw new Error(`Illegal ${typeof el}!`); case !Array.isArray(el): funcs[i] = createArrayValidator(el); break; default: funcs[i] = createObjectValidator(el); } } return funcs; }; getValidatorEntriesForObject = function(obj) { var entries, j, k, keys, len, prop; keys = Object.keys(obj); entries = []; for (i = j = 0, len = keys.length; j < len; i = ++j) { k = keys[i]; prop = obj[k]; if (typeof prop === "number") { entries.push([k, getTypeValidator(prop)]); continue; } if (typeof prop === "string") { entries.push([k, staticValidatorOrThrow(prop)]); continue; } if (typeof prop !== "object") { throw new Error(`Illegal ${typeof prop}!`); } if (Array.isArray(prop)) { entries.push([k, createArrayValidator(prop)]); } else { entries.push([k, createObjectValidator(prop)]); } } return entries; }; //########################################################### createArrayValidator = function(arr) { var func, funcs; if (arr.length === 0) { throw new Error("[] is illegal!"); } funcs = getTypeValidatorsForArray(arr); // olog valEntries func = function(arg) { var el, err, f, hits, j, len; if (!Array.isArray(arg)) { return ISINVALID; } hits = 0; for (i = j = 0, len = funcs.length; j < len; i = ++j) { f = funcs[i]; el = arg[i]; if (!(el === void 0)) { hits++; } err = f(el); if (err) { return err; } } if (arg.length > hits) { return ISINVALID; } }; return func; }; createObjectValidator = function(obj) { var func, valEntries; // Obj is Schema Obj like obj = { prop1:STRING, prop2:NUMBER,... } if (obj === null) { throw new Error("null is illegal!"); } valEntries = getValidatorEntriesForObject(obj); // olog valEntries if (valEntries.length === 0) { throw new Error("{} is illegal!"); } func = function(arg) { var e, err, hits, j, keys, len, prop; // log "validating Object!" // olog arg // log "valEntries.length: #{valEntries.length}" if (typeof arg !== "object") { return ISINVALID; } if (arg === null) { return ISINVALID; } hits = 0; for (j = 0, len = valEntries.length; j < len; j++) { e = valEntries[j]; // olog e prop = arg[e[0]]; if (!(prop === void 0)) { hits++; } err = e[1](prop); if (err) { return err; } } keys = Object.keys(arg); // log "arg keys Length: #{keys.length} -> hits: #{hits}" if (keys.length > hits) { return ISINVALID; } }; // log "is valid!" return func; }; //endregion //endregion //########################################################### //region Type Validator Functions typeValidatorFunctions = new Array(typeArraySize); //########################################################### //region Validator Functions For Basic Schema Types typeValidatorFunctions[STRING] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } }; typeValidatorFunctions[STRINGEMAIL] = function(arg) { var atPos, c, dotPos, j, lastPos, len, tld; if (typeof arg !== "string") { return NOTASTRING; } if (arg.length > 320 || arg.length < 5) { return INVALIDSIZE; } if (invalidEmailSmallRegex.test(arg)) { return INVALIDEMAIL; } // if arg.indexOf("..") >= 0 then return INVALIDEMAIL // if arg.indexOf("--") >= 0 then return INVALIDEMAIL // if arg.indexOf("-.") >= 0 then return INVALIDEMAIL // if arg.indexOf(".-") >= 0 then return INVALIDEMAIL atPos = arg.indexOf("@"); if (atPos <= 0 || atPos > 64 || (arg.length - atPos) < 4 || arg[0] === "." || arg[atPos - 1] === "." || arg[0] === "-" || arg[atPos - 1] === "-" || arg[atPos + 1] === "." || arg[atPos + 1] === "-") { return INVALIDEMAIL; } // if atPos <= 0 then return INVALIDEMAIL // if atPos > 64 then return INVALIDEMAIL // if arg[0] == "." or arg[atPos - 1] == "." then return INVALIDEMAIL // if arg[0] == "-" or arg[atPos - 1] == "-" then return INVALIDEMAIL // if arg[atPos + 1] == "." or arg[atPos + 1] == "-" then return INVALIDEMAIL for (i = j = 0, len = arg.length; j < len; i = ++j) { c = arg[i]; if (!(domainCharMap[arg.charCodeAt(i)] || i === atPos || (i < atPos && (c === "+" || c === "_")))) { return INVALIDEMAIL; } } if (arg[arg.length - 1] === "." || arg[arg.length - 1] === "-") { return INVALIDEMAIL; } lastPos = atPos; dotPos = arg.indexOf(".", atPos + 1); if (dotPos < 0) { return INVALIDEMAIL; } while (dotPos > 0) { if ((dotPos - lastPos) > 63) { return INVALIDEMAIL; } lastPos = dotPos; dotPos = arg.indexOf(".", lastPos + 1); } tld = arg.slice(lastPos + 1); if (numericOnlyRegex.test(tld)) { return INVALIDEMAIL; } }; typeValidatorFunctions[STRINGHEX] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX32] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 32) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX64] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 64) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX128] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 128) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX256] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 256) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX512] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 512) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[NUMBER] = function(arg) { if (typeof arg !== "number") { return NOTANUMBER; } if (isNaN(arg)) { return ISNAN; } if (arg === 2e308 || arg === -2e308) { return ISNOTFINITE; } }; typeValidatorFunctions[BOOLEAN] = function(arg) { if (typeof arg !== "boolean") { return NOTABOOLEAN; } }; typeValidatorFunctions[ARRAY] = function(arg) { if (!Array.isArray(arg)) { return NOTANARRAY; } }; typeValidatorFunctions[OBJECT] = function(arg) { if (typeof arg !== "object") { return NOTANOBJECT; } }; typeValidatorFunctions[STRINGORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } }; typeValidatorFunctions[STRINGEMAILORNOTHING] = function(arg) { var atPos, c, dotPos, j, lastPos, len, tld; if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length > 320 || arg.length < 5) { return INVALIDSIZE; } if (invalidEmailSmallRegex.test(arg)) { return INVALIDEMAIL; } // if arg.indexOf("..") >= 0 then return INVALIDEMAIL // if arg.indexOf("--") >= 0 then return INVALIDEMAIL // if arg.indexOf("-.") >= 0 then return INVALIDEMAIL // if arg.indexOf(".-") >= 0 then return INVALIDEMAIL atPos = arg.indexOf("@"); if (atPos <= 0 || atPos > 64 || (arg.length - atPos) < 4 || arg[0] === "." || arg[atPos - 1] === "." || arg[0] === "-" || arg[atPos - 1] === "-" || arg[atPos + 1] === "." || arg[atPos + 1] === "-") { return INVALIDEMAIL; } // if atPos <= 0 then return INVALIDEMAIL // if atPos > 64 then return INVALIDEMAIL // if arg[0] == "." or arg[atPos - 1] == "." then return INVALIDEMAIL // if arg[0] == "-" or arg[atPos - 1] == "-" then return INVALIDEMAIL // if arg[atPos + 1] == "." or arg[atPos + 1] == "-" then return INVALIDEMAIL for (i = j = 0, len = arg.length; j < len; i = ++j) { c = arg[i]; if (!(domainCharMap[arg.charCodeAt(i)] || i === atPos || (i < atPos && (c === "+" || c === "_")))) { return INVALIDEMAIL; } } if (arg[arg.length - 1] === "." || arg[arg.length - 1] === "-") { return INVALIDEMAIL; } lastPos = atPos; dotPos = arg.indexOf(".", atPos + 1); if (dotPos < 0) { return INVALIDEMAIL; } while (dotPos > 0) { if ((dotPos - lastPos) > 63) { return INVALIDEMAIL; } lastPos = dotPos; dotPos = arg.indexOf(".", lastPos + 1); } tld = arg.slice(lastPos + 1); if (numericOnlyRegex.test(tld)) { return INVALIDEMAIL; } }; typeValidatorFunctions[STRINGHEXORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX32ORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 32) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX64ORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 64) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX128ORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 128) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX256ORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 256) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX512ORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 512) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[NUMBERORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "number") { return NOTANUMBER; } if (isNaN(arg)) { return ISNAN; } if (arg === 2e308 || arg === -2e308) { return ISNOTFINITE; } }; typeValidatorFunctions[BOOLEANORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "boolean") { return NOTABOOLEAN; } }; typeValidatorFunctions[ARRAYORNOTHING] = function(arg) { if (arg === void 0) { return; } if (!Array.isArray(arg)) { return NOTANARRAY; } }; typeValidatorFunctions[OBJECTORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "object") { return NOTANOBJECT; } }; typeValidatorFunctions[STRINGORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } }; typeValidatorFunctions[STRINGEMAILORNULL] = function(arg) { var atPos, c, dotPos, j, lastPos, len, tld; if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length > 320 || arg.length < 5) { return INVALIDSIZE; } if (invalidEmailSmallRegex.test(arg)) { return INVALIDEMAIL; } // if arg.indexOf("..") >= 0 then return INVALIDEMAIL // if arg.indexOf("--") >= 0 then return INVALIDEMAIL // if arg.indexOf("-.") >= 0 then return INVALIDEMAIL // if arg.indexOf(".-") >= 0 then return INVALIDEMAIL atPos = arg.indexOf("@"); if (atPos <= 0 || atPos > 64 || (arg.length - atPos) < 4 || arg[0] === "." || arg[atPos - 1] === "." || arg[0] === "-" || arg[atPos - 1] === "-" || arg[atPos + 1] === "." || arg[atPos + 1] === "-") { return INVALIDEMAIL; } // if atPos <= 0 then return INVALIDEMAIL // if atPos > 64 then return INVALIDEMAIL // if arg[0] == "." or arg[atPos - 1] == "." then return INVALIDEMAIL // if arg[0] == "-" or arg[atPos - 1] == "-" then return INVALIDEMAIL // if arg[atPos + 1] == "." or arg[atPos + 1] == "-" then return INVALIDEMAIL for (i = j = 0, len = arg.length; j < len; i = ++j) { c = arg[i]; if (!(domainCharMap[arg.charCodeAt(i)] || i === atPos || (i < atPos && (c === "+" || c === "_")))) { return INVALIDEMAIL; } } if (arg[arg.length - 1] === "." || arg[arg.length - 1] === "-") { return INVALIDEMAIL; } lastPos = atPos; dotPos = arg.indexOf(".", atPos + 1); if (dotPos < 0) { return INVALIDEMAIL; } while (dotPos > 0) { if ((dotPos - lastPos) > 63) { return INVALIDEMAIL; } lastPos = dotPos; dotPos = arg.indexOf(".", lastPos + 1); } tld = arg.slice(lastPos + 1); if (numericOnlyRegex.test(tld)) { return INVALIDEMAIL; } }; typeValidatorFunctions[STRINGHEXORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX32ORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 32) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX64ORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 64) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX128ORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 128) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX256ORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 256) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[STRINGHEX512ORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } if (arg.length !== 512) { return INVALIDSIZE; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[NUMBERORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "number") { return NOTANUMBER; } if (isNaN(arg)) { return ISNAN; } if (arg === 2e308 || arg === -2e308) { return ISNOTFINITE; } }; typeValidatorFunctions[BOOLEANORNULL] = function(arg) { if (arg === null) { return; } if (typeof arg !== "boolean") { return NOTABOOLEAN; } }; typeValidatorFunctions[ARRAYORNULL] = function(arg) { if (arg === null) { return; } if (!Array.isArray(arg)) { return NOTANARRAY; } }; typeValidatorFunctions[NONNULLOBJECT] = function(arg) { if (typeof arg !== "object") { return NOTANOBJECT; } if (arg === null) { return ISNULL; } }; typeValidatorFunctions[NONEMPTYSTRING] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length === 0) { return ISEMPTYSTRING; } }; typeValidatorFunctions[NONEMPTYARRAY] = function(arg) { if (!Array.isArray(arg)) { return NOTANARRAY; } if (arg.length === 0) { return ISEMPTYARRAY; } }; typeValidatorFunctions[NONEMPTYSTRINGHEX] = function(arg) { if (typeof arg !== "string") { return NOTASTRING; } if (arg.length === 0) { return ISEMPTYSTRING; } i = 0; while (i < arg.length) { if (hexMap[arg.charCodeAt(i)] === void 0) { return INVALIDHEX; } i++; } }; typeValidatorFunctions[NONEMPTYSTRINGCLEAN] = function(arg) { var code; if (typeof arg !== "string") { return NOTASTRING; } if (arg.length === 0) { return ISEMPTYSTRING; } i = 0; while (i < arg.length) { code = arg.charCodeAt(i); if (code > 0x2ff || dirtyCharMap[code]) { return ISDIRTYSTRING; } i++; } }; typeValidatorFunctions[STRINGCLEAN] = function(arg) { var code; if (typeof arg !== "string") { return NOTASTRING; } i = 0; while (i < arg.length) { code = arg.charCodeAt(i); if (code > 0x2ff || dirtyCharMap[code]) { return ISDIRTYSTRING; } i++; } }; typeValidatorFunctions[STRINGCLEANORNULL] = function(arg) { var code; if (arg === null) { return; } if (typeof arg !== "string") { return NOTASTRING; } i = 0; while (i < arg.length) { code = arg.charCodeAt(i); if (code > 0x2ff || dirtyCharMap[code]) { return ISDIRTYSTRING; } i++; } }; typeValidatorFunctions[STRINGCLEANORNOTHING] = function(arg) { var code; if (arg === void 0) { return; } if (typeof arg !== "string") { return NOTASTRING; } i = 0; while (i < arg.length) { code = arg.charCodeAt(i); if (code > 0x2ff || dirtyCharMap[code]) { return ISDIRTYSTRING; } i++; } }; typeValidatorFunctions[OBJECTCLEAN] = function(arg) { if (typeof arg !== "object") { return NOTANOBJECT; } if (isDirtyObject(arg)) { return ISDIRTYOBJECT; } }; typeValidatorFunctions[NONNULLOBJECTCLEAN] = function(arg) { if (typeof arg !== "object") { return NOTANOBJECT; } if (arg === null) { return ISNULL; } if (isDirtyObject(arg)) { return ISDIRTYOBJECT; } }; typeValidatorFunctions[OBJECTCLEANORNOTHING] = function(arg) { if (arg === void 0) { return; } if (typeof arg !== "object") { return NOTANOBJECT; } if (isDirtyObject(arg)) { return ISDIRTYOBJECT; } }; //endregion //endregion //########################################################### //region Error Codes and Messages export var NOTASTRING = 1000; export var NOTANUMBER = 1001; export var NOTABOOLEAN = 1002; export var NOTANARRAY = 1003; export var NOTANOBJECT = 1004; export var INVALIDHEX = 1005; export var INVALIDEMAIL = 1006; export var INVALIDSIZE = 1007; export var ISNAN = 1008; export var ISNULL = 1009; export var ISEMPTYSTRING = 1010; export var ISEMPTYARRAY = 1011; export var ISDIRTYSTRING = 1012; export var ISDIRTYOBJECT = 1013; export var ISNOTFINITE = 1014; export var ISINVALID = 2222; // export THISERROR = 2223 //########################################################### ErrorToMessage = Object.create(null); ErrorToMessage[NOTASTRING] = "Not a String!"; ErrorToMessage[NOTANUMBER] = "Not a Number!"; ErrorToMessage[NOTABOOLEAN] = "Not a Boolean!"; ErrorToMessage[NOTANARRAY] = "Not an Array!"; ErrorToMessage[NOTANOBJECT] = "Not an Object!"; ErrorToMessage[INVALIDHEX] = "String is not valid hex!"; ErrorToMessage[INVALIDEMAIL] = "String is not a valid email!"; ErrorToMessage[INVALIDSIZE] = "String size mismatch!"; ErrorToMessage[ISNAN] = "Number is NaN!"; ErrorToMessage[ISNULL] = "Object is null!"; ErrorToMessage[ISEMPTYSTRING] = "String is empty!"; ErrorToMessage[ISEMPTYARRAY] = "Array is empty!"; ErrorToMessage[ISDIRTYSTRING] = "String is dirty!"; ErrorToMessage[ISDIRTYOBJECT] = "Object is dirty!"; ErrorToMessage[ISNOTFINITE] = "Number is not finite!"; ErrorToMessage[ISINVALID] = "Is invalid!"; // ErrorToMessage[THISERROR] = "This was the Error!" //endregion //########################################################### //region API = exports //########################################################### //# takes obj to be validated, schema and optional boolean staticStrings //# a truthy staticStrings allows you to put static //# strings into your schema like: //# {userInpput: STRING, publicAccess: "onlywithexactlythisstring"} //# returns undefined if the obj is valid or the errorCode on invalid obj export var validate = function(obj, schema, staticStrings) { var type; if (staticStrings === true) { staticValidatorOrThrow = createStaticStringValidator; } else { staticValidatorOrThrow = createThrower("Static string!"); } type = typeof schema; if (type === "number") { return getTypeValidator(schema)(obj); } if (type === "string") { return staticValidatorOrThrow(schema)(obj); } if (type !== "object") { throw new Error(`Illegal ${typeof schema}!`); } if (Array.isArray(schema)) { return createArrayValidator(schema)(obj); } else { return createObjectValidator(schema)(obj); } }; //########################################################### //# takes schema and optional boolean staticStrings //# a truthy staticStrings allows you to put static //# strings into your schema like: //# {userInpput: STRING, publicAccess: "onlywithexactlythisstring"} //# returns the validator function export var createValidator = function(schema, staticStrings) { var type; if (staticStrings === true) { staticValidatorOrThrow = createStaticStringValidator; } else { staticValidatorOrThrow = createThrower("Static string!"); } type = typeof schema; if (type === "number") { return getTypeValidator(schema); } if (type === "string") { return staticValidatorOrThrow(schema); } if (type !== "object") { throw new Error(`Illegal ${typeof schema}!`); } if (Array.isArray(schema)) { return createArrayValidator(schema); } else { return createObjectValidator(schema); } }; //########################################################### //# takes errorcode //# returns the associated errorMessage or "" export var getErrorMessage = function(errorCode) { var msg; msg = ErrorToMessage[errorCode]; if (typeof msg !== "string") { return ""; } else { return msg; } }; //########################################################### //# takes errorCode and errorMessage //# this function cannot overwrite predefined ErrorCodes //# returns the new errorCode for the defined Error export var defineNewError = function(errorMessage) { var errorCode; if (locked) { throw new Error("We are closed!"); } errorCode = Object.keys(ErrorToMessage).length + 1000; if (errorCode >= 2000) { throw new Error("Exeeding error code limit!"); } if (typeof errorMessage !== "string") { throw new Error("ErrorMessage not a String!"); } ErrorToMessage[errorCode] = errorMessage; return errorCode; }; //########################################################### //# takes a validatorFunction //# this function cannot overwrite predefined types //# returns the new enumeration number for the defined Type export var defineNewType = function(validatorFunc) { var newTypeId; if (locked) { throw new Error("We are closed!"); } newTypeId = typeValidatorFunctions.length; if (newTypeId >= 1000) { throw new Error("Exeeding type limit!"); } typeValidatorFunctions[newTypeId] = validatorFunc; return newTypeId; }; //########################################################### //# takes a type and validatorFunc //# sets the specified functions as validator for the //# given type export var setTypeValidator = function(type, valiatorFunc) { if (locked) { throw new Error("We are closed!"); } if (typeof type !== "number") { throw new Error("type is not a Number!"); } if (type >= typeValidatorFunctions.length || type < 1) { throw new Error("Type does not exist!"); } if ((valiatorFunc != null) && typeof valiatorFunc !== "function") { throw new Error("validatorFunc is not a Function!"); } if (typeof validatorFunction !== "undefined" && validatorFunction !== null) { typeValidatorFunctions[type] = validatorFunc; } else { typeValidatorFunctions[type] = function() {}; } }; //########################################################### //# locks/freezes all internal maps no mutation after this! export var lock = function() { locked = true; Object.freeze(typeValidatorFunctions); Object.freeze(typeStringifierFunctions); Object.freeze(ErrorToMessage); }; //endregion