# @arbidocs/client 中文文档

规范地址：https://npmcn.com/package/%40arbidocs/client/

版本：0\.5\.133
npm 元数据更新时间：2026-11-06T20:03:40.835Z
中文译文更新时间：2026-11-06T13:43:39.869Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40arbidocs/client
原文对照：https://npmcn.com/package/%40arbidocs/client/?lang=original
项目主页：https://github.com/arbicity/ARBI-frontend#readme
源码仓库：https://github.com/arbicity/ARBI-frontend

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

- 包体积（解压后）：3.7 MB，9 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-02-17T22:48:18.799Z
- 最新版本发布：2026-11-06T20:03:40.624Z
- 近 30 天下载量：62380（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：480（近 12 个月 480 个）

## 中文简介

ARBI API 的 TypeScript SDK — 零知识认证、 E2E 加密和类型安全 REST 客户端

## 安装

```sh
npm install @arbidocs/client
```

也可以使用：`pnpm add @arbidocs/client`、`yarn add @arbidocs/client`、`bun add @arbidocs/client`

## README

# @ arbidocs/ 客户端

ARBI API的TypeScript客户端——零知识认证,E2E加密,以及类型安全的REST客户端.

## 安装

```bash
npm install @arbidocs/client
```

对于Node.js环境(没有浏览器),也安装了索引DB多填充:

```bash
npm install fake-indexeddb
```

## 快速启动

```typescript
import { createArbiClient } from '@arbidocs/client'

const arbi = createArbiClient({
  baseUrl: 'https://www.arbidocs.com',
  deploymentDomain: 'www.arbidocs.com',
})

// Login
const session = await arbi.auth.login({
  email: 'user@example.com',
  password: 'mypassword',
})

// Type-safe API calls — auto-injects Bearer token
const { data: workspaces } = await arbi.fetch.GET('/api/user/workspaces')
console.log(workspaces) // WorkspaceResponse[]
```

## 实例

### 注册+登录(节点.js)

```javascript
// Polyfill IndexedDB for Node.js (must be first import)
require('fake-indexeddb/auto')
const { createArbiClient } = require('@arbidocs/client')

async function main() {
  const arbi = createArbiClient({
    baseUrl: 'https://www.arbidocs.com',
    deploymentDomain: 'www.arbidocs.com',
    credentials: 'omit', // No cookies in Node.js
  })

  // Register a new user
  const { signingPrivateKey } = await arbi.auth.register({
    email: 'alice@example.com',
    password: 'SecurePass123!',
    verificationCode: '...', // From /api/user/verify-email flow
    firstName: 'Alice',
    lastName: 'Smith',
  })

  // Login
  const session = await arbi.auth.login({
    email: 'alice@example.com',
    password: 'SecurePass123!',
  })

  console.log('Logged in as', session.userExtId)
  console.log('Token:', session.accessToken.slice(0, 20) + '...')
}

main()
```

### 创建工作空间并上传文档

