SPB Git

spb/autoscholar

Public
1.8 KB · 41 lines typescript
1import { z } from "zod";23const Env = z.object({4  NODE_ENV: z.enum(["development", "production", "test"]).default("development"),5  APP_BASE_URL: z.string().url().default("http://localhost:8470"),6  DATABASE_URL: z.string().min(1),7  ARTIFACT_ROOT: z.string().min(1).default("./data/artifacts"),8  SESSION_SECRET: z.string().min(32, "SESSION_SECRET must be at least 32 characters"),9  ADMIN_BOOTSTRAP_USERNAME: z.string().min(1).default("admin"),10  ADMIN_BOOTSTRAP_PASSWORD: z.string().optional(),11  WORKER_ENROLLMENT_SECRET: z.string().min(16).optional(),12  INTERNAL_API_ALLOWED_CIDRS: z.string().default("127.0.0.1/32,::1/128,192.168.2.0/24"),13  TRUST_PROXY: z.coerce.number().int().min(0).max(1).default(0),14  LOG_LEVEL: z.string().default("info"),15  SCHEDULER_TICK_MS: z.coerce.number().int().min(500).default(5000),16  LEASE_TTL_SECONDS: z.coerce.number().int().min(30).default(120),17  DEFAULT_MAX_BUDGET_USD: z.coerce.number().positive().default(25),18  DEFAULT_MAX_RUNTIME_MINUTES: z.coerce.number().int().positive().default(240),19  PUBLISHING_ENABLED: z.coerce.number().int().min(0).max(1).default(1),20  DISPATCH_ENABLED: z.coerce.number().int().min(0).max(1).default(1),21  STAGING_MODE: z.coerce.number().int().min(0).max(1).default(0),22  ANTHROPIC_MODEL: z.string().default("claude-opus-5-5"),23  ANTHROPIC_REVIEWER_MODEL: z.string().default("claude-opus-5-5"),24});25export type Env = z.infer<typeof Env>;2627let cached: Env | undefined;28export function getEnv(): Env {29  if (cached) return cached;30  const parsed = Env.safeParse(process.env);31  if (!parsed.success) {32    const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");33    throw new Error(`invalid environment: ${msg}`);34  }35  cached = parsed.data;36  return cached;37}38export function resetEnvCache(): void {39  cached = undefined;40}41
Files · c27002badbd32682d76a437e46e69e520c90e8fe
Menu

Theme