@@ -121,9 +121,13 @@ export class EnhancerGenerator {
121121 }
122122
123123 // reexport PrismaClient types (original or fixed)
124+ const modelsTsContent = `export * from '${ resultPrismaTypeImport } ';${
125+ this . isNewPrismaClientGenerator ? '\nexport * from \'./json-fields\';' : ''
126+ } `;
127+
124128 const modelsTs = this . project . createSourceFile (
125129 path . join ( this . outDir , 'models.ts' ) ,
126- `export * from ' ${ resultPrismaTypeImport } ';` ,
130+ modelsTsContent ,
127131 { overwrite : true }
128132 ) ;
129133 this . saveSourceFile ( modelsTs ) ;
@@ -490,6 +494,20 @@ export type Enhanced<Client> =
490494 private async processClientTypesNewPrismaGenerator ( prismaClientDir : string , delegateInfo : DelegateInfo ) {
491495 const project = new Project ( ) ;
492496
497+ // Create a shared json-fields.ts file for all type definitions
498+ const jsonFieldsFile = project . createSourceFile ( path . join ( this . outDir , 'json-fields.ts' ) , undefined , {
499+ overwrite : true ,
500+ } ) ;
501+
502+ // Generate all type definitions in the shared file
503+ for ( const decl of this . model . declarations ) {
504+ if ( isTypeDef ( decl ) ) {
505+ generateTypeDefType ( jsonFieldsFile , decl ) ;
506+ }
507+ }
508+
509+ await jsonFieldsFile . save ( ) ;
510+
493511 for ( const d of this . model . declarations . filter ( isDataModel ) ) {
494512 const fileName = `${ prismaClientDir } /models/${ d . name } .ts` ;
495513 const sf = project . addSourceFileAtPath ( fileName ) ;
@@ -502,6 +520,44 @@ export type Enhanced<Client> =
502520 throw new PluginError ( name , `Unexpected syntax list structure in ${ fileName } ` ) ;
503521 }
504522
523+ // Check if $Types is used in any type aliases (before and after transformation)
524+ let needsTypesImport = false ;
525+ syntaxList . getChildren ( ) . forEach ( ( node ) => {
526+ if ( Node . isTypeAliasDeclaration ( node ) ) {
527+ // Check original type
528+ const typeText = node . getType ( ) . getText ( ) ;
529+ if ( typeText . includes ( '$Types' ) ) {
530+ needsTypesImport = true ;
531+ }
532+
533+ // Check if transformation would add $Types
534+ const structure = this . transformTypeAlias ( node , delegateInfo ) ;
535+ if ( structure . type && typeof structure . type === 'string' && structure . type . includes ( '$Types' ) ) {
536+ needsTypesImport = true ;
537+ }
538+ }
539+ } ) ;
540+
541+ // Add $Types import if needed
542+ if ( needsTypesImport ) {
543+ sfNew . addStatements ( 'import $Types = runtime.Types;' ) ;
544+ }
545+
546+ // Add import for json-fields if this model has JSON type fields
547+ const modelWithJsonFields = this . modelsWithJsonTypeFields . find ( ( m ) => m . name === d . name ) ;
548+ if ( modelWithJsonFields ) {
549+ // Get the specific types that are used in this model
550+ const getTypedJsonFields = ( model : DataModel ) => {
551+ return model . fields . filter ( ( f ) => isTypeDef ( f . type . reference ?. ref ) ) ;
552+ } ;
553+ const jsonFieldTypes = getTypedJsonFields ( modelWithJsonFields ) ;
554+ const typeNames = jsonFieldTypes . map ( field => field . type . reference ! . $refText ) ;
555+
556+ if ( typeNames . length > 0 ) {
557+ sfNew . addStatements ( `import type { ${ typeNames . join ( ', ' ) } } from "../../json-fields";` ) ;
558+ }
559+ }
560+
505561 syntaxList . getChildren ( ) . forEach ( ( node ) => {
506562 if ( Node . isInterfaceDeclaration ( node ) ) {
507563 sfNew . addInterface ( this . transformInterface ( node , delegateInfo ) ) ;
0 commit comments