restsharp.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. "use strict";
  2. var _ = require('../../lodash'), parseRequest = require('./parseRequest'), sanitize = require('./util').sanitize, sanitizeOptions = require('./util').sanitizeOptions, addFormParam = require('./util').addFormParam, self;
  3. /**
  4. * Generates snippet in csharp-restsharp by parsing data from Postman-SDK request object
  5. *
  6. * @param {Object} request - Postman SDK request object
  7. * @param {Object} options - Options to tweak code snippet
  8. * @returns {String} csharp-restsharp code snippet for given request object
  9. */
  10. function makeSnippet(request, options) {
  11. const UNSUPPORTED_METHODS_LIKE_POST = ['LINK', 'UNLINK', 'LOCK', 'PROPFIND'], UNSUPPORTED_METHODS_LIKE_GET = ['PURGE', 'UNLOCK', 'VIEW', 'COPY'];
  12. var snippet = `var client = new RestClient("${sanitize(request.url.toString())}");\n`, isUnSupportedMethod = UNSUPPORTED_METHODS_LIKE_GET.includes(request.method) ||
  13. UNSUPPORTED_METHODS_LIKE_POST.includes(request.method);
  14. // if (options.requestTimeout) {
  15. // snippet += `client.Timeout = ${options.requestTimeout};\n`;
  16. // }
  17. // else {
  18. // snippet += 'client.Timeout = -1;\n';
  19. // }
  20. // if (!options.followRedirect) {
  21. // snippet += 'client.FollowRedirects = false;\n';
  22. // }
  23. snippet += `var request = new RestRequest(${isUnSupportedMethod ? '' : ('Method.' + request.method)});\n`;
  24. if (request.body && request.body.mode === 'graphql' && !request.headers.has('Content-Type')) {
  25. request.addHeader({
  26. key: 'Content-Type',
  27. value: 'application/json'
  28. });
  29. }
  30. snippet += parseRequest.parseHeader(request.toJSON(), options.trimRequestBody);
  31. if (request.body && request.body.mode === 'formdata') {
  32. let isFile = false, formdata = request.body.formdata, formdataArray = [];
  33. request.body.toJSON().formdata.forEach((data) => {
  34. if (!data.disabled && data.type === 'file') {
  35. isFile = true;
  36. }
  37. });
  38. // The following statement needs to be added else the multipart/form-data request where there is no file
  39. // is being sent as x-www-form-urlencoded by default
  40. if (!isFile) {
  41. snippet += 'request.AlwaysMultipartFormData = true;\n';
  42. }
  43. // The following code handles multiple files in the same formdata param.
  44. // It removes the form data params where the src property is an array of filepath strings
  45. // Splits that array into different form data params with src set as a single filepath string
  46. formdata.members.forEach((param) => {
  47. let key = param.key, type = param.type, disabled = param.disabled, contentType = param.contentType;
  48. // check if type is file or text
  49. if (type === 'file') {
  50. // if src is not of type string we check for array(multiple files)
  51. if (typeof param.src !== 'string') {
  52. // if src is an array(not empty), iterate over it and add files as separate form fields
  53. if (Array.isArray(param.src) && param.src.length) {
  54. param.src.forEach((filePath) => {
  55. addFormParam(formdataArray, key, param.type, filePath, disabled, contentType);
  56. });
  57. }
  58. // if src is not an array or string, or is an empty array, add a placeholder for file path(no files case)
  59. else {
  60. addFormParam(formdataArray, key, param.type, '/path/to/file', disabled, contentType);
  61. }
  62. }
  63. // if src is string, directly add the param with src as filepath
  64. else {
  65. addFormParam(formdataArray, key, param.type, param.src, disabled, contentType);
  66. }
  67. }
  68. // if type is text, directly add it to formdata array
  69. else {
  70. addFormParam(formdataArray, key, param.type, param.value, disabled, contentType);
  71. }
  72. });
  73. request.body.update({
  74. mode: 'formdata',
  75. formdata: formdataArray
  76. });
  77. }
  78. snippet += parseRequest.parseBody(request, options.trimRequestBody);
  79. if (isUnSupportedMethod) {
  80. (UNSUPPORTED_METHODS_LIKE_GET.includes(request.method)) &&
  81. (snippet += `IRestResponse response = client.ExecuteAsGet(request, "${request.method}");\n`);
  82. (UNSUPPORTED_METHODS_LIKE_POST.includes(request.method)) &&
  83. (snippet += `IRestResponse response = client.ExecuteAsPost(request, "${request.method}");\n`);
  84. }
  85. else {
  86. snippet += 'IRestResponse response = client.Execute(request);\n';
  87. }
  88. snippet += 'Console.WriteLine(response.Content);';
  89. return snippet;
  90. }
  91. self = module.exports = {
  92. /**
  93. * Used in order to get additional options for generation of C# code snippet (i.e. Include Boilerplate code)
  94. *
  95. * @module getOptions
  96. *
  97. * @returns {Array} Additional options specific to generation of csharp-restsharp code snippet
  98. */
  99. getOptions: function () {
  100. return [
  101. {
  102. name: 'Include boilerplate',
  103. id: 'includeBoilerplate',
  104. type: 'boolean',
  105. default: false,
  106. description: 'Include class definition and import statements in snippet'
  107. },
  108. {
  109. name: 'Set indentation count',
  110. id: 'indentCount',
  111. type: 'positiveInteger',
  112. default: 2,
  113. description: 'Set the number of indentation characters to add per code level'
  114. },
  115. {
  116. name: 'Set indentation type',
  117. id: 'indentType',
  118. type: 'enum',
  119. availableOptions: ['Tab', 'Space'],
  120. default: 'Space',
  121. description: 'Select the character used to indent lines of code'
  122. },
  123. {
  124. name: 'Set request timeout',
  125. id: 'requestTimeout',
  126. type: 'positiveInteger',
  127. default: 0,
  128. description: 'Set number of milliseconds the request should wait for a response ' +
  129. 'before timing out (use 0 for infinity)'
  130. },
  131. {
  132. name: 'Follow redirects',
  133. id: 'followRedirect',
  134. type: 'boolean',
  135. default: true,
  136. description: 'Automatically follow HTTP redirects'
  137. },
  138. {
  139. name: 'Trim request body fields',
  140. id: 'trimRequestBody',
  141. type: 'boolean',
  142. default: false,
  143. description: 'Remove white space and additional lines that may affect the server\'s response'
  144. }
  145. ];
  146. },
  147. /**
  148. * Converts Postman sdk request object to csharp-restsharp code snippet
  149. *
  150. * @module convert
  151. *
  152. * @param {Object} request - Postman-SDK request object
  153. * @param {Object} options - Options to tweak code snippet generated in C#
  154. * @param {String} options.indentType - type for indentation eg: Space, Tab (default: Space)
  155. * @param {String} options.indentCount - number of spaces or tabs for indentation. (default: 4 for indentType:
  156. Space, default: 1 for indentType: Tab)
  157. * @param {Boolean} [options.includeBoilerplate] - indicates whether to include class definition in C#
  158. * @param {Boolean} options.followRedirect - whether to enable followredirect
  159. * @param {Boolean} options.trimRequestBody - whether to trim fields in request body or not (default: false)
  160. * @param {Number} options.requestTimeout - time in milli-seconds after which request will bail out
  161. (default: 0 -> never bail out)
  162. * @param {Function} callback - Callback function with parameters (error, snippet)
  163. * @returns {String} Generated C# snippet via callback
  164. */
  165. convert: function (request, options, callback) {
  166. if (!_.isFunction(callback)) {
  167. throw new Error('C#-RestSharp-Converter: Callback is not valid function');
  168. }
  169. // String representing value of indentation required
  170. var indentString,
  171. // snippets to include C# class definition according to options
  172. headerSnippet = '', footerSnippet = '',
  173. // snippet to create request in csharp-restsharp
  174. snippet = '';
  175. options = sanitizeOptions(options, self.getOptions());
  176. indentString = options.indentType === 'Tab' ? '\t' : ' ';
  177. indentString = indentString.repeat(options.indentCount);
  178. if (options.includeBoilerplate) {
  179. headerSnippet = 'using System;\n' +
  180. 'using RestSharp;\n\n' +
  181. 'namespace ApiTestApp {\n' +
  182. indentString + 'class ApiTest {\n' +
  183. indentString.repeat(2) + 'static void Main(string[] args) {\n';
  184. footerSnippet = indentString.repeat(2) + '}\n' + indentString + '}\n}\n';
  185. }
  186. snippet = makeSnippet(request, options);
  187. // if boilerplate is included then two more indentString needs to be added in snippet
  188. (options.includeBoilerplate) &&
  189. (snippet = indentString.repeat(3) + snippet.split('\n').join('\n' + indentString.repeat(3)) + '\n');
  190. return callback(null, headerSnippet + snippet + footerSnippet);
  191. }
  192. };