import { createEnv } from "@t3-oss/env-core"; import { z } from "zod"; const redisConnectionRegex = /^((?.*?):(?.*?)@)?(?.*?):(?\d+)$/; export const env = createEnv({ server: { IS_PROD: z .boolean() .default(false) .transform( () => process.env.BUN_ENV === "production" || process.env.NODE_ENV === "production", ), IS_DEV: z .boolean() .default(false) .transform( () => process.env.BUN_ENV === "development" || process.env.NODE_ENV === "development", ), VERSION: z.string().min(1).default("development"), PORT: z.coerce.number().default(3001), REDIS_CONNECTION: z.string().regex(redisConnectionRegex), PRIMARY_API_KEY: process.env.NODE_ENV === "development" ? z.string().optional() : z.string().min(10), SECONDARY_API_KEY: process.env.NODE_ENV === "development" ? z.string().optional() : z.string().min(10), SENTRY_DSN: z.string().min(1).optional(), SENTRY_ENVIRONMENT: z .enum(["development", "test", "stage", "pre-prod", "production"]) .default("development"), SENTRY_ENABLED: z .string() .refine((s) => s === "true" || s === "false") .transform((s) => s === "true"), SENTRY_TRACE_SAMPLE_RATE: z.coerce.number().default(0.001), SCAN_BATCH_SIZE: z.coerce.number().default(2000), }, createFinalSchema: (shape) => { return z.object(shape).transform((env, ctx) => { if (env.SENTRY_ENABLED && !env.SENTRY_DSN) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "SENTRY_DSN is required when SENTRY_ENABLED is true", }); return z.NEVER; } return { ...env, SENTRY_ENABLED: env.SENTRY_ENABLED && !!env.SENTRY_DSN, }; }); }, runtimeEnv: { ...process.env, }, }); const redisMatch = env.REDIS_CONNECTION.match(redisConnectionRegex); if (!redisMatch?.groups) { throw new Error("Invalid REDIS_CONNECTION format"); } export const redisConfig = { host: redisMatch.groups.host, port: Number(redisMatch.groups.port), username: redisMatch.groups.username, password: redisMatch.groups.password, };