Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/module/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async function loadAuthOptions(context: SchemaContext) {
.filter(([, value]) => typeof value === 'string')
.map(([key, value]) => [key, value as string]),
)
const userConfig = await loadUserAuthConfig(configFile, isProduction, alias, context.nuxt.options.runtimeConfig)
const userConfig = await loadUserAuthConfig(configFile, isProduction, alias, context.nuxt.options.runtimeConfig, context.nuxt.options.rootDir)

const extendedConfig: { plugins?: BetterAuthPlugin[] } = {}
await context.nuxt.callHook('better-auth:config:extend', extendedConfig)
Expand Down
15 changes: 15 additions & 0 deletions src/schema-generator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { BetterAuthOptions } from 'better-auth'
import type { Casing } from 'drizzle-orm/utils'
import { existsSync } from 'node:fs'
import { generateDrizzleSchema as _generateDrizzleSchema } from '@better-auth/cli/api'
import { consola } from 'consola'
import { join } from 'pathe'

export interface SchemaOptions { usePlural?: boolean, useUuid?: boolean, casing?: Casing }

Expand Down Expand Up @@ -59,6 +61,17 @@ interface SchemaGeneratorGlobals {
defineServerAuth?: RuntimeDefineServerAuthFn
}

function loadLocalEnv(rootDir?: string): void {
if (!rootDir)
return

const envPath = join(rootDir, '.env.local')
if (!existsSync(envPath))
return

process.loadEnvFile(envPath)
}

declare global {
// eslint-disable-next-line vars-on-top
var __nuxtBetterAuthDefineServerAuth: RuntimeDefineServerAuthFn | undefined
Expand All @@ -69,6 +82,7 @@ export async function loadUserAuthConfig(
throwOnError = false,
alias?: Record<string, string>,
runtimeConfig: unknown = {},
rootDir?: string,
): Promise<Partial<BetterAuthOptions>> {
const { createJiti } = await import('jiti')
const { defineServerAuth: runtimeDefineServerAuth } = await import('./runtime/config')
Expand All @@ -85,6 +99,7 @@ export async function loadUserAuthConfig(
schemaGlobals.__nuxtBetterAuthDefineServerAuth!._count++

try {
loadLocalEnv(rootDir)
const mod = await jiti.import(configPath) as { default?: unknown }
const configFn = mod.default
if (typeof configFn === 'function') {
Expand Down
24 changes: 24 additions & 0 deletions test/schema-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,30 @@ describe('loadUserAuthConfig', () => {

expect(result).toEqual({ appName: '/auth/sign-up' })
})

it('loads .env.local before importing auth config dependencies', async () => {
const envPath = join(TEST_DIR, '.env.local')
const helperPath = join(TEST_DIR, 'env-helper.ts')
const configPath = join(TEST_DIR, 'env-config.ts')
const originalApiKey = process.env.RESEND_API_KEY
delete process.env.RESEND_API_KEY

try {
writeFileSync(envPath, 'RESEND_API_KEY=re_test_fixture\n')
writeFileSync(helperPath, `if (!process.env.RESEND_API_KEY)\n throw new Error('Missing API key. Pass it to the constructor new Resend("re_123")')\n\nexport function getPlugins() { return [] }\n`)
writeFileSync(configPath, `import { getPlugins } from './env-helper'\nexport default defineServerAuth({ plugins: getPlugins() })`)

const result = await loadUserAuthConfig(configPath, true, undefined, {}, TEST_DIR)

expect(result).toEqual({ plugins: [] })
}
finally {
if (originalApiKey === undefined)
delete process.env.RESEND_API_KEY
else
process.env.RESEND_API_KEY = originalApiKey
}
})
})

describe('defineServerAuth', () => {
Expand Down
Loading