72 lines
3.9 KiB
TypeScript
72 lines
3.9 KiB
TypeScript
import 'dotenv/config';
|
|
import { z } from 'zod';
|
|
|
|
const optionalEnvironmentValue = <T extends z.ZodTypeAny>(schema: T) =>
|
|
z.preprocess((value) => value === '' ? undefined : value, schema.optional());
|
|
|
|
const environmentSchema = z.object({
|
|
API_PORT: z.coerce.number().int().positive().default(3001),
|
|
DATABASE_URL: z.string().url().default('postgres://compor:compor_local_password@localhost:5433/compor_hub'),
|
|
FRONTEND_ORIGIN: z.string().url().default('http://localhost:3000'),
|
|
APP_ENV: z.enum(['development', 'test', 'production']).default('development'),
|
|
JWT_SECRET: z.string().min(32).default('development-only-secret-change-before-production'),
|
|
SUPERADMIN_EMAIL: optionalEnvironmentValue(z.string().email()),
|
|
SUPERADMIN_PASSWORD: optionalEnvironmentValue(z.string().min(8)),
|
|
SUPERADMIN_NAME: z.string().min(1).max(120).default('Compor HUB Superadmin'),
|
|
AUTH_RATE_LIMIT_MAX: z.coerce.number().int().min(1).max(1000).default(10),
|
|
AUTH_RATE_LIMIT_WINDOW_SECONDS: z.coerce.number().int().min(60).max(86_400).default(900),
|
|
JWT_SESSION_TTL: z.string().regex(/^\d+[smhd]$/).default('7d'),
|
|
INVITATION_TTL_HOURS: z.coerce.number().int().min(1).max(24 * 90).default(24 * 7),
|
|
PASSWORD_RESET_TTL_HOURS: z.coerce.number().int().min(1).max(24 * 30).default(24),
|
|
AUDIT_LOG_PAGE_SIZE: z.coerce.number().int().min(10).max(500).default(50),
|
|
SMTP_HOST: optionalEnvironmentValue(z.string().trim().min(1).max(255)),
|
|
SMTP_PORT: optionalEnvironmentValue(z.coerce.number().int().min(1).max(65_535)),
|
|
SMTP_USER: optionalEnvironmentValue(z.string().trim().min(1).max(320)),
|
|
SMTP_PASS: optionalEnvironmentValue(z.string().min(1).max(1_000)),
|
|
MAIL_FROM: optionalEnvironmentValue(z.string().trim().min(3).max(320)),
|
|
BUNNY_STREAM_LIBRARY_ID: optionalEnvironmentValue(z.coerce.number().int().positive()),
|
|
BUNNY_STREAM_API_KEY: optionalEnvironmentValue(z.string().min(20)),
|
|
BUNNY_EMBED_TOKEN_KEY: optionalEnvironmentValue(z.string().min(20)),
|
|
BUNNY_WEBHOOK_SECRET: optionalEnvironmentValue(z.string().min(20)),
|
|
BUNNY_EMBED_TOKEN_TTL_SECONDS: z.coerce.number().int().min(60).max(86_400).default(600),
|
|
BUNNY_MAX_UPLOAD_MB: z.coerce.number().int().min(1).max(5120).default(5120),
|
|
BUNNY_STORAGE_ZONE: optionalEnvironmentValue(z.string().trim().min(1).max(120)),
|
|
BUNNY_STORAGE_PASSWORD: optionalEnvironmentValue(z.string().min(1)),
|
|
BUNNY_STORAGE_ENDPOINT: optionalEnvironmentValue(z.string().url()),
|
|
BUNNY_STORAGE_CDN_HOST: optionalEnvironmentValue(z.string().url()),
|
|
BUNNY_COVER_MAX_UPLOAD_MB: z.coerce.number().int().min(1).max(50).default(10),
|
|
BUNNY_ASSET_MAX_UPLOAD_MB: z.coerce.number().int().min(1).max(512).default(100),
|
|
});
|
|
|
|
export const config = environmentSchema.parse(process.env);
|
|
|
|
if (config.APP_ENV === 'production' && config.JWT_SECRET === 'development-only-secret-change-before-production') {
|
|
throw new Error('JWT_SECRET deve ter um valor único em produção.');
|
|
}
|
|
|
|
const bunnyConfigurationValues = [
|
|
config.BUNNY_STREAM_LIBRARY_ID,
|
|
config.BUNNY_STREAM_API_KEY,
|
|
config.BUNNY_EMBED_TOKEN_KEY,
|
|
];
|
|
|
|
if (bunnyConfigurationValues.some(Boolean) && !bunnyConfigurationValues.every(Boolean)) {
|
|
throw new Error('BUNNY_STREAM_LIBRARY_ID, BUNNY_STREAM_API_KEY e BUNNY_EMBED_TOKEN_KEY devem ser configurados juntos.');
|
|
}
|
|
|
|
const bunnyStorageConfigurationValues = [
|
|
config.BUNNY_STORAGE_ZONE,
|
|
config.BUNNY_STORAGE_PASSWORD,
|
|
config.BUNNY_STORAGE_ENDPOINT,
|
|
config.BUNNY_STORAGE_CDN_HOST,
|
|
];
|
|
|
|
if (bunnyStorageConfigurationValues.some(Boolean) && !bunnyStorageConfigurationValues.every(Boolean)) {
|
|
throw new Error('BUNNY_STORAGE_ZONE, BUNNY_STORAGE_PASSWORD, BUNNY_STORAGE_ENDPOINT e BUNNY_STORAGE_CDN_HOST devem ser configurados juntos.');
|
|
}
|
|
|
|
const smtpConfigurationValues = [config.SMTP_HOST, config.SMTP_PORT, config.SMTP_USER, config.SMTP_PASS, config.MAIL_FROM];
|
|
if (smtpConfigurationValues.some(Boolean) && !smtpConfigurationValues.every(Boolean)) {
|
|
throw new Error('SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS e MAIL_FROM devem ser configurados juntos.');
|
|
}
|