249 lines
7.6 KiB
JavaScript
249 lines
7.6 KiB
JavaScript
var _ = require('../util').lodash,
|
|
PropertyBase = require('./property-base').PropertyBase,
|
|
PropertyList = require('./property-list').PropertyList,
|
|
QueryParam = require('./query-param').QueryParam,
|
|
FormParam = require('./form-param').FormParam,
|
|
|
|
EMPTY = '',
|
|
|
|
RequestBody;
|
|
|
|
/**
|
|
* @typedef RequestBody.definition
|
|
* @property {String} mode
|
|
* @property {String} raw
|
|
* @property {String} file
|
|
* @property {Object} graphql
|
|
* @property {Object[]} formdata
|
|
* @property {Object[]|String} urlencoded
|
|
*/
|
|
_.inherit((
|
|
|
|
/**
|
|
* RequestBody holds data related to the request body. By default, it provides a nice wrapper for url-encoded,
|
|
* form-data, and raw types of request bodies.
|
|
*
|
|
* @constructor
|
|
* @extends {PropertyBase}
|
|
*
|
|
* @param {Object} options -
|
|
*/
|
|
RequestBody = function PostmanRequestBody (options) {
|
|
// this constructor is intended to inherit and as such the super constructor is required to be executed
|
|
RequestBody.super_.apply(this, arguments);
|
|
if (!options) { return; } // in case definition object is missing, there is no point moving forward
|
|
|
|
this.update(options);
|
|
}), PropertyBase);
|
|
|
|
_.assign(RequestBody.prototype, /** @lends RequestBody.prototype */ {
|
|
/**
|
|
* Set the content of this request data
|
|
*
|
|
* @param {Object} options -
|
|
*/
|
|
update (options) {
|
|
_.isString(options) && (options = { mode: 'raw', raw: options });
|
|
if (!options.mode) { return; } // need a valid mode @todo raise error?
|
|
|
|
var mode = RequestBody.MODES[options.mode.toString().toLowerCase()] || RequestBody.MODES.raw,
|
|
urlencoded = options.urlencoded,
|
|
formdata = options.formdata,
|
|
graphql = options.graphql,
|
|
file = options.file,
|
|
raw = options.raw;
|
|
|
|
// Handle URL Encoded data
|
|
if (options.urlencoded) {
|
|
_.isString(options.urlencoded) && (urlencoded = QueryParam.parse(options.urlencoded));
|
|
urlencoded = new PropertyList(QueryParam, this, urlencoded);
|
|
}
|
|
|
|
// Handle Form data
|
|
if (options.formdata) {
|
|
formdata = new PropertyList(FormParam, this, options.formdata);
|
|
}
|
|
|
|
// Handle GraphQL data
|
|
if (options.graphql) {
|
|
graphql = {
|
|
query: graphql.query,
|
|
operationName: graphql.operationName,
|
|
variables: graphql.variables
|
|
};
|
|
}
|
|
|
|
_.isString(options.file) && (file = { src: file });
|
|
|
|
// If mode is raw but options does not give raw content, set it to empty string
|
|
(mode === RequestBody.MODES.raw && !raw) && (raw = '');
|
|
|
|
// If mode is urlencoded but options does not provide any content, set it to an empty property list
|
|
(mode === RequestBody.MODES.urlencoded && !urlencoded) && (urlencoded = new PropertyList(QueryParam, this, []));
|
|
|
|
// If mode is formdata but options does not provide any content, set it to an empty property list
|
|
(mode === RequestBody.MODES.formdata && !formdata) && (formdata = new PropertyList(FormParam, this, []));
|
|
|
|
// If mode is graphql but options does not provide any content, set empty query
|
|
(mode === RequestBody.MODES.graphql && !graphql) && (graphql = {});
|
|
|
|
_.assign(this, /** @lends RequestBody.prototype */ {
|
|
|
|
/**
|
|
* Indicates the type of request data to use.
|
|
*
|
|
* @type {String}
|
|
*/
|
|
mode: mode,
|
|
|
|
/**
|
|
* If the request has raw body data associated with it, the data is held in this field.
|
|
*
|
|
* @type {String}
|
|
*/
|
|
raw: raw,
|
|
|
|
/**
|
|
* Any URL encoded body params go here.
|
|
*
|
|
* @type {PropertyList<QueryParam>}
|
|
*/
|
|
urlencoded: urlencoded,
|
|
|
|
/**
|
|
* Form data parameters for this request are held in this field.
|
|
*
|
|
* @type {PropertyList<FormParam>}
|
|
*/
|
|
formdata: formdata,
|
|
|
|
/**
|
|
* Holds a reference to a file which should be read as the RequestBody. It can be a file path (when used
|
|
* with Node) or a unique ID (when used with the browser).
|
|
*
|
|
* @note The reference stored here should be resolved by a resolver function (which should be provided to
|
|
* the Postman Runtime).
|
|
*/
|
|
file: file,
|
|
|
|
/**
|
|
* If the request has raw graphql data associated with it, the data is held in this field.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
graphql: graphql,
|
|
|
|
/**
|
|
* If the request has body Options associated with it, the data is held in this field.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
options: _.isObject(options.options) ? options.options : undefined,
|
|
|
|
/**
|
|
* Indicates whether to include body in request or not.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
disabled: options.disabled
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Stringifies and returns the request body.
|
|
*
|
|
* @note FormData is not supported yet.
|
|
* @returns {*}
|
|
*/
|
|
toString () {
|
|
// Formdata. Goodluck.
|
|
if (this.mode === RequestBody.MODES.formdata || this.mode === RequestBody.MODES.file) {
|
|
// @todo: implement this, check if we need to return undefined or something.
|
|
return EMPTY;
|
|
}
|
|
|
|
if (this.mode === RequestBody.MODES.urlencoded) {
|
|
return PropertyList.isPropertyList(this.urlencoded) ? QueryParam.unparse(this.urlencoded.all()) :
|
|
((this.urlencoded && _.isFunction(this.urlencoded.toString)) ? this.urlencoded.toString() : EMPTY);
|
|
}
|
|
|
|
if (this.mode === RequestBody.MODES.raw) {
|
|
return (this.raw && _.isFunction(this.raw.toString)) ? this.raw.toString() : EMPTY;
|
|
}
|
|
|
|
return EMPTY;
|
|
},
|
|
|
|
/**
|
|
* If the request body is set to a mode, but does not contain data, then we should not be sending it.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
isEmpty () {
|
|
var mode = this.mode,
|
|
data = mode && this[mode];
|
|
|
|
// bail out if there's no data for the selected mode
|
|
if (!data) {
|
|
return true;
|
|
}
|
|
|
|
// Handle file mode
|
|
// @note this is a legacy exception. ideally every individual data mode
|
|
// in future would declare its "empty state".
|
|
if (mode === RequestBody.MODES.file) {
|
|
return !(data.src || data.content);
|
|
}
|
|
|
|
if (_.isString(data)) {
|
|
return (data.length === 0);
|
|
}
|
|
|
|
if (_.isFunction(data.count)) { // handle for property lists
|
|
return (data.count() === 0);
|
|
}
|
|
|
|
return _.isEmpty(data); // catch all for remaining data modes
|
|
},
|
|
|
|
/**
|
|
* Convert the request body to JSON compatible plain object
|
|
*
|
|
* @returns {Object}
|
|
*/
|
|
toJSON () {
|
|
var obj = PropertyBase.toJSON(this);
|
|
|
|
// make sure that file content is removed because it is non-serializable ReadStream
|
|
_.unset(obj, 'file.content');
|
|
|
|
return obj;
|
|
}
|
|
});
|
|
|
|
_.assign(RequestBody, /** @lends RequestBody **/{
|
|
/**
|
|
* Defines the name of this property for internal use.
|
|
*
|
|
* @private
|
|
* @readOnly
|
|
* @type {String}
|
|
*/
|
|
_postman_propertyName: 'RequestBody',
|
|
|
|
/**
|
|
* @enum {string} MODES
|
|
*/
|
|
MODES: {
|
|
file: 'file',
|
|
formdata: 'formdata',
|
|
graphql: 'graphql',
|
|
raw: 'raw',
|
|
urlencoded: 'urlencoded'
|
|
}
|
|
});
|
|
|
|
module.exports = {
|
|
RequestBody
|
|
};
|