1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/util/contract.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,51 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +"use strict"; 1.9 + 1.10 +module.metadata = { 1.11 + "stability": "unstable" 1.12 +}; 1.13 + 1.14 +const { validateOptions: valid } = require("../deprecated/api-utils"); 1.15 + 1.16 +// Function takes property validation rules and returns function that given 1.17 +// an `options` object will return validated / normalized options back. If 1.18 +// option(s) are invalid validator will throw exception described by rules. 1.19 +// Returned will also have contain `rules` property with a given validation 1.20 +// rules and `properties` function that can be used to generate validated 1.21 +// property getter and setters can be mixed into prototype. For more details 1.22 +// see `properties` function below. 1.23 +function contract(rules) { 1.24 + function validator(options) { 1.25 + return valid(options || {}, rules); 1.26 + } 1.27 + validator.rules = rules 1.28 + validator.properties = function(modelFor) { 1.29 + return properties(modelFor, rules); 1.30 + } 1.31 + return validator; 1.32 +} 1.33 +exports.contract = contract 1.34 + 1.35 +// Function takes `modelFor` instance state model accessor functions and 1.36 +// a property validation rules and generates object with getters and setters 1.37 +// that can be mixed into prototype. Property accessors update model for the 1.38 +// given instance. If you wish to react to property updates you can always 1.39 +// override setters to put specific logic. 1.40 +function properties(modelFor, rules) { 1.41 + let descriptor = Object.keys(rules).reduce(function(descriptor, name) { 1.42 + descriptor[name] = { 1.43 + get: function() { return modelFor(this)[name] }, 1.44 + set: function(value) { 1.45 + let change = {}; 1.46 + change[name] = value; 1.47 + modelFor(this)[name] = valid(change, rules)[name]; 1.48 + } 1.49 + } 1.50 + return descriptor 1.51 + }, {}); 1.52 + return Object.create(Object.prototype, descriptor); 1.53 +} 1.54 +exports.properties = properties