qing-client 0.0.52 → 0.0.53
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 +300 -2
- package/lib/client/index.d.ts +5 -0
- package/lib/client/index.js +15 -0
- package/lib/service/AiService.js +2 -1
- package/lib/service/AuthService.d.ts +12 -1
- package/lib/service/AuthService.js +27 -0
- package/lib/service/DeliveryStreamService.js +6 -0
- package/lib/service/EzAbilityService.js +5 -4
- package/lib/service/FileService.d.ts +12 -2
- package/lib/service/FileService.js +17 -2
- package/lib/service/MsgService.d.ts +3 -1
- package/lib/service/MsgService.js +9 -1
- package/lib/service/ProviderService.js +3 -0
- package/lib/types/file.d.ts +10 -0
- package/lib/types/msg.d.ts +5 -0
- package/lib/types/user.d.ts +20 -0
- package/lib/utils/snakeCase.d.ts +4 -0
- package/lib/utils/snakeCase.js +28 -0
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -171,6 +171,8 @@ client.setUserContext({
|
|
|
171
171
|
| `client.user` | 用户信息 |
|
|
172
172
|
| `client.token` | Token 管理 |
|
|
173
173
|
| `client.msg` | 消息中心 |
|
|
174
|
+
| `client.files` | 文件服务(V2 新路由 `/api/files`) |
|
|
175
|
+
| `client.file` | 文件服务(V1 兼容老项目 `/api/file`) |
|
|
174
176
|
| `client.ai` | AI 对话/会话(chatCompletion、会话与助手等) |
|
|
175
177
|
| `client.aigc` | AIGC 能力 |
|
|
176
178
|
| `client.audit` | 审计日志 |
|
|
@@ -181,7 +183,7 @@ client.setUserContext({
|
|
|
181
183
|
| `client.deliveryStream` | 投递流 |
|
|
182
184
|
| `client.ezAbility` | Ez 能力 |
|
|
183
185
|
|
|
184
|
-
|
|
186
|
+
`client.files` 与 `client.file` 指向同一后端(fileServiceUrl),仅路径前缀不同;也可单独 `import { FileService } from "qing-client"` 并传入配置(如 `new FileService(config, 'files')` 或 `'file'`)。
|
|
185
187
|
|
|
186
188
|
---
|
|
187
189
|
|
|
@@ -201,6 +203,8 @@ client.setUserContext({
|
|
|
201
203
|
| `register(data, projectId?, options?)` | `data`: `RegisterRequest`(`username`, `email`, `password`, `name?`, `phone?`, `org_id?`, `app_id?`) | `Promise<RegisterResponse>` | 注册,返回同登录结构。 |
|
|
202
204
|
| `createTemporaryToken(request?, options?)` | `request?`: `TemporaryTokenRequest`(`expires_in?`,秒,60–3600) | `Promise<TemporaryTokenResponse>`:`temporary_token`, `expires_at`, `expires_in` | 签发临时令牌。 |
|
|
203
205
|
| `verifyTemporaryToken(request, options?)` | `request`: `VerifyTemporaryTokenRequest` | `Promise<VerifyTemporaryTokenResponse>` | 验证临时令牌。 |
|
|
206
|
+
| `getTokenInfo(options?)` | — | `Promise<TokenInfoResponse>`:`sub`, `exp`, `expires_at`, `project_id`, `role`, `token_type`, `org_id?`, `app_id?` | 获取当前令牌信息(脱敏),需已 setToken。 |
|
|
207
|
+
| `revokeToken(token?, options?)` | `token?`: string(不传则撤销当前令牌) | `Promise<RevokeTokenResponse>` | 撤销当前或指定令牌;撤销指定令牌仅限本人或管理员。 |
|
|
204
208
|
| `logout(token, options?)` | `token`: string | `Promise<void>` | 登出。 |
|
|
205
209
|
|
|
206
210
|
### client.user(用户)
|
|
@@ -220,10 +224,15 @@ client.setUserContext({
|
|
|
220
224
|
| 方法 | 入参 | 返回值 | 说明 |
|
|
221
225
|
|------|------|--------|------|
|
|
222
226
|
| `getMessages(params?, options?)` | `params?`: `MessageQueryParams`(`type?`, `category?`, `isRead?`, `page?`, `limit?`, `userId?`, `pid?`, `aid?`) | `Promise<Message[]>` | 当前用户消息列表。`Message` 含 `_id`, `userId`, `title`, `content`, `type`, `category`, `isRead`, `readAt?`, `createdAt`, `updatedAt` 等。 |
|
|
227
|
+
| `getAdminMessages(params?, options?)` | 同上(管理员可传 `userId`/`pid`/`aid` 筛选) | `Promise<Message[]>` | 管理员获取消息列表(需管理员权限)。 |
|
|
228
|
+
| `getTypes(options?)` | — | `Promise<MessageTypeItem[]>`:`{ value: 'system' \| 'business' \| 'notice', label }` | 消息类型枚举,供前端筛选或展示。 |
|
|
229
|
+
| `getCategories(options?)` | — | `Promise<CategoryInfo[]>`:`category`, `unreadCount`, `latestMessage?` | 用户消息分类及未读数。 |
|
|
223
230
|
| `getUnreadStats(userId?, options?)` | `userId?`: string(管理员可指定) | `Promise<MessageStats>`:`total`, `byCategory` | 未读统计。 |
|
|
224
231
|
| `markAsRead(messageId, request?, options?)` | `messageId`: string<br>`request?`: `MarkAsReadRequest` | `Promise<Message>` | 单条标已读。 |
|
|
225
232
|
| `markManyAsRead(request, options?)` | `request`: `BatchMarkAsReadRequest`(如 `messageIds`) | `Promise<{ modifiedCount: number }>` | 批量标已读。 |
|
|
233
|
+
| `deleteMessage(messageId, request?, options?)` | `messageId`: string<br>`request?`: `MarkAsReadRequest`(管理员可传 `userId`) | `Promise<Message>` | 删除消息(软删除)。 |
|
|
226
234
|
| `createMessage(request, options?)` | `request`: `CreateMessageRequest`(`userId?`, `title`, `content`, `type`, `category`, `metadata?`) | `Promise<Message>` | 创建消息(管理员)。 |
|
|
235
|
+
| `createManyMessages(request, options?)` | `request`: `BatchCreateMessageRequest`(`messages: Array<{ userId, title, content, type, category, metadata? }>`) | `Promise<{ createdCount: number, messages: Message[] }>` | 批量创建消息(管理员)。 |
|
|
227
236
|
| `sendMail(request, options?)` | `request`: `MailRequest`(`to`, `subject?`, `text?`, `html?`, `cc?`, `bcc?`, `attachments?` 等) | `Promise<void>` | 发送邮件。 |
|
|
228
237
|
| `sendFeishuMessage(message, options?)` | `message`: `FeishuMessage`(`url`, `title?`, `elements`, `noticeUser?`, `actions?`) | `Promise<void>` | 发送飞书消息。 |
|
|
229
238
|
|
|
@@ -268,12 +277,266 @@ client.setUserContext({
|
|
|
268
277
|
- **client.org**:组织/项目/应用 CRUD、解析等,见 `OrgService` 与 `types/org`。
|
|
269
278
|
- **client.deliveryStream**:投递流、版本、需求等,见 `DeliveryStreamService` 与 `types/delivery-stream`。
|
|
270
279
|
- **client.ezAbility**:需求枚举、PRD/MVPRD 生成、任务查询等,见 `EzAbilityService` 与 `types/ez-ability`。
|
|
271
|
-
- **
|
|
280
|
+
- **client.files / client.file**:文件服务(files 为新路由,file 兼容老项目);方法同下。
|
|
281
|
+
- **FileService**(独立实例):`createFile`、`getFileById`、`listFiles`、`getStorageStats`、`generateOSSUploadSign`、`getFolderTree`、`getDownloadUrl` 等,见 `FileService` 与 `types/file`。构造时可选 `new FileService(config, 'files')` 或 `'file'`。
|
|
272
282
|
|
|
273
283
|
安装后可在 `node_modules/qing-client/lib/` 下查看 `*.d.ts` 或直接在业务代码中通过 IDE 跳转到上述类型与方法。
|
|
274
284
|
|
|
275
285
|
---
|
|
276
286
|
|
|
287
|
+
## 各服务方法使用示例
|
|
288
|
+
|
|
289
|
+
以下为各服务**每个方法**的调用示例(假设已初始化 `client` 并已 `await client.setToken("...")`)。
|
|
290
|
+
|
|
291
|
+
### client.auth(认证)
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
// 表单登录(旧版)
|
|
295
|
+
const loginRes = await client.auth.login("username", "password", 0);
|
|
296
|
+
await client.setToken(loginRes.access_token);
|
|
297
|
+
|
|
298
|
+
// JSON 登录(推荐)
|
|
299
|
+
const res = await client.auth.loginJson(
|
|
300
|
+
{ username: "user", password: "pwd", org_id: "org1", app_id: "app1" },
|
|
301
|
+
0
|
|
302
|
+
);
|
|
303
|
+
await client.setToken(res.access_token);
|
|
304
|
+
|
|
305
|
+
// 微信小程序登录
|
|
306
|
+
const wxRes = await client.auth.wechatMiniProgramLogin({
|
|
307
|
+
code: "wx_code",
|
|
308
|
+
phone_code: "optional_phone_code",
|
|
309
|
+
});
|
|
310
|
+
await client.setToken(wxRes.access_token);
|
|
311
|
+
|
|
312
|
+
// 注册
|
|
313
|
+
const regRes = await client.auth.register({
|
|
314
|
+
username: "newuser",
|
|
315
|
+
email: "a@b.com",
|
|
316
|
+
password: "pwd",
|
|
317
|
+
name: "显示名",
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// 签发临时令牌
|
|
321
|
+
const tmp = await client.auth.createTemporaryToken({ expires_in: 300 });
|
|
322
|
+
|
|
323
|
+
// 验证临时令牌
|
|
324
|
+
const verified = await client.auth.verifyTemporaryToken({
|
|
325
|
+
temporary_token: tmp.temporary_token,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// 获取当前令牌信息
|
|
329
|
+
const info = await client.auth.getTokenInfo();
|
|
330
|
+
// info: { sub, exp, expires_at, project_id, role, token_type, org_id?, app_id? }
|
|
331
|
+
|
|
332
|
+
// 撤销令牌(不传则撤销当前)
|
|
333
|
+
await client.auth.revokeToken();
|
|
334
|
+
await client.auth.revokeToken("specific_token");
|
|
335
|
+
|
|
336
|
+
// 登出
|
|
337
|
+
await client.auth.logout("token_to_logout");
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### client.user(用户)
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
// 当前用户
|
|
344
|
+
const me = await client.user.getCurrentUser();
|
|
345
|
+
|
|
346
|
+
// 按 ID 查用户(管理员)
|
|
347
|
+
const user = await client.user.getUserById(123);
|
|
348
|
+
|
|
349
|
+
// 创建用户(管理员)
|
|
350
|
+
const created = await client.user.createUser({
|
|
351
|
+
username: "u1",
|
|
352
|
+
email: "u1@example.com",
|
|
353
|
+
password: "pwd",
|
|
354
|
+
name: "User One",
|
|
355
|
+
role: "USER",
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
// 更新用户(管理员)
|
|
359
|
+
const updated = await client.user.updateUser(123, {
|
|
360
|
+
name: "New Name",
|
|
361
|
+
avatar: "https://...",
|
|
362
|
+
phone: "13800138000",
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// 用户列表(分页、可选项目过滤)
|
|
366
|
+
const list = await client.user.listUsers(false, 1, 10, 0);
|
|
367
|
+
// list: { data: User[], pagination: { ... } }
|
|
368
|
+
|
|
369
|
+
// 更新当前用户资料
|
|
370
|
+
await client.user.updateCurrentUser({ name: "My Name", avatar: "..." });
|
|
371
|
+
|
|
372
|
+
// 修改当前用户密码
|
|
373
|
+
await client.user.changeOwnPassword({
|
|
374
|
+
old_password: "old",
|
|
375
|
+
new_password: "new",
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// 停用用户(管理员)
|
|
379
|
+
await client.user.deactivateUser(123);
|
|
380
|
+
|
|
381
|
+
// 恢复用户(管理员)
|
|
382
|
+
await client.user.restoreUser(123);
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### client.msg(消息中心)
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
// 获取当前用户消息列表(可分页、按类型/分类/已读筛选)
|
|
389
|
+
const messages = await client.msg.getMessages({
|
|
390
|
+
type: "business",
|
|
391
|
+
category: "order",
|
|
392
|
+
isRead: false,
|
|
393
|
+
page: 1,
|
|
394
|
+
limit: 20,
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// 管理员获取消息列表(可传 userId/pid/aid 筛选)
|
|
398
|
+
const adminList = await client.msg.getAdminMessages({
|
|
399
|
+
userId: "user-id",
|
|
400
|
+
page: 1,
|
|
401
|
+
limit: 100,
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// 消息类型枚举(供前端筛选用)
|
|
405
|
+
const types = await client.msg.getTypes();
|
|
406
|
+
// types: [{ value: 'system'|'business'|'notice', label }]
|
|
407
|
+
|
|
408
|
+
// 用户消息分类及未读数
|
|
409
|
+
const categories = await client.msg.getCategories();
|
|
410
|
+
// categories: [{ category, unreadCount, latestMessage? }]
|
|
411
|
+
|
|
412
|
+
// 未读统计(管理员可传 userId)
|
|
413
|
+
const stats = await client.msg.getUnreadStats();
|
|
414
|
+
// stats: { total, byCategory: Record<string, number> }
|
|
415
|
+
|
|
416
|
+
// 标记单条已读
|
|
417
|
+
const msg = await client.msg.markAsRead("message_id_24");
|
|
418
|
+
|
|
419
|
+
// 批量标记已读
|
|
420
|
+
const { modifiedCount } = await client.msg.markManyAsRead({
|
|
421
|
+
messageIds: ["id1", "id2"],
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// 删除消息(软删除)
|
|
425
|
+
const deleted = await client.msg.deleteMessage("message_id");
|
|
426
|
+
|
|
427
|
+
// 创建单条消息(管理员)
|
|
428
|
+
const created = await client.msg.createMessage({
|
|
429
|
+
title: "通知标题",
|
|
430
|
+
content: "内容",
|
|
431
|
+
type: "business",
|
|
432
|
+
category: "task",
|
|
433
|
+
userId: "optional_target_user_id",
|
|
434
|
+
metadata: { taskId: "t1" },
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// 批量创建消息(管理员)
|
|
438
|
+
const batch = await client.msg.createManyMessages({
|
|
439
|
+
messages: [
|
|
440
|
+
{ userId: "u1", title: "标题", content: "内容", type: "notice", category: "announce" },
|
|
441
|
+
],
|
|
442
|
+
});
|
|
443
|
+
// batch: { createdCount, messages }
|
|
444
|
+
|
|
445
|
+
// 发送邮件
|
|
446
|
+
await client.msg.sendMail({
|
|
447
|
+
to: ["a@example.com"],
|
|
448
|
+
subject: "主题",
|
|
449
|
+
text: "纯文本内容",
|
|
450
|
+
// 或 html: "<p>HTML 内容</p>",
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
// 发送飞书消息
|
|
454
|
+
await client.msg.sendFeishuMessage({
|
|
455
|
+
url: "https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
|
|
456
|
+
title: "卡片标题",
|
|
457
|
+
elements: [{ title: "字段名", text: "字段值", color: "green" }],
|
|
458
|
+
noticeUser: [{ user_id: "user_open_id" }],
|
|
459
|
+
actions: [{ text: "查看", url: "https://...", type: "primary" }],
|
|
460
|
+
});
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### client.ai(AI 对话与会话)
|
|
464
|
+
|
|
465
|
+
```ts
|
|
466
|
+
// 单次对话(非流式)
|
|
467
|
+
const chat = await client.ai.chatCompletion({
|
|
468
|
+
sessionId: "session-id",
|
|
469
|
+
message: "你好",
|
|
470
|
+
model: "model-id",
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
// 流式对话
|
|
474
|
+
const stream = await client.ai.chatCompletionStream({
|
|
475
|
+
sessionId: "session-id",
|
|
476
|
+
message: "你好",
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// 创建会话
|
|
480
|
+
const session = await client.ai.createSession({
|
|
481
|
+
assistant_id: "asst-id",
|
|
482
|
+
model_id: "model-id",
|
|
483
|
+
title: "新会话",
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// 会话列表
|
|
487
|
+
const sessions = await client.ai.getSessions({ page: 1, limit: 20, status: "active" });
|
|
488
|
+
|
|
489
|
+
// 会话详情
|
|
490
|
+
const detail = await client.ai.getSession("session-id");
|
|
491
|
+
|
|
492
|
+
// 会话消息列表
|
|
493
|
+
const msgs = await client.ai.getSessionMessages("session-id", { page: 1, limit: 50 });
|
|
494
|
+
|
|
495
|
+
// 向会话追加消息
|
|
496
|
+
await client.ai.addMessageToSession("session-id", { role: "user", content: "..." });
|
|
497
|
+
|
|
498
|
+
// 助手列表 / 详情
|
|
499
|
+
const assistants = await client.ai.getAssistants({ page: 1, limit: 20 });
|
|
500
|
+
const assistant = await client.ai.getAssistant("assistant-id");
|
|
501
|
+
await client.ai.createAssistant({ name: "助手", model_id: "..." });
|
|
502
|
+
|
|
503
|
+
// 模型列表 / 详情
|
|
504
|
+
const { models } = await client.ai.getModels({ provider: "openai", capability: "chat" });
|
|
505
|
+
const model = await client.ai.getModel("model-id");
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### client.frontHost(静态 HTML 托管)
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
// 托管项目列表
|
|
512
|
+
const projects = await client.frontHost.listProjects();
|
|
513
|
+
|
|
514
|
+
// 项目详情
|
|
515
|
+
const project = await client.frontHost.getProject("project-id");
|
|
516
|
+
|
|
517
|
+
// 创建托管项目(上传 zip)
|
|
518
|
+
const created = await client.frontHost.createProject({
|
|
519
|
+
deployType: "route",
|
|
520
|
+
routePath: "/my-app",
|
|
521
|
+
file: zipBlob,
|
|
522
|
+
name: "My App",
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// 部署新版本
|
|
526
|
+
const deploy = await client.frontHost.deployNewVersion("project-id", zipBlob);
|
|
527
|
+
|
|
528
|
+
// 项目版本列表
|
|
529
|
+
const versions = await client.frontHost.getProjectVersions("project-id");
|
|
530
|
+
|
|
531
|
+
// 回滚版本
|
|
532
|
+
await client.frontHost.rollbackVersion("project-id", "version-id");
|
|
533
|
+
|
|
534
|
+
// 删除项目
|
|
535
|
+
await client.frontHost.deleteProject("project-id");
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
277
540
|
## 用户与认证
|
|
278
541
|
|
|
279
542
|
### 登录
|
|
@@ -410,6 +673,41 @@ SDK 完全使用 TypeScript 编写,并自带类型声明文件。
|
|
|
410
673
|
|
|
411
674
|
---
|
|
412
675
|
|
|
676
|
+
## CI 测试与已知差异
|
|
677
|
+
|
|
678
|
+
供自动化测试与文档对齐参考。
|
|
679
|
+
|
|
680
|
+
### 1. 当前 SDK 未实现的方法(请勿在测试或文档中引用)
|
|
681
|
+
|
|
682
|
+
以下名称在 SDK 中**不存在**,若 CI 或文档中引用会导致失败。**其中多数在基础服务(basis-service)中也没有对应接口**,属于“后端本身未提供”而非仅 SDK 未封装:
|
|
683
|
+
|
|
684
|
+
| 误用名称 | 说明 / 替代 | 基础服务是否有对应接口 |
|
|
685
|
+
|----------|-------------|------------------------|
|
|
686
|
+
| `auth.refreshToken` / `auth.verifyToken` | 未实现;auth 仅有 login/register/logout、temporary-token、verify-temporary-token | **无**(User-Auth 无 refresh/verify 用户 token 接口) |
|
|
687
|
+
| `token.getTokenInfo` / `token.revokeToken` | 请使用 **`client.auth.getTokenInfo()`**、**`client.auth.revokeToken(token?)`**(接口在 auth 服务下) | **有**(User-Auth 已提供 GET/POST `/api/auth/token/info`、`/token/revoke`) |
|
|
688
|
+
| `token.listActiveTokens` | 未实现 | **无**(需会话存储能力) |
|
|
689
|
+
| `msg.getTypes` | 已实现:**`client.msg.getTypes()`**,返回消息类型枚举(system / business / notice) | **有**(msg_center 已提供 GET `/message/types`) |
|
|
690
|
+
| `file.getStorageStats` | 已实现:**`client.file.getStorageStats()`**(或独立 `FileService` 实例),返回 totalSize、fileCount、quota、usedPercent;配额按角色:超管无上限、管理员 100GB、普通用户 10GB | **有**(file-service 已提供 GET `/storage-stats` 及创建文件时配额校验) |
|
|
691
|
+
| `audit.getLogTypes` / `audit.exportLogs` | 未实现 | **无**(audit-log-service 仅有 POST /、POST /batch、GET / 查询) |
|
|
692
|
+
| `org.resolveProject` / `org.listOrganizations` | 请使用 `org.resolve(request)`、`org.adminListOrganizations(query)` | **有等价**:org 有 POST `/org/resolve`、GET `/admin/orgs`(SDK 为 resolve / adminListOrganizations) |
|
|
693
|
+
| `frontHost.getStats` | 未实现 | **无**(gateway_h5 仅有 /health,无 /stats) |
|
|
694
|
+
| `ezAbility.getRequirementEnums` | 请使用 `ezAbility.enumerateRequirements(request)`(需求枚举) | **有等价**:需求枚举为 `enumerateRequirements`,无单独 getRequirementEnums 接口 |
|
|
695
|
+
|
|
696
|
+
### 2. 参数与调用约定
|
|
697
|
+
|
|
698
|
+
* **provider.getModel(providerId, modelId)**:两个参数均必须为**非空字符串**,传 `undefined` 会抛错。
|
|
699
|
+
* **deliveryStream.listRequirements(streamId, query?, options?)** / **listVersions(streamId, query?, options?)**:第一个参数必须为 **streamId 字符串**,不能传对象。
|
|
700
|
+
|
|
701
|
+
### 3. 权限要求
|
|
702
|
+
|
|
703
|
+
* **org** 服务中大部分管理接口(如 `getProject`、`getProjectApps`、`adminListProjects`、`adminListApps` 等)需要 **SUPER_ADMIN** 或 **SYSTEM** 角色;使用 ADMIN 账号调用会返回权限不足。
|
|
704
|
+
|
|
705
|
+
### 4. 请求体格式
|
|
706
|
+
|
|
707
|
+
* 部分接口请求体在发送前会转为 **snake_case**(如 `ai.createSession`、`msg.createMessage`、`ezAbility.enumerateRequirements` / `generatePRD` / `generateMVPRD` / `nameRequirement`),与后端 API 约定一致;入参仍使用 TypeScript 的 camelCase 类型即可。
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
413
711
|
## License
|
|
414
712
|
|
|
415
713
|
MIT
|
package/lib/client/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AuthService } from "../service/AuthService";
|
|
|
4
4
|
import { MsgService } from "../service/MsgService";
|
|
5
5
|
import { TokenService } from "../service/TokenService";
|
|
6
6
|
import { UserService } from "../service/UserService";
|
|
7
|
+
import { FileService } from "../service/FileService";
|
|
7
8
|
import { AuditLogService } from "../service/AuditLogService";
|
|
8
9
|
import { ProviderService } from "../service/ProviderService";
|
|
9
10
|
import { UsageService } from "../service/UsageService";
|
|
@@ -18,6 +19,10 @@ export declare class Client {
|
|
|
18
19
|
readonly msg: MsgService;
|
|
19
20
|
readonly user: UserService;
|
|
20
21
|
readonly token: TokenService;
|
|
22
|
+
/** 文件服务(V2 新路由 /api/files) */
|
|
23
|
+
readonly files: FileService;
|
|
24
|
+
/** 文件服务(V1 兼容老项目 /api/file) */
|
|
25
|
+
readonly file: FileService;
|
|
21
26
|
readonly aigc: AigcService;
|
|
22
27
|
readonly ai: AiService;
|
|
23
28
|
readonly audit: AuditLogService;
|
package/lib/client/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const AuthService_1 = require("../service/AuthService");
|
|
|
7
7
|
const MsgService_1 = require("../service/MsgService");
|
|
8
8
|
const TokenService_1 = require("../service/TokenService");
|
|
9
9
|
const UserService_1 = require("../service/UserService");
|
|
10
|
+
const FileService_1 = require("../service/FileService");
|
|
10
11
|
const AuditLogService_1 = require("../service/AuditLogService");
|
|
11
12
|
const ProviderService_1 = require("../service/ProviderService");
|
|
12
13
|
const UsageService_1 = require("../service/UsageService");
|
|
@@ -22,6 +23,8 @@ class Client {
|
|
|
22
23
|
this.msg = new MsgService_1.MsgService(config);
|
|
23
24
|
this.user = new UserService_1.UserService(config);
|
|
24
25
|
this.token = new TokenService_1.TokenService(config);
|
|
26
|
+
this.files = new FileService_1.FileService(config, "files");
|
|
27
|
+
this.file = new FileService_1.FileService(config, "file");
|
|
25
28
|
this.aigc = new AigcService_1.AigcService(config);
|
|
26
29
|
this.ai = new AiService_1.AiService(config);
|
|
27
30
|
this.audit = new AuditLogService_1.AuditLogService(config);
|
|
@@ -39,6 +42,8 @@ class Client {
|
|
|
39
42
|
this.msg.setUserContext(context);
|
|
40
43
|
this.user.setUserContext(context);
|
|
41
44
|
this.token.setUserContext(context);
|
|
45
|
+
this.files.setUserContext(context);
|
|
46
|
+
this.file.setUserContext(context);
|
|
42
47
|
this.aigc.setUserContext(context);
|
|
43
48
|
this.ai.setUserContext(context);
|
|
44
49
|
this.audit.setUserContext(context);
|
|
@@ -61,6 +66,8 @@ class Client {
|
|
|
61
66
|
this.msg.setProjectId(projectId);
|
|
62
67
|
this.user.setProjectId(projectId);
|
|
63
68
|
this.token.setProjectId(projectId);
|
|
69
|
+
this.files.setProjectId(projectId);
|
|
70
|
+
this.file.setProjectId(projectId);
|
|
64
71
|
this.aigc.setProjectId(projectId);
|
|
65
72
|
this.ai.setProjectId(projectId);
|
|
66
73
|
this.audit.setProjectId(projectId);
|
|
@@ -83,6 +90,8 @@ class Client {
|
|
|
83
90
|
this.msg.setAppId(appId);
|
|
84
91
|
this.user.setAppId(appId);
|
|
85
92
|
this.token.setAppId(appId);
|
|
93
|
+
this.files.setAppId(appId);
|
|
94
|
+
this.file.setAppId(appId);
|
|
86
95
|
this.aigc.setAppId(appId);
|
|
87
96
|
this.ai.setAppId(appId);
|
|
88
97
|
this.audit.setAppId(appId);
|
|
@@ -105,6 +114,8 @@ class Client {
|
|
|
105
114
|
this.msg.setProjectAndApp(projectId, appId);
|
|
106
115
|
this.user.setProjectAndApp(projectId, appId);
|
|
107
116
|
this.token.setProjectAndApp(projectId, appId);
|
|
117
|
+
this.files.setProjectAndApp(projectId, appId);
|
|
118
|
+
this.file.setProjectAndApp(projectId, appId);
|
|
108
119
|
this.aigc.setProjectAndApp(projectId, appId);
|
|
109
120
|
this.ai.setProjectAndApp(projectId, appId);
|
|
110
121
|
this.audit.setProjectAndApp(projectId, appId);
|
|
@@ -126,6 +137,8 @@ class Client {
|
|
|
126
137
|
await this.msg.setToken(token);
|
|
127
138
|
await this.user.setToken(token);
|
|
128
139
|
await this.token.setToken(token);
|
|
140
|
+
await this.files.setToken(token);
|
|
141
|
+
await this.file.setToken(token);
|
|
129
142
|
await this.aigc.setToken(token);
|
|
130
143
|
await this.ai.setToken(token);
|
|
131
144
|
await this.audit.setToken(token);
|
|
@@ -142,6 +155,8 @@ class Client {
|
|
|
142
155
|
await this.msg.clearToken();
|
|
143
156
|
await this.user.clearToken();
|
|
144
157
|
await this.token.clearToken();
|
|
158
|
+
await this.files.clearToken();
|
|
159
|
+
await this.file.clearToken();
|
|
145
160
|
await this.aigc.clearToken();
|
|
146
161
|
await this.ai.clearToken();
|
|
147
162
|
await this.audit.clearToken();
|
package/lib/service/AiService.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AiService = void 0;
|
|
4
4
|
// src/service/AiService.ts
|
|
5
5
|
const BaseClient_1 = require("../client/BaseClient");
|
|
6
|
+
const snakeCase_1 = require("../utils/snakeCase");
|
|
6
7
|
class AiService extends BaseClient_1.BaseClient {
|
|
7
8
|
constructor(config) {
|
|
8
9
|
super(config, 'ai');
|
|
@@ -27,7 +28,7 @@ class AiService extends BaseClient_1.BaseClient {
|
|
|
27
28
|
return this.request('/session', {
|
|
28
29
|
...options,
|
|
29
30
|
method: 'POST',
|
|
30
|
-
body: request
|
|
31
|
+
body: (0, snakeCase_1.keysToSnakeCase)(request)
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
async getSessions(params, options) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseClient } from "../client/BaseClient";
|
|
2
2
|
import { ClientConfig, RequestOptions } from "../types";
|
|
3
|
-
import { LoginResponse, TemporaryTokenRequest, TemporaryTokenResponse, VerifyTemporaryTokenRequest, VerifyTemporaryTokenResponse, WechatLoginCredentials, LoginCredentials, RegisterRequest, RegisterResponse } from "../types/user";
|
|
3
|
+
import { LoginResponse, TemporaryTokenRequest, TemporaryTokenResponse, VerifyTemporaryTokenRequest, VerifyTemporaryTokenResponse, WechatLoginCredentials, LoginCredentials, RegisterRequest, RegisterResponse, TokenInfoResponse, RevokeTokenResponse } from "../types/user";
|
|
4
4
|
export declare class AuthService extends BaseClient {
|
|
5
5
|
constructor(config: ClientConfig);
|
|
6
6
|
/**
|
|
@@ -29,4 +29,15 @@ export declare class AuthService extends BaseClient {
|
|
|
29
29
|
createTemporaryToken(request?: TemporaryTokenRequest, options?: RequestOptions): Promise<TemporaryTokenResponse>;
|
|
30
30
|
verifyTemporaryToken(request: VerifyTemporaryTokenRequest, options?: RequestOptions): Promise<VerifyTemporaryTokenResponse>;
|
|
31
31
|
logout(token: string, options?: RequestOptions): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取当前令牌信息(脱敏)
|
|
34
|
+
* GET /token/info,需在请求头带 Authorization: Bearer <token>
|
|
35
|
+
*/
|
|
36
|
+
getTokenInfo(options?: RequestOptions): Promise<TokenInfoResponse>;
|
|
37
|
+
/**
|
|
38
|
+
* 撤销令牌
|
|
39
|
+
* 不传 token 则撤销当前请求的令牌;传 token 则撤销指定令牌(仅限本人或管理员)
|
|
40
|
+
* POST /token/revoke
|
|
41
|
+
*/
|
|
42
|
+
revokeToken(token?: string, options?: RequestOptions): Promise<RevokeTokenResponse>;
|
|
32
43
|
}
|
|
@@ -120,5 +120,32 @@ class AuthService extends BaseClient_1.BaseClient {
|
|
|
120
120
|
}
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* 获取当前令牌信息(脱敏)
|
|
125
|
+
* GET /token/info,需在请求头带 Authorization: Bearer <token>
|
|
126
|
+
*/
|
|
127
|
+
async getTokenInfo(options) {
|
|
128
|
+
return this.request('/token/info', {
|
|
129
|
+
...options,
|
|
130
|
+
method: 'GET',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 撤销令牌
|
|
135
|
+
* 不传 token 则撤销当前请求的令牌;传 token 则撤销指定令牌(仅限本人或管理员)
|
|
136
|
+
* POST /token/revoke
|
|
137
|
+
*/
|
|
138
|
+
async revokeToken(token, options) {
|
|
139
|
+
const body = token ? { token } : {};
|
|
140
|
+
return this.request('/token/revoke', {
|
|
141
|
+
...options,
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: {
|
|
144
|
+
...options?.headers,
|
|
145
|
+
'Content-Type': 'application/json',
|
|
146
|
+
},
|
|
147
|
+
body: JSON.stringify(body),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
123
150
|
}
|
|
124
151
|
exports.AuthService = AuthService;
|
|
@@ -81,6 +81,9 @@ class DeliveryStreamService extends BaseClient_1.BaseClient {
|
|
|
81
81
|
* GET /streams/:streamId/versions
|
|
82
82
|
*/
|
|
83
83
|
async listVersions(streamId, query, options) {
|
|
84
|
+
if (typeof streamId !== "string" || streamId === "") {
|
|
85
|
+
throw new Error("DeliveryStreamService.listVersions 第一个参数必须为 streamId 字符串");
|
|
86
|
+
}
|
|
84
87
|
return this.paginatedRequest(`/streams/${streamId}/versions`, {
|
|
85
88
|
...options,
|
|
86
89
|
method: 'GET',
|
|
@@ -146,6 +149,9 @@ class DeliveryStreamService extends BaseClient_1.BaseClient {
|
|
|
146
149
|
* GET /streams/:streamId/requirements
|
|
147
150
|
*/
|
|
148
151
|
async listRequirements(streamId, query, options) {
|
|
152
|
+
if (typeof streamId !== "string" || streamId === "") {
|
|
153
|
+
throw new Error("DeliveryStreamService.listRequirements 第一个参数必须为 streamId 字符串");
|
|
154
|
+
}
|
|
149
155
|
return this.paginatedRequest(`/streams/${streamId}/requirements`, {
|
|
150
156
|
...options,
|
|
151
157
|
method: 'GET',
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.EzAbilityService = void 0;
|
|
4
4
|
// npm/src/service/EzAbilityService.ts
|
|
5
5
|
const BaseClient_1 = require("../client/BaseClient");
|
|
6
|
+
const snakeCase_1 = require("../utils/snakeCase");
|
|
6
7
|
/**
|
|
7
8
|
* EzAbility 服务 - AI 能力服务客户端
|
|
8
9
|
*
|
|
@@ -34,7 +35,7 @@ class EzAbilityService extends BaseClient_1.BaseClient {
|
|
|
34
35
|
async enumerateRequirements(request) {
|
|
35
36
|
return this.request("/requirements/enumerate", {
|
|
36
37
|
method: "POST",
|
|
37
|
-
body: request,
|
|
38
|
+
body: (0, snakeCase_1.keysToSnakeCase)(request),
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
// ==================== PRD生成 ====================
|
|
@@ -54,7 +55,7 @@ class EzAbilityService extends BaseClient_1.BaseClient {
|
|
|
54
55
|
async generatePRD(request) {
|
|
55
56
|
return this.request("/prd/generate", {
|
|
56
57
|
method: "POST",
|
|
57
|
-
body: request,
|
|
58
|
+
body: (0, snakeCase_1.keysToSnakeCase)(request),
|
|
58
59
|
});
|
|
59
60
|
}
|
|
60
61
|
/**
|
|
@@ -113,7 +114,7 @@ class EzAbilityService extends BaseClient_1.BaseClient {
|
|
|
113
114
|
async generateMVPRD(request) {
|
|
114
115
|
return this.request("/prd-mvp/generate", {
|
|
115
116
|
method: "POST",
|
|
116
|
-
body: request,
|
|
117
|
+
body: (0, snakeCase_1.keysToSnakeCase)(request),
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
120
|
/**
|
|
@@ -166,7 +167,7 @@ class EzAbilityService extends BaseClient_1.BaseClient {
|
|
|
166
167
|
async nameRequirement(request) {
|
|
167
168
|
return this.request("/requirement-naming/name", {
|
|
168
169
|
method: "POST",
|
|
169
|
-
body: request,
|
|
170
|
+
body: (0, snakeCase_1.keysToSnakeCase)(request),
|
|
170
171
|
});
|
|
171
172
|
}
|
|
172
173
|
// ==================== 任务管理 ====================
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { BaseClient } from "../client/BaseClient";
|
|
2
2
|
import { ClientConfig, RequestOptions, PaginatedResponse } from "../types";
|
|
3
|
-
import { File, CreateFileRequest, UpdateFileRequest, FileListQuery, Folder, FolderItemsResponse, FolderTreeNode, CreateFolderRequest, UpdateFolderRequest, OSSConfig, GenerateOSSUploadSignRequest, GenerateOSSUploadSignResponse, OSSCallbackQuery, OSSCallbackBody, OSSCallbackResponse, TaskOptionsResponse, FolderContentsResponse, FileUrlResponse, BatchDeleteRequest, BatchDeleteResponse, BatchMoveRequest, BatchMoveResponse, FileSearchQuery, TransferUploadFileRequest, TransferUploadFileResponse } from "../types/file";
|
|
3
|
+
import { File, CreateFileRequest, UpdateFileRequest, FileListQuery, StorageStatsResponse, Folder, FolderItemsResponse, FolderTreeNode, CreateFolderRequest, UpdateFolderRequest, OSSConfig, GenerateOSSUploadSignRequest, GenerateOSSUploadSignResponse, OSSCallbackQuery, OSSCallbackBody, OSSCallbackResponse, TaskOptionsResponse, FolderContentsResponse, FileUrlResponse, BatchDeleteRequest, BatchDeleteResponse, BatchMoveRequest, BatchMoveResponse, FileSearchQuery, TransferUploadFileRequest, TransferUploadFileResponse } from "../types/file";
|
|
4
|
+
/**
|
|
5
|
+
* 文件服务:files(V2 新路由)/ file(V1 兼容老项目)
|
|
6
|
+
* 同一后端,仅请求路径前缀不同:/api/files 或 /api/file
|
|
7
|
+
*/
|
|
4
8
|
export declare class FileService extends BaseClient {
|
|
5
|
-
constructor(config: ClientConfig);
|
|
9
|
+
constructor(config: ClientConfig, serviceName?: 'files' | 'file');
|
|
6
10
|
/**
|
|
7
11
|
* 创建文件记录(OSS回调使用)
|
|
8
12
|
* POST /api/files (网关转发到 /api/v1/files)
|
|
@@ -23,6 +27,12 @@ export declare class FileService extends BaseClient {
|
|
|
23
27
|
* DELETE /api/files/:id (网关转发到 /api/v1/files/:id)
|
|
24
28
|
*/
|
|
25
29
|
deleteFile(fileId: string, options?: RequestOptions): Promise<null>;
|
|
30
|
+
/**
|
|
31
|
+
* 获取存储统计与配额
|
|
32
|
+
* GET /api/files/storage-stats
|
|
33
|
+
* 按角色:超管无上限,管理员 100GB,普通用户 10GB;返回 totalSize、fileCount、quota、usedPercent
|
|
34
|
+
*/
|
|
35
|
+
getStorageStats(options?: RequestOptions): Promise<StorageStatsResponse>;
|
|
26
36
|
/**
|
|
27
37
|
* 获取文件列表
|
|
28
38
|
* GET /api/files (网关转发到 /api/v1/files)
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FileService = void 0;
|
|
4
4
|
const BaseClient_1 = require("../client/BaseClient");
|
|
5
|
+
/**
|
|
6
|
+
* 文件服务:files(V2 新路由)/ file(V1 兼容老项目)
|
|
7
|
+
* 同一后端,仅请求路径前缀不同:/api/files 或 /api/file
|
|
8
|
+
*/
|
|
5
9
|
class FileService extends BaseClient_1.BaseClient {
|
|
6
|
-
constructor(config) {
|
|
7
|
-
super(config,
|
|
10
|
+
constructor(config, serviceName = 'files') {
|
|
11
|
+
super(config, serviceName);
|
|
8
12
|
}
|
|
9
13
|
/**
|
|
10
14
|
* 创建文件记录(OSS回调使用)
|
|
@@ -66,6 +70,17 @@ class FileService extends BaseClient_1.BaseClient {
|
|
|
66
70
|
method: 'DELETE'
|
|
67
71
|
});
|
|
68
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* 获取存储统计与配额
|
|
75
|
+
* GET /api/files/storage-stats
|
|
76
|
+
* 按角色:超管无上限,管理员 100GB,普通用户 10GB;返回 totalSize、fileCount、quota、usedPercent
|
|
77
|
+
*/
|
|
78
|
+
async getStorageStats(options) {
|
|
79
|
+
return this.request('/storage-stats', {
|
|
80
|
+
...options,
|
|
81
|
+
method: 'GET'
|
|
82
|
+
});
|
|
83
|
+
}
|
|
69
84
|
/**
|
|
70
85
|
* 获取文件列表
|
|
71
86
|
* GET /api/files (网关转发到 /api/v1/files)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseClient } from "../client/BaseClient";
|
|
2
2
|
import { ClientConfig, RequestOptions } from "../types";
|
|
3
|
-
import { BatchCreateMessageRequest, BatchMarkAsReadRequest, CategoryInfo, CreateMessageRequest, FeishuMessage, MailRequest, MarkAsReadRequest, Message, MessageQueryParams, MessageStats } from "../types/msg";
|
|
3
|
+
import { BatchCreateMessageRequest, BatchMarkAsReadRequest, CategoryInfo, CreateMessageRequest, FeishuMessage, MailRequest, MarkAsReadRequest, Message, MessageQueryParams, MessageStats, MessageTypeItem } from "../types/msg";
|
|
4
4
|
export declare class MsgService extends BaseClient {
|
|
5
5
|
constructor(config: ClientConfig);
|
|
6
6
|
sendMail(request: MailRequest, options?: RequestOptions): Promise<void>;
|
|
@@ -14,6 +14,8 @@ export declare class MsgService extends BaseClient {
|
|
|
14
14
|
deleteMessage(messageId: string, request?: MarkAsReadRequest, options?: RequestOptions): Promise<Message>;
|
|
15
15
|
getUnreadStats(userId?: string, options?: RequestOptions): Promise<MessageStats>;
|
|
16
16
|
getCategories(options?: RequestOptions): Promise<CategoryInfo[]>;
|
|
17
|
+
/** 获取消息类型枚举(system / business / notice),供前端筛选或展示 */
|
|
18
|
+
getTypes(options?: RequestOptions): Promise<MessageTypeItem[]>;
|
|
17
19
|
createMessage(request: CreateMessageRequest, options?: RequestOptions): Promise<Message>;
|
|
18
20
|
createManyMessages(request: BatchCreateMessageRequest, options?: RequestOptions): Promise<{
|
|
19
21
|
createdCount: number;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MsgService = void 0;
|
|
4
4
|
// client/npm/src/service/MsgService.ts
|
|
5
5
|
const BaseClient_1 = require("../client/BaseClient");
|
|
6
|
+
const snakeCase_1 = require("../utils/snakeCase");
|
|
6
7
|
class MsgService extends BaseClient_1.BaseClient {
|
|
7
8
|
constructor(config) {
|
|
8
9
|
super(config, 'msg');
|
|
@@ -88,12 +89,19 @@ class MsgService extends BaseClient_1.BaseClient {
|
|
|
88
89
|
method: 'GET'
|
|
89
90
|
});
|
|
90
91
|
}
|
|
92
|
+
/** 获取消息类型枚举(system / business / notice),供前端筛选或展示 */
|
|
93
|
+
async getTypes(options) {
|
|
94
|
+
return this.request('/message/types', {
|
|
95
|
+
...options,
|
|
96
|
+
method: 'GET'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
91
99
|
// 创建消息(需要管理员权限)
|
|
92
100
|
async createMessage(request, options) {
|
|
93
101
|
return this.request('/message', {
|
|
94
102
|
...options,
|
|
95
103
|
method: 'POST',
|
|
96
|
-
body: request
|
|
104
|
+
body: (0, snakeCase_1.keysToSnakeCase)(request)
|
|
97
105
|
});
|
|
98
106
|
}
|
|
99
107
|
// 批量创建消息(需要管理员权限)
|
|
@@ -73,6 +73,9 @@ class ProviderService extends BaseClient_1.BaseClient {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
async getModel(providerId, modelId, options) {
|
|
76
|
+
if (providerId == null || providerId === "" || modelId == null || modelId === "") {
|
|
77
|
+
throw new Error("ProviderService.getModel 需要有效的 providerId 和 modelId 字符串");
|
|
78
|
+
}
|
|
76
79
|
return this.request(this.path(`/models/${providerId}/${modelId}`), {
|
|
77
80
|
...options,
|
|
78
81
|
method: "GET",
|
package/lib/types/file.d.ts
CHANGED
|
@@ -48,6 +48,16 @@ export interface FileListQuery {
|
|
|
48
48
|
acl?: 'private' | 'public-read';
|
|
49
49
|
uid?: string;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* 存储统计与配额(getStorageStats 返回)
|
|
53
|
+
* quota 为 null 表示无上限(超管);有值时 usedPercent 为已用百分比
|
|
54
|
+
*/
|
|
55
|
+
export interface StorageStatsResponse {
|
|
56
|
+
totalSize: number;
|
|
57
|
+
fileCount: number;
|
|
58
|
+
quota: number | null;
|
|
59
|
+
usedPercent?: number;
|
|
60
|
+
}
|
|
51
61
|
export interface Folder {
|
|
52
62
|
id: string;
|
|
53
63
|
name: string;
|
package/lib/types/msg.d.ts
CHANGED
package/lib/types/user.d.ts
CHANGED
|
@@ -105,3 +105,23 @@ export interface VerifyTemporaryTokenResponse {
|
|
|
105
105
|
token_valid: boolean;
|
|
106
106
|
project_id: number;
|
|
107
107
|
}
|
|
108
|
+
/** 当前令牌信息(脱敏,供前端判断身份与过期) */
|
|
109
|
+
export interface TokenInfoResponse {
|
|
110
|
+
sub: string;
|
|
111
|
+
exp: number;
|
|
112
|
+
expires_at?: string;
|
|
113
|
+
project_id: number;
|
|
114
|
+
role?: string;
|
|
115
|
+
token_type?: string;
|
|
116
|
+
org_id?: string;
|
|
117
|
+
app_id?: string;
|
|
118
|
+
}
|
|
119
|
+
/** 撤销令牌请求(不传 token 则撤销当前请求的令牌) */
|
|
120
|
+
export interface RevokeTokenRequest {
|
|
121
|
+
token?: string;
|
|
122
|
+
}
|
|
123
|
+
/** 撤销令牌响应 */
|
|
124
|
+
export interface RevokeTokenResponse {
|
|
125
|
+
success: boolean;
|
|
126
|
+
message: string;
|
|
127
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.keysToSnakeCase = keysToSnakeCase;
|
|
4
|
+
/**
|
|
5
|
+
* 将 camelCase 键名转为 snake_case(用于请求体与后端 API 对齐)
|
|
6
|
+
*/
|
|
7
|
+
function toSnakeCase(str) {
|
|
8
|
+
return str.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 递归转换对象键为 snake_case,最大深度 3,避免深层嵌套导致问题
|
|
12
|
+
*/
|
|
13
|
+
function keysToSnakeCase(obj, depth = 0) {
|
|
14
|
+
const maxDepth = 3;
|
|
15
|
+
if (depth > maxDepth)
|
|
16
|
+
return obj;
|
|
17
|
+
if (obj === null || typeof obj !== 'object')
|
|
18
|
+
return obj;
|
|
19
|
+
if (Array.isArray(obj)) {
|
|
20
|
+
return obj.map((item) => keysToSnakeCase(item, depth + 1));
|
|
21
|
+
}
|
|
22
|
+
const result = {};
|
|
23
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
24
|
+
const snakeKey = toSnakeCase(key);
|
|
25
|
+
result[snakeKey] = keysToSnakeCase(value, depth + 1);
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|