@cratestack/refine

中文文档
0.19.3发布于 2026/11/10MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 3691

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

中文使用文档
文档目录11 节
  1. 带有生成运单的运行时包
  2. 用法(REST)
  3. RPC 运输
  4. 过滤器
  5. 倾斜
  6. 主密钥
  7. 优化锁定( O) @version 编号 : If-Match (中文(简体) )
  8. 错误
  9. createMany 编号 : updateMany 编号 : deleteMany
  10. 程序( custom (中文(简体) )
  11. 范围

@ cratestack/ refine (英语)

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

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

带有生成运单的运行时包

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

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

cratestack generate-typescript \
  --schema schema.cstack \
  --out ./generated \
  --refine
// 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曰:表相会相会 总是允许默认布局的客户类 不论那面旗帜。 见 范围。 。 。 .

用法(REST)

与所生成的表:

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));

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

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 (见上文); 手写的,看起来是这样的:

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] 关键公约(见 过滤器 下方,钢丝上有一个不同的容器形状.
  • 将编译到单个逗号连接字符串( 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 页:1 一个分批的RPC数据提供者原则上是可能的,但在此范围之外——见 范围。 。 。 .

过滤器

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

精细操作器板条链查询密钥
eqfield (无后缀)
nefield__ne
infield__in (合并分离)
lt 编号 : lte 编号 : gt 编号 : gtefield__lt 编号 : __lte 编号 : __gt 编号 : __gte
containsfield__contains
startswithfield__startsWith
nullfield__isNull=true
nnullfield__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 运输 为什么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 处理器接收 实值 该错误 :

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 运输 原因(每框架 If-Match 在批量请求中无法表示). 所以这三种方法在两种运输上都有作用,但是没有解剖性,而且代价是N请求 而不是一个.

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

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

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 运输。 。 。 .
  • 皇家警察局 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 内 盒装文件 手电线版本 包括上面每个设计选择背后的全部推理.

版本与发布记录

@cratestack/refine 共发布 46 个版本,首次发布于 2026/08/13;过去 12 个月发布了 46 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.19.3latest2026/11/101 天前
0.19.22026/11/091 天前
0.19.12026/11/092 天前
0.19.02026/11/092 天前
0.18.12026/11/073 天前
0.18.02026/11/074 天前

关于 @cratestack/refine 的常见问题

@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 和提交记录判断。