API 客户端
Framedash API 客户端(@framedash/api-client)是用于操作 Framedash 开发者平台 REST API 的带类型 TypeScript / JavaScript 客户端。它与 @framedash/cli 和 @framedash/mcp-server 内部使用的客户端相同,并以独立包的形式发布,便于你将 Framedash 遥测数据直接集成到自有的内部工具、仪表盘和自动化流程中。
它内置了认证、项目作用域路径生成、响应解包和结构化错误处理,以及若干安全防护(仅限 HTTPS 的基础 URL、拒绝会泄露凭据的重定向、请求超时),让你专注于数据本身。
- Node.js 18 或更高版本(使用全局
fetch、AbortSignal.timeout和node:net) - 用于访问 Web API 的管理员 API 密钥(
fd_admin_前缀)
npm install @framedash/api-clientimport { ApiClient, ApiError } from "@framedash/api-client";
const client = new ApiClient({ baseUrl: "https://app.framedash.dev", apiKey: process.env.FRAMEDASH_API_KEY ?? "", projectId: process.env.FRAMEDASH_PROJECT_ID ?? "", onError: (err: ApiError) => { // onError 在任何非成功响应时被调用,必须 throw(或退出)。 // 其返回类型为 `never`。抛出的值会传播到你的 await。 throw err; },});
// 项目作用域 GET -> /api/v1/projects/{projectId}/dashboard?days=30const dashboard = await client.get(client.projectPath("dashboard?days=30"));console.log(dashboard);客户端会自动解包 API 信封:成功的 { "success": true, "data": ... } 响应仅解析为 data。
ApiClient 构造函数接收一个选项对象:
| 选项 | 类型 | 说明 |
|---|---|---|
baseUrl | string | 应用主机 URL(例如 https://app.framedash.dev)。必须为 HTTPS(仅 localhost / 回环允许 HTTP)。 |
apiKey | string | 管理员 API 密钥,每次请求都通过 X-API-Key 头发送。 |
projectId | string | 默认项目 UUID。projectPath() 必需;对于非项目路径还会作为 X-Project-Id 头发送。 |
onError | (error: ApiError) => never | 在任何非成功响应时调用。必须 throw 或退出进程。 |
基础 URL 在客户端构造时会被校验,不安全或格式错误的 URL 会立即 throw。你也可以使用导出的 assertSafeBaseUrl(baseUrl) 自行执行同样的检查。
四个 HTTP 辅助方法覆盖 Web API。每个都返回解包后的 data 负载,并可通过泛型参数指定类型:
const data = await client.get<MyType>("/api/v1/...");await client.post("/api/v1/...", body);await client.patch("/api/v1/...", body);await client.delete("/api/v1/...");项目作用域路径
Section titled “项目作用域路径”大多数端点都按项目划分。projectPath(suffix) 使用客户端配置的 projectId 构建 /api/v1/projects/{projectId}/{suffix}:
// GET /api/v1/projects/{projectId}/statusconst status = await client.get(client.projectPath("status"));
// GET /api/v1/projects/{projectId}/retention?days=30const retention = await client.get(client.projectPath("retention?days=30"));
// GET /api/v1/projects/{projectId}/mapsconst maps = await client.get(client.projectPath("maps"));在未配置 projectId 的情况下调用 projectPath() 会 throw。
切换项目上下文
Section titled “切换项目上下文”withProject(projectId) 返回绑定到另一个项目的新客户端,复用相同的基础 URL、API 密钥和错误处理器。原客户端保持不变:
const other = client.withProject("another-project-uuid");const otherStatus = await other.get(other.projectPath("status"));
// 当前绑定的项目 ID:console.log(client.currentProjectId);执行 SQL 查询
Section titled “执行 SQL 查询”const rows = await client.post("/api/v1/query", { sql: "SELECT event_name, count() FROM events GROUP BY event_name", project_id: client.currentProjectId, limit: 100,});// 列出告警规则const alerts = await client.get(client.projectPath("alerts"));
// 创建告警规则const created = await client.post(client.projectPath("alerts"), { name: "FPS Alert", // ...其余规则字段});
// 停用告警规则await client.delete(client.projectPath(`alerts/${alertId}`));导入内容注册表条目
Section titled “导入内容注册表条目”// content 端点在路径上不是项目作用域;// 客户端会根据配置的 projectId 自动添加 X-Project-Id 头。// 批量 upsert 的请求体将数组包装在 entries 属性中(每次请求最多 500 条)。await client.post("/api/v1/content", { entries });const content = await client.get("/api/v1/content");端点、查询参数和负载结构的完整列表请参阅 API 概览。
任何非成功响应(网络错误、非 2xx 状态,或缺少 success: true 的响应体)都会被转换为 ApiError 并传给你的 onError 回调。ApiError 携带解析后的 RFC 9457 Problem Details:
| 成员 | 类型 | 说明 |
|---|---|---|
status | number | HTTP 状态码。 |
headers | Headers | 响应头(例如 X-RateLimit-Reset)。 |
message | string | 人类可读的错误信息。 |
retryable | boolean | API 是否将该错误标记为可重试。 |
retryAfter | number | undefined | 建议的重试间隔(秒)。 |
errorCategory | string | undefined | API 错误类别。 |
problem | ProblemDetails | 解析后的原始 Problem Details 对象。 |
一个考虑限流的处理器:
const client = new ApiClient({ baseUrl: "https://app.framedash.dev", apiKey: process.env.FRAMEDASH_API_KEY ?? "", projectId: process.env.FRAMEDASH_PROJECT_ID ?? "", onError: (err: ApiError): never => { if (err.status === 429) { const retryAfter = err.retryAfter ?? err.headers.get("X-RateLimit-Reset"); throw new Error(`Rate limited; retry after ${retryAfter}`); } throw err; },});为避免管理员密钥泄露,客户端强制执行若干安全措施:
- 仅限 HTTPS 的基础 URL。除
localhost/ 回环开发端点外,普通 HTTP 会被拒绝;嵌入凭据的 URL(https://...@host)也会被拒绝。 - 不允许重定向。API 不会重定向程序化的 JSON 请求,因此任何 3xx 都被视为错误;客户端不会向重定向目标重新发送
X-API-Key头。 - 每次调用 30 秒请求超时(通过
AbortSignal.timeout)。
- API 概览 — REST 端点详情
- CLI 参考 — 基于本客户端构建的命令行工具
- MCP Server — 基于本客户端构建的 LLM 集成