UNPKG

cis-api-tool

Version:

根据 swagger/yapi/apifox 的接口定义生成 TypeScript/JavaScript 的接口类型及其请求函数代码。

361 lines (359 loc) 10.8 kB
const require_chunk = require('./chunk-nOFOJqeH.js'); const dayjs = require_chunk.__toESM(require("dayjs")); const swagger_client = require_chunk.__toESM(require("swagger-client")); const lodash = require_chunk.__toESM(require("lodash")); //#region src/swaggerJsonToYApiData.ts let 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"; (0, lodash.each)(data.paths, (apis) => { (0, lodash.each)(apis, (api) => { (0, lodash.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 = []; const 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 new Promise((resolve) => { const data = (0, swagger_client.default)({ spec: res }); data.then((res$1) => { resolve(res$1.spec); }); }); } async function run(res) { const 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); res = await handleSwaggerData(res); SwaggerData = res; interfaceData.swaggerData = SwaggerData; 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 = []; (0, lodash.each)(res.paths, (apis, path) => { delete apis.parameters; (0, lodash.each)(apis, (api, method) => { api.path = path; api.method = method; let data = null; try { data = handleSwagger(api, res.tags); if (data.catname) { if (!(0, lodash.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) => { const catName = catData.name; return (0, lodash.find)(interfaceData.apis, (apiData) => { return apiData.catname === catName; }); }); return interfaceData; } function handleSwagger(data, originTags = []) { const 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; if (originTags.length > 0 && (0, lodash.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; } } 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; } /** * 从 schema 中提取类型信息 * @param schema 参数或响应的 schema 对象 * @returns 类型字符串 */ function extractTypeFromSchema(schema) { if (!schema || typeof schema !== "object") return "string"; if (schema.type) { if (schema.type === "array" && schema.items) { const itemType = extractTypeFromSchema(schema.items); return `array<${itemType}>`; } return schema.type; } if (schema.$ref) return "object"; if (schema.properties) return "object"; if (schema.enum) return "string"; if (schema.format) switch (schema.format) { case "int32": case "int64": return "integer"; case "float": case "double": return "number"; case "date": case "date-time": return "string"; default: return "string"; } return "string"; } /** * 从 schema 中提取类型信息,返回标准类型字符串 * @param schema 参数或响应的 schema 对象 * @returns 标准类型字符串 */ function getStandardTypeFromSchema(schema) { if (!schema || typeof schema !== "object") return "string"; if (schema.type) return schema.type; if (schema.$ref) return "object"; if (schema.properties) return "object"; if (schema.enum) return "string"; if (schema.format) switch (schema.format) { case "int32": case "int64": return "integer"; case "float": case "double": return "number"; case "date": case "date-time": return "string"; default: return "string"; } return "string"; } 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 }); const defaultParam = { name: param.name, desc: param.description, required: param.required ? "1" : "0" }; if (param.in) switch (param.in) { case "path": if (param.schema) { defaultParam.type = getStandardTypeFromSchema(param.schema); if (param.schema.type === "array" && param.schema.items) defaultParam.schema = param.schema; } else defaultParam.type = param.type; api.req_params.push(defaultParam); break; case "query": if (param.schema) { defaultParam.type = getStandardTypeFromSchema(param.schema); if (param.schema.type === "array" && param.schema.items) defaultParam.schema = param.schema; } else defaultParam.type = param.type; api.req_query.push(defaultParam); break; case "body": handleBodyPamras(param.schema, api); break; case "formData": if (param.schema) { const formType = getStandardTypeFromSchema(param.schema); defaultParam.type = formType === "file" ? "file" : "text"; if (param.schema.type === "array" && param.schema.items) defaultParam.schema = param.schema; } else defaultParam.type = param.type === "file" ? "file" : "text"; if (param.example) defaultParam.example = param.example; api.req_body_form.push(defaultParam); break; case "header": if (param.schema) { defaultParam.type = getStandardTypeFromSchema(param.schema); if (param.schema.type === "array" && param.schema.items) defaultParam.schema = param.schema; } else defaultParam.type = param.type; api.req_headers.push(defaultParam); break; default: break; } else { if (param.schema) { defaultParam.type = getStandardTypeFromSchema(param.schema); if (param.schema.type === "array" && param.schema.items) defaultParam.schema = param.schema; } else defaultParam.type = param.type; 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; const codes = Object.keys(api); let curCode; if (codes.length > 0) { if (codes.indexOf("200") > -1) curCode = "200"; else curCode = codes[0]; const 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; } async function swaggerJsonToYApiData(data) { const yapiData = await run(data); if (!yapiData.cats.length) { yapiData.cats = [{ name: "default", desc: "default" }]; yapiData.apis.forEach((api) => { api.catname = "default"; }); } const currentTime = (0, dayjs.default)().unix(); const project = { _id: 0, name: yapiData.swaggerData.info.title, desc: yapiData.swaggerData.info.description || "", basepath: yapiData.swaggerData.basePath || "", tag: [], env: [{ name: "local", domain: `${yapiData.swaggerData.schemes?.[0] || "http"}://${yapiData.swaggerData.host || "127.0.0.1"}` }] }; const cats = yapiData.cats.map((cat, index) => ({ _id: index + 1, name: cat.name, desc: cat.desc, add_time: currentTime, up_time: currentTime })); const interfaces = yapiData.apis.map((api, index) => ({ ...api, _id: index + 1, project_id: 0, catid: cats.find((cat) => cat.name === api.catname)?._id || -1, tag: api.tag || [], add_time: currentTime, up_time: currentTime })); return { project, cats, interfaces }; } //#endregion Object.defineProperty(exports, 'swaggerJsonToYApiData', { enumerable: true, get: function () { return swaggerJsonToYApiData; } });