# @forumulate/sdk 中文文档

规范地址：https://npmcn.com/package/%40forumulate/sdk/

版本：0\.13\.8
npm 元数据更新时间：2026-11-13T15:32:44.219Z
中文译文更新时间：2026-11-15T09:50:17.749Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40forumulate/sdk
原文对照：https://npmcn.com/package/%40forumulate/sdk/?lang=original
项目主页：https://forumulate.com/reference

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：38.7 MB，42 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2026-10-03T07:53:26.609Z
- 最新版本发布：2026-11-13T15:32:43.917Z
- 近 30 天下载量：5025（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：28（近 12 个月 28 个）

## 中文简介

用于Forumulate REST API的已打入类型脚本客户端.

## 安装

```sh
npm install @forumulate/sdk
```

也可以使用：`pnpm add @forumulate/sdk`、`yarn add @forumulate/sdk`、`bun add @forumulate/sdk`

## README

# @ 论坛/ sdk

输入的脚本客户端 [论坛](https://forumulate.com/) REST API:一个组织的文献、论坛、博客和其他一切。 它没有运行时间依赖关系,运行在Node 18+, Bun, Deno 和浏览器中( global) `fetch`) (中文(简体) ).

## 安装

```sh
npm install @forumulate/sdk
```

## 认证

Mint 个人访问 **账户 —— 托肯斯** (单位:千美元)[论坛.com/账户/托肯](https://forumulate.com/account/tokens)) (中文(简体) ). 象征性需要 `read` 读取和 `read` + 键 `write` 改变一切. [API 令牌和范围](https://forumulate.com/guides/api-tokens-and-scopes) 解释两道门是象征性的.

```ts
import { ForumulateClient } from '@forumulate/sdk';

// Reads FORUMULATE_TOKEN and FORUMULATE_URL (default https://forumulate.com).
const forumulate = ForumulateClient.fromEnv();

// …or explicitly. The API base is the site plus /api.
const explicit = new ForumulateClient({
  baseUrl: 'https://forumulate.com/api',
  token: process.env.FORUMULATE_TOKEN,
});
```

| 变量 | 默认 | 含义 |
| --- | --- | --- |
| `FORUMULATE_TOKEN` | 无 | 个人访问 Token, 发送为 `Authorization: Bearer`。 。 。 . |
| `FORUMULATE_URL` | `https://forumulate.com` | 遗址. API是它的 API是它的 API是它的 `/api`。一个已经结束于 `/api` 用于当前. |
| `FORUMULATE_API_URL` | 无 | 准确的 API 基础,用于本地 API 没有 `/api` 前缀( e)`http://localhost:4000`) (中文(简体) ). |

这个 [国 际](https://www.npmjs.com/package/@forumulate/cli) 编辑 [MCP 服务器](https://www.npmjs.com/package/@forumulate/mcp) 读取相同的变量.

## 快速启动

```ts
const { user } = await forumulate.auth.me();
const { orgs } = await forumulate.orgs.list();
const orgId = orgs[0]!.id; // ids and slugs are both accepted wherever an org id is

// Every list is an async iterator over every row, across every page.
for await (const space of forumulate.spaces.list({ orgId })) {
  console.log(space.slug, space.type);
}
```

## 每个操作都是一种方法

每个API的~1800操作都是以其操作Id命名的方法: `ForumTopics_get` 实值 `forumulate.forum.topics.get`, (中文(简体) ), `Webhook_rotate` 实值 `forumulate.webhooks.rotate`。路径、查询、正文和回复从 openAPI 光谱和命名空间由它产生,所以在 [API 参考](https://forumulate.com/reference) 在这里是一种方法.

```ts
// One argument: path params at the top level, `query` and `body` nested.
const { space } = await forumulate.spaces.get({ orgId, spaceId });
await forumulate.blog.create({ orgId, spaceId, body: { title: 'v2 is out', content } });
await forumulate.webhooks.update({ orgId, webhookId, body: { active: false } });
await forumulate.webhooks.delete({ orgId, webhookId }); // `delete` aliases the API's `remove`
await forumulate.tokens.rotate({ id: patId });
await forumulate.forum.taxonomy.listCategories({ orgId, spaceId }); // a sub-namespace per area of a namespace
```

| 区域 | 命名空间 |
| --- | --- |
| 组织 | `orgs`, (中文(简体) ), `spaces`, (中文(简体) ), `sites`, (中文(简体) ), `members`, (中文(简体) ), `invites`, (中文(简体) ), `roles`, (中文(简体) ), `grants`, (中文(简体) ), `groups`, (中文(简体) ), `tokens`, (中文(简体) ), `users`, (中文(简体) ), `billing`, (中文(简体) ), `sso`, (中文(简体) ), `scim` |
| 文档 | `items`, (中文(简体) ), `pages`, (中文(简体) ), `collections`, (中文(简体) ), `shapes`, (中文(简体) ), `snapshots`, (中文(简体) ), `changeRequests`, (中文(简体) ), `docs`, (中文(简体) ), `openapi`, (中文(简体) ), `comments` |
| 社区和出版 | `blog`, (中文(简体) ), `forum`, (中文(简体) ), `community`, (中文(简体) ), `moderation`, (中文(简体) ), `chat`, (中文(简体) ), `messages`, (中文(简体) ), `changelog`, (中文(简体) ), `roadmap`, (中文(简体) ), `newsletter` |
| 空间类型 | `status`, (中文(简体) ), `events`, (中文(简体) ), `courses`, (中文(简体) ), `faq`, (中文(简体) ), `careers`, (中文(简体) ), `legal`, (中文(简体) ), `forms`, (中文(简体) ), `questions` |
| 平台 | `webhooks`, (中文(简体) ), `domains`, (中文(简体) ), `themes`, (中文(简体) ), `extensions`, (中文(简体) ), `integrations`, (中文(简体) ), `notifications`, (中文(简体) ), `mail`, (中文(简体) ), `assets`, (中文(简体) ), `embeds`, (中文(简体) ), `privacy` |
| 搜索、人工智能和分析 | `search`, (中文(简体) ), `ai`, (中文(简体) ), `analytics` |
| 无头CMS | `content` (图书馆、条目、模型、地方、密钥、资产.), `delivery` |
| 公共阅读器( 无符号) | `public`,则 `public…` 每个区域的子名称空间 : `forum.publicTopic`, (中文(简体) ), `status.public`, (中文(简体) ), `blog.public`. |

`method.operationId` 告诉你是什么操作 一个方法呼叫。 以 id 表示,类型相同:

```ts
const { space } = await forumulate.request('Space_get', { orgId, spaceId });
for await (const hook of forumulate.paginate('Webhook_list', { orgId })) console.log(hook.url);
```

0.5位助手(`spaces.list(orgId)`, (中文(简体) ), `items.create(orgId, spaceId, input)`...) 仍然工作着 不变,但 `auth.register` 财务报告和审定财务报表 `auth.login`,在 0.6 中被删除:他们的路线在 签入后转到了阿特拉斯系统,所以每个呼叫者都失败了. 以个人访问托肯认证 。 如果用生成的方法分享一个名称,它就是相同的操作,而成员 无论是呼叫形状.

### 倾斜

列表返回 a `PagePromise`数字 : `await` 当API回答第一页时, `for await` 每行都是这样.

```ts
const first = await forumulate.blog.list({ orgId, spaceId, query: { limit: 50 } });
first.page.nextCursor; // the envelope: page.{limit, hasMore, nextCursor, total}, rows under data

for await (const post of forumulate.blog.list({ orgId, spaceId })) {
  /* every post */
}
for await (const page of forumulate.blog.list({ orgId, spaceId }).pages()) {
  /* every page */
}
```

走着走着 `page.nextCursor`,以及 `?page=` 对于没有光标的排序列表。 这个 生成的方法发送 `Forumulate-Version` (SDK的版本生成于, `API_VERSION`, (中文(简体) ), 除非你设定 `apiVersion`),因为只有一个版本的答案携带了信封.

## 共同任务

### 1\. 写出并出版 " 降标 " 一页

`items` 是类型不可知的表面: 相同的呼叫会写出一个 docs 页面、博客文章或论坛主题 .

```ts
const { item } = await forumulate.items.create(orgId, spaceId, {
  title: 'Install',
  slug: 'install',
  body: '# Install\n\nRun `npm i acme`.',
});
await forumulate.items.publish(orgId, spaceId, item.id);

// Later: replace the body and republish.
await forumulate.items.setContent(orgId, spaceId, item.id, { body: '# Install\n\n…' });
await forumulate.items.publish(orgId, spaceId, item.id);
```

### 2\. 列出空间中的所有内容

```ts
const res = await forumulate.items.list(orgId, spaceId, { limit: 100, include: ['body'] });
for (const it of res.items) console.log(it.id, it.title, it.contentIn);
// res.page.nextCursor pages onward; res.sync.checkpoint drives an incremental sync.
```

问 `body`。 。 。 . `sections` 仅为写在形状上的棋子而填入,所以空格为自由形式的页面答案 `include: ['sections']` 单用空物体.

### 3\. 搜索

```ts
// Everything you can see in an org: docs, forum, blog.
const { hits } = await forumulate.search.unified(orgId, 'rate limits', { limit: 10 });

// A public docs space, no token needed.
const anon = new ForumulateClient({ baseUrl: 'https://forumulate.com/api' });
const { hits: pub } = await anon.public.search(orgId, spaceId, 'rate limits');
```

### 4\. 启动论坛专题并作出答复

```ts
const doc = (text: string) => ({
  type: 'doc' as const,
  content: [{ type: 'paragraph', content: [{ type: 'text', text }] }],
});
const { topic } = await forumulate.forum.createTopic(orgId, forumSpaceId, {
  title: 'v2 is out',
  content: doc('Here is what changed.'),
});
const topicId = (topic as { id: string }).id;
await forumulate.forum.reply(orgId, forumSpaceId, topicId, doc('Upgrade notes are in the docs.'));
```

### 5\. 校验网签

```ts
import { constructWebhookEvent } from '@forumulate/sdk';

// Verifies the signature and its timestamp, THEN parses; throws if either fails.
const event = await constructWebhookEvent({
  secret: process.env.FORUMULATE_WEBHOOK_SECRET!,
  body: rawBody, // the exact bytes received, before JSON.parse
  signature: req.headers['x-forumulate-signature'] as string,
  timestamp: req.headers['x-forumulate-timestamp'] as string, // deliveries older than 5 min fail
});
```

`verifyWebhookSignature` (另见: `forumulate.webhooks.verifySignature`)是同一支票返回 a 布尔。 以 `forumulate.webhooks.create({ orgId, body: { url, events } })`· ; `webhooks.rotate`, (中文(简体) ), `webhooks.ping`, (中文(简体) ), `webhooks.deliveries` 财务报告和审定财务报表 `webhooks.replay` 之后管理它.

### 6\. 翻译,任何作品

`client.translations` 从空格类型中选择正确的路径:一个docs页面的语言双,一个帖子,主题或发行的翻译,或者一个事件. 你只给原作和语言取名. 机器翻译使用你的组织自己的DeepL密钥或AI提供者. 见 [各地翻译](https://forumulate.com/guides/translations-everywhere)。 。 。 .

```ts
const cov = await client.translations.status(orgId, spaceId); // piece × language → missing/draft/published/outdated
await client.translations.locales.set(orgId, { spaceId }, [{ code: 'es', label: 'Español' }]);
await client.translations.auto(orgId, spaceId, pageId, 'es');
const es = await client.translations.get(orgId, spaceId, pageId, 'es'); // { title, markdown, state }
await client.translations.put(orgId, spaceId, pageId, 'es', { markdown: '…', published: true });
```

### 7\. 您公布的政策的大门注册和注册

`client.policies` 和三个独立的函数是服务器的一半 [政策接受门](https://forumulate.com/guides/policy-acceptance-gate): 您的合法空间 发布术语,隐私政策等,被用户在任何应用程序中接受,无论在任何标识中.

```ts
import { ForumulateClient, signPolicyTicket, verifyAcceptanceToken, policyGatePageUrl } from '@forumulate/sdk';

const client = ForumulateClient.fromEnv();
const space = { orgId: process.env.FORUMULATE_ORG!, spaceId: process.env.FORUMULATE_LEGAL_SPACE! };

// What does this user still have to accept before signing in?
const status = await client.policies.status({ ...space, subject: user.id, event: 'sign_in' });

if (!status.satisfied) {
  // Send them to the hosted acceptance page with a ticket you sign yourself (no API call).
  const ticket = await signPolicyTicket(
    { ...space, subject: user.id, event: 'sign_in', returnUrl: 'https://app.example.com/policy/return' },
    process.env.FORUMULATE_POLICY_GATE_KEYS!, // "pgk_…:pgs_…"
  );
  return redirect(policyGatePageUrl({ ...space, ticket }));
}

// On the way back (or from the widget): verify the acceptance token offline, with key rotation.
const r = await verifyAcceptanceToken(token, {
  keys: process.env.FORUMULATE_POLICY_GATE_KEYS,
  subject: user.id,
  requireSatisfied: true,
});
```

还有 `client.policies.accept` 编号 : `claim` 编号 : `verify` 编号 : `acceptances` 编号 : `export` 编号 : `erase`,以及 `client.policies.list({ spaceId, secret })` 读取 Forumulate 策略 feed v1. `verifyPolicyWebhook(headers, rawBody, secret)` 检查a `policy.published` 编号 : `policy.retired` 通知,以及 `signPolicyFeedRequest` 编号 : `verifyPolicyFeedRequest` 执行种子的要求 签名,所以任何平台都可以消耗feed或服务自己的. Auth0的食谱 苏帕基地的办事员, Firebase, Auth.js 和一个自定义后端 : [政策门秘方](https://forumulate.com/guides/policy-gate-recipes)。 。 。 .

## 每个终点 : `typed()`

以上帮助者覆盖了通路. `typed(method, path, init)` 覆盖 OpenAPI 光谱中的每个路由, 并包含路径、 参数、 查询、 车体和响应全部推断, 以及路径和方法上的自动完成 :

```ts
const { spaces } = await forumulate.typed('get', '/orgs/{orgId}/spaces', {
  params: { orgId },
  query: { limit: 50 },
});

await forumulate.typed('post', '/orgs/{orgId}/spaces', {
  params: { orgId },
  body: { name: 'Docs', slug: 'docs', type: 'DOCS', visibility: 'PUBLIC' },
});
```

过 `raw: true` 对于未受伤害者 `Response` (二进制下载). 为了其他一切, `request(method, path, { body, query, headers })` 是未键入的逃生舱门 `typed` 援助者们必定要援助他们.

响应文件( PDF, PNG, ZIP) 或流分辨率到 `Response`; 文本答案( CSV, Markdown, iCal) 解析为 a `string`。 。 。 .

## 错误

每个非-2xx响应都会发出一个 `ForumulateError` 带有 API 错误信封 : `status`, (中文(简体) ), `code`, (中文(简体) ), `message`, (中文(简体) ), `details` (外地一级,用于 `validation.failed`, (中文(简体) ), `requestId` (在支持请求中引用) 财务报告和审定财务报表 `retryAfter` (秒,当API说).

```ts
import { ForumulateError } from '@forumulate/sdk';

try {
  await forumulate.orgs.create({ body: { name: '', slug: '' } });
} catch (err) {
  if (err instanceof ForumulateError && err.code === 'validation.failed') {
    console.log(err.details); // { name: ['Required'], … }
  }
}
```

A 类 `401` 表示该令牌已丢失或被撤销. A 类 `403` 说明它缺乏范围或能力 [API 令牌和范围](https://forumulate.com/guides/api-tokens-and-scopes)。一个网络失败,其寿命超过其重试是 `ForumulateError` 与 `status: 0` 财务报告和审定财务报表 `code: 'network.error'`。 。 。 .

## 报复和自责

安全重复的请求将在 `408`, (中文(简体) ), `429`, (中文(简体) ), `502`, (中文(简体) ), `503`, (中文(简体) ), `504` 网络 失败: 默认重复两次, 等待什么 `Retry-After` 说: 而不是睡觉过, 否则指数回落与焦躁。 A 类 `500` 未重审.

每个POST和PACH都带有 `Idempotency-Key`,每次呼叫一次,再使用一次 重试,所以写一个超时的回试,没有跑两次. 传出你自己去去除尘器 跨进程:

```ts
await forumulate.items.create({ orgId, spaceId, body, idempotencyKey: message.id });
```

每通电话都要 `headers`, (中文(简体) ), `signal` (单位:千美元) `AbortSignal`和 `maxRetries`。 。 。 .

## 选项

```ts
new ForumulateClient({
  baseUrl: 'https://forumulate.com/api',
  token,
  apiVersion: '2027-02-01', // Forumulate-Version for every request (default: generated methods only)
  maxRetries: 2, // 0 turns retries off
  autoIdempotencyKey: true, // generated Idempotency-Key on POST/PATCH
  userAgent: 'my-app/1.0', // default forumulate-sdk-js/<version> outside a browser
  headers: { 'X-Trace': id }, // sent on every request
  fetch: customFetch, // any fetch-compatible function
  credentials: true, // browser on the same origin: send the session cookie instead of a token
});
```

默认 `User-Agent` 浏览器外的事项:边缘防火墙挑战默认库用户代理.

软件包没有运行时的依赖性,并且标记为无副作用 命名空间大约为100个KB未被忽略(约20个KB gziped),命名空间是先用后建.

## 链接

-   [API 参考](https://forumulate.com/reference): 每条路由, OpenAPI 文档位于 `https://forumulate.com/api/openapi.json`。 。 。 .
-   [指南](https://forumulate.com/guides) • 妇女 [社区](https://forumulate.com/community)
-   [`@forumulate/cli`](https://www.npmjs.com/package/@forumulate/cli):来自终端或CI的同名API.
-   [`@forumulate/mcp`](https://www.npmjs.com/package/@forumulate/mcp): 连接克劳德, Cursor 或 VS 代码到您的组织.

## 维护者: 重新生成类型

`src/schema.ts` 备份 `typed()`。它是生成的,而且只有类型;不要手工编辑。 从部署的光谱中刷新它 :

```sh
curl -s https://forumulate.com/api/openapi.json -o packages/sdk/openapi.json
pnpm --filter @forumulate/sdk generate-schema   # → src/schema.ts, then src/operations.gen.ts
```

`src/operations.gen.ts` 是命名空间后面的路由表( y)`generate-operations` 重建它 (仅此一次)。 安置在 `scripts/generate-operations.mjs`: 操作ID标签的短地图 前缀为命名空间,所以新标签在某个地方登陆时不需要编辑. `src/coverage.test.ts` 失败 当表格僵化时,当操作没有方法时,或者当一个0.5助手和生成一个 方法共享名称而不是操作.

## 许可证

麻省理工学院

## 常见问题

### @forumulate/sdk 是什么？

用于Forumulate REST API的已打入类型脚本客户端\.

### 如何安装 @forumulate/sdk？

在项目目录运行 npm install @forumulate/sdk，或使用 pnpm add / yarn add / bun add。

### @forumulate/sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @forumulate/sdk 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @forumulate/sdk 可以商用吗？

@forumulate/sdk 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @forumulate/sdk 的下载量有多少？

根据 npm 官方下载统计，@forumulate/sdk 在 2026/10/16 – 2026/11/14 这 30 天内被下载 5,025 次，日均约 168 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @forumulate/sdk 还在维护吗？

最新版本 0\.13\.8 发布于 2026/11/13（2 天前）；至今共发布 28 个版本，其中过去 12 个月发布了 28 个；首次发布于 2026/10/03。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

