123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- "use strict";
- var _ = require('../../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: function (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));
- // @todo: The fallback in the ternary expression will never be hit, as urlencoded points to
- // @todo: options.urlencoded
- urlencoded = urlencoded ? new PropertyList(QueryParam, this, urlencoded) :
- new PropertyList(QueryParam, this, []);
- }
- // Handle Form data
- if (options.formdata) {
- // @todo: The fallback in the ternary expression will never be hit, as formdata points to
- // @todo: options.formdata
- formdata = formdata ? new PropertyList(FormParam, this, options.formdata) :
- new PropertyList(FormParam, this, []);
- }
- // 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: function () {
- // 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: function () {
- 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: function () {
- 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: RequestBody
- };
|