mock平台

run.js 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. const _ = require('underscore')
  2. const swagger = require('swagger-client');
  3. const compareVersions = require('compare-versions');
  4. var SwaggerData, isOAS3;
  5. function handlePath(path) {
  6. if (path === '/') return path;
  7. if (path.charAt(0) != '/') {
  8. path = '/' + path;
  9. }
  10. if (path.charAt(path.length - 1) === '/') {
  11. path = path.substr(0, path.length - 1);
  12. }
  13. return path;
  14. }
  15. function openapi2swagger(data) {
  16. data.swagger = '2.0';
  17. _.each(data.paths, apis => {
  18. _.each(apis, api => {
  19. _.each(api.responses, res => {
  20. if (
  21. res.content &&
  22. res.content['application/json'] &&
  23. typeof res.content['application/json'] === 'object'
  24. ) {
  25. Object.assign(res, res.content['application/json']);
  26. delete res.content;
  27. }
  28. });
  29. if (api.requestBody) {
  30. if (!api.parameters) api.parameters = [];
  31. let body = {
  32. type: 'object',
  33. name: 'body',
  34. in: 'body'
  35. };
  36. try {
  37. body.schema = api.requestBody.content['application/json'].schema;
  38. } catch (e) {
  39. body.schema = {};
  40. }
  41. api.parameters.push(body);
  42. }
  43. });
  44. });
  45. return data;
  46. }
  47. async function handleSwaggerData(res) {
  48. return await new Promise(resolve => {
  49. let data = swagger({
  50. spec: res
  51. });
  52. data.then(res => {
  53. resolve(res.spec);
  54. });
  55. });
  56. }
  57. async function run(res) {
  58. let interfaceData = { apis: [], cats: [] };
  59. if(typeof res === 'string' && res){
  60. try{
  61. res = JSON.parse(res);
  62. } catch (e) {
  63. console.error('json 解析出错',e.message)
  64. }
  65. }
  66. isOAS3 = res.openapi && compareVersions(res.openapi,'3.0.0') >= 0;
  67. if (isOAS3) {
  68. res = openapi2swagger(res);
  69. }
  70. res = await handleSwaggerData(res);
  71. SwaggerData = res;
  72. if (res.tags && Array.isArray(res.tags)) {
  73. res.tags.forEach(tag => {
  74. interfaceData.cats.push({
  75. name: tag.name,
  76. desc: tag.description
  77. });
  78. });
  79. }
  80. _.each(res.paths, (apis, path) => {
  81. // parameters is common parameters, not a method
  82. delete apis.parameters;
  83. _.each(apis, (api, method) => {
  84. api.path = path;
  85. api.method = method;
  86. let data = null;
  87. try {
  88. data = handleSwagger(api);
  89. if (data.catname) {
  90. if (!_.find(interfaceData.cats, item => item.name === data.catname)) {
  91. interfaceData.cats.push({
  92. name: data.catname,
  93. desc: data.catname
  94. });
  95. }
  96. }
  97. } catch (err) {
  98. data = null;
  99. }
  100. if (data) {
  101. interfaceData.apis.push(data);
  102. }
  103. });
  104. });
  105. return interfaceData;
  106. }
  107. function handleSwagger(data) {
  108. let api = {};
  109. //处理基本信息
  110. api.method = data.method.toUpperCase();
  111. api.title = data.summary || data.path;
  112. api.desc = data.description;
  113. api.catname = data.tags && Array.isArray(data.tags) ? data.tags[0] : null;
  114. api.path = handlePath(data.path);
  115. api.req_params = [];
  116. api.req_body_form = [];
  117. api.req_headers = [];
  118. api.req_query = [];
  119. api.req_body_type = 'raw';
  120. api.res_body_type = 'raw';
  121. if (data.produces && data.produces.indexOf('application/json') > -1) {
  122. api.res_body_type = 'json';
  123. api.res_body_is_json_schema = true;
  124. }
  125. if (data.consumes && Array.isArray(data.consumes)) {
  126. if (
  127. data.consumes.indexOf('application/x-www-form-urlencoded') > -1 ||
  128. data.consumes.indexOf('multipart/form-data') > -1
  129. ) {
  130. api.req_body_type = 'form';
  131. } else if (data.consumes.indexOf('application/json') > -1) {
  132. api.req_body_type = 'json';
  133. api.req_body_is_json_schema = true;
  134. }
  135. }
  136. //处理response
  137. api.res_body = handleResponse(data.responses);
  138. try {
  139. JSON.parse(api.res_body);
  140. api.res_body_type = 'json';
  141. api.res_body_is_json_schema = true;
  142. } catch (e) {
  143. api.res_body_type = 'raw';
  144. }
  145. //处理参数
  146. function simpleJsonPathParse(key, json) {
  147. if (!key || typeof key !== 'string' || key.indexOf('#/') !== 0 || key.length <= 2) {
  148. return null;
  149. }
  150. let keys = key.substr(2).split('/');
  151. keys = keys.filter(item => {
  152. return item;
  153. });
  154. for (let i = 0, l = keys.length; i < l; i++) {
  155. try {
  156. json = json[keys[i]];
  157. } catch (e) {
  158. json = '';
  159. break;
  160. }
  161. }
  162. return json;
  163. }
  164. if (data.parameters && Array.isArray(data.parameters)) {
  165. data.parameters.forEach(param => {
  166. if (param && typeof param === 'object' && param.$ref) {
  167. param = simpleJsonPathParse(param.$ref, { parameters: SwaggerData.parameters });
  168. }
  169. let defaultParam = {
  170. name: param.name,
  171. desc: param.description,
  172. required: param.required ? '1' : '0'
  173. };
  174. switch (param.in) {
  175. case 'path':
  176. api.req_params.push(defaultParam);
  177. break;
  178. case 'query':
  179. api.req_query.push(defaultParam);
  180. break;
  181. case 'body':
  182. handleBodyPamras(param.schema, api);
  183. break;
  184. case 'formData':
  185. defaultParam.type = param.type === 'file' ? 'file' : 'text';
  186. api.req_body_form.push(defaultParam);
  187. break;
  188. case 'header':
  189. api.req_headers.push(defaultParam);
  190. break;
  191. }
  192. });
  193. }
  194. return api;
  195. }
  196. function isJson(json) {
  197. try {
  198. return JSON.parse(json);
  199. } catch (e) {
  200. return false;
  201. }
  202. }
  203. function handleBodyPamras(data, api) {
  204. api.req_body_other = JSON.stringify(data, null, 2);
  205. if (isJson(api.req_body_other)) {
  206. api.req_body_type = 'json';
  207. api.req_body_is_json_schema = true;
  208. }
  209. }
  210. function handleResponse(api) {
  211. let res_body = '';
  212. if (!api || typeof api !== 'object') {
  213. return res_body;
  214. }
  215. let codes = Object.keys(api);
  216. let curCode;
  217. if (codes.length > 0) {
  218. if (codes.indexOf('200') > -1) {
  219. curCode = '200';
  220. } else curCode = codes[0];
  221. let res = api[curCode];
  222. if (res && typeof res === 'object') {
  223. if (res.schema) {
  224. res_body = JSON.stringify(res.schema, null, 2);
  225. } else if (res.description) {
  226. res_body = res.description;
  227. }
  228. } else if (typeof res === 'string') {
  229. res_body = res;
  230. } else {
  231. res_body = '';
  232. }
  233. } else {
  234. res_body = '';
  235. }
  236. return res_body;
  237. }
  238. module.exports = run;