```javascript
require('fake-indexeddb/auto')
const fs = require('fs')
const {
  createArbiClient,
  getSession,
  sealedBoxDecrypt,
  deriveEncryptionKeypairFromSigning,
  createWorkspaceKeyHeader,
} = require('@arbidocs/client')

async function main() {
  const arbi = createArbiClient({
    baseUrl: 'https://www.arbidocs.com',
    deploymentDomain: 'www.arbidocs.com',
    credentials: 'omit',
  })

  // Login
  const { accessToken, serverSessionKey } = await arbi.auth.login({
    email: 'alice@example.com',
    password: 'SecurePass123!',
  })

  // Create workspace
  const { data: workspace } = await arbi.fetch.POST('/api/workspace/create_protected', {
    body: {
      name: 'My Case Files',
      description: 'Documents for Case #1234',
      is_public: false,
    },
  })

  // Decrypt the workspace key and generate the auth header.
  // The server wraps the workspace symmetric key with your public key
  // during creation. You unwrap it here to prove you own the workspace.
  const session = await getSession()
  const pubKey = session.signingPrivateKey.slice(32, 64)
  const encKP = deriveEncryptionKeypairFromSigning({
    publicKey: pubKey,
    secretKey: session.signingPrivateKey,
  })
  const workspaceKey = sealedBoxDecrypt(workspace.wrapped_key, encKP.secretKey)
  const wsHeader = await createWorkspaceKeyHeader(workspaceKey, serverSessionKey)

  // Tell the SDK which workspace is active (middleware auto-injects the header)
  arbi.session.setSelectedWorkspace(workspace.external_id)
  arbi.session.setCachedWorkspaceHeader(workspace.external_id, wsHeader)

  // Upload a PDF (multipart — use raw fetch since openapi-fetch
  // doesn't handle multipart/form-data)
  const formData = new FormData()
  const pdf = fs.readFileSync('./contract.pdf')
  formData.append('files', new Blob([pdf], { type: 'application/pdf' }), 'contract.pdf')

  const uploadRes = await fetch(
    `https://www.arbidocs.com/api/document/upload?workspace_ext_id=${workspace.external_id}`,
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${accessToken}`,
        'workspace-key': wsHeader,
      },
      body: formData,
    }
  )

  const { doc_ext_ids } = await uploadRes.json()
  console.log('Uploaded document:', doc_ext_ids[0])

  // List documents (workspace-key header injected automatically by middleware)
  const { data: docs } = await arbi.fetch.GET(
    '/api/workspace/{workspace_ext_id}/documents',
    { params: { path: { workspace_ext_id: workspace.external_id } } }
  )

  for (const doc of docs) {
    console.log(`  ${doc.file_name} — ${doc.status}`)
  }
}

main()
```

### 订阅会话状态更改

SDK的车 `SessionManager` 支持被动更新的订阅模式:

```typescript
const arbi = createArbiClient({ baseUrl, deploymentDomain })

// React to session changes (useful for custom UI frameworks)
const unsubscribe = arbi.session.subscribe((state) => {
  console.log('Session changed:', {
    loggedIn: !!state.accessToken,
    email: state.userEmail,
    workspace: state.selectedWorkspaceId,
  })
})

// Later: stop listening
unsubscribe()
```

## API 参考

### `createArbiClient(options)`

创建 SDK 客户端实例 .

```typescript
interface ArbiClientOptions {
  baseUrl: string              // ARBI API URL (e.g. "https://www.arbidocs.com")
  deploymentDomain: string     // Used for deterministic key derivation
  credentials?: RequestCredentials  // Default: 'include'. Use 'omit' for Node.js
  session?: SessionManager           // The host's session state; default: in-memory
  persistence?: SessionPersistence   // Keys between page loads; default: encrypted IndexedDB
  sso?: SsoTokenSource | null        // The SSO provider's token, asked only in SSO mode
  middleware?: Middleware[]          // Host middleware, run before the re-login middleware
  reloginExcludePatterns?: string[]  // Paths whose 401 never re-logs in
  onReloginSuccess?: (data) => void
  onRetryCloneFailed?: () => void
}
```

客户端拥有会话回收: 每一次请求失败, 都会重写一次 401次 (单机,5s冷却),400"无活工作空间"重新打开工作空间,并重新登录 服务器拒绝结束会话( q)`session.clear()`,则 `auth.onSessionExpired` ) (中文(简体) ). A 类 登录仍可完成或无法访问的服务器会让会话单独离开 .

返回 a `ArbiClient` 带有这些命名空间 :

| 命名空间 | 说明 |
| --- | --- |
| `arbi.fetch` | 类型安全 `openapi-fetch` 带有自动自动中间软件的客户端 |
| `arbi.session` | 记忆会话状态( 地址、 用户、 工作空间) |
| `arbi.auth` | 高级认证 : `register`, (中文(简体) ), `login`, (中文(简体) ), `loginWithKey`, (中文(简体) ), `logout`, (中文(简体) ), `changePassword`, (中文(简体) ), `relogin` |
| `arbi.crypto` | 加密工具:密钥衍生、签名、加密、基础64 |
| `arbi.storage` | 索引数据库会话持久性 : `getSession`, (中文(简体) ), `saveSession` |

### 认证方法

