Download server/src/lib/config.ts from automindy/fokemal: direct link, hf CLI and curl.
- Browser
- Download file 5.75 kB
-
https://huggingface.co/spaces/automindy/fokemal/resolve/main/server/src/lib/config.ts
- Command line
-
hf download hf://spaces/automindy/fokemal/server/src/lib/config.ts
-
curl -L -o config.ts https://huggingface.co/spaces/automindy/fokemal/resolve/main/server/src/lib/config.ts
5.75 kB
| const DEFAULT_RPM = 120; | |
| // JSON body ceiling for the LLM wire surfaces (/v1, /v1beta, /mcp, Ollama | |
| // /api/*). Vision requests inline base64 images (~33% inflation over the raw | |
| // bytes; google.ts alone forwards images up to 8MB, ~10.7MB in base64), so a | |
| // single-screenshot Codex turn easily clears 10MB, and history replay stacks | |
| // several of them (an 11.85MB real-world request was observed). express.json | |
| // buffers the whole body in memory (2-3x transiently during the parse), so | |
| // this also bounds the per-request spike on small containers. Anything past | |
| // the ceiling 413s before routing β no fallback, no analytics row β so it | |
| // must sit above the largest payload we expect to serve. 25MB is the balance | |
| // point: it clears the observed 11.85MB replayed session with room to spare, | |
| // while keeping the worst case survivable on the small hosts this runs on (a | |
| // Pi or a 512MB VPS β the limit is PER REQUEST, so a handful of concurrent | |
| // maximal bodies is the number that actually has to fit in RAM). Inbound | |
| // image normalization shrinks payloads ~6-10x right after the parse, so the | |
| // steady state sits far below this. Raise REQUEST_BODY_LIMIT_MB on a bigger | |
| // box if a client genuinely sends more. The dashboard/admin surface keeps its | |
| // own smaller fixed ceiling. | |
| const DEFAULT_REQUEST_BODY_LIMIT_MB = 25; | |
| function parseRateLimitRpm(): number { | |
| const raw = process.env.PROXY_RATE_LIMIT_RPM; | |
| if (raw === undefined || raw.trim() === '') return DEFAULT_RPM; | |
| const n = Number(raw); | |
| if (!Number.isFinite(n) || n < 0) return DEFAULT_RPM; | |
| return Math.floor(n); | |
| } | |
| function parseRequestBodyLimitBytes(): number { | |
| const raw = process.env.REQUEST_BODY_LIMIT_MB; | |
| if (raw === undefined || raw.trim() === '') return DEFAULT_REQUEST_BODY_LIMIT_MB * 1024 * 1024; | |
| const n = Number(raw); | |
| if (!Number.isFinite(n) || n < 1) return DEFAULT_REQUEST_BODY_LIMIT_MB * 1024 * 1024; | |
| return Math.floor(n) * 1024 * 1024; | |
| } | |
| export interface Config { | |
| port: number | string; | |
| host: string; | |
| dbPath: string | null; | |
| dashboardOrigins: string[]; | |
| clientDist: string | null; | |
| proxyRateLimitRpm: number; | |
| /** JSON body limit (bytes) for the LLM wire surfaces β see | |
| * parseRequestBodyLimitBytes. REQUEST_BODY_LIMIT_MB overrides. */ | |
| requestBodyLimitBytes: number; | |
| nodeEnv: string; | |
| serveStaticAssets: boolean; | |
| /** | |
| * Express `trust proxy` setting, parsed from TRUST_PROXY (#1024). | |
| * - false: do not trust forwarded headers (default; direct callers | |
| * cannot spoof X-Forwarded-For). | |
| * - true: trust all proxies (with a security warning). | |
| * - number: trust that many hops counted from the socket peer | |
| * (Express's `trust proxy: 1` idiom for one proxy in front). | |
| * - string[]: trust only these proxy addresses/CIDRs. | |
| */ | |
| trustProxy: boolean | number | string[]; | |
| /** | |
| * Tri-state override for the CSP `upgrade-insecure-requests` directive (#682). | |
| * - undefined: auto β emit the directive only when the request arrived over | |
| * TLS (or behind an HTTPS reverse proxy that forwarded X-Forwarded-Proto). | |
| * - true: always emit (force HTTPS upgrade even on plain HTTP). | |
| * - false: never emit (let HTTP LAN installs render the dashboard). | |
| */ | |
| cspUpgradeInsecureRequests: boolean | undefined; | |
| } | |
| export function loadConfig(): Config { | |
| return { | |
| port: process.env.PORT ?? 3001, | |
| // Dual-stack ('::') by default so the dashboard is reachable over both IPv4 | |
| // and IPv6 (e.g. IPv6-enabled Docker networks β #180). Hosts with IPv6 | |
| // disabled fall back to IPv4-only below; HOST overrides the default outright. | |
| host: process.env.HOST ?? '::', | |
| dbPath: process.env.FREEAPI_DB_PATH?.trim() || null, | |
| dashboardOrigins: (process.env.DASHBOARD_ORIGINS ?? '') | |
| .split(',') | |
| .map(s => s.trim()) | |
| .filter(Boolean), | |
| clientDist: process.env.CLIENT_DIST ?? null, | |
| proxyRateLimitRpm: parseRateLimitRpm(), | |
| requestBodyLimitBytes: parseRequestBodyLimitBytes(), | |
| nodeEnv: process.env.NODE_ENV ?? 'development', | |
| serveStaticAssets: true, | |
| trustProxy: parseTrustProxy(), | |
| // CSP_UPGRADE_INSECURE_REQUESTS: true|false forces the directive on/off; | |
| // unset (the default) leaves it on auto β emit only when the request is | |
| // already TLS or forwarded as https, so HTTP LAN installs still render. | |
| cspUpgradeInsecureRequests: parseCspUpgradeInsecureRequests(), | |
| }; | |
| } | |
| // Parse TRUST_PROXY (#1024). unset/empty/false β false (do not trust forwarded | |
| // headers); true β trust all proxies; a non-negative integer β that many hops | |
| // from the socket peer (so `TRUST_PROXY=1` means "one proxy in front", the | |
| // Express idiom, not "trust everything"); otherwise a comma-separated list of | |
| // proxy addresses/CIDRs β trust only those hops. | |
| function parseTrustProxy(): boolean | number | string[] { | |
| const raw = process.env.TRUST_PROXY; | |
| if (raw === undefined || raw.trim() === '') return false; | |
| const lower = raw.trim().toLowerCase(); | |
| if (lower === 'true' || lower === 'yes') return true; | |
| if (lower === 'false' || lower === 'no') return false; | |
| if (/^\d+$/.test(lower)) { | |
| const hops = Number(lower); | |
| return hops > 0 ? hops : false; | |
| } | |
| const addrs = raw.split(',').map(s => s.trim()).filter(Boolean); | |
| return addrs.length > 0 ? addrs : false; | |
| } | |
| function parseCspUpgradeInsecureRequests(): boolean | undefined { | |
| const raw = process.env.CSP_UPGRADE_INSECURE_REQUESTS; | |
| if (raw === undefined || raw.trim() === '') return undefined; | |
| const lower = raw.trim().toLowerCase(); | |
| if (lower === 'true' || lower === '1' || lower === 'yes') return true; | |
| if (lower === 'false' || lower === '0' || lower === 'no') return false; | |
| return undefined; | |
| } | |