11import { mkdir , writeFile } from 'node:fs/promises'
22import { defu } from 'defu'
33import { join } from 'pathe'
4- import { ensureDependencyInstalled } from 'nypm'
5- import { addServerImportsDir , addServerScanDir , logger } from '@nuxt/kit'
4+ import { addServerImportsDir , addServerScanDir , addServerTemplate , addTypeTemplate , logger } from '@nuxt/kit'
65import { copyDatabaseMigrationsToHubDir , copyDatabaseQueriesToHubDir } from '../runtime/database/server/utils/migrations/helpers'
76import { logWhenReady } from '../features'
87import { resolve } from '../module'
@@ -14,7 +13,7 @@ import type { HubConfig } from '../features'
1413
1514const log = logger . withTag ( 'nuxt:hub' )
1615
17- export async function setupDatabase ( nuxt : Nuxt , hub : HubConfig ) {
16+ export async function setupDatabase ( nuxt : Nuxt , hub : HubConfig , deps : Record < string , string > ) {
1817 // Configure dev storage
1918 if ( typeof hub . database === 'string' && ! [ 'postgresql' , 'sqlite' , 'mysql' ] . includes ( hub . database ) ) {
2019 return logWhenReady ( nuxt , `Unknown database dialect set in hub.database: ${ hub . database } ` , 'error' )
@@ -104,7 +103,8 @@ export async function setupDatabase(nuxt: Nuxt, hub: HubConfig) {
104103 path : join ( hub . dir ! , 'database/sqlite/db.sqlite3' )
105104 }
106105 }
107- } else if ( dialect === 'mysql' ) {
106+ await mkdir ( join ( hub . dir ! , 'database/sqlite' ) , { recursive : true } )
107+ } else if ( dialect === 'mysql' ) {
108108 if ( ! nuxt . options . nitro . devDatabase ?. db ?. connector ) {
109109 logWhenReady ( nuxt , '`hubDatabase()` configured with `MySQL` during local development is not supported yet. Please manually configure your development database in `nitro.devDatabase.db` in `nuxt.config.ts`. Learn more at https://hub.nuxt.com/docs/features/database.' , 'warn' )
110110 }
@@ -115,14 +115,14 @@ export async function setupDatabase(nuxt: Nuxt, hub: HubConfig) {
115115
116116 // Verify development database dependencies are installed
117117 const developmentDriver = nuxt . options . nitro . devDatabase ?. db ?. connector as ConnectorName
118- if ( developmentDriver === 'postgresql' ) {
119- await ensureDependencyInstalled ( 'pg ')
120- } else if ( developmentDriver === 'pglite' ) {
121- await ensureDependencyInstalled ( ' @electric-sql/pglite')
122- } else if ( developmentDriver === 'mysql2' ) {
123- await ensureDependencyInstalled ( ' mysql2')
124- } else if ( developmentDriver === 'better-sqlite3' ) {
125- await ensureDependencyInstalled ( ' better-sqlite3')
118+ if ( developmentDriver === 'postgresql' && ! deps . pg ) {
119+ logWhenReady ( nuxt , 'Please run `npx nypm i pg` to use PostgreSQL as database.' , 'error ')
120+ } else if ( developmentDriver === 'pglite' && ! deps [ '@electric-sql/pglite' ] ) {
121+ logWhenReady ( nuxt , 'Please run `npx nypm i @electric-sql/pglite` to use PGlite as database.' , 'error ')
122+ } else if ( developmentDriver === 'mysql2' && ! deps . mysql2 ) {
123+ logWhenReady ( nuxt , 'Please run `npx nypm i mysql2` to use MySQL as database.' , 'error ')
124+ } else if ( developmentDriver === 'better-sqlite3' && ! deps [ 'better-sqlite3' ] ) {
125+ logWhenReady ( nuxt , 'Please run `npx nypm i better-sqlite3` to use SQLite as database.' , 'error ')
126126 }
127127
128128 // Enable Nitro database
@@ -145,22 +145,14 @@ export async function setupDatabase(nuxt: Nuxt, hub: HubConfig) {
145145 } )
146146
147147 // Setup Drizzle ORM
148- let isDrizzleOrmInstalled = false
149- try {
150- require . resolve ( 'drizzle-orm' , { paths : [ nuxt . options . rootDir ] } )
151- isDrizzleOrmInstalled = true
152- } catch {
153- // Ignore
154- }
155-
156- if ( isDrizzleOrmInstalled ) {
148+ if ( deps [ 'drizzle-orm' ] ) {
157149 const connector = nuxt . options . nitro . devDatabase . db . connector as ConnectorName
158150 const dbConfig = nuxt . options . nitro . devDatabase . db . options
159151
160152 // @ts -expect-error not all connectors are supported
161153 const db0ToDrizzle : Record < ConnectorName , string > = {
162154 postgresql : 'node-postgres' ,
163- pglite : 'pglite ' ,
155+ pglite : 'pg-proxy ' ,
164156 mysql2 : 'mysql2' ,
165157 planetscale : 'planetscale-serverless' ,
166158 'better-sqlite3' : 'better-sqlite3' ,
@@ -180,23 +172,29 @@ export async function setupDatabase(nuxt: Nuxt, hub: HubConfig) {
180172 let connectionConfig = dbConfig
181173 if ( connector === 'postgresql' && dbConfig ?. url ) {
182174 connectionConfig = { connectionString : dbConfig . url , ...dbConfig . options }
175+ } else if ( connector === 'better-sqlite3' && dbConfig ?. path ) {
176+ connectionConfig = { source : dbConfig . path , ...dbConfig . options }
183177 }
184178
185179 let drizzleOrmContent = `import { drizzle } from 'drizzle-orm/${ db0ToDrizzle [ connector ] } '
186- import type { DrizzleConfig } from 'drizzle-orm'
187180
188- export function hubDrizzle<TSchema extends Record<string, unknown> = Record<string, never>> (options?: DrizzleConfig<TSchema> ) {
181+ export function hubDrizzle(options) {
189182 return drizzle({
190183 ...options,
191184 connection: ${ JSON . stringify ( connectionConfig ) }
192185 })
193186}`
187+ const drizzleOrmTypes = `import type { DrizzleConfig } from 'drizzle-orm'
188+ import { drizzle } from 'drizzle-orm/${ db0ToDrizzle [ connector ] } '
189+
190+ declare module '#hub/drizzle-orm' {
191+ export function hubDrizzle<TSchema extends Record<string, unknown> = Record<string, never>>(options?: DrizzleConfig<TSchema>): ReturnType<typeof drizzle<TSchema>>
192+ }`
194193
195194 if ( connector === 'pglite' ) {
196195 drizzleOrmContent = `import { drizzle } from 'drizzle-orm/pg-proxy'
197- import type { DrizzleConfig } from 'drizzle-orm'
198196
199- export function hubDrizzle<TSchema extends Record<string, unknown> = Record<string, never>> (options?: DrizzleConfig<TSchema> ) {
197+ export function hubDrizzle(options) {
200198 return drizzle(async (sql, params, method) => {
201199 try {
202200 const rows = await $fetch<any[]>('/api/_hub/database/query', { method: 'POST', body: { sql, params, method } })
@@ -211,18 +209,19 @@ export function hubDrizzle<TSchema extends Record<string, unknown> = Record<stri
211209}`
212210 }
213211
214- // create hub directory in .nuxt if it doesn't exist
215- const hubBuildDir = join ( nuxt . options . buildDir , 'hub' )
216- await mkdir ( hubBuildDir , { recursive : true } )
217-
218- const drizzleOrmPath = join ( hubBuildDir , 'drizzle-orm.ts' )
219- await writeFile ( drizzleOrmPath , drizzleOrmContent , 'utf-8' )
220-
221- nuxt . options . alias [ '#hub/drizzle-orm' ] = drizzleOrmPath
212+ addServerTemplate ( {
213+ filename : '#hub/drizzle-orm' ,
214+ getContents : ( ) => drizzleOrmContent
215+ } )
216+ addTypeTemplate ( {
217+ filename : 'types/hub/drizzle-orm.d.ts' ,
218+ getContents : ( ) => drizzleOrmTypes
219+ } )
220+ addServerImportsDir ( resolve ( 'runtime/database/server/drizzle-utils' ) )
222221 }
223222}
224223
225- export async function setupProductionDatabase ( nitro : Nitro , hub : HubConfig ) {
224+ export async function setupProductionDatabase ( nitro : Nitro , hub : HubConfig , deps : Record < string , string > ) {
226225 const preset = nitro . options . preset
227226 if ( ! preset ) return
228227
@@ -238,7 +237,6 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig) {
238237
239238 switch ( preset ) {
240239 // Does your favourite cloud provider require special configuration? Feel free to open a PR to add zero-config support for other presets
241-
242240 case 'vercel' : {
243241 if ( dialect === true || dialect === 'postgresql' ) {
244242 databaseConfig = {
@@ -347,19 +345,6 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig) {
347345 }
348346
349347 if ( databaseConfig ! ) {
350- // check if connector dependencies are installed
351- switch ( databaseConfig . connector ) {
352- case 'postgresql' :
353- await ensureDependencyInstalled ( 'pg' )
354- break
355- case 'better-sqlite3' :
356- await ensureDependencyInstalled ( 'better-sqlite3' )
357- break
358- case 'mysql2' :
359- await ensureDependencyInstalled ( 'mysql2' )
360- break
361- }
362-
363348 // set connector
364349 // @ts -expect-error temporarily set to empty object
365350 nitro . options . database ||= { }
0 commit comments