apifox-api 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # apifox-api
2
+
3
+ 一个命令行工具,把当前工作目录绑定到 Apifox 项目,搜索接口并生成 TypeScript 类型。数据来自 Apifox 的 OpenAPI 导出 API,按 Module 缓存到本地。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install -g apifox-api
9
+ ```
10
+
11
+ 或直接用 `npx` / `bunx`,无需全局安装。
12
+
13
+ ## 快速开始
14
+
15
+ ### 1. 获取 Apifox projectId 和 Access Token
16
+
17
+ - **projectId**:Apifox 项目设置 → 基本设置 → 项目 ID
18
+ - **Access Token**:Apifox 账号设置 → API 访问令牌,新建一个个人令牌
19
+
20
+ ### 2. 绑定当前工作目录
21
+
22
+ 在你的业务项目根目录运行:
23
+
24
+ ```bash
25
+ apifox-api init <projectId> --authKey <your-access-token>
26
+ ```
27
+
28
+ 如果要绑定多个模块:
29
+
30
+ ```bash
31
+ apifox-api init <projectId> --moduleIds 5,8,12 --authKey <your-access-token>
32
+ ```
33
+
34
+ 绑定信息写入全局注册表 `~/.apifox-api.json`(以工作目录为 key,一台机器可同时绑定多个项目)。`init` 会立即拉取每个 module 的 OpenAPI 快照并缓存到当前目录的 `.cache/apifox-api/` 下。
35
+
36
+ > 不想把 token 写进文件?省略 `--authKey`,改用 `APIFOX_AUTH_KEY` 环境变量(运行时 env 优先于文件中的值)。重新 `init` 同一目录会覆盖旧绑定并打印 before/after。
37
+
38
+ ### 3. 搜索与生成类型
39
+
40
+ ```bash
41
+ # 搜索接口(支持多关键词,默认 or 模式)
42
+ apifox-api search 订单 退款
43
+
44
+ # 按 HTTP 方法过滤
45
+ apifox-api search 订单 --method GET
46
+
47
+ # 为某个接口生成 TS 类型(method + path 来自搜索结果)
48
+ apifox-api get GET /orders/{id}
49
+ ```
50
+
51
+ `search` 输出一个 markdown 表格(方法 / 路径 / 名称 / Tags),并报告命中总数与是否截断。`get` 输出请求参数、请求体和主成功响应的 TypeScript 类型。
52
+
53
+ ## 命令
54
+
55
+ | 命令 | 说明 |
56
+ |---|---|
57
+ | `init <projectId> [--moduleIds 5,8,12] [--authKey <token>]` | 绑定当前目录到 Apifox 项目,写入 `~/.apifox-api.json`,并首次拉取每个 module 的快照 |
58
+ | `search <keyword...> [--mode or\|and] [--method GET] [--limit 20] [--moduleId N]` | 在当前 module 内搜索接口候选 |
59
+ | `get <method> <path> [--moduleId N]` | 为指定接口生成 TypeScript 类型(Operation Key = method + path) |
60
+ | `refresh` | 刷新当前项目全部 module 的 OpenAPI 快照 |
61
+ | `module [moduleId]` | 查看当前 module 与全部 moduleIds,或切换当前 module |
62
+ | `config set-auth-key <token>` | 设置全局默认 Apifox Auth Key(所有未单独配置 authKey 的项目回退到它) |
63
+
64
+ ## 模块(Module)
65
+
66
+ 一个 Apifox 项目可包含多个模块。`init --moduleIds` 绑定你关心的模块:
67
+
68
+ - **单 module**:自动作为当前 module,无需切换,也不生成 `.current-module`。
69
+ - **多 module**:`init` 生成 `.current-module` 文件标记当前模块(默认指向第一个);用 `apifox-api module <id>` 切换。
70
+ - `search` 和 `get` 只在当前 module 的快照内工作,**不跨 module 混搜**。
71
+ - 临时只查一次别的 module:加 `--moduleId N`。
72
+ - 不传 `--moduleIds`:使用项目的默认模块。
73
+
74
+ ## 认证
75
+
76
+ Apifox Auth Key 用于访问 Apifox 的 OpenAPI 导出 API,是 CLI 拉取接口数据所必需的凭证。它的来源有以下 3 级优先级(从高到低):
77
+
78
+ 1. 运行时环境变量 `APIFOX_AUTH_KEY`(覆盖一切,方便 CI 与临时切换 token)
79
+ 2. 全局注册表 `~/.apifox-api.json` 中当前项目的 `bindings.authKey`(由 `init --authKey` 写入,只对该项目生效)
80
+ 3. 全局注册表 `~/.apifox-api.json` 顶层的 `authKey`(由 `config set-auth-key` 写入,是所有项目共享的默认值)
81
+
82
+ 如果不想每个项目 `init` 时都带 `--authKey`、也不想设置环境变量,可以运行一次 `apifox-api config set-auth-key <token>` 设一个全局默认,所有没有单独配置 `authKey` 的项目都会回退到它。覆盖时会打印前后 sha256 指纹(脱敏)。
83
+
84
+ `~/.apifox-api.json` 以 `0600` 权限创建(POSIX 有效;Windows 上为尽力而为)。
85
+
86
+ ## 缓存
87
+
88
+ 每个 module 的 OpenAPI 快照单独缓存到绑定目录的 `.cache/apifox-api/` 下,文件名包含 `projectId`、`moduleId`、auth 指纹与导出参数 hash。默认 TTL 24 小时,可用环境变量覆盖:
89
+
90
+ ```bash
91
+ APIFOX_MCP_OPENAPI_TTL_MS=86400000
92
+ ```
93
+
94
+ 读取时若远程刷新失败,会回退到同 token 的过期缓存并附带警告;显式 `refresh` 永不回退,远程失败即报错。
95
+
96
+ ## 从旧版(apifox-mcp MCP server)迁移
97
+
98
+ 旧版是 MCP server + 工作区 `.apifox-mcp.json`。升级后:
99
+
100
+ - 在业务项目根目录运行 `apifox-api init <projectId> --authKey <token>`,会自动检测并迁移旧 `.apifox-mcp.json` 中的 `projectId`。
101
+ - 旧文件 `.apifox-mcp.json` 不再生效,建议手动删除。
102
+
103
+ ## 开发
104
+
105
+ ```bash
106
+ bun install
107
+ bun test
108
+ bunx tsc --noEmit
109
+ bun run build
110
+ ```
111
+
112
+ ## AI 协作
113
+
114
+ 本仓库附带一份 Cursor Agent Skill(`.cursor/skills/apifox-api/SKILL.md`),告诉 AI 何时先 `search` 再 `get`、Operation Key 的概念、以及多 module 项目如何切换当前 module。
Binary file
Binary file
package/dist/index.js ADDED
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ // @bun
3
+ import x0 from"os";import S$ from"path";import N from"fs/promises";import h from"os";import S from"path";import{createHash as H0}from"crypto";var W0=".apifox-api.json",o=".apifox-mcp.json",u=".current-module",I=1,R$=384;function x($){let Q=$.trim();if(!Q)throw Error("请提供 Apifox projectId!");if(Q.startsWith("http://")||Q.startsWith("https://"))throw Error("请提供 Apifox projectId,而不是 Apifox 分享链接 URL。");if(!/^[A-Za-z0-9_-]+$/.test(Q))throw Error("无效的 Apifox projectId,只能包含字母、数字、下划线或短横线。");return Q}function O($){return H0("sha256").update($).digest("hex").slice(0,16)}function g($){if(!Number.isInteger($)||$<=0)throw Error(`无效的 moduleId:${$}。moduleId 必须是正整数。`);return $}function j$($){if($===void 0||$.trim()==="")return[];let Q=$.split(",").map((Z)=>Z.trim()).filter((Z)=>Z.length>0);if(Q.length===0)return[];return Q.map((Z)=>{let J=Number(Z);if(!Number.isInteger(J)||J<=0||String(J)!==Z)throw Error(`无效的 moduleId:${Z}。--moduleIds 必须是逗号分隔的正整数。`);return g(J)})}function U0(){return process.platform==="win32"}function G0($){let Q=$.replace(/\\/g,"/");return U0()?Q.toLowerCase():Q}async function v($){let Q=S.resolve($),Z;try{Z=await N.realpath(Q)}catch{Z=Q}return G0(Z)}function V0($,Q){return $===Q}function y($){return S.join($,W0)}function _$($,Q){let Z=[],J=$;while(!0){if(Z.push(J),V0(J,Q))break;let X=S.posix.dirname(J);if(X===J)break;J=X}return Z}function B0($,Q){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`无效的 Apifox 绑定记录: ${Q} 必须是 JSON 对象。`);let Z=$;if(typeof Z.projectId!=="string")throw Error(`无效的 Apifox 绑定记录: ${Q} 缺少 projectId。`);let J=Z.authKey;if(J!==void 0&&typeof J!=="string")throw Error(`无效的 Apifox 绑定记录: ${Q} 的 authKey 必须是字符串。`);let X=Z.projectName;if(X!==void 0&&typeof X!=="string")throw Error(`无效的 Apifox 绑定记录: ${Q} 的 projectName 必须是字符串。`);let H=Z.moduleIds,Y;if(H===void 0)Y=[];else if(Array.isArray(H))Y=H.map((W)=>{let U=Number(W);if(!Number.isInteger(U)||U<=0)throw Error(`无效的 Apifox 绑定记录: ${Q} 的 moduleIds 必须是正整数数组。`);return U});else throw Error(`无效的 Apifox 绑定记录: ${Q} 的 moduleIds 必须是数组。`);return{projectId:x(Z.projectId),...typeof J==="string"?{authKey:J}:{},moduleIds:Y,...X?{projectName:X.trim()}:{}}}function z0($,Q){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`无效的 Apifox 全局注册表: ${Q} 必须是 JSON 对象。`);let Z=$;if(Z.schemaVersion!==I)throw Error(`无效的 Apifox 全局注册表: ${Q} 的 schemaVersion 必须是 ${I}。`);let J=Z.bindings;if(!J||typeof J!=="object"||Array.isArray(J))throw Error(`无效的 Apifox 全局注册表: ${Q} 的 bindings 必须是对象。`);let X={};for(let[W,U]of Object.entries(J))X[W]=B0(U,W);let H=Z.authKey,Y;if(H!==void 0){if(typeof H!=="string")throw Error(`无效的 Apifox 全局注册表: ${Q} 的 authKey 必须是字符串。`);let W=H.trim();if(W)Y=W}return{schemaVersion:I,...Y?{authKey:Y}:{},bindings:X}}async function t($){let Q=y($),Z;try{Z=await N.readFile(Q,"utf-8")}catch(J){if(J?.code==="ENOENT"||J?.code==="ENOTDIR")return{schemaVersion:I,bindings:{}};throw Error(`读取 Apifox 全局注册表失败: ${Q}: ${J?.message||String(J)}`)}try{return z0(JSON.parse(Z),Q)}catch(J){if(J instanceof SyntaxError)throw Error(`无效的 Apifox 全局注册表: ${Q} 不是有效 JSON。`);throw J}}async function q$($,Q){let Z=y($);await N.mkdir(S.dirname(Z),{recursive:!0}),await N.writeFile(Z,`${JSON.stringify(Q,null,2)}
4
+ `,{encoding:"utf-8",mode:R$});try{await N.chmod(Z,R$)}catch{}return Z}function L0($,Q,Z){let J=$.APIFOX_AUTH_KEY?.trim();if(J)return{authKey:J,authFingerprint:O(J),usedEnv:!0};if(Q)return{authKey:Q,authFingerprint:O(Q),usedEnv:!1};if(Z)return{authKey:Z,authFingerprint:O(Z),usedEnv:!1};throw Error(["未配置 Apifox Auth Key。可选配置方式(优先级从高到低):"," 1. 环境变量 APIFOX_AUTH_KEY(覆盖一切)"," 2. 在当前目录运行 `apifox-api init <projectId> --authKey <token>`(仅对当前项目生效)"," 3. 运行 `apifox-api config set-auth-key <token>`(全局默认,所有项目共享)"].join(`
5
+ `))}function C0($){let Q=Object.entries($);if(Q.length===0)return"(全局注册表中目前没有任何绑定。)";return Q.map(([Z,J])=>{let X=J.moduleIds.length>0?`, moduleIds=[${J.moduleIds.join(",")}]`:"",H=J.projectName?` (${J.projectName})`:"";return`- ${Z} -> projectId=${J.projectId}${H}${X}`}).join(`
6
+ `)}function R0($,Q,Z){let J=Q.map((X)=>`- ${X}`).join(`
7
+ `);return Error(["当前工作目录还没有绑定 Apifox 项目。",`已解析工作目录: ${$}`,"已检查的目录:",J,"","全局注册表中已有的绑定:",C0(Z),"","请在目标项目根目录运行:"," apifox-api init <projectId> [--moduleIds 5,8,12] [--authKey <token>]"].join(`
8
+ `))}async function T($={}){let Q=$.cwd??process.cwd(),Z=$.homeDir??h.homedir(),J=$.env??process.env,X=await v(Q),H=await v(Z),Y=await t(Z),W=_$(X,H);for(let U of W){let G=Y.bindings[U];if(G){let V=L0(J,G.authKey,Y.authKey),z=F$(U);return{projectId:G.projectId,...V,moduleIds:G.moduleIds,...G.projectName?{projectName:G.projectName}:{},workspaceDir:z,registryPath:y(Z),...G.authKey?{storedAuthKey:G.authKey}:{},source:`全局注册表 ${y(Z)} -> ${U}`}}}throw R0(X,W,Y.bindings)}function F$($){return $}async function N$($){let Q=$.cwd??process.cwd(),Z=$.homeDir??h.homedir(),J=await v(Q),X=await t(Z),H=X.bindings[J],Y=$.projectName?.trim(),W={projectId:x($.projectId),moduleIds:$.moduleIds.map(g),...$.authKey&&$.authKey.trim()?{authKey:$.authKey.trim()}:{},...Y?{projectName:Y}:{}};return X.bindings[J]=W,{registryPath:await q$(Z,X),workspaceKey:J,...H?{previousBinding:H}:{}}}async function O$($){let Q=$.homeDir??h.homedir(),Z=$.authKey.trim();if(!Z)throw Error("authKey 不能为空。");let J=await t(Q),X=J.authKey?O(J.authKey):void 0;return J.authKey=Z,{registryPath:await q$(Q,J),...X?{previousFingerprint:X}:{},nextFingerprint:O(Z)}}async function T$($){let Q=S.join($,o),Z;try{Z=await N.readFile(Q,"utf-8")}catch(J){if(J?.code==="ENOENT"||J?.code==="ENOTDIR")return;throw J}try{let J=JSON.parse(Z);if(typeof J.projectId!=="string")return;return{projectId:x(J.projectId),...typeof J.projectName==="string"&&J.projectName.trim()?{projectName:J.projectName.trim()}:{}}}catch{return}}async function j0($,Q){let Z=await v($),J=await v(Q),X=_$(Z,J);for(let H of X){let Y=S.join(F$(H),u);try{return(await N.readFile(Y,"utf-8")).trim()}catch(W){if(W?.code==="ENOENT"||W?.code==="ENOTDIR")continue;throw W}}return}async function K($){let{moduleIds:Q,moduleIdFlag:Z}=$;if(Q.length===0){if(Z!==void 0)throw Error(`当前项目只使用默认模块,不接受 --moduleId。收到的 --moduleId=${Z}。`);return}if(Z!==void 0){let Y=g(Z);if(!Q.includes(Y))throw Error(`--moduleId ${Y} 不在当前项目绑定的 moduleIds [${Q.join(", ")}] 内。`);return Y}if(Q.length===1)return Q[0];let J=$.cwd??process.cwd(),X=$.homeDir??h.homedir(),H=await j0(J,X);if(H!==void 0&&H!==""){let Y=Number(H);if(!Number.isInteger(Y)||Y<=0)throw Error(`.current-module 文件内容无效: ${H}。请用 \`apifox-api module <moduleId>\` 重置。`);let W=g(Y);if(!Q.includes(W))throw Error(`.current-module 指向的 moduleId ${W} 不在当前项目绑定的 moduleIds [${Q.join(", ")}] 内。请用 \`apifox-api module <moduleId>\` 切换。`);return W}throw Error(["当前项目绑定了多个 module,但未指定当前 module。",`绑定的 moduleIds: [${Q.join(", ")}]`,"请先选择一个 module:"," apifox-api module <moduleId>","或在命令中临时指定:"," --moduleId <moduleId>"].join(`
9
+ `))}async function c($,Q){let Z=S.join($,u);await N.writeFile(Z,`${Q}
10
+ `,"utf-8")}import{createHash as _0}from"crypto";import e from"fs/promises";import l from"path";var p="2024-03-28",E$="zh-CN",P$={scope:{type:"ALL"},options:{includeApifoxExtensionProperties:!1,addFoldersToTags:!1},oasVersion:"3.1",exportFormat:"JSON"},q0=86400000,F0=l.join(".cache","apifox-api");function N0($=process.env){let Q=$.APIFOX_MCP_OPENAPI_TTL_MS;if(!Q)return q0;let Z=Number(Q);if(!Number.isFinite(Z)||Z<0)throw Error("APIFOX_MCP_OPENAPI_TTL_MS 必须是非负数字。");return Z}function O0($){return _0("sha256").update($).digest("hex").slice(0,16)}function T0($){return $.replace(/[^A-Za-z0-9_-]/g,"_")}function $$(){return O0(JSON.stringify({apiVersion:p,locale:E$,body:P$}))}function E0($){return l.join($,F0)}function D$($){return $===void 0?"default":`m${$}`}function P0($,Q,Z=E0($.workspaceDir)){let J=[T0($.projectId),D$(Q),$.authFingerprint,$$(),"openapi.json"].join(".");return l.join(Z,J)}function D0($){let Q={...P$};if($!==void 0)Q.moduleId=$;return Q}async function S0($){try{return(await $.text()).slice(0,500)}catch{return""}}async function A0($,Q,Z,J=fetch){let X=`https://api.apifox.com/v1/projects/${encodeURIComponent($)}/export-openapi?locale=${E$}`,H=await J(X,{method:"POST",headers:{"X-Apifox-Api-Version":p,Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify(D0(Z))});if(!H.ok){let W=await S0(H);throw Error(`请求 Apifox OpenAPI 导出失败 (HTTP ${H.status})${W?`: ${W}`:""}`)}let Y=await H.json();if(!Y||typeof Y!=="object"||!Y.paths)throw Error("Apifox OpenAPI 导出响应不是有效的 OpenAPI JSON,缺少 paths。");return Y}async function K0($){try{return JSON.parse(await e.readFile($,"utf-8"))}catch{return}}async function M0($,Q){await e.mkdir(l.dirname($),{recursive:!0}),await e.writeFile($,JSON.stringify(Q,null,2),"utf-8")}function w0($,Q,Z){return Q-$.timestamp<Z}function v0($,Q,Z){let J=$.moduleId,X=Z===void 0;if(X!==(J===void 0))return!1;if(!X&&J!==Z)return!1;return $.projectId===Q.projectId&&$.authFingerprint===Q.authFingerprint&&$.exportApiVersion===p&&$.exportParamsHash===$$()}async function b($,Q,Z={}){let J=Z.env??process.env,X=Z.now?.()??Date.now(),H=N0(J),Y=P0($,Q,Z.cacheDir),W=await K0(Y),U=W&&v0(W,$,Q)?W:void 0;if(!Z.forceRefresh&&U&&w0(U,X,H))return{data:U.data,cachePath:Y,refreshed:!1,stale:!1,moduleId:Q};try{let G=await A0($.projectId,$.authKey,Q,Z.fetchImpl),V={timestamp:X,projectId:$.projectId,...Q!==void 0?{moduleId:Q}:{},authFingerprint:$.authFingerprint,exportApiVersion:p,exportParamsHash:$$(),data:G};return await M0(Y,V),{data:G,cachePath:Y,refreshed:!0,stale:!1,moduleId:Q}}catch(G){let V=G?.message||String(G);if(!Z.forceRefresh&&Z.allowStaleOnError!==!1&&U)return{data:U.data,cachePath:Y,refreshed:!1,stale:!0,warning:`OpenAPI 快照刷新失败,已使用本地过期缓存: ${V}`,moduleId:Q};throw Error(`刷新 OpenAPI 快照失败 (moduleId=${D$(Q)}): ${V}`)}}async function m($,Q={}){let Z=$.moduleIds.length===0?[void 0]:$.moduleIds,J=[];for(let X of Z){let H=await b($,X,Q);J.push({...H,moduleId:X})}return J}var A$=["用法: apifox-api init <projectId> [--moduleIds 5,8,12] [--authKey <token>]","","说明:","- 把当前工作目录绑定到一个 Apifox projectId,写入全局注册表 ~/.apifox-api.json。","- --moduleIds:逗号分隔的正整数,绑定多个模块;省略表示只使用默认模块。","- --authKey:Apifox Access Token,会存入全局注册表;省略时回退 APIFOX_AUTH_KEY 环境变量。"].join(`
11
+ `);function b0($){let Q,Z,J,X=!1,H=!1;for(let Y=0;Y<$.length;Y+=1){let W=$[Y];if(W===void 0)continue;if(W==="--moduleIds"){if(X)throw Error("--moduleIds 只能提供一次。");let U=$[Y+1];if(U===void 0||U.startsWith("--")||!U.trim())throw Error("--moduleIds 需要提供逗号分隔的正整数。");Z=U,X=!0,Y+=1;continue}if(W==="--authKey"){if(H)throw Error("--authKey 只能提供一次。");let U=$[Y+1];if(U===void 0||U.startsWith("--")||!U.trim())throw Error("--authKey 需要提供非空 token。");J=U.trim(),H=!0,Y+=1;continue}if(W.startsWith("--"))throw Error(`未知 init 参数: ${W}`);if(Q!==void 0)throw Error(`init 只能接受一个 projectId,多余参数: ${W}`);Q=W}if(!Q)throw Error("请提供 Apifox projectId。");return{projectId:x(Q),moduleIds:j$(Z),...J?{authKey:J}:{}}}function k0($,Q){if($&&$.trim())return $.trim();return Q.APIFOX_AUTH_KEY?.trim()||void 0}function f0($,Q,Z,J,X){return{projectId:$,authKey:Q,authFingerprint:O(Q),moduleIds:Z,...X?{projectName:X}:{},workspaceDir:J,registryPath:"",source:"init 临时解析"}}function I0($){return $===void 0?"默认模块":`moduleId=${$}`}async function K$($){let Q=$.stdout??process.stdout,Z=$.stderr??process.stderr,J=$.cwd??process.cwd(),X=$.homeDir??x0.homedir(),H=$.env??process.env,Y;try{Y=b0($.args)}catch(z){return Z.write(`apifox-api init 失败: ${z?.message||String(z)}
12
+
13
+ ${A$}
14
+ `),1}let W=k0(Y.authKey,H),U=await T$(J),G;try{G=await N$({cwd:J,homeDir:X,projectId:Y.projectId,...W?{authKey:W}:{},moduleIds:Y.moduleIds,...U?.projectName?{projectName:U.projectName}:{}})}catch(z){return Z.write(`写入全局注册表失败: ${z?.message||String(z)}
15
+
16
+ ${A$}
17
+ `),1}let V=[];if(V.push("已写入 Apifox Project Binding。"),V.push(`workspace: ${G.workspaceKey}`),V.push(`registry: ${G.registryPath}`),V.push(`projectId: ${Y.projectId}`),V.push(`moduleIds: ${Y.moduleIds.length===0?"[](默认模块)":`[${Y.moduleIds.join(", ")}]`}`),W)V.push(`authKey: 已配置(fingerprint=${O(W)})`);else V.push("authKey: 未配置(运行时需通过 APIFOX_AUTH_KEY 提供)");if(G.previousBinding){let z=G.previousBinding.moduleIds.length===0?"[](默认模块)":`[${G.previousBinding.moduleIds.join(", ")}]`;V.push(""),V.push(`已覆盖原有绑定: projectId=${G.previousBinding.projectId}, moduleIds=${z}`)}if(W){let z=f0(Y.projectId,W,Y.moduleIds,G.workspaceKey,U?.projectName);V.push(""),V.push("正在首次拉取接口文档快照..."),Q.write(`${V.join(`
18
+ `)}
19
+ `),V.length=0;try{let B=await m(z,{forceRefresh:!0,allowStaleOnError:!1,...$.fetchImpl?{fetchImpl:$.fetchImpl}:{},...$.now?{now:$.now}:{},env:H});for(let L of B){let C=L.data?.paths?Object.keys(L.data.paths).length:0;V.push(` ✓ ${I0(L.moduleId)} 已缓存(${C} 个路径)`)}}catch(B){Z.write(`首次拉取接口文档快照失败: ${B?.message||String(B)}
20
+ `),Z.write("绑定已建立,可稍后运行 `apifox-api refresh` 重试。\n")}}else V.push(""),V.push("未配置 authKey,已跳过首次拉取。运行时需通过 APIFOX_AUTH_KEY 提供 token。");if(Y.moduleIds.length>1){let z=Y.moduleIds[0];if(z!==void 0)try{await c(G.workspaceKey,z),V.push(""),V.push(`已生成 ${S$.join(G.workspaceKey,u)}(当前 module=${z})。`),V.push("切换当前 module: apifox-api module <moduleId>")}catch(B){Z.write(`写入 .current-module 失败: ${B?.message||String(B)}
21
+ `)}}if(U){let z=S$.join(J,o);V.push(""),V.push(`检测到旧版工作区绑定 ${z} (projectId=${U.projectId})。`),V.push("新版绑定已迁移到全局注册表,旧文件不再生效,建议手动删除。")}return Q.write(`${V.join(`
22
+ `)}
23
+ `),0}import g0 from"os";var y0=["用法: apifox-api refresh","","说明:","- 强制刷新当前工作目录绑定的 Apifox 项目的全部 module 的 OpenAPI 快照。","- moduleIds 为空时刷新默认模块一次。","- 该命令不接受任何参数(位置参数或 --flag 均会报错)。"].join(`
24
+ `);function h0($){return $===void 0?"默认模块":`moduleId=${$}`}async function M$($){let Q=$.stdout??process.stdout,Z=$.stderr??process.stderr,J=$.cwd??process.cwd(),X=$.homeDir??g0.homedir(),H=$.env??process.env;if($.args.length>0){let G=$.args[0];return Z.write(`apifox-api refresh 失败: refresh 不接受任何参数,收到 “${G}”。
25
+
26
+ ${y0}
27
+ `),1}let Y;try{Y=await T({cwd:J,homeDir:X,env:H})}catch(G){return Z.write(`apifox-api refresh 失败: ${G?.message||String(G)}
28
+ `),1}let W;try{W=await m(Y,{forceRefresh:!0,allowStaleOnError:!1,env:H,...$.fetchImpl?{fetchImpl:$.fetchImpl}:{},...$.now?{now:$.now}:{}})}catch(G){return Z.write(`apifox-api refresh 失败: ${G?.message||String(G)}
29
+ `),1}let U=[];U.push(`已刷新 ${W.length} 个 module 的 OpenAPI 快照。`);for(let G of W){let V=G.data?.paths?Object.keys(G.data.paths).length:0;U.push(` ✓ ${h0(G.moduleId)}(${V} 个路径)`)}return Q.write(`${U.join(`
30
+ `)}
31
+ `),0}import u0 from"os";var c0=["用法: apifox-api module [moduleId]","","说明:","- 无参:打印当前 module 与全部绑定的 moduleIds。","- 有参:把 <moduleId> 写入绑定根的 .current-module,完成切换。","- <moduleId> 必须是正整数,且在绑定的 moduleIds 内。"].join(`
32
+ `);function Q$($){return $.length===0?"[](默认模块)":`[${$.join(", ")}]`}function l0($){return $===void 0?"默认模块":`moduleId=${$}`}function p0($){let Q;for(let X of $){if(X===void 0)continue;if(X.startsWith("--"))throw Error(`未知 module 参数: ${X}`);if(Q!==void 0)throw Error(`module 只能接受一个 moduleId,多余参数: ${X}`);Q=X}if(Q===void 0)return{};let Z=Q.trim();if(!Z)throw Error("moduleId 不能为空。");let J=Number(Z);if(!Number.isInteger(J)||J<=0||String(J)!==Z)throw Error(`moduleId 必须是正整数,收到 “${Q}”。`);return{moduleId:J}}async function w$($){let Q=$.stdout??process.stdout,Z=$.stderr??process.stderr,J=$.cwd??process.cwd(),X=$.homeDir??u0.homedir(),H=$.env??process.env,Y;try{Y=p0($.args)}catch(G){return Z.write(`apifox-api module 失败: ${G?.message||String(G)}
33
+
34
+ ${c0}
35
+ `),1}let W;try{W=await T({cwd:J,homeDir:X,env:H})}catch(G){return Z.write(`apifox-api module 失败: ${G?.message||String(G)}
36
+ `),1}if(Y.moduleId===void 0){let G;try{G=await K({cwd:J,homeDir:X,moduleIds:W.moduleIds})}catch(V){return Z.write(`apifox-api module 失败: ${V?.message||String(V)}
37
+ `),Q.write(`绑定的 moduleIds: ${Q$(W.moduleIds)}
38
+ `),1}return Q.write(`当前 module: ${l0(G)}
39
+ `),Q.write(`绑定的 moduleIds: ${Q$(W.moduleIds)}
40
+ `),0}let U=Y.moduleId;if(!W.moduleIds.includes(U))return Z.write(`apifox-api module 失败: moduleId ${U} 不在绑定的 moduleIds ${Q$(W.moduleIds)} 内。
41
+ `),1;try{await c(W.workspaceDir,U)}catch(G){return Z.write(`apifox-api module 失败: 写入 .current-module 失败: ${G?.message||String(G)}
42
+ `),1}return Q.write(`已切换当前 module 为 ${U}。
43
+ `),0}import m0 from"os";var d0=["用法: apifox-api config set-auth-key <token>","","说明:","- 设置全局默认 Apifox Auth Key。","- 所有未单独配置 authKey 的项目都会回退到这个全局 token。","- <token> 不能为空或纯空白。"].join(`
44
+ `);function a0($){let Q=$[0];if(Q===void 0)throw Error("config 需要子命令。用法: apifox-api config set-auth-key <token>");if(Q!=="set-auth-key")throw Error(`未知的 config 子命令: ${Q}。当前支持: set-auth-key <token>`);let Z=$[1];if(Z===void 0||Z.trim()==="")throw Error("config set-auth-key 需要一个 <token> 参数。");let J=$[2];if(J!==void 0)throw Error(`config set-auth-key 只接受一个 <token>,多余参数: ${J}`);return{action:"set-auth-key",authKey:Z.trim()}}async function v$($){let Q=$.stdout??process.stdout,Z=$.stderr??process.stderr,J=$.homeDir??m0.homedir(),X=$.env??process.env,H;try{H=a0($.args)}catch(W){return Z.write(`apifox-api config 失败: ${W?.message||String(W)}
45
+
46
+ ${d0}
47
+ `),1}let Y;try{Y=await O$({homeDir:J,authKey:H.authKey})}catch(W){return Z.write(`apifox-api config 失败: ${W?.message||String(W)}
48
+ `),1}if(Q.write(`已设置全局默认 Apifox Auth Key。
49
+ `),Y.previousFingerprint!==void 0)Q.write(` 之前: ${Y.previousFingerprint}
50
+ `);else Q.write(` 之前: (无)
51
+ `);return Q.write(` 现在: ${Y.nextFingerprint}
52
+ `),Q.write(` 写入: ${Y.registryPath}
53
+ `),Q.write(`所有未单独配置 authKey 的项目都会回退到这个全局 token。
54
+ `),0}import C5 from"os";class n{constructor($,Q){let Z=$._tree,J=Array.from(Z.keys());this.set=$,this._type=Q,this._path=J.length>0?[{node:Z,keys:J}]:[]}next(){let $=this.dive();return this.backtrack(),$}dive(){if(this._path.length===0)return{done:!0,value:void 0};let{node:$,keys:Q}=M(this._path);if(M(Q)==="")return{done:!1,value:this.result()};let Z=$.get(M(Q));return this._path.push({node:Z,keys:Array.from(Z.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;let $=M(this._path).keys;if($.pop(),$.length>0)return;this._path.pop(),this.backtrack()}key(){return this.set._prefix+this._path.map(({keys:$})=>M($)).filter(($)=>$!=="").join("")}value(){return M(this._path).node.get("")}result(){switch(this._type){case"VALUES":return this.value();case"KEYS":return this.key();default:return[this.key(),this.value()]}}[Symbol.iterator](){return this}}var M=($)=>{return $[$.length-1]},n0=($,Q,Z)=>{let J=new Map;if(Q===void 0)return J;let X=Q.length+1,H=X+Z,Y=new Uint8Array(H*X).fill(Z+1);for(let W=0;W<X;++W)Y[W]=W;for(let W=1;W<H;++W)Y[W*X]=W;return I$($,Q,Z,J,Y,1,X,""),J},I$=($,Q,Z,J,X,H,Y,W)=>{let U=H*Y;$:for(let G of $.keys())if(G===""){let V=X[U-1];if(V<=Z)J.set(W,[$.get(G),V])}else{let V=H;for(let z=0;z<G.length;++z,++V){let B=G[z],L=Y*V,C=L-Y,R=X[L],j=Math.max(0,V-Z-1),P=Math.min(Y-1,V+Z);for(let q=j;q<P;++q){let r=B!==Q[q],k=X[C+q]+ +r,D=X[C+q+1]+1,f=X[L+q]+1,C$=X[L+q+1]=Math.min(k,D,f);if(C$<R)R=C$}if(R>Z)continue $}I$($.get(G),Q,Z,J,X,V,Y,W+G)}};class E{constructor($=new Map,Q=""){this._size=void 0,this._tree=$,this._prefix=Q}atPrefix($){if(!$.startsWith(this._prefix))throw Error("Mismatched prefix");let[Q,Z]=i(this._tree,$.slice(this._prefix.length));if(Q===void 0){let[J,X]=G$(Z);for(let H of J.keys())if(H!==""&&H.startsWith(X)){let Y=new Map;return Y.set(H.slice(X.length),J.get(H)),new E(Y,$)}}return new E(Q,$)}clear(){this._size=void 0,this._tree.clear()}delete($){return this._size=void 0,i0(this._tree,$)}entries(){return new n(this,"ENTRIES")}forEach($){for(let[Q,Z]of this)$(Q,Z,this)}fuzzyGet($,Q){return n0(this._tree,$,Q)}get($){let Q=H$(this._tree,$);return Q!==void 0?Q.get(""):void 0}has($){let Q=H$(this._tree,$);return Q!==void 0&&Q.has("")}keys(){return new n(this,"KEYS")}set($,Q){if(typeof $!=="string")throw Error("key must be a string");return this._size=void 0,Z$(this._tree,$).set("",Q),this}get size(){if(this._size)return this._size;this._size=0;let $=this.entries();while(!$.next().done)this._size+=1;return this._size}update($,Q){if(typeof $!=="string")throw Error("key must be a string");this._size=void 0;let Z=Z$(this._tree,$);return Z.set("",Q(Z.get(""))),this}fetch($,Q){if(typeof $!=="string")throw Error("key must be a string");this._size=void 0;let Z=Z$(this._tree,$),J=Z.get("");if(J===void 0)Z.set("",J=Q());return J}values(){return new n(this,"VALUES")}[Symbol.iterator](){return this.entries()}static from($){let Q=new E;for(let[Z,J]of $)Q.set(Z,J);return Q}static fromObject($){return E.from(Object.entries($))}}var i=($,Q,Z=[])=>{if(Q.length===0||$==null)return[$,Z];for(let J of $.keys())if(J!==""&&Q.startsWith(J))return Z.push([$,J]),i($.get(J),Q.slice(J.length),Z);return Z.push([$,Q]),i(void 0,"",Z)},H$=($,Q)=>{if(Q.length===0||$==null)return $;for(let Z of $.keys())if(Z!==""&&Q.startsWith(Z))return H$($.get(Z),Q.slice(Z.length))},Z$=($,Q)=>{let Z=Q.length;$:for(let J=0;$&&J<Z;){for(let H of $.keys())if(H!==""&&Q[J]===H[0]){let Y=Math.min(Z-J,H.length),W=1;while(W<Y&&Q[J+W]===H[W])++W;let U=$.get(H);if(W===H.length)$=U;else{let G=new Map;G.set(H.slice(W),U),$.set(Q.slice(J,J+W),G),$.delete(H),$=G}J+=W;continue $}let X=new Map;return $.set(Q.slice(J),X),X}return $},i0=($,Q)=>{let[Z,J]=i($,Q);if(Z===void 0)return;if(Z.delete(""),Z.size===0)g$(J);else if(Z.size===1){let[X,H]=Z.entries().next().value;y$(J,X,H)}},g$=($)=>{if($.length===0)return;let[Q,Z]=G$($);if(Q.delete(Z),Q.size===0)g$($.slice(0,-1));else if(Q.size===1){let[J,X]=Q.entries().next().value;if(J!=="")y$($.slice(0,-1),J,X)}},y$=($,Q,Z)=>{if($.length===0)return;let[J,X]=G$($);J.set(X+Q,Z),J.delete(X)},G$=($)=>{return $[$.length-1]},V$="or",h$="and",s0="and_not";class A{constructor($){if(($===null||$===void 0?void 0:$.fields)==null)throw Error('MiniSearch: option "fields" must be provided');let Q=$.autoVacuum==null||$.autoVacuum===!0?Y$:$.autoVacuum;this._options={...X$,...$,autoVacuum:Q,searchOptions:{...x$,...$.searchOptions||{}},autoSuggestOptions:{...$5,...$.autoSuggestOptions||{}}},this._index=new E,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=U$,this.addFields(this._options.fields)}add($){let{extractField:Q,stringifyField:Z,tokenize:J,processTerm:X,fields:H,idField:Y}=this._options,W=Q($,Y);if(W==null)throw Error(`MiniSearch: document does not have ID field "${Y}"`);if(this._idToShortId.has(W))throw Error(`MiniSearch: duplicate ID ${W}`);let U=this.addDocumentId(W);this.saveStoredFields(U,$);for(let G of H){let V=Q($,G);if(V==null)continue;let z=J(Z(V,G),G),B=this._fieldIds[G],L=new Set(z).size;this.addFieldLength(U,B,this._documentCount-1,L);for(let C of z){let R=X(C,G);if(Array.isArray(R))for(let j of R)this.addTerm(B,U,j);else if(R)this.addTerm(B,U,R)}}}addAll($){for(let Q of $)this.add(Q)}addAllAsync($,Q={}){let{chunkSize:Z=10}=Q,J={chunk:[],promise:Promise.resolve()},{chunk:X,promise:H}=$.reduce(({chunk:Y,promise:W},U,G)=>{if(Y.push(U),(G+1)%Z===0)return{chunk:[],promise:W.then(()=>new Promise((V)=>setTimeout(V,0))).then(()=>this.addAll(Y))};else return{chunk:Y,promise:W}},J);return H.then(()=>this.addAll(X))}remove($){let{tokenize:Q,processTerm:Z,extractField:J,stringifyField:X,fields:H,idField:Y}=this._options,W=J($,Y);if(W==null)throw Error(`MiniSearch: document does not have ID field "${Y}"`);let U=this._idToShortId.get(W);if(U==null)throw Error(`MiniSearch: cannot remove document with ID ${W}: it is not in the index`);for(let G of H){let V=J($,G);if(V==null)continue;let z=Q(X(V,G),G),B=this._fieldIds[G],L=new Set(z).size;this.removeFieldLength(U,B,this._documentCount,L);for(let C of z){let R=Z(C,G);if(Array.isArray(R))for(let j of R)this.removeTerm(B,U,j);else if(R)this.removeTerm(B,U,R)}}this._storedFields.delete(U),this._documentIds.delete(U),this._idToShortId.delete(W),this._fieldLength.delete(U),this._documentCount-=1}removeAll($){if($)for(let Q of $)this.remove(Q);else if(arguments.length>0)throw Error("Expected documents to be present. Omit the argument to remove all documents.");else this._index=new E,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}discard($){let Q=this._idToShortId.get($);if(Q==null)throw Error(`MiniSearch: cannot discard document with ID ${$}: it is not in the index`);this._idToShortId.delete($),this._documentIds.delete(Q),this._storedFields.delete(Q),(this._fieldLength.get(Q)||[]).forEach((Z,J)=>{this.removeFieldLength(Q,J,this._documentCount,Z)}),this._fieldLength.delete(Q),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()}maybeAutoVacuum(){if(this._options.autoVacuum===!1)return;let{minDirtFactor:$,minDirtCount:Q,batchSize:Z,batchWait:J}=this._options.autoVacuum;this.conditionalVacuum({batchSize:Z,batchWait:J},{minDirtCount:Q,minDirtFactor:$})}discardAll($){let Q=this._options.autoVacuum;try{this._options.autoVacuum=!1;for(let Z of $)this.discard(Z)}finally{this._options.autoVacuum=Q}this.maybeAutoVacuum()}replace($){let{idField:Q,extractField:Z}=this._options,J=Z($,Q);this.discard(J),this.add($)}vacuum($={}){return this.conditionalVacuum($)}conditionalVacuum($,Q){if(this._currentVacuum){if(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&Q,this._enqueuedVacuum!=null)return this._enqueuedVacuum;return this._enqueuedVacuum=this._currentVacuum.then(()=>{let Z=this._enqueuedVacuumConditions;return this._enqueuedVacuumConditions=U$,this.performVacuuming($,Z)}),this._enqueuedVacuum}if(this.vacuumConditionsMet(Q)===!1)return Promise.resolve();return this._currentVacuum=this.performVacuuming($),this._currentVacuum}async performVacuuming($,Q){let Z=this._dirtCount;if(this.vacuumConditionsMet(Q)){let J=$.batchSize||W$.batchSize,X=$.batchWait||W$.batchWait,H=1;for(let[Y,W]of this._index){for(let[U,G]of W)for(let[V]of G){if(this._documentIds.has(V))continue;if(G.size<=1)W.delete(U);else G.delete(V)}if(this._index.get(Y).size===0)this._index.delete(Y);if(H%J===0)await new Promise((U)=>setTimeout(U,X));H+=1}this._dirtCount-=Z}await null,this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null}vacuumConditionsMet($){if($==null)return!0;let{minDirtCount:Q,minDirtFactor:Z}=$;return Q=Q||Y$.minDirtCount,Z=Z||Y$.minDirtFactor,this.dirtCount>=Q&&this.dirtFactor>=Z}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}has($){return this._idToShortId.has($)}getStoredFields($){let Q=this._idToShortId.get($);if(Q==null)return;return this._storedFields.get(Q)}search($,Q={}){let{searchOptions:Z}=this._options,J={...Z,...Q},X=this.executeQuery($,Q),H=[];for(let[Y,{score:W,terms:U,match:G}]of X){let V=U.length||1,z={id:this._documentIds.get(Y),score:W*V,terms:Object.keys(G),queryTerms:U,match:G};if(Object.assign(z,this._storedFields.get(Y)),J.filter==null||J.filter(z))H.push(z)}if($===A.wildcard&&J.boostDocument==null)return H;return H.sort(k$),H}autoSuggest($,Q={}){Q={...this._options.autoSuggestOptions,...Q};let Z=new Map;for(let{score:X,terms:H}of this.search($,Q)){let Y=H.join(" "),W=Z.get(Y);if(W!=null)W.score+=X,W.count+=1;else Z.set(Y,{score:X,terms:H,count:1})}let J=[];for(let[X,{score:H,terms:Y,count:W}]of Z)J.push({suggestion:X,terms:Y,score:H/W});return J.sort(k$),J}get documentCount(){return this._documentCount}get termCount(){return this._index.size}static loadJSON($,Q){if(Q==null)throw Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse($),Q)}static async loadJSONAsync($,Q){if(Q==null)throw Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJSAsync(JSON.parse($),Q)}static getDefault($){if(X$.hasOwnProperty($))return J$(X$,$);else throw Error(`MiniSearch: unknown option "${$}"`)}static loadJS($,Q){let{index:Z,documentIds:J,fieldLength:X,storedFields:H,serializationVersion:Y}=$,W=this.instantiateMiniSearch($,Q);W._documentIds=d(J),W._fieldLength=d(X),W._storedFields=d(H);for(let[U,G]of W._documentIds)W._idToShortId.set(G,U);for(let[U,G]of Z){let V=new Map;for(let z of Object.keys(G)){let B=G[z];if(Y===1)B=B.ds;V.set(parseInt(z,10),d(B))}W._index.set(U,V)}return W}static async loadJSAsync($,Q){let{index:Z,documentIds:J,fieldLength:X,storedFields:H,serializationVersion:Y}=$,W=this.instantiateMiniSearch($,Q);W._documentIds=await a(J),W._fieldLength=await a(X),W._storedFields=await a(H);for(let[G,V]of W._documentIds)W._idToShortId.set(V,G);let U=0;for(let[G,V]of Z){let z=new Map;for(let B of Object.keys(V)){let L=V[B];if(Y===1)L=L.ds;z.set(parseInt(B,10),await a(L))}if(++U%1000===0)await u$(0);W._index.set(G,z)}return W}static instantiateMiniSearch($,Q){let{documentCount:Z,nextId:J,fieldIds:X,averageFieldLength:H,dirtCount:Y,serializationVersion:W}=$;if(W!==1&&W!==2)throw Error("MiniSearch: cannot deserialize an index created with an incompatible version");let U=new A(Q);return U._documentCount=Z,U._nextId=J,U._idToShortId=new Map,U._fieldIds=X,U._avgFieldLength=H,U._dirtCount=Y||0,U._index=new E,U}executeQuery($,Q={}){if($===A.wildcard)return this.executeWildcardQuery(Q);if(typeof $!=="string"){let z={...Q,...$,queries:void 0},B=$.queries.map((L)=>this.executeQuery(L,z));return this.combineResults(B,z.combineWith)}let{tokenize:Z,processTerm:J,searchOptions:X}=this._options,H={tokenize:Z,processTerm:J,...X,...Q},{tokenize:Y,processTerm:W}=H,V=Y($).flatMap((z)=>W(z)).filter((z)=>!!z).map(e0(H)).map((z)=>this.executeQuerySpec(z,H));return this.combineResults(V,H.combineWith)}executeQuerySpec($,Q){let Z={...this._options.searchOptions,...Q},J=(Z.fields||this._options.fields).reduce((C,R)=>({...C,[R]:J$(Z.boost,R)||1}),{}),{boostDocument:X,weights:H,maxFuzzy:Y,bm25:W}=Z,{fuzzy:U,prefix:G}={...x$.weights,...H},V=this._index.get($.term),z=this.termResults($.term,$.term,1,$.termBoost,V,J,X,W),B,L;if($.prefix)B=this._index.atPrefix($.term);if($.fuzzy){let C=$.fuzzy===!0?0.2:$.fuzzy,R=C<1?Math.min(Y,Math.round($.term.length*C)):C;if(R)L=this._index.fuzzyGet($.term,R)}if(B)for(let[C,R]of B){let j=C.length-$.term.length;if(!j)continue;L===null||L===void 0||L.delete(C);let P=G*C.length/(C.length+0.3*j);this.termResults($.term,C,P,$.termBoost,R,J,X,W,z)}if(L)for(let C of L.keys()){let[R,j]=L.get(C);if(!j)continue;let P=U*C.length/(C.length+j);this.termResults($.term,C,P,$.termBoost,R,J,X,W,z)}return z}executeWildcardQuery($){let Q=new Map,Z={...this._options.searchOptions,...$};for(let[J,X]of this._documentIds){let H=Z.boostDocument?Z.boostDocument(X,"",this._storedFields.get(J)):1;Q.set(J,{score:H,terms:[],match:{}})}return Q}combineResults($,Q=V$){if($.length===0)return new Map;let Z=Q.toLowerCase(),J=r0[Z];if(!J)throw Error(`Invalid combination operator: ${Q}`);return $.reduce(J)||new Map}toJSON(){let $=[];for(let[Q,Z]of this._index){let J={};for(let[X,H]of Z)J[X]=Object.fromEntries(H);$.push([Q,J])}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:$,serializationVersion:2}}termResults($,Q,Z,J,X,H,Y,W,U=new Map){if(X==null)return U;for(let G of Object.keys(H)){let V=H[G],z=this._fieldIds[G],B=X.get(z);if(B==null)continue;let L=B.size,C=this._avgFieldLength[z];for(let R of B.keys()){if(!this._documentIds.has(R)){this.removeTerm(z,R,Q),L-=1;continue}let j=Y?Y(this._documentIds.get(R),Q,this._storedFields.get(R)):1;if(!j)continue;let P=B.get(R),q=this._fieldLength.get(R)[z],r=t0(P,L,this._documentCount,q,C,W),k=Z*J*V*j*r,D=U.get(R);if(D){D.score+=k,Q5(D.terms,$);let f=J$(D.match,Q);if(f)f.push(G);else D.match[Q]=[G]}else U.set(R,{score:k,terms:[$],match:{[Q]:[G]}})}}return U}addTerm($,Q,Z){let J=this._index.fetch(Z,f$),X=J.get($);if(X==null)X=new Map,X.set(Q,1),J.set($,X);else{let H=X.get(Q);X.set(Q,(H||0)+1)}}removeTerm($,Q,Z){if(!this._index.has(Z)){this.warnDocumentChanged(Q,$,Z);return}let J=this._index.fetch(Z,f$),X=J.get($);if(X==null||X.get(Q)==null)this.warnDocumentChanged(Q,$,Z);else if(X.get(Q)<=1)if(X.size<=1)J.delete($);else X.delete(Q);else X.set(Q,X.get(Q)-1);if(this._index.get(Z).size===0)this._index.delete(Z)}warnDocumentChanged($,Q,Z){for(let J of Object.keys(this._fieldIds))if(this._fieldIds[J]===Q){this._options.logger("warn",`MiniSearch: document with ID ${this._documentIds.get($)} has changed before removal: term "${Z}" was not present in field "${J}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}}addDocumentId($){let Q=this._nextId;return this._idToShortId.set($,Q),this._documentIds.set(Q,$),this._documentCount+=1,this._nextId+=1,Q}addFields($){for(let Q=0;Q<$.length;Q++)this._fieldIds[$[Q]]=Q}addFieldLength($,Q,Z,J){let X=this._fieldLength.get($);if(X==null)this._fieldLength.set($,X=[]);X[Q]=J;let Y=(this._avgFieldLength[Q]||0)*Z+J;this._avgFieldLength[Q]=Y/(Z+1)}removeFieldLength($,Q,Z,J){if(Z===1){this._avgFieldLength[Q]=0;return}let X=this._avgFieldLength[Q]*Z-J;this._avgFieldLength[Q]=X/(Z-1)}saveStoredFields($,Q){let{storeFields:Z,extractField:J}=this._options;if(Z==null||Z.length===0)return;let X=this._storedFields.get($);if(X==null)this._storedFields.set($,X={});for(let H of Z){let Y=J(Q,H);if(Y!==void 0)X[H]=Y}}}A.wildcard=Symbol("*");var J$=($,Q)=>Object.prototype.hasOwnProperty.call($,Q)?$[Q]:void 0,r0={[V$]:($,Q)=>{for(let Z of Q.keys()){let J=$.get(Z);if(J==null)$.set(Z,Q.get(Z));else{let{score:X,terms:H,match:Y}=Q.get(Z);J.score=J.score+X,J.match=Object.assign(J.match,Y),b$(J.terms,H)}}return $},[h$]:($,Q)=>{let Z=new Map;for(let J of Q.keys()){let X=$.get(J);if(X==null)continue;let{score:H,terms:Y,match:W}=Q.get(J);b$(X.terms,Y),Z.set(J,{score:X.score+H,terms:X.terms,match:Object.assign(X.match,W)})}return Z},[s0]:($,Q)=>{for(let Z of Q.keys())$.delete(Z);return $}},o0={k:1.2,b:0.7,d:0.5},t0=($,Q,Z,J,X,H)=>{let{k:Y,b:W,d:U}=H;return Math.log(1+(Z-Q+0.5)/(Q+0.5))*(U+$*(Y+1)/($+Y*(1-W+W*J/X)))},e0=($)=>(Q,Z,J)=>{let X=typeof $.fuzzy==="function"?$.fuzzy(Q,Z,J):$.fuzzy||!1,H=typeof $.prefix==="function"?$.prefix(Q,Z,J):$.prefix===!0,Y=typeof $.boostTerm==="function"?$.boostTerm(Q,Z,J):1;return{term:Q,fuzzy:X,prefix:H,termBoost:Y}},X$={idField:"id",extractField:($,Q)=>$[Q],stringifyField:($,Q)=>$.toString(),tokenize:($)=>$.split(Z5),processTerm:($)=>$.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:($,Q)=>{if(typeof(console===null||console===void 0?void 0:console[$])==="function")console[$](Q)},autoVacuum:!0},x$={combineWith:V$,prefix:!1,fuzzy:!1,maxFuzzy:6,boost:{},weights:{fuzzy:0.45,prefix:0.375},bm25:o0},$5={combineWith:h$,prefix:($,Q,Z)=>Q===Z.length-1},W$={batchSize:1000,batchWait:10},U$={minDirtFactor:0.1,minDirtCount:20},Y$={...W$,...U$},Q5=($,Q)=>{if(!$.includes(Q))$.push(Q)},b$=($,Q)=>{for(let Z of Q)if(!$.includes(Z))$.push(Z)},k$=({score:$},{score:Q})=>Q-$,f$=()=>new Map,d=($)=>{let Q=new Map;for(let Z of Object.keys($))Q.set(parseInt(Z,10),$[Z]);return Q},a=async($)=>{let Q=new Map,Z=0;for(let J of Object.keys($))if(Q.set(parseInt(J,10),$[J]),++Z%1000===0)await u$(0);return Q},u$=($)=>new Promise((Q)=>setTimeout(Q,$)),Z5=/[\n\r\p{Z}\p{P}]+/u;var J5=new Set(["get","post","put","delete","patch","head","options","trace"]),X5=20,Y5=50;function H5($){return[...new Set($.filter(Boolean))]}function W5($){let Q=$.split("/").pop()||"";try{return decodeURIComponent(Q)}catch{return Q}}function F($,Q=[]){if(!$||typeof $!=="object")return Q;if(typeof $.$ref==="string")Q.push(W5($.$ref));if(Array.isArray($)){for(let Z of $)F(Z,Q);return Q}for(let Z of["schema","items","additionalProperties","not"])F($[Z],Q);for(let Z of["oneOf","anyOf","allOf"])for(let J of $[Z]||[])F(J,Q);for(let Z of Object.values($.properties||{}))F(Z,Q);for(let Z of Object.values($.content||{}))F(Z?.schema,Q);for(let Z of Object.values($.responses||{}))F(Z,Q);for(let Z of $.parameters||[])F(Z,Q);return F($.requestBody,Q),Q}function m$($){let Q=[],Z=$?.paths||{};for(let[J,X]of Object.entries(Z)){if(!X||typeof X!=="object")continue;for(let[H,Y]of Object.entries(X)){let W=H.toLowerCase();if(!J5.has(W)||!Y||typeof Y!=="object")continue;let U=W.toUpperCase(),G=String(Y.summary||""),V=G||`${U} ${J}`,z=String(Y.operationId||""),B=Array.isArray(Y.tags)?Y.tags.map(String):[],L=String(Y.description||""),C=H5(F({parameters:[...X.parameters||[],...Y.parameters||[]],requestBody:Y.requestBody,responses:Y.responses}));Q.push({method:U,path:J,summary:G,title:V,operationId:z,tags:B,description:L,schemaNames:C})}}return Q.sort((J,X)=>{let H=J.path.localeCompare(X.path);if(H!==0)return H;return J.method.localeCompare(X.method)})}function U5($){if($===void 0)return X5;if(!Number.isInteger($)||$<1)throw Error("search 的 --limit 必须是 1 到 50 的整数。");if($>Y5)throw Error("search 的 --limit 最大为 50,请缩小关键词或使用 --method 过滤。");return $}function G5($){return $.map((Q)=>Q.trim().toLowerCase()).filter(Boolean)}function c$($,Q){if(!Q)return 0;let Z=$.path.toLowerCase(),J=$.summary.toLowerCase(),X=$.operationId.toLowerCase(),H=$.tags.join(" ").toLowerCase(),Y=$.schemaNames.join(" ").toLowerCase();if(Z===Q)return 1000;if(J===Q)return 900;if(Z.includes(Q))return Z.includes(`/${Q}`)?700:600;if(J.includes(Q))return 500;if(X.includes(Q))return 400;if(H.includes(Q))return 300;if(Y.includes(Q))return 200;return 0}function V5($,Q){if(!Q)return $;return $.filter((Z)=>Z.method===Q)}var l$=typeof Intl.Segmenter<"u"?new Intl.Segmenter("zh",{granularity:"word"}):void 0;function p$($){let Q=$.toLowerCase();if(l$)return Array.from(l$.segment(Q)).filter((Z)=>Z.isWordLike).map((Z)=>Z.segment);return Q.match(/[a-z0-9]+|[\u4e00-\u9fa5]/g)??[]}function B5($,Q,Z){if(Q.length===0)return $;let J=$.map((W,U)=>({id:U,path:W.path,summary:W.summary,operationId:W.operationId,tags:W.tags,description:W.description,schemaNames:W.schemaNames})),X=new A({fields:["path","summary","operationId","tags","description","schemaNames"],storeFields:[],tokenize:p$,processTerm:(W)=>W,searchOptions:{tokenize:p$,processTerm:(W)=>W,fuzzy:!0}});X.addAll(J);let H=Q.map((W)=>new Set(X.search(W).map((U)=>U.id))),Y=Z==="and"?H.reduce((W,U)=>new Set([...W].filter((G)=>U.has(G)))):new Set(H.flatMap((W)=>[...W]));return $.filter((W,U)=>Y.has(U))}function z5($,Q){return[...$].sort((Z,J)=>{let X=c$(J,Q)-c$(Z,Q);if(X!==0)return X;let H=Z.path.localeCompare(J.path);if(H!==0)return H;return Z.method.localeCompare(J.method)})}function L5($,Q){let{mode:Z="or",method:J}=Q,X=G5(Q.keywords||[]),H=J?.trim().toUpperCase();if(X.length===0&&!H)throw Error("请提供 keywords 或 method,避免一次性返回整个项目的接口列表。");let Y=V5($,H),W=B5(Y,X,Z);return z5(W,X[0]||"")}function d$($,Q){let Z=U5(Q.limit),J=L5($,Q),X=J.slice(0,Z);return{total:J.length,showing:X.length,truncated:J.length>X.length,limit:Z,items:X}}function a$($,Q){let Z=[];if(Q)Z.push(`> 警告: ${Q}`),Z.push("");if($.total===0)return Z.push("未找到符合条件的接口。可以换一个接口名、业务关键词、路径片段或 method 再搜索。"),Z.join(`
55
+ `);Z.push(`共找到 ${$.total} 个接口,当前展示 ${$.showing} 个。${$.truncated?"结果已截断,请收窄关键词或提高 limit(最大 50)。":""}`),Z.push(""),Z.push("| 方法 | 路径 | 接口名称 | Tags |"),Z.push("|---|---|---|---|");for(let J of $.items)Z.push(`| ${J.method} | \`${J.path}\` | ${J.summary||J.title} | ${J.tags.join(", ")||"-"} |`);if(Z.push(""),$.truncated)Z.push("当前结果已截断,请先收窄搜索范围;不要基于截断列表直接调用 `get`。");else if($.total===1)Z.push("已找到唯一接口。只有用户明确要求生成 TypeScript 类型或入参返回值类型时,才使用该 `method + path` 调用 `get`。");else Z.push("找到多个候选接口。请先让用户选择一个具体接口;不要直接调用 `get`。");return Z.join(`
56
+ `)}var n$=["用法: apifox-api search [keywords...] [--mode or|and] [--method <METHOD>] [--limit <N>] [--moduleId <N>]","","说明:","- 在当前 module 的接口文档内检索接口(按 path / 接口名称 / tags / operationId / schema 关键词)。","- keywords: 一个或多个搜索词(位置参数),默认按 OR 组合。","- --mode: 多个关键词的组合方式,默认 or,可选 and。","- --method: 按 HTTP 方法过滤,例如 GET / POST / PUT / DELETE。","- --limit: 限制返回条数,默认 20,最大 50。","- --moduleId: 仅本次覆盖当前 module。"].join(`
57
+ `);function s($,Q,Z,J){let X=$[Q+1];if(X===void 0||X.startsWith("--")||!X.trim())throw Error(`${Z} 需要提供${J}。`);return X}function R5($){let Q=[],Z,J,X,H,Y=!1,W=!1,U=!1,G=!1;for(let V=0;V<$.length;V+=1){let z=$[V];if(z===void 0)continue;if(z==="--mode"){if(Y)throw Error("--mode 只能提供一次。");let B=s($,V,"--mode","or 或 and").trim().toLowerCase();if(B!=="or"&&B!=="and")throw Error(`--mode 只接受 or 或 and,收到: ${B}。`);Z=B,Y=!0,V+=1;continue}if(z==="--method"){if(W)throw Error("--method 只能提供一次。");J=s($,V,"--method","HTTP 方法").trim().toUpperCase(),W=!0,V+=1;continue}if(z==="--limit"){if(U)throw Error("--limit 只能提供一次。");let L=s($,V,"--limit","1 到 50 的整数").trim(),C=Number(L);if(!Number.isInteger(C)||C<1||String(C)!==L)throw Error(`--limit 必须是 1 到 50 的整数,收到: ${L}。`);X=C,U=!0,V+=1;continue}if(z==="--moduleId"){if(G)throw Error("--moduleId 只能提供一次。");let L=s($,V,"--moduleId","正整数").trim(),C=Number(L);if(!Number.isInteger(C)||C<=0||String(C)!==L)throw Error(`--moduleId 必须是正整数,收到: ${L}。`);H=C,G=!0,V+=1;continue}if(z.startsWith("--"))throw Error(`未知 search 参数: ${z}`);Q.push(z)}return{keywords:Q,mode:Z??"or",...J!==void 0?{method:J}:{},...X!==void 0?{limit:X}:{},...H!==void 0?{moduleId:H}:{}}}function j5($){if($.includes("limit"))return"--limit 必须是 1 到 50 的整数,最大 50。";return $}async function i$($){let Q=$.stdout??process.stdout,Z=$.stderr??process.stderr,J=$.cwd??process.cwd(),X=$.homeDir??C5.homedir(),H=$.env??process.env,Y;try{Y=R5($.args)}catch(B){return Z.write(`apifox-api search 失败: ${B?.message||String(B)}
58
+
59
+ ${n$}
60
+ `),1}if(Y.keywords.length===0&&!Y.method)return Z.write(`apifox-api search 失败: 请提供 keywords 或 --method,避免返回整个模块的接口。
61
+
62
+ ${n$}
63
+ `),1;let W;try{W=await T({cwd:J,homeDir:X,env:H})}catch(B){return Z.write(`${B?.message||String(B)}
64
+ `),1}let U;try{U=await K({cwd:J,homeDir:X,moduleIds:W.moduleIds,...Y.moduleId!==void 0?{moduleIdFlag:Y.moduleId}:{}})}catch(B){return Z.write(`apifox-api search 失败: ${B?.message||String(B)}
65
+ `),1}let G;try{G=await b(W,U,{allowStaleOnError:!0,...$.fetchImpl?{fetchImpl:$.fetchImpl}:{},...$.now?{now:$.now}:{},env:H})}catch(B){return Z.write(`apifox-api search 失败: ${B?.message||String(B)}
66
+ `),1}let V=m$(G.data),z;try{z=d$(V,{keywords:Y.keywords,mode:Y.mode,...Y.method!==void 0?{method:Y.method}:{},...Y.limit!==void 0?{limit:Y.limit}:{}})}catch(B){let L=j5(B?.message||String(B));return Z.write(`apifox-api search 失败: ${L}
67
+ `),1}return Q.write(`${a$(z,G.warning)}
68
+ `),0}import S5 from"os";var s$=["get","post","put","delete","patch","head","options","trace"];function t$($){if(!$)return"";let Q=String($).replace(/[^A-Za-z0-9_\u4e00-\u9fa5]/g,"");return Q?Q.charAt(0).toUpperCase()+Q.slice(1):"Anonymous"}function B$($){let Q=String($);return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(Q)?Q:JSON.stringify(Q)}function z$($){return String($||"").replace(/\*\//g,"* /").replace(/\r?\n/g," ")}function e$($){let Q=$.split("/").pop()||"";try{return decodeURIComponent(Q)}catch{return Q}}function _5($,Q){if(!$.startsWith("#/components/schemas/"))return;return Q[e$($)]}function q5($){return $===void 0?"undefined":JSON.stringify($)}function r$($){return[...new Set($.filter(Boolean))]}function _($,Q){if(Q?.nullable===!0&&!$.split("|").map((Z)=>Z.trim()).includes("null"))return`${$} | null`;return $}class $0{schemas;emitted=new Set;queue=[];orderedRefs=[];refNames=new Map;usedNames=new Map;bodies=new Map;constructor($){this.schemas=$}renderSchema($){return this.typeOf($)}drain(){while(this.queue.length){let $=this.queue.shift();if(this.emitted.has($))continue;this.emitRef($)}return this.orderedRefs.map(($)=>this.bodies.get($)).filter(($)=>Boolean($))}allocateName($){let Q=this.refNames.get($);if(Q)return Q;let Z=t$(e$($))||"Schema",J=this.usedNames.get(Z)||0,X=J+1;this.usedNames.set(Z,X);let H=J===0?Z:`${Z}${X}`;return this.refNames.set($,H),H}enqueueRef($){let Q=this.allocateName($);if(!this.emitted.has($)&&!this.queue.includes($))this.queue.push($);return Q}emitRef($){this.emitted.add($);let Q=this.allocateName($),Z=_5($,this.schemas);if(!Z){this.bodies.set($,`export type ${Q} = any; // missing schema ${$}`),this.orderedRefs.push($);return}if(Z.type==="object"||Z.properties){let J=this.renderInterface(Q,Z);this.bodies.set($,J)}else this.bodies.set($,`export type ${Q} = ${this.typeOf(Z)};`);this.orderedRefs.push($)}renderInterface($,Q){let Z=Q.properties||{},J=new Set(Q.required||[]),H=Object.keys(Z).map((Y)=>{let W=Z[Y];return`${W?.description?` /** ${z$(W.description)} */
69
+ `:""} ${B$(Y)}${J.has(Y)?"":"?"}: ${this.typeOf(W)};`});return`export interface ${$} {
70
+ ${H.join(`
71
+ `)}
72
+ }`}enumType($){if(!Array.isArray($.enum)||$.enum.length===0)return;return r$($.enum.map(q5)).join(" | ")}typeOf($){if(!$||typeof $!=="object")return"any";if(typeof $.$ref==="string")return this.enqueueRef($.$ref);let Q=this.enumType($);if(Q)return _(Q,$);if(Array.isArray($.type))return r$($.type.map((Z)=>this.typeOf({...$,type:Z}))).join(" | ");if($.oneOf||$.anyOf){let Z=($.oneOf||$.anyOf).map((J)=>this.typeOf(J)).join(" | ");return _(Z||"any",$)}if($.allOf){let Z=$.allOf.map((J)=>this.typeOf(J)).join(" & ");return _(Z||"any",$)}if($.type==="array"||$.items)return _(`Array<${this.typeOf($.items)}>`,$);if($.type==="object"||$.properties){let Z=$.properties||{},J=new Set($.required||[]),X=Object.keys(Z);if(X.length>0){let H=X.map((Y)=>`${B$(Y)}${J.has(Y)?"":"?"}: ${this.typeOf(Z[Y])}`);return _(`{ ${H.join("; ")} }`,$)}if($.additionalProperties&&typeof $.additionalProperties==="object")return _(`Record<string, ${this.typeOf($.additionalProperties)}>`,$);return _("Record<string, any>",$)}switch($.type){case"string":return _("string",$);case"integer":case"number":return _("number",$);case"boolean":return _("boolean",$);case"null":return"null";default:return _("any",$)}}}function F5($,Q,Z){let J=Q.trim().toLowerCase(),X=Z.trim();if(!J)throw Error("请提供 method。可先运行 apifox-api search 获取完整的 method + path。");if(!X)throw Error("请提供 path。可先运行 apifox-api search 获取完整的 method + path。");if(!s$.includes(J))throw Error(`无效的 HTTP method: ${Q}`);let H=$?.paths?.[X];if(!H)throw Error(`未找到接口路径 ${X}。请先运行 apifox-api search 获取完整 path。`);let Y=H[J];if(!Y){let W=s$.filter((U)=>H[U]).map((U)=>U.toUpperCase()).join(", ");throw Error(`未找到接口 ${J.toUpperCase()} ${X}${W?`。该路径可用方法: ${W}`:""}`)}return{method:J.toUpperCase(),path:X,pathItem:H,operation:Y,schemas:$?.components?.schemas||{}}}function N5($){let Q=$.operation,Z=Q.operationId||Q.summary||`${$.method}_${$.path}`;return t$(Z)||"Api"}function O5($,Q){let Z=[...$?.parameters||[],...Q?.parameters||[]],J=new Map;for(let X of Z){if(!X?.name||!X?.in)continue;J.set(`${X.in}:${X.name}`,X)}return[...J.values()]}function o$($){let Q=Object.entries($||{}),Z=Q.find(([H])=>H.toLowerCase()==="application/json"),J=Q.find(([H])=>H.toLowerCase().endsWith("+json")),X=Z||J;if(!X)return;return{mediaType:X[0],schema:X[1]?.schema}}function T5($){let Q=Object.entries($||{}),Z=["application/json","application/x-www-form-urlencoded","multipart/form-data"];for(let X of Z){let H=Q.find(([Y])=>Y.toLowerCase()===X);if(H)return{mediaType:H[0],schema:H[1]?.schema}}let J=Q[0];return J?{mediaType:J[0],schema:J[1]?.schema}:void 0}function E5($){let Q=Object.entries($||{}),Z=$?.["200"],J=o$(Z?.content);if(J)return{statusCode:"200",...J};for(let[X,H]of Q){if(!/^2\d\d$/.test(X)||X==="200")continue;let Y=o$(H?.content);if(Y)return{statusCode:X,...Y}}return}function P5($,Q,Z){if(Q.length===0)return;let J=Q.map((X)=>{let H=X.description?` /** ${z$(X.description)} */
73
+ `:"",Y=X.schema||{type:X.type||"string"};return`${H} ${B$(X.name)}${X.required?"":"?"}: ${Z.renderSchema(Y)};`});return`export interface ${$}Request {
74
+ ${J.join(`
75
+ `)}
76
+ }`}function D5($){let Q=new $0($.schemas),Z=N5($),J=$.operation,X=J.description||J.summary||`${$.method} ${$.path}`,H=[`/** ${z$(X)} */`,`// ${$.method} ${$.path}`],Y=O5($.pathItem,J),W=P5(Z,Y,Q);if(W)H.push(`
77
+ // ====== 请求参数 ======`),H.push(W);let U=T5(J.requestBody?.content);if(U?.schema)H.push(`
78
+ // ====== 请求体 ======`),H.push(`// ${U.mediaType}`),H.push(`export type ${Z}RequestBody = ${Q.renderSchema(U.schema)};`);let G=E5(J.responses);if(G?.schema)H.push(`
79
+ // ====== 返回响应 ======`),H.push(`// ${G.statusCode} ${G.mediaType}`),H.push(`export type ${Z}Response = ${Q.renderSchema(G.schema)};`);else H.push(`
80
+ // 未找到 2xx JSON 响应,未生成 Response 类型。`);let V=Q.drain();if(V.length)H.push(`
81
+ // ====== 关联类型定义 ======`),H.push(...V);return H.join(`
82
+ `)}function Q0($,Q,Z){return D5(F5($,Q,Z))}var Z0=["用法: apifox-api get <method> <path> [--moduleId N]","","说明:","- 根据 HTTP method 和 path 定位接口,生成 TypeScript 类型并输出到 stdout。","- --moduleId:临时使用指定 module 的接口快照,不影响当前 module 设置。"].join(`
83
+ `);class L$ extends Error{constructor($){super($);this.name="MissingPositionalArgsError"}}function A5($){let Q=[],Z,J=!1;for(let X=0;X<$.length;X+=1){let H=$[X];if(H===void 0)continue;if(H==="--moduleId"){if(J)throw Error("--moduleId 只能提供一次。");let Y=$[X+1];if(Y===void 0||Y.startsWith("--")||!Y.trim())throw Error("--moduleId 需要提供一个正整数。");let W=Y.trim(),U=Number(W);if(!Number.isInteger(U)||U<=0||String(U)!==W)throw Error(`无效的 moduleId:${W}。--moduleId 必须是正整数。`);Z=U,J=!0,X+=1;continue}if(H.startsWith("--"))throw Error(`未知 get 参数: ${H}`);Q.push(H)}if(Q.length<2)throw new L$(Z0);if(Q.length>2){let X=Q.slice(2).join(" ");throw Error(`get 只能接受 <method> <path> 两个位置参数,多余参数: ${X}`)}return{method:Q[0],path:Q[1],...Z!==void 0?{moduleIdFlag:Z}:{}}}async function J0($){let Q=$.stdout??process.stdout,Z=$.stderr??process.stderr,J=$.cwd??process.cwd(),X=$.homeDir??S5.homedir(),H=$.env??process.env,Y;try{Y=A5($.args)}catch(B){if(B instanceof L$)Z.write(`${B.message}
84
+ `);else Z.write(`apifox-api get 失败: ${B?.message||String(B)}
85
+
86
+ ${Z0}
87
+ `);return 1}let W,U;try{W=await T({cwd:J,homeDir:X,env:H}),U=await K({cwd:J,homeDir:X,moduleIds:W.moduleIds,...Y.moduleIdFlag!==void 0?{moduleIdFlag:Y.moduleIdFlag}:{}})}catch(B){return Z.write(`${B?.message||String(B)}
88
+ `),1}let G,V;try{let B=await b(W,U,{allowStaleOnError:!0,env:H,...$.fetchImpl?{fetchImpl:$.fetchImpl}:{},...$.now?{now:$.now}:{}});V=B.warning,G=Q0(B.data,Y.method,Y.path)}catch(B){let L=B?.message||String(B);if(L.includes("未找到"))Z.write(`未找到接口 ${Y.method.toUpperCase()} ${Y.path},可先运行 \`apifox-api search <关键词>\` 获取完整的 method + path
89
+ `);else Z.write(`apifox-api get 失败: ${L}
90
+ `);return 1}let z=V?`// 警告: ${V}
91
+
92
+ ${G}
93
+ `:`${G}
94
+ `;return Q.write(z),0}var Y0=process.argv.slice(2),X0=Y0[0],w=Y0.slice(1),K5=["apifox-api \u2014 Apifox \u63A5\u53E3\u6587\u6863 CLI","","\u7528\u6CD5: apifox-api <command> [args]","","\u547D\u4EE4:"," init <projectId> [--moduleIds 5,8,12] [--authKey <token>] \u7ED1\u5B9A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u5230 Apifox \u9879\u76EE"," search <keyword...> [--mode or|and] [--method GET] [...] \u5728\u5F53\u524D module \u5185\u641C\u7D22\u63A5\u53E3"," get <method> <path> [--moduleId N] \u4E3A\u6307\u5B9A\u63A5\u53E3\u751F\u6210 TypeScript \u7C7B\u578B"," refresh \u5237\u65B0\u5F53\u524D\u9879\u76EE\u5168\u90E8 module \u7684\u5FEB\u7167"," module [moduleId] \u67E5\u770B\u6216\u5207\u6362\u5F53\u524D module"," config set-auth-key <token> \u8BBE\u7F6E\u5168\u5C40\u9ED8\u8BA4 Apifox Auth Key",""].join(`
95
+ `);async function M5(){switch(X0){case"init":return K$({args:w});case"search":return i$({args:w});case"get":return J0({args:w});case"refresh":return M$({args:w});case"module":return w$({args:w});case"config":return v$({args:w});case void 0:return process.stderr.write(`${K5}
96
+ `),1;default:return process.stderr.write([`\u672A\u77E5\u547D\u4EE4: ${X0}`,"\u53EF\u7528\u547D\u4EE4: init, search, get, refresh, module, config"].join(`
97
+ `)),1}}M5().then(($)=>{process.exitCode=$}).catch(($)=>{console.error(`apifox-api \u542F\u52A8\u5931\u8D25: ${$?.message||String($)}`),process.exitCode=1});
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "apifox-api",
3
+ "module": "dist/index.js",
4
+ "type": "module",
5
+ "private": false,
6
+ "scripts": {
7
+ "test": "bun test",
8
+ "typecheck": "bunx tsc --noEmit",
9
+ "build": "bun build index.ts --outdir dist --target=node --minify && bun postbuild.ts",
10
+ "prepublishOnly": "bun run build"
11
+ },
12
+ "bin": {
13
+ "apifox-api": "dist/index.js"
14
+ },
15
+ "engines": {
16
+ "node": ">=18"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "assets",
21
+ "README.md",
22
+ "package.json"
23
+ ],
24
+ "devDependencies": {
25
+ "@types/bun": "latest",
26
+ "minisearch": "^7.2.0"
27
+ },
28
+ "peerDependencies": {
29
+ "typescript": "^5"
30
+ },
31
+ "version": "0.0.14",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
35
+ }