This commit is contained in:
2024-03-01 20:28:14 +08:00
commit 076c21dc36
491 changed files with 84482 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
import { message } from 'antd';
import run from './run';
module.exports = function() {
this.bindHook('import_data', function(importDataModule) {
if (!importDataModule || typeof importDataModule !== 'object') {
console.error('importDataModule 参数Must be Object Type');
return null;
}
importDataModule.swagger = {
name: 'Swagger',
run: async function(res) {
try {
return await run(res);
} catch (err) {
console.error(err);
message.error('解析失败');
}
},
desc: `<p>Swagger数据导入 支持 v2.0+ </p>
<p>
<a target="_blank" href="https://hellosean1025.github.io/yapi/documents/data.html#通过命令行导入接口数据">通过命令行导入接口数据</a>
</p>
`
};
});
};

View File

@@ -0,0 +1,4 @@
module.exports = {
server: true,
client: true
}

View File

@@ -0,0 +1,326 @@
const _ = require('underscore')
const swagger = require('swagger-client');
const compareVersions = require('compare-versions');
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, apis => {
_.each(apis, api => {
_.each(api.responses, 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 = [];
let 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;
}
async function handleSwaggerData(res) {
return await new Promise(resolve => {
let data = swagger({
spec: res
});
data.then(res => {
resolve(res.spec);
});
});
}
async function run(res) {
let interfaceData = { apis: [], cats: [] };
if(typeof res === 'string' && res){
try{
res = JSON.parse(res);
} catch (e) {
console.error('json 解析出错',e.message)
}
}
isOAS3 = res.openapi && compareVersions(res.openapi,'3.0.0') >= 0;
if (isOAS3) {
res = openapi2swagger(res);
}
res = await handleSwaggerData(res);
SwaggerData = res;
interfaceData.basePath = res.basePath || '';
if (res.tags && Array.isArray(res.tags)) {
res.tags.forEach(tag => {
interfaceData.cats.push({
name: tag.name,
desc: tag.description
});
});
}else{
res.tags = []
}
_.each(res.paths, (apis, path) => {
// parameters is common parameters, not a method
delete apis.parameters;
_.each(apis, (api, method) => {
api.path = path;
api.method = method;
let data = null;
try {
data = handleSwagger(api, res.tags);
if (data.catname) {
if (!_.find(interfaceData.cats, item => 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(catData=>{
let catName = catData.name;
return _.find(interfaceData.apis, apiData=>{
return apiData.catname === catName
})
})
return interfaceData;
}
function handleSwagger(data, originTags= []) {
let 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;
for(let i=0; i< data.tags.length; i++){
if(/v[0-9\.]+/.test(data.tags[i])){
continue;
}
// 如果根路径有 tags使用根路径 tags,不使用每个接口定义的 tag 做完分类
if(originTags.length > 0 && _.find(originTags, item=>{
return item.name === data.tags[i]
})){
api.catname = data.tags[i];
break;
}
if(originTags.length === 0){
api.catname = data.tags[i];
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;
}
let keys = key.substr(2).split('/');
keys = keys.filter(item => {
return item;
});
for (let 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(param => {
if (param && typeof param === 'object' && param.$ref) {
param = simpleJsonPathParse(param.$ref, { parameters: SwaggerData.parameters });
}
let defaultParam = {
name: param.name,
desc: param.description,
required: param.required ? '1' : '0'
};
if (param.in) {
switch (param.in) {
case 'path':
api.req_params.push(defaultParam);
break;
case 'query':
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;
}
} 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) {
let res_body = '';
if (!api || typeof api !== 'object') {
return res_body;
}
let codes = Object.keys(api);
let curCode;
if (codes.length > 0) {
if (codes.indexOf('200') > -1) {
curCode = '200';
} else curCode = codes[0];
let 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;
}
module.exports = run;

View File

@@ -0,0 +1,12 @@
module.exports = function(){
this.bindHook('import_data', function(importDataModule){
importDataModule.swagger = async (res)=>{
try{
return await require('./run.js')(res)
}catch(err){
this.commons.log(err, 'error')
return false;
}
}
})
}