跳至主要内容

共享 Prisma 客户端扩展

您可以将您的 Prisma 客户端扩展 作为包或模块与他人共享,并将他人创建的扩展导入到您的项目中。

如果您想构建一个可共享的扩展,我们还建议您使用 prisma-client-extension-starter 模板。

要探索 Prisma 官方客户端扩展和社区制作的扩展示例,请访问页面。

安装共享的打包扩展

在您的项目中,您可以安装任何其他用户已发布到 npm 的 Prisma 客户端扩展。为此,请运行以下命令

npm install prisma-extension-<package-name>

例如,如果可用扩展的包名称是 prisma-extension-find-or-create,您可以按如下方式安装它

npm install prisma-extension-find-or-create

要从上面的示例中导入 find-or-create 扩展,并使用它包装您的客户端实例,您可以使用以下代码。此示例假设扩展名为 findOrCreate

import findOrCreate from 'prisma-extension-find-or-create'
import { PrismaClient } from '../generated/prisma/client'
const prisma = new PrismaClient()
const xprisma = prisma.$extends(findOrCreate)
const user = await xprisma.user.findOrCreate()

当您在扩展中调用方法时,请使用 $extends 语句中的常量名称,而不是 prisma。在上面的示例中,xprisma.user.findOrCreate 有效,但 prisma.user.findOrCreate 无效,因为原始的 prisma 未被修改。

创建可共享扩展

当您希望创建其他用户可以使用且不只是针对您的 schema 定制的扩展时,Prisma ORM 提供了实用程序,允许您创建可共享的扩展。

要创建可共享的扩展

  1. 使用 Prisma.defineExtension 将扩展定义为模块
  2. 使用以 $all 前缀开头的方法之一,例如 $allModels$allOperations

定义扩展

使用 Prisma.defineExtension 方法使您的扩展可共享。您可以使用它打包扩展,将您的扩展分离到单独的文件中,或作为 npm 包与其他用户共享。

Prisma.defineExtension 的好处是它为扩展作者在开发和共享扩展用户提供了严格的类型检查和自动完成功能。

使用通用方法

$allModels 下包含方法的扩展适用于每个模型,而不是特定模型。同样,$allOperations 下的方法适用于整个客户端实例,而不是命名组件,例如 resultquery

您不需要将 $all 前缀与 client 组件一起使用,因为 client 组件始终适用于客户端实例。

例如,通用扩展可能采用以下形式

export default Prisma.defineExtension({
name: 'prisma-extension-find-or-create', //Extension name
model: {
$allModels: {
// new method
findOrCreate(/* args */) {
/* code for the new method */
return query(args)
},
},
},
})

请参阅以下页面,了解修改 Prisma 客户端操作的不同方法

对于 4.16.0 之前的版本

Prisma 导入可从以下代码片段中显示的不同路径获取

import { Prisma } from '@prisma/client/scripts/default-index'

export default Prisma.defineExtension({
name: 'prisma-extension-<extension-name>',
})

将可共享扩展发布到 npm

然后您可以在 npm 上共享扩展。当您选择包名称时,我们建议您使用 prisma-extension-<package-name> 约定,以便更容易查找和安装。

从打包扩展调用客户端级别方法

警告

目前,对于引用 PrismaClient 并调用客户端级别方法的扩展存在限制,如下面的示例所示。

如果您从 事务(交互式或批处理)内部触发扩展,扩展代码将在新连接中发出查询并忽略当前事务上下文。

在 GitHub 上的此问题中了解更多信息:需要使用客户端级别方法的客户端扩展会静默忽略事务

在以下情况下,您需要引用您的扩展所包装的 Prisma 客户端实例

  • 当您想在打包扩展中使用 客户端级别方法,例如 $queryRaw 时。
  • 当您想在打包扩展中链接多个 $extends 调用时。

但是,当有人将您的打包扩展包含在他们的项目中时,您的代码无法知道 Prisma 客户端实例的详细信息。

您可以按如下方式引用此客户端实例

Prisma.defineExtension((client) => {
// The Prisma Client instance that the extension user applies the extension to
return client.$extends({
name: 'prisma-extension-<extension-name>',
})
})

例如

export default Prisma.defineExtension((client) => {
return client.$extends({
name: 'prisma-extension-find-or-create',
query: {
$allModels: {
async findOrCreate({ args, query, operation }) {
return (await client.$transaction([query(args)]))[0]
},
},
},
})
})

高级类型安全:用于定义通用扩展的类型实用程序

您可以使用 类型实用程序 提高共享扩展的类型安全性。

© . This site is unofficial and not affiliated with Prisma Data, Inc.