UNPKG

yapi-to-typescript

Version:

根据 YApi 的接口定义生成 TypeScript/JavaScript 的接口类型及其请求函数代码。

496 lines (411 loc) 13.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; exports.__esModule = true; exports.swaggerJsonToYApiData = swaggerJsonToYApiData; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _dayjs = _interopRequireDefault(require("dayjs")); var _swaggerClient = _interopRequireDefault(require("swagger-client")); var _vtils = require("vtils"); // @ts-nocheck // ref: https://github.com/YMFE/yapi/blob/master/exts/yapi-plugin-import-swagger/run.js var SwaggerData, isOAS3; function handlePath(path) { if (path === '/') return path; if (path.charAt(0) !== '/') { path = "/" + path; } if (path.charAt(path.length - 1) === '/') { path = path.substr(0, path.length - 1); } return path; } function openapi2swagger(data) { data.swagger = '2.0'; (0, _vtils.each)(data.paths, function (apis) { (0, _vtils.each)(apis, function (api) { (0, _vtils.each)(api.responses, function (res) { if (res.content && res.content['application/json'] && typeof res.content['application/json'] === 'object') { Object.assign(res, res.content['application/json']); delete res.content; } if (res.content && res.content['application/hal+json'] && typeof res.content['application/hal+json'] === 'object') { Object.assign(res, res.content['application/hal+json']); delete res.content; } if (res.content && res.content['*/*'] && typeof res.content['*/*'] === 'object') { Object.assign(res, res.content['*/*']); delete res.content; } }); if (api.requestBody) { if (!api.parameters) api.parameters = []; var body = { type: 'object', name: 'body', in: 'body' }; try { body.schema = api.requestBody.content['application/json'].schema; } catch (e) { body.schema = {}; } api.parameters.push(body); } }); }); return data; } function handleSwaggerData(_x) { return _handleSwaggerData.apply(this, arguments); } function _handleSwaggerData() { _handleSwaggerData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(res) { return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: return _context.abrupt("return", new Promise(function (resolve) { var data = (0, _swaggerClient.default)({ spec: res }); data.then(function (res) { resolve(res.spec); }); })); case 1: case "end": return _context.stop(); } } }, _callee); })); return _handleSwaggerData.apply(this, arguments); } function run(_x2) { return _run.apply(this, arguments); } function _run() { _run = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(res) { var interfaceData; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: interfaceData = { apis: [], cats: [], basePath: '', swaggerData: {} }; if (typeof res === 'string' && res) { try { res = JSON.parse(res); } catch (e) { console.error('json 解析出错', e.message); } } isOAS3 = res.openapi && String(res.openapi).startsWith('3.'); if (isOAS3) { res = openapi2swagger(res); } _context2.next = 6; return handleSwaggerData(res); case 6: res = _context2.sent; SwaggerData = res; interfaceData.swaggerData = SwaggerData; interfaceData.basePath = res.basePath || ''; if (res.tags && Array.isArray(res.tags)) { res.tags.forEach(function (tag) { interfaceData.cats.push({ name: tag.name, desc: tag.description }); }); } else { res.tags = []; } (0, _vtils.each)(res.paths, function (apis, path) { // parameters is common parameters, not a method delete apis.parameters; (0, _vtils.each)(apis, function (api, method) { api.path = path; api.method = method; var data = null; try { data = handleSwagger(api, res.tags); if (data.catname) { if (!(0, _vtils.find)(interfaceData.cats, function (item) { return item.name === data.catname; })) { if (res.tags.length === 0) { interfaceData.cats.push({ name: data.catname, desc: data.catname }); } } } } catch (err) { data = null; } if (data) { interfaceData.apis.push(data); } }); }); interfaceData.cats = interfaceData.cats.filter(function (catData) { var catName = catData.name; return (0, _vtils.find)(interfaceData.apis, function (apiData) { return apiData.catname === catName; }); }); return _context2.abrupt("return", interfaceData); case 14: case "end": return _context2.stop(); } } }, _callee2); })); return _run.apply(this, arguments); } function handleSwagger(data, originTags) { if (originTags === void 0) { originTags = []; } var api = {}; //处理基本信息 api.method = data.method.toUpperCase(); api.title = data.summary || data.path; api.desc = data.description; api.catname = null; if (data.tags && Array.isArray(data.tags)) { api.tag = data.tags; var _loop = function _loop(i) { if (/v[0-9.]+/.test(data.tags[i])) { return "continue"; } // 如果根路径有 tags,使用根路径 tags,不使用每个接口定义的 tag 做完分类 if (originTags.length > 0 && (0, _vtils.find)(originTags, function (item) { return item.name === data.tags[i]; })) { api.catname = data.tags[i]; return "break"; } if (originTags.length === 0) { api.catname = data.tags[i]; return "break"; } }; for (var i = 0; i < data.tags.length; i++) { var _ret = _loop(i); if (_ret === "continue") continue; if (_ret === "break") break; } } api.path = handlePath(data.path); api.req_params = []; api.req_body_form = []; api.req_headers = []; api.req_query = []; api.req_body_type = 'raw'; api.res_body_type = 'raw'; if (data.produces && data.produces.indexOf('application/json') > -1) { api.res_body_type = 'json'; api.res_body_is_json_schema = true; } if (data.consumes && Array.isArray(data.consumes)) { if (data.consumes.indexOf('application/x-www-form-urlencoded') > -1 || data.consumes.indexOf('multipart/form-data') > -1) { api.req_body_type = 'form'; } else if (data.consumes.indexOf('application/json') > -1) { api.req_body_type = 'json'; api.req_body_is_json_schema = true; } } //处理response api.res_body = handleResponse(data.responses); try { JSON.parse(api.res_body); api.res_body_type = 'json'; api.res_body_is_json_schema = true; } catch (e) { api.res_body_type = 'raw'; } //处理参数 function simpleJsonPathParse(key, json) { if (!key || typeof key !== 'string' || key.indexOf('#/') !== 0 || key.length <= 2) { return null; } var keys = key.substr(2).split('/'); keys = keys.filter(function (item) { return item; }); for (var _i = 0, l = keys.length; _i < l; _i++) { try { json = json[keys[_i]]; } catch (e) { json = ''; break; } } return json; } if (data.parameters && Array.isArray(data.parameters)) { data.parameters.forEach(function (param) { if (param && typeof param === 'object' && param.$ref) { param = simpleJsonPathParse(param.$ref, { parameters: SwaggerData.parameters }); } var defaultParam = { name: param.name, desc: param.description, required: param.required ? '1' : '0' }; if (param.in) { switch (param.in) { case 'path': defaultParam.type = param.type; api.req_params.push(defaultParam); break; case 'query': defaultParam.type = param.type; api.req_query.push(defaultParam); break; case 'body': handleBodyPamras(param.schema, api); break; case 'formData': defaultParam.type = param.type === 'file' ? 'file' : 'text'; if (param.example) { defaultParam.example = param.example; } api.req_body_form.push(defaultParam); break; case 'header': api.req_headers.push(defaultParam); break; default: break; } } else { api.req_query.push(defaultParam); } }); } return api; } function isJson(json) { try { return JSON.parse(json); } catch (e) { return false; } } function handleBodyPamras(data, api) { api.req_body_other = JSON.stringify(data, null, 2); if (isJson(api.req_body_other)) { api.req_body_type = 'json'; api.req_body_is_json_schema = true; } } function handleResponse(api) { var res_body = ''; if (!api || typeof api !== 'object') { return res_body; } var codes = Object.keys(api); var curCode; if (codes.length > 0) { if (codes.indexOf('200') > -1) { curCode = '200'; } else curCode = codes[0]; var res = api[curCode]; if (res && typeof res === 'object') { if (res.schema) { res_body = JSON.stringify(res.schema, null, 2); } else if (res.description) { res_body = res.description; } } else if (typeof res === 'string') { res_body = res; } else { res_body = ''; } } else { res_body = ''; } return res_body; } function swaggerJsonToYApiData(_x3) { return _swaggerJsonToYApiData.apply(this, arguments); } function _swaggerJsonToYApiData() { _swaggerJsonToYApiData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(data) { var _yapiData$swaggerData; var yapiData, currentTime, project, cats, interfaces; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return run(data); case 2: yapiData = _context3.sent; // 兼容没有分类的情况 if (!yapiData.cats.length) { yapiData.cats = [{ name: 'default', desc: 'default' }]; yapiData.apis.forEach(function (api) { api.catname = 'default'; }); } currentTime = (0, _dayjs.default)().unix(); project = { _id: 0, name: yapiData.swaggerData.info.title, desc: yapiData.swaggerData.info.description || '', basepath: yapiData.swaggerData.basePath || '', tag: [], env: [{ name: 'local', domain: (((_yapiData$swaggerData = yapiData.swaggerData.schemes) == null ? void 0 : _yapiData$swaggerData[0]) || 'http') + "://" + (yapiData.swaggerData.host || '127.0.0.1') }] }; cats = yapiData.cats.map(function (cat, index) { return { _id: index + 1, name: cat.name, desc: cat.desc, add_time: currentTime, up_time: currentTime }; }); interfaces = yapiData.apis.map(function (api, index) { var _cats$find; return (0, _extends2.default)({}, api, { _id: index + 1, project_id: 0, catid: ((_cats$find = cats.find(function (cat) { return cat.name === api.catname; })) == null ? void 0 : _cats$find._id) || -1, tag: api.tag || [], add_time: currentTime, up_time: currentTime }); }); return _context3.abrupt("return", { project: project, cats: cats, interfaces: interfaces }); case 9: case "end": return _context3.stop(); } } }, _callee3); })); return _swaggerJsonToYApiData.apply(this, arguments); }