# @btravstack/contract 中文文档

规范地址：https://npmcn.com/package/%40btravstack/contract/

版本：0\.58\.0
npm 元数据更新时间：2026-11-07T21:12:01.355Z
中文译文更新时间：2026-11-08T17:40:25.459Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：75.2 kB，17 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：0 个
- peer 依赖：zod ^4\.3\.0，@orpc/contract ^2\.0\.0-beta\.28
- 首次发布：2026-08-25T16:16:25.392Z
- 最新版本发布：2026-11-07T21:12:00.703Z
- 近 30 天下载量：9699（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：62（近 12 个月 62 个）

## 中文简介

合同等级: 标记和规范化的形状 客户端和执行它的服务器都需要—— 认证的 () 标记, 以及带有其图案的光标页

## 安装

```sh
npm install @btravstack/contract
```

也可以使用：`pnpm add @btravstack/contract`、`yarn add @btravstack/contract`、`bun add @btravstack/contract`

## README

# @btravstack/ 合同

> 合同层次: 客户端和服务器同时执行 需要,没有交通工具。 声明 **哪些安全计划** a. 程序 接受 和每个范围必须给予什么, 没有关于谁的呼叫者 是;并描述 **名单的一页** 一次,像一个端口所说的类型 和计划 合同出版。 根没有依赖性——a 客户端可以在没有服务器的情况下接受合同,任何运输合同 可使用同一标记.

