flycode-mcp 1.5.2 → 1.6.0

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 CHANGED
@@ -11,7 +11,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the
11
11
  - 基于官方 `@modelcontextprotocol/sdk` 实现,使用标准 `stdio` 传输协议。
12
12
  - 启动即完成 APaaS IDE 平台鉴权链路:账号登录 → 获取租户信息 → 获取 IDE Token。
13
13
  - 内置统一请求层 `request`,自动按请求类型(`center` / `tenant`)切换中心服务地址与当前租户连接地址,并自动注入鉴权 Token。
14
- - 当前提供工具:业务逻辑类 `page_model_logic_list`(分页查询业务逻辑列表)、`get_model_logic`(查询单个业务逻辑详情)、`save_model_logic`(保存 / 更新业务逻辑完整 JSON)、`simple_save_flycode_model_logic`(轻量保存 flycode 业务逻辑,只传 `modelLogicCode` / `flycode` / 可选 `input` / `output`);实体类 `page_entity_list`(分页查询实体列表)、`get_entity`(查询实体详情);表单 / 页面类 `page_form_list`(分页查询表单 / 页面列表)、`get_form`(查询表单 / 页面详情);通用类 `generate_unique_code`(生成唯一编码,用于新建实体 / 领域 / 表单时生成 JSON 中的 `code` 字段)。
14
+ - 当前提供工具:业务逻辑类 `page_model_logic_list`(分页查询业务逻辑列表)、`get_model_logic`(查询单个业务逻辑详情)、`save_model_logic`(保存 / 更新业务逻辑完整 JSON)、`simple_save_flycode_model_logic`(轻量保存 flycode 业务逻辑,只传 `modelLogicCode` / `flycode` / 可选 `input` / `output`);实体类 `page_entity_list`(分页查询实体列表)、`get_entity`(查询实体详情);表单 / 页面类 `page_form_list`(分页查询表单 / 页面列表)、`get_form`(查询表单 / 页面详情);SQL 执行类 `run_sql`(在业务库中执行一条 SELECT 查询,返回查询结果数据与结果总数);通用类 `generate_unique_code`(生成唯一编码,用于新建实体 / 领域 / 表单时生成 JSON 中的 `code` 字段)。
15
15
 
16
16
  ---
17
17
 
@@ -240,6 +240,23 @@ username=<账号>&password=<密码>&tenantCode=<租户号>&envName=<环境名>
240
240
 
241
241
  > 注:工具的 `description` 中附有「字段速查」,列出了各顶层对象的关键字段与编码枚举含义(如 `pageinfo.type` 页面类型、`marktype` 创建标记、`clientcategorycode` 用户端等),便于理解返回 JSON。详情类型的字段定义见 `src/clients/formClient.ts`(`FormResult` / `FormPageInfo` / `FormViewNode` / `FormControl` 等接口)。
242
242
 
243
+ ### `run_sql` — 执行 SQL 查询
244
+
245
+ 在业务库中执行一条 SELECT 查询 SQL(只读、幂等),直接探查业务表数据、核对字段值、验证同步结果等。底层调用 `runClient.sqlRun`(接口 `POST /api/biz/sqlrun`)。
246
+
247
+ **输入参数:**
248
+
249
+ | 参数 | 类型 | 必填 | 说明 |
250
+ | ----- | ------ | ---- | -------------------------------------------------------------------------- |
251
+ | `sql` | string | 是 | 要执行的 SQL 查询语句,只支持 SELECT 查询,一次只能一条 SQL |
252
+
253
+ **返回:** 查询结果的 JSON(`resp_data`),主要字段:
254
+
255
+ - `data`:查询结果数据,数组中的每一项为一条查询结果记录(对象);查询无结果时为 `null` 或空数组
256
+ - `influenceCount`:查询结果总数(数值)
257
+
258
+ > 注:接口仅支持 SELECT 查询,不支持 INSERT / UPDATE / DELETE 等写操作。返回的 `data` 行结构不可预知,工具以宽松结构透传,确保任意查询结果均可正常返回。
259
+
243
260
  ### `generate_unique_code` — 生成唯一编码
