67 lines
2.1 KiB
JavaScript
67 lines
2.1 KiB
JavaScript
var assert = require('./assert');
|
|
var isTypeName = require('./isTypeName');
|
|
var isFunction = require('./isFunction');
|
|
var forbidNewOperator = require('./forbidNewOperator');
|
|
var isIdentity = require('./isIdentity');
|
|
var create = require('./create');
|
|
var is = require('./is');
|
|
var getTypeName = require('./getTypeName');
|
|
var getFunctionName = require('./getFunctionName');
|
|
|
|
function getDefaultName(type, predicate) {
|
|
return '{' + getTypeName(type) + ' | ' + getFunctionName(predicate) + '}';
|
|
}
|
|
|
|
function refinement(type, predicate, name) {
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
assert(isFunction(type), function () { return 'Invalid argument type ' + assert.stringify(type) + ' supplied to refinement(type, predicate, [name]) combinator (expected a type)'; });
|
|
assert(isFunction(predicate), function () { return 'Invalid argument predicate supplied to refinement(type, predicate, [name]) combinator (expected a function)'; });
|
|
assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to refinement(type, predicate, [name]) combinator (expected a string)'; });
|
|
}
|
|
|
|
var displayName = name || getDefaultName(type, predicate);
|
|
var identity = isIdentity(type);
|
|
|
|
function Refinement(value, path) {
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (identity) {
|
|
forbidNewOperator(this, Refinement);
|
|
}
|
|
path = path || [displayName];
|
|
}
|
|
|
|
var x = create(type, value, path);
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
assert(predicate(x), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/'); });
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
Refinement.meta = {
|
|
kind: 'subtype',
|
|
type: type,
|
|
predicate: predicate,
|
|
name: name,
|
|
identity: identity
|
|
};
|
|
|
|
Refinement.displayName = displayName;
|
|
|
|
Refinement.is = function (x) {
|
|
return is(x, type) && predicate(x);
|
|
};
|
|
|
|
Refinement.update = function (instance, patch) {
|
|
return Refinement(assert.update(instance, patch));
|
|
};
|
|
|
|
return Refinement;
|
|
}
|
|
|
|
refinement.getDefaultName = getDefaultName;
|
|
module.exports = refinement;
|