@@ -14,6 +14,7 @@ import {
1414import { DataModel , DataModelFieldType , Model , isEnum , isTypeDef } from '@zenstackhq/sdk/ast' ;
1515import { getPrismaClientImportSpec , supportCreateMany , type DMMF } from '@zenstackhq/sdk/prisma' ;
1616import { paramCase } from 'change-case' ;
17+ import fs from 'fs' ;
1718import { lowerCaseFirst } from 'lower-case-first' ;
1819import path from 'path' ;
1920import { Project , SourceFile , VariableDeclarationKind } from 'ts-morph' ;
@@ -45,6 +46,14 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
4546 outDir = resolvePath ( outDir , options ) ;
4647 ensureEmptyDir ( outDir ) ;
4748
49+ if ( options . portable && typeof options . portable !== 'boolean' ) {
50+ throw new PluginError (
51+ name ,
52+ `Invalid value for "portable" option: ${ options . portable } , a boolean value is expected`
53+ ) ;
54+ }
55+ const portable = options . portable ?? false ;
56+
4857 await generateModelMeta ( project , models , typeDefs , {
4958 output : path . join ( outDir , '__model_meta.ts' ) ,
5059 generateAttributes : false ,
@@ -61,6 +70,10 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
6170 generateModelHooks ( target , version , project , outDir , dataModel , mapping , options ) ;
6271 } ) ;
6372
73+ if ( portable ) {
74+ generateBundledTypes ( project , outDir , options ) ;
75+ }
76+
6477 await saveProject ( project ) ;
6578 return { warnings } ;
6679}
@@ -333,9 +346,7 @@ function generateModelHooks(
333346 const fileName = paramCase ( model . name ) ;
334347 const sf = project . createSourceFile ( path . join ( outDir , `${ fileName } .ts` ) , undefined , { overwrite : true } ) ;
335348
336- sf . addStatements ( '/* eslint-disable */' ) ;
337-
338- const prismaImport = getPrismaClientImportSpec ( outDir , options ) ;
349+ const prismaImport = options . portable ? './__types' : getPrismaClientImportSpec ( outDir , options ) ;
339350 sf . addImportDeclaration ( {
340351 namedImports : [ 'Prisma' , model . name ] ,
341352 isTypeOnly : true ,
@@ -584,6 +595,7 @@ function generateIndex(
584595 sf . addStatements ( `export { SvelteQueryContextKey, setHooksContext } from '${ runtimeImportBase } /svelte';` ) ;
585596 break ;
586597 }
598+ sf . addStatements ( `export { default as metadata } from './__model_meta';` ) ;
587599}
588600
589601function makeGetContext ( target : TargetFramework ) {
@@ -724,3 +736,21 @@ function makeMutationOptions(target: string, returnType: string, argsType: strin
724736function makeRuntimeImportBase ( version : TanStackVersion ) {
725737 return `@zenstackhq/tanstack-query/runtime${ version === 'v5' ? '-v5' : '' } ` ;
726738}
739+
740+ function generateBundledTypes ( project : Project , outDir : string , options : PluginOptions ) {
741+ if ( ! options . prismaClientDtsPath ) {
742+ throw new PluginError ( name , `Unable to determine the location of PrismaClient types` ) ;
743+ }
744+
745+ // copy PrismaClient index.d.ts
746+ const content = fs . readFileSync ( options . prismaClientDtsPath , 'utf-8' ) ;
747+ project . createSourceFile ( path . join ( outDir , '__types.d.ts' ) , content , { overwrite : true } ) ;
748+
749+ // "runtime/library.d.ts" is referenced by Prisma's DTS, and it's generated into Prisma's output
750+ // folder if a custom output is specified; if not, it's referenced from '@prisma/client'
751+ const libraryDts = path . join ( path . dirname ( options . prismaClientDtsPath ) , 'runtime' , 'library.d.ts' ) ;
752+ if ( fs . existsSync ( libraryDts ) ) {
753+ const content = fs . readFileSync ( libraryDts , 'utf-8' ) ;
754+ project . createSourceFile ( path . join ( outDir , 'runtime' , 'library.d.ts' ) , content , { overwrite : true } ) ;
755+ }
756+ }
0 commit comments