📖 **[文档](https://btravstack.github.io/btravstack/reference/contract)** • 妇女 [API 参考](https://btravstack.github.io/btravstack/api/contract/)

```sh
pnpm add @btravstack/contract
```

没有安装在旁边, 除非你使用页面 **计划** 下级 `@btravstack/contract/zod`,其 `zod` 是一个可选的对等点。 可选 `@btravstack/contract/orpc` 需要输入 `@orpc/contract`页:1 `contractInputSchema` 财务报告和审定财务报表 `contractOutputSchema` 检索程序 最初的Zod计划 和他们的具体类型. **一个包裹 一艘标有标记的合同将这艘作为 `peerDependency`** 而不是一个 普通的——标记基于身份,所以每个应用程序有一个副本是 点; 见 [为什么是同行](https://npmcn.com/package/%40btravstack/contract/#readme-the-marker-is-a-weakmap-not-a-property) 见下文. 节点 `>=22`。 。 。 .

## 使用量

```ts
import { authenticated } from "@btravstack/contract";

export const contract = {
  orders: authenticated({ user: [] })({
    place,
    find,
    // Overrides the group default for itself: a `user` token needs the scope,
    // or a `service` token needs nothing.
    export: authenticated(
      { user: ["orders:export"] },
      { service: [] },
    )(oc.output(z.object({ csv: z.string() }))),
  }),
  customers: { find },
};
```

`authenticated` 实值 **剪辑**: 它需要一个或多个 OpenAPI 安全 要求——按照它必须给予的范围绘制的计划名称——和手 返回标记节点的函数。 有几个要求是: **命令**,尝试 以给出的顺序。 标记记录是对下面每个程序的默认 它; 标记程序 **替换** 自我默认。 最接近的标记 胜出,这是OpenAPI自己的规则. 在构建链完成后应用它, 从不在里面.

**合约上写着哪些计划保护一条路线 `defineHttp({ authenticators })` 说出每个人的意志.** 无身份 类型在此命名, 所以服务器对呼叫器本身的视图没有到达 一个客户,丰富它 永远不会改变合同.

### 标记是弱地图,不是地产

标记是 **基于身份** a 包括: `WeakMap`,该节点上没有财产——该节点 为什么一个包裹的运输 标有标记的合同 把这个作为一个 **端点** 依赖性而不是普通的:两份将意味着两份登记处, 一份没有标记的契约是受保护的路线 服务开放。 登记簿是防止复制的 (它挂断) `globalThis` 下级 `Symbol.for("@btravstack/contract/requirements")`因此,每个 复制共享 1 `WeakMap`),因此,一个偏差的第二份副本需要一个编译错误 不匹配的标记符号, 不是打开的路由 .

`isAuthenticated(node)` 读回 `Requirements` 一个节点的标志是, 或者说 `undefined` 当没有人标出它.

## 输入列表

一页,一页描述:一个端口说话的类型和合同的计划 出版是相同的形状, 测试针是它们无法分开的.

```ts
import { pageOf, pageRequestOf } from "@btravstack/contract/zod";

export const orders = oc.router({
  list: oc
    .input(pageRequestOf({ minQuantity: z.number().int().min(1).optional() }))
    .output(pageOf(orderView)),
});
```

旗帜和光标是一个事实. `hasNextPage: true` 携带 `nextCursor` 继续列名 `hasNextPage: false` 没有这样的 田地——所以"还有更多,没有什么可跟随它",是无法形容的, 和检查旗子的客户端持有光标,且不能将光标放大. `after` 财务报告和审定财务报表 `before` 属于该类的结合,但被该类人拒绝为一对 schema:一个页面向一个方向运行.

适配器页面列表 `keyset(request)`对象 持有两半键集页面—— `take` (页外加一行) 这证明下一个, `backward`, (中文(简体) ), `cursor`,则a `page` 折叠什么 商店回答:

```ts
import { keyset } from "@btravstack/contract";

const keys = keyset(request);
const listed = keys.page(store.seek(keys), (row) => String(row.id));
```

过度牵引和修饰 通过建筑,这是整个原因 它们是一个物体. `keyset` 不运行查询——这是一件事 此级不能表示——当商店报告两个光标本身时, `page(items, { previous, next })` 直接带走 控制器转动 对端口的有效输入 `PageRequest` 与 `pageRequest(input)`。 。 。 .

### 排序列表

列表会声明它自己的可分类词汇表, 对照它的项目检查 已经发布,并且需要默认,即隐含的默认是 列表由无人选择的东西排序 :

```ts
import { sortableBy } from "@btravstack/contract/zod";

export const sortedOrders = oc.router({
  list: oc
    .input(
      pageRequestOf(
        { minQuantity: z.number().int().min(1).optional() },
        {
          sortableBy: sortableBy(orderView, ["quantity"]),
          defaultSort: { field: "quantity", direction: "desc" },
        },
      ),
    )
    .output(pageOf(orderView)),
});
```

光标带有该类 **逐字记录,不是散发** —— 说 `field:direction`, (中文(简体) ), 现场 `encodeURIComponent`d, 就像排序值和结节 旁边——因为词汇表已经在发布的 OpenAPI 中公开了 文档。 光标是 只对以下类型有效:, `keyset(request)` 答题 `SortedKeyset<F> | CursorRefused`,适配器必须分支 而不是一个未过滤的页 从错误的一面:

```ts
import { keyset } from "@btravstack/contract";

const sortedKeys = keyset(sortedRequest);
const sortedListed = sortedKeys.resumable
  ? sortedKeys.page(sortedRows, (row) => [String(row.quantity), String(row.id)])
  : sortedKeys.reason; // "malformed" or "sort-mismatch"
```

`SortedKeyset<F>.page`是因为 `cursorOf` 返回时 **两者** 排序搜索的值 所以被遗忘的断了就是 编译出错,而不是静默地跳过绑定行的密钥集.

## 许可证

[麻省理工学院](https://npmcn.com/package/%40btravstack/contract/LICENSE) 贝诺伊特旅行社

## 常见问题

### @btravstack/contract 是什么？

合同等级: 标记和规范化的形状 客户端和执行它的服务器都需要—— 认证的 \(\) 标记, 以及带有其图案的光标页

### 如何安装 @btravstack/contract？

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

### @btravstack/contract 支持 TypeScript 吗？

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

### @btravstack/contract 支持 ESM 还是 CommonJS？

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

### @btravstack/contract 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @btravstack/contract 可以商用吗？

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

### @btravstack/contract 的下载量有多少？

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

### @btravstack/contract 还在维护吗？

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

