New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

schema-inspector

Package Overview
Dependencies
Maintainers
2
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

schema-inspector - npm Package Compare versions

Comparing version 2.0.1 to 2.0.2

3022

lib/schema-inspector.js

@@ -0,1 +1,6 @@

// Disable no-var because we need to support old IE for now.
/* eslint-disable no-var */
// Disable space-before-function-paren for compatibility with VS Code default JS formatter.
/* eslint-disable space-before-function-paren */
/*

@@ -7,1587 +12,1580 @@ * This module is intended to be executed both on client side and server side.

(function () {
var root = {};
// Dependencies --------------------------------------------------------------
root.async = (typeof require === 'function') ? require('async') : window.async;
if (typeof root.async !== 'object') {
throw new Error('Module async is required (https://github.com/caolan/async)');
}
var async = root.async;
var root = {};
// Dependencies --------------------------------------------------------------
root.async = (typeof require === 'function') ? require('async') : window.async;
if (typeof root.async !== 'object') {
throw new Error('Module async is required (https://github.com/caolan/async)');
}
var async = root.async;
function _extend(origin, add) {
if (!add || typeof add !== 'object') {
return origin;
}
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
}
function _extend(origin, add) {
if (!add || typeof add !== 'object') {
return origin;
}
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
}
function _merge() {
var ret = {};
var args = Array.prototype.slice.call(arguments);
var keys = null;
var i = null;
function _merge() {
var ret = {};
var args = Array.prototype.slice.call(arguments);
var keys = null;
var i = null;
args.forEach(function (arg) {
if (arg && arg.constructor === Object) {
keys = Object.keys(arg);
i = keys.length;
while (i--) {
ret[keys[i]] = arg[keys[i]];
}
}
});
return ret;
}
args.forEach(function (arg) {
if (arg && arg.constructor === Object) {
keys = Object.keys(arg);
i = keys.length;
while (i--) {
ret[keys[i]] = arg[keys[i]];
}
}
});
return ret;
}
// Customisable class (Base class) -------------------------------------------
// Use with operation "new" to extend Validation and Sanitization themselves,
// not their prototype. In other words, constructor shall be call to extend
// those functions, instead of being in their constructor, like this:
// _extend(Validation, new Customisable);
// Customisable class (Base class) -------------------------------------------
// Use with operation "new" to extend Validation and Sanitization themselves,
// not their prototype. In other words, constructor shall be call to extend
// those functions, instead of being in their constructor, like this:
// _extend(Validation, new Customisable);
function Customisable() {
this.custom = {};
function Customisable() {
this.custom = {};
this.extend = function (custom) {
return _extend(this.custom, custom);
};
this.extend = function (custom) {
return _extend(this.custom, custom);
};
this.reset = function () {
this.custom = {};
};
this.reset = function () {
this.custom = {};
};
this.remove = function (fields) {
if (!_typeIs.array(fields)) {
fields = [fields];
}
fields.forEach(function (field) {
delete this.custom[field];
}, this);
};
}
this.remove = function (fields) {
if (!_typeIs.array(fields)) {
fields = [fields];
}
fields.forEach(function (field) {
delete this.custom[field];
}, this);
};
}
// Inspection class (Base class) ---------------------------------------------
// Use to extend Validation and Sanitization prototypes. Inspection
// constructor shall be called in derived class constructor.
// Inspection class (Base class) ---------------------------------------------
// Use to extend Validation and Sanitization prototypes. Inspection
// constructor shall be called in derived class constructor.
function Inspection(schema, custom) {
var _stack = ['@'];
function Inspection(schema, custom) {
var _stack = ['@'];
this._schema = schema;
this._custom = {};
if (custom != null) {
for (var key in custom) {
if (Object.prototype.hasOwnProperty.call(custom, key)) {
this._custom['$' + key] = custom[key];
}
}
}
this._schema = schema;
this._custom = {};
if (custom != null) {
for (var key in custom) {
if (Object.prototype.hasOwnProperty.call(custom, key)) {
this._custom['$' + key] = custom[key];
}
}
}
this._getDepth = function () {
return _stack.length;
};
this._getDepth = function () {
return _stack.length;
};
this._dumpStack = function () {
return _stack.map(function (i) {return i.replace(/^\[/g, '\u001b\u001c\u001d\u001e');})
.join('.').replace(/\.\u001b\u001c\u001d\u001e/g, '[');
};
this._dumpStack = function () {
/* eslint-disable no-control-regex */
return _stack.map(function (i) { return i.replace(/^\[/g, '\u001b\u001c\u001d\u001e'); })
.join('.').replace(/\.\u001b\u001c\u001d\u001e/g, '[');
/* eslint-enable no-control-regex */
};
this._deeperObject = function (name) {
_stack.push((/^[a-z$_][a-z0-9$_]*$/i).test(name) ? name : '["' + name + '"]');
return this;
};
this._deeperObject = function (name) {
_stack.push((/^[a-z$_][a-z0-9$_]*$/i).test(name) ? name : '["' + name + '"]');
return this;
};
this._deeperArray = function (i) {
_stack.push('[' + i + ']');
return this;
};
this._deeperArray = function (i) {
_stack.push('[' + i + ']');
return this;
};
this._back = function () {
_stack.pop();
return this;
};
}
// Simple types --------------------------------------------------------------
// If the property is not defined or is not in this list:
var _typeIs = {
"function": function (element) {
return typeof element === 'function';
},
"string": function (element) {
return typeof element === 'string';
},
"number": function (element) {
return typeof element === 'number' && !isNaN(element);
},
"integer": function (element) {
return typeof element === 'number' && element % 1 === 0;
},
"NaN": function (element) {
return typeof element === 'number' && isNaN(element);
},
"boolean": function (element) {
return typeof element === 'boolean';
},
"null": function (element) {
return element === null;
},
"date": function (element) {
return element != null && element instanceof Date;
},
"object": function (element) {
return typeof element === 'object' && element.constructor !== Array && element != null;
},
"array": function (element) {
return element != null && element.constructor === Array;
},
"any": function () {
return true;
}
};
this._back = function () {
_stack.pop();
return this;
};
}
// Simple types --------------------------------------------------------------
// If the property is not defined or is not in this list:
var _typeIs = {
function: function (element) {
return typeof element === 'function';
},
string: function (element) {
return typeof element === 'string';
},
number: function (element) {
return typeof element === 'number' && !isNaN(element);
},
integer: function (element) {
return typeof element === 'number' && element % 1 === 0;
},
NaN: function (element) {
return typeof element === 'number' && isNaN(element);
},
boolean: function (element) {
return typeof element === 'boolean';
},
null: function (element) {
return element === null;
},
date: function (element) {
return element != null && element instanceof Date;
},
object: function (element) {
return typeof element === 'object' && element != null && element.constructor !== Array;
},
array: function (element) {
return element != null && element.constructor === Array;
},
any: function () {
return true;
}
};
function _simpleType(type, candidate) {
if (typeof type == 'function') {
return candidate instanceof type;
}
type = type in _typeIs ? type : 'any';
return _typeIs[type](candidate);
}
function _simpleType(type, candidate) {
if (typeof type === 'function') {
return candidate instanceof type;
}
type = type in _typeIs ? type : 'any';
return _typeIs[type](candidate);
}
function _realType(candidate) {
for (var i in _typeIs) {
if (_simpleType(i, candidate)) {
if (i !== 'any' && (i !== 'object' || candidate.constructor === Object)) { return i; }
return 'an instance of ' + candidate.constructor.name;
}
}
}
function _realType(candidate) {
for (var i in _typeIs) {
if (_simpleType(i, candidate)) {
if (i !== 'any' && (i !== 'object' || candidate.constructor === Object)) { return i; }
return 'an instance of ' + candidate.constructor.name;
}
}
}
function getIndexes(a, value) {
var indexes = [];
var i = a.indexOf(value);
function getIndexes(a, value) {
var indexes = [];
var i = a.indexOf(value);
while (i !== -1) {
indexes.push(i);
i = a.indexOf(value, i + 1);
}
return indexes;
}
while (i !== -1) {
indexes.push(i);
i = a.indexOf(value, i + 1);
}
return indexes;
}
// Available formats ---------------------------------------------------------
var _formats = {
'void': /^$/,
'url': /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)?(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,
'date-time': /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z?|(-|\+)\d{2}:\d{2})$/,
'date': /^\d{4}-\d{2}-\d{2}$/,
'coolDateTime': /^\d{4}(-|\/)\d{2}(-|\/)\d{2}(T| )\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/,
'time': /^\d{2}\:\d{2}\:\d{2}$/,
'color': /^#([0-9a-f])+$/i,
// 2021-03-13 - Email regex was replaced with result of running email-safe-regex
// latest version as of that day in order so fix GHSL-2020-35.
// const emailRegexSafe = require('email-regex-safe');
// const regexString = emailRegexSafe({
// exact: true,
// returnString: true,
// });
// <using debugger to inspect state of regexString after previous statement>
//
// Note that this regex is pretty flexible, but it's a bit stricter than
// what we had before. It requires the local part of the email address to
// be at least two characters. Was able to find some justification for
// this at https://stackoverflow.com/a/15783334/5051165. Test suite
// was corrected accordingly.
'email': new RegExp(`(?:[^\\W_](?:[\\w\\.\\+]+)@(?:localhost|(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?:(?:[a-z\\u00a1-\\uffff0-9][-_]*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:northwesternmutual|travelersinsurance|vermögensberatung|vermögensberater|americanexpress|kerryproperties|sandvikcoromant|afamilycompany|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|international|lifeinsurance|spreadbetting|travelchannel|wolterskluwer|construction|lplfinancial|scholarships|versicherung|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|williamhill|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nationwide|nextdirect|onyourside|properties|protection|prudential|realestate|republican|restaurant|schaeffler|swiftcover|tatamotors|technology|university|vlaanderen|volkswagen|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|fujixerox|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|institute|insurance|kuokgroup|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|scjohnson|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|موريتانيا|yodobashi|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|budapest|builders|business|capetown|catering|catholic|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|etisalat|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|training|vanguard|ventures|verisign|woodside|السعودية|yokohama|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lanxess|lasalle|latrobe|leclerc|limited|lincoln|markets|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|singles|staples|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|католик|الجزائر|العليان|اتصالات|پاکستان|البحرين|كاثوليك|இந்தியா|yamaxun|youtube|zuerich|abarth|abbott|abbvie|africa|agency|airbus|airtel|alipay|alsace|alstom|amazon|anquan|aramco|author|bayern|beauty|berlin|bharti|bostik|boston|broker|camera|career|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|webcam|xihuan|москва|онлайн|ファッション|भारतम्|ارامكو|امارات|الاردن|المغرب|ابوظبي|مليسيا|இலங்கை|فلسطين|yachts|yandex|zappos|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|drive|dubai|earth|edeka|email|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glade|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|irish|iveco|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|lixil|loans|locus|lotte|lotto|macys|mango|media|miami|money|movie|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|ישראל|বাংলা|భారత్|भारोत|संगठन|ایران|بازار|بھارت|سودان|همراه|سورية|ഭാരതം|嘉里大酒店|yahoo|aarp|able|adac|aero|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|duck|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|raid|read|reit|rent|rest|rich|rmit|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|ಭಾರತ|ଭାରତ|大众汽车|ভাৰত|ভারত|موقع|香格里拉|сайт|アマゾン|дети|ポイント|ලංකා|電訊盈科|クラウド|ભારત|भारत|عمان|بارت|ڀارت|عراق|شبكة|بيتك|组织机构|تونس|グーグル|ਭਾਰਤ|yoga|zara|zero|zone|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceo|cfa|cfd|com|cpa|crs|csc|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gay|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|llp|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|off|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|qvc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|spa|srl|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|कॉम|セール|คอม|我爱你|қаз|срб|бел|קום|淡马锡|орг|नेट|ストア|мкд|كوم|中文网|ком|укр|亚马逊|诺基亚|飞利浦|мон|عرب|ไทย|рус|ລາວ|みんな|天主教|مصر|قطر|հայ|新加坡|xxx|xyz|you|yun|zip|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|佛山|慈善|集团|在线|한국|点看|八卦|公益|公司|网站|移动|联通|бг|时尚|微博|삼성|商标|商店|商城|ею|新闻|家電|中信|中国|中國|娱乐|谷歌|购物|通販|网店|餐厅|网络|香港|食品|台湾|台灣|手机|澳門|닷컴|政府|გე|机构|健康|招聘|рф|大拿|ευ|ελ|世界|書籍|网址|닷넷|コム|游戏|企业|信息|嘉里|广东|政务|ye|yt|za|zm|zw))))`),
'numeric': /^[0-9]+$/,
'integer': /^\-?[0-9]+$/,
'decimal': /^\-?[0-9]*\.?[0-9]+$/,
'alpha': /^[a-z]+$/i,
'alphaNumeric': /^[a-z0-9]+$/i,
'alphaDash': /^[a-z0-9_-]+$/i,
'javascript': /^[a-z_\$][a-z0-9_\$]*$/i,
'upperString': /^[A-Z ]*$/,
'lowerString': /^[a-z ]*$/,
'v4uuid': /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$/i
};
// Available formats ---------------------------------------------------------
/* eslint-disable no-useless-escape */
// TODO: Study these regex expressions and add more tests so we can consider removing
// rule no-useless-escape.
var _formats = {
void: /^$/,
url: /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)?(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,
'date-time': /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z?|(-|\+)\d{2}:\d{2})$/,
date: /^\d{4}-\d{2}-\d{2}$/,
coolDateTime: /^\d{4}(-|\/)\d{2}(-|\/)\d{2}(T| )\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/,
time: /^\d{2}\:\d{2}\:\d{2}$/,
color: /^#([0-9a-f])+$/i,
// 2021-03-13 - Email regex was replaced with result of running email-safe-regex
// latest version as of that day in order so fix GHSL-2020-35.
// const emailRegexSafe = require('email-regex-safe');
// const regexString = emailRegexSafe({
// exact: true,
// returnString: true,
// });
// <using debugger to inspect state of regexString after previous statement>
//
// Note that this regex is pretty flexible, but it's a bit stricter than
// what we had before. It requires the local part of the email address to
// be at least two characters. Was able to find some justification for
// this at https://stackoverflow.com/a/15783334/5051165. Test suite
// was corrected accordingly.
/* eslint-disable prefer-regex-literals */
/* eslint-disable quotes */
email: new RegExp(`(?:[^\\W_](?:[\\w\\.\\+]+)@(?:localhost|(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?:(?:[a-z\\u00a1-\\uffff0-9][-_]*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:northwesternmutual|travelersinsurance|vermögensberatung|vermögensberater|americanexpress|kerryproperties|sandvikcoromant|afamilycompany|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|international|lifeinsurance|spreadbetting|travelchannel|wolterskluwer|construction|lplfinancial|scholarships|versicherung|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|williamhill|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nationwide|nextdirect|onyourside|properties|protection|prudential|realestate|republican|restaurant|schaeffler|swiftcover|tatamotors|technology|university|vlaanderen|volkswagen|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|fujixerox|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|institute|insurance|kuokgroup|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|scjohnson|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|موريتانيا|yodobashi|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|budapest|builders|business|capetown|catering|catholic|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|etisalat|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|training|vanguard|ventures|verisign|woodside|السعودية|yokohama|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lanxess|lasalle|latrobe|leclerc|limited|lincoln|markets|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|singles|staples|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|католик|الجزائر|العليان|اتصالات|پاکستان|البحرين|كاثوليك|இந்தியா|yamaxun|youtube|zuerich|abarth|abbott|abbvie|africa|agency|airbus|airtel|alipay|alsace|alstom|amazon|anquan|aramco|author|bayern|beauty|berlin|bharti|bostik|boston|broker|camera|career|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|webcam|xihuan|москва|онлайн|ファッション|भारतम्|ارامكو|امارات|الاردن|المغرب|ابوظبي|مليسيا|இலங்கை|فلسطين|yachts|yandex|zappos|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|drive|dubai|earth|edeka|email|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glade|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|irish|iveco|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|lixil|loans|locus|lotte|lotto|macys|mango|media|miami|money|movie|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|ישראל|বাংলা|భారత్|भारोत|संगठन|ایران|بازار|بھارت|سودان|همراه|سورية|ഭാരതം|嘉里大酒店|yahoo|aarp|able|adac|aero|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|duck|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|raid|read|reit|rent|rest|rich|rmit|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|ಭಾರತ|ଭାରତ|大众汽车|ভাৰত|ভারত|موقع|香格里拉|сайт|アマゾン|дети|ポイント|ලංකා|電訊盈科|クラウド|ભારત|भारत|عمان|بارت|ڀارت|عراق|شبكة|بيتك|组织机构|تونس|グーグル|ਭਾਰਤ|yoga|zara|zero|zone|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceo|cfa|cfd|com|cpa|crs|csc|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gay|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|llp|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|off|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|qvc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|spa|srl|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|कॉम|セール|คอม|我爱你|қаз|срб|бел|קום|淡马锡|орг|नेट|ストア|мкд|كوم|中文网|ком|укр|亚马逊|诺基亚|飞利浦|мон|عرب|ไทย|рус|ລາວ|みんな|天主教|مصر|قطر|հայ|新加坡|xxx|xyz|you|yun|zip|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|佛山|慈善|集团|在线|한국|点看|八卦|公益|公司|网站|移动|联通|бг|时尚|微博|삼성|商标|商店|商城|ею|新闻|家電|中信|中国|中國|娱乐|谷歌|购物|通販|网店|餐厅|网络|香港|食品|台湾|台灣|手机|澳門|닷컴|政府|გე|机构|健康|招聘|рф|大拿|ευ|ελ|世界|書籍|网址|닷넷|コム|游戏|企业|信息|嘉里|广东|政务|ye|yt|za|zm|zw))))`),
/* eslint-enable prefer-regex-literals */
/* eslint-enable quotes */
numeric: /^[0-9]+$/,
integer: /^\-?[0-9]+$/,
decimal: /^\-?[0-9]*\.?[0-9]+$/,
alpha: /^[a-z]+$/i,
alphaNumeric: /^[a-z0-9]+$/i,
alphaDash: /^[a-z0-9_-]+$/i,
javascript: /^[a-z_\$][a-z0-9_\$]*$/i,
upperString: /^[A-Z ]*$/,
lowerString: /^[a-z ]*$/,
v4uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$/i
};
/* eslint-enable no-useless-escape */
// Validation ------------------------------------------------------------------
var _validationAttribut = {
optional: function (schema, candidate) {
var opt = typeof schema.optional === 'boolean' ? schema.optional : (schema.optional === 'true'); // Default is false
// Validation ------------------------------------------------------------------
var _validationAttribut = {
optional: function (schema, candidate) {
var opt = typeof schema.optional === 'boolean' ? schema.optional : (schema.optional === 'true'); // Default is false
if (opt === true) {
return;
}
if (typeof candidate === 'undefined') {
this.report('is missing and not optional', null, 'optional');
}
},
type: function (schema, candidate) {
// return because optional function already handle this case
if (typeof candidate === 'undefined' || (typeof schema.type !== 'string' && !(schema.type instanceof Array) && typeof schema.type !== 'function')) {
return;
}
var types = _typeIs.array(schema.type) ? schema.type : [schema.type];
var typeIsValid = types.some(function (type) {
return _simpleType(type, candidate);
});
if (!typeIsValid) {
types = types.map(function (t) {return typeof t === 'function' ? 'an instance of ' + t.name : t; });
this.report('must be ' + types.join(' or ') + ', but is ' + _realType(candidate), null, 'type');
}
},
uniqueness: function (schema, candidate) {
if (typeof schema.uniqueness === 'string') { schema.uniqueness = (schema.uniqueness === 'true'); }
if (typeof schema.uniqueness !== 'boolean' || schema.uniqueness === false || (!_typeIs.array(candidate) && typeof candidate !== 'string')) {
return;
}
var reported = [];
for (var i = 0; i < candidate.length; i++) {
if (reported.indexOf(candidate[i]) >= 0) {
continue;
}
var indexes = getIndexes(candidate, candidate[i]);
if (indexes.length > 1) {
reported.push(candidate[i]);
this.report('has value [' + candidate[i] + '] more than once at indexes [' + indexes.join(', ') + ']', null, 'uniqueness');
}
}
},
pattern: function (schema, candidate) {
var self = this;
var regexs = schema.pattern;
if (typeof candidate !== 'string') {
return;
}
var matches = false;
if (!_typeIs.array(regexs)) {
regexs = [regexs];
}
regexs.forEach(function (regex) {
if (typeof regex === 'string' && regex in _formats) {
regex = _formats[regex];
}
if (regex instanceof RegExp) {
if (regex.test(candidate)) {
matches = true;
}
}
});
if (!matches) {
self.report('must match [' + regexs.join(' or ') + '], but is equal to "' + candidate + '"', null, 'pattern');
}
},
validDate: function (schema, candidate) {
if (String(schema.validDate) === 'true' && candidate instanceof Date && isNaN(candidate.getTime())) {
this.report('must be a valid date', null, 'validDate');
}
},
minLength: function (schema, candidate) {
if (typeof candidate !== 'string' && !_typeIs.array(candidate)) {
return;
}
var minLength = Number(schema.minLength);
if (isNaN(minLength)) {
return;
}
if (candidate.length < minLength) {
this.report('must be longer than ' + minLength + ' elements, but it has ' + candidate.length, null, 'minLength');
}
},
maxLength: function (schema, candidate) {
if (typeof candidate !== 'string' && !_typeIs.array(candidate)) {
return;
}
var maxLength = Number(schema.maxLength);
if (isNaN(maxLength)) {
return;
}
if (candidate.length > maxLength) {
this.report('must be shorter than ' + maxLength + ' elements, but it has ' + candidate.length, null, 'maxLength');
}
},
exactLength: function (schema, candidate) {
if (typeof candidate !== 'string' && !_typeIs.array(candidate)) {
return;
}
var exactLength = Number(schema.exactLength);
if (isNaN(exactLength)) {
return;
}
if (candidate.length !== exactLength) {
this.report('must have exactly ' + exactLength + ' elements, but it have ' + candidate.length, null, 'exactLength');
}
},
lt: function (schema, candidate) {
var limit = Number(schema.lt);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate >= limit) {
this.report('must be less than ' + limit + ', but is equal to "' + candidate + '"', null, 'lt');
}
},
lte: function (schema, candidate) {
var limit = Number(schema.lte);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate > limit) {
this.report('must be less than or equal to ' + limit + ', but is equal to "' + candidate + '"', null, 'lte');
}
},
gt: function (schema, candidate) {
var limit = Number(schema.gt);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate <= limit) {
this.report('must be greater than ' + limit + ', but is equal to "' + candidate + '"', null, 'gt');
}
},
gte: function (schema, candidate) {
var limit = Number(schema.gte);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate < limit) {
this.report('must be greater than or equal to ' + limit + ', but is equal to "' + candidate + '"', null, 'gte');
}
},
eq: function (schema, candidate) {
if (typeof candidate !== 'number' && typeof candidate !== 'string' && typeof candidate !== 'boolean') {
return;
}
var limit = schema.eq;
if (typeof limit !== 'number' && typeof limit !== 'string' && typeof limit !== 'boolean' && !_typeIs.array(limit)) {
return;
}
if (_typeIs.array(limit)) {
for (var i = 0; i < limit.length; i++) {
if (candidate === limit[i]) {
return;
}
}
this.report('must be equal to [' + limit.map(function (l) {
return '"' + l + '"';
}).join(' or ') + '], but is equal to "' + candidate + '"', null, 'eq');
}
else {
if (candidate !== limit) {
this.report('must be equal to "' + limit + '", but is equal to "' + candidate + '"', null, 'eq');
}
}
},
ne: function (schema, candidate) {
if (typeof candidate !== 'number' && typeof candidate !== 'string') {
return;
}
var limit = schema.ne;
if (typeof limit !== 'number' && typeof limit !== 'string' && !_typeIs.array(limit)) {
return;
}
if (_typeIs.array(limit)) {
for (var i = 0; i < limit.length; i++) {
if (candidate === limit[i]) {
this.report('must not be equal to "' + limit[i] + '"', null, 'ne');
return;
}
}
}
else {
if (candidate === limit) {
this.report('must not be equal to "' + limit + '"', null, 'ne');
}
}
},
someKeys: function (schema, candidat) {
var _keys = schema.someKeys;
if (!_typeIs.object(candidat)) {
return;
}
var valid = _keys.some(function (action) {
return (action in candidat);
});
if (!valid) {
this.report('must have at least key ' + _keys.map(function (i) {
return '"' + i + '"';
}).join(' or '), null, 'someKeys');
}
},
strict: function (schema, candidate) {
if (typeof schema.strict === 'string') { schema.strict = (schema.strict === 'true'); }
if (schema.strict !== true || !_typeIs.object(candidate) || !_typeIs.object(schema.properties)) {
return;
}
var self = this;
if (typeof schema.properties['*'] === 'undefined') {
var intruder = Object.keys(candidate).filter(function (key) {
return (typeof schema.properties[key] === 'undefined');
});
if (intruder.length > 0) {
var msg = 'should not contains ' + (intruder.length > 1 ? 'properties' : 'property') +
' [' + intruder.map(function (i) { return '"' + i + '"'; }).join(', ') + ']';
self.report(msg, null, 'strict');
}
}
},
exec: function (schema, candidate, callback) {
var self = this;
if (opt === true) {
return;
}
if (typeof candidate === 'undefined') {
this.report('is missing and not optional', null, 'optional');
}
},
type: function (schema, candidate) {
// return because optional function already handle this case
if (typeof candidate === 'undefined' || (typeof schema.type !== 'string' && !(schema.type instanceof Array) && typeof schema.type !== 'function')) {
return;
}
var types = _typeIs.array(schema.type) ? schema.type : [schema.type];
var typeIsValid = types.some(function (type) {
return _simpleType(type, candidate);
});
if (!typeIsValid) {
types = types.map(function (t) { return typeof t === 'function' ? 'an instance of ' + t.name : t; });
this.report('must be ' + types.join(' or ') + ', but is ' + _realType(candidate), null, 'type');
}
},
uniqueness: function (schema, candidate) {
if (typeof schema.uniqueness === 'string') { schema.uniqueness = (schema.uniqueness === 'true'); }
if (typeof schema.uniqueness !== 'boolean' || schema.uniqueness === false || (!_typeIs.array(candidate) && typeof candidate !== 'string')) {
return;
}
var reported = [];
for (var i = 0; i < candidate.length; i++) {
if (reported.indexOf(candidate[i]) >= 0) {
continue;
}
var indexes = getIndexes(candidate, candidate[i]);
if (indexes.length > 1) {
reported.push(candidate[i]);
this.report('has value [' + candidate[i] + '] more than once at indexes [' + indexes.join(', ') + ']', null, 'uniqueness');
}
}
},
pattern: function (schema, candidate) {
var self = this;
var regexs = schema.pattern;
if (typeof candidate !== 'string') {
return;
}
var matches = false;
if (!_typeIs.array(regexs)) {
regexs = [regexs];
}
regexs.forEach(function (regex) {
if (typeof regex === 'string' && regex in _formats) {
regex = _formats[regex];
}
if (regex instanceof RegExp) {
if (regex.test(candidate)) {
matches = true;
}
}
});
if (!matches) {
self.report('must match [' + regexs.join(' or ') + '], but is equal to "' + candidate + '"', null, 'pattern');
}
},
validDate: function (schema, candidate) {
if (String(schema.validDate) === 'true' && candidate instanceof Date && isNaN(candidate.getTime())) {
this.report('must be a valid date', null, 'validDate');
}
},
minLength: function (schema, candidate) {
if (typeof candidate !== 'string' && !_typeIs.array(candidate)) {
return;
}
var minLength = Number(schema.minLength);
if (isNaN(minLength)) {
return;
}
if (candidate.length < minLength) {
this.report('must be longer than ' + minLength + ' elements, but it has ' + candidate.length, null, 'minLength');
}
},
maxLength: function (schema, candidate) {
if (typeof candidate !== 'string' && !_typeIs.array(candidate)) {
return;
}
var maxLength = Number(schema.maxLength);
if (isNaN(maxLength)) {
return;
}
if (candidate.length > maxLength) {
this.report('must be shorter than ' + maxLength + ' elements, but it has ' + candidate.length, null, 'maxLength');
}
},
exactLength: function (schema, candidate) {
if (typeof candidate !== 'string' && !_typeIs.array(candidate)) {
return;
}
var exactLength = Number(schema.exactLength);
if (isNaN(exactLength)) {
return;
}
if (candidate.length !== exactLength) {
this.report('must have exactly ' + exactLength + ' elements, but it have ' + candidate.length, null, 'exactLength');
}
},
lt: function (schema, candidate) {
var limit = Number(schema.lt);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate >= limit) {
this.report('must be less than ' + limit + ', but is equal to "' + candidate + '"', null, 'lt');
}
},
lte: function (schema, candidate) {
var limit = Number(schema.lte);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate > limit) {
this.report('must be less than or equal to ' + limit + ', but is equal to "' + candidate + '"', null, 'lte');
}
},
gt: function (schema, candidate) {
var limit = Number(schema.gt);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate <= limit) {
this.report('must be greater than ' + limit + ', but is equal to "' + candidate + '"', null, 'gt');
}
},
gte: function (schema, candidate) {
var limit = Number(schema.gte);
if (typeof candidate !== 'number' || isNaN(limit)) {
return;
}
if (candidate < limit) {
this.report('must be greater than or equal to ' + limit + ', but is equal to "' + candidate + '"', null, 'gte');
}
},
eq: function (schema, candidate) {
if (typeof candidate !== 'number' && typeof candidate !== 'string' && typeof candidate !== 'boolean') {
return;
}
var limit = schema.eq;
if (typeof limit !== 'number' && typeof limit !== 'string' && typeof limit !== 'boolean' && !_typeIs.array(limit)) {
return;
}
if (_typeIs.array(limit)) {
for (var i = 0; i < limit.length; i++) {
if (candidate === limit[i]) {
return;
}
}
this.report('must be equal to [' + limit.map(function (l) {
return '"' + l + '"';
}).join(' or ') + '], but is equal to "' + candidate + '"', null, 'eq');
} else {
if (candidate !== limit) {
this.report('must be equal to "' + limit + '", but is equal to "' + candidate + '"', null, 'eq');
}
}
},
ne: function (schema, candidate) {
if (typeof candidate !== 'number' && typeof candidate !== 'string') {
return;
}
var limit = schema.ne;
if (typeof limit !== 'number' && typeof limit !== 'string' && !_typeIs.array(limit)) {
return;
}
if (_typeIs.array(limit)) {
for (var i = 0; i < limit.length; i++) {
if (candidate === limit[i]) {
this.report('must not be equal to "' + limit[i] + '"', null, 'ne');
return;
}
}
} else {
if (candidate === limit) {
this.report('must not be equal to "' + limit + '"', null, 'ne');
}
}
},
someKeys: function (schema, candidat) {
var _keys = schema.someKeys;
if (!_typeIs.object(candidat)) {
return;
}
var valid = _keys.some(function (action) {
return (action in candidat);
});
if (!valid) {
this.report('must have at least key ' + _keys.map(function (i) {
return '"' + i + '"';
}).join(' or '), null, 'someKeys');
}
},
strict: function (schema, candidate) {
if (typeof schema.strict === 'string') { schema.strict = (schema.strict === 'true'); }
if (schema.strict !== true || !_typeIs.object(candidate) || !_typeIs.object(schema.properties)) {
return;
}
var self = this;
if (typeof schema.properties['*'] === 'undefined') {
var intruder = Object.keys(candidate).filter(function (key) {
return (typeof schema.properties[key] === 'undefined');
});
if (intruder.length > 0) {
var msg = 'should not contains ' + (intruder.length > 1 ? 'properties' : 'property') +
' [' + intruder.map(function (i) { return '"' + i + '"'; }).join(', ') + ']';
self.report(msg, null, 'strict');
}
}
},
exec: function (schema, candidate, callback) {
var self = this;
if (typeof callback === 'function') {
return this.asyncExec(schema, candidate, callback);
}
(_typeIs.array(schema.exec) ? schema.exec : [schema.exec]).forEach(function (exec) {
if (typeof exec === 'function') {
exec.call(self, schema, candidate);
}
});
},
properties: function (schema, candidate, callback) {
if (typeof callback === 'function') {
return this.asyncProperties(schema, candidate, callback);
}
if (!(schema.properties instanceof Object) || !(candidate instanceof Object)) {
return;
}
var properties = schema.properties,
i;
if (properties['*'] != null) {
for (i in candidate) {
if (i in properties) {
continue;
}
this._deeperObject(i);
this._validate(properties['*'], candidate[i]);
this._back();
}
}
for (i in properties) {
if (i === '*') {
continue;
}
this._deeperObject(i);
this._validate(properties[i], candidate[i]);
this._back();
}
},
items: function (schema, candidate, callback) {
if (typeof callback === 'function') {
return this.asyncItems(schema, candidate, callback);
}
if (!(schema.items instanceof Object) || !(candidate instanceof Object)) {
return;
}
var items = schema.items;
var i, l;
// If provided schema is an array
// then call validate for each case
// else it is an Object
// then call validate for each key
if (_typeIs.array(items) && _typeIs.array(candidate)) {
for (i = 0, l = items.length; i < l; i++) {
this._deeperArray(i);
this._validate(items[i], candidate[i]);
this._back();
}
}
else {
for (var key in candidate) {
if (Object.prototype.hasOwnProperty.call(candidate, key)) {
this._deeperArray(key);
this._validate(items, candidate[key]);
this._back();
}
if (typeof callback === 'function') {
return this.asyncExec(schema, candidate, callback);
}
(_typeIs.array(schema.exec) ? schema.exec : [schema.exec]).forEach(function (exec) {
if (typeof exec === 'function') {
exec.call(self, schema, candidate);
}
});
},
properties: function (schema, candidate, callback) {
if (typeof callback === 'function') {
return this.asyncProperties(schema, candidate, callback);
}
if (!(schema.properties instanceof Object) || !(candidate instanceof Object)) {
return;
}
var properties = schema.properties;
var i;
if (properties['*'] != null) {
for (i in candidate) {
if (i in properties) {
continue;
}
this._deeperObject(i);
this._validate(properties['*'], candidate[i]);
this._back();
}
}
for (i in properties) {
if (i === '*') {
continue;
}
this._deeperObject(i);
this._validate(properties[i], candidate[i]);
this._back();
}
},
items: function (schema, candidate, callback) {
if (typeof callback === 'function') {
return this.asyncItems(schema, candidate, callback);
}
if (!(schema.items instanceof Object) || !(candidate instanceof Object)) {
return;
}
var items = schema.items;
var i, l;
// If provided schema is an array
// then call validate for each case
// else it is an Object
// then call validate for each key
if (_typeIs.array(items) && _typeIs.array(candidate)) {
for (i = 0, l = items.length; i < l; i++) {
this._deeperArray(i);
this._validate(items[i], candidate[i]);
this._back();
}
} else {
for (var key in candidate) {
if (Object.prototype.hasOwnProperty.call(candidate, key)) {
this._deeperArray(key);
this._validate(items, candidate[key]);
this._back();
}
}
}
}
};
}
}
}
};
var _asyncValidationAttribut = {
asyncExec: function (schema, candidate, callback) {
var self = this;
async.eachSeries(_typeIs.array(schema.exec) ? schema.exec : [schema.exec], function (exec, done) {
if (typeof exec === 'function') {
if (exec.length > 2) {
return exec.call(self, schema, candidate, done);
}
exec.call(self, schema, candidate);
}
async.nextTick(done);
}, callback);
},
asyncProperties: function (schema, candidate, callback) {
if (!(schema.properties instanceof Object) || !_typeIs.object(candidate)) {
return callback();
}
var self = this;
var properties = schema.properties;
async.series([
function (next) {
if (properties['*'] == null) {
return next();
}
async.eachSeries(Object.keys(candidate), function (i, done) {
if (i in properties) {
return async.nextTick(done);
}
self._deeperObject(i);
self._asyncValidate(properties['*'], candidate[i], function (err) {
self._back();
done(err);
});
}, next);
},
function (next) {
async.eachSeries(Object.keys(properties), function (i, done) {
if (i === '*') {
return async.nextTick(done);
}
self._deeperObject(i);
self._asyncValidate(properties[i], candidate[i], function (err) {
self._back();
done(err);
});
}, next);
}
], callback);
},
asyncItems: function (schema, candidate, callback) {
if (!(schema.items instanceof Object) || !(candidate instanceof Object)) {
return callback();
}
var self = this;
var items = schema.items;
var _asyncValidationAttribut = {
asyncExec: function (schema, candidate, callback) {
var self = this;
async.eachSeries(_typeIs.array(schema.exec) ? schema.exec : [schema.exec], function (exec, done) {
if (typeof exec === 'function') {
if (exec.length > 2) {
return exec.call(self, schema, candidate, done);
}
exec.call(self, schema, candidate);
}
async.nextTick(done);
}, callback);
},
asyncProperties: function (schema, candidate, callback) {
if (!(schema.properties instanceof Object) || !_typeIs.object(candidate)) {
return callback();
}
var self = this;
var properties = schema.properties;
async.series([
function (next) {
if (properties['*'] == null) {
return next();
}
async.eachSeries(Object.keys(candidate), function (i, done) {
if (i in properties) {
return async.nextTick(done);
}
self._deeperObject(i);
self._asyncValidate(properties['*'], candidate[i], function (err) {
self._back();
done(err);
});
}, next);
},
function (next) {
async.eachSeries(Object.keys(properties), function (i, done) {
if (i === '*') {
return async.nextTick(done);
}
self._deeperObject(i);
self._asyncValidate(properties[i], candidate[i], function (err) {
self._back();
done(err);
});
}, next);
}
], callback);
},
asyncItems: function (schema, candidate, callback) {
if (!(schema.items instanceof Object) || !(candidate instanceof Object)) {
return callback();
}
var self = this;
var items = schema.items;
var i, l;
if (_typeIs.array(items) && _typeIs.array(candidate)) {
async.timesSeries(items.length, function (i, done) {
self._deeperArray(i);
self._asyncValidate(items[i], candidate[i], function (err, res) {
self._back();
done(err, res);
});
self._back();
}, callback);
} else {
async.eachSeries(Object.keys(candidate), function (key, done) {
self._deeperArray(key);
self._asyncValidate(items, candidate[key], function (err, res) {
self._back();
done(err, res);
});
}, callback);
}
}
};
if (_typeIs.array(items) && _typeIs.array(candidate)) {
async.timesSeries(items.length, function (i, done) {
self._deeperArray(i);
self._asyncValidate(items[i], candidate[i], function (err, res) {
self._back();
done(err, res);
});
self._back();
}, callback);
}
else {
async.eachSeries(Object.keys(candidate), function (key, done) {
self._deeperArray(key);
self._asyncValidate(items, candidate[key], function (err, res) {
self._back();
done(err, res);
});
}, callback);
}
}
};
// Validation Class ----------------------------------------------------------
// inherits from Inspection class (actually we just call Inspection
// constructor with the new context, because its prototype is empty
function Validation(schema, custom) {
Inspection.prototype.constructor.call(this, schema, _merge(Validation.custom, custom));
var _error = [];
// Validation Class ----------------------------------------------------------
// inherits from Inspection class (actually we just call Inspection
// constructor with the new context, because its prototype is empty
function Validation(schema, custom) {
Inspection.prototype.constructor.call(this, schema, _merge(Validation.custom, custom));
var _error = [];
this._basicFields = Object.keys(_validationAttribut);
this._customFields = Object.keys(this._custom);
this.origin = null;
this._basicFields = Object.keys(_validationAttribut);
this._customFields = Object.keys(this._custom);
this.origin = null;
this.report = function (message, code, reason) {
var newErr = {
code: code || this.userCode || null,
reason: reason || 'unknown',
message: this.userError || message || 'is invalid',
property: this.userAlias ? (this.userAlias + ' (' + this._dumpStack() + ')') : this._dumpStack()
};
_error.push(newErr);
return this;
};
this.report = function (message, code, reason) {
var newErr = {
code: code || this.userCode || null,
reason: reason || 'unknown',
message: this.userError || message || 'is invalid',
property: this.userAlias ? (this.userAlias + ' (' + this._dumpStack() + ')') : this._dumpStack()
};
_error.push(newErr);
return this;
};
this.result = function () {
return {
error: _error,
valid: _error.length === 0,
format: function () {
if (this.valid === true) {
return 'Candidate is valid';
}
return this.error.map(function (i) {
return 'Property ' + i.property + ': ' + i.message;
}).join('\n');
}
};
};
}
this.result = function () {
return {
error: _error,
valid: _error.length === 0,
format: function () {
if (this.valid === true) {
return 'Candidate is valid';
}
return this.error.map(function (i) {
return 'Property ' + i.property + ': ' + i.message;
}).join('\n');
}
};
};
}
_extend(Validation.prototype, _validationAttribut);
_extend(Validation.prototype, _asyncValidationAttribut);
_extend(Validation, new Customisable());
_extend(Validation.prototype, _validationAttribut);
_extend(Validation.prototype, _asyncValidationAttribut);
_extend(Validation, new Customisable());
Validation.prototype.validate = function (candidate, callback) {
this.origin = candidate;
if (typeof callback === 'function') {
var self = this;
return async.nextTick(function () {
self._asyncValidate(self._schema, candidate, function (err) {
self.origin = null;
callback(err, self.result());
});
});
}
return this._validate(this._schema, candidate).result();
};
Validation.prototype.validate = function (candidate, callback) {
this.origin = candidate;
if (typeof callback === 'function') {
var self = this;
return async.nextTick(function () {
self._asyncValidate(self._schema, candidate, function (err) {
self.origin = null;
callback(err, self.result());
});
});
}
return this._validate(this._schema, candidate).result();
};
Validation.prototype._validate = function (schema, candidate, callback) {
this.userCode = schema.code || null;
this.userError = schema.error || null;
this.userAlias = schema.alias || null;
this._basicFields.forEach(function (i) {
if ((i in schema || i === 'optional') && typeof this[i] === 'function') {
this[i](schema, candidate);
}
}, this);
this._customFields.forEach(function (i) {
if (i in schema && typeof this._custom[i] === 'function') {
this._custom[i].call(this, schema, candidate);
}
}, this);
return this;
};
Validation.prototype._validate = function (schema, candidate, callback) {
this.userCode = schema.code || null;
this.userError = schema.error || null;
this.userAlias = schema.alias || null;
this._basicFields.forEach(function (i) {
if ((i in schema || i === 'optional') && typeof this[i] === 'function') {
this[i](schema, candidate);
}
}, this);
this._customFields.forEach(function (i) {
if (i in schema && typeof this._custom[i] === 'function') {
this._custom[i].call(this, schema, candidate);
}
}, this);
return this;
};
Validation.prototype._asyncValidate = function (schema, candidate, callback) {
var self = this;
this.userCode = schema.code || null;
this.userError = schema.error || null;
this.userAlias = schema.alias || null;
Validation.prototype._asyncValidate = function (schema, candidate, callback) {
var self = this;
this.userCode = schema.code || null;
this.userError = schema.error || null;
this.userAlias = schema.alias || null;
async.series([
function (next) {
async.eachSeries(Object.keys(_validationAttribut), function (i, done) {
async.nextTick(function () {
if ((i in schema || i === 'optional') && typeof self[i] === 'function') {
if (self[i].length > 2) {
return self[i](schema, candidate, done);
}
self[i](schema, candidate);
}
done();
});
}, next);
},
function (next) {
async.eachSeries(Object.keys(self._custom), function (i, done) {
async.nextTick(function () {
if (i in schema && typeof self._custom[i] === 'function') {
if (self._custom[i].length > 2) {
return self._custom[i].call(self, schema, candidate, done);
}
self._custom[i].call(self, schema, candidate);
}
done();
});
}, next);
}
], callback);
};
async.series([
function (next) {
async.eachSeries(Object.keys(_validationAttribut), function (i, done) {
async.nextTick(function () {
if ((i in schema || i === 'optional') && typeof self[i] === 'function') {
if (self[i].length > 2) {
return self[i](schema, candidate, done);
}
self[i](schema, candidate);
}
done();
});
}, next);
},
function (next) {
async.eachSeries(Object.keys(self._custom), function (i, done) {
async.nextTick(function () {
if (i in schema && typeof self._custom[i] === 'function') {
if (self._custom[i].length > 2) {
return self._custom[i].call(self, schema, candidate, done);
}
self._custom[i].call(self, schema, candidate);
}
done();
});
}, next);
}
], callback);
};
// Sanitization ----------------------------------------------------------------
// functions called by _sanitization.type method.
var _forceType = {
number: function (post, schema) {
var n;
if (typeof post === 'number') {
return post;
} else if (post === '') {
if (typeof schema.def !== 'undefined') {
return schema.def;
}
return null;
} else if (typeof post === 'string') {
n = parseFloat(post.replace(/,/g, '.').replace(/ /g, ''));
if (typeof n === 'number') {
return n;
}
} else if (post instanceof Date) {
return +post;
}
return null;
},
integer: function (post, schema) {
var n;
if (typeof post === 'number' && post % 1 === 0) {
return post;
} else if (post === '') {
if (typeof schema.def !== 'undefined') {
return schema.def;
}
return null;
} else if (typeof post === 'string') {
n = parseInt(post.replace(/ /g, ''), 10);
if (typeof n === 'number') {
return n;
}
} else if (typeof post === 'number') {
return parseInt(post, 10);
} else if (typeof post === 'boolean') {
if (post) { return 1; }
return 0;
} else if (post instanceof Date) {
return +post;
}
return null;
},
string: function (post, schema) {
if (typeof post === 'boolean' || typeof post === 'number' || post instanceof Date) {
return post.toString();
} else if (_typeIs.array(post)) {
// If user authorize array and strings...
if (schema.items || schema.properties) {
return post;
}
return post.join(String(schema.joinWith || ','));
} else if (post instanceof Object) {
// If user authorize objects ans strings...
if (schema.items || schema.properties) {
return post;
}
return JSON.stringify(post);
} else if (typeof post === 'string' && post.length) {
return post;
}
return null;
},
date: function (post, schema) {
if (post instanceof Date) {
return post;
} else {
var d = new Date(post);
if (!isNaN(d.getTime())) { // if valid date
return d;
}
}
return null;
},
boolean: function (post, schema) {
if (typeof post === 'undefined') return null;
if (typeof post === 'string' && post.toLowerCase() === 'false') return false;
return !!post;
},
object: function (post, schema) {
if (typeof post !== 'string' || _typeIs.object(post)) {
return post;
}
try {
return JSON.parse(post);
} catch (e) {
return null;
}
},
array: function (post, schema) {
if (_typeIs.array(post)) {
return post;
}
if (typeof post === 'undefined') {
return null;
}
if (typeof post === 'string') {
if (post.substring(0, 1) === '[' && post.slice(-1) === ']') {
try {
return JSON.parse(post);
} catch (e) {
return null;
}
}
return post.split(String(schema.splitWith || ','));
}
if (!_typeIs.array(post)) {
return [post];
}
return null;
}
};
// Sanitization ----------------------------------------------------------------
// functions called by _sanitization.type method.
var _forceType = {
number: function (post, schema) {
var n;
if (typeof post === 'number') {
return post;
}
else if (post === '') {
if (typeof schema.def !== 'undefined')
return schema.def;
return null;
}
else if (typeof post === 'string') {
n = parseFloat(post.replace(/,/g, '.').replace(/ /g, ''));
if (typeof n === 'number') {
return n;
}
}
else if (post instanceof Date) {
return +post;
}
return null;
},
integer: function (post, schema) {
var n;
if (typeof post === 'number' && post % 1 === 0) {
return post;
}
else if (post === '') {
if (typeof schema.def !== 'undefined')
return schema.def;
return null;
}
else if (typeof post === 'string') {
n = parseInt(post.replace(/ /g, ''), 10);
if (typeof n === 'number') {
return n;
}
}
else if (typeof post === 'number') {
return parseInt(post, 10);
}
else if (typeof post === 'boolean') {
if (post) { return 1; }
return 0;
}
else if (post instanceof Date) {
return +post;
}
return null;
},
string: function (post, schema) {
if (typeof post === 'boolean' || typeof post === 'number' || post instanceof Date) {
return post.toString();
}
else if (_typeIs.array(post)) {
// If user authorize array and strings...
if (schema.items || schema.properties)
return post;
return post.join(String(schema.joinWith || ','));
}
else if (post instanceof Object) {
// If user authorize objects ans strings...
if (schema.items || schema.properties)
return post;
return JSON.stringify(post);
}
else if (typeof post === 'string' && post.length) {
return post;
}
return null;
},
date: function (post, schema) {
if (post instanceof Date) {
return post;
}
else {
var d = new Date(post);
if (!isNaN(d.getTime())) { // if valid date
return d;
}
}
return null;
},
boolean: function (post, schema) {
if (typeof post === 'undefined') return null;
if (typeof post === 'string' && post.toLowerCase() === 'false') return false;
return !!post;
},
object: function (post, schema) {
if (typeof post !== 'string' || _typeIs.object(post)) {
return post;
}
try {
return JSON.parse(post);
}
catch (e) {
return null;
}
},
array: function (post, schema) {
if (_typeIs.array(post))
return post;
if (typeof post === 'undefined')
return null;
if (typeof post === 'string') {
if (post.substring(0,1) === '[' && post.slice(-1) === ']') {
try {
return JSON.parse(post);
}
catch (e) {
return null;
}
}
return post.split(String(schema.splitWith || ','));
var _applyRules = {
upper: function (post) {
return post.toUpperCase();
},
lower: function (post) {
return post.toLowerCase();
},
title: function (post) {
// Fix by seb (replace \w\S* by \S* => exemple : coucou ça va)
return post.replace(/\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
},
capitalize: function (post) {
return post.charAt(0).toUpperCase() + post.substr(1).toLowerCase();
},
ucfirst: function (post) {
return post.charAt(0).toUpperCase() + post.substr(1);
},
trim: function (post) {
return post.trim();
}
};
}
if (!_typeIs.array(post))
return [ post ];
return null;
}
};
// Every function return the future value of each property. Therefore you
// have to return post even if you do not change its value
var _sanitizationAttribut = {
strict: function (schema, post) {
if (typeof schema.strict === 'string') { schema.strict = (schema.strict === 'true'); }
if (schema.strict !== true) {
return post;
}
if (!_typeIs.object(schema.properties)) {
return post;
}
if (!_typeIs.object(post)) {
return post;
}
Object.keys(post).forEach(function (key) {
if (!(key in schema.properties)) {
delete post[key];
}
});
return post;
},
optional: function (schema, post) {
var opt = typeof schema.optional === 'boolean' ? schema.optional : (schema.optional !== 'false'); // Default: true
if (opt === true) {
return post;
}
if (typeof post !== 'undefined') {
return post;
}
this.report();
if (schema.def === Date) {
return new Date();
}
return schema.def;
},
type: function (schema, post) {
// if (_typeIs['object'](post) || _typeIs.array(post)) {
// return post;
// }
if (typeof schema.type !== 'string' || typeof _forceType[schema.type] !== 'function') {
return post;
}
var n;
var opt = typeof schema.optional === 'boolean' ? schema.optional : true;
if (typeof _forceType[schema.type] === 'function') {
n = _forceType[schema.type](post, schema);
if ((n === null && !opt) || (!n && isNaN(n)) || (n === null && schema.type === 'string')) {
n = schema.def;
}
} else if (!opt) {
n = schema.def;
}
if ((n != null || (typeof schema.def !== 'undefined' && schema.def === n)) && n !== post) {
this.report();
return n;
}
return post;
},
rules: function (schema, post) {
var rules = schema.rules;
if (typeof post !== 'string' || (typeof rules !== 'string' && !_typeIs.array(rules))) {
return post;
}
var modified = false;
(_typeIs.array(rules) ? rules : [rules]).forEach(function (rule) {
if (typeof _applyRules[rule] === 'function') {
post = _applyRules[rule](post);
modified = true;
}
});
if (modified) {
this.report();
}
return post;
},
min: function (schema, post) {
var postTest = Number(post);
if (isNaN(postTest)) {
return post;
}
var min = Number(schema.min);
if (isNaN(min)) {
return post;
}
if (postTest < min) {
this.report();
return min;
}
return post;
},
max: function (schema, post) {
var postTest = Number(post);
if (isNaN(postTest)) {
return post;
}
var max = Number(schema.max);
if (isNaN(max)) {
return post;
}
if (postTest > max) {
this.report();
return max;
}
return post;
},
minLength: function (schema, post) {
var limit = Number(schema.minLength);
if (typeof post !== 'string' || isNaN(limit) || limit < 0) {
return post;
}
var str = '';
var gap = limit - post.length;
if (gap > 0) {
for (var i = 0; i < gap; i++) {
str += '-';
}
this.report();
return post + str;
}
return post;
},
maxLength: function (schema, post) {
var limit = Number(schema.maxLength);
if (typeof post !== 'string' || isNaN(limit) || limit < 0) {
return post;
}
if (post.length > limit) {
this.report();
return post.slice(0, limit);
}
return post;
},
properties: function (schema, post, callback) {
if (typeof callback === 'function') {
return this.asyncProperties(schema, post, callback);
}
if (!post || typeof post !== 'object') {
return post;
}
var properties = schema.properties;
var tmp;
var i;
if (typeof properties['*'] !== 'undefined') {
for (i in post) {
if (i in properties) {
continue;
}
this._deeperObject(i);
tmp = this._sanitize(properties['*'], post[i]);
if (typeof tmp !== 'undefined' || 'exec' in properties['*']) {
post[i] = tmp;
}
this._back();
}
}
for (i in properties) {
if (i !== '*') {
this._deeperObject(i);
tmp = this._sanitize(properties[i], post[i]);
if (typeof tmp !== 'undefined' || 'exec' in properties[i]) {
post[i] = tmp;
}
this._back();
}
}
return post;
},
items: function (schema, post, callback) {
if (typeof callback === 'function') {
return this.asyncItems(schema, post, callback);
}
if (!(schema.items instanceof Object) || !(post instanceof Object)) {
return post;
}
var i;
if (_typeIs.array(schema.items) && _typeIs.array(post)) {
var minLength = schema.items.length < post.length ? schema.items.length : post.length;
for (i = 0; i < minLength; i++) {
this._deeperArray(i);
post[i] = this._sanitize(schema.items[i], post[i]);
this._back();
}
} else {
for (i in post) {
if (Object.prototype.hasOwnProperty.call(post, i)) {
this._deeperArray(i);
post[i] = this._sanitize(schema.items, post[i]);
this._back();
}
}
}
return post;
},
exec: function (schema, post, callback) {
if (typeof callback === 'function') {
return this.asyncExec(schema, post, callback);
}
var execs = _typeIs.array(schema.exec) ? schema.exec : [schema.exec];
var _applyRules = {
upper: function (post) {
return post.toUpperCase();
},
lower: function (post) {
return post.toLowerCase();
},
title: function (post) {
// Fix by seb (replace \w\S* by \S* => exemple : coucou ça va)
return post.replace(/\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
},
capitalize: function (post) {
return post.charAt(0).toUpperCase() + post.substr(1).toLowerCase();
},
ucfirst: function (post) {
return post.charAt(0).toUpperCase() + post.substr(1);
},
trim: function (post) {
return post.trim();
}
};
execs.forEach(function (exec) {
if (typeof exec === 'function') {
post = exec.call(this, schema, post);
}
}, this);
return post;
}
};
// Every function return the future value of each property. Therefore you
// have to return post even if you do not change its value
var _sanitizationAttribut = {
strict: function (schema, post) {
if (typeof schema.strict === 'string') { schema.strict = (schema.strict === 'true'); }
if (schema.strict !== true)
return post;
if (!_typeIs.object(schema.properties))
return post;
if (!_typeIs.object(post))
return post;
var that = this;
Object.keys(post).forEach(function (key) {
if (!(key in schema.properties)) {
delete post[key];
}
});
return post;
},
optional: function (schema, post) {
var opt = typeof schema.optional === 'boolean' ? schema.optional : (schema.optional !== 'false'); // Default: true
if (opt === true) {
return post;
}
if (typeof post !== 'undefined') {
return post;
}
this.report();
if (schema.def === Date) {
return new Date();
}
return schema.def;
},
type: function (schema, post) {
// if (_typeIs['object'](post) || _typeIs.array(post)) {
// return post;
// }
if (typeof schema.type !== 'string' || typeof _forceType[schema.type] !== 'function') {
return post;
}
var n;
var opt = typeof schema.optional === 'boolean' ? schema.optional : true;
if (typeof _forceType[schema.type] === 'function') {
n = _forceType[schema.type](post, schema);
if ((n === null && !opt) || (!n && isNaN(n)) || (n === null && schema.type === 'string')) {
n = schema.def;
}
}
else if (!opt) {
n = schema.def;
}
if ((n != null || (typeof schema.def !== 'undefined' && schema.def === n)) && n !== post) {
this.report();
return n;
}
return post;
},
rules: function (schema, post) {
var rules = schema.rules;
if (typeof post !== 'string' || (typeof rules !== 'string' && !_typeIs.array(rules))) {
return post;
}
var modified = false;
(_typeIs.array(rules) ? rules : [rules]).forEach(function (rule) {
if (typeof _applyRules[rule] === 'function') {
post = _applyRules[rule](post);
modified = true;
}
});
if (modified) {
this.report();
}
return post;
},
min: function (schema, post) {
var postTest = Number(post);
if (isNaN(postTest)) {
return post;
}
var min = Number(schema.min);
if (isNaN(min)) {
return post;
}
if (postTest < min) {
this.report();
return min;
}
return post;
},
max: function (schema, post) {
var postTest = Number(post);
if (isNaN(postTest)) {
return post;
}
var max = Number(schema.max);
if (isNaN(max)) {
return post;
}
if (postTest > max) {
this.report();
return max;
}
return post;
},
minLength: function (schema, post) {
var limit = Number(schema.minLength);
if (typeof post !== 'string' || isNaN(limit) || limit < 0) {
return post;
}
var str = '';
var gap = limit - post.length;
if (gap > 0) {
for (var i = 0; i < gap; i++) {
str += '-';
}
this.report();
return post + str;
}
return post;
},
maxLength: function (schema, post) {
var limit = Number(schema.maxLength);
if (typeof post !== 'string' || isNaN(limit) || limit < 0) {
return post;
}
if (post.length > limit) {
this.report();
return post.slice(0, limit);
}
return post;
},
properties: function (schema, post, callback) {
if (typeof callback === 'function') {
return this.asyncProperties(schema, post, callback);
}
if (!post || typeof post !== 'object') {
return post;
}
var properties = schema.properties;
var tmp;
var i;
if (typeof properties['*'] !== 'undefined') {
for (i in post) {
if (i in properties) {
continue;
}
this._deeperObject(i);
tmp = this._sanitize(schema.properties['*'], post[i]);
if (typeof tmp !== 'undefined') {
post[i]= tmp;
}
this._back();
}
}
for (i in schema.properties) {
if (i !== '*') {
this._deeperObject(i);
tmp = this._sanitize(schema.properties[i], post[i]);
if (typeof tmp !== 'undefined') {
post[i]= tmp;
}
this._back();
}
}
return post;
},
items: function (schema, post, callback) {
if (typeof callback === 'function') {
return this.asyncItems(schema, post, callback);
}
if (!(schema.items instanceof Object) || !(post instanceof Object)) {
return post;
}
var i;
if (_typeIs.array(schema.items) && _typeIs.array(post)) {
var minLength = schema.items.length < post.length ? schema.items.length : post.length;
for (i = 0; i < minLength; i++) {
this._deeperArray(i);
post[i] = this._sanitize(schema.items[i], post[i]);
this._back();
}
}
else {
for (i in post) {
if (Object.prototype.hasOwnProperty.call(post, i)) {
this._deeperArray(i);
post[i] = this._sanitize(schema.items, post[i]);
this._back();
}
}
}
return post;
},
exec: function (schema, post, callback) {
if (typeof callback === 'function') {
return this.asyncExec(schema, post, callback);
}
var execs = _typeIs.array(schema.exec) ? schema.exec : [schema.exec];
var _asyncSanitizationAttribut = {
asyncExec: function (schema, post, callback) {
var self = this;
var execs = _typeIs.array(schema.exec) ? schema.exec : [schema.exec];
execs.forEach(function (exec) {
if (typeof exec === 'function') {
post = exec.call(this, schema, post);
}
}, this);
return post;
}
};
async.eachSeries(execs, function (exec, done) {
if (typeof exec === 'function') {
if (exec.length > 2) {
return exec.call(self, schema, post, function (err, res) {
if (err) {
return done(err);
}
post = res;
done();
});
}
post = exec.call(self, schema, post);
}
done();
}, function (err) {
callback(err, post);
});
},
asyncProperties: function (schema, post, callback) {
if (!post || typeof post !== 'object') {
return callback(null, post);
}
var self = this;
var properties = schema.properties;
var _asyncSanitizationAttribut = {
asyncExec: function (schema, post, callback) {
var self = this;
var execs = _typeIs.array(schema.exec) ? schema.exec : [schema.exec];
async.series([
function (next) {
if (properties['*'] == null) {
return next();
}
var globing = properties['*'];
async.eachSeries(Object.keys(post), function (i, next) {
if (i in properties) {
return next();
}
self._deeperObject(i);
self._asyncSanitize(globing, post[i], function (err, res) {
if (err) { /* Error can safely be ignored here */ }
if (typeof res !== 'undefined') {
post[i] = res;
}
self._back();
next();
});
}, next);
},
function (next) {
async.eachSeries(Object.keys(properties), function (i, next) {
if (i === '*') {
return next();
}
self._deeperObject(i);
self._asyncSanitize(properties[i], post[i], function (err, res) {
if (err) {
return next(err);
}
if (typeof res !== 'undefined') {
post[i] = res;
}
self._back();
next();
});
}, next);
}
], function (err) {
return callback(err, post);
});
},
asyncItems: function (schema, post, callback) {
if (!(schema.items instanceof Object) || !(post instanceof Object)) {
return callback(null, post);
}
var self = this;
var items = schema.items;
if (_typeIs.array(items) && _typeIs.array(post)) {
var minLength = items.length < post.length ? items.length : post.length;
async.timesSeries(minLength, function (i, next) {
self._deeperArray(i);
self._asyncSanitize(items[i], post[i], function (err, res) {
if (err) {
return next(err);
}
post[i] = res;
self._back();
next();
});
}, function (err) {
callback(err, post);
});
} else {
async.eachSeries(Object.keys(post), function (key, next) {
self._deeperArray(key);
self._asyncSanitize(items, post[key], function (err, res) {
if (err) {
return next();
}
post[key] = res;
self._back();
next();
});
}, function (err) {
callback(err, post);
});
}
return post;
}
};
async.eachSeries(execs, function (exec, done) {
if (typeof exec === 'function') {
if (exec.length > 2) {
return exec.call(self, schema, post, function (err, res) {
if (err) {
return done(err);
}
post = res;
done();
});
}
post = exec.call(self, schema, post);
}
done();
}, function (err) {
callback(err, post);
});
},
asyncProperties: function (schema, post, callback) {
if (!post || typeof post !== 'object') {
return callback(null, post);
}
var self = this;
var properties = schema.properties;
// Sanitization Class --------------------------------------------------------
// inherits from Inspection class (actually we just call Inspection
// constructor with the new context, because its prototype is empty
function Sanitization(schema, custom) {
Inspection.prototype.constructor.call(this, schema, _merge(Sanitization.custom, custom));
var _reporting = [];
async.series([
function (next) {
if (properties['*'] == null) {
return next();
}
var globing = properties['*'];
async.eachSeries(Object.keys(post), function (i, next) {
if (i in properties) {
return next();
}
self._deeperObject(i);
self._asyncSanitize(globing, post[i], function (err, res) {
if (err) { /* Error can safely be ignored here */ }
if (typeof res !== 'undefined') {
post[i] = res;
}
self._back();
next();
});
}, next);
},
function (next) {
async.eachSeries(Object.keys(properties), function (i, next) {
if (i === '*') {
return next();
}
self._deeperObject(i);
self._asyncSanitize(properties[i], post[i], function (err, res) {
if (err) {
return next(err);
}
if (typeof res !== 'undefined') {
post[i] = res;
}
self._back();
next();
});
}, next);
}
], function (err) {
return callback(err, post);
});
},
asyncItems: function (schema, post, callback) {
if (!(schema.items instanceof Object) || !(post instanceof Object)) {
return callback(null, post);
}
var self = this;
var items = schema.items;
if (_typeIs.array(items) && _typeIs.array(post)) {
var minLength = items.length < post.length ? items.length : post.length;
async.timesSeries(minLength, function (i, next) {
self._deeperArray(i);
self._asyncSanitize(items[i], post[i], function (err, res) {
if (err) {
return next(err);
}
post[i] = res;
self._back();
next();
});
}, function (err) {
callback(err, post);
});
}
else {
async.eachSeries(Object.keys(post), function (key, next) {
self._deeperArray(key);
self._asyncSanitize(items, post[key], function (err, res) {
if (err) {
return next();
}
post[key] = res;
self._back();
next();
});
}, function (err) {
callback(err, post);
});
}
return post;
}
};
this._basicFields = Object.keys(_sanitizationAttribut);
this._customFields = Object.keys(this._custom);
this.origin = null;
// Sanitization Class --------------------------------------------------------
// inherits from Inspection class (actually we just call Inspection
// constructor with the new context, because its prototype is empty
function Sanitization(schema, custom) {
Inspection.prototype.constructor.call(this, schema, _merge(Sanitization.custom, custom));
var _reporting = [];
this.report = function (message) {
var newNot = {
message: message || 'was sanitized',
property: this.userAlias ? (this.userAlias + ' (' + this._dumpStack() + ')') : this._dumpStack()
};
if (!_reporting.some(function (e) { return e.property === newNot.property; })) {
_reporting.push(newNot);
}
};
this._basicFields = Object.keys(_sanitizationAttribut);
this._customFields = Object.keys(this._custom);
this.origin = null;
this.result = function (data) {
// For old IE.
/* eslint-disable object-shorthand */
return {
data: data,
reporting: _reporting,
format: function () {
return this.reporting.map(function (i) {
return 'Property ' + i.property + ' ' + i.message;
}).join('\n');
}
};
/* eslint-enable object-shorthand */
};
}
this.report = function (message) {
var newNot = {
message: message || 'was sanitized',
property: this.userAlias ? (this.userAlias + ' (' + this._dumpStack() + ')') : this._dumpStack()
};
if (!_reporting.some(function (e) { return e.property === newNot.property; })) {
_reporting.push(newNot);
}
};
_extend(Sanitization.prototype, _sanitizationAttribut);
_extend(Sanitization.prototype, _asyncSanitizationAttribut);
_extend(Sanitization, new Customisable());
this.result = function (data) {
return {
data: data,
reporting: _reporting,
format: function () {
return this.reporting.map(function (i) {
return 'Property ' + i.property + ' ' + i.message;
}).join('\n');
}
};
};
}
Sanitization.prototype.sanitize = function (post, callback) {
this.origin = post;
if (typeof callback === 'function') {
var self = this;
return this._asyncSanitize(this._schema, post, function (err, data) {
self.origin = null;
callback(err, self.result(data));
});
}
var data = this._sanitize(this._schema, post);
this.origin = null;
return this.result(data);
};
_extend(Sanitization.prototype, _sanitizationAttribut);
_extend(Sanitization.prototype, _asyncSanitizationAttribut);
_extend(Sanitization, new Customisable());
Sanitization.prototype._sanitize = function (schema, post) {
this.userAlias = schema.alias || null;
this._basicFields.forEach(function (i) {
if ((i in schema || i === 'optional') && typeof this[i] === 'function') {
post = this[i](schema, post);
}
}, this);
this._customFields.forEach(function (i) {
if (i in schema && typeof this._custom[i] === 'function') {
post = this._custom[i].call(this, schema, post);
}
}, this);
return post;
};
Sanitization.prototype._asyncSanitize = function (schema, post, callback) {
var self = this;
this.userAlias = schema.alias || null;
Sanitization.prototype.sanitize = function (post, callback) {
this.origin = post;
if (typeof callback === 'function') {
var self = this;
return this._asyncSanitize(this._schema, post, function (err, data) {
self.origin = null;
callback(err, self.result(data));
});
}
var data = this._sanitize(this._schema, post);
this.origin = null;
return this.result(data);
};
async.waterfall([
function (next) {
async.reduce(self._basicFields, post, function (value, i, next) {
async.nextTick(function () {
if ((i in schema || i === 'optional') && typeof self[i] === 'function') {
if (self[i].length > 2) {
return self[i](schema, value, next);
}
value = self[i](schema, value);
}
next(null, value);
});
}, next);
},
function (inter, next) {
async.reduce(self._customFields, inter, function (value, i, next) {
async.nextTick(function () {
if (i in schema && typeof self._custom[i] === 'function') {
if (self._custom[i].length > 2) {
return self._custom[i].call(self, schema, value, next);
}
value = self._custom[i].call(self, schema, value);
}
next(null, value);
});
}, next);
}
], callback);
};
Sanitization.prototype._sanitize = function (schema, post) {
this.userAlias = schema.alias || null;
this._basicFields.forEach(function (i) {
if ((i in schema || i === 'optional') && typeof this[i] === 'function') {
post = this[i](schema, post);
}
}, this);
this._customFields.forEach(function (i) {
if (i in schema && typeof this._custom[i] === 'function') {
post = this._custom[i].call(this, schema, post);
}
}, this);
return post;
};
// ---------------------------------------------------------------------------
Sanitization.prototype._asyncSanitize = function (schema, post, callback) {
var self = this;
this.userAlias = schema.alias || null;
var INT_MIN = -2147483648;
var INT_MAX = 2147483647;
async.waterfall([
function (next) {
async.reduce(self._basicFields, post, function (value, i, next) {
async.nextTick(function () {
if ((i in schema || i === 'optional') && typeof self[i] === 'function') {
if (self[i].length > 2) {
return self[i](schema, value, next);
}
value = self[i](schema, value);
}
next(null, value);
});
}, next);
},
function (inter, next) {
async.reduce(self._customFields, inter, function (value, i, next) {
async.nextTick(function () {
if (i in schema && typeof self._custom[i] === 'function') {
if (self._custom[i].length > 2) {
return self._custom[i].call(self, schema, value, next);
}
value = self._custom[i].call(self, schema, value);
}
next(null, value);
});
}, next);
}
], callback);
};
var _rand = {
int: function (min, max) {
return min + (0 | Math.random() * (max - min + 1));
},
float: function (min, max) {
return (Math.random() * (max - min) + min);
},
bool: function () {
return (Math.random() > 0.5);
},
char: function (min, max) {
return String.fromCharCode(this.int(min, max));
},
fromList: function (list) {
return list[this.int(0, list.length - 1)];
}
};
// ---------------------------------------------------------------------------
var _formatSample = {
'date-time': function () {
return new Date().toISOString();
},
date: function () {
return new Date().toISOString().replace(/T.*$/, '');
},
time: function () {
return new Date().toLocaleTimeString({}, { hour12: false });
},
color: function (min, max) {
var s = '#';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('0123456789abcdefABCDEF');
}
return s;
},
numeric: function () {
return '' + _rand.int(0, INT_MAX);
},
integer: function () {
if (_rand.bool() === true) {
return '-' + this.numeric();
}
return this.numeric();
},
decimal: function () {
return this.integer() + '.' + this.numeric();
},
alpha: function (min, max) {
var s = '';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
}
return s;
},
alphaNumeric: function (min, max) {
var s = '';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
}
return s;
},
alphaDash: function (min, max) {
var s = '';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('_-abcdefghijklmnopqrstuvwxyz_-ABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789_-');
}
return s;
},
javascript: function (min, max) {
var s = _rand.fromList('_$abcdefghijklmnopqrstuvwxyz_$ABCDEFGHIJKLMNOPQRSTUVWXYZ_$');
for (var i = 0, l = _rand.int(min, max - 1); i < l; i++) {
s += _rand.fromList('_$abcdefghijklmnopqrstuvwxyz_$ABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789_$');
}
return s;
}
};
var INT_MIN = -2147483648;
var INT_MAX = 2147483647;
function _getLimits(schema) {
var min = INT_MIN;
var max = INT_MAX;
var _rand = {
int: function (min, max) {
return min + (0 | Math.random() * (max - min + 1));
},
float: function (min, max) {
return (Math.random() * (max - min) + min);
},
bool: function () {
return (Math.random() > 0.5);
},
char: function (min, max) {
return String.fromCharCode(this.int(min, max));
},
fromList: function (list) {
return list[this.int(0, list.length - 1)];
}
};
if (schema.gte != null) {
min = schema.gte;
} else if (schema.gt != null) {
min = schema.gt + 1;
}
if (schema.lte != null) {
max = schema.lte;
} else if (schema.lt != null) {
max = schema.lt - 1;
}
// For old IE.
/* eslint-disable object-shorthand */
return { min: min, max: max };
/* eslint-enable object-shorthand */
}
var _formatSample = {
'date-time': function () {
return new Date().toISOString();
},
'date': function () {
return new Date().toISOString().replace(/T.*$/, '');
},
'time': function () {
return new Date().toLocaleTimeString({}, { hour12: false });
},
'color': function (min, max) {
var s = '#';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('0123456789abcdefABCDEF');
}
return s;
},
'numeric': function () {
return '' + _rand.int(0, INT_MAX);
},
'integer': function () {
if (_rand.bool() === true) {
return '-' + this.numeric();
}
return this.numeric();
},
'decimal': function () {
return this.integer() + '.' + this.numeric();
},
'alpha': function (min, max) {
var s = '';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
}
return s;
},
'alphaNumeric': function (min, max) {
var s = '';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
}
return s;
},
'alphaDash': function (min, max) {
var s = '';
if (min < 1) {
min = 1;
}
for (var i = 0, l = _rand.int(min, max); i < l; i++) {
s += _rand.fromList('_-abcdefghijklmnopqrstuvwxyz_-ABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789_-');
}
return s;
},
'javascript': function (min, max) {
var s = _rand.fromList('_$abcdefghijklmnopqrstuvwxyz_$ABCDEFGHIJKLMNOPQRSTUVWXYZ_$');
for (var i = 0, l = _rand.int(min, max - 1); i < l; i++) {
s += _rand.fromList('_$abcdefghijklmnopqrstuvwxyz_$ABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789_$');
}
return s;
}
};
var _typeGenerator = {
string: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
var s = '';
var minLength = schema.minLength != null ? schema.minLength : 0;
var maxLength = schema.maxLength != null ? schema.maxLength : 32;
if (typeof schema.pattern === 'string' && typeof _formatSample[schema.pattern] === 'function') {
return _formatSample[schema.pattern](minLength, maxLength);
}
function _getLimits(schema) {
var min = INT_MIN;
var max = INT_MAX;
var l = schema.exactLength != null ? schema.exactLength : _rand.int(minLength, maxLength);
for (var i = 0; i < l; i++) {
s += _rand.char(32, 126);
}
return s;
},
number: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
var limit = _getLimits(schema);
var n = _rand.float(limit.min, limit.max);
if (schema.ne != null) {
var ne = _typeIs.array(schema.ne) ? schema.ne : [schema.ne];
while (ne.indexOf(n) !== -1) {
n = _rand.float(limit.min, limit.max);
}
}
return n;
},
integer: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
var limit = _getLimits(schema);
var n = _rand.int(limit.min, limit.max);
if (schema.ne != null) {
var ne = _typeIs.array(schema.ne) ? schema.ne : [schema.ne];
while (ne.indexOf(n) !== -1) {
n = _rand.int(limit.min, limit.max);
}
}
return n;
},
boolean: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
return _rand.bool();
},
null: function (schema) {
return null;
},
date: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
return new Date();
},
object: function (schema) {
var o = {};
var prop = schema.properties || {};
if (schema.gte != null) {
min = schema.gte;
}
else if (schema.gt != null) {
min = schema.gt + 1;
}
if (schema.lte != null) {
max = schema.lte;
}
else if (schema.lt != null) {
max = schema.lt - 1;
}
return { min: min, max: max };
}
for (var key in prop) {
if (Object.prototype.hasOwnProperty.call(prop, key)) {
if (prop[key].optional === true && _rand.bool() === true) {
continue;
}
if (key !== '*') {
o[key] = this.generate(prop[key]);
} else {
var rk = '__random_key_';
var randomKey = rk + 0;
var n = _rand.int(1, 9);
for (var i = 1; i <= n; i++) {
if (!(randomKey in prop)) {
o[randomKey] = this.generate(prop[key]);
}
randomKey = rk + i;
}
}
}
}
return o;
},
array: function (schema) {
var self = this;
var items = schema.items || {};
var minLength = schema.minLength != null ? schema.minLength : 0;
var maxLength = schema.maxLength != null ? schema.maxLength : 16;
var type;
var candidate;
var size;
var i;
var _typeGenerator = {
string: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
var s = '';
var minLength = schema.minLength != null ? schema.minLength : 0;
var maxLength = schema.maxLength != null ? schema.maxLength : 32;
if (typeof schema.pattern === 'string' && typeof _formatSample[schema.pattern] === 'function') {
return _formatSample[schema.pattern](minLength, maxLength);
}
if (_typeIs.array(items)) {
size = items.length;
if (schema.exactLength != null) {
size = schema.exactLength;
} else if (size < minLength) {
size = minLength;
} else if (size > maxLength) {
size = maxLength;
}
candidate = new Array(size);
type = null;
for (i = 0; i < size; i++) {
type = items[i].type || 'any';
if (_typeIs.array(type)) {
type = type[_rand.int(0, type.length - 1)];
}
candidate[i] = self[type](items[i]);
}
} else {
size = schema.exactLength != null ? schema.exactLength : _rand.int(minLength, maxLength);
candidate = new Array(size);
type = items.type || 'any';
if (_typeIs.array(type)) {
type = type[_rand.int(0, type.length - 1)];
}
for (i = 0; i < size; i++) {
candidate[i] = self[type](items);
}
}
return candidate;
},
any: function (schema) {
var fields = Object.keys(_typeGenerator);
var i = fields[_rand.int(0, fields.length - 2)];
return this[i](schema);
}
};
var l = schema.exactLength != null ? schema.exactLength : _rand.int(minLength, maxLength);
for (var i = 0; i < l; i++) {
s += _rand.char(32, 126);
}
return s;
},
number: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
var limit = _getLimits(schema);
var n = _rand.float(limit.min, limit.max);
if (schema.ne != null) {
var ne = _typeIs.array(schema.ne) ? schema.ne : [schema.ne];
while (ne.indexOf(n) !== -1) {
n = _rand.float(limit.min, limit.max);
}
}
return n;
},
integer: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
var limit = _getLimits(schema);
var n = _rand.int(limit.min, limit.max);
if (schema.ne != null) {
var ne = _typeIs.array(schema.ne) ? schema.ne : [schema.ne];
while (ne.indexOf(n) !== -1) {
n = _rand.int(limit.min, limit.max);
}
}
return n;
},
boolean: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
return _rand.bool();
},
"null": function (schema) {
return null;
},
date: function (schema) {
if (schema.eq != null) {
return schema.eq;
}
return new Date();
},
object: function (schema) {
var o = {};
var prop = schema.properties || {};
// CandidateGenerator Class (Singleton) --------------------------------------
function CandidateGenerator() {
// Maybe extends Inspection class too ?
}
for (var key in prop) {
if (Object.prototype.hasOwnProperty.call(prop, key)) {
if (prop[key].optional === true && _rand.bool() === true) {
continue;
}
if (key !== '*') {
o[key] = this.generate(prop[key]);
}
else {
var rk = '__random_key_';
var randomKey = rk + 0;
var n = _rand.int(1, 9);
for (var i = 1; i <= n; i++) {
if (!(randomKey in prop)) {
o[randomKey] = this.generate(prop[key]);
}
randomKey = rk + i;
}
}
}
}
return o;
},
array: function (schema) {
var self = this;
var items = schema.items || {};
var minLength = schema.minLength != null ? schema.minLength : 0;
var maxLength = schema.maxLength != null ? schema.maxLength : 16;
var type;
var candidate;
var size;
var i;
_extend(CandidateGenerator.prototype, _typeGenerator);
if (_typeIs.array(items)) {
size = items.length;
if (schema.exactLength != null) {
size = schema.exactLength;
}
else if (size < minLength) {
size = minLength;
}
else if (size > maxLength) {
size = maxLength;
}
candidate = new Array(size);
type = null;
for (i = 0; i < size; i++) {
type = items[i].type || 'any';
if (_typeIs.array(type)) {
type = type[_rand.int(0, type.length - 1)];
}
candidate[i] = self[type](items[i]);
}
}
else {
size = schema.exactLength != null ? schema.exactLength : _rand.int(minLength, maxLength);
candidate = new Array(size);
type = items.type || 'any';
if (_typeIs.array(type)) {
type = type[_rand.int(0, type.length - 1)];
}
for (i = 0; i < size; i++) {
candidate[i] = self[type](items);
}
}
return candidate;
},
any: function (schema) {
var fields = Object.keys(_typeGenerator);
var i = fields[_rand.int(0, fields.length - 2)];
return this[i](schema);
}
};
var _instance = null;
CandidateGenerator.instance = function () {
if (!(_instance instanceof CandidateGenerator)) {
_instance = new CandidateGenerator();
}
return _instance;
};
// CandidateGenerator Class (Singleton) --------------------------------------
function CandidateGenerator() {
// Maybe extends Inspection class too ?
}
CandidateGenerator.prototype.generate = function (schema) {
var type = schema.type || 'any';
if (_typeIs.array(type)) {
type = type[_rand.int(0, type.length - 1)];
}
return this[type](schema);
};
_extend(CandidateGenerator.prototype, _typeGenerator);
// Exports ---------------------------------------------------------------------
var SchemaInspector = {};
var _instance = null;
CandidateGenerator.instance = function () {
if (!(_instance instanceof CandidateGenerator)) {
_instance = new CandidateGenerator();
}
return _instance;
};
// if server-side (node.js) else client-side
if (typeof module !== 'undefined' && module.exports) {
module.exports = SchemaInspector;
} else {
window.SchemaInspector = SchemaInspector;
}
CandidateGenerator.prototype.generate = function (schema) {
var type = schema.type || 'any';
if (_typeIs.array(type)) {
type = type[_rand.int(0, type.length - 1)];
}
return this[type](schema);
};
SchemaInspector.newSanitization = function (schema, custom) {
return new Sanitization(schema, custom);
};
// Exports ---------------------------------------------------------------------
var SchemaInspector = {};
SchemaInspector.newValidation = function (schema, custom) {
return new Validation(schema, custom);
};
// if server-side (node.js) else client-side
if (typeof module !== 'undefined' && module.exports) {
module.exports = SchemaInspector;
}
else {
window.SchemaInspector = SchemaInspector;
}
SchemaInspector.Validation = Validation;
SchemaInspector.Sanitization = Sanitization;
SchemaInspector.newSanitization = function (schema, custom) {
return new Sanitization(schema, custom);
};
SchemaInspector.sanitize = function (schema, post, custom, callback) {
if (arguments.length === 3 && typeof custom === 'function') {
callback = custom;
custom = null;
}
return new Sanitization(schema, custom).sanitize(post, callback);
};
SchemaInspector.newValidation = function (schema, custom) {
return new Validation(schema, custom);
};
SchemaInspector.validate = function (schema, candidate, custom, callback) {
if (arguments.length === 3 && typeof custom === 'function') {
callback = custom;
custom = null;
}
return new Validation(schema, custom).validate(candidate, callback);
};
SchemaInspector.Validation = Validation;
SchemaInspector.Sanitization = Sanitization;
SchemaInspector.sanitize = function (schema, post, custom, callback) {
if (arguments.length === 3 && typeof custom === 'function') {
callback = custom;
custom = null;
}
return new Sanitization(schema, custom).sanitize(post, callback);
};
SchemaInspector.validate = function (schema, candidate, custom, callback) {
if (arguments.length === 3 && typeof custom === 'function') {
callback = custom;
custom = null;
}
return new Validation(schema, custom).validate(candidate, callback);
};
SchemaInspector.generate = function (schema, n) {
if (typeof n === 'number') {
var r = new Array(n);
for (var i = 0; i < n; i++) {
r[i] = CandidateGenerator.instance().generate(schema);
}
return r;
}
return CandidateGenerator.instance().generate(schema);
};
SchemaInspector.generate = function (schema, n) {
if (typeof n === 'number') {
var r = new Array(n);
for (var i = 0; i < n; i++) {
r[i] = CandidateGenerator.instance().generate(schema);
}
return r;
}
return CandidateGenerator.instance().generate(schema);
};
})();
{
"name": "schema-inspector",
"description": "Schema-Inspector is a powerful tool to sanitize and validate JS objects.",
"version": "2.0.1",
"version": "2.0.2",
"main": "index.js",
"author": {
"name": "Sebastien Chopin",
"url": "https://twitter.com/atinux"
"name": "Sebastien Chopin (https://twitter.com/atinux)"
},
"maintainers": [
"atinux"
"Matt Welke (https://github.com/mattwelke)"
],

@@ -22,16 +21,11 @@ "keywords": [

],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/Atinux/schema-inspector/raw/master/LICENSE"
}
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Atinux/schema-inspector.git"
"url": "https://github.com/schema-inspector/schema-inspector.git"
},
"bugs": {
"url": "https://github.com/Atinux/schema-inspector/issues"
"url": "https://github.com/schema-inspector/schema-inspector/issues"
},
"homepage": "http://atinux.github.io/schema-inspector/",
"homepage": "http://schema-inspector.github.io/schema-inspector/",
"dependencies": {

@@ -41,9 +35,10 @@ "async": "~2.6.3"

"devDependencies": {
"mocha": "^8.3.2",
"mocha": "^10.0.0",
"semistandard": "^16.0.1",
"should": "^13.2.3"
},
"scripts": {
"test": "make test"
},
"readmeFilename": "README.md"
"test": "mocha -u tdd -t 30000 -R spec",
"lint": "semistandard"
}
}
<!-- markdownlint-disable MD041 MD033 MD024 -->
[![schema-inspector logo](https://raw.githubusercontent.com/schema-inspector/schema-inspector/master/misc/schema-inspector.png)](http://schema-inspector.github.io/schema-inspector/)
# schema-inspector
![Lint workflow](https://github.com/schema-inspector/schema-inspector/actions/workflows/lint.yml/badge.svg)
![CodeQL workflow](https://github.com/schema-inspector/schema-inspector/actions/workflows/codeql-analysis.yml/badge.svg)
![Test workflow](https://github.com/schema-inspector/schema-inspector/actions/workflows/test.yml/badge.svg)
[![NPM version](https://badge.fury.io/js/schema-inspector.png)](http://badge.fury.io/js/schema-inspector)
Schema-Inspector is a powerful tool to sanitize and validate JS objects.
It's designed to work both client-side and server-side and to be scalable with allowing asynchronous and synchronous calls.
[![NPM version](https://badge.fury.io/js/schema-inspector.png)](http://badge.fury.io/js/schema-inspector)
**See a live example:** <http://schema-inspector.github.io/schema-inspector/>

@@ -26,2 +30,7 @@

## Comparison with JSON Schema
`schema-inspector` is not compatable with JSON Schema. They are two different ways to validate data.
However, the main difference is that `schema-inspector` supports sanitization of data.
## Version 2.0.0

@@ -28,0 +37,0 @@

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