123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import "../src/plugins/dotenv.js";
- import { z } from "zod";
- // Функция для обязательных строковых переменных
- const requiredString = (envVar: string, defaultValue?: string) => {
- return z.preprocess(
- (val) => {
- if (typeof val !== "string" || val.trim() === "") {
- if (defaultValue !== undefined) return defaultValue;
- return z.NEVER;
- }
- return val.trim();
- },
- z
- .string()
- .min(
- 1,
- `${envVar} не определен. Пожалуйста, задайте переменную в файле ${process.env.NODE_ENV === "production" ? ".env" : ".dev.env"} или переменных окружения.`,
- ),
- );
- };
- // Функция для обязательных числовых переменных
- const requiredNumber = (envVar: string, defaultValue?: number) => {
- return z.preprocess(
- (val) => {
- if (val === undefined || val === null || val === "") {
- if (defaultValue !== undefined) return defaultValue;
- return z.NEVER;
- }
- // Если значение передано не строкой и не числом — ошибка
- if (typeof val !== "string" && typeof val !== "number") {
- return z.NEVER;
- }
- const parsed = Number(val);
- if (!isFinite(parsed)) {
- return z.NEVER;
- }
- return parsed;
- },
- z.number().min(1, `${envVar} должен быть числом. Например: 5432.`),
- );
- };
- // Описание схемы переменных окружения
- const ConfigSchema = z.object({
- PORT: requiredNumber("PORT", 3000),
- LOGS_LEVEL: z
- .enum(["error", "warn", "info", "verbose", "debug", "silly"])
- .default("info"),
- API_URL: requiredString("API_URL"),
- // DB
- DB_USER: requiredString("DB_USER"),
- DB_HOST: requiredString("DB_HOST"),
- DB_PORT: requiredNumber("DB_PORT"),
- DB_NAME: requiredString("DB_NAME"),
- DB_PASS: requiredString("DB_PASS"),
- // MAIL
- SMTP_HOST: requiredString("SMTP_HOST"),
- SMTP_PORT: requiredNumber("SMTP_PORT"),
- SMTP_USER: requiredString("SMTP_USER"),
- SMTP_PASS: requiredString("SMTP_PASS"),
- // AUTH
- JWT_ACCESS_SECRET: requiredString("JWT_ACCESS_SECRET"),
- JWT_REFRESH_SECRET: requiredString("JWT_REFRESH_SECRET"),
- PASSWORD_MAX_TRIES: requiredNumber("PASSWORD_MAX_TRIES", 5),
- ACCESS_TOKEN_LIFETIME_MINS: requiredNumber("ACCESS_TOKEN_LIFETIME_MINS", 15),
- REFRESH_TOKEN_LIFETIME_DAYS: requiredNumber("REFRESH_TOKEN_LIFETIME_DAYS", 7),
- // CONFIRM PINS
- CONFIRM_PIN_LIFETIME_MINS: requiredNumber("CONFIRM_PIN_LIFETIME_MINS", 10),
- CONFIRM_PIN_MAX_TRIES: requiredNumber("CONFIRM_PIN_MAX_TRIES", 3),
- });
- // Проверяем валидность конфигурации
- const result = ConfigSchema.safeParse(process.env);
- if (!result.success) {
- console.error(
- "❌ Невалидные переменные окружения:\n",
- JSON.stringify(result.error.format(), null, 2),
- );
- process.exit(1);
- }
- export const config = result.data;
- // Экспорт типа конфигурации
- export type Config = z.infer<typeof ConfigSchema>;
- // Логируем успешную валидацию без чувствительных данных
- const safeConfig = {
- ...config,
- DB_PASS: "********",
- SMTP_PASS: "********",
- JWT_ACCESS_SECRET: "********",
- JWT_REFRESH_SECRET: "********",
- };
- console.debug("✅ Валидация env прошла успешно:", safeConfig);
|