"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 }); } };