Skip to content

Commit b0d9154

Browse files
authored
feat: support Prisma v5 (#587)
1 parent 46fec66 commit b0d9154

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1267
-3070
lines changed

.github/workflows/build-test.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,17 @@ jobs:
1818
strategy:
1919
matrix:
2020
node-version: [18.x]
21+
prisma-version: [v4, v5]
2122

2223
steps:
23-
- uses: actions/checkout@v3
24+
- name: Checkout
25+
uses: actions/checkout@v3
26+
27+
- name: Set Prisma Version
28+
if: ${{ matrix.prisma-version == 'v5' }}
29+
shell: bash
30+
run: |
31+
bash ./script/test-prisma-v5.sh
2432
2533
- name: Install pnpm
2634
uses: pnpm/action-setup@v2

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"devDependencies": {
1717
"@changesets/cli": "^2.26.0",
1818
"concurrently": "^7.4.0",
19+
"replace-in-file": "^7.0.1",
1920
"tsup": "^7.1.0"
2021
}
2122
}

packages/plugins/openapi/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"author": "ZenStack Team",
2525
"license": "MIT",
2626
"dependencies": {
27-
"@prisma/generator-helper": "4.10.0",
27+
"@prisma/generator-helper": "^5.0.0",
2828
"@zenstackhq/runtime": "workspace:*",
2929
"@zenstackhq/sdk": "workspace:*",
3030
"change-case": "^4.1.2",
@@ -36,10 +36,9 @@
3636
"zod-validation-error": "^0.2.1"
3737
},
3838
"devDependencies": {
39-
"@prisma/internals": "4.10.0",
4039
"@readme/openapi-parser": "^2.4.0",
4140
"@types/jest": "^29.5.0",
42-
"@types/lower-case-first": "^1.0.1",
41+
"@types/node": "^18.0.0",
4342
"@types/pluralize": "^0.0.29",
4443
"@types/tmp": "^0.2.3",
4544
"@typescript-eslint/eslint-plugin": "^5.54.0",

packages/plugins/openapi/src/generator-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import { PluginError, PluginOptions, getDataModels, hasAttribute } from '@zenstackhq/sdk';
33
import { Model } from '@zenstackhq/sdk/ast';
44
import type { OpenAPIV3_1 as OAPI } from 'openapi-types';

packages/plugins/openapi/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import { PluginError, PluginOptions } from '@zenstackhq/sdk';
33
import { Model } from '@zenstackhq/sdk/ast';
44
import { RESTfulOpenAPIGenerator } from './rest-generator';

packages/plugins/openapi/src/rest-generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Inspired by: https://github.com/omar-dulaimi/prisma-trpc-generator
22

3-
import { DMMF } from '@prisma/generator-helper';
3+
import type { DMMF } from '@prisma/generator-helper';
44
import {
55
AUXILIARY_FIELDS,
66
analyzePolicies,

packages/plugins/openapi/src/rpc-generator.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,12 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
713713
const fields = input.fields.filter((f) => !AUXILIARY_FIELDS.includes(f.name));
714714
for (const field of fields) {
715715
const options = field.inputTypes
716-
.filter((f) => f.type !== 'Null')
716+
.filter(
717+
(f) =>
718+
f.type !== 'Null' &&
719+
// fieldRefTypes refer to other fields in the model and don't need to be generated as part of schema
720+
f.location !== 'fieldRefTypes'
721+
)
717722
.map((f) => {
718723
return this.wrapArray(this.prismaTypeToOpenAPIType(f.type), f.isList);
719724
});

packages/plugins/prisma-types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
/// Types copied over from Prisma's generated code to avoid being broken due to Prisma upgrades
3+
4+
export type Enumerable<T> = T | Array<T>;
5+
6+
type _TupleToUnion<T> = T extends (infer E)[] ? E : never;
7+
8+
export type TupleToUnion<K extends readonly any[]> = _TupleToUnion<K>;
9+
10+
export type MaybeTupleToUnion<T> = T extends any[] ? TupleToUnion<T> : T;
11+
12+
export type PickEnumerable<T, K extends Enumerable<keyof T> | keyof T> = Pick<T, MaybeTupleToUnion<K>>;

packages/plugins/swr/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"author": "ZenStack Team",
2626
"license": "MIT",
2727
"dependencies": {
28-
"@prisma/generator-helper": "4.10.0",
28+
"@prisma/generator-helper": "^5.0.0",
2929
"@zenstackhq/runtime": "workspace:*",
3030
"@zenstackhq/sdk": "workspace:*",
3131
"change-case": "^4.1.2",
@@ -37,10 +37,9 @@
3737
"devDependencies": {
3838
"@tanstack/react-query": "^4.28.0",
3939
"@types/jest": "^29.5.0",
40-
"@types/lower-case-first": "^1.0.1",
40+
"@types/node": "^18.0.0",
4141
"@types/react": "18.2.0",
4242
"@types/tmp": "^0.2.3",
43-
"@types/upper-case-first": "^1.1.2",
4443
"@zenstackhq/testtools": "workspace:*",
4544
"copyfiles": "^2.4.1",
4645
"jest": "^29.5.0",

packages/plugins/swr/src/generator.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import {
33
PluginOptions,
44
createProject,
@@ -59,7 +59,7 @@ function generateModelHooks(project: Project, outDir: string, model: DataModel,
5959
});
6060
sf.addStatements([
6161
`import { useContext } from 'react';`,
62-
`import { RequestHandlerContext, type RequestOptions } from '@zenstackhq/swr/runtime';`,
62+
`import { RequestHandlerContext, type RequestOptions, type PickEnumerable } from '@zenstackhq/swr/runtime';`,
6363
`import * as request from '@zenstackhq/swr/runtime';`,
6464
]);
6565

@@ -193,7 +193,7 @@ function generateModelHooks(project: Project, outDir: string, model: DataModel,
193193
`HasSelectOrTake extends Prisma.Or<Prisma.Extends<'skip', Prisma.Keys<T>>, Prisma.Extends<'take', Prisma.Keys<T>>>`,
194194
`OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.${model.name}GroupByArgs['orderBy'] }: { orderBy?: Prisma.${model.name}GroupByArgs['orderBy'] },`,
195195
`OrderFields extends Prisma.ExcludeUnderscoreKeys<Prisma.Keys<Prisma.MaybeTupleToUnion<T['orderBy']>>>`,
196-
`ByFields extends Prisma.TupleToUnion<T['by']>`,
196+
`ByFields extends Prisma.MaybeTupleToUnion<T['by']>`,
197197
`ByValid extends Prisma.Has<ByFields, OrderFields>`,
198198
`HavingFields extends Prisma.GetHavingFields<T['having']>`,
199199
`HavingValid extends Prisma.Has<ByFields, HavingFields>`,
@@ -243,7 +243,7 @@ function generateModelHooks(project: Project, outDir: string, model: DataModel,
243243
];
244244
const inputType = `Prisma.SubsetIntersection<T, Prisma.${model.name}GroupByArgs, OrderByArg> & InputErrors`;
245245
const returnType = `{} extends InputErrors ?
246-
Array<Prisma.PickArray<Prisma.${model.name}GroupByOutputType, T['by']> &
246+
Array<PickEnumerable<Prisma.${model.name}GroupByOutputType, T['by']> &
247247
{
248248
[P in ((keyof T) & (keyof Prisma.${model.name}GroupByOutputType))]: P extends '_count'
249249
? T[P] extends boolean

packages/plugins/swr/src/runtime/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { deserialize, serialize } from '@zenstackhq/runtime/browser';
33
import { createContext } from 'react';
44
import type { MutatorCallback, MutatorOptions, SWRResponse } from 'swr';
55
import useSWR, { useSWRConfig } from 'swr';
6+
export * from './prisma-types';
67

78
/**
89
* Function signature for `fetch`.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../prisma-types.ts

packages/plugins/tanstack-query/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"author": "ZenStack Team",
4343
"license": "MIT",
4444
"dependencies": {
45-
"@prisma/generator-helper": "4.10.0",
45+
"@prisma/generator-helper": "^5.0.0",
4646
"@zenstackhq/runtime": "workspace:*",
4747
"@zenstackhq/sdk": "workspace:*",
4848
"change-case": "^4.1.2",
@@ -56,10 +56,9 @@
5656
"@tanstack/react-query": "4.29.7",
5757
"@tanstack/svelte-query": "4.29.7",
5858
"@types/jest": "^29.5.0",
59-
"@types/lower-case-first": "^1.0.1",
59+
"@types/node": "^18.0.0",
6060
"@types/react": "18.2.0",
6161
"@types/tmp": "^0.2.3",
62-
"@types/upper-case-first": "^1.1.2",
6362
"@zenstackhq/testtools": "workspace:*",
6463
"copyfiles": "^2.4.1",
6564
"jest": "^29.5.0",

packages/plugins/tanstack-query/src/generator.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import {
33
PluginError,
44
PluginOptions,
@@ -300,7 +300,7 @@ function generateModelHooks(
300300
`HasSelectOrTake extends Prisma.Or<Prisma.Extends<'skip', Prisma.Keys<T>>, Prisma.Extends<'take', Prisma.Keys<T>>>`,
301301
`OrderByArg extends Prisma.True extends HasSelectOrTake ? { orderBy: Prisma.${model.name}GroupByArgs['orderBy'] }: { orderBy?: Prisma.${model.name}GroupByArgs['orderBy'] },`,
302302
`OrderFields extends Prisma.ExcludeUnderscoreKeys<Prisma.Keys<Prisma.MaybeTupleToUnion<T['orderBy']>>>`,
303-
`ByFields extends Prisma.TupleToUnion<T['by']>`,
303+
`ByFields extends Prisma.MaybeTupleToUnion<T['by']>`,
304304
`ByValid extends Prisma.Has<ByFields, OrderFields>`,
305305
`HavingFields extends Prisma.GetHavingFields<T['having']>`,
306306
`HavingValid extends Prisma.Has<ByFields, HavingFields>`,
@@ -350,7 +350,7 @@ function generateModelHooks(
350350
];
351351

352352
const returnType = `{} extends InputErrors ?
353-
Array<Prisma.PickArray<Prisma.${model.name}GroupByOutputType, T['by']> &
353+
Array<PickEnumerable<Prisma.${model.name}GroupByOutputType, T['by']> &
354354
{
355355
[P in ((keyof T) & (keyof Prisma.${model.name}GroupByOutputType))]: P extends '_count'
356356
? T[P] extends boolean
@@ -406,6 +406,7 @@ function makeGetContext(target: TargetFramework) {
406406
function makeBaseImports(target: TargetFramework) {
407407
const shared = [
408408
`import { query, postMutation, putMutation, deleteMutation } from '@zenstackhq/tanstack-query/runtime/${target}';`,
409+
`import type { PickEnumerable } from '@zenstackhq/tanstack-query/runtime';`,
409410
];
410411
switch (target) {
411412
case 'react':
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './prisma-types';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../prisma-types.ts

packages/plugins/tanstack-query/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from 'tsup';
22

33
export default defineConfig({
4-
entry: ['src/runtime/react.ts', 'src/runtime/svelte.ts'],
4+
entry: ['src/runtime/index.ts', 'src/runtime/react.ts', 'src/runtime/svelte.ts'],
55
outDir: 'dist/runtime',
66
splitting: false,
77
sourcemap: true,

packages/plugins/trpc/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
"author": "ZenStack Team",
2525
"license": "MIT",
2626
"dependencies": {
27-
"@prisma/generator-helper": "4.10.0",
28-
"@prisma/internals": "4.10.0",
27+
"@prisma/generator-helper": "^5.0.0",
2928
"@zenstackhq/sdk": "workspace:*",
3029
"change-case": "^4.1.2",
3130
"lower-case-first": "^2.0.2",
@@ -40,7 +39,7 @@
4039
"@trpc/react-query": "^10.32.0",
4140
"@trpc/server": "^10.32.0",
4241
"@types/jest": "^29.5.0",
43-
"@types/lower-case-first": "^1.0.1",
42+
"@types/node": "^18.0.0",
4443
"@types/prettier": "^2.7.2",
4544
"@zenstackhq/testtools": "workspace:*",
4645
"copyfiles": "^2.4.1",

packages/plugins/trpc/src/generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import {
33
CrudFailureReason,
44
PluginError,

packages/plugins/trpc/src/helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import { PluginError, getPrismaClientImportSpec } from '@zenstackhq/sdk';
33
import { Model } from '@zenstackhq/sdk/ast';
44
import { lowerCaseFirst } from 'lower-case-first';
@@ -123,7 +123,7 @@ function getPrismaOperationTypes(model: string, operation: string) {
123123
? { orderBy: Prisma.${capModel}GroupByArgs['orderBy'] }
124124
: { orderBy?: Prisma.${capModel}GroupByArgs['orderBy'] },
125125
OrderFields extends Prisma.ExcludeUnderscoreKeys<Prisma.Keys<Prisma.MaybeTupleToUnion<T['orderBy']>>>,
126-
ByFields extends Prisma.TupleToUnion<T['by']>,
126+
ByFields extends Prisma.MaybeTupleToUnion<T['by']>,
127127
ByValid extends Prisma.Has<ByFields, OrderFields>,
128128
HavingFields extends Prisma.GetHavingFields<T['having']>,
129129
HavingValid extends Prisma.Has<ByFields, HavingFields>,

packages/plugins/trpc/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DMMF } from '@prisma/generator-helper';
1+
import type { DMMF } from '@prisma/generator-helper';
22
import { PluginOptions } from '@zenstackhq/sdk';
33
import { Model } from '@zenstackhq/sdk/ast';
44
import { generate } from './generator';

packages/runtime/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,9 @@
6464
"homepage": "https://zenstack.dev",
6565
"license": "MIT",
6666
"devDependencies": {
67-
"@prisma/client": "^4.0.0",
6867
"@types/bcryptjs": "^2.4.2",
6968
"@types/jest": "^29.5.0",
70-
"@types/lower-case-first": "^1.0.1",
71-
"@types/node": "^14.18.29",
69+
"@types/node": "^18.0.0",
7270
"@types/pluralize": "^0.0.29",
7371
"copyfiles": "^2.4.1",
7472
"rimraf": "^3.0.2",

packages/runtime/src/enhancements/utils.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,37 @@ let _PrismaClientUnknownRequestError: new (...args: unknown[]) => Error;
6060
function loadPrismaModule(prisma: any) {
6161
// https://github.com/prisma/prisma/discussions/17832
6262
if (prisma._engineConfig?.datamodelPath) {
63+
// try engine path first
6364
const loadPath = path.dirname(prisma._engineConfig.datamodelPath);
6465
try {
6566
const _prisma = require(loadPath).Prisma;
66-
if (typeof _prisma !== 'undefined') return _prisma;
67-
return require('@prisma/client/runtime');
67+
if (typeof _prisma !== 'undefined') {
68+
return _prisma;
69+
}
6870
} catch {
69-
return require('@prisma/client/runtime');
71+
// noop
7072
}
71-
} else {
73+
}
74+
75+
try {
76+
// Prisma v4
7277
return require('@prisma/client/runtime');
78+
} catch {
79+
try {
80+
// Prisma v5
81+
return require('@prisma/client');
82+
} catch (err) {
83+
if (process.env.ZENSTACK_TEST === '1') {
84+
// running in test, try cwd
85+
try {
86+
return require(path.join(process.cwd(), 'node_modules/@prisma/client/runtime'));
87+
} catch {
88+
return require(path.join(process.cwd(), 'node_modules/@prisma/client'));
89+
}
90+
} else {
91+
throw err;
92+
}
93+
}
7394
}
7495
}
7596

packages/schema/package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@
8080
},
8181
"dependencies": {
8282
"@paralleldrive/cuid2": "^2.2.0",
83-
"@prisma/generator-helper": "4.10.0",
84-
"@prisma/internals": "4.10.0",
83+
"@prisma/generator-helper": "^5.0.0",
8584
"@zenstackhq/language": "workspace:*",
8685
"@zenstackhq/sdk": "workspace:*",
8786
"async-exit-hook": "^2.0.1",
@@ -114,13 +113,11 @@
114113
"devDependencies": {
115114
"@types/async-exit-hook": "^2.0.0",
116115
"@types/jest": "^29.5.0",
117-
"@types/lower-case-first": "^1.0.1",
118-
"@types/node": "^14.18.32",
116+
"@types/node": "^18.0.0",
119117
"@types/pluralize": "^0.0.29",
120118
"@types/semver": "^7.3.13",
121119
"@types/strip-color": "^0.1.0",
122120
"@types/tmp": "^0.2.3",
123-
"@types/upper-case-first": "^1.1.2",
124121
"@types/uuid": "^8.3.4",
125122
"@types/vscode": "^1.56.0",
126123
"@typescript-eslint/eslint-plugin": "^5.42.0",
@@ -134,7 +131,6 @@
134131
"eslint": "^8.27.0",
135132
"eslint-plugin-jest": "^27.1.7",
136133
"jest": "^29.5.0",
137-
"prisma": "^4.0.0",
138134
"renamer": "^4.0.0",
139135
"rimraf": "^3.0.2",
140136
"tmp": "^0.2.1",

packages/schema/src/cli/plugin-runner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
/* eslint-disable @typescript-eslint/no-var-requires */
33
import type { DMMF } from '@prisma/generator-helper';
4-
import { getDMMF } from '@prisma/internals';
54
import { isPlugin, Plugin } from '@zenstackhq/language/ast';
65
import {
76
getDataModels,
7+
getDMMF,
88
getLiteral,
99
getLiteralArray,
1010
hasValidationAttributes,

0 commit comments

Comments
 (0)