51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
const envSchema = z.object({
|
|
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
|
|
PORT: z.coerce.number().min(1).max(65535).default(3000),
|
|
HOST: z.string().default('0.0.0.0'),
|
|
|
|
DATABASE_URL: z.string().min(1),
|
|
REDIS_URL: z.string().min(1).default('redis://localhost:6379'),
|
|
|
|
JWT_SECRET: z.string().min(32),
|
|
JWT_ACCESS_TTL: z.string().default('15m'),
|
|
JWT_REFRESH_TTL: z.string().default('7d'),
|
|
|
|
LLM_BASE_URL: z.string().url().default('http://localhost:11434/v1'),
|
|
LLM_MODEL: z.string().default('qwen2.5:14b'),
|
|
LLM_FALLBACK_MODEL: z.string().optional(),
|
|
LLM_API_KEY: z.string().optional(),
|
|
LLM_TIMEOUT_MS: z.coerce.number().default(15000),
|
|
LLM_MAX_RETRIES: z.coerce.number().min(0).default(1),
|
|
LLM_RETRY_DELAY_MS: z.coerce.number().min(0).default(1000),
|
|
LLM_TEMPERATURE: z.coerce.number().min(0).max(2).default(0.7),
|
|
LLM_MAX_TOKENS: z.coerce.number().default(2048),
|
|
|
|
RATE_LIMIT_REGISTER: z.coerce.number().default(3),
|
|
RATE_LIMIT_FORGOT_PASSWORD: z.coerce.number().default(3),
|
|
RATE_LIMIT_VERIFY_EMAIL: z.coerce.number().default(5),
|
|
RATE_LIMIT_API_AUTHED: z.coerce.number().default(100),
|
|
RATE_LIMIT_API_GUEST: z.coerce.number().default(30),
|
|
|
|
CORS_ORIGINS: z.string().default('http://localhost:5173'),
|
|
SENTRY_DSN: z.string().optional(),
|
|
});
|
|
|
|
export type Env = z.infer<typeof envSchema>;
|
|
|
|
function parseEnv(): Env {
|
|
const result = envSchema.safeParse(process.env);
|
|
if (!result.success) {
|
|
const msg = result.error.flatten().fieldErrors;
|
|
throw new Error(`Invalid environment: ${JSON.stringify(msg)}`);
|
|
}
|
|
return result.data;
|
|
}
|
|
|
|
export const env = parseEnv();
|
|
|
|
export function getCorsOrigins(): string[] {
|
|
return env.CORS_ORIGINS.split(',').map((s) => s.trim()).filter(Boolean);
|
|
}
|