property.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. "use strict";
  2. var _ = require('../../lodash'), PropertyBase = require('./property-base').PropertyBase, DISABLED = 'disabled', DESCRIPTION = 'description', Property; // constructor
  3. /**
  4. * @typedef Property.definition
  5. * @property {String=} [id] A unique string that identifies the property.
  6. * @property {String=} [name] A distinctive and human-readable name of the property.
  7. * @property {Boolean=} [disabled] Denotes whether the property is disabled or not.
  8. * @property {Object=} [info] The meta information regarding the Property is provided as the `info` object.
  9. * @property {String=} [info.id] If set, this is used instead of the definition root's id.
  10. * @property {String=} [info.name] If set, this is used instead of the definition root's name.
  11. */
  12. _.inherit((
  13. /**
  14. * The Property class forms the base of all postman collection SDK elements. This is to be used only for SDK
  15. * development or to extend the SDK with additional functionalities. All SDK classes (constructors) that are
  16. * supposed to be identifyable (i.e. ones that can have a `name` and `id`) are derived from this class.
  17. *
  18. * For more information on what is the structure of the `definition` the function parameter, have a look at
  19. * {@link Property.definition}.
  20. *
  21. * > This is intended to be a private class except for those who want to extend the SDK itself and add more
  22. * > functionalities.
  23. *
  24. * @constructor
  25. * @extends {PropertyBase}
  26. *
  27. * @param {Property.definition=} [definition] Every constructor inherited from `Property` is required to call the
  28. * super constructor function. This implies that construction parameters of every inherited member is propagated
  29. * to be sent up to this point.
  30. *
  31. * @see Property.definition
  32. */
  33. Property = function PostmanProperty(definition) {
  34. // this constructor is intended to inherit and as such the super constructor is required to be executed
  35. Property.super_.apply(this, arguments);
  36. // The definition can have an `info` object that stores the identification of this property. If that is present,
  37. // we use it instead of the definition root.
  38. var src = definition && definition.info || definition, id;
  39. // first we extract id from all possible sources
  40. // we also check if this property is marked to require an ID, we generate one if not found.
  41. id = (src && src.id) || this.id || (this._ && this._.postman_id) || (this._postman_propertyRequiresId &&
  42. Math.random().toString(16).substr(2) /* uuid.v4() */);
  43. /**
  44. * The `id` of the property is a unique string that identifies this property and can be used to refer to
  45. * this property from relevant other places. It is a good practice to define the id or let the system
  46. * auto generate a UUID if one is not defined for properties that require an `id`.
  47. * @name id
  48. * @type {String}
  49. * @memberOf Property.prototype
  50. *
  51. * @note The property can also be present in the `postman_id` meta in case it is not specified in the
  52. * object. An auto-generated property is used wherever one is not specified
  53. */
  54. id && (this.id = id);
  55. /**
  56. * A property can have a distinctive and human-readable name. This is to be used to display the name of the
  57. * property within Postman, Newman or other runtimes that consume collection. In certain cases, the absence
  58. * of name might cause the runtime to use the `id` as a fallback.
  59. * @name name
  60. * @memberOf Property.prototype
  61. * @type {String}
  62. */
  63. src && src.name && (this.name = src.name);
  64. /**
  65. * This (optional) flag denotes whether this property is disabled or not. Usually, this is helpful when a
  66. * property is part of a {@link PropertyList}. For example, in a PropertyList of {@link Header}s, the ones
  67. * that are disabled can be filtered out and not processed.
  68. * @type {Boolean}
  69. * @optional
  70. * @name disabled
  71. *
  72. * @memberOf Property.prototype
  73. */
  74. definition && _.has(definition, DISABLED) && (this.disabled = Boolean(definition.disabled));
  75. }), PropertyBase);
  76. _.assign(Property.prototype, /** @lends Property.prototype */ {
  77. /**
  78. * Returns an object representation of the Property with its variable references substituted.
  79. *
  80. * @example <caption>Resolve an object using variable definitions from itself and its parents</caption>
  81. * property.toObjectResolved();
  82. *
  83. * @example <caption>Resolve an object using variable definitions on a different object</caption>
  84. * property.toObjectResolved(item);
  85. *
  86. * @example <caption>Resolve an object using variables definitions as a flat list of variables</caption>
  87. * property.toObjectResolved(null, [variablesDefinition1, variablesDefinition1], {ignoreOwnVariables: true});
  88. *
  89. * @private
  90. * @draft
  91. * @param {?Item|ItemGroup=} [scope] - One can specifically provide an item or group with `.variables`. In
  92. * the event one is not provided, the variables are taken from this object or one from the parent tree.
  93. * @param {Array<Object>} overrides - additional objects to lookup for variable values
  94. * @param {Object} [options]
  95. * @param {Boolean} [options.ignoreOwnVariables] - if set to true, `.variables` on self(or scope)
  96. * will not be used for variable resolution. Only variables in `overrides` will be used for resolution.
  97. * @returns {Object|undefined}
  98. * @throws {Error} If `variables` cannot be resolved up the parent chain.
  99. */
  100. toObjectResolved: function (scope, overrides, options) {
  101. var ignoreOwnVariables = options && options.ignoreOwnVariables, variableSourceObj, variables, reference;
  102. // ensure you do not substitute variables itself!
  103. reference = this.toJSON();
  104. _.isArray(reference.variable) && (delete reference.variable);
  105. // if `ignoreScopeVariables` is turned on, ignore `.variables` and resolve with only `overrides`
  106. // otherwise find `.variables` on current object or `scope`
  107. if (ignoreOwnVariables) {
  108. return Property.replaceSubstitutionsIn(reference, overrides);
  109. }
  110. // 1. if variables is passed as params, use it or fall back to oneself
  111. // 2. for a source from point (1), and look for `.variables`
  112. // 3. if `.variables` is not found, then rise up the parent to find first .variables
  113. variableSourceObj = scope || this;
  114. do {
  115. variables = variableSourceObj.variables;
  116. variableSourceObj = variableSourceObj.__parent;
  117. } while (!variables && variableSourceObj);
  118. if (!variables) { // worst case = no variable param and none detected in tree or object
  119. throw Error('Unable to resolve variables. Require a List type property for variable auto resolution.');
  120. }
  121. return variables.substitute(reference, overrides);
  122. }
  123. });
  124. _.assign(Property, /** @lends Property */ {
  125. /**
  126. * Defines the name of this property for internal use.
  127. * @private
  128. * @readOnly
  129. * @type {String}
  130. */
  131. _postman_propertyName: 'Property',
  132. });
  133. module.exports = {
  134. Property: Property
  135. };