# @cratestack/refine 中文文档

规范地址：https://npmcn.com/package/%40cratestack/refine/

版本：0\.19\.3
npm 元数据更新时间：2026-11-09T16:13:12.956Z
中文译文更新时间：2026-11-10T23:36:38.440Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：110 kB，43 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=24
- 运行依赖：0 个
- peer 依赖：@refinedev/core ^5\.0\.0
- 首次发布：2026-08-13T03:30:48.542Z
- 最新版本发布：2026-11-09T16:13:12.551Z
- 近 30 天下载量：3691（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：46（近 12 个月 46 个）

## 中文简介

精细.dev Data Provider over CrateStack所生成的TypeScript客户端(REST或RPC)——安全终端用户admin-UI表面,它通过生成的API(政策,验证,@转换货币,审计),与板条板-studio的直通数据库不同

## 安装

```sh
npm install @cratestack/refine
```

也可以使用：`pnpm add @cratestack/refine`、`yarn add @cratestack/refine`、`bun add @cratestack/refine`

## README

# @ cratestack/ refine (英语)

A 类 [精炼.dev](https://refine.dev/) `DataProvider` 超过 CrateStack 生成的 TypeScript 客户端 —— **资源** (单位:千美元)`createCratestackDataProvider`)或(或) **难民保护委员会** (单位:千美元)`createCratestackRpcDataProvider`,用于 `transport rpc` 计划。 电线精炼器修好了 `getList`编号 :`getOne`编号 :`getMany`编号 :`create`编号 :`update`编号 : `deleteOne` 表面到生成的模型类( e)`client.widgets`, (中文(简体) ), `client.ledgers`),绘图 精炼的滤波操作器、相接键、主键和 `@version` 乐观冲突 输入服务器的真实合同——同一合同 [板条板球](https://cratestack.dev/) 故意绕道. `cratestack-studio` 会谈 `[target.db]` 直接跳过 `@@allow`页:1 精炼基于此软件包的应用通过生成的API并继承政策,验证, `@version` 货币和审计。 这就是这个软件包存在的原因(cratestack#571):精炼 是安全的终端用户管理员 工作室是系统管理员.

两家运输公司都分享同样的README,除非有一节另有说明 `getList`编号 :`getOne`编号 :`getMany`编号 :`create`编号 :`update`编号 :`deleteOne`编号 :`createMany`编号 :`updateMany`编号 :`deleteMany`编号 : `custom` 行为、过滤操作器表、发光语义、主键处理和 `@version` 乐观锁定的保证是相同的;只有下面的电线调用不同。 见 [RPC 运输](https://npmcn.com/package/%40cratestack/refine/#readme-rpc-transport) 说明RPC的具体内容,以及 [范围](https://npmcn.com/package/%40cratestack/refine/#readme-scope) 为了什么 供养者有.

## 带有生成运单的运行时包

A 类 `DataProvider` 每个资源需要四个东西——生成的 API 对象本身,模型的 主键字段名称, 是否声明 `@@paged`,以及是否/其中声明 `@version`。 。 。 . 没有人有 _运行时间_ 发现路径: 生成的客户端没有 `$meta` 对象和否 透视结束点, 仅限其类型脚本 **类型** 在编译时已编码 (确认为真实生成) `client.ts`编号 :`models.ts` 这个软件包自己的测试驱动器——见 [测试/](https://npmcn.com/package/%40cratestack/refine/tests)) (中文(简体) ). 因此,提供者本身必须是手写运行时函数 它的逻辑中没有任何图谋可以产生.

这个 **显示** 这是另一个问题, 板条板#571 解决它的另一方式: 事实都存在 `.cstack` 计划,所以发电机释放出来。 过 `--refine` 改为 `cratestack generate-typescript` 它会写一个额外的 `src/refine.ts` 在客户端旁边:

```bash
cratestack generate-typescript \
  --schema schema.cstack \
  --out ./generated \
  --refine
```

```ts
// generated/src/refine.ts — generated, do not edit
export function cratestackRefineResources(client: ExampleApiClientClient): ResourceMap { … }
```

手写显示的仍然被完全支持(它是一个普通的物体字面,每个 下面的例子显示一个),但生成的模型不能漂移:一个获得收益的模型 `@version`,或一个 谁 `@id` 未调用 `id`时,更新其下个 `generate-typescript` 运行代替 在运行时悄悄失败.

`--refine` 工作为 **两者** REST和RPC计划。 释放的函数也是一样的形状 办法.. `cratestackRefineResources(client)` — 已输入 `ResourceMap` 技术开发和转让 `RpcResourceMap` 页:1 RPC,因此整个运输过程中的消费代码是相同的. 也可以自由编曲 `--swr` (文件/模型+钩子布局, `<package-name>/swr`曰:表相会相会 总是允许默认布局的客户类 不论那面旗帜。 见 [范围](https://npmcn.com/package/%40cratestack/refine/#readme-scope)。 。 。 .

## 用法(REST)

与所生成的表:

```ts
import { createCratestackDataProvider } from "@cratestack/refine";
import { ExampleApiClientClient } from "./generated/src/client.js";
import { cratestackRefineResources } from "./generated/src/refine.js";

const client = new ExampleApiClientClient("https://api.example.com", { basePath: "/api" });
const dataProvider = createCratestackDataProvider(cratestackRefineResources(client));
```

或写出显示自己——相同的形状,以及生成的文件包含的内容:

```ts
const dataProvider = createCratestackDataProvider({
  widgets: { api: client.widgets, primaryKey: "id", paged: false },
  ledgers: { api: client.ledgers, primaryKey: "id", paged: true, versionField: "version" },
  products: { api: client.products, primaryKey: "sku", paged: false },
});
```

把这个直接递给精炼师 `<Refine dataProvider={dataProvider} .../>`。 。 。 .

## RPC 运输

对a `transport rpc` 计划, 使用 `createCratestackRpcDataProvider` 还有一个 `RpcResourceMap` 换成 - 每项资源有相同的四个事实(`api`, (中文(简体) ), `primaryKey`, (中文(简体) ), `paged`选项 `versionField`),同样 `getList`编号 :`getOne`/... / 说`custom` 行为,相同的过滤操作表和 `@version` 保证为 师曰. `--refine` 生成 RPC 方案表, 键入 `RpcResourceMap` (见上文); 手写的,看起来是这样的:

```ts
import { createCratestackRpcDataProvider } from "@cratestack/refine";
import { ExampleApiClientClient } from "./generated/src/client.js";

const client = new ExampleApiClientClient("https://api.example.com", { basePath: "/api" });
const dataProvider = createCratestackRpcDataProvider({
  widgets: { api: client.widgets, primaryKey: "id", paged: false },
  ledgers: { api: client.ledgers, primaryKey: "id", paged: true, versionField: "version" },
  products: { api: client.products, primaryKey: "sku", paged: false },
});
```

和REST有什么不同,机械上:

-   生成的 RPC 模型类 `list` 以查询定位 (单位:千美元)`list(query, options)`)而不是在选项中嵌入,对象为REST的方式 `list({ query, headers, signal })` 是否为 -- `createCratestackRpcDataProvider` 构建一个 `RpcListQuery` (RPC键入) 列表输入形状)而不是 REST 的 `CratestackFetchQuery`。 。 。 . `get`编号 :`create`编号 :`update`编号 :`delete` 为: 两种运输方式的位置相同;只有它们的选项类型不同 (单位:千美元)`CratestackRpcCallOptions` 对 `CratestackRequestConfig`) (中文(简体) ).
-   过滤器编译到 `RpcListPredicate[]` (单位:千美元)`{ key, value }` (对)而不是REST的 `Record<string,string>` - 一样 `field[__operator]` 关键公约(见 [过滤器](https://npmcn.com/package/%40cratestack/refine/#readme-filters) 下方,钢丝上有一个不同的容器形状.
-   将编译到单个逗号连接字符串( S)`"-createdAt,id"`) 而不是REST的(英语: `string[]` 运行时间加入客户端- 相同 `field`编号 :`-field` DSL. (英语).
-   **每一个空闲的电话都带着 `If-Match` 和REST一样.** 皇家警察派来武器 (单位:千美元)`crates/cratestack-macros/src/transport/rpc.rs`通过真正的HTTP `HeaderMap` 直接穿过 改为: `handle_update_*_dispatch`编号 :`handle_delete_*_dispatch` fns REST 用途 (单位:千美元)`crates/cratestack-macros/src/axum/model/handlers_update.rs`)改为: `If-Match` 通过 `parse_if_match_version` 所以,一个 stale 或缺少 `If-Match` 反对: `@version` 模式返回 不变 `412 Precondition Failed` 根据实际生成的 RPC 客户端在 此软件包自己的测试套件( name of translators)`tests/rpc-optimistic-locking.test.ts`) (中文(简体) ).
-   **`createCratestackRpcDataProvider` 从不打电话 `POST /rpc/batch`。 。 。 .** 批量请求是 HTTP 请求中包含 N 帧,所以每个帧 `If-Match` 信头是无法表达的.. `createMany`编号 :`updateMany`编号 :`deleteMany` n 是真实的无线往返, 而非原子 可再生能源技术战略用途(见 [创建 Many / 更新 Many / 删除 Many](https://npmcn.com/package/%40cratestack/refine/#readme-createmany--updatemany--deletemany) 页:1 一个分批的RPC数据提供者原则上是可能的,但在此范围之外——见 [范围](https://npmcn.com/package/%40cratestack/refine/#readme-scope)。 。 。 .

## 过滤器

适用于两个供应商。 精细 `CrudFilters` (单位:千美元)`{ field, operator, value }`) 映射到同一地点 `field[__operator]` 关于这两种运输的关键公约——REST公约 `field__operator=value` 查询段落 (单位:千美元)`toQueryFilters`) 和RPC(RPC)的 `RpcListPredicate[]` (单位:千美元)`toRpcQueryFilters`载有相同的 `key`, (中文(简体) ), 铁丝网上不同的容器形状 相同的运算符设置生成的客户端共享 过滤器类型( e)`EqualityFilter`编号 :`ComparableFilter`编号 :`StringFilter`揭露:

| 精细操作器 | 板条链查询密钥 |
| --- | --- |
| `eq` | `field` (无后缀) |
| `ne` | `field__ne` |
| `in` | `field__in` (合并分离) |
| `lt` 编号 : `lte` 编号 : `gt` 编号 : `gte` | `field__lt` 编号 : `__lte` 编号 : `__gt` 编号 : `__gte` |
| `contains` | `field__contains` |
| `startswith` | `field__startsWith` |
| `null` | `field__isNull=true` |
| `nnull` | `field__isNull=false` |

**其它精细操作员扔出** —— 说 `endswith`, (中文(简体) ), `between`, (中文(简体) ), `nin`, (中文(简体) ), `containss`精细 `or`编号 :`and` 过滤组, 以及上表中没有的任何东西 。 丢弃不支持的过滤器 默默地显示错误的数据,好像它已被过滤过一样;一个错误绝对更好. 说明 并且 `eq`编号 :`ne`编号 :`in`/ 比较运算符只针对 **所需经费** (不可撤销)字段 那是服务器侧的密码门 (单位:千美元)`crates/cratestack-macros/src/axum/filter_arms.rs::generate_query_filter_arm`不是这个 软件包可以左右工作.

## 倾斜

适用于两个供应商。 精细 `{ current, pageSize }` 地图到 `limit`编号 :`offset` 直接说. **`totalCount` 只有永远 为a 排放 `@@paged` 模型列表路线.** 设定 `paged: false` 在资源配置 诚实地 - a 不包括:`@@paged` 资源 `getList` 仍然返回真实数据,但 `total` 降解为 "多少行此一回回回",而不是真实的计数. 增加一个 `@@paged` 页:1 模型,或配置精细 `pagination: { mode: "off" }` 资源,并将结果作为 1 (封面)页.

## 主密钥

适用于两个供应商。 精细的假设每个记录 `id: BaseKey`. . . . . . . `@id` 可以在任意领域 (单位:千美元)`primaryKey` ,在上方的资源配置中)。 每一个回回的唱片都得到合成 `id` 字段 加上它真正的主键 所以精炼的行选机械 有一些关键; 写( a)`get`编号 :`update`编号 :`deleteOne`) 得到同样的值返回并直接传递至 真正的主要关键——不需要翻译,因为 _值空间_ 完全一样。 一个地方 这个咬: a `<Create>` 窗体的字段必须使用 schema 真正的主键字段名(例如). `sku`(没有) `id` ——创出的有效载荷尚未有合成记录 `id` 从.

