You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
2.7 KiB
JavaScript

"use strict";
/* TODO: Implement .unique */
/* TODO: Implement enums */
function createTypeRule(props) {
return Object.assign(props, {
_isTypeRule: true,
_constraints: [],
validate: function (validator) {
this._constraints.push({
type: "validate",
validator: validator
});
return this;
},
optional: function () {
return this.default(null);
},
default: function (value) {
this._constraints.push({
type: "default",
value: value
});
return this;
}
});
}
function createBaseTypeFunction(typeName, allowUndefined = false) {
return function (options = {}) {
return createTypeRule({
_baseType: typeName,
_options: options,
_allowUndefined: allowUndefined
});
};
}
function createCollectionTypeFunction(typeName, hasKeyType) {
if (hasKeyType) {
return function (keyType, itemType, options = {}) {
if (keyType == null || itemType == null) {
throw new Error("Must specify both a key type and a value type");
}
return createTypeRule({
_collectionType: typeName,
_itemType: itemType,
_keyType: keyType,
_options: options
});
};
} else {
return function (itemType, options = {}) {
return createTypeRule({
_collectionType: typeName,
_itemType: itemType,
_options: options
});
};
}
}
module.exports = {
_createTypeRule: createTypeRule,
string: createBaseTypeFunction("string"),
boolean: createBaseTypeFunction("boolean"),
number: createBaseTypeFunction("number"),
nothing: createBaseTypeFunction("nothing", true),
null: createBaseTypeFunction("null"),
undefined: createBaseTypeFunction("undefined", true),
instanceOf: function (constructor) {
/* TEST: Check that constructor is actually a function */
return createTypeRule({
_constructorType: constructor
});
},
setOf: createCollectionTypeFunction("set", false),
arrayOf: createCollectionTypeFunction("array", false),
mapOf: createCollectionTypeFunction("map", true),
/* TODO: Consider whether objectOf is needed/desirable at all */
// objectOf: createCollectionTypeFunction("map", true),
function: function (args, returnType) {
if (args == null) {
throw new Error("Must specify argument types when creating a function rule");
} else if (returnType == null) {
throw new Error("Must specify a return type when creating a function rule");
}
return createTypeRule({
_baseType: "guardedFunction",
_options: {
args: args,
returnType: returnType
}
});
},
slot: function () {
return createTypeRule({
_isSlotRule: true
});
},
self: function () {
return createTypeRule({
_isSelfRule: true
});
},
either: function (...types) {
return createTypeRule({
_modifierType: "either",
_types: types
});
}
};