import { createClient } from '@libsql/client'; import { hashPassword } from 'better-auth/crypto'; import { readFileSync } from 'node:fs'; import { randomUUID } from 'node:crypto'; function readDotEnv() { try { const entries = readFileSync('.env', 'utf8') .split('\n') .map((line) => line.trim()) .filter((line) => line && !line.startsWith('#')) .map((line) => { const index = line.indexOf('='); const key = line.slice(0, index); const value = line.slice(index + 1).replace(/^"|"$/g, ''); return [key, value]; }); for (const [key, value] of entries) { process.env[key] ??= value; } } catch { // .env is optional in deployed or scripted environments. } } readDotEnv(); const databaseUrl = process.env.DATABASE_URL; const email = process.env.ADMIN_EMAIL?.trim().toLowerCase(); const password = process.env.ADMIN_PASSWORD; const name = process.env.ADMIN_NAME?.trim() || 'Administrator'; const overwrite = process.env.ADMIN_OVERWRITE === '1'; if (!databaseUrl) { console.error('DATABASE_URL is required.'); process.exit(1); } if (!email || !password) { console.error('ADMIN_EMAIL and ADMIN_PASSWORD are required.'); console.error('Example: ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=change-me pnpm admin:create'); process.exit(1); } const client = createClient({ url: databaseUrl }); const now = Date.now(); const existing = await client.execute({ sql: 'select id from user where email = ? limit 1', args: [email] }); if (existing.rows.length > 0 && !overwrite) { console.error(`A user with email ${email} already exists. Set ADMIN_OVERWRITE=1 to update the password.`); process.exit(1); } const userId = existing.rows[0]?.id?.toString() ?? randomUUID(); const passwordHash = await hashPassword(password); if (existing.rows.length === 0) { await client.execute({ sql: 'insert into user (id, name, email, email_verified, image, created_at, updated_at) values (?, ?, ?, ?, ?, ?, ?)', args: [userId, name, email, 1, null, now, now] }); } else { await client.execute({ sql: 'update user set name = ?, email_verified = ?, updated_at = ? where id = ?', args: [name, 1, now, userId] }); } const account = await client.execute({ sql: 'select id from account where user_id = ? and provider_id = ? limit 1', args: [userId, 'credential'] }); if (account.rows.length === 0) { await client.execute({ sql: 'insert into account (id, account_id, provider_id, user_id, password, created_at, updated_at) values (?, ?, ?, ?, ?, ?, ?)', args: [randomUUID(), userId, 'credential', userId, passwordHash, now, now] }); } else { await client.execute({ sql: 'update account set password = ?, updated_at = ? where id = ?', args: [passwordHash, now, account.rows[0].id] }); } console.log(`Admin user ready: ${email}`);