## 优化锁定( O)`@version` 编号 : `If-Match`(中文(简体) )

**这个包件中唯一最重要的正确性点,它坚持两种运输.** A 类 `@version` 模式要求 `If-Match` 两次更新 _财务报告和审定财务报表_ 删除(cratestack#493/#519#538)- 缺少或陈旧 `If-Match` 返回时 `412 Precondition Failed` 使行无碍 请求作为RPC的无名电话或REST发出 `PATCH`编号 :`DELETE` (见 [RPC 运输](https://npmcn.com/package/%40cratestack/refine/#readme-rpc-transport) 为什么RPC的发送路径执行这个和REST相同). 精细 `update`编号 :`deleteOne` 钩子在编辑前获取记录,所以该版本由 ;每个提供者记得它(按 `createCratestackDataProvider`编号 : `createCratestackRpcDataProvider` 调用,而不是模块-全局),来自每个返回 a 的读取/写入 新的记录,并自动发送。 A 类 `412` 表面为 可区分的冲突(`statusCode: 412`而不是普通的 失败——检查 `error.statusCode === 412` 在一个 `onError` 处理器显示“其他人改变了” 而不是一般的.

过 `meta: { ifMatch: <version> }` 改为 `update`编号 :`deleteOne` 以明确覆盖缓存(例如). (原始内容存档于2017-10-21) (中文(中国大陆) ). Orious-lock-aware problem works. 通话 `update`编号 :`deleteOne` 编号 `@version` 资源无 已知的版本, 没有覆盖 扔出而不是默默省略 `If-Match` - 省略它不会 在电线上失败了 _暂停_ 值确实如此,所以这个软件包拒绝为您犯错误.

## 错误

**每一种方法都以同样的方式转换,而转换永远不会破坏被抛出的东西.** 全体人员 `getList`, (中文(简体) ), `getMany`, (中文(简体) ), `getOne`, (中文(简体) ), `create`, (中文(简体) ), `update`, (中文(简体) ), `deleteOne` 财务报告和审定财务报表 `custom` 路由一个抛出值 结束 `toRefineError` (出口,所以你可以再利用)——没有任何方法可以将生和 没有方法,其误差可以改进 `statusCode` (cratestack #786; 在此之前修复两者) 列表方法与四种单一记录方法不一致,您击出哪种方法取决于 屏幕上显示用户。).

改划 **注释已丢入的值** 而不是替换它。 如果你的运输 扔出已打出的错误, 值为 `onError` 处理器接收 _实值_ 该错误 :

```ts
class DeviceNotEnrolledError extends Error {}

// works identically on list screens and on detail/create/edit screens
if (error instanceof DeviceNotEnrolledError) { … }
```

`message` 财务报告和审定财务报表 `statusCode` 这才是精炼的 `CratestackHttpError` 拿信封来 `payload.message` 晋升,a `412` 得到乐观锁定的消息 上,同时 `status`编号 :`payload`编号 :`response` 在同一对象上保留可读性。 当抛出值 无法附加注释(抛出原始对象、被冻结的对象),您得到 `{ message, statusCode, cause }` 原文列在下 `cause`。 。 。 .

不通过字符串匹配来分类错误 `message` ——这是允许进行的一个字段转换 重写.

## `createMany` 编号 : `updateMany` 编号 : `deleteMany`

已在两个供应商中执行,没有减少,但因N次连续单次记录往返旅行 (单位:千美元)`Promise.all` 结束 `create`编号 :`update`编号 :`deleteOne`),不是真正的批发. 生成的 REST 客户端 显示没有 `updateMany`编号 :`deleteMany` 围绕服务器的实际包装 `update_many`编号 : `delete_many`. RPC运输确实有一个真正的批量终点(`POST /rpc/batch`不过 `createCratestackRpcDataProvider` 故意不在这里使用,看 [RPC 运输](https://npmcn.com/package/%40cratestack/refine/#readme-rpc-transport) 原因(每框架 `If-Match` 在批量请求中无法表示). 所以这三种方法在两种运输上都有作用,但是没有解剖性,而且代价是N请求 而不是一个.

## 程序(`custom`(中文(简体) )

一个箱子 `procedure` 没有其他家在一个 `DataProvider`通过 a `procedures` 地图到 `createCratestackDataProvider`'(或 `createCratestackRpcDataProvider`'s) 第二个参数和调用 它通过精炼 `custom` - 两个供应商的形状相同:

```ts
const dataProvider = createCratestackDataProvider(resources, {
  procedures: { publishPost: (args) => client.procedures.publishPost(args as never) },
});

await dataProvider.custom!({
  url: "",
  method: "post",
  meta: { procedure: "publishPost" },
  payload: { args: { postId: 1 } },
});
```

## 范围

**超越范围**

-   **`liveProvider`** ——生成的TypeScript客户端今天没有SSE消费者(没有) `EventSource` 在任何地方 `crates/cratestack-client-typescript/templates/`),尽管服务器有真实的 订阅端点 。 首先需要一个TS SSE客户端. 适用于两种运输方式.
-   **`authProvider`** ——与数据访问分开的正统关切. 适用于两种运输方式.
-   **剪接 RPC 写道** —— 说 `createCratestackRpcDataProvider` 从不打电话 `POST /rpc/batch`连 尽管RPC的运输有一个。 每个框架 `If-Match` 信头不能用一个字来表示 批量请求,以及此软件包 `@version` 保证不是它会默默地削弱的东西 获得原子学——见 [RPC 运输](https://npmcn.com/package/%40cratestack/refine/#readme-rpc-transport)。 。 。 .
-   **皇家警察局 `where`编号 :`or` 过滤表达式 DSL,以及 `fields`编号 :`include`编号 :`includeFields` 预测** —— 说 `CratestackRpcListQuery` 铁丝网上所有这些都支持 但精细的 `CrudFilters`编号 :`Sort` 形状上没有映射到它们( refine 没有“ raw 服务器过滤器表达式” 或 "关系投影"概念,因此这个提供者从不给他们写信. 来电者可以 想要达到过去精炼的抽象:呼叫 `config.api.list({ where: "..." })` 直接说.

**本套件继承了已知的、先前存在的缺口,而不是原因:** 线路压制 (cratestack#514)没有执行,所以政策被否定 `create`编号 :`update`编号 :`delete` 仍然生成一个 面向工作的客户方法—— `config.api.create` 仅证明模式声明 _有点_ `@@allow("create", ...)`,不是说现在的打电话者满足了它。 精细 `<Create>` 按钮连接到此资源 `403`{\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}在为一个无法做到的打电话者提交申请 创建一个。 直到514号船,在精炼的门 `resources` 配置 (单位:千美元)`create: false`编号 :`edit: false`编号 :`delete: false`)每个呼叫者角色,不在本包的方法上 存在.

见 `guides/refine-integration.md` 内 [盒装文件](https://github.com/cratestack/cratestack-docs) 手电线版本 包括上面每个设计选择背后的全部推理.

## 常见问题

### @cratestack/refine 是什么？

精细\.dev Data Provider over CrateStack所生成的TypeScript客户端\(REST或RPC\)——安全终端用户admin-UI表面,它通过生成的API\(政策,验证,@转换货币,审计\),与板条板-studio的直通数据库不同

### 如何安装 @cratestack/refine？

在项目目录运行 npm install @cratestack/refine，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@refinedev/core（^5\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @cratestack/refine 支持 TypeScript 吗？

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

### @cratestack/refine 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @cratestack/refine 需要什么版本的 Node\.js？

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

### @cratestack/refine 可以商用吗？

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

### @cratestack/refine 的下载量有多少？

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

### @cratestack/refine 还在维护吗？

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