244
261
 
245
262
  通过雪花算法(`src/utils/snowflake.ts`)生成一个全局唯一 ID(code)。在新建实体、领域、表单等内容时,其 JSON 字段中通常需要携带一个唯一 `code`(如实体的 `objectcode`、表单的 `code` 等),可调用本工具获取并填入。底层直接调用 snowflake 实例的 `nextId()`。
@@ -272,6 +289,7 @@ flycode-mcp/
272
289
  │ │ ├── logicClient.ts # 业务逻辑分页/详情查询、保存请求
273
290
  │ │ ├── entityClient.ts # 实体列表 pageEntityList / 详情 getEntity 请求
274
291
  │ │ ├── formClient.ts # 表单 / 页面列表 pageFormList、详情 getForm 请求;FormResult 等详情类型定义
292
+ │ │ ├── runClient.ts # SQL 查询 sqlRun 请求(POST /api/biz/sqlrun)
275
293
  │ │ └── types.ts # 公共响应信封类型(DataResponse / PageResponse / CommonResponse)
276
294
  │ ├── store/ # 运行时内存存储
277
295
  │ │ ├── token.ts # 鉴权 Token 存储器
@@ -285,8 +303,10 @@ flycode-mcp/
285
303
  │ │ ├── entity/
286
304
  │ │ │ ├── read.ts # 只读类工具(page_entity_list / get_entity)
287
305
  │ │ │ └── schemas.ts # 实体共享 zod schema(EntityResult / EntityProperty,宽松透传结构)
288
- │ │ └── form/
289
- │ │ └── read.ts # 只读类工具(page_form_list / get_form)
306
+ │ │ ├── form/
307
+ │ │ │ └── read.ts # 只读类工具(page_form_list / get_form)
308
+ │ │ └── run/
309
+ │ │ └── read.ts # 只读类工具(run_sql:执行 SQL 查询)
290
310
  │ └── utils/
291
311
  │ ├── config.ts # 从命令行参数解析连接配置(BASE_URL / 账号等)
292
312
  │ ├── request.ts # 统一 axios 请求层(中心/租户地址切换 + Token 注入)
@@ -307,8 +327,8 @@ flycode-mcp/
307
327
  2. **登录**:`service/auth.ts` 中的 `authenticate()` 调用 `/api/multiplat/auth/login` 获取 Token,存入内存。
308
328
  3. **定位租户与环境**:`authenticate()` 调用 `/api/multiplat/auth/getTenantInfo`,依据 `tenantCode + envName` 匹配出目标租户,保存其连接信息(`conn.config`)到内存。
309
329
  4. **获取 IDE Token**:`authenticate()` 调用 `/api/multiplat/auth/getIdeToken` 换取 IDE 专用 Token 并覆盖内存中的 Token。
310
- 5. **注册并启动**:创建 `McpServer`,注册 `page_model_logic_list`、`get_model_logic`、`save_model_logic`、`simple_save_flycode_model_logic`、`page_entity_list`、`get_entity`、`page_form_list`、`get_form`、`generate_unique_code` 等工具,通过 `StdioServerTransport` 监听请求。
311
- 6. **业务请求**:工具被调用时,`logicClient` / `entityClient` / `formClient` 通过 `request({ type: "tenant" })` 自动切换到当前租户连接地址,并携带已注入的 Token 发起查询。
330
+ 5. **注册并启动**:创建 `McpServer`,注册 `page_model_logic_list`、`get_model_logic`、`save_model_logic`、`simple_save_flycode_model_logic`、`page_entity_list`、`get_entity`、`page_form_list`、`get_form`、`run_sql`、`generate_unique_code` 等工具,通过 `StdioServerTransport` 监听请求。
331
+ 6. **业务请求**:工具被调用时,`logicClient` / `entityClient` / `formClient` / `runClient` 通过 `request({ type: "tenant" })` 自动切换到当前租户连接地址,并携带已注入的 Token 发起查询。
312
332
 
313
333
  ---
