跳到主要內容

共用 Prisma Client 擴充功能

您可以與其他使用者分享您的 Prisma Client 擴充功能,以套件或模組的形式,並將其他使用者建立的擴充功能匯入到您的專案中。

如果您想要建立可分享的擴充功能,我們也建議您使用 prisma-client-extension-starter 範本。

若要探索 Prisma 官方 Client 擴充功能和社群製作的擴充功能範例,請造訪頁面。

安裝共用的封裝擴充功能

在您的專案中,您可以安裝其他使用者發布到 npm 的任何 Prisma Client 擴充功能。若要這麼做,請執行以下命令

npm install prisma-extension-<package-name>

例如,如果可用擴充功能的套件名稱是 prisma-extension-find-or-create,您可以如下安裝它

npm install prisma-extension-find-or-create

若要從上述範例匯入 find-or-create 擴充功能,並使用它包裝您的 client 實例,您可以使用以下程式碼。此範例假設擴充功能名稱為 findOrCreate

import findOrCreate from 'prisma-extension-find-or-create'

const prisma = new PrismaClient().$extends(findOrCreate)
const user = await prisma.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 下的方法適用於整個 client 實例,而不是命名的元件,例如 resultquery

您不需要在 client 元件中使用 $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 Client 運作方式的不同方法

對於早於 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> 慣例,以便更容易找到和安裝。

從您封裝的擴充功能呼叫 client 層級方法

警告

目前,對於參考 PrismaClient 並呼叫 client 層級方法的擴充功能,存在限制,如下例所示。

如果您從 交易(互動式或批次處理)內部觸發擴充功能,則擴充功能程式碼將在新連線中發出查詢,並忽略目前的交易情境。

在此 GitHub 議題中了解更多資訊:需要使用 client 層級方法的 Client 擴充功能會靜默地忽略交易

在以下情況中,您需要參考您的擴充功能包裝的 Prisma Client 實例

  • 當您想要在您封裝的擴充功能中使用client 層級方法,例如 $queryRaw 時。
  • 當您想要在您封裝的擴充功能中鏈接多個 $extends 呼叫時。

但是,當有人將您封裝的擴充功能包含在其專案中時,您的程式碼無法得知 Prisma Client 實例的詳細資訊。

您可以如下參考此 client 實例

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]
},
},
},
})
})

進階類型安全:用於定義通用擴充功能的類型工具程式

您可以使用類型工具程式來改善您共用擴充功能的類型安全。