All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Javascript.ApiClient.mustache Maven / Gradle / Ivy

There is a newer version: 7.9.0
Show newest version
{{>licenseInfo}}
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['superagent', 'querystring'], factory);
  } else if (typeof module === 'object' && module.exports) {
    // CommonJS-like environments that support module.exports, like Node.
    module.exports = factory(require('superagent'), require('querystring'));
  } else {
    // Browser globals (root is window)
    if (!root.{{moduleName}}) {
      root.{{moduleName}} = {};
    }
    root.{{moduleName}}.ApiClient = factory(root.superagent, root.querystring);
  }
}(this, function(superagent, querystring) {
  'use strict';

{{#emitJSDoc}}  /**
   * @module {{#invokerPackage}}{{invokerPackage}}/{{/invokerPackage}}ApiClient
   * @version {{projectVersion}}
   */

  /**
   * Manages low level client-server communications, parameter marshalling, etc. There should not be any need for an
   * application to use this class directly - the *Api and model classes provide the public API for the service. The
   * contents of this file should be regarded as internal but are documented for completeness.
   * @alias module:{{#invokerPackage}}{{invokerPackage}}/{{/invokerPackage}}ApiClient
   * @class
   */
{{/emitJSDoc}}  var exports = function() {
{{#emitJSDoc}}    /**
     * The base URL against which to resolve every API call's (relative) path.
     * @type {String}
     * @default {{{basePath}}}
     */
{{/emitJSDoc}}    this.basePath = '{{{basePath}}}'.replace(/\/+$/, '');

{{#emitJSDoc}}    /**
     * The authentication methods to be included for all API calls.
     * @type {Array.}
     */
{{/emitJSDoc}}{{=< >=}}    this.authentications = {
<#authMethods>
<#isBasic>
<#isBasicBasic>
      '': {type: 'basic'}<^-last>,

<#isBasicBearer>
      '': {type: 'bearer'}<^-last>,<#bearerFormat> // <&.>


<#isApiKey>
      '': {type: 'apiKey', 'in': <#isKeyInHeader>'header'<^isKeyInHeader>'query', name: ''}<^-last>,

<#isOAuth>
      '': {type: 'oauth2'}<^-last>,


    };
<={{ }}=>
{{#emitJSDoc}}    /**
     * The default HTTP headers to be included for all API calls.
     * @type {Array.}
     * @default {}
     */
{{/emitJSDoc}}    this.defaultHeaders = {};

    /**
     * The default HTTP timeout for all API calls.
     * @type {Number}
     * @default 60000
     */
    this.timeout = 60000;

    /**
     * If set to false an additional timestamp parameter is added to all API GET calls to
     * prevent browser caching
     * @type {Boolean}
     * @default true
     */
    this.cache = true;

{{#emitJSDoc}}    /**
     * If set to true, the client will save the cookies from each server
     * response, and return them in the next request.
     * @default false
     */
{{/emitJSDoc}}    this.enableCookies = false;

    /*
     * Used to save and return cookies in a node.js (non-browser) setting,
     * if this.enableCookies is set to true.
     */
    if (typeof window === 'undefined') {
      this.agent = new superagent.agent();
    }

    /*
     * Allow user to override superagent agent
     */
    this.requestAgent = null;

    /*
     * Allow user to add superagent plugins
     */
    this.plugins = null;
  };

{{#emitJSDoc}}  /**
   * Returns a string representation for an actual parameter.
   * @param param The actual parameter.
   * @returns {String} The string representation of param.
   */
{{/emitJSDoc}}  exports.prototype.paramToString = function(param) {
    if (param == undefined || param == null) {
      return '';
    }
    if (param instanceof Date) {
      return param.toJSON();
    }
    if (this.canBeJsonified(param)) {
      return JSON.stringify(param);
    }
    return param.toString();
  };

{{#emitJSDoc}}  /**
    * Returns a boolean indicating if the parameter could be JSON.stringified
    * @param param The actual parameter
    * @returns {Boolean} Flag indicating if param can be JSON.stringified
    */
{{/emitJSDoc}}  exports.prototype.canBeJsonified = function(str) {
    if (typeof str !== 'string' && typeof str !== 'object') return false;
    try {
      const type = str.toString();
      return type === '[object Object]'
          || type === '[object Array]';
    } catch (err) {
      return false;
    }
  };

{{#emitJSDoc}}
 /**
   * Builds full URL by appending the given path to the base URL and replacing path parameter place-holders with parameter values.
   * NOTE: query parameters are not handled here.
   * @param {String} path The path to append to the base URL.
   * @param {Object} pathParams The parameter values to append.
   * @returns {String} The encoded path with parameter values substituted.
   */
{{/emitJSDoc}}
  exports.prototype.buildUrl = function(path, pathParams, apiBasePath) {
    if (!path.match(/^\//)) {
      path = '/' + path;
    }
    var url = this.basePath + path;


    // use API (operation, path) base path if defined
    if (apiBasePath !== null && apiBasePath !== undefined) {
        url = apiBasePath + path;
    }

    var _this = this;
    url = url.replace(/\{([\w-\.]+)\}/g, function(fullMatch, key) {
      var value;
      if (pathParams.hasOwnProperty(key)) {
        value = _this.paramToString(pathParams[key]);
      } else {
        value = fullMatch;
      }
      return encodeURIComponent(value);
    });
    return url;
  };

{{#emitJSDoc}}  /**
   * Checks whether the given content type represents JSON.
* JSON content type examples:
*
    *
  • application/json
  • *
  • application/json; charset=UTF8
  • *
  • APPLICATION/JSON
  • *
* @param {String} contentType The MIME content type to check. * @returns {Boolean} true if contentType represents JSON, otherwise false. */ {{/emitJSDoc}} exports.prototype.isJsonMime = function(contentType) { return Boolean(contentType != null && contentType.match(/^application\/json(;.*)?$/i)); }; {{#emitJSDoc}} /** * Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first. * @param {Array.} contentTypes * @returns {String} The chosen content type, preferring JSON. */ {{/emitJSDoc}} exports.prototype.jsonPreferredMime = function(contentTypes) { for (var i = 0; i < contentTypes.length; i++) { if (this.isJsonMime(contentTypes[i])) { return contentTypes[i]; } } return contentTypes[0]; }; {{#emitJSDoc}} /** * Checks whether the given parameter value represents file-like content. * @param param The parameter to check. * @returns {Boolean} true if param represents a file. */ {{/emitJSDoc}} exports.prototype.isFileParam = function(param) { // fs.ReadStream in Node.js and Electron (but not in runtime like browserify) if (typeof require === 'function') { var fs; try { fs = require('fs'); } catch (err) {} if (fs && fs.ReadStream && param instanceof fs.ReadStream) { return true; } } // Buffer in Node.js if (typeof Buffer === 'function' && param instanceof Buffer) { return true; } // Blob in browser if (typeof Blob === 'function' && param instanceof Blob) { return true; } // File in browser (it seems File object is also instance of Blob, but keep this for safe) if (typeof File === 'function' && param instanceof File) { return true; } return false; }; {{#emitJSDoc}} /** * Normalizes parameter values: *
    *
  • remove nils
  • *
  • keep files and arrays
  • *
  • format to string with `paramToString` for other cases
  • *
* @param {Object.} params The parameters as object properties. * @returns {Object.} normalized parameters. */ {{/emitJSDoc}} exports.prototype.normalizeParams = function(params) { var newParams = {}; for (var key in params) { if (params.hasOwnProperty(key) && params[key] != undefined && params[key] != null) { var value = params[key]; if (this.isFileParam(value) || Array.isArray(value)) { newParams[key] = value; } else { newParams[key] = this.paramToString(value); } } } return newParams; }; {{#emitJSDoc}} /** * Enumeration of collection format separator strategies. * @enum {String} * @readonly */ exports.CollectionFormatEnum = { /** * Comma-separated values. Value: csv * @const */ CSV: ',', /** * Space-separated values. Value: ssv * @const */ SSV: ' ', /** * Tab-separated values. Value: tsv * @const */ TSV: '\t', /** * Pipe(|)-separated values. Value: pipes * @const */ PIPES: '|', /** * Native array. Value: multi * @const */ MULTI: 'multi' }; /** * Builds a string representation of an array-type actual parameter, according to the given collection format. * @param {Array} param An array parameter. * @param {module:{{#invokerPackage}}{{invokerPackage}}/{{/invokerPackage}}ApiClient.CollectionFormatEnum} collectionFormat The array element separator strategy. * @returns {String|Array} A string representation of the supplied collection, using the specified delimiter. Returns * param as is if collectionFormat is multi. */ {{/emitJSDoc}} exports.prototype.buildCollectionParam = function buildCollectionParam(param, collectionFormat) { if (param == null) { return null; } switch (collectionFormat) { case 'csv': return param.map(this.paramToString, this).join(','); case 'ssv': return param.map(this.paramToString, this).join(' '); case 'tsv': return param.map(this.paramToString, this).join('\t'); case 'pipes': return param.map(this.paramToString, this).join('|'); case 'multi': // return the array directly as SuperAgent will handle it as expected return param.map(this.paramToString, this); case 'passthrough': return param; default: throw new Error('Unknown collection format: ' + collectionFormat); } }; {{#emitJSDoc}} /** * Applies authentication headers to the request. * @param {Object} request The request object created by a superagent() call. * @param {Array.} authNames An array of authentication method names. */ {{/emitJSDoc}} exports.prototype.applyAuthToRequest = function(request, authNames) { var _this = this; authNames.forEach(function(authName) { var auth = _this.authentications[authName]; switch (auth.type) { case 'basic': if (auth.username || auth.password) { request.auth(auth.username || '', auth.password || ''); } break; case 'bearer': if (auth.accessToken) { var localVarBearerToken = typeof auth.accessToken === 'function' ? auth.accessToken() : auth.accessToken request.set({'Authorization': 'Bearer ' + localVarBearerToken}); } break; case 'apiKey': if (auth.apiKey) { var data = {}; if (auth.apiKeyPrefix) { data[auth.name] = auth.apiKeyPrefix + ' ' + auth.apiKey; } else { data[auth.name] = auth.apiKey; } if (auth['in'] === 'header') { request.set(data); } else { request.query(data); } } break; case 'oauth2': if (auth.accessToken) { request.set({'Authorization': 'Bearer ' + auth.accessToken}); } break; default: throw new Error('Unknown authentication type: ' + auth.type); } }); }; {{#emitJSDoc}} /** * Deserializes an HTTP response body into a value of the specified type. * @param {Object} response A SuperAgent response object. * @param {(String|Array.|Object.|Function)} returnType The type to return. Pass a string for simple types * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type: * all properties on data will be converted to this type. * @returns A value of the specified type. */ {{/emitJSDoc}} exports.prototype.deserialize = function deserialize(response, returnType) { if (response == null || returnType == null || response.status == 204) { return null; } // Rely on SuperAgent for parsing response body. // See http://visionmedia.github.io/superagent/#parsing-response-bodies var data = response.body; if (data == null || (typeof data === 'object' && typeof data.length === 'undefined' && !Object.keys(data).length)) { // SuperAgent does not always produce a body; use the unparsed response as a fallback data = response.text; } return exports.convertToType(data, returnType); }; {{#emitJSDoc}}{{^usePromises}} /** * Callback function to receive the result of the operation. * @callback module:{{#invokerPackage}}{{invokerPackage}}/{{/invokerPackage}}ApiClient~callApiCallback * @param {String} error Error message, if any. * @param data The data returned by the service call. * @param {String} response The complete HTTP response. */ {{/usePromises}} /** * Invokes the REST service using the supplied settings and parameters. * @param {String} path The base URL to invoke. * @param {String} httpMethod The HTTP method to use. * @param {Object.} pathParams A map of path parameters and their values. * @param {Object.} queryParams A map of query parameters and their values. * @param {Object.} collectionQueryParams A map of collection query parameters and their values. * @param {Object.} headerParams A map of header parameters and their values. * @param {Object.} formParams A map of form parameters and their values. * @param {Object} bodyParam The value to pass as the request body. * @param {Array.} authNames An array of authentication type names. * @param {Array.} contentTypes An array of request MIME types. * @param {Array.} accepts An array of acceptable response MIME types. * @param {(String|Array|ObjectFunction)} returnType The required type to return; can be a string for simple types or the * constructor for a complex type.{{^usePromises}} * @param {module:{{#invokerPackage}}{{invokerPackage}}/{{/invokerPackage}}ApiClient~callApiCallback} callback The callback function.{{/usePromises}} * @returns {{#usePromises}}{Promise} A {@link https://www.promisejs.org/|Promise} object{{/usePromises}}{{^usePromises}}{Object} The SuperAgent request object{{/usePromises}}. */ {{/emitJSDoc}} exports.prototype.callApi = function callApi(path, httpMethod, pathParams, queryParams, collectionQueryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts, returnType, apiBasePath{{^usePromises}}, callback{{/usePromises}}) { var _this = this; var url = this.buildUrl(path, pathParams, apiBasePath); var request = superagent(httpMethod, url); if (this.plugins !== null) { for (var index in this.plugins) { if (this.plugins.hasOwnProperty(index)) { request.use(this.plugins[index]) } } } // apply authentications this.applyAuthToRequest(request, authNames); // set collection query parameters for (var key in collectionQueryParams) { if (collectionQueryParams.hasOwnProperty(key)) { var param = collectionQueryParams[key]; if (param.collectionFormat === 'csv') { // SuperAgent normally percent-encodes all reserved characters in a query parameter. However, // commas are used as delimiters for the 'csv' collectionFormat so they must not be encoded. We // must therefore construct and encode 'csv' collection query parameters manually. if (param.value != null) { var value = param.value.map(this.paramToString).map(encodeURIComponent).join(','); request.query(encodeURIComponent(key) + "=" + value); } } else { // All other collection query parameters should be treated as ordinary query parameters. queryParams[key] = this.buildCollectionParam(param.value, param.collectionFormat); } } } // set query parameters if (httpMethod.toUpperCase() === 'GET' && this.cache === false) { queryParams['_'] = new Date().getTime(); } request.query(this.normalizeParams(queryParams)); // set header parameters request.set(this.defaultHeaders).set(this.normalizeParams(headerParams)); // set requestAgent if it is set by user if (this.requestAgent) { request.agent(this.requestAgent); } // set request timeout request.timeout(this.timeout); var contentType = this.jsonPreferredMime(contentTypes); if (contentType) { // Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746) if(contentType != 'multipart/form-data') { request.type(contentType); } } if (contentType === 'application/x-www-form-urlencoded') { request.send(querystring.stringify(this.normalizeParams(formParams))); } else if (contentType == 'multipart/form-data') { var _formParams = this.normalizeParams(formParams); for (var key in _formParams) { if (_formParams.hasOwnProperty(key)) { let _formParamsValue = _formParams[key]; if (this.isFileParam(_formParamsValue)) { // file field request.attach(key, _formParamsValue); } else if (Array.isArray(_formParamsValue) && _formParamsValue.length && this.isFileParam(_formParamsValue[0])) { // multiple files _formParamsValue.forEach(file => request.attach(key, file)); } else { request.field(key, _formParamsValue); } } } } else if (bodyParam !== null && bodyParam !== undefined) { if (!request.header['Content-Type']) { request.type('application/json'); } request.send(bodyParam); } var accept = this.jsonPreferredMime(accepts); if (accept) { request.accept(accept); } if (returnType === 'Blob') { request.responseType('blob'); } else if (returnType === 'String') { request.responseType('string'); } // Attach previously saved cookies, if enabled if (this.enableCookies){ if (typeof window === 'undefined') { this.agent._attachCookies(request); } else { request.withCredentials(); } } {{#usePromises}} return new Promise(function(resolve, reject) { request.end(function(error, response) { if (error) { reject(error); } else { try { var data = _this.deserialize(response, returnType); if (_this.enableCookies && typeof window === 'undefined'){ _this.agent._saveCookies(response); } resolve({data: data, response: response}); } catch (err) { reject(err); } } }); });{{/usePromises}} {{^usePromises}} request.end(function(error, response) { if (callback) { var data = null; if (!error) { try { data = _this.deserialize(response, returnType); if (_this.enableCookies && typeof window === 'undefined'){ _this.agent._saveCookies(response); } } catch (err) { error = err; } } callback(error, data, response); } }); return request; {{/usePromises}} }; {{#emitJSDoc}} /** * Parses an ISO-8601 string representation or epoch representation of a date value. * @param {String} str The date value as a string. * @returns {Date} The parsed date object. */ {{/emitJSDoc}} exports.parseDate = function(str) { if (isNaN(str)) { return new Date(str.replace(/T/i, ' ')); } return new Date(+str); }; {{#emitJSDoc}} /** * Converts a value to the specified type. * @param {(String|Object)} data The data to convert, as a string or object. * @param {(String|Array.|Object.|Function)} type The type to return. Pass a string for simple types * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type: * all properties on data will be converted to this type. * @returns An instance of the specified type or null or undefined if data is null or undefined. */ {{/emitJSDoc}} exports.convertToType = function(data, type) { if (data === null || data === undefined) return data switch (type) { case 'Boolean': return Boolean(data); case 'Integer': return parseInt(data, 10); case 'Number': return parseFloat(data); case 'String': return String(data); case 'Date': return this.parseDate(String(data)); case 'Blob': return data; default: if (type === Object) { // generic object, return directly return data; } else if (typeof type.constructFromObject === 'function') { // for model type like User or enum class return type.constructFromObject(data); } else if (Array.isArray(type)) { // for array type like: ['String'] var itemType = type[0]; return data.map(function(item) { return exports.convertToType(item, itemType); }); } else if (typeof type === 'object') { // for plain object type like: {'String': 'Integer'} var keyType, valueType; for (var k in type) { if (type.hasOwnProperty(k)) { keyType = k; valueType = type[k]; break; } } var result = {}; for (var k in data) { if (data.hasOwnProperty(k)) { var key = exports.convertToType(k, keyType); var value = exports.convertToType(data[k], valueType); result[key] = value; } } return result; } else { // for unknown type, return the data directly return data; } } }; {{#emitJSDoc}} /** * Gets an array of host settings * @returns An array of host settings */ {{/emitJSDoc}} exports.hostSettings = function() { return [ {{#servers}} { 'url': "{{{url}}}", 'description': "{{{description}}}{{^description}}No description provided{{/description}}", {{#variables}} {{#-first}} 'variables': { {{/-first}} {{{name}}}: { 'description': "{{{description}}}{{^description}}No description provided{{/description}}", 'default_value': "{{{defaultValue}}}", {{#enumValues}} {{#-first}} 'enum_values': [ {{/-first}} "{{{.}}}"{{^-last}},{{/-last}} {{#-last}} ] {{/-last}} {{/enumValues}} }{{^-last}},{{/-last}} {{#-last}} } {{/-last}} {{/variables}} }{{^-last}},{{/-last}} {{/servers}} ]; }; exports.getBasePathFromSettings = function(index, variables) { var variables = variables || {}; var servers = this.hostSettings(); // check array index out of bound if (index < 0 || index >= servers.length) { throw new Error("Invalid index " + index + " when selecting the host settings. Must be less than " + servers.length); } var server = servers[index]; var url = server['url']; // go through variable and assign a value for (var variable_name in server['variables']) { if (variable_name in variables) { let variable = server['variables'][variable_name]; if ( !('enum_values' in variable) || variable['enum_values'].includes(variables[variable_name]) ) { url = url.replace("{" + variable_name + "}", variables[variable_name]); } else { throw new Error("The variable `" + variable_name + "` in the host URL has invalid value " + variables[variable_name] + ". Must be " + server['variables'][variable_name]['enum_values'] + "."); } } else { // use default value url = url.replace("{" + variable_name + "}", server['variables'][variable_name]['default_value']) } } return url; }; {{#emitJSDoc}} /** * Constructs a new map or array model from REST data. * @param data {Object|Array} The REST data. * @param obj {Object|Array} The target object or array. */ {{/emitJSDoc}} exports.constructFromObject = function(data, obj, itemType) { if (Array.isArray(data)) { for (var i = 0; i < data.length; i++) { if (data.hasOwnProperty(i)) obj[i] = exports.convertToType(data[i], itemType); } } else { for (var k in data) { if (data.hasOwnProperty(k)) obj[k] = exports.convertToType(data[k], itemType); } } }; {{#emitJSDoc}} /** * The default API client implementation. * @type {module:{{#invokerPackage}}{{invokerPackage}}/{{/invokerPackage}}ApiClient} */ {{/emitJSDoc}} exports.instance = new exports(); return exports; }));