"use strict"; require("dotenv").config({ quiet: true }); const { z } = require("zod"); function intFromEnv(name, fallback) { const raw = process.env[name]; if (!raw) { return fallback; } const parsed = Number.parseInt(raw, 10); return Number.isInteger(parsed) ? parsed : fallback; } function strFromEnv(name, fallback) { const raw = process.env[name]; return raw && String(raw).trim() ? String(raw).trim() : fallback; } const parsed = { port: intFromEnv("PORT", 3000), stateFilePath: strFromEnv("STATE_FILE_PATH", "./data/state.json"), logLevel: strFromEnv("LOG_LEVEL", "info"), xWebhookSecret: process.env.X_WEBHOOK_SECRET || "dev-x-secret", polarWebhookSecret: process.env.POLAR_WEBHOOK_SECRET || "dev-polar-secret", rateLimits: { webhookPerMinute: intFromEnv("WEBHOOK_RPM", 120), authPerMinute: intFromEnv("AUTH_RPM", 30), actionPerMinute: intFromEnv("ACTION_RPM", 60), }, credit: { baseCredits: intFromEnv("BASE_CREDITS", 1), includedChars: intFromEnv("INCLUDED_CHARS", 25000), stepChars: intFromEnv("STEP_CHARS", 10000), stepCredits: intFromEnv("STEP_CREDITS", 1), maxCharsPerArticle: intFromEnv("MAX_CHARS_PER_ARTICLE", 120000), }, }; const ConfigSchema = z.object({ port: z.number().int().positive(), stateFilePath: z.string().min(1), logLevel: z.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]), xWebhookSecret: z.string().min(1), polarWebhookSecret: z.string().min(1), rateLimits: z.object({ webhookPerMinute: z.number().int().positive(), authPerMinute: z.number().int().positive(), actionPerMinute: z.number().int().positive(), }), credit: z.object({ baseCredits: z.number().int().positive(), includedChars: z.number().int().positive(), stepChars: z.number().int().positive(), stepCredits: z.number().int().positive(), maxCharsPerArticle: z.number().int().positive(), }), }); const config = ConfigSchema.parse(parsed); module.exports = { config, };