65 lines
2.3 KiB
JavaScript
65 lines
2.3 KiB
JavaScript
var assert = require('./assert');
|
|
var isFunction = require('./isFunction');
|
|
var isArray = require('./isArray');
|
|
var mixin = require('./mixin');
|
|
var isStruct = require('./isStruct');
|
|
var isInterface = require('./isInterface');
|
|
var isObject = require('./isObject');
|
|
var refinement = require('./refinement');
|
|
var decompose = require('./decompose');
|
|
|
|
function compose(predicates, unrefinedType, name) {
|
|
var result = predicates.reduce(function (type, predicate) {
|
|
return refinement(type, predicate);
|
|
}, unrefinedType);
|
|
if (name) {
|
|
result.displayName = name;
|
|
result.meta.name = name;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function getProps(type) {
|
|
return isObject(type) ? type : type.meta.props;
|
|
}
|
|
|
|
function getDefaultProps(type) {
|
|
return isObject(type) ? null : type.meta.defaultProps;
|
|
}
|
|
|
|
function pushAll(arr, elements) {
|
|
Array.prototype.push.apply(arr, elements);
|
|
}
|
|
|
|
function extend(combinator, mixins, options) {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
assert(isFunction(combinator), function () { return 'Invalid argument combinator supplied to extend(combinator, mixins, options), expected a function'; });
|
|
assert(isArray(mixins), function () { return 'Invalid argument mixins supplied to extend(combinator, mixins, options), expected an array'; });
|
|
}
|
|
var props = {};
|
|
var prototype = {};
|
|
var predicates = [];
|
|
var defaultProps = {};
|
|
mixins.forEach(function (x, i) {
|
|
var decomposition = decompose(x);
|
|
var unrefinedType = decomposition.unrefinedType;
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
assert(isObject(unrefinedType) || isStruct(unrefinedType) || isInterface(unrefinedType), function () { return 'Invalid argument mixins[' + i + '] supplied to extend(combinator, mixins, options), expected an object, struct, interface or a refinement (of struct or interface)'; });
|
|
}
|
|
pushAll(predicates, decomposition.predicates);
|
|
mixin(props, getProps(unrefinedType));
|
|
mixin(prototype, unrefinedType.prototype);
|
|
mixin(defaultProps, getDefaultProps(unrefinedType), true);
|
|
});
|
|
options = combinator.getOptions(options);
|
|
options.defaultProps = mixin(defaultProps, options.defaultProps, true);
|
|
var result = compose(predicates, combinator(props, {
|
|
strict: options.strict,
|
|
defaultProps: options.defaultProps
|
|
}), options.name);
|
|
mixin(result.prototype, prototype);
|
|
return result;
|
|
}
|
|
|
|
module.exports = extend;
|