143 lines
7.7 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.env = void 0;
const dotenv_1 = __importDefault(require("dotenv"));
const zod_1 = require("zod");
dotenv_1.default.config();
const envSchema = zod_1.z.object({
// Server
NODE_ENV: zod_1.z.enum(['development', 'production', 'test']).default('development'),
PORT: zod_1.z.coerce.number().default(4000),
API_URL: zod_1.z.string().default('http://localhost:4000'),
ADMIN_URL: zod_1.z.string().default('http://localhost:3000'),
DOMAIN: zod_1.z.string().default('cmlite.org'),
// Database
DATABASE_URL: zod_1.z.string(),
// Redis
REDIS_URL: zod_1.z.string().default('redis://redis-changemaker:6379'),
// JWT
JWT_ACCESS_SECRET: zod_1.z.string().min(32),
JWT_REFRESH_SECRET: zod_1.z.string().min(32),
JWT_ACCESS_EXPIRY: zod_1.z.string().default('15m'),
JWT_REFRESH_EXPIRY: zod_1.z.string().default('7d'),
// Encryption (for DB-stored secrets like SMTP password; falls back to JWT_ACCESS_SECRET)
ENCRYPTION_KEY: zod_1.z.string().optional(),
// Initial Super Admin (auto-created during database seeding)
INITIAL_ADMIN_EMAIL: zod_1.z.string().email().default('admin@cmlite.org'),
INITIAL_ADMIN_PASSWORD: zod_1.z.string().min(12).default('REQUIRED_STRONG_PASSWORD_CHANGE_THIS'),
// SMTP
SMTP_HOST: zod_1.z.string().default('mailhog-changemaker'),
SMTP_PORT: zod_1.z.coerce.number().default(1025),
SMTP_USER: zod_1.z.string().default(''),
SMTP_PASS: zod_1.z.string().default(''),
SMTP_FROM: zod_1.z.string().default('noreply@cmlite.org'),
SMTP_FROM_NAME: zod_1.z.string().default('Changemaker Lite'),
EMAIL_TEST_MODE: zod_1.z.string().default('true'),
TEST_EMAIL_RECIPIENT: zod_1.z.string().default('admin@cmlite.org'),
// Listmonk
LISTMONK_URL: zod_1.z.string().default('http://listmonk-app:9000'),
LISTMONK_ADMIN_USER: zod_1.z.string().default('admin'),
LISTMONK_ADMIN_PASSWORD: zod_1.z.string().default(''),
LISTMONK_SYNC_ENABLED: zod_1.z.string().default('false'),
LISTMONK_PROXY_PORT: zod_1.z.coerce.number().default(9002),
// Represent API (Canadian electoral data)
REPRESENT_API_URL: zod_1.z.string().default('https://represent.opennorth.ca'),
// CORS
CORS_ORIGINS: zod_1.z.string().default('http://localhost:3000'),
// Rate Limiting
RATE_LIMIT_WINDOW_MS: zod_1.z.coerce.number().default(15 * 60 * 1000),
RATE_LIMIT_MAX: zod_1.z.coerce.number().default(500),
// Geocoding
MAPBOX_API_KEY: zod_1.z.string().optional(),
GEOCODING_RATE_LIMIT_MS: zod_1.z.coerce.number().default(1100),
GEOCODING_CACHE_ENABLED: zod_1.z.string().default('true'),
GEOCODING_CACHE_TTL_HOURS: zod_1.z.coerce.number().default(24),
// Phase 2: Performance & Accuracy
GOOGLE_MAPS_API_KEY: zod_1.z.string().optional(),
GOOGLE_MAPS_ENABLED: zod_1.z.string().default('false'),
GEOCODING_PARALLEL_ENABLED: zod_1.z.string().default('true'),
GEOCODING_BATCH_SIZE: zod_1.z.coerce.number().default(10),
// Bulk Re-Geocoding (Phase 3)
BULK_GEOCODE_ENABLED: zod_1.z.string().default('true'),
BULK_GEOCODE_MAX_BATCH: zod_1.z.coerce.number().default(5000),
// Platform Services (NocoDB, n8n, Gitea)
NOCODB_URL: zod_1.z.string().default('http://changemaker-v2-nocodb:8080'),
NOCODB_PORT: zod_1.z.coerce.number().default(8091),
NOCODB_EMBED_PORT: zod_1.z.coerce.number().default(8881),
N8N_URL: zod_1.z.string().default('http://n8n-changemaker:5678'),
N8N_PORT: zod_1.z.coerce.number().default(5678),
N8N_EMBED_PORT: zod_1.z.coerce.number().default(8882),
GITEA_URL: zod_1.z.string().default('http://gitea-changemaker:3000'),
GITEA_PORT: zod_1.z.coerce.number().default(3030),
GITEA_EMBED_PORT: zod_1.z.coerce.number().default(8883),
// MailHog (email testing UI)
MAILHOG_URL: zod_1.z.string().default('http://mailhog-changemaker:8025'),
MAILHOG_EMBED_PORT: zod_1.z.coerce.number().default(8884),
// Mini QR (QR code generator)
MINI_QR_URL: zod_1.z.string().default('http://mini-qr:8080'),
MINI_QR_PORT: zod_1.z.coerce.number().default(8089),
MINI_QR_EMBED_PORT: zod_1.z.coerce.number().default(8885),
// Excalidraw (collaborative whiteboard)
EXCALIDRAW_URL: zod_1.z.string().default('http://excalidraw-changemaker:80'),
EXCALIDRAW_PORT: zod_1.z.coerce.number().default(8090),
EXCALIDRAW_EMBED_PORT: zod_1.z.coerce.number().default(8886),
// Pangolin (tunnel / reverse proxy)
PANGOLIN_API_URL: zod_1.z.string()
.default('')
.refine((url) => !url || url.startsWith('https://'), { message: 'PANGOLIN_API_URL must use HTTPS for secure credential transmission' }),
PANGOLIN_API_KEY: zod_1.z.string().default(''),
PANGOLIN_ORG_ID: zod_1.z.string().default(''),
PANGOLIN_SITE_ID: zod_1.z.string().default(''),
PANGOLIN_ENDPOINT: zod_1.z.string().default(''),
PANGOLIN_NEWT_ID: zod_1.z.string().default(''),
PANGOLIN_NEWT_SECRET: zod_1.z.string().default(''),
// NAR (National Address Register)
NAR_DATA_DIR: zod_1.z.string().default('/data'),
// Media Management
ENABLE_MEDIA_FEATURES: zod_1.z.string().default('false'),
MEDIA_API_PORT: zod_1.z.coerce.number().default(4100),
MEDIA_API_PUBLIC_URL: zod_1.z.string().default('http://media-api:4100'),
MEDIA_ROOT: zod_1.z.string().default('/media/library'),
MEDIA_UPLOADS: zod_1.z.string().default('/media/uploads'),
MAX_UPLOAD_SIZE_GB: zod_1.z.coerce.number().default(10),
PUBLIC_MEDIA_PORT: zod_1.z.coerce.number().default(3100),
// Docs / Code Server
CODE_SERVER_URL: zod_1.z.string().default('http://code-server-changemaker:8080'),
CODE_SERVER_PORT: zod_1.z.coerce.number().default(8888),
MKDOCS_PREVIEW_URL: zod_1.z.string().default('http://mkdocs-changemaker:8000'),
MKDOCS_PORT: zod_1.z.coerce.number().default(4003),
MKDOCS_DOCS_PATH: zod_1.z.string().default('/mkdocs/docs'),
MKDOCS_CONFIG_PATH: zod_1.z.string().default('/mkdocs/mkdocs.yml'),
MKDOCS_CONTAINER_NAME: zod_1.z.string().default('mkdocs-changemaker'),
MKDOCS_SITE_SERVER_URL: zod_1.z.string().default('http://mkdocs-site-server-changemaker:80'),
MKDOCS_SITE_SERVER_PORT: zod_1.z.coerce.number().default(4004),
// Monitoring Services (behind 'monitoring' profile)
PROMETHEUS_URL: zod_1.z.string().default('http://prometheus-changemaker:9090'),
PROMETHEUS_PORT: zod_1.z.coerce.number().default(9090),
GRAFANA_URL: zod_1.z.string().default('http://grafana-changemaker:3000'),
GRAFANA_PORT: zod_1.z.coerce.number().default(3005),
ALERTMANAGER_URL: zod_1.z.string().default('http://alertmanager-changemaker:9093'),
ALERTMANAGER_PORT: zod_1.z.coerce.number().default(9093),
CADVISOR_URL: zod_1.z.string().default('http://cadvisor-changemaker:8080'),
CADVISOR_PORT: zod_1.z.coerce.number().default(8086),
NODE_EXPORTER_URL: zod_1.z.string().default('http://node-exporter-changemaker:9100'),
NODE_EXPORTER_PORT: zod_1.z.coerce.number().default(9100),
REDIS_EXPORTER_URL: zod_1.z.string().default('http://redis-exporter-changemaker:9121'),
REDIS_EXPORTER_PORT: zod_1.z.coerce.number().default(9121),
GOTIFY_URL: zod_1.z.string().default('http://gotify-changemaker:80'),
GOTIFY_PORT: zod_1.z.coerce.number().default(8889),
});
function validateEnv() {
const result = envSchema.safeParse(process.env);
if (!result.success) {
console.error('Invalid environment variables:');
console.error(result.error.flatten().fieldErrors);
process.exit(1);
}
return result.data;
}
exports.env = validateEnv();
//# sourceMappingURL=env.js.map