diff --git a/src/create-trait.js b/src/create-trait.js index 49f952a..28ed9ad 100644 --- a/src/create-trait.js +++ b/src/create-trait.js @@ -12,14 +12,13 @@ const nullMissingFields = require("./util/null-missing-fields"); module.exports = function createTrait(name, schema, options = {}) { let schemaDescriptors = mapObj(schema, (key, rule) => { - return generateDescriptor(rule, key, true, options._registry); + return generateDescriptor(rule, key, true); }); let schemaKeys = getSchemaKeys(schema); return typeRules._createTypeRule({ _isTrait: true, - _registry: options._registry, _name: name, applyImplementation: function (implementation) { /* FIXME: Verify that there are no extraneous keys or unspecified values */ @@ -44,9 +43,9 @@ module.exports = function createTrait(name, schema, options = {}) { let implementationDescriptors = mapObj(implementation, (key, value) => { if (value != null && value._isSlotRule === true) { - return generateDescriptor(schema[key], key, true, options._registry); + return generateDescriptor(schema[key], key, true); } else { - return generateDescriptor(value, key, false, options._registry); + return generateDescriptor(value, key, false); } }); diff --git a/src/create-type.js b/src/create-type.js index 4346c48..94a6870 100644 --- a/src/create-type.js +++ b/src/create-type.js @@ -9,17 +9,16 @@ const generateValidator = require("./generate-validator"); const getSchemaKeys = require("./util/get-schema-keys"); const nullMissingFields = require("./util/null-missing-fields"); -module.exports = function createType(name, schema, options = {}) { +module.exports = function createType(name, schema) { if (schema._isTypeRule === true) { return typeRules._createTypeRule({ _typeName: name, _isTypeAlias: true, - _alias: schema, - _registry: options._registry + _alias: schema }); } else { let propertyDescriptors = mapObj(schema, (key, rule) => { - return generateDescriptor(rule, key, false, options._registry); + return generateDescriptor(rule, key, false); }); let protoProperties = { @@ -56,7 +55,6 @@ module.exports = function createType(name, schema, options = {}) { proto._type = factory; - factory._registry = options._registry; factory._schemaKeys = schemaKeys; factory._isCustomType = true; factory._name = name; diff --git a/src/generate-descriptor.js b/src/generate-descriptor.js index 25cdc57..d70b908 100644 --- a/src/generate-descriptor.js +++ b/src/generate-descriptor.js @@ -4,9 +4,9 @@ const generateValidator = require("./generate-validator"); const guardedSet = require("./guarded-collections/set"); const guardedMap = require("./guarded-collections/map"); -module.exports = function generateDescriptor(rule, key, allowSlot = false, registry) { +module.exports = function generateDescriptor(rule, key, allowSlot = false) { if (rule._isTypeRule === true) { - let validator = generateValidator(rule, key, registry); + let validator = generateValidator(rule, key); if (rule._collectionType != null) { let guardedCollectionFactory; @@ -19,8 +19,8 @@ module.exports = function generateDescriptor(rule, key, allowSlot = false, regis throw new Error(`Unknown collection type: ${rule._collectionType}`); } - let valueGuard = generateValidator(rule._itemType, undefined, registry); - let keyGuard = (rule._keyType != null) ? generateValidator(rule._keyType, undefined, registry) : null; + let valueGuard = generateValidator(rule._itemType); + let keyGuard = (rule._keyType != null) ? generateValidator(rule._keyType) : null; return [key, { enumerable: true, diff --git a/src/generate-validator.js b/src/generate-validator.js index 38f27b2..9243dab 100644 --- a/src/generate-validator.js +++ b/src/generate-validator.js @@ -12,7 +12,7 @@ const createUndefinedValidator = require("./validator-functions/undefined"); const getValueType = require("./util/get-value-type"); const errors = require("./errors"); -module.exports = function generateValidator(rule, name = "", registry) { +module.exports = function generateValidator(rule, name = "") { let baseRule; if (rule._baseType != null) { @@ -37,7 +37,7 @@ module.exports = function generateValidator(rule, name = "", registry) baseRule = () => true; /* FIXME */ } else if (rule._modifierType != null) { if (rule._modifierType === "either") { - let validators = rule._types.map((type) => generateValidator(type, undefined, registry)); + let validators = rule._types.map((type) => generateValidator(type)); baseRule = function (value) { let matched = false; @@ -60,7 +60,7 @@ module.exports = function generateValidator(rule, name = "", registry) throw new Error(`Unrecognized modifier: ${rule._modifierType}`); } } else if (rule._isTypeAlias === true) { - baseRule = generateValidator(rule._alias, name, registry); + baseRule = generateValidator(rule._alias, name); } else if (rule._isCustomType === true) { let validator = rule._validator; @@ -77,7 +77,7 @@ module.exports = function generateValidator(rule, name = "", registry) baseRule = function (value) { /* FIXME: Better error when the type is unknown */ - let actualType = registry._types.get(rule._name); + let actualType = rule._registry._types.get(rule._name); if (actualType._isCustomType) { if (actualType._validator.call(this, value) === true) { @@ -87,7 +87,7 @@ module.exports = function generateValidator(rule, name = "", registry) } } else { if (aliasValidator == null) { - aliasValidator = generateValidator(actualType._alias, name, registry); + aliasValidator = generateValidator(actualType._alias, name); } let validatorResult = aliasValidator.call(this, value); @@ -110,21 +110,17 @@ module.exports = function generateValidator(rule, name = "", registry) } }; } else if (rule._isRegistryTrait === true) { - if (registry == null) { - throw new Error("Registry-based type rules can only be used within the context of a type registry"); - } else { - baseRule = function (value) { - /* TODO: The below approach requires that traits be defined before the types that use them, and disallows trait registry references in `.implements` calls, due to _implementedTraits always needing to contain actual trait definitions; in the future, a better approach needs to be found for this such that trait registry references can be used everywhere. */ - let actualRule = registry._traits.get(rule._name); + baseRule = function (value) { + /* TODO: The below approach requires that traits be defined before the types that use them, and disallows trait registry references in `.implements` calls, due to _implementedTraits always needing to contain actual trait definitions; in the future, a better approach needs to be found for this such that trait registry references can be used everywhere. */ + let actualRule = rule._registry._traits.get(rule._name); - /* FIXME: Better error when the trait is unknown */ - if (value._type != null && value._type._implementedTraits != null && value._type._implementedTraits.has(actualRule)) { - return true; - } else { - return new errors.ValidationError(`Expected object of a type with the ${rule._name} trait, got ${getValueType(value)} instead`); - } - }; - } + /* FIXME: Better error when the trait is unknown */ + if (value._type != null && value._type._implementedTraits != null && value._type._implementedTraits.has(actualRule)) { + return true; + } else { + return new errors.ValidationError(`Expected object of a type with the ${rule._name} trait, got ${getValueType(value)} instead`); + } + }; } else if (rule._isSelfRule === true) { baseRule = function (value) { if (value instanceof this._type) { @@ -195,7 +191,7 @@ module.exports = function generateValidator(rule, name = "", registry) }); } } else { - /* FIXME: Possibly special-case (for better performance) if the only extra rule is a 'default value' rule? This would avoid a `for` loop in the case where a value is explicitly specified. */ + /* TODO: Possibly special-case (for better performance) if the only extra rule is a 'default value' rule? This would avoid a `for` loop in the case where a value is explicitly specified. */ for (let rule of rules) { let result = rule.call(this, value); diff --git a/src/guard-function.js b/src/guard-function.js index 3a8fb09..9580db5 100644 --- a/src/guard-function.js +++ b/src/guard-function.js @@ -2,12 +2,12 @@ const generateValidator = require("./generate-validator"); -module.exports = function guardFunction(args, returnType, func, _registry) { +module.exports = function guardFunction(args, returnType, func) { let rules = args.map((arg) => { - return generateValidator(arg, undefined, _registry); + return generateValidator(arg); }); - let returnValueValidator = generateValidator(returnType, undefined, _registry); + let returnValueValidator = generateValidator(returnType); let guardedFunction = function (...params) { let paramsWithDefaults = new Array(params.length); diff --git a/src/registry.js b/src/registry.js index e7c69ea..4b24935 100644 --- a/src/registry.js +++ b/src/registry.js @@ -11,11 +11,7 @@ module.exports = function createRegistry() { _traits: new Map(), createType: function (name, schema, options = {}) { if (!this._types.has(name)) { - let combinedOptions = Object.assign({ - _registry: this - }, options); - - let type = moduleAPI.createType(name, schema, combinedOptions); + let type = moduleAPI.createType(name, schema, options); this._types.set(name, type); return type; } else { @@ -24,30 +20,25 @@ module.exports = function createRegistry() { }, createTrait: function (name, schema, options = {}) { if (!this._traits.has(name)) { - let combinedOptions = Object.assign({ - _registry: this - }, options); - - let trait = moduleAPI.createTrait(name, schema, combinedOptions); + let trait = moduleAPI.createTrait(name, schema, options); this._traits.set(name, trait); return trait; } else { throw new Error(`A trait named ${name} already exists in this registry`); } }, - guardFunction: function (args, returnType, func) { - return moduleAPI.guardFunction(args, returnType, func, this); - }, type: function (typeName) { return typeRules._createTypeRule({ _isCustomRegistryType: true, - _name: typeName + _name: typeName, + _registry: this }); }, trait: function (traitName) { return typeRules._createTypeRule({ _isRegistryTrait: true, - _name: traitName + _name: traitName, + _registry: this }); }, createRegistry: undefined diff --git a/test/models.js b/test/models.js index 88a3490..80b1f97 100644 --- a/test/models.js +++ b/test/models.js @@ -5,7 +5,6 @@ const expect = require("chai").expect; const dm = require("../src"); /* FIXME: Disallow null/nothing/undefined in model definitions, as they make no semantic sense? But allow them for eg. function guards. */ -/* FIXME: Registry */ /* FIXME: Test passing an already-guarded collection into a guarded collection factory - either stand-alone or in the context of a model? */ let Identity = dm.createType("Identity", { label: dm.string(),