# @casl/prisma 中文文档

规范地址：https://npmcn.com/package/%40casl/prisma/

版本：2\.2\.0
npm 元数据更新时间：2026-10-28T15:05:48.566Z
中文译文更新时间：2026-11-09T04:04:43.988Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：89.8 kB，21 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- peer 依赖：@casl/ability ^7\.0\.0，@prisma/client ^4\.16\.0 \|\| ^5\.0\.0 \|\| ^6\.0\.0 \|\| ^7\.0\.0
- 首次发布：2021-05-10T14:53:45.519Z
- 最新版本发布：2026-10-28T15:05:47.708Z
- 近 30 天下载量：812299（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：30（近 12 个月 9 个）

## 中文简介

允许根据 CASL 规则使用 Prisma 客户端查询可访问的记录

## 安装

```sh
npm install @casl/prisma
```

也可以使用：`pnpm add @casl/prisma`、`yarn add @casl/prisma`、`bun add @casl/prisma`

## README

# 卡塞尔·普里斯马

[![@casl/prisma NPM version](https://badge.fury.io/js/%40casl%2Fprisma.svg)](https://badge.fury.io/js/%40casl%2Fprisma) [![](https://img.shields.io/npm/dm/%40casl%2Fprisma.svg)](https://www.npmjs.com/package/%40casl%2Fprisma) [![Support](https://img.shields.io/badge/Support-github%20discussions-green?style=flat&link=https://github.com/stalniy/casl/discussions)](https://github.com/stalniy/casl/discussions)

此软件包允许定义 [卡塞尔](https://github.com/stalniy/casl) 权限在 [普里斯马](https://prisma.io/) 使用 Prisma 的模型 `WhereInput`. 这在SQL世界的许可管理方面带来了很大的力量:

1.  我们可以使用 Prisma 查询来定义权限, 无需再学习 MongoDB 查询语言 .
2.  此外,我们可以问我们的SQL数据库的问题,例如:"哪些记录可以读取"或者"哪些记录可以更新".

## 安装

```sh
npm install @casl/prisma @casl/ability
# or
yarn add @casl/prisma @casl/ability
# or
pnpm add @casl/prisma @casl/ability
```

`@casl/prisma` 需要 Prisma 客户端 4.1.6.0 或稍后。 Prisma 客户端扩展为 `createCaslExtension` 需要添加到 Prisma 客户端的帮助 !

## 使用量

这个软件包与其它软件包有些不同,因为它提供了一个自定义 `createPrismaAbility` 配置用于使用 Prisma 检查权限的工厂函数 [输入位置](https://www.prisma.io/docs/orm/reference/prisma-client-reference#where)数字 :

```ts
import { User, Post, Prisma } from '@prisma/client';
import { Ability, AbilityBuilder, subject, type ForcedSubject, type TaggedSubject } from '@casl/ability';
import { createPrismaAbility, PrismaQuery } from '@casl/prisma';

type AppSubjects =
  | User & ForcedSubject<'User'>
  | Post & ForcedSubject<'Post'>
type AppAbility = Ability<[string, AppSubjects], PrismaQuery, TaggedSubject>;
const { can, cannot, build } = new AbilityBuilder<AppAbility>(createPrismaAbility);

can('read', 'Post', { authorId: 1 });
cannot('read', 'Post', { title: { startsWith: '[WIP]:' } });

const ability = build();
ability.can('read', 'Post');
ability.can('read', subject('Post', { title: '...', authorId: 1 })));
```

> 见 [CASL 指南](https://casl.js.org/v7/en/guide/intro) 学习如何定义能力。 除条件语言外,一切都是一样的.

> 如果您使用 Prisma 7 生成 Prisma 客户端 `prisma-client` 生成器, 从您生成的客户端路径导入模型类型( 例如 ) `./prisma/generated/client`并创建一个小包装 `@casl/prisma/runtime` 如下所示.

### 关于主题助手的说明

`ForcedSubject<'Post'>` 在对象上声明标记 。 当主题结合只包含标记对象类型时,必须指定 `TaggedSubject` 作为第三个通用参数: `Ability` 或者说 `PrismaAbility` 还接受主题名称,例如: `'Post'` 在许可检查中:

```ts
type AppAbility = Ability<[string, AppSubjects], PrismaQuery, TaggedSubject>;
```

`TaggedSubject` 用途 `__caslSubjectType__` 在默认情况下,匹配 `subject` 帮手 如果你忽略了第三个通用参数, `DefaultSubject` 保留已存在的行为: 明确包含名称和标记对象类型, 例如 `Ability<[string, 'User' | 'Post' | AppSubjects], PrismaQuery>`。 。 。 .

因为Prisma在不披露任何类型信息的情况下返回了DTO对象,所以我们需要使用 `subject` 帮助手动提供该类型,因此CASL可以理解哪些规则适用于对象所传.

不幸的是,除了在所有模型中增加一栏之外,没有实现自动化的简单方法。 详情请检查 [这个问题](https://github.com/prisma/prisma/issues/5315)。 。 。 .

> 要了解更多关于对象类型的检测细节, 请读 [CASL 主题类型检测](https://casl.js.org/v7/en/guide/subject-type-detection)

### 关于 Prisma 查询运行时解释器的说明

`@casl/prisma` 用途 [播音员](https://github.com/stalniy/ucast) 解释 Prisma [输入位置](https://www.prisma.io/docs/orm/reference/prisma-client-reference#where) 在 JavaScript 运行时。 然而,没有多少说明:

-   未实现 JSON 列的平等
-   未实现数组/列表列的等同性(尽管操作符喜欢) `has`, (中文(简体) ), `hasSome` 财务报告和审定财务报表 `hasEvery` 足够多了)
-   在确定关系条件时,总是指定一个操作员(`every`, (中文(简体) ), `none`, (中文(简体) ), `some`, (中文(简体) ), `is` 或者说 `isNot`(中文(简体) )

口译员投出a `ParsingQueryError` 如果它接收到查询操作器的无效参数,或者如果某些操作没有被支持.

## Prisma 7 配置

Prisma 7 将连接细节移动到 `prisma.config.ts` 不再装入 `.env` 文件自动。 在您的方案上添加配置 `prisma generate` 继续工作 :

```ts
// prisma.config.ts
import 'dotenv/config';
import { defineConfig } from 'prisma/config';

export default defineConfig({
  schema: './schema.prisma',
  datasource: {
    // fall back to a local URL so generate does not fail in CI
    url: process.env.DATABASE_URL ?? 'postgresql://postgres:postgres@localhost:5432/postgres',
  },
});
```

如果你坚持遗产 `prisma-client-js` 生成器, 默认 `@prisma/client` 导入继续工作.

## 查找可访问的记录

一个不错的特征 [普里斯马](https://prisma.io/) 财务报告和审定财务报表 [卡塞尔](https://github.com/stalniy/casl) 整合就是我们能够从数据库中获取所有记录,我们的用户可以访问. 要做到这一点,只是使用 `accessibleBy` 帮助函数 :

```ts
// ability is a PrismaAbility instance created in the example above

const accessiblePosts = await prisma.post.findMany({
  where: accessibleBy(ability).ofType('Post')
});
```

该函数接受 `Ability` 实例和实例 `action` (违约) `read`),返回实例 `AccessibleRecords` 带有 `ofType` 用于接受 Prisma 模型名称并返回从权限规则汇总的对象的方法 `WhereInput`。 。 。 .

**重要**:如果用户无法访问任何帖子, `.ofType` 返回一个特殊的空条件。 如果您直接传递给 Prisma 客户端, 无需 `createCaslExtension`,Prisma 拒绝查询,因为该条件包含一个内部标记字段. 这使得被拒绝的访问被关闭.

把这个与商业逻辑条件结合起来,只需要使用 `AND`数字 :

```ts
const accessiblePosts = await prisma.post.findMany({
  where: {
    AND: [
      accessibleBy(ability).ofType('Post'),
      { /* business related conditions */ }
    ]
  }
})
```

为当前Prisma扩展执行,设置 `accessibleBy(...)` 在复合条件下,例如 `AND: [...]` 允许更快地对空条件检测到短路.

### Prisma 客户端扩展名

`createCaslExtension` 地址 [这个问题](https://github.com/stalniy/casl/issues/794) 通过让Prisma客户端将 CASL 的空条件作为空查询结果处理,而不是丢弃被禁错误.

**重要内容:** 请确保将此扩展添加到您用于 CASL 保护查询的 Prisma 客户端实例中。 否则,某些CASL限制可能应用不当.

添加为其它常规扩展 :

```ts
import { PrismaClient } from '@prisma/client';
import { createCaslExtension } from '@casl/prisma';

const prisma = new PrismaClient().$extends(createCaslExtension());
```

有了这个扩展,带有空 CASL 条件的操作返回同样类型的"无记录"结果 Prisma 用户通常期望:

```ts
const posts = await prisma.post.findMany({
  where: accessibleBy(ability).ofType('Post')
});
// posts === []
```

需要匹配记录的单一记录操作,例如 `findFirstOrThrow`, (中文(简体) ), `findUniqueOrThrow`, (中文(简体) ), `update`,以及 `delete`,将会以“没有找到...”错误的记录来拒绝.

## 类型脚本支持

软件包是用TypeScript编写的,它提供了全面的IDE提示并编译了时间验证.

> 一定要打电话 `prisma generate`。 。 。 . `@casl/prisma` 使用 Prisma 生成的类型, 因此如果客户端没有生成, 将没有任何效果 .

此外,还有几个帮助者使与Prisma和CASL合作变得容易:

### Prisma 查询

它是一种通用类型,提供 `Prisma.ModelWhereInput` 以一般方式。 我们需要通过 一个命名的模型:

```ts
import type { User } from '@prisma/client';
import type { ForcedSubject } from '@casl/ability';
import type { PrismaQuery } from '@casl/prisma';

// almost the same as Prisma.UserWhereInput except that it's a higher order type
type UserWhereInput = PrismaQuery<User & ForcedSubject<'User'>>;
```

## 自定义 Prisma 客户端输出路径( Prisma 7 默认)

普丽斯玛7's `prisma-client` 生成器将客户端写入自定义目录, 所以 `@prisma/client` 不再再出口您的项目类型。 将 CASL 点在生成的客户端上, 并使用一个建在上的小包装 `@casl/prisma/runtime`数字 :

```prisma
// schema.prisma
generator client {
  provider = "prisma-client"
  output   = "../src/generated/client"
}
```

```ts
// prisma.config.ts
import { defineConfig } from 'prisma/config';

export default defineConfig({
  schema: './schema.prisma',
  datasource: { url: process.env.DATABASE_URL! },
});
```

```ts
// src/casl-prisma.ts
import {
  accessibleBy,
  createPrismaAbility,
  ParsingQueryError,
  prismaQuery,
  type PrismaQueryOf,
  type WhereInputOf,
} from '@casl/prisma/runtime';
import type { Ability, ForcedSubject, TaggedSubject } from "@casl/ability";
import type { Prisma, Post, User } from './generated/client';

export { accessibleBy, createPrismaAbility, ParsingQueryError, prismaQuery };

export type PrismaQuery<T extends ForcedSubject<any> = ForcedSubject<any>> =
  PrismaQueryOf<Prisma.TypeMap, T>;
export type WhereInput<TModelName extends Prisma.ModelName> =
  WhereInputOf<Prisma.TypeMap, TModelName>;
export type AppSubjects =
  | User & ForcedSubject<'User'>
  | Post & ForcedSubject<'Post'>
;

export type AppAbility = Ability<['create' | "read" | "update" | "delete", 'all' | AppSubjects], PrismaQuery, TaggedSubject>
```

在您的应用程序中使用此包装而非导入 `@casl/prisma` 直接说 如果你坚持遗产 `prisma-client-js` prisma 6.x 兼容性生成器, 默认值 `@casl/prisma` 进入点继续工作.

## 想帮忙吗?

想要提交错误, 提供一些代码, 还是改进文档 ? 不错! 阅读指南 [捐款](https://github.com/stalniy/casl/blob/main/CONTRIBUTING.md)。 。 。 .

如果你想帮助我们 维持我们的社区和项目,考虑 [成为开放集体的出资人](https://opencollective.com/casljs/contribute)

> 见 [支助CASL](https://casl.js.org/v7/en/support-casljs) 详情

## 许可证

[MIT 许可证](http://www.opensource.org/licenses/MIT)

## 常见问题

### @casl/prisma 是什么？

允许根据 CASL 规则使用 Prisma 客户端查询可访问的记录

### 如何安装 @casl/prisma？

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

### @casl/prisma 支持 TypeScript 吗？

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

### @casl/prisma 支持 ESM 还是 CommonJS？

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

### @casl/prisma 可以商用吗？

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

### @casl/prisma 的下载量有多少？

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

### @casl/prisma 还在维护吗？

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

