node-util
Version:
node.js utils
1,217 lines (915 loc) • 24.5 kB
JavaScript
;
var fs = require("fs"),
crypto = require("crypto");
var util = require("util"),
cwd = process.cwd(),
ObjectProto = Object.prototype,
toString = ObjectProto.toString,
hasOwnProperty = ObjectProto.hasOwnProperty,
defineProperty = Object.defineProperty,
slice = Array.prototype.slice,
isArray = Array.isArray,
UID_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
UID_CHARS_LENGTH = UID_CHARS.length,
SIGN_REPLACER = /\=+$/,
FORMAT_REGEX = /%[sdj%]/g;
function isEmpty(obj) {
if (obj === null || obj === undefined) return true;
if (isNumber(obj)) return false;
if (isArray(obj) || isString(obj)) return obj.length === 0;
for (var key in obj) if (has(obj, key)) return false;
return true;
}
util.isEmpty = isEmpty;
function isObject(obj) {
return obj === Object(obj);
}
util.isObject = isObject;
function isArrayLike(obj) {
return typeof(obj) === "object" && typeof(obj.length) === "number";
}
util.isArrayLike = isArrayLike;
util.isArray = isArray;
function isArguments(obj) {
return toString.call(obj) === "[object Arguments]";
}
util.isArguments = isArguments;
function isFunction(obj) {
return typeof(obj) === "function";
}
util.isFunction = isFunction;
function isString(obj) {
return toString.call(obj) === "[object String]";
}
util.isString = isString;
function isNumber(obj) {
return toString.call(obj) === "[object Number]";
}
util.isNumber = isNumber;
function isDecimal(obj) {
return isNumber(obj) && obj % 1 !== 0;
}
util.isDecimal = isDecimal;
function isInteger(obj) {
return isNumber(obj) && obj % 1 === 0;
}
util.isInteger = isInteger;
function isDate(obj) {
return toString.call(obj) === "[object Date]";
}
util.isDate = isDate;
function isRegExp(obj) {
return toString.call(obj) === "[object RegExp]";
}
util.isRegExp = isRegExp;
util.isFinite = isFinite;
util.isNaN = isNaN;
function isBoolean(obj) {
return obj === true || obj === false || toString.call(obj) === "[object Boolean]";
}
util.isBoolean = isBoolean;
function isNull(obj) {
return obj === null;
}
util.isNull = isNull;
function isUndefined(obj) {
return obj === void 0;
}
util.isUndefined = isUndefined;
function has(obj, key) {
return hasOwnProperty.call(obj, key);
}
util.has = has;
function extend(parent, child) {
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = child;
return child;
}
util.extend = extend;
function format(fmt) {
var i = 1,
args = arguments,
len = args.length;
return String(fmt).replace(FORMAT_REGEX, function(x) {
if (x === "%%") return "%";
if (i >= len) return x;
if (x === "%s") {
return String(args[i++]);
} else if (x === "%d") {
return Number(args[i++]);
} else if (x === "%j") {
try {
return JSON.stringify(args[i++]);
} catch (e) {
return "[Circular]";
}
} else {
return x;
}
});
}
util.format = format;
function invert(obj) {
var result = {};
for (key in obj) result[obj[key]] = key;
return result;
}
util.invert = invert;
function arraySubtract(obj, sub) {
var i, j;
for (i = sub.length; i--;)
for (j = obj.length; j--;) {
if (obj[i] === sub[j]) obj.splice(i, 1);
}
return obj;
}
util.arraySubtract = arraySubtract;
function flattenArray(array, out) {
isArray(out) || (out = []);
var item,
i, il;
for (i = 0, il = array.length; i < il; i++) {
if (isArray((item = array[i]))) {
flattenArray(item, out);
} else {
out.push(item);
}
}
return out;
}
util.flattenArray = flattenArray;
function unique(array, out) {
isArray(out) || (out = []);
var visted = [],
item, i = 0,
il = array.length;
for (; i < il; i++) {
if (visted.indexOf((item = array[i])) !== -1) continue;
visted.push(item);
out.push(item);
}
return out;
}
util.unique = unique;
function intersection() {
return unique(flattenArray(slice.call(arguments)));
}
util.intersection = intersection;
function prng(length) {
length || (length = 24);
var out = "",
i;
for (i = length; i--;) out += UID_CHARS[Math.floor(Math.random() * UID_CHARS_LENGTH)];
return out;
}
util.prng = prng;
function merge(obj, add) {
for (var key in add) {
if (obj[key] == undefined) obj[key] = add[key];
}
return obj;
};
util.merge = merge;
function override(obj, add) {
for (var key in add) {
if (add[key] != undefined) obj[key] = add[key];
}
return obj;
};
util.override = override;
function copy(obj) {
var out, i, il;
if (typeof(obj) !== "object") return obj;
if (isArrayLike(obj)) {
out = [];
for (i = 0, il = obj.length; i < il; i++) out.push(copy(obj[i]));
} else if (isObject(obj)) {
out = {};
for (var key in obj) out[key] = copy(obj[key]);
} else {
out = obj;
}
return out;
};
util.copy = copy;
function clear(obj) {
for (var key in obj) delete obj[key];
return obj;
};
util.clear = clear;
util.keys = Object.keys;
function each(obj, iterator, ctx) {
if (obj == null) return;
var i, il, objKeys;
if (isArrayLike(obj)) {
if (ctx) {
for (i = 0, il = obj.length; i < il; i++) {
if (iterator.call(ctx, obj[i], i, obj) === false) return;
}
} else {
for (i = 0, il = obj.length; i < il; i++) {
if (iterator(obj[i], i, obj) === false) return;
}
}
} else if (isObject(obj)) {
objKeys = keys(obj);
if (ctx) {
for (i = 0, il = objKeys.length; i < il; i++) {
if (iterator.call(ctx, obj[objKeys[i]], objKeys[i], obj) === false) return;
}
} else {
for (i = 0, il = objKeys.length; i < il; i++) {
if (iterator(obj[objKeys[i]], objKeys[i], obj) === false) return;
}
}
} else {
throw new TypeError("each(obj, iterator, ctx) obj must be ArrayLike or an Object");
}
}
util.each = each;
function async(tasks, callback) {
var i = 0;
if (!isArray(tasks) || !callback) {
tasks = slice.call(arguments);
callback = tasks.pop();
}
if (!isFunction(callback)) {
throw new TypeError("async(tasks, ..., callback) last arguments is not a function");
return;
}
function iterate(err) {
var fn = tasks[i++];
if (err || !isFunction(fn)) {
callback(err);
return;
}
try {
fn(iterate);
} catch (e) {
callback(e);
}
}
iterate();
}
util.async = async;
var escapeMap = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
},
unescapeMap = {
"&": "&",
"<": "<",
">": ">",
""": '"',
"'": "'"
},
ESCAPE_REGEX = new RegExp("[" + Object.keys(escapeMap).join("") + "]", "g"),
UNESCAPE_REGEX = new RegExp("(" + Object.keys(unescapeMap).join("|") + ")", "g");
function escape_filter(match) {
return escapeMap[match];
}
function escape(str) {
if (str == null) return "";
return ("" + str).replace(ESCAPE_REGEX, escape_filter);
}
util.escape = escape;
function unescape_filter(match) {
return unescapeMap[match];
}
function unescape(str) {
if (str == null) return "";
return ("" + str).replace(UNESCAPE_REGEX, unescape_filter);
}
util.unescape = unescape;
var queryStringParse_regexp = /\+/g;
function queryStringParse(qs, sep, eq, options) {
sep = sep || "&";
eq = eq || "=";
var obj = {},
regexp = queryStringParse_regexp,
maxKeys = 1000,
decode = decodeURIComponent,
len, i;
if (!isString(qs) || qs.length === 0) return obj;
qs = qs.split(sep);
var maxKeys = 1000;
if (options && isNumber(options.maxKeys)) {
maxKeys = options.maxKeys;
}
len = qs.length;
if (maxKeys > 0 && len > maxKeys) len = maxKeys;
if (options && isFunction(options.decodeURIComponent)) decode = options.decodeURIComponent;
for (i = 0; i < len; i++) {
var x = qs[i].replace(regexp, "%20"),
idx = x.indexOf(eq),
kstr, vstr, k, v, tmp;
if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}
try {
k = decode(kstr);
v = decode(vstr);
if ((tmp = +v)) v = tmp;
} catch (e) {
continue;
}
if (!has(obj, k)) {
obj[k] = v;
} else if (isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}
return obj;
}
util.queryStringParse = util.queryStringDecode = queryStringParse;
function stringifyPrimitive(v) {
if (isString(v)) return v;
if (isBoolean(v)) return v ? "true" : "false";
if (isNumber(v)) return isFinite(v) ? v : "";
return '';
};
function queryStringStringify(obj, sep, eq, options) {
sep = sep || "&";
eq = eq || "=";
if (isNull(obj)) {
obj = undefined;
}
var encode = encodeURIComponent;
if (options && isFunction(options.encodeURIComponent)) encode = options.encodeURIComponent;
if (isObject(obj)) {
return Object.keys(obj).map(function(k) {
var ks = encode(stringifyPrimitive(k)) + eq;
if (isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + encode(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encode(stringifyPrimitive(obj[k]));
}
}).join(sep);
}
return "";
}
util.queryStringStringify = util.queryStringEncode = queryStringStringify;
function template(text, data, settings) {
var render,
escapes = util.templateEscapes,
escaper = util.templateEscaper,
start, end, match = "([\\s\\S]+?)",
evaluate, interpolate, escape,
index = 0,
source = "__p+='";
settings = merge((settings || {}), util.templateSettings);
start = settings.start;
end = settings.end;
evaluate = start + match + end;
interpolate = start + settings.interpolate + match + end;
escape = start + settings.escape + match + end;
text.replace(new RegExp(escape + "|" + interpolate + "|" + evaluate + "|$", "g"), function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset).replace(escaper, function(match) {
return '\\' + escapes[match];
});
if (escape) source += "'+\n((__t=(" + escape + "))==null?'':escape(__t))+\n'";
if (interpolate) source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
if (evaluate) source += "';\n" + evaluate + "\n__p+='";
index = offset + match.length;
return match;
});
source += "';\n";
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join, print=function(){__p+=__j.call(arguments,'');};\n" + source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data);
function temp(data) {
return render.call(this, data);
};
temp.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
return temp;
}
util.template = template;
util.templateEscaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
util.templateSettings = {
start: "<%",
end: "%>",
interpolate: "=",
escape: "-"
};
util.templateEscapes = {
"'": "'",
"\\": "\\",
"\r": "r",
"\n": "n",
"\t": "t",
"\u2028": "u2028",
"\u2029": "u2029"
};
function renderFile(pathname, data, settings, callback) {
data || (data = {});
if (isFunction(settings)) {
callback = settings;
settings = {};
}
readFile(pathname, function(err, text) {
if (err) {
callback(err);
return;
}
var out;
try {
out = template(text, data, settings);
} catch (e) {
callback(e);
return;
}
callback(null, out);
});
}
util.renderFile = renderFile;
function uid(length) {
length || (length = 24);
var out = "",
bytes = crypto.pseudoRandomBytes(length),
i;
for (i = length; i--;) out += UID_CHARS[bytes[i] % UID_CHARS_LENGTH];
return out;
}
util.uid = uid;
function md5(str, encoding) {
return crypto.createHash("md5").update(str, "utf8").digest(encoding || "hex");
}
util.md5 = md5;
function signSecret(value, secret) {
return value + "." + crypto.createHmac("sha256", secret).update(value).digest("base64").replace(SIGN_REPLACER, "");
}
util.signSecret = signSecret;
function unsignSecret(value, secret) {
var str = value.slice(0, value.lastIndexOf("."));
return signSecret(str, secret) === value ? str : false;
}
util.unsignSecret = unsignSecret;
util.diveDefaults = {
all: false,
recursive: true,
files: true,
directories: false
};
function dive(dir, opts, action, complete) {
if (isFunction(opts)) {
complete = isFunction(action) ? action : function() {};
action = opts;
opts = {};
} else if (!isFunction(complete)) {
complete = function() {};
}
if (isString(dir)) dir = cwd;
merge(opts, util.diveDefaults);
function doDive(dir) {
fs.readdir(dir, function(err, files) {
todo--;
if (err) {
action(err);
return;
}
files.every(function(file) {
if (opts.all || file[0] !== ".") {
todo++;
var fullPath = path.resolve(dir, file);
fs.stat(fullPath, function(err, stat) {
if (err) {
todo--;
return action(err) !== false;
}
if (stat) {
if (stat.isDirectory()) {
if (opts.directories) return action(null, fullPath) !== false;
if (opts.recursive) doDive(fullPath);
} else {
if (opts.files) return action(null, fullPath) !== false;
if (!--todo) complete();
}
}
return true;
});
}
return true;
});
if (!todo) complete();
});
}
var todo = 1;
doDive(dir);
}
util.dive = dive;
function diveSync(dir, opts, action) {
if (isFunction(opts)) {
action = opts;
opts = {};
}
if (isString(dir)) dir = cwd;
merge(opts, util.diveDefaults);
function doDive(dir) {
var files;
todo--;
try {
files = fs.readdirSync(dir);
} catch (e) {
return action(e) !== false;
}
return files.every(function(file) {
if (opts.all || file[0] !== ".") {
todo++;
var fullPath = path.resolve(dir, file),
stat;
try {
stat = fs.statSync(fullPath);
} catch (e) {
todo--;
return action(e) !== false;
}
if (stat) {
if (stat.isDirectory()) {
if (opts.directories) return action(null, fullPath) !== false;
if (opts.recursive) return doDive(fullPath) !== false;
} else {
if (opts.files) return action(null, fullPath) !== false;
}
}
}
return true;
});
}
var todo = 1;
doDive(dir);
}
util.diveSync = diveSync;
function fsCopy(dir, dest) {
var stat;
dir = path.resolve(cwd, dir);
dest = path.resolve(cwd, dest);
try {
stat = fs.statSync(dir);
} catch (e) {}
if (!stat.isDirectory()) {
var buffer;
try {
buffer = fs.readFileSync(dir);
} catch (e) {
console.warn(e);
return;
}
mkdirPSync(path.dirname(dest));
fs.writeFileSync(dest, buffer);
return;
}
diveSync(dir, function(err, fullPath) {
if (err) {
console.warn(err);
return;
}
var pathName = fullPath.substring(dir.length),
buffer;
if (pathName[0] === "/") pathName = "." + pathName;
pathName = path.resolve(dest, pathName);
try {
buffer = fs.readFileSync(fullPath);
} catch (e) {
console.warn(e);
return;
}
mkdirPSync(path.dirname(pathName));
fs.writeFileSync(pathName, buffer);
});
}
util.fsCopy = fsCopy;
function mkdirP(pathName, mode, callback, made) {
if (isFunction(mode) || mode === undefined) {
callback = mode;
mode = 493;
}
if (!made) made = null;
callback || (callback = function() {});
if (isString(mode)) mode = parseInt(mode, 8);
fs.mkdir(pathName, mode, function(err) {
if (!err) {
made = made || pathName;
callback(null, made);
return;
}
switch (err.code) {
case "ENOENT":
mkdirP(path.dirname(pathName), mode, function(err, made) {
if (err) {
callback(err, made);
} else {
mkdirP(pathName, mode, callback, made);
}
});
break;
default:
fs.stat(pathName, function(er, stat) {
if (er || !stat.isDirectory()) {
callback(er, made);
} else {
callback(null, made);
}
});
break;
}
});
}
util.mkdirP = mkdirP;
function mkdirPSync(pathName, mode, made) {
mode || (mode = 493);
made || (made = null);
if (isString(mode)) mode = parseInt(mode, 8);
try {
fs.mkdirSync(pathName, mode);
made = made || pathName;
} catch (err) {
switch (err.code) {
case "ENOENT":
made = mkdirPSync(path.dirname(pathName), mode, made);
mkdirPSync(pathName, mode, made);
break;
default:
var stat;
try {
stat = fs.statSync(pathName);
} catch (err) {
throw err;
}
if (!stat.isDirectory()) throw err;
break;
}
}
return made;
}
util.mkdirPSync = mkdirPSync;
util.validator = (function() {
var EMAIL = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/,
URL = /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i,
EMPTY =/^[\s\t\r\n]*$/,
IPv4 = /^(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)$/,
IPv6 = /^::|^::1|^([a-fA-F0-9]{1,4}::?){1,7}([a-fA-F0-9]{1,4})$/,
ALPHA = /^[a-zA-Z]+$/,
ALPHA_NUMERIC = /^[a-zA-Z0-9]+$/,
NUMERIC = /^[0-9]+$/,
HEXA_DECIMAL = /^[0-9a-fA-F]+$/,
HEX_COLOR = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/,
INT = /^(?:-?(?:0|[1-9][0-9]*))$/,
DECIMAL = /^(?:-?(?:[0-9]+))?(?:\.[0-9]*)?(?:[eE][\+\-]?(?:[0-9]+))?$/,
UUID = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
UUID_V3 = /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
UUID_V4 = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
UUID_V5 = /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
REMOVE = /[^0-9]+/g,
CREDIT_CARD = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;
function toDateTime(date) {
if (date instanceof Date) return date;
var intDate = Date.parse(date);
if (isNaN(intDate)) return null;
return new Date(intDate);
}
function toDate(date) {
if (!(date instanceof Date)) date = toDateTime(date);
if (!date) return null;
return date;
}
var rules = {
email: function(str) {
return util.isString(str) && !!str.match(EMAIL);
},
empty: util.isEmpty,
notEmpty: function(str) {
return !util.isEmpty(str);
},
url: function(str) {
return util.isString(str) && !!str.match(URL);
},
ip: function(str) {
if (!util.isString(str)) return false;
if (rules.ipv4(str)) {
return true;
} else if (rules.ipv6(str)) {
return true;
}
return false;
},
ipv4: function(str) {
if (!util.isString(str)) return false;
if (IPv4.test(str)) {
if (str.split(".").sort()[3] > 255) return false;
return true;
}
return false;
},
ipv6: function(str) {
return util.isString(str) && IPv6.test(str);
},
alpha: function(str) {
return util.isString(str) && !!str.match(ALPHA);
},
alphanumeric: function(str) {
return util.isString(str) && !!str.match(ALPHA_NUMERIC);
},
hexadecimal: function(str) {
return util.isString(str) && !!str.match(HEXA_DECIMAL);
},
hexcolor: function(str) {
return util.isString(str) && !!str.match(HEX_COLOR);
},
numeric: function(str) {
return util.isNumber(str) || !!str.match(NUMERIC);
},
lowercase: function(str) {
return util.isString(str) && str === str.toLowerCase();
},
uppercase: function(str) {
return util.isString(str) && str === str.toUpperCase();
},
json: function(str) {
if (!util.isString(str)) return false;
try{
var obj = JSON.parse(str);
if (obj && util.isObject(obj) && obj !== null) {
return true;
}
} catch(e) {}
return false;
},
int: util.isInteger,
integer: util.isInteger,
intstring: function(str) {
return util.isString(str) && !!str.match(INT);
},
integerstring: function(str) {
return util.isString(str) && !!str.match(INT);
},
decimal: util.isDecimal,
float: util.isDecimal,
decimalstring: function(str) {
return util.isString(str) && !!str.match(DECIMAL);
},
floatstring: function(str) {
return util.isString(str) && !!str.match(DECIMAL);
},
number: util.isNumber,
finite: util.isFinite,
falsey: function(x) {
return x == false;
},
truthy: function(x) {
return x == true;
},
divisibleby: function(str, num) {
if (!util.isNumber(str)) return false;
if (!util.isNumber(num)) num = +num;
return str % num === 0;
},
null: function(str) {
return str === "";
},
notNull: function(str) {
return str !== "";
},
equals: function(a, b) {
return a === b;
},
contains: function(str, elem) {
return !!elem && ~str.indexOf(elem);
},
notContains: function(str, elem) {
return !!elem && str.indexOf(elem) === -1;
},
regex: function(str, pattern, modifiers) {
if (!util.isString(str)) str += '';
if (!util.isRegExp(pattern)) pattern = new RegExp(pattern, modifiers);
return !!str.match(pattern);
},
notRegex: function(str, pattern, modifiers) {
if (!util.isString(str)) str += '';
if (!util.isRegExp(pattern)) pattern = new RegExp(pattern, modifiers);
return !str.match(pattern);
},
length: function(str, min, max) {
var length = str.length;
return length >= min && (max === undefined || length <= max);
},
minLength: function(str, min) {
if (util.isString(min)) min = +min;
return str.length >= min;
},
maxLength: function(str, max) {
if (util.isString(max)) max = +max;
return str.length <= max;
},
uuid: function(str, version) {
if (!version) return UUID.test(str);
var pattern = UUID;
if (version == 3 || version === "v3") {
pattern = UUID_V3;
} else if (version == 4 || version === "v4") {
pattern = UUID_V4;
} else if (version == 5 || version === "v5") {
pattern = UUID_V5;
}
return pattern.test(str);
},
uuidv3: function(str) {
return UUID_V3.test(str);
},
uuidv4: function(str) {
return UUID_V4.test(str);
},
uuidv5: function(str) {
return UUID_V5.test(str);
},
date: function(str) {
return util.isDate(str) || !util.isNaN(Date.parse(str));
},
after: function(str, date) {
date = date || new Date();
var origDate = toDate(str),
compDate = toDate(date);
return !(origDate && compDate && origDate <= compDate);
},
before: function(str, date) {
date = date || new Date();
var origDate = toDate(str),
compDate = toDate(date);
return !(origDate && compDate && origDate >= compDate);
},
in: function(str, opts) {
if (!opts || !util.isFunction(opts.indexOf)) return false;
if (util.isArray(opts)) opts = opts.map(String);
return !!~opts.indexOf(str);
},
notIn: function(str, opts) {
if (!opts || typeof(opts.indexOf) !== "function") return false;
if (util.isArray(opts)) opts = opts.map(String);
return opts.indexOf(str) === -1;
},
min: function(str, min) {
if (util.isString(str)) str = +str;
if (util.isString(min)) min = +min;
return str <= min;
},
max: function(str, min) {
if (util.isString(str)) str = +str;
if (util.isString(min)) min = +min;
return str >= min;
},
creditcard: function(str) {
var sanitized = str.replace(REMOVE, ""),
sum = 0, digit, tmpNum, shouldDouble,
i;
if (sanitized.match(CREDIT_CARD) === null) return false;
for (i = sanitized.length - 1; i >= 0; i--) {
digit = sanitized.substring(i, (i + 1));
tmpNum = parseInt(digit, 10);
if (shouldDouble) {
tmpNum *= 2;
if (tmpNum >= 10) {
sum += ((tmpNum % 10) + 1);
}
else {
sum += tmpNum;
}
}
else {
sum += tmpNum;
}
shouldDouble = !shouldDouble;
}
if ((sum % 10) === 0) return true;
return false;
}
};
function validator(name, value) {
var rule = rules[name],
args;
if (!rule) throw new Error("Unknown Rule "+ name);
if (arguments.length > 2) {
args = slice.call(arguments, 1);
return rule.apply(rules, args);
}
return rule(value);
}
validator.rules = rules;
return validator;
}());
module.exports = util;