🌟 **Help us spread the word about Prisma by starring the repo or [tweeting](https://twitter.com/intent/tweet?text=Check%20out%20the%20latest%20prisma%20release%20v4.16.0%20%F0%9F%9A%80%0D%0A%0D%0Ahttps://github.com/prisma/prisma/releases/tag/4.16.0) about the release.** 🌟
Highlights
This release promotes the following [Preview](https://www.prisma.io/docs/about/prisma/releases#preview) features to [General Availability](https://www.prisma.io/docs/about/prisma/releases#generally-available-ga):
- Prisma Client extensions
- Ordering by nulls first and last
- Count by filtered relation
Prisma Client extensions are Generally Available
Today, we’re very excited to announce that [Prisma Client extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions) are Generally Available and production-ready! This means you can use the feature without the `clientExtensions` Preview feature flag.🚀
Prisma Client extensions are a powerful new feature for adding functionality on top of your Prisma Client in a type-safe manner. With this feature, you can create simple, but flexible solutions.
Prisma Client extensions have 4 different types of components that can be included in an extension:
- [**Result** extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/result) components: add custom fields and methods to query result objects, for example, virtual/computed fields.
- [**Model** extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/model) components: enable you to add new methods to your models alongside existing model methods such as `findMany`.
- [**Query** extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/query) components: let you hook into the lifecycle of a query and perform side effects, modify query arguments, or modify the results in a type-safe way. These are an alternative to [middleware](https://www.prisma.io/docs/concepts/components/prisma-client/middleware) that provide complete type safety and can be applied in an ad-hoc manner to different extensions.
- [**Client** extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/client) components: allow you to add new top-level methods to Prisma Client. You can use this to extend Prisma Client with functionality that isn’t tied to specific models.
tsx
const prisma = new PrismaClient().$extends({
name: "extension-name",
result: { /* ... */ },
model: { /* ... */ },
query: { /* ... */ },
client: { /* ... */ },
});
You can also create and publish extensions for others to use. Learn more about how to share extensions in our [documentation](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/shared-extensions).
More features and changes made to Client Extensions
We also made the following improvements to Prisma Client extensions in preparation for General Availability:
- Added a top-level `$allOperations` method for `query` component that captures all model operations as well as top-level raw queries. Refer to our [documentation](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/query#modify-all-prisma-client-operations) for more information.
tsx
const prisma = new PrismaClient().$extends({
query: {
$allOperations({ args, query, operation, model }) {
/* your extension's logic here */
}
}
})
- [`Prisma.validator`](https://www.prisma.io/docs/concepts/components/prisma-client/advanced-type-safety/prisma-validator) can now also be used for extended types:
tsx
const prisma = new PrismaClient().$extends({/* ... */})
const data = Prisma.validator(prisma, 'user', 'findFirst', 'select')({
id: true,
})
- `query` callbacks for `$queryRaw` and `$executeRaw` will always receive `Sql` instance as `args`. This instance can be used to compose a new query using `Prisma.sql`:
tsx
const prisma = new PrismaClient().$extends({
query: {
$queryRaw({ args, query }) {
return query(Prisma.sql`START TRANSACTION; ${args}; COMMIT;`)
}
}
})
- `$on` cannot be called after extending Prisma Client. Therefore, if you want to use event handlers together with extensions, we recommend using the `$on` method before `$extends`.
tsx
const prisma = new PrismaClient()
.$on(/* ... */)
.$extends({/* ... */})
- We updated the import path for utilities used for authoring extension to `prisma/client/extension` rather than `prisma/client`
diff
+ import { Prisma } from "prisma/client/extension"
- import { Prisma } from "prisma/client"
Deprecating Middleware
We also took this opportunity to [deprecate](https://en.wikipedia.org/wiki/Deprecation) Prisma Client’s [middleware](https://www.prisma.io/docs/concepts/components/prisma-client/middleware). We recommend using to using [Prisma Client `query` extension components](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions/query) which can be used to achieve the same functionality and with better type safety.
> 🚧 Middleware will still be available in Prisma Client’s API. However, we recommend using Prisma Client extensions over middleware.
Ordering by nulls first and last is now Generally Available
Starting with this release, we’re excited to announce that `orderByNulls` is now Generally Available! This means you can use the feature without the `orderByNulls` Preview feature flag.🌟
We introduced this feature in [4.1.0](https://github.com/prisma/prisma/releases/tag/4.1.0) to enable you to sort records with null fields to either appear at the beginning or end of the result.
The following example query sorts posts by `updatedAt`, with records having a null value at the end of the list:
tsx
await prisma.post.findMany({
orderBy: {
updatedAt: { sort: 'asc', nulls: 'last' },
},
})
To learn more about this feature, refer to our [documentation](https://www.prisma.io/docs/concepts/components/prisma-client/filtering-and-sorting#sort-with-null-records-first-or-last).
We’re excited to see what you will build! Feel free to share with us what you build on Twitter, Slack, or Discord.
Count by filtered relation is now Generally Available
This release moves the `filteredRelationCount` Preview feature to General Availability! This means you can use the feature without the `filteredRelationCount` Preview feature flag.
We first introduced this feature in [4.3.0](https://github.com/prisma/prisma/releases/tag/4.3.0) to add the ability to count by filtered relations.
The following query, for example, counts all posts with the title “Hello!”:
tsx
await prisma.user.findMany({
select: {
_count: {
select: {
posts: { where: { title: 'Hello!' } },
},
},
},
})
To learn more about this feature, refer to our [documentation](https://www.prisma.io/docs/concepts/components/prisma-client/aggregation-grouping-summarizing#filter-the-relation-count).
Introspection warnings for expression indexes
In the last two releases, [4.13.0](https://github.com/prisma/prisma/releases/tag/4.13.0) and [4.14.0](https://github.com/prisma/prisma/releases/tag/4.14.0), we added 9 introspection warnings. These warnings surface features in use in your database that cannot currently be represented in the Prisma schema.
In this release, we’re adding one more introspection warning to the list: [expression indexes](https://github.com/prisma/prisma/issues/2504).
On database introspection, the Prisma CLI will surface the feature with a warning, and a comment in your Prisma schema for sections for each feature in use. The warnings will also contain instructions for workarounds on how to use the feature.
Fixes and improvements
Prisma Client
- [Attach comments to enum values](https://github.com/prisma/prisma/issues/3807)
- [Extend Prisma Client](https://github.com/prisma/prisma/issues/7161)
- [Triple-slash Comments should attach to Composite Types](https://github.com/prisma/prisma/issues/13726)
- [Nested disconnect fails on MongoDB with extendedWhereUnique](https://github.com/prisma/prisma/issues/16869)
- [[ClientExtensions, TypeScript] Fields of custom type aren't available when using the ClientExtensions preview-feature, unless `select`'d explicitly. ](https://github.com/prisma/prisma/issues/17388)
- [Extensions incorrect typings generated (casing)](https://github.com/prisma/prisma/issues/17405)
- [Misleading error message of `prisma generate` when running it directly after installing `prisma`](https://github.com/prisma/prisma/issues/17639)
- [Prisma.validator: with clientExtensions enabled, Typescript can no longer compute types](https://github.com/prisma/prisma/issues/17767)
- [enum docstrings do not make it to the prisma client](https://github.com/prisma/prisma/issues/17828)
- [VScode behavior is very slow while using clientExtensions](https://github.com/prisma/prisma/issues/17843)
- [Client extensions in interactive transactions are bound to the base client](https://github.com/prisma/prisma/issues/17948)
- [`$runCommandRaw` is not passing the expected data to middleware or client extension](https://github.com/prisma/prisma/issues/18092)
- [PCE: Improve runtime types in raw query extensions](https://github.com/prisma/prisma/issues/18125)
- [Sequential transactions run out of order when using client extensions and middleware](https://github.com/prisma/prisma/issues/18276)
- [Client Extension: Make `.prismaVersion.client` available on "prisma/client/scripts/default-index"](https://github.com/prisma/prisma/issues/18829)
- [Cannot create record with Prisma.DbNull when clientExtensions enabled](https://github.com/prisma/prisma/issues/18854)
- [Extended client raw queries fail when using the Prisma.sql helper](https://github.com/prisma/prisma/issues/18875)
- [jsonProtocol: array shortcut is missing for `distinct` field](https://github.com/prisma/prisma/issues/18906)
- [Prisma Client Extension: support `Prisma.validator`](https://github.com/prisma/prisma/issues/18943)
- [Prisma Client: make `clientExtensions` GA ](https://github.com/prisma/prisma/issues/19416)
- [PCE: Query extensions of `$queryRawUnsafe` also triggers `$allModels.$allOperations`](https://github.com/prisma/prisma/issues/19550)
- [PCE: `$on` applied to an extended client is also bound to the parent client](https://github.com/prisma/prisma/issues/19552)
- [Type "never" returned from nested properties when using "select" after enabling data proxy + accelerate](https://github.com/prisma/prisma/issues/19572)
- [`$queryRaw*` is broken in interactive transactions together with `clientExtensions` in `4.16.0-dev.17`](https://github.com/prisma/prisma/issues/19651)
- [Deploying to an offline environment fails because it tries to download a Prisma engine checksum file ](https://github.com/prisma/prisma/issues/19666)
- [jsonProtocol: Wrong error message shown for validation error for checked/unchecked types](https://github.com/prisma/prisma/issues/19707)
- [Bug: FindXOrThrow don't get batched on the engine](https://github.com/prisma/prisma/issues/16625)
Prisma Migrate
- [Allow skipping sha checksum](https://github.com/prisma/prisma/issues/12230)
- [Documentation not available in DMMF for MongoDB `type`s](https://github.com/prisma/prisma/issues/18551)
- [`prisma db pull` gets rid of `default(uuid())` on re-introspection](https://github.com/prisma/prisma/issues/18857)
Language tools (e.g. VS Code)
- [`Go to Definition` does not work when target model contains a field with a type name that starts with the same name](https://github.com/prisma/language-tools/issues/1247)
Prisma Studio
- [`Error: spawn xdg-open ENOENT` on `prisma studio`](https://github.com/prisma/studio/issues/1128)
📺 Join us for another "What's new in Prisma" live stream
Learn about the latest release and other news from the Prisma community by joining us for another ["What's new in Prisma"](https://youtube.com/playlist?list=PLn2e1F9Rfr6l1B9RP0A9NdX7i7QIWfBa7) live stream.
The stream takes place [on YouTube](https://youtu.be/pLxsipkdQmc) on **Thursday, June 22** at **5 pm Berlin | 8 am San Francisco**.