decorators/ModelProperties.js

/** @namespace decorators */
// @flow

/**
 * When working with `GQLBase` instances that expose properties
 * that have a 1:1 mapping to their own model property of the
 * same name, adding the getters manually can be annoying. This
 * takes an indeterminate amount of strings representing the
 * properties for which getters should be injected.
 *
 * @function Getters
 * @memberof! decorators
 *
 * @param {Array<String>} propertyNames if the model has 'name' and
 * 'age' as properties, then passing those two strings will result
 * in getters that surface those properties as GraphQL fields.
 * @return {Function} a class decorator method.s
 */
export function Getters(...propertyNames: Array<String>): Function {
  return function(target: mixed): mixed {
    for (let property of propertyNames) {
      Object.defineProperty(target.prototype, property, {
        get: function() {
          return this.model[property];
        }
      });
    }

    return target;
  }
}

/**
 * When working with `GQLBase` instances that expose properties
 * that have a 1:1 mapping to their own model property of the
 * same name, adding the setters manually can be annoying. This
 * takes an indeterminate amount of strings representing the
 * properties for which setters should be injected.
 *
 * @function Setters
 * @memberof! decorators
 *
 * @param {Array<String>} propertyNames if the model has 'name' and
 * 'age' as properties, then passing those two strings will result
 * in setters that surface those properties as GraphQL fields.
 * @return {Function} a class decorator method
 */
export function Setters(...propertyNames: Array<String>):Function {
  return function(target: mixed): mixed {
    for (let property of propertyNames) {
      Object.defineProperty(target.prototype, property, {
        set: function(value) {
          this.model[property] = value;
        }
      });
    }

    return target;
  }
}

/**
 * When working with `GQLBase` instances that expose properties
 * that have a 1:1 mapping to their own model property of the
 * same name, adding the getters manually can be annoying. This
 * takes an indeterminate amount of strings representing the
 * properties for which getters should be injected.
 *
 * This method creates both getters and setters
 *
 * @function Properties
 * @memberof! decorators
 * @since 2.1.0
 *
 * @param {Array<String>} propertyNames if the model has 'name' and
 * 'age' as properties, then passing those two strings will result
 * in getters and setters that surface those properties as GraphQL fields.
 * @return {Function} a class decorator method
 */
export function Properties(...propertyNames: Array<String>): Function {
  return function(target: mixed): mixed {
    for (let property of propertyNames) {
      Object.defineProperty(target.prototype, property, {
        set: function(value) {
          this.model[property] = value;
        },
        get: function() {
          return this.model[property];
        }
      });
    }

    return target;
  }
}

export default Properties;