TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { z } from 'zod';23/**4 * Server-side environment. Loaded lazily so browser bundles never import it.5 * Secrets are never logged (see logger redaction) and never exposed to the client.6 */7const EnvSchema = z.object({8 DATABASE_URL: z.string().default('postgres://localhost:5432/rareindex'),9 FIRECRAWL_API_KEY: z.string().optional(),10 SCRAPFLY_API_KEY: z.string().optional(),11 ANTHROPIC_API_KEY: z.string().optional(),12 OPENAI_API_KEY: z.string().optional(),13 LOCAL_LLM_BASE_URL: z.string().optional(),14 LOCAL_LLM_API_KEY: z.string().optional(),15 POKEMONTCG_API_KEY: z.string().optional(),16 NEXT_PUBLIC_SITE_URL: z.string().default('http://localhost:3000'),17 SESSION_SECRET: z.string().default('dev-only-session-secret-change-me-please'),18 ADMIN_TOKEN: z.string().optional(),19 API_PORT: z.coerce.number().default(8211),20 WEB_PORT: z.coerce.number().default(8210),21 WORKER_CONCURRENCY: z.coerce.number().default(4),22 LOG_LEVEL: z.string().default('info'),23 NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),24 RI_DATA_DIR: z.string().default('./data'),25});2627export type Env = z.infer<typeof EnvSchema>;2829let cached: Env | null = null;30export function env(): Env {31 if (!cached) cached = EnvSchema.parse(process.env);32 return cached;33}3435export function isProduction(): boolean {36 return env().NODE_ENV === 'production';37}38