314
334
 
@@ -0,0 +1,16 @@
1
+ import request from "../utils/request.js";
2
+ /**
3
+ * 执行 SQL 查询
4
+ *
5
+ * @param data 要执行的 SQL 语句
6
+ * @returns 响应结果
7
+ */
8
+ export function sqlRun(data) {
9
+ return request({
10
+ url: '/api/biz/sqlrun',
11
+ method: 'post',
12
+ data,
13
+ type: 'business'
14
+ });
15
+ }
16
+ //# sourceMappingURL=runClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runClient.js","sourceRoot":"","sources":["../../src/clients/runClient.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,qBAAqB,CAAA;AAoCzC;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,IAAkB;IACvC,OAAO,OAAO,CAAC;QACb,GAAG,EAAE,iBAAiB;QACtB,MAAM,EAAE,MAAM;QACd,IAAI;QACJ,IAAI,EAAE,UAAU;KACjB,CAAC,CAAA;AACJ,CAAC"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { readTools as logicReadTools } from './tools/logic/read.js';
6
6
  import { writeTools as logicWriteTools } from './tools/logic/write.js';
7
7
  import { readTools as entityReadTools } from './tools/entity/read.js';
8
8
  import { readTools as formReadTools } from './tools/form/read.js';
9
+ import { readTools as runReadTools } from './tools/run/read.js';
9
10
  import { commonTools } from './tools/common.js';
10
11
  // 鉴权初始化(登录 -> 获取租户信息 -> 获取 IDE Token)
11
12
  await authenticate();
@@ -20,6 +21,7 @@ const allTools = [
20
21
  ...logicWriteTools,
21
22
  ...entityReadTools,
22
23
  ...formReadTools,
24
+ ...runReadTools,
23
25
  ...commonTools,
24
26
  ];
25
27
  for (const t of allTools) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,sCAAsC;AACtC,MAAM,YAAY,EAAE,CAAA;AAEpB,aAAa;AACb,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAA;AAEF,uCAAuC;AACvC,MAAM,QAAQ,GAAc;IAC1B,GAAG,cAAc;IACjB,GAAG,eAAe;IAClB,GAAG,eAAe;IAClB,GAAG,aAAa;IAChB,GAAG,WAAW;CACf,CAAA;AAED,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;IACzB,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;AAClD,CAAC;AAED,OAAO;AACP,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/B,kBAAkB;IAClB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAA;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,sCAAsC;AACtC,MAAM,YAAY,EAAE,CAAA;AAEpB,aAAa;AACb,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAA;AAEF,uCAAuC;AACvC,MAAM,QAAQ,GAAc;IAC1B,GAAG,cAAc;IACjB,GAAG,eAAe;IAClB,GAAG,eAAe;IAClB,GAAG,aAAa;IAChB,GAAG,YAAY;IACf,GAAG,WAAW;CACf,CAAA;AAED,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;IACzB,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;AAClD,CAAC;AAED,OAAO;AACP,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/B,kBAAkB;IAClB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAA;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import { sqlRun } from '../../clients/runClient.js';
