提交 a4020e3c authored 作者: 王绍森's avatar 王绍森

init

上级
/apis
/models
/node_modules
.DS_Store
api-doc.json
\ No newline at end of file
1. 修改index.js的URL,
2. 在命令运行node src/index.js
\ No newline at end of file
const fs = require('fs');
const path = require('path');
const { deleteFolderRecursive } = require('./utils');
const { EROFS } = require('constants');
function getSubType(subtye) {
// List«组织机构模型(OrgModel})»
// 组织机构模型(OrgModel})
// Page«组织机构模型(OrgModel})»
// boolean
if (!subtye) {
console.error("subtype为空: ", subtye);
return;
}
if (!subtye.includes('«')) {
let hasparent = subtye.match(/.*\((.+)\).*/)
if (hasparent) {
return hasparent[1]
}
return subtye
}
if (subtye.startsWith('Page«')) {
return `page<${getSubType(subtye.slice(5, -1))}>`;
}
if (subtye.startsWith('List«')) {
return `List<${getSubType(subtye.slice(5, -1))}>`;
}
if (subtye.startsWith('Result«')) {
return `Result<${getSubType(subtye.slice(7, -1))}>`;
}
throw new Error("为识别的subtype:" + subtye)
}
/**
* 获取ref的类型
*
*/
function getTypeofDefinitions(ref) {
// '#/definitions/Result«boolean»'
// '#/definitions/Result«List«资源管理模型(ModuleModel})»»'
// "#/definitions/资源管理新增参数模型"
return getSubType(ref.replace('#/definitions/', ''));
}
function convertType(item, importedModels) {
const {type, $ref} = item;
if (type === 'integer' || type === 'number') {
return 'number';
}
if (type === 'array') {
return convertType(item.items, importedModels) + '[]';
}
if ($ref) {
const typeofRef = getTypeofDefinitions($ref)
return typeofRef;
}
return type;
}
function getFields (properties, importedModels) {
return Object.keys(properties).map(key => {
const { type, description, $ref } = properties[key];
const desc = (description ? `
/**
* ${description}
*/
` : '') + `${key}: `;
let fieldType = convertType(properties[key], importedModels);
if (!fieldType) {
console.log("\n\n未识别的type:" + type)
console.log(properties[key])
return false;
}
return desc + fieldType + ';\n';
}).filter(i => i).join('\n');
}
function getModelInterface(title, name, properties) {
const imprtedModels = [];
const titleComment = title ? `
/**
* ${title}
*/
` : '';
let modelInterface = titleComment + `
export default interface ${name} {
${properties ? getFields(properties, imprtedModels) : ''}
}
`;
imprtedModels.forEach(importModel => {
modelInterface = `\nimport ${importModel} from './${importModel}';\n` + modelInterface
});
return modelInterface;
}
function generateModels(definitions) {
const modelDirectory = path.resolve(__dirname, '../models');
if (!fs.existsSync(modelDirectory)) {
fs.mkdirSync(modelDirectory);
} else {
deleteFolderRecursive(modelDirectory);
fs.mkdirSync(modelDirectory);
}
const modelNames = Object.keys(definitions);
for (let index = 0; index < modelNames.length; index++) {
const modelName = modelNames[index];
// Page, Map, Result不用生成Model文件,用泛型处理
if (['Page«', 'Map«', 'Result«'].some(i => modelName.startsWith(i))) continue;
let title, name;
const { properties } = definitions[modelName];
// 模型中文名称加模型英文名称的类型, 比如:投票候选人(VoteCandidatesModel)
const match = modelName.match(/^(.+)\((.+)\)$/);
if (match) {
title = match[1];
name = match[2];
} else if (modelName) {
// modelName只是一个单词
name = modelName;
}
if (name) {
const modelCotent = getModelInterface(title, name, properties);
fs.writeFileSync(path.resolve(__dirname, `../models/${name}.ts`), modelCotent, {encoding: "utf-8"});
console.log('write model: ', name);
}
}
}
/**
* 根据接口的parameters对象生成TS的接口参数字符串
* @param {*} parameters
*/
function getParamsString(parameters, importedModels) {
const parametersUsed = parameters ? parameters.filter(i => i.in !== 'header') : null;
const paramsString = parametersUsed ? parametersUsed.map(param => {
let fieldType = convertType(param, importedModels);
if (fieldType) {
console.error("函数参数类型获取失败:", param);
}
return `${param.name}${param.required ? '' : '?'}: ${fieldType}`
}).join(', ') : null;
if (paramsString) {
return 'params: { ' + paramsString + ' }'
}
return '';
}
/**
* 根据接口response[200]里面的
* @param {*} schema
*/
function getReturnType(schema, importedModels) {
// $ref: "#/definitions/Page«问卷库(QuestionnaireModel)»"
// type: "boolean"
const type = convertType(schema,importedModels);
return type;
}
function getApiMethods(apiMethodMap, apiName) {
const importedModels = [];
let content = `import request from './request'`;
const methodNames = Object.keys(apiMethodMap);
for (let index = 0; index < methodNames.length; index++) {
const methodName = methodNames[index];
const { post } = apiMethodMap[methodName];
if (!post) continue;
const { parameters, responses } = post;
const paramsString = getParamsString(parameters, importedModels);
if (!responses) {
console.log('response undefined: ', apiMethodMap[methodName]);
}
const returnType = getReturnType(responses[200].schema, importedModels);
content += `
\t export function ${methodName}(${paramsString}): Promise<${returnType}> {
return request('/${apiName}/${methodName}', ${paramsString ? 'params' : ''});
}
`;
}
return importedModels.join("\n") + content;
}
function generateFunctions(paths) {
const apisDirectory = path.resolve(__dirname, '../apis');
if (!fs.existsSync(apisDirectory)) {
fs.mkdirSync(apisDirectory);
} else {
deleteFolderRecursive(apisDirectory);
fs.mkdirSync(apisDirectory);
}
const pathnameList = Object.keys(paths);
// {
// HomeApi: { getPagge: {...}, add: {...} },
// }
const apiMap = {};
for (let index = 0; index < pathnameList.length; index++) {
const pathname = pathnameList[index];
const [_, apiName, methodName] = pathname.split('/');
if (!apiMap[apiName]) {
apiMap[apiName] = {};
}
apiMap[apiName][methodName] = paths[pathname];
}
let apiNames = Object.keys(apiMap);
for (let index = 0; index < apiNames.length; index++) {
const apiName = apiNames[index];
fs.writeFileSync(path.resolve(__dirname, `../apis/${apiName}.ts`), getApiMethods(apiMap[apiName], apiName), {encoding: 'utf-8'});
console.log('write api functions: ', apiName);
}
}
module.exports = function() {
const jsonData = fs.readFileSync(path.resolve(__dirname, '../api-doc.json'), { encoding: 'utf-8'});
const jsonObject = JSON.parse(jsonData);
// 网关
const gateWay = jsonObject.basePath;
generateModels(jsonObject.definitions);
generateFunctions(jsonObject.paths)
}
\ No newline at end of file
const http = require("http");
const fs = require('fs');
module.exports = function(jsonurl, callback) {
http.get(jsonurl, {
headers: {
'Content-Type': 'ext/html;charset=UTF-8',
},
}, (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
fs.writeFileSync('./api-doc.json', rawData, { encoding: 'utf-8'});
console.log('write api-doc.json success!');
if (callback) {
callback(null)
}
} catch (e) {
console.error(e.message);
callback(e)
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
}
\ No newline at end of file
const getSwaggerJSON = require('./getSwaggerJSON');
const generat = require('./generat')
const url = 'http://192.168.1.122/produce/v1/api/uia/v2/api-docs'
getSwaggerJSON(url, (err) => {
if (!err) {
generat();
}
});
\ No newline at end of file
const fs = require("fs");
module.exports.deleteFolderRecursive = function(path) {
if( fs.existsSync(path) ) {
fs.readdirSync(path).forEach(function(file) {
const curPath = path + "/" + file;
if(fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
};
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论