|
'use strict'; |
|
|
|
|
|
var types = [ |
|
'object', |
|
'number', |
|
'string', |
|
'symbol', |
|
'boolean', |
|
'date', |
|
'function', |
|
]; |
|
|
|
function normalize(coercer, value) { |
|
var coercers = coercer; |
|
if (!Array.isArray(coercers)) { |
|
coercers = [coercer]; |
|
} |
|
|
|
var ctx = this; |
|
var args = slice(arguments, 2); |
|
|
|
|
|
var result; |
|
coercers.some(function (coercer) { |
|
var val = value; |
|
if (typeof value === 'function' && coercer !== 'function') { |
|
val = value.apply(ctx, args); |
|
} |
|
|
|
result = coerce(ctx, coercer, val); |
|
return result !== undefined; |
|
}); |
|
|
|
return result; |
|
} |
|
|
|
function coerce(ctx, coercer, value) { |
|
|
|
if (typeof coercer === 'string') { |
|
if (coerce[coercer]) { |
|
return coerce[coercer].call(ctx, value); |
|
} |
|
return typeOf(coercer, value); |
|
} |
|
|
|
|
|
if (typeof coercer === 'function') { |
|
return coercer.call(ctx, value); |
|
} |
|
|
|
throw new Error('Invalid coercer. Can only be a string or function.'); |
|
} |
|
|
|
coerce.string = function (value) { |
|
if ( |
|
value != null && |
|
typeof value === 'object' && |
|
typeof value.toString === 'function' |
|
) { |
|
value = value.toString(); |
|
} |
|
return typeOf('string', primitive(value)); |
|
}; |
|
|
|
coerce.number = function (value) { |
|
return typeOf('number', primitive(value)); |
|
}; |
|
|
|
coerce.boolean = function (value) { |
|
return typeOf('boolean', primitive(value)); |
|
}; |
|
|
|
coerce.date = function (value) { |
|
value = primitive(value); |
|
if (typeof value === 'number' && !isNaN(value) && isFinite(value)) { |
|
return new Date(value); |
|
} |
|
}; |
|
|
|
function typeOf(type, value) { |
|
if (typeof value === type) { |
|
return value; |
|
} |
|
} |
|
|
|
function primitive(value) { |
|
if ( |
|
value != null && |
|
typeof value === 'object' && |
|
typeof value.valueOf === 'function' |
|
) { |
|
value = value.valueOf(); |
|
} |
|
return value; |
|
} |
|
|
|
function slice(value, from) { |
|
return Array.prototype.slice.call(value, from); |
|
} |
|
|
|
|
|
types.forEach(function (type) { |
|
|
|
var typeArg = [type]; |
|
|
|
normalize[type] = function () { |
|
var args = slice(arguments); |
|
return normalize.apply(this, typeArg.concat(args)); |
|
}; |
|
}); |
|
|
|
module.exports = normalize; |
|
|