3
+ /**
4
+ * 执行 SQL 查询结果(SqlRunResult)的 outputSchema 形状。
5
+ * 字段类型严格依据 runClient.ts 中的 SqlRunResult 接口声明构建:
6
+ * - data:查询结果数据,接口声明为 unknown[] | null(可选且可空),每行是一条记录对象。
7
+ * 由于每行内部结构无法提前约束,统一以 z.unknown() 承接,保证服务端返回的任何行都能通过校验。
8
+ * - influenceCount:查询结果总数,接口声明为 number | null(可选且可空);对字符串型数字用 z.coerce.number() 容错。
9
+ * 使用 z.looseObject 实现服务端偶发返回的额外字段原样透传,避免 -32602 Output validation 报错。
10
+ * 描述文字直接采用 runClient.ts 中 SqlRunResult 各字段的注释内容。
11
+ */
12
+ const sqlRunResultShape = {
13
+ data: z.array(z.unknown()).nullable().optional().describe('查询结果数据,数组中的每一项为一条查询结果记录(对象)'),
14
+ influenceCount: z.coerce.number().nullable().optional().describe('查询结果总数')
15
+ };
16
+ /** 只读类工具:查询、列表、读取等不会修改数据的操作。 */
17
+ export const readTools = [
18
+ {
19
+ name: 'run_sql',
20
+ config: {
21
+ title: '执行 SQL 查询',
22
+ description: '在业务库(数据库为 PostgreSQL)中执行一条 SELECT 查询 SQL(接口仅支持 SELECT,一次只能一条 SQL),返回查询结果数据 data 与结果总数 influenceCount。适用于直接探查业务表数据、核对字段值、验证同步结果等只读场景。',
23
+ inputSchema: {
24
+ sql: z.string().describe('要执行的 SQL 查询语句,只支持 SELECT 查询,一次只能一条 SQL')
25
+ },
26
+ // z.looseObject 实现有额外字段时原样透传
27
+ outputSchema: z.looseObject(sqlRunResultShape),
28
+ annotations: {
29
+ readOnlyHint: true, // 此操作只执行 SELECT 查询,不会修改数据
30
+ destructiveHint: false, // 此操作不具有破坏性
31
+ idempotentHint: true // 重复执行同一条 SELECT 结果相同
32
+ }
33
+ },
34
+ handler: async (args) => {
35
+ const { sql } = args;
36
+ try {
37
+ const res = await sqlRun({ sql });
38
+ return {
39
+ content: [{
40
+ type: 'text',
41
+ text: JSON.stringify(res.resp_data)
42
+ }],
43
+ // outputSchema 已在工具上声明,SDK 1.30 要求调用结果必须携带
44
+ // structuredContent 与之匹配,否则会抛 -32602;这里同时返回
45
+ // 文本(给人/模型阅读)和结构化内容(供 schema 校验)。
46
+ structuredContent: res.resp_data
47
+ };
48
+ }
49
+ catch (e) {
50
+ // 业务/网络错误:HTTP 非 200 时 Axios 已在传输层抛出,
51
+ // 错误体形如 {"error_type":600,"error_code":"token无效,请重新登录","error_params":null}
52
+ // 将其原始 JSON 原样返回给模型,不做二次包装。
53
+ const err = e;
54
+ const body = err.response?.data ?? e;
55
+ return {
56
+ isError: true,
57
+ content: [{
58
+ type: 'text',
59
+ text: JSON.stringify(body)
60
+ }]
61
+ };
62
+ }
63
+ }
64
+ }
65
+ ];
66
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/tools/run/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAGnD;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG;IACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IACxF,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;CACrD,CAAA;AAEvB,gCAAgC;AAChC,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC;QACE,IAAI,EAAE,SAAS;QACf,MAAM,EAAE;YACN,KAAK,EAAE,WAAW;YAClB,WAAW,EAAE,sIAAsI;YACnJ,WAAW,EAAE;gBACX,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;aACnE;YACD,6BAA6B;YAC7B,YAAY,EAAE,CAAC,CAAC,WAAW,CAAC,iBAAiB,CAA2B;YACxE,WAAW,EAAE;gBACX,YAAY,EAAE,IAAI,EAAM,0BAA0B;gBAClD,eAAe,EAAE,KAAK,EAAE,YAAY;gBACpC,cAAc,EAAE,IAAI,CAAI,sBAAsB;aAC/C;SACF;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;gBACjC,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;yBACpC,CAAC;oBACF,2CAA2C;oBAC3C,4CAA4C;oBAC5C,kCAAkC;oBAClC,iBAAiB,EAAE,GAAG,CAAC,SAA+C;iBACvE,CAAA;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,sCAAsC;gBACtC,4EAA4E;gBAC5E,4BAA4B;gBAC5B,MAAM,GAAG,GAAG,CAAsC,CAAA;gBAClD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAA;gBACpC,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;yBAC3B,CAAC;iBACH,CAAA;YACH,CAAC;QACH,CAAC;KACF;CACF,CAAA"}
@@ -42,6 +42,7 @@ service.interceptors.response.use((response) => response.data, (error) => Promis
42
42
  * ```
43
43
  * - `type` 可选,默认 `"center"`:用 BASE_URL 作为基础地址。
44
44
  * - `type: "tenant"`:用当前租户 `Tenant.conn.config` 作为基础地址;
45
+ * "business":用当前租户 `Tenant.conn.business` 作为基础地址;
45
46
  * 若尚未设置租户信息(未调用 setTenant)则直接 reject。
46
47
  *
47
48
  * 返回值为响应体(已剥离 AxiosResponse 包装),类型即传入的泛型 T。
@@ -50,17 +51,24 @@ service.interceptors.response.use((response) => response.data, (error) => Promis
50
51
  * @param config 请求配置,可额外携带 `type`
51
52
  */
52
53
  export default function request(config) {
53
- const type = config.type ?? "center";
54
- if (type === "tenant") {
55
- const tenant = getTenant();
56
- if (!tenant) {
57
- return Promise.reject(new Error("type 为 tenant 时,必须先调用 setTenant() 设置租户信息"));
54
+ const { type = "center", ...rest } = config;
55
+ let baseURL;
56
+ switch (type) {
57
+ case "center":
58
+ baseURL = BASE_URL || "";
59
+ break;
60
+ // tenant 与 business 共用同一段租户校验,仅在最终取用的连接地址上不同
61
+ case "tenant":
62
+ case "business": {
63
+ const tenant = getTenant();
64
+ if (!tenant) {
65
+ return Promise.reject(new Error(`type 为 ${type} 时,必须先调用 setTenant() 设置租户信息`));
66
+ }
67
+ baseURL = type === "tenant" ? tenant.conn.config : tenant.conn.business;
68
+ break;
58
69
  }
59
- config.baseURL = tenant.conn.config;
60
70
  }
61
- else {
62
- config.baseURL = BASE_URL || "";
63
- }
64
- return service(config);
71
+ // 用展开拷贝而非改写入参,避免副作用;同时剔除自定义的 type 字段,不泄漏给 Axios
72
+ return service({ ...rest, baseURL });
65
73
  }
66
74
  //# sourceMappingURL=request.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/utils/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAgB9C;;;GAGG;AACH,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,QAAQ,IAAI,EAAE;IACvB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE;QACP,cAAc,EAAE,kBAAkB;KACnC;CACF,CAAC,CAAA;AAEF;;;GAGG;AACH,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;IAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;QACrC,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;IAC9B,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAC,CAAA;AAEF;;;GAGG;AACH,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAC/B,CAAC,QAAuB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAU,MAAqB;IAC5D,MAAM,IAAI,GAAgB,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAA;IAEjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;QAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,0CAA0C,CAAC,CACtD,CAAA;QACH,CAAC;QACD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAA;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,OAAO,GAAG,QAAQ,IAAI,EAAE,CAAA;IACjC,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAA0B,CAAA;AACjD,CAAC"}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/utils/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAiB9C;;;GAGG;AACH,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,QAAQ,IAAI,EAAE;IACvB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE;QACP,cAAc,EAAE,kBAAkB;KACnC;CACF,CAAC,CAAA;AAEF;;;GAGG;AACH,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;IAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;QACrC,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;IAC9B,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAC,CAAA;AAEF;;;GAGG;AACH,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAC/B,CAAC,QAAuB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAU,MAAqB;IAC5D,MAAM,EAAE,IAAI,GAAG,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAA;IAE3C,IAAI,OAAe,CAAA;IACnB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,GAAG,QAAQ,IAAI,EAAE,CAAA;YACxB,MAAK;QACP,6CAA6C;QAC7C,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;YAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,UAAU,IAAI,6BAA6B,CAAC,CACvD,CAAA;YACH,CAAC;YACD,OAAO,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAA;YACvE,MAAK;QACP,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,OAAO,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAA0B,CAAA;AAC/D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flycode-mcp",
3
- "version": "1.5.2",
3
+ "version": "1.6.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",