UNPKG

auto-port

Version:

基于Swagger文档自动生成的接口文档

223 lines (192 loc) 7.66 kB
const fs = require('fs') const path = require('path') const chalk = require('chalk') import { getConfig } from './config' const apiConfig = getConfig() import { checkOutputDirExit, findDefinitions } from './utils' if (apiConfig.cache) { checkOutputDirExit('/port.lock.json') } const axios = require('axios') import { paths, definitions } from './parse' import { enumFile, modelFile, apiFile } from './generate' //调试用 function readLocalFile() { console.time(chalk.blueBright('耗时')) let count = 0 let filelist = ['../mock/swagger.mock4.json'] checkOutputDirExit(apiConfig.outputDir) filelist.forEach(url => { fs.readFile(path.resolve(__dirname, url), 'utf-8', function (err, data) { if (err) { if (filelist.length === ++count) { console.log(chalk.greenBright('API文档生成成功🚀🚀🚀')) console.timeEnd(chalk.blueBright('耗时')) } } else { setTimeout(() => { let res = JSON.parse(data.toString()) compile(res, apiConfig.outputDir) if (filelist.length === ++count) { console.log(chalk.greenBright('API文档生成成功🚀🚀🚀')) console.timeEnd(chalk.blueBright('耗时')) } }, 2000); } }) }) } // debugger // readLocalFile() //正式用 function readOnlineFile() { console.time(chalk.blueBright('耗时')) let count = 0 if (apiConfig.groupList) { apiConfig.groupList.forEach(item => { checkOutputDirExit(item.outputDir) item.list.forEach(url => { axios.get(apiConfig.baseUrl + url).then(r => { if (r.status === 200) { console.log(chalk.greenBright(url + '地址请求成功')) compile(r.data, item.outputDir) if (item.list.length === ++count) { console.log(chalk.greenBright('API文档生成成功🚀🚀🚀')) console.timeEnd(chalk.blueBright('耗时')) } } }).catch(err => { console.log('错误信息:', err); if (err.response.status === 502) { console.log(chalk.redBright(url + '地址请求失败')) } else { console.log(err) } if (item.list.length === ++count) { console.log(chalk.greenBright('API文档生成成功🚀🚀🚀')) console.timeEnd(chalk.blueBright('耗时')) } }) }) }) } else { checkOutputDirExit(apiConfig.outputDir) apiConfig.list.forEach(url => { axios.get(apiConfig.baseUrl + url).then(r => { if (r.status === 200) { console.log(chalk.greenBright(url + '地址请求成功')) compile(r.data, apiConfig.outputDir) if (apiConfig.list.length === ++count) { console.log(chalk.greenBright('API文档生成成功🚀🚀🚀')) console.timeEnd(chalk.blueBright('耗时')) } } }).catch(err => { console.log('错误信息:', err); if (err.response.status === 502) { console.log(chalk.redBright(url + '地址请求失败')) } else { console.log(err) } if (apiConfig.list.length === ++count) { console.log(chalk.greenBright('API文档生成成功🚀🚀🚀')) console.timeEnd(chalk.blueBright('耗时')) } }) }) } } readOnlineFile() function checkFileStructure(dirname) { checkOutputDirExit(dirname) checkOutputDirExit(dirname + '/apis') } function compile(swaggerjson, dirname = './') { if (typeof swaggerjson === 'string') { let source = swaggerjson.replace(/\n/gm, ' '); // 下面校验给定字符串是否为一个合法的json try { // 再看看是不是jsonp的格式 let reg = /^([\w\.]+)\(\s*([\s\S]*)\s*\)$/igm; let matches = reg.exec(source); if (matches != null) { funcName = matches[1]; source = matches[2]; } // 这里可能会throw exception swaggerjson = JSON.parse(source); } catch (ex) { // new Function的方式,能自动给key补全双引号,但是不支持bigint,所以是下下策,放在try-catch里搞 try { swaggerjson = new Function("return " + source)(); } catch (exx) { try { // 再给你一次机会,是不是下面这种情况: "{\"ret\":\"0\", \"msg\":\"ok\"}" swaggerjson = new Function("return '" + source + "'")(); if (typeof swaggerjson === 'string') { // 最后给你一次机会,是个字符串,老夫给你再转一次 swaggerjson = new Function("return " + jsonObj)(); } } catch (exxx) { console.log('===================================='); console.log(exxx); console.log('===================================='); } } } } //转换API let pathMap = paths(swaggerjson.paths) //根据Tag创建对应文件夹 Object.keys(pathMap).forEach(module => { let flag = true let halfUpdadte = apiConfig.updateTags && apiConfig.updateTags.length let moduleApis = pathMap[module] if (halfUpdadte) { if (moduleApis.some(i => i.isNeedUpdate)) { flag = true } else { flag = false } } else { flag = true } if (!flag) { return } let moduleDir = `${dirname}/${module}` checkFileStructure(moduleDir) //获取一个swagger提供的所有的枚举和类型 const { enumMap, modelMap } = definitions(apiConfig.version === 'V2' ? swaggerjson.definitions : swaggerjson.components.schemas) let usedEnum = [] let usedModel = [] findDefinitions(halfUpdadte ? moduleApis.filter(i => i.isNeedUpdate) : moduleApis, usedEnum, usedModel, enumMap, modelMap) //生成enum if (usedEnum.length) { checkOutputDirExit((apiConfig.enumIsUnify ? dirname : moduleDir) + '/Enum') enumFile(module, enumMap, usedEnum, (apiConfig.enumIsUnify ? dirname : moduleDir) + '/Enum') } //生成Request/Response Model if (usedModel.length) { checkOutputDirExit(moduleDir + '/Type') modelFile(module, enumMap, modelMap, usedModel, moduleDir + '/Type') } //生成API apiFile(module, moduleApis, enumMap, modelMap, moduleDir + '/apis', swaggerjson) }) }