1
1
import { DELEGATE_AUX_RELATION_PREFIX } from '@zenstackhq/runtime' ;
2
+ import { invariant , upperCaseFirst } from '@zenstackhq/runtime/local-helpers' ;
2
3
import {
3
4
PluginError ,
4
5
getAttribute ,
@@ -26,7 +27,6 @@ import {
26
27
type Model ,
27
28
} from '@zenstackhq/sdk/ast' ;
28
29
import { getDMMF , getPrismaClientImportSpec , getPrismaVersion , type DMMF } from '@zenstackhq/sdk/prisma' ;
29
- import { invariant , upperCaseFirst } from '@zenstackhq/runtime/local-helpers' ;
30
30
import fs from 'fs' ;
31
31
import path from 'path' ;
32
32
import semver from 'semver' ;
@@ -105,44 +105,122 @@ export class EnhancerGenerator {
105
105
}
106
106
107
107
async generate ( ) : Promise < { dmmf : DMMF . Document | undefined ; newPrismaClientDtsPath : string | undefined } > {
108
- let dmmf : DMMF . Document | undefined ;
108
+ if ( this . isNewPrismaClientGenerator ) {
109
+ // "prisma-client" generator
110
+ return this . generateForNewClientGenerator ( ) ;
111
+ } else {
112
+ // "prisma-client-js" generator
113
+ return this . generateForOldClientGenerator ( ) ;
114
+ }
115
+ }
109
116
117
+ // logic for "prisma-client" generator
118
+ private async generateForNewClientGenerator ( ) {
119
+ const needsLogicalClient = this . needsLogicalClient ;
110
120
const prismaImport = getPrismaClientImportSpec ( this . outDir , this . options ) ;
111
- let prismaTypesFixed = false ;
112
- let resultPrismaTypeImport = prismaImport ;
113
-
114
- if ( this . needsLogicalClient ) {
115
- prismaTypesFixed = true ;
116
- resultPrismaTypeImport = LOGICAL_CLIENT_GENERATION_PATH ;
117
- if ( this . isNewPrismaClientGenerator ) {
118
- resultPrismaTypeImport += '/client' ;
119
- }
121
+ let resultPrismaBaseImport = path . dirname ( prismaImport ) ; // get to the parent folder of "client"
122
+ let dmmf : DMMF . Document | undefined ;
123
+
124
+ if ( needsLogicalClient ) {
125
+ // use logical client, note we use the parent of "client" folder here too
126
+ resultPrismaBaseImport = LOGICAL_CLIENT_GENERATION_PATH ;
120
127
const result = await this . generateLogicalPrisma ( ) ;
121
128
dmmf = result . dmmf ;
122
129
}
123
130
124
- // reexport PrismaClient types (original or fixed)
125
- const modelsTsContent = `export * from '${ resultPrismaTypeImport } ';${
126
- this . isNewPrismaClientGenerator ? "\nexport * from './json-types';" : ''
127
- } `;
131
+ // `models.ts` for exporting model types
132
+ const modelsTsContent = [
133
+ `export * from '${ resultPrismaBaseImport } /models';` ,
134
+ `export * from './json-types';` ,
135
+ ] . join ( '\n' ) ;
136
+ const modelsTs = this . project . createSourceFile ( path . join ( this . outDir , 'models.ts' ) , modelsTsContent , {
137
+ overwrite : true ,
138
+ } ) ;
139
+ this . saveSourceFile ( modelsTs ) ;
140
+
141
+ // `enums.ts` for exporting enums
142
+ const enumsTs = this . project . createSourceFile (
143
+ path . join ( this . outDir , 'enums.ts' ) ,
144
+ `export * from '${ resultPrismaBaseImport } /enums';` ,
145
+ {
146
+ overwrite : true ,
147
+ }
148
+ ) ;
149
+ this . saveSourceFile ( enumsTs ) ;
150
+
151
+ // `client.ts` for exporting `PrismaClient` and `Prisma` namespace
152
+ const clientTs = this . project . createSourceFile (
153
+ path . join ( this . outDir , 'client.ts' ) ,
154
+ `export * from '${ resultPrismaBaseImport } /client';` ,
155
+ {
156
+ overwrite : true ,
157
+ }
158
+ ) ;
159
+ this . saveSourceFile ( clientTs ) ;
160
+
161
+ // `enhance.ts` and `enhance-edge.ts`
162
+ for ( const target of [ 'node' , 'edge' ] as const ) {
163
+ this . generateEnhance ( prismaImport , `${ resultPrismaBaseImport } /client` , needsLogicalClient , target ) ;
164
+ }
165
+
166
+ return {
167
+ // logical dmmf if there is one
168
+ dmmf,
169
+ // new client generator doesn't have a barrel .d.ts file
170
+ newPrismaClientDtsPath : undefined ,
171
+ } ;
172
+ }
173
+
174
+ // logic for "prisma-client-js" generator
175
+ private async generateForOldClientGenerator ( ) {
176
+ const needsLogicalClient = this . needsLogicalClient ;
177
+ const prismaImport = getPrismaClientImportSpec ( this . outDir , this . options ) ;
178
+ let resultPrismaClientImport = prismaImport ;
179
+ let dmmf : DMMF . Document | undefined ;
180
+
181
+ if ( needsLogicalClient ) {
182
+ // redirect `PrismaClient` import to the logical client
183
+ resultPrismaClientImport = LOGICAL_CLIENT_GENERATION_PATH ;
184
+ const result = await this . generateLogicalPrisma ( ) ;
185
+ dmmf = result . dmmf ;
186
+ }
128
187
188
+ // `models.ts` for exporting model types
189
+ const modelsTsContent = `export * from '${ resultPrismaClientImport } ';` ;
129
190
const modelsTs = this . project . createSourceFile ( path . join ( this . outDir , 'models.ts' ) , modelsTsContent , {
130
191
overwrite : true ,
131
192
} ) ;
132
193
this . saveSourceFile ( modelsTs ) ;
133
194
195
+ // `enhance.ts` and `enhance-edge.ts`
196
+ for ( const target of [ 'node' , 'edge' ] as const ) {
197
+ this . generateEnhance ( prismaImport , resultPrismaClientImport , needsLogicalClient , target ) ;
198
+ }
199
+
200
+ return {
201
+ // logical dmmf if there is one
202
+ dmmf,
203
+ newPrismaClientDtsPath : needsLogicalClient
204
+ ? path . resolve ( this . outDir , LOGICAL_CLIENT_GENERATION_PATH , 'index.d.ts' )
205
+ : undefined ,
206
+ } ;
207
+ }
208
+
209
+ private generateEnhance (
210
+ prismaImport : string ,
211
+ prismaClientImport : string ,
212
+ needsLogicalClient : boolean ,
213
+ target : 'node' | 'edge'
214
+ ) {
134
215
const authDecl = getAuthDecl ( getDataModelAndTypeDefs ( this . model ) ) ;
135
216
const authTypes = authDecl ? generateAuthType ( this . model , authDecl ) : '' ;
136
217
const authTypeParam = authDecl ? `auth.${ authDecl . name } ` : 'AuthUser' ;
137
-
138
218
const checkerTypes = this . generatePermissionChecker ? generateCheckerType ( this . model ) : '' ;
139
219
140
- for ( const target of [ 'node' , 'edge' ] ) {
141
- // generate separate `enhance()` for node and edge runtime
142
- const outFile = target === 'node' ? 'enhance.ts' : 'enhance-edge.ts' ;
143
- const enhanceTs = this . project . createSourceFile (
144
- path . join ( this . outDir , outFile ) ,
145
- `/* eslint-disable */
220
+ const outFile = target === 'node' ? 'enhance.ts' : 'enhance-edge.ts' ;
221
+ const enhanceTs = this . project . createSourceFile (
222
+ path . join ( this . outDir , outFile ) ,
223
+ `/* eslint-disable */
146
224
import { type EnhancementContext, type EnhancementOptions, type ZodSchemas, type AuthUser } from '@zenstackhq/runtime';
147
225
import { createEnhancement } from '@zenstackhq/runtime/enhancements/${ target } ';
148
226
import modelMeta from './model-meta';
154
232
}
155
233
156
234
${
157
- prismaTypesFixed
158
- ? this . createLogicalPrismaImports ( prismaImport , resultPrismaTypeImport , target )
235
+ needsLogicalClient
236
+ ? this . createLogicalPrismaImports ( prismaImport , prismaClientImport , target )
159
237
: this . createSimplePrismaImports ( prismaImport , target )
160
238
}
161
239
@@ -164,23 +242,15 @@ ${authTypes}
164
242
${ checkerTypes }
165
243
166
244
${
167
- prismaTypesFixed
245
+ needsLogicalClient
168
246
? this . createLogicalPrismaEnhanceFunction ( authTypeParam )
169
247
: this . createSimplePrismaEnhanceFunction ( authTypeParam )
170
248
}
171
249
` ,
172
- { overwrite : true }
173
- ) ;
174
-
175
- this . saveSourceFile ( enhanceTs ) ;
176
- }
250
+ { overwrite : true }
251
+ ) ;
177
252
178
- return {
179
- dmmf,
180
- newPrismaClientDtsPath : prismaTypesFixed
181
- ? path . resolve ( this . outDir , LOGICAL_CLIENT_GENERATION_PATH , 'index.d.ts' )
182
- : undefined ,
183
- } ;
253
+ this . saveSourceFile ( enhanceTs ) ;
184
254
}
185
255
186
256
private getZodImport ( ) {
210
280
return normalizedRelative ( this . outDir , zodAbsPath ) ;
211
281
}
212
282
213
- private createSimplePrismaImports ( prismaImport : string , target : string ) {
283
+ private createSimplePrismaImports ( prismaImport : string , target : string | undefined ) {
214
284
const prismaTargetImport = target === 'edge' ? `${ prismaImport } /edge` : prismaImport ;
215
285
216
286
return `import { Prisma, type PrismaClient } from '${ prismaTargetImport } ';
@@ -241,10 +311,10 @@ export function enhance<DbClient extends object>(prisma: DbClient, context?: Enh
241
311
` ;
242
312
}
243
313
244
- private createLogicalPrismaImports ( prismaImport : string , prismaClientImport : string , target : string ) {
314
+ private createLogicalPrismaImports ( prismaImport : string , prismaClientImport : string , target : string | undefined ) {
245
315
const prismaTargetImport = target === 'edge' ? `${ prismaImport } /edge` : prismaImport ;
246
316
const runtimeLibraryImport = this . isNewPrismaClientGenerator
247
- ? // new generator has these typed only in "@prisma/client"
317
+ ? // new generator has these types only in "@prisma/client"
248
318
'@prisma/client/runtime/library'
249
319
: // old generator has these types generated with the client
250
320
`${ prismaImport } /runtime/library` ;
0 commit comments