yapi-to-typescript
Version:
根据 YApi 的接口定义生成 TypeScript/JavaScript 的接口类型及其请求函数代码。
483 lines (407 loc) • 13.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import _regeneratorRuntime from "@babel/runtime/regenerator";
// @ts-nocheck
// ref: https://github.com/YMFE/yapi/blob/master/exts/yapi-plugin-import-swagger/run.js
import dayjs from 'dayjs';
import swagger from 'swagger-client';
import { each, find } from 'vtils';
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';
each(data.paths, function (apis) {
each(apis, function (api) {
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 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(res) {
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
return _context.abrupt("return", new Promise(function (resolve) {
var data = swagger({
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 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(res) {
var interfaceData;
return _regeneratorRuntime.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 = [];
}
each(res.paths, function (apis, path) {
// parameters is common parameters, not a method
delete apis.parameters;
each(apis, function (api, method) {
api.path = path;
api.method = method;
var data = null;
try {
data = handleSwagger(api, res.tags);
if (data.catname) {
if (!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 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 && 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;
}
export function swaggerJsonToYApiData(_x3) {
return _swaggerJsonToYApiData.apply(this, arguments);
}
function _swaggerJsonToYApiData() {
_swaggerJsonToYApiData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(data) {
var _yapiData$swaggerData;
var yapiData, currentTime, project, cats, interfaces;
return _regeneratorRuntime.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 = dayjs().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 _extends({}, 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);
}