@shixinde/apifox-swagger
Version:
从 Apifox 导出 Swagger/OpenAPI 文档并生成 TypeScript 类型定义的工具
135 lines (134 loc) • 5.25 kB
JavaScript
import * as l from "fs-extra";
import * as p from "openapi-typescript";
import * as u from "tiny-invariant";
import m from "tiny-invariant";
import "undici";
import { i as P } from "./index-36248d82.js";
const f = [
4523,
4524,
4525,
4526,
4527
], g = [
"127.0.0.1",
"localhost"
], d = async (t) => {
let e;
const a = t && t.length > 0 ? t : [
0,
1,
2,
3,
4,
5
];
console.log(`Trying to connect to local Apifox client on hosts: ${g.join(", ")} and ports: ${f.join(", ")}`);
for (const n of g)
for (const r of f) {
console.log(`Checking ${n}:${r}...`);
for (const i of a)
try {
const o = `http://${n}:${r}/export/openapi/${i}?version=3.0`;
console.log(`Trying URL: ${o}`);
const s = await fetch(o, {
method: "GET",
timeout: 3e3
// 3秒超时
});
if (console.log(`Response status: ${s.status}`), s.status === 200)
return console.log(`Successfully fetched swagger from ${o}`), e = await s.json(), e;
} catch (o) {
console.log(`Failed to connect to ${n}:${r}/export/openapi/${i}: ${o.message}`);
continue;
}
}
return console.log("All connection attempts failed."), e;
}, h = async (t, e, a) => {
(0, u.default)(
a,
"APIFOX_ACCESS_TOKEN is required"
);
const n = e ? {
type: "SELECTED_FOLDERS",
// 导出指定文件夹
selectedFolderIds: [
e
]
} : {
type: "ALL"
// 导出整个项目
};
return await (await fetch(`https://api.apifox.com/v1/projects/${t}/export-openapi?locale=zh-CN`, {
method: "POST",
headers: {
"X-Apifox-Api-Version": "2024-03-28",
// API 版本
"Content-Type": "application/json",
Authorization: `Bearer ${a}`
// 访问令牌
},
redirect: "follow",
body: JSON.stringify({
scope: n,
// 导出范围
options: {
includeApifoxExtensionProperties: !1,
// 不包含 Apifox 扩展属性
addFoldersToTags: !1
// 不将文件夹添加为标签
},
oasVersion: "3.1",
// OpenAPI 规范版本
exportFormat: "JSON"
// 导出格式
})
})).json();
}, x = async ({ projectId: t, outdir: e, folderId: a, folderName: n, useLocal: r, token: i }) => {
let o;
if (r) {
if (console.log("Fetching swagger from local Apifox client..."), o = await d(t ? [t] : void 0), !o)
throw new Error("Failed to fetch swagger from local Apifox client. Please ensure Apifox is running and has projects loaded.");
} else {
const w = a ? `folder [${a}] to <${n}>` : "to <all>";
console.log(`Fetching swagger from apifox project [${t}] ${w}...`), o = await h(t, a, i);
}
const s = `${e}/swagger/${n ?? "all"}.json`, c = `${e}/swagger/${n ?? "all"}.ts`;
!o.openapi && o.swagger && (console.log("Converting Swagger 2.0 to OpenAPI 3.0 format..."), o.openapi = "3.0.0", delete o.swagger, o.info || (o.info = { title: "API", version: "1.0.0" }), o.paths || (o.paths = {})), o.openapi || (o.openapi = "3.0.0"), o.info || (o.info = { title: "API", version: "1.0.0" }), o.paths || (o.paths = {}), console.log(`Swagger format: ${o.openapi || o.swagger || "unknown"}`);
const _ = await (0, p.default)(o, {});
return l.default.ensureDirSync(`${e}/swagger`), l.default.writeJsonSync(s, o, {
spaces: 2
// 格式化 JSON,使用 2 个空格缩进
}), l.default.writeFileSync(
c,
(0, p.astToString)(_)
), console.log(`Exported swagger [json] to ${s}`), console.log(`Exported swagger [type] to ${c}`), o;
}, A = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
exportSwagger: x,
fetchSwagger: h,
fetchSwaggerLocal: d
}, Symbol.toStringTag, { value: "Module" })), T = (t) => {
console.log("cli ===>", t), t.command("apifox-swagger").description("Fetch apifox client").option("--projectId <projectId>", "The project id of the apifox").option("-o, --outdir <outdir>", "The outdir format of the apifox", {
default: `./.${t.name}/apifox`
}).option("--folderId <folderId>", "The folder id of the apifox").option("--folderName <folderName>", "The folder name of the apifox").option("--local", "Fetch from local Apifox client instead of cloud API").option("--token <token>", "Apifox access token (alternative to APIFOX_ACCESS_TOKEN env var)").action(async (e) => {
var r, i;
console.log("options ===>", e), e.local ? console.log("Fetching apifox client from local Apifox application...") : (m(e.projectId, "projectId is required when not using --local option"), console.log(`Fetching apifox client https://api.apifox.com/v1/projects/${e.projectId}/export-openapi?locale=zh-CN...`));
const a = e.token || ((i = (r = globalThis.process) == null ? void 0 : r.env) == null ? void 0 : i.APIFOX_ACCESS_TOKEN), { exportSwagger: n } = await Promise.resolve().then(() => A);
await n({
projectId: e.projectId,
outputDir: e.outdir,
folderId: e.folderId,
folderName: e.folderName,
useLocal: e.local,
token: a
});
});
};
export {
P as apiTypes,
x as exportSwagger,
h as fetchSwagger,
d as fetchSwaggerLocal,
T as initCommandApifox
};