101 lines
4.1 KiB
JavaScript
101 lines
4.1 KiB
JavaScript
var _ = require('lodash'),
|
|
sdk = require('postman-collection'),
|
|
|
|
createItemContext = require('../create-item-context'),
|
|
|
|
/**
|
|
* Resolve variables in item and auth in context.
|
|
*
|
|
* @param {ItemContext} context
|
|
* @param {Item} [context.item]
|
|
* @param {RequestAuth} [context.auth]
|
|
* @param {Object} payload
|
|
* @param {VariableScope} payload._variables
|
|
* @param {Object} payload.data
|
|
* @param {VariableScope} payload.environment
|
|
* @param {VariableScope} payload.collectionVariables
|
|
* @param {VariableScope} payload.globals
|
|
*/
|
|
resolveVariables = function (context, payload) {
|
|
if (!(context.item && context.item.request)) { return; }
|
|
|
|
// @todo - resolve variables in a more graceful way
|
|
var variableDefinitions = [
|
|
// extract the variable list from variable scopes
|
|
// @note: this is the order of precedence for variable resolution - don't change it
|
|
payload._variables.values,
|
|
payload.data,
|
|
payload.environment.values,
|
|
payload.collectionVariables.values,
|
|
payload.globals.values
|
|
],
|
|
urlString = context.item.request.url.toString(),
|
|
item,
|
|
auth;
|
|
|
|
// @todo - no need to sync variables when SDK starts supporting resolution from scope directly
|
|
// @todo - avoid resolving the entire item as this unnecessarily resolves URL
|
|
item = context.item = new sdk.Item(context.item.toObjectResolved(null,
|
|
variableDefinitions, {ignoreOwnVariables: true}));
|
|
|
|
auth = context.auth;
|
|
|
|
// resolve variables in URL string
|
|
if (urlString) {
|
|
// @note this adds support resolving nested variables as URL parser doesn't support them well.
|
|
urlString = sdk.Property.replaceSubstitutions(urlString, variableDefinitions);
|
|
|
|
// Re-parse the URL from the resolved string
|
|
item.request.url = new sdk.Url(urlString);
|
|
}
|
|
|
|
// resolve variables in auth
|
|
auth && (context.auth = new sdk.RequestAuth(auth.toObjectResolved(null,
|
|
variableDefinitions, {ignoreOwnVariables: true})));
|
|
};
|
|
|
|
module.exports = {
|
|
init: function (done) {
|
|
done();
|
|
},
|
|
|
|
triggers: ['response'],
|
|
|
|
process: {
|
|
request: function (payload, next) {
|
|
var abortOnError = _.has(payload, 'abortOnError') ? payload.abortOnError : this.options.abortOnError,
|
|
|
|
// helper function to trigger `response` callback anc complete the command
|
|
complete = function (err, nextPayload) {
|
|
// nextPayload will be empty for unhandled errors
|
|
// trigger `response` callback
|
|
// nextPayload.response will be empty for error flows
|
|
// the `item` argument is resolved and mutated here
|
|
nextPayload && this.triggers.response(err, nextPayload.coords, nextPayload.response,
|
|
nextPayload.request, nextPayload.item, nextPayload.cookies, nextPayload.history);
|
|
|
|
// the error is passed twice to allow control between aborting the error vs just
|
|
// bubbling it up
|
|
return next(err && abortOnError ? err : null, nextPayload, err);
|
|
}.bind(this),
|
|
context = createItemContext(payload);
|
|
|
|
// resolve variables in item and auth
|
|
resolveVariables(context, payload);
|
|
|
|
// add context for use, after resolution
|
|
payload.context = context;
|
|
|
|
// we do not queue `httprequest` instruction here,
|
|
// queueing will unblock the item command to prepare for the next `event` instruction
|
|
// at this moment request is not fulfilled, and we want to block it
|
|
this.immediate('httprequest', payload)
|
|
.done(function (nextPayload, err) {
|
|
// change signature to error first
|
|
complete(err, nextPayload);
|
|
})
|
|
.catch(complete);
|
|
}
|
|
}
|
|
};
|