| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- const baseController = require('controllers/base.js');
- const interfaceModel = require('models/interface.js');
- const projectModel = require('models/project.js');
- const interfaceCatModel = require('models/interfaceCat.js');
- const yapi = require('yapi.js');
- class exportSwaggerController extends baseController {
- constructor(ctx) {
- super(ctx);
- this.catModel = yapi.getInst(interfaceCatModel);
- this.interModel = yapi.getInst(interfaceModel);
- this.projectModel = yapi.getInst(projectModel);
- }
- /*
- handleListClass,handleExistId is same as the exportController(yapi-plugin-export-data).
- No DRY,but i have no idea to optimize it.
- */
- async handleListClass(pid, status) {
- let result = await this.catModel.list(pid),
- newResult = [];
- for (let i = 0, item, list; i < result.length; i++) {
- item = result[i].toObject();
- list = await this.interModel.listByInterStatus(item._id, status);
- list = list.sort((a, b) => {
- return a.index - b.index;
- });
- if (list.length > 0) {
- item.list = list;
- newResult.push(item);
- }
- }
- return newResult;
- }
- handleExistId(data) {
- function delArrId(arr, fn) {
- if (!Array.isArray(arr)) return;
- arr.forEach(item => {
- delete item._id;
- delete item.__v;
- delete item.uid;
- delete item.edit_uid;
- delete item.catid;
- delete item.project_id;
- if (typeof fn === 'function') fn(item);
- });
- }
- delArrId(data, function (item) {
- delArrId(item.list, function (api) {
- delArrId(api.req_body_form);
- delArrId(api.req_params);
- delArrId(api.req_query);
- delArrId(api.req_headers);
- if (api.query_path && typeof api.query_path === 'object') {
- delArrId(api.query_path.params);
- }
- });
- });
- return data;
- }
- async exportData(ctx) {
- let pid = ctx.request.query.pid;
- let type = ctx.request.query.type;
- let status = ctx.request.query.status;
- if (!pid) {
- ctx.body = yapi.commons.resReturn(null, 200, 'pid 不为空');
- }
- let curProject;
- let tp = '';
- try {
- curProject = await this.projectModel.get(pid);
- ctx.set('Content-Type', 'application/octet-stream');
- const list = await this.handleListClass(pid, status);
- switch (type) {
- case 'OpenAPIV2':
- { //in this time, only implemented OpenAPI V2.0
- let data = this.handleExistId(list);
- let model = await convertToSwaggerV2Model(data);
- tp = JSON.stringify(model, null, 2);
- ctx.set('Content-Disposition', `attachment; filename=swaggerApi.json`);
- return (ctx.body = tp);
- }
- default:
- {
- ctx.body = yapi.commons.resReturn(null, 400, 'type 无效参数')
- }
- }
- } catch (error) {
- yapi.commons.log(error, 'error');
- ctx.body = yapi.commons.resReturn(null, 502, '下载出错');
- }
- //Convert to SwaggerV2.0 (OpenAPI 2.0)
- async function convertToSwaggerV2Model(list) {
- const swaggerObj = {
- swagger: '2.0',
- info: {
- title: curProject.name,
- version: 'last', // last version
- description: curProject.desc
- },
- //host: "", // No find any info of host in this point :-)
- basePath: curProject.basepath ? curProject.basepath : '/', //default base path is '/'(root)
- tags: (() => {
- let tagArray = [];
- list.forEach(t => {
- tagArray.push({
- name: t.name,
- description: t.desc
- /*externalDocs:{
- descroption:"",
- url:""
- } */
- });
- });
- return tagArray;
- })(),
- schemes: [
- "http" //Only http
- ],
- paths: (() => {
- let apisObj = {};
- for (let aptTag of list) { //list of category
- for (let api of aptTag.list) //list of api
- {
- if (apisObj[api.path] == null) {
- apisObj[api.path] = {};
- }
- apisObj[api.path][api.method.toLowerCase()] = (() => {
- let apiItem = {};
- apiItem['tags'] = [aptTag.name];
- apiItem['summary'] = api.title;
- apiItem['description'] = api.markdown;
- switch (api.req_body_type) {
- case 'form':
- case 'file':
- apiItem['consumes'] = ['multipart/form-data']; //form data required
- break;
- case 'json':
- apiItem['consumes'] = ['application/json'];
- break;
- case 'raw':
- apiItem['consumes'] = ['text/plain'];
- break;
- default:
- break;
- }
- apiItem['parameters'] = (() => {
- let paramArray = [];
- for (let p of api.req_headers) //Headers parameters
- {
- //swagger has consumes proprety, so skip proprety "Content-Type"
- if (p.name === 'Content-Type') {
- continue;
- }
- paramArray.push({
- name: p.name,
- in: 'header',
- description: `${p.name} (Only:${p.value})`,
- required: p.required === 1,
- type: 'string', //always be type string
- default: p.value
- });
- }
- for (let p of api.req_params) //Path parameters
- {
- paramArray.push({
- name: p.name,
- in: 'path',
- description: p.desc,
- required: true, //swagger path parameters required proprety must be always true,
- type: 'string' //always be type string
- });
- }
- for (let p of api.req_query) //Query parameters
- {
- paramArray.push({
- name: p.name,
- in: 'query',
- required: p.required === 1,
- description: p.desc,
- type: 'string' //always be type string
- });
- }
- switch (api.req_body_type) //Body parameters
- {
- case 'form':
- {
- for (let p of api.req_body_form) {
- paramArray.push({
- name: p.name,
- in: 'formData',
- required: p.required === 1,
- description: p.desc,
- type: p.type === 'text' ? 'string' : 'file' //in this time .formData type have only text or file
- });
- }
- break;
- }
- case 'json':
- {
- if (api.req_body_other) {
- let jsonParam = JSON.parse(api.req_body_other);
- if (jsonParam) {
- paramArray.push({
- name: 'root',
- in: 'body',
- description: jsonParam.description,
- schema: jsonParam //as same as swagger's format
- });
- }
- }
- break;
- }
- case 'file':
- {
- paramArray.push({
- name: 'upfile',
- in: 'formData', //use formData
- description: api.req_body_other,
- type: 'file'
- });
- break;
- }
- case 'raw':
- {
- paramArray.push({
- name: 'raw',
- in: 'body',
- description: 'raw paramter',
- schema: {
- type: 'string',
- format: 'binary',
- default: api.req_body_other
- }
- });
- break;
- }
- default:
- break;
- }
- return paramArray;
- })();
- apiItem['responses'] = {
- '200': {
- description: 'successful operation',
- schema: (() => {
- let schemaObj = {};
- if (api.res_body_type === 'raw') {
- schemaObj['type'] = 'string';
- schemaObj['format'] = 'binary';
- schemaObj['default'] = api.res_body;
- } else if (api.res_body_type === 'json') {
- if (api.res_body) {
- let resBody = JSON.parse(api.res_body);
- if (resBody !== null) {
- //schemaObj['type']=resBody.type;
- schemaObj = resBody; //as the parameters,
- }
- }
- }
- return schemaObj;
- })()
- }
- };
- return apiItem;
- })();
- }
- }
- return apisObj;
- })()
- };
- return swaggerObj;
- }
- }
- }
- module.exports = exportSwaggerController;
|