contract.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. module.metadata = {
  6. "stability": "unstable"
  7. };
  8. const { validateOptions: valid } = require("../deprecated/api-utils");
  9. // Function takes property validation rules and returns function that given
  10. // an `options` object will return validated / normalized options back. If
  11. // option(s) are invalid validator will throw exception described by rules.
  12. // Returned will also have contain `rules` property with a given validation
  13. // rules and `properties` function that can be used to generate validated
  14. // property getter and setters can be mixed into prototype. For more details
  15. // see `properties` function below.
  16. function contract(rules) {
  17. function validator(options) {
  18. return valid(options || {}, rules);
  19. }
  20. validator.rules = rules
  21. validator.properties = function(modelFor) {
  22. return properties(modelFor, rules);
  23. }
  24. return validator;
  25. }
  26. exports.contract = contract
  27. // Function takes `modelFor` instance state model accessor functions and
  28. // a property validation rules and generates object with getters and setters
  29. // that can be mixed into prototype. Property accessors update model for the
  30. // given instance. If you wish to react to property updates you can always
  31. // override setters to put specific logic.
  32. function properties(modelFor, rules) {
  33. let descriptor = Object.keys(rules).reduce(function(descriptor, name) {
  34. descriptor[name] = {
  35. get: function() { return modelFor(this)[name] },
  36. set: function(value) {
  37. let change = {};
  38. change[name] = value;
  39. modelFor(this)[name] = valid(change, rules)[name];
  40. }
  41. }
  42. return descriptor
  43. }, {});
  44. return Object.create(Object.prototype, descriptor);
  45. }
  46. exports.properties = properties