postman-collection
Advanced tools
Comparing version 0.0.13 to 0.0.14
var _ = require('../util').lodash, | ||
ItemGroup = require('./item-group').ItemGroup, | ||
VariableList = require('./variable-list').VariableList, | ||
Version = require('./version').Version, | ||
@@ -9,2 +10,42 @@ Collection, // constructor | ||
/** | ||
* The following is the object structure accepted as constructor parameter while calling `new Collection(...)`. It is | ||
* also the structure exported when {@link Property#toJSON} or {@link Property#toObjectResolved} is called on a | ||
* collection instance. | ||
* @typedef Collection~definition | ||
* | ||
* @property {Object=} [info] The meta information regarding the collection is provided as the `info` object. | ||
* @property {String=} [info.id] Every collection is identified by the unique value of this property. It is recommended | ||
* that you maintain the same id since changing the id usually implies that is a different collection than it was | ||
* originally. | ||
* @property {String=} [info.name] A collection's friendly name is defined by this property. You would want to set this | ||
* field to a value that would allow you to easily identify this collection among a bunch of other collections. | ||
* @property {String=} [info.version] Postman allows you to version your collections as they grow, and this field holds | ||
* the version number. While optional, it is recommended that you use this field to its fullest extent. | ||
* @property {Array<(Item~definition|ItemGroup~definition)>} [item] Items are the basic unit for a Postman collection. | ||
* You can think of them as corresponding to a single API endpoint. Each Item has one request and may have multiple API | ||
* responses associated with it. | ||
* @property {Object<Variable~definition>} [variable] Collection variables allow you to define a set of variables, | ||
* that are a *part of the collection*, as opposed to environments, which are separate entities. | ||
* @property {String|Version~definition=} [version] Version of the collection expressed in [semver](http://semver.org/) | ||
* format. | ||
* | ||
* @see {ItemGroup~definition} - Since `Collection` inherits {@link ItemGroup}, the properties supported by ItemGroup | ||
* are applicable as well. | ||
* | ||
* @example <caption>JSON definition of an example collection</caption> | ||
* { | ||
* "info": { | ||
* "name": "My Postman Collection", | ||
* "version": "1.0.0" | ||
* } | ||
* "item": [{ | ||
* "request": "{{base-url}}/get" | ||
* }], | ||
* "variables": [{ | ||
* "id": "base-url", | ||
* "value": "https://echo.getpostman.com" | ||
* }] | ||
* } | ||
*/ | ||
_.inherit(( | ||
@@ -22,4 +63,4 @@ /** | ||
* | ||
* @param {Object=} [definition] - Pass the initial definition of the collection (name, id, etc) as the `definition` | ||
* parameter. The definition object is structured exactly as the collection format as defined in | ||
* @param {Collection~definition=} [definition] - Pass the initial definition of the collection (name, id, etc) as | ||
* the `definition` parameter. The definition object is structured exactly as the collection format as defined in | ||
* [https://www.schema.getpostman.com/](https://www.schema.getpostman.com/). This parameter is optional. That | ||
@@ -100,3 +141,18 @@ * implies that you can create an empty instance of collection and add requests and other properties in order to | ||
*/ | ||
variables: new VariableList(this, definition && definition.variable, environments) | ||
variables: new VariableList(this, definition && definition.variable, environments), | ||
/** | ||
* The `version` key in collection is used to express the version of the collection. It is useful in either | ||
* tracking development iteration of an API server or the version of an API itself. It can also be used to | ||
* represent the number of iterations of the collection as it is updated through its lifetime. | ||
* | ||
* Version is expressed in [semver](http://semver.org/) format. | ||
* | ||
* @type {Version} | ||
* @optional | ||
* | ||
* @see {@link http://semver.org/} | ||
*/ | ||
version: (definition && definition.info && definition.info.version) ? | ||
new Version(definition.info.version) : undefined | ||
}); | ||
@@ -103,0 +159,0 @@ }), ItemGroup); |
@@ -32,9 +32,16 @@ var _ = require('../util').lodash, | ||
/** | ||
* @typedef Description~definition | ||
* @property {String} content | ||
* @property {String} format | ||
*/ | ||
/** | ||
* This is one of the properties that are (if provided) processed by all other properties. Any property can have an | ||
* instance of `Description` property assigned to it with the key name `description` and it should be treated as | ||
* something that "describes" the property within which it belongs. Usually this property is used to generate | ||
* documentatation and other contextual information for a property in a Collection. | ||
* documentation and other contextual information for a property in a Collection. | ||
* @constructor | ||
* | ||
* @param def {Object|String} Definition of this Description object | ||
* @param {Description~definition|String} [definition] The content of the description can be passed as a string when it | ||
* is in `text/plain` format or otherwise be sent as part of an object adhering to the {@link Description~definition} | ||
* structure having `content` and `format`. | ||
* | ||
@@ -58,34 +65,11 @@ * @example <caption>Add a description to an instance of Collection</caption> | ||
*/ | ||
Description = function PostmanPropertyDescription (def) { | ||
Description = function PostmanPropertyDescription (definition) { | ||
// if the definition is a string, it implies that this is a get of URL | ||
_.isString(def) && (def = { | ||
content: def, | ||
_.isString(definition) && (definition = { | ||
content: definition, | ||
type: DEFAULT_MIMETYPE | ||
}); | ||
// in case definition object is missing, there is no point moving forward | ||
if (!def) { return; } | ||
/** | ||
* The raw content of the description | ||
* | ||
* @type {String} | ||
* @lends Description.prototype | ||
*/ | ||
this.content = def.content; | ||
/** | ||
* The mime-type of the description. | ||
* | ||
* @type {String} | ||
* @lends Description.prototype | ||
*/ | ||
this.type = def.type || DEFAULT_MIMETYPE; | ||
/** | ||
* A description can have multiple versions associated with it. | ||
* | ||
* @private | ||
* @type {*} | ||
* @lends Description.prototype | ||
*/ | ||
this.version = def.version; | ||
// populate the description | ||
definition && this.update(definition); | ||
}; | ||
@@ -97,9 +81,22 @@ | ||
* | ||
* @param {String} content | ||
* @param {type=} [type] | ||
* @param {String|Description~definition} content | ||
* @param {String=} [type] | ||
* @todo parse version of description | ||
*/ | ||
update: function (content, type) { | ||
this.content = content; | ||
type && (this.type = type); | ||
!this.type && (this.type = DEFAULT_MIMETYPE); | ||
_.isObject(content) && ((type = content.type), (content = content.content)); | ||
_.extend(this, /** @lends Description.prototype */ { | ||
/** | ||
* The raw content of the description | ||
* | ||
* @type {String} | ||
*/ | ||
content: content, | ||
/** | ||
* The mime-type of the description. | ||
* | ||
* @type {String} | ||
*/ | ||
type: type || DEFAULT_MIMETYPE | ||
}); | ||
}, | ||
@@ -106,0 +103,0 @@ |
@@ -7,2 +7,7 @@ var _ = require('../util').lodash, | ||
/** | ||
* @typedef Event~definition | ||
* @property {String} listen | ||
* @property {Script} script | ||
*/ | ||
_.inherit(( | ||
@@ -15,13 +20,22 @@ /** | ||
* | ||
* @param {Object} options Pass the initial definition of the event (name, id, listener name, etc) as the | ||
* options parameter. | ||
* @param {String=} [listen] - optional parameter to override the event name to be listened to (handy when creating | ||
* an event from an array map iterator.) | ||
* @param {Event~definition} definition Pass the initial definition of the event (name, id, listener name, etc) as | ||
* the options parameter. | ||
*/ | ||
Event = function PostmanEvent (options) { | ||
Event = function PostmanEvent (definition) { | ||
// this constructor is intended to inherit and as such the super constructor is required to be excuted | ||
Event.super_.call(this, options); | ||
if (!options) { return; } // in case definition object is missing, there is no point moving forward | ||
Event.super_.call(this, definition); | ||
// set initial values of this event | ||
definition && this.update(definition); | ||
}), Property); | ||
// @todo: error if no name? | ||
_.extend(Event.prototype, /** @lends Event.prototype */ { | ||
/** | ||
* Update an event | ||
* @param {Event~definition} options | ||
*/ | ||
update: function (definition) { | ||
if (!definition) { | ||
return; | ||
} | ||
_.merge(this, /** @lends Event.prototype */ { | ||
@@ -32,3 +46,3 @@ /** | ||
*/ | ||
listen: _.isString(options.listen) ? options.listen.toLowerCase() : undefined, | ||
listen: _.isString(definition.listen) ? definition.listen.toLowerCase() : undefined, | ||
/** | ||
@@ -38,10 +52,6 @@ * The script that is to be executed when this event is triggered. | ||
*/ | ||
script: _.isString(options.script) ? options.script : new Script(options.script), | ||
/** | ||
* A flag for events that can be disabled when put within a list | ||
* @type {Boolean} | ||
*/ | ||
disabled: (options && _.has(options, 'disabled')) ? !!options.disabled : undefined | ||
script: _.isString(definition.script) ? definition.script : new Script(definition.script) | ||
}); | ||
}), Property); | ||
} | ||
}); | ||
@@ -48,0 +58,0 @@ _.extend(Event, /** @lends Event */ { |
@@ -10,2 +10,36 @@ var _ = require('../util').lodash, | ||
/** | ||
* The following defines the object (or JSON) structure that one can pass to the ItemGroup while creating a new | ||
* ItemGroup instance. This is also the object structure returned when `.toJSON()` is called on an ItemGroup instance. | ||
* | ||
* @typedef ItemGroup~definition | ||
* @property {Array<ItemGroup~definition|Item~definition>=} [item] | ||
* @property {Array<RequestAuth~definition>=} [auth] | ||
* @property {Array<Event~definition>=} [event] | ||
* | ||
* @example | ||
* { | ||
* "name": "Echo Get Requests", | ||
* "id": "echo-get-requests", | ||
* "item": [{ | ||
* "request": "https://echo.getpostman.com/get" | ||
* }, { | ||
* "request": "https://echo.getpostman.com/headers" | ||
* }], | ||
* "auth": { | ||
* "type": "basic", | ||
* "basic": { | ||
* "username": "jean", | ||
* "password": "{{somethingsecret}}" | ||
* } | ||
* }, | ||
* "event": [{ | ||
* "listen": "prerequest", | ||
* "script: { | ||
* "type": "text/javascript", | ||
* "exec": "console.log(new Date())" | ||
* } | ||
* }] | ||
* } | ||
*/ | ||
_.inherit(( | ||
@@ -25,8 +59,19 @@ /** | ||
* | ||
* @param {Object} options | ||
* @param {ItemGroup~definition=} [definition] While creating a new instance of ItemGroup, one can provide the | ||
* initial configuration of the item group with the requests it contains, the authentication applied to all | ||
* requests, events that the requests responds to, etc. | ||
* | ||
* @example <caption>Add a new ItemGroup to a collection instance</caption> | ||
* var Collection = require('postman-collection').Collection, | ||
* ItemGroup = require('postman-collection').ItemGroup, | ||
* myCollection; | ||
* | ||
* myCollection = new Collection(); // create an empty collection | ||
* myCollection.add(new ItemGroup({ // add a folder called "blank folder" | ||
* "name": "This is a blank folder" | ||
* })); | ||
*/ | ||
ItemGroup = function PostmanItemGroup (options) { | ||
ItemGroup = function PostmanItemGroup (definition) { | ||
// this constructor is intended to inherit and as such the super constructor is required to be excuted | ||
ItemGroup.super_.apply(this, arguments); | ||
if (!options) { return; } // in case definition object is missing, there is no point moving forward | ||
@@ -58,3 +103,3 @@ _.merge(this, /** @lends ItemGroup.prototype */ { | ||
*/ | ||
items: new PropertyList(ItemGroup._createNewGroupOrItem, this, options.item), | ||
items: new PropertyList(ItemGroup._createNewGroupOrItem, this, definition && definition.item), | ||
@@ -88,3 +133,3 @@ /** | ||
*/ | ||
auth: _.createDefined(options, 'auth', RequestAuth), | ||
auth: _.createDefined(definition, 'auth', RequestAuth), | ||
@@ -115,3 +160,3 @@ /** | ||
*/ | ||
events: new EventList(this, options.event) | ||
events: new EventList(this, definition && definition.event) | ||
}); | ||
@@ -121,2 +166,7 @@ }), Property); | ||
_.extend(ItemGroup.prototype, /** @lends ItemGroup.prototype */ { | ||
/** | ||
* Defines that this property requires an ID field | ||
* @private | ||
* @readonly | ||
*/ | ||
_postman_requiresId: true, | ||
@@ -123,0 +173,0 @@ /** |
@@ -10,31 +10,113 @@ var _ = require('../util').lodash, | ||
/** | ||
* The following defines the object (or JSON) structure that one can pass to the Item while creating a new Item | ||
* instance. This is also the object structure returned when `.toJSON()` is called on an Item instance. | ||
* @typedef Item~definition | ||
* | ||
* @property {Request~definition=} [request] A request represents an HTTP request. If a string, the string is assumed to | ||
* be the request URL and the method is assumed to be 'GET'. | ||
* @property {Array<Response~definition>=} [responses] Sample responses for this request can be stored along with the | ||
* item definition. | ||
* @property {Array<Event~definition>=} [events] Postman allows you to configure scripts to run when specific events | ||
* occur. These scripts are stored here, and can be referenced in the collection by their id. | ||
* | ||
* @example | ||
* { | ||
* "name": "Get Headers from Echo", | ||
* "id": "my-request-1", | ||
* "description": "Makes a GET call to echo service and returns the client headers that were sent", | ||
* | ||
* "request": { | ||
* "url": "https://echo.getpostman.com/headers", | ||
* "method": "GET" | ||
* } | ||
* } | ||
* | ||
* @todo add response and event to example | ||
*/ | ||
_.inherit(( | ||
/** | ||
* A Postman Collection Item that holds your request definition, responses and other stuff | ||
* A Postman Collection Item that holds your request definition, responses and other stuff. An Item essentially is | ||
* a HTTP request definition along with the sample responses and test scripts clubbed together. One or more of these | ||
* items can be grouped together and placed in an {@link ItemGroup} and as such forms a {@link Collection} of | ||
* requests. | ||
* | ||
* @constructor | ||
* @extends {Property} | ||
* | ||
* @param {Object} options | ||
* @param {Item~definition=} [definition] While creating a new instance of Item, one can provide the initial | ||
* configuration of the item with the the request it sends, the expected sample responses, tests, etc | ||
* | ||
* @example <caption>Add a new Item to a folder in a collection instance</caption> | ||
* var Collection = require('postman-collection').Collection, | ||
* Item = require('postman-collection').Item, | ||
* myCollection; | ||
* | ||
* myCollection = new Collection({ | ||
* "item": [{ | ||
* "id": "my-folder-1", | ||
* "name": "The solo folder in this collection", | ||
* "item": [] // blank array indicates this is a folder | ||
* }] | ||
* }); // create a collection with an empty folder | ||
* // add a request to "my-folder-1" that sends a GET request | ||
* myCollection.items.one("my-folder-1").add(new Item({ | ||
* "name": "Send a GET request", | ||
* "id": "my-get-request" | ||
* "request": { | ||
* "url": 'https://echo.getpostman.com/get", | ||
* "method": "GET" | ||
* } | ||
* })); | ||
*/ | ||
Item = function PostmanItem (options) { | ||
Item = function PostmanItem (definition) { | ||
// this constructor is intended to inherit and as such the super constructor is required to be excuted | ||
Item.super_.apply(this, arguments); | ||
if (!options) { return; } // in case definition object is missing, there is no point moving forward | ||
_.merge(this, /** @lends Item.prototype */ { | ||
/** | ||
* The request in this item | ||
* The instance of the {@link Request} object inside an Item defines the HTTP request that is supposed to be | ||
* sent. It further contains the request method, url, request body, etc. | ||
* @type {Request} | ||
*/ | ||
request: new Request(options.request), | ||
request: definition && (new Request(definition.request)), | ||
/** | ||
* List of sample responses | ||
* An Item also contains a list of sample responses that is expected when the request defined in the item is | ||
* executed. The sample responses are useful in elaborating API usage and is also useful for other | ||
* integrations that use the sample responses to do something - say a mock service. | ||
* @type {PropertyList<Response>} | ||
*/ | ||
responses: new PropertyList(Response, this, options.response), | ||
responses: new PropertyList(Response, this, definition && definition.response), | ||
/** | ||
* Events of this item | ||
* Events are a set of of {@link Script}s that are executed when certain activities are triggered on an | ||
* Item. For example, on defining an event that listens to the "test" event, would cause the associated | ||
* script of the event to be executed when the test runs. | ||
* @type {EventList} | ||
* | ||
* @example <caption>Add a script to be executed on "prerequest" event</caption> | ||
* var Collection = require('postman-collection').Collection, | ||
* Item = require('postman-collection').Item, | ||
* myCollection; | ||
* | ||
* myCollection = new Collection({ | ||
* "item": [{ | ||
* "name": "Send a GET request", | ||
* "id": "my-get-request" | ||
* "request": { | ||
* "url": 'https://echo.getpostman.com/get", | ||
* "method": "GET" | ||
* } | ||
* }] | ||
* }); // create a collection with one request | ||
* | ||
* // add a pre-request script to the event list | ||
* myCollection.items.one('my-get-request').events.add({ | ||
* "listen": "prerequest", | ||
* "script": { | ||
* "type": "text/javascript", | ||
* "exec": "console.log(new Date())" | ||
* } | ||
* }); | ||
*/ | ||
events: new EventList(this, options.event) | ||
events: new EventList(this, definition && definition.event) | ||
}); | ||
@@ -52,3 +134,7 @@ }), Property); | ||
// TODO: Think about this name @shamasis | ||
/** | ||
* @private | ||
* @todo Think about this name @shamasis | ||
* @returns {*} | ||
*/ | ||
processAuth: function () { | ||
@@ -59,5 +145,23 @@ return this.request.authorize(); | ||
/** | ||
* Returns Events corresponding to a particular event name. If no name is given, returns all events | ||
* Returns {@link Event}s corresponding to a particular event name. If no name is given, returns all events. This | ||
* is useful when you want to trigger all associated scripts for an event. | ||
* | ||
* @param name {String} | ||
* @param {String} name - one of the available event types such as `test`, `prerequest`, `postrequest`, etc. | ||
* @returns {Array<Event>} | ||
* | ||
* @example <caption>Get all events for an item and evaluate their scripts</caption> | ||
* var fs = require('fs'), // needed to read JSON file from disk | ||
* Collection = require('postman-collection').Collection, | ||
* myCollection; | ||
* | ||
* // Load a collection to memory from a JSON file on disk (say, sample-collection.json) | ||
* myCollection = new Collection(JSON.stringify(fs.readFileSync('sample-collection.json').toString())); | ||
* | ||
* // assuming the collection has a request called "my-request-1" in root, we get it's test events | ||
* myCollection.items.one("my-request-1").getEvents("test").forEach(function (event) { | ||
* event.script && eval(event.script.toSource()); | ||
* }); | ||
* | ||
* @todo decide appropriate verb names based on the fact that it gets events for a specific listener name | ||
* @draft | ||
*/ | ||
@@ -64,0 +168,0 @@ getEvents: function (name) { |
@@ -7,14 +7,17 @@ var _ = require('../util').lodash, | ||
/** | ||
* @typedef PropertyBase~definition | ||
* @property {String|Description} [description] | ||
*/ | ||
/** | ||
* Base of all properties in Postman Collection. It defines the root for all standalone properties for postman | ||
* collection. It expects a property definition as parameter and the base is primarily interested in | ||
* - property names that start with underscore. | ||
* collection. | ||
* @constructor | ||
* @private | ||
* | ||
* @param {Object} options | ||
* @param {PropertyBase~definition} definition | ||
*/ | ||
PropertyBase = function PropertyBase (options) { | ||
PropertyBase = function PropertyBase (definition) { | ||
// In case definition object is missing, there is no point moving forward. Also if the definition is basic string | ||
// we do not need to do anything with it. | ||
if (!options || typeof options === 'string') { return; } | ||
if (!definition || typeof definition === 'string') { return; } | ||
@@ -24,3 +27,3 @@ // call the meta extraction functions to create the object where all keys that are prefixed with underscore can be | ||
// @todo: make this a closed function to do getter and setter which is non enumerable | ||
var meta = _(options && options.info || options) | ||
var meta = _(definition && definition.info || definition) | ||
.pick(PropertyBase.propertyIsMeta).mapKeys(PropertyBase.propertyUnprefixMeta).value(); | ||
@@ -30,7 +33,24 @@ | ||
/** | ||
* A detailed description of this property. The description can be written in plain text, html or markdown as | ||
* mentioned in {@link Description}.format enumeration. | ||
* The `description` property holds the detailed documentation of any property. The description can be written | ||
* in plain text, html or markdown as mentioned in {@link Description.format} enumeration. It is recommended | ||
* that this property be updated using the [describe](#describe) function. | ||
* | ||
* @type {Description} | ||
* @see Property#describe | ||
* | ||
* @example <caption>Accessing descriptions of all root items in a collection</caption> | ||
* var fs = require('fs'), // needed to read JSON file from disk | ||
* Collection = require('postman-collection').Collection, | ||
* myCollection; | ||
* | ||
* // Load a collection to memory from a JSON file on disk (say, sample-collection.json) | ||
* myCollection = new Collection(JSON.stringify(fs.readFileSync('sample-collection.json').toString())); | ||
* | ||
* // Log the description of all root items | ||
* myCollection.item.all().forEach(function (item) { | ||
* console.log(item.name || 'Untitled Item'); | ||
* item.description && console.log(item.description.toString()); | ||
* }); | ||
*/ | ||
description: _.createDefined(options, 'description', Description) | ||
description: _.createDefined(definition, 'description', Description) | ||
}); | ||
@@ -89,3 +109,3 @@ | ||
/** | ||
* Filter funcion to check whether a key starts with underscore or not. These usually are the meta properties. It | ||
* Filter function to check whether a key starts with underscore or not. These usually are the meta properties. It | ||
* returns `true` if the criteria is matched. | ||
@@ -92,0 +112,0 @@ * |
@@ -5,30 +5,52 @@ var _ = require('../util').lodash, | ||
Description = require('./description').Description, | ||
Version = require('./version').Version, | ||
/** | ||
* Maintain a list of types that are native | ||
* @private | ||
* @enum {String} | ||
*/ | ||
nativeTypes = { | ||
'string': true, | ||
'number': true, | ||
'boolean': true | ||
}, | ||
Property; // constructor | ||
/** | ||
* @typedef Property~definition | ||
* @property {String=} [id] | ||
* @property {String=} [name] | ||
* @property {Boolean=} [disabled] | ||
*/ | ||
_.inherit(( | ||
/** | ||
* This forms the base of properties **that are identifiable**. Identifiable implies that it expects the following | ||
* in property definition parameter | ||
* - id | ||
* - name | ||
* - version | ||
* - description | ||
* The Property class forms the base of all postman collection SDK elements. This is to be used only for SDK | ||
* development or to extend the SDK with additional functionalities. All SDK classes (constructors) that are | ||
* supposed to be identifyable (i.e. ones that can have a `name` and `id`) are derived from this class. | ||
* | ||
* For more information on what is the structure of the `definition` the function parameter, have a look at | ||
* {@link Property~definition}. | ||
* | ||
* > This is intended to be a private class except for those who want to extend the SDK itself and add more | ||
* > functionalities. | ||
* | ||
* @constructor | ||
* @extends {PropertyBase} | ||
* | ||
* @param {Object} options | ||
* @param {Property~definition=} [definition] Every constructor inherited from `Property` is required to call the | ||
* super constructor function. This implies that construction parameters of every inherited member is propagated | ||
* to be sent up to this point. | ||
* | ||
* @see Property~definition | ||
*/ | ||
Property = function PostmanProperty (options) { | ||
Property = function PostmanProperty (definition) { | ||
// this constructor is intended to inherit and as such the super constructor is required to be excuted | ||
Property.super_.apply(this, arguments); | ||
if (!options) { return; } // in case definition object is missing, there is no point moving forward | ||
// The definition can have an `info` object that stores the identification of this property. If that is present, | ||
// we use it instead of the definition root. | ||
var src = options.info || options, | ||
version = (options.info && options.info.version) ? new Version(options.info.version) : undefined; | ||
var src = definition && definition.info || definition; | ||
_.merge(this, /** @lends Property.prototype */ { | ||
src && _.extend(this, /** @lends Property.prototype */ { | ||
/*jshint -W069 */ | ||
@@ -61,10 +83,3 @@ /** | ||
*/ | ||
disabled: (options && _.has(options, 'disabled')) ? !!options.disabled : undefined, | ||
/** | ||
* The (optional) version of this property, expressed in [semver](http://semver.org/) format. | ||
* @type {Version} | ||
* @optional | ||
*/ | ||
version: version | ||
disabled: (definition && _.has(definition, 'disabled')) ? !!definition.disabled : undefined | ||
}); | ||
@@ -131,2 +146,54 @@ | ||
return variables ? variables.substitute(this.toJSON(), overrides) : undefined; | ||
}, | ||
/** | ||
* Regular expression to be used in {String}.replace for extracting variable substitutions | ||
* @private | ||
* @readOnly | ||
* @type {RegExp} | ||
*/ | ||
REGEX_EXTRACT_VARS: /\{\{([^}]*?)}}/g, | ||
/** | ||
* This function accepts a string followed by a number of variable sources as arguments. One or more variable | ||
* sources can be provided and it will use the one that has the value in left-to-right order. | ||
* | ||
* @param {String} str | ||
* @param {VariableList|Object|Array.<VariableList|Object>} variables | ||
* @returns {String} | ||
*/ | ||
replaceSubstitutions: function (str, variables) { | ||
// if there is nothing to replace, we move on | ||
if (!(str && _.isString(str))) { | ||
return str; | ||
} | ||
// extract all arguments to get the list of variables | ||
!_.isArray(variables) && (variables = _.tail(arguments)); | ||
return str.replace(this.REGEX_EXTRACT_VARS, function (match, token) { | ||
var r = _.findValue(variables, token); | ||
r && _.isFunction(r.toString) && (r = r.toString()); | ||
return nativeTypes[(typeof r)] ? r : match; | ||
}); | ||
}, | ||
/** | ||
* This function accepts an object followed by a number of variable sources as arguments. One or more variable | ||
* sources can be provided and it will use the one that has the value in left-to-right order. | ||
* | ||
* @param {Object} obj | ||
* @param {Array.<VariableList|Object>} variables | ||
* @param {Boolean=} [mutate=false] | ||
* @returns {Object} | ||
*/ | ||
replaceSubstitutionsIn: function (obj, variables, mutate) { | ||
// if there is nothing to replace, we move on | ||
if (!(obj && _.isObject(obj))) { | ||
return obj; | ||
} | ||
return _.merge(mutate ? obj : {}, obj, function (objectValue, sourceValue) { | ||
return _.isString(sourceValue) ? this.replaceSubstitutions(sourceValue, variables) : undefined; | ||
}, this); | ||
} | ||
@@ -133,0 +200,0 @@ }); |
@@ -16,13 +16,2 @@ var _ = require('../util').lodash, | ||
/** | ||
* Maintain a list of types that are native | ||
* @private | ||
* @enum {String} | ||
*/ | ||
nativeTypes = { | ||
'string': true, | ||
'number': true, | ||
'boolean': true | ||
}, | ||
VariableList; | ||
@@ -67,12 +56,7 @@ | ||
* @param {String} str | ||
* @param {Array<Object>=} [overrides] - additional objects to lookup for variable values | ||
* @param {Object} [overrides] - additional objects to lookup for variable values | ||
* @returns {String} | ||
*/ | ||
replace: function (str, overrides) { | ||
var self = this; | ||
return str.replace ? str.replace(VariableList.REGEX_EXTRACT_VARS, function (a, b) { | ||
var r = self.has(b) ? self.one(b) : _.findValue(overrides, b); | ||
r && _.isFunction(r.toString) && (r = r.toString()); | ||
return nativeTypes[(typeof r)] ? r : a; | ||
}) : str; | ||
return PropertyBase.replaceSubstitutions(str, this, overrides); | ||
}, | ||
@@ -90,5 +74,3 @@ | ||
substitute: function (obj, overrides, mutate) { | ||
return _.isObject(obj) ? _.merge(mutate ? obj : {}, obj, function (objectValue, sourceValue) { | ||
return _.isString(sourceValue) ? this.replace(sourceValue, overrides) : undefined; | ||
}, this) : obj; | ||
return PropertyBase.replaceSubstitutionsIn(obj, _.union([this], overrides), mutate); | ||
}, | ||
@@ -156,2 +138,4 @@ | ||
* @type {String} | ||
* | ||
* @note that this is directly accessed only in case of VariableList from _.findValue lodash util mixin | ||
*/ | ||
@@ -158,0 +142,0 @@ _postman_propertyName: 'VariableList', |
@@ -9,10 +9,35 @@ var _ = require('../util').lodash, | ||
/** | ||
* The object representation of a Variable consists the variable value and type. It also optionally includes the `id` | ||
* and a friendly `name` of the variable. The `id` and the `name` of a variable is usually managed and used when a | ||
* variable is made part of a {@link VariableList} instance. | ||
* | ||
* @typedef {Object} Variable~definition | ||
* @property {*=} [value] - The value of the variable that will be stored and will be typecast to the `type` | ||
* set in the variable or passed along in this parameter. | ||
* @property {String=} [type] - The type of this variable from the list of types defined at {@link Variable.types}. | ||
* | ||
* @example | ||
* { | ||
* "id": "my-var-1", | ||
* "name": "MyFirstVariable", | ||
* "value": "Hello World", | ||
* "type": "string" | ||
* } | ||
*/ | ||
_.inherit(( | ||
/** | ||
* A variable inside a collection is similar to variables in any programming construct. The variable has an | ||
* identifier name (provided by its id) and a value. A variable is optionally accompanied by a variable type. One | ||
* or more variables can be associated with a collection and can be referred from anywhere else in the collection | ||
* using the double-brace {{variable-id}} format. | ||
* | ||
* Properties can then use the `.toObjectResolved` function to procure an object representation of the property with | ||
* all the variable references replaced by corresponding values. | ||
* @constructor | ||
* @extends {Property} | ||
* | ||
* @param {Object} options | ||
* @param {Variable~definition=} [definition] - Specify the initial value and type of the variable. | ||
*/ | ||
Variable = function PostmanVariable (options) { | ||
Variable = function PostmanVariable (definition) { | ||
// this constructor is intended to inherit and as such the super constructor is required to be executed | ||
@@ -23,3 +48,3 @@ Variable.super_.apply(this, arguments); | ||
/** | ||
* @type {valueTypes} | ||
* @type {Variable.types} | ||
*/ | ||
@@ -33,3 +58,3 @@ type: ANY, | ||
(options !== undefined) && this.update(options); | ||
(definition !== undefined) && this.update(definition); | ||
}), Property); | ||
@@ -40,3 +65,3 @@ | ||
* Gets the value of the variable | ||
* @returns {Variable.type} | ||
* @returns {Variable.types} | ||
*/ | ||
@@ -74,8 +99,9 @@ get: function () { | ||
/** | ||
* Typecasts a value to the {@link Variable.type} of this {@link Variable}. | ||
* Typecasts a value to the {@link Variable.types} of this {@link Variable}. Returns the value of the variable | ||
* converted to the type specified in {@link Variable#type}. | ||
* @param {*} value | ||
* @returns {Variable.type} | ||
* @returns {*} | ||
*/ | ||
cast: function (value) { | ||
return (Variable.type[this.type] || Variable.type.any)(value); | ||
return (Variable.types[this.type] || Variable.types.any)(value); | ||
}, | ||
@@ -86,6 +112,6 @@ | ||
* @param {String} typeName | ||
* @returns {Variable.type} | ||
* @returns {String} - returns the current type of the variable from the list of {@link Variable.types} | ||
*/ | ||
valueType: function (typeName) { | ||
if (!typeName || !Variable.type[(typeName = typeName && typeName.toString().toLowerCase())]) { | ||
valueType: function (typeName, _nocast) { | ||
if (!typeName || !Variable.types[(typeName = typeName && typeName.toString().toLowerCase())]) { | ||
return this.type || ANY; // @todo: throw new Error('Invalid variable type.'); | ||
@@ -97,3 +123,3 @@ } | ||
this.type = typeName; | ||
this.value = this.cast(this.value); | ||
!_nocast && (this.value = this.cast(this.value)); | ||
} | ||
@@ -105,4 +131,5 @@ | ||
/** | ||
* Updates the type and value of a variable | ||
* @param {Object} options | ||
* Updates the type and value of a variable from an object or JSON definition of the variable. | ||
* | ||
* @param {Variable~definition} options | ||
*/ | ||
@@ -114,3 +141,3 @@ update: function (options) { | ||
// set type and value. | ||
options.hasOwnProperty('type') && this.valueType(options.type); | ||
options.hasOwnProperty('type') && this.valueType(options.type, options.hasOwnProperty('value')); | ||
options.hasOwnProperty('value') && this.set(options.value); | ||
@@ -129,9 +156,31 @@ } | ||
/** | ||
* Types of variables | ||
* The possible supported types of a variable is defined here. The keys defined here are the possible values of | ||
* {@link Variable#type}. | ||
* | ||
* Additional variable types can be supported by adding the type-casting function to this enumeration. | ||
* @enum {Function} | ||
* @readonly | ||
*/ | ||
type: { | ||
types: { | ||
/** | ||
* When a variable's `type` is set to "string", it ensures that {@link Variable#get} converts the value of the | ||
* variable to a string before returning the data. | ||
*/ | ||
'string': String, | ||
/** | ||
* A boolean type of variable can either be set to `true` or `false`. Any other value set is converted to | ||
* Boolean when procured from {@link Variable#get}. | ||
*/ | ||
'boolean': Boolean, | ||
/** | ||
* A "number" type variable ensures that the value is always represented as a number. A non-number type value | ||
* is returned as `NaN`. | ||
*/ | ||
'number': Number, | ||
/** | ||
* Free-form type of a value. This is the default for any variable, unless specified otherwise. It ensures that | ||
* the variable can store data in any type and no conversion is done while using {@link Variable#get}. | ||
* @param val | ||
* @returns {*} | ||
*/ | ||
'any': function (val) { | ||
@@ -138,0 +187,0 @@ return val; // passthrough |
@@ -143,9 +143,19 @@ var _ = require('lodash'); | ||
var i, | ||
var obj, | ||
i, | ||
ii; | ||
for (i = 0, ii = arr.length; i < ii; i++) { | ||
if (_.isObject(arr[i]) && _.has(arr[i], key)) { | ||
return arr[i][key]; | ||
obj = arr[i]; | ||
// ensure that the item is an object | ||
if (!(obj && _.isObject(obj))) { | ||
continue; | ||
} | ||
if (obj.constructor._postman_propertyName === 'VariableList') { | ||
if (obj.has(key)) { return obj.one(key); } | ||
} | ||
else if (_.has(obj, key)) { | ||
return obj[key]; | ||
} | ||
} | ||
@@ -152,0 +162,0 @@ } |
@@ -5,3 +5,3 @@ { | ||
"author": "Postman Labs <help@getpostman.com>", | ||
"version": "0.0.13", | ||
"version": "0.0.14", | ||
"keywords": [ | ||
@@ -8,0 +8,0 @@ "postman" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
240274
60
5512