```typescript
// Register
await arbi.auth.register({ email, password, verificationCode, firstName?, lastName? })

// Login with password
await arbi.auth.login({ email, password })

// Login with recovery key (Uint8Array)
await arbi.auth.loginWithKey({ email, signingPrivateKey })

// Change password
await arbi.auth.changePassword({ email, currentPassword, newPassword })

// Logout (clears session + IndexedDB)
await arbi.auth.logout()

// Re-login using stored private key (auto-called by middleware on 401)
await arbi.auth.relogin()

// "The session could not be recovered": show the sign-in screen
const off = arbi.auth.onSessionExpired(() => showSignIn())

// Seal every workspace key to this server session (before deriving an MCP session from it)
await arbi.auth.openAllWorkspaces()
```

### 中件( 自动应用)

这个 `arbi.fetch` 客户端自动应用了三个中间软件层:

1.  **熊熊奥特** - 注射剂 `Authorization: Bearer <token>` 在每次请求中
2.  **工作空间密钥** - 注射剂 `workspace-key` 工作空间范围终点页眉
3.  **自动重写** 401年,从所储存的钥匙和回盘中重新提取证书

### 独立出口

所有构件可单独导入供高级使用:

```typescript
import {
  // Crypto primitives
  initSodium, signMessage, sealedBoxDecrypt, sealedBoxEncrypt,
  deriveEncryptionKeypairFromSigning, createWorkspaceKeyHeader,
  generateUserKeypairs, generateLoginCredentials,
  encryptMessage, decryptMessage,
  base64Encode, base64Decode, base64ToBytes, bytesToBase64,

  // Storage
  getSession, saveSession, clearAllData, hasSession,

  // Middleware (compose your own client)
  createBearerAuthMiddleware, createWorkspaceKeyMiddleware, createAutoReloginMiddleware,

  // Relogin handler
  createReloginHandler,

  // Session manager
  createSessionManager,

  // OpenAPI schema types
  type paths, type components, type operations,
} from '@arbidocs/client'
```

### 锁定器

```typescript
import { configureLogger, logger } from '@arbidocs/client'

configureLogger({ verbose: import.meta.env.DEV }) // once, at startup
logger.error('always printed')
logger.warn('printed only when verbose') // likewise info, debug
```

## 如何运作

### 零知识认证

ARBI使用Ed25519签名进行认证. 您的密码从不离开客户端 :

1.  **密钥衍生**数字 : `Argon2id(email + password + deploymentDomain)` \* Ed25519种子\*
2.  **登记**: 发送到服务器的公钥, 私钥留在本地
3.  **登录**:客户端签署时间戳,服务器验证签名
4.  **会议**: 服务器返回用于工作空间操作的加密会话密钥

### 工作空间加密

每个工作区都有一个对称的密钥(NaCl SecretBox). 关键是:

-   创建工作空间时生成的服务器侧
-   与您的 X25519 公用密钥相接( 来源于您的 Ed25519 签名密钥)
-   使用未包装客户端 `sealedBoxDecrypt`
-   用于生成每个请求 `workspace-key` 头(HMAC钥匙持有证明)

### 索引 DB 存储

SDK将签名的私人密钥和会话密钥存储在索引DB中,用从Web Crypto API中无法提取的AES-GCM密钥加密. 在节点.js中,使用 `fake-indexeddb` 作为多填充.

## 所需资源

-   **浏览器**: 任何现代浏览器( Chrome, Firefox, Safari, Edge)
-   **节点.js**: v18+ (需要数) `fetch`, (中文(简体) ), `FormData`, (中文(简体) ), `Blob` (原始内容存档于2017-09-29). Globals. 安装 `fake-indexeddb` 用于索引数据库.
-   **类型脚本**: 5.0+(可选——也与普通联署材料合作)

## 释放

每个版本的放出注释 [GitHub 发布](https://github.com/arbicity/ARBI-frontend/releases)。 。 。 .

## 常见问题

### @arbidocs/client 是什么？

ARBI API 的 TypeScript SDK — 零知识认证、 E2E 加密和类型安全 REST 客户端

### 如何安装 @arbidocs/client？

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

### @arbidocs/client 支持 TypeScript 吗？

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

### @arbidocs/client 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @arbidocs/client 可以商用吗？

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

### @arbidocs/client 的下载量有多少？

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

### @arbidocs/client 还在维护吗？

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

