Files
household-bot/packages/config/src/env.ts

56 lines
2.0 KiB
TypeScript

import { createEnv } from '@t3-oss/env-core'
import { z } from 'zod'
function parseOptionalCsv(value: string | undefined): readonly string[] | undefined {
const trimmed = value?.trim()
if (!trimmed) {
return undefined
}
return trimmed
.split(',')
.map((entry) => entry.trim())
.filter(Boolean)
}
const server = {
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
DATABASE_URL: z.string().url(),
TELEGRAM_BOT_TOKEN: z.string().min(1),
TELEGRAM_WEBHOOK_SECRET: z.string().min(1),
TELEGRAM_WEBHOOK_PATH: z.string().min(1).default('/webhook/telegram'),
MINI_APP_ALLOWED_ORIGINS: z
.string()
.optional()
.transform((value) => parseOptionalCsv(value)),
SCHEDULER_OIDC_ALLOWED_EMAILS: z
.string()
.optional()
.transform((value) => parseOptionalCsv(value)),
OPENAI_API_KEY: z.string().min(1).optional(),
PURCHASE_PARSER_MODEL: z.string().min(1).default('gpt-4o-mini'),
ASSISTANT_MODEL: z.string().min(1).default('gpt-4o-mini'),
ASSISTANT_ROUTER_MODEL: z.string().min(1).default('gpt-5-nano'),
ASSISTANT_TIMEOUT_MS: z.coerce.number().int().positive().default(20000),
ASSISTANT_MEMORY_MAX_TURNS: z.coerce.number().int().positive().default(12),
ASSISTANT_RATE_LIMIT_BURST: z.coerce.number().int().positive().default(5),
ASSISTANT_RATE_LIMIT_BURST_WINDOW_MS: z.coerce.number().int().positive().default(60000),
ASSISTANT_RATE_LIMIT_ROLLING: z.coerce.number().int().positive().default(50),
ASSISTANT_RATE_LIMIT_ROLLING_WINDOW_MS: z.coerce.number().int().positive().default(86400000),
SCHEDULER_SHARED_SECRET: z.string().min(1).optional()
}
export const env = createEnv({
server,
runtimeEnv: process.env,
emptyStringAsUndefined: true,
onValidationError: (issues) => {
console.error('Invalid environment variables:')
console.error(JSON.stringify(issues, null, 2))
throw new Error('Environment validation failed')
}
})