11import { invariant } from '@zenstackhq/common-helpers' ;
22import { loadDocument } from '@zenstackhq/language' ;
33import { PrismaSchemaGenerator } from '@zenstackhq/sdk' ;
4- import { generateTsSchema } from '@zenstackhq/testtools' ;
4+ import { createTestProject , generateTsSchema } from '@zenstackhq/testtools' ;
55import SQLite from 'better-sqlite3' ;
66import { execSync } from 'node:child_process' ;
77import fs from 'node:fs' ;
@@ -67,6 +67,7 @@ export type CreateTestClientOptions<Schema extends SchemaDef> = Omit<ClientOptio
6767export async function createTestClient < Schema extends SchemaDef > (
6868 schema : Schema ,
6969 options ?: CreateTestClientOptions < Schema > ,
70+ schemaFile ?: string ,
7071) : Promise < ClientContract < Schema > > ;
7172export async function createTestClient < Schema extends SchemaDef > (
7273 schema : string ,
@@ -75,35 +76,70 @@ export async function createTestClient<Schema extends SchemaDef>(
7576export async function createTestClient < Schema extends SchemaDef > (
7677 schema : Schema | string ,
7778 options ?: CreateTestClientOptions < Schema > ,
79+ schemaFile ?: string ,
7880) : Promise < any > {
7981 let workDir : string | undefined ;
8082 let _schema : Schema ;
83+ const provider = options ?. provider ?? 'sqlite' ;
8184
8285 let dbName = options ?. dbName ;
83- const provider = options ?. provider ?? 'sqlite' ;
84- if ( provider === 'sqlite' && options ?. usePrismaPush && ! dbName ) {
85- dbName = 'file:./test.db' ;
86+ if ( ! dbName ) {
87+ if ( provider === 'sqlite' ) {
88+ dbName = './test.db' ;
89+ } else {
90+ throw new Error ( `dbName is required for ${ provider } provider` ) ;
91+ }
8692 }
8793
94+ const dbUrl =
95+ provider === 'sqlite'
96+ ? `file:${ dbName } `
97+ : `postgres://${ TEST_PG_CONFIG . user } :${ TEST_PG_CONFIG . password } @${ TEST_PG_CONFIG . host } :${ TEST_PG_CONFIG . port } /${ dbName } ` ;
98+
8899 if ( typeof schema === 'string' ) {
89- const generated = await generateTsSchema ( schema , provider , dbName , options ?. extraSourceFiles ) ;
100+ const generated = await generateTsSchema ( schema , provider , dbUrl , options ?. extraSourceFiles ) ;
90101 workDir = generated . workDir ;
91- _schema = generated . schema as Schema ;
102+ // replace schema's provider
103+ _schema = {
104+ ...generated . schema ,
105+ provider : {
106+ type : provider ,
107+ } ,
108+ } as Schema ;
92109 } else {
93- _schema = schema ;
94- if ( options ?. extraSourceFiles ) {
95- throw new Error ( '`extraSourceFiles` is not supported when schema is a SchemaDef object' ) ;
110+ // replace schema's provider
111+ _schema = {
112+ ...schema ,
113+ provider : {
114+ type : provider ,
115+ } ,
116+ } ;
117+ workDir = await createTestProject ( ) ;
118+ if ( schemaFile ) {
119+ let schemaContent = fs . readFileSync ( schemaFile , 'utf-8' ) ;
120+ if ( dbUrl ) {
121+ // replace `datasource db { }` section
122+ schemaContent = schemaContent . replace (
123+ / d a t a s o u r c e \s + d b \s * { [ ^ } ] * } / m,
124+ `datasource db {
125+ provider = '${ provider } '
126+ url = '${ dbUrl } '
127+ }` ,
128+ ) ;
129+ }
130+ fs . writeFileSync ( path . join ( workDir , 'schema.zmodel' ) , schemaContent ) ;
96131 }
97132 }
98133
134+ console . log ( `Work directory: ${ workDir } ` ) ;
135+
99136 const { plugins, ...rest } = options ?? { } ;
100137 const _options : ClientOptions < Schema > = {
101138 ...rest ,
102139 } as ClientOptions < Schema > ;
103140
104141 if ( options ?. usePrismaPush ) {
105- invariant ( typeof schema === 'string' , 'schema must be a string' ) ;
106- invariant ( workDir , 'workDir is required' ) ;
142+ invariant ( typeof schema === 'string' || schemaFile , 'a schema file must be provided when using prisma db push' ) ;
107143 const r = await loadDocument ( path . resolve ( workDir , 'schema.zmodel' ) ) ;
108144 if ( ! r . success ) {
109145 throw new Error ( r . errors . join ( '\n' ) ) ;
@@ -135,7 +171,7 @@ export async function createTestClient<Schema extends SchemaDef>(
135171 } as unknown as ClientOptions < Schema > [ 'dialectConfig' ] ;
136172 } else {
137173 _options . dialectConfig = {
138- database : new SQLite ( options ?. usePrismaPush ? getDbPath ( path . join ( workDir ! , 'schema.prisma' ) ) : ':memory:' ) ,
174+ database : new SQLite ( path . join ( workDir ! , dbName ) ) ,
139175 } as unknown as ClientOptions < Schema > [ 'dialectConfig' ] ;
140176 }
141177
@@ -153,15 +189,3 @@ export async function createTestClient<Schema extends SchemaDef>(
153189
154190 return client ;
155191}
156-
157- function getDbPath ( prismaSchemaPath : string ) {
158- const content = fs . readFileSync ( prismaSchemaPath , 'utf-8' ) ;
159- const found = content . match ( / ^ \s * u r l \s * = ( \s | " ) * ( [ ^ " ] + ) ( \s | " ) * $ / m) ;
160- if ( ! found ) {
161- throw new Error ( 'No url found in prisma schema' ) ;
162- }
163- const dbPath = found [ 2 ] ! ;
164- // convert 'file:./dev.db' to './dev.db'
165- const r = path . join ( path . dirname ( prismaSchemaPath ) , dbPath . replace ( / ^ f i l e : / , '' ) ) ;
166- return r ;
167- }
0 commit comments