/** * Platform-specific paths and environment variable configuration */ const path = require('path'); const platformPaths = require('../../platform-paths'); const CADDYFILE_PATH = process.env.CADDYFILE_PATH || platformPaths.caddyfile; const CADDY_ADMIN_URL = process.env.CADDY_ADMIN_URL || platformPaths.caddyAdminUrl; const SERVICES_FILE = process.env.SERVICES_FILE || platformPaths.servicesFile; const SERVICES_DIR = path.dirname(SERVICES_FILE); const CONFIG_FILE = process.env.CONFIG_FILE || path.join(SERVICES_DIR, 'config.json'); const DNS_CREDENTIALS_FILE = process.env.DNS_CREDENTIALS_FILE || path.join(SERVICES_DIR, 'dns-credentials.json'); const TAILSCALE_CONFIG_FILE = process.env.TAILSCALE_CONFIG_FILE || path.join(SERVICES_DIR, 'tailscale-config.json'); const NOTIFICATIONS_FILE = process.env.NOTIFICATIONS_FILE || path.join(SERVICES_DIR, 'notifications.json'); const TOTP_CONFIG_FILE = process.env.TOTP_CONFIG_FILE || path.join(SERVICES_DIR, 'totp-config.json'); const ERROR_LOG_FILE = process.env.ERROR_LOG_FILE || path.join(platformPaths.dataDir, 'error.log'); const LICENSE_SECRET_FILE = process.env.LICENSE_SECRET_FILE || path.join(platformPaths.dataDir, '.license-secret'); const BROWSE_ROOTS = (process.env.MEDIA_BROWSE_ROOTS || '') .split(',') .filter(r => r.includes('=')) .map(r => { const eqIndex = r.indexOf('='); const containerPath = r.slice(0, eqIndex).trim(); const hostPath = r.slice(eqIndex + 1).trim(); return { containerPath, hostPath }; }); module.exports = { CADDYFILE_PATH, CADDY_ADMIN_URL, SERVICES_FILE, SERVICES_DIR, // Re-export the resolved data directory so other modules (notably // src/utilities/nesting-guard.js) can locate `/app/data` without having to // also require('../../platform-paths') — keeps a single source of truth for // the data dir on the src/config/paths surface. Without this, `dataDir` // resolves to `undefined`, and `path.join(undefined, 'data')` throws // `TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type // string. Received undefined` at startup (DC-077 fingerprint). Fall back to // platformPaths.dataDir if SERVICES_DIR is somehow not a string (defensive — // SERVICES_DIR is computed from a path.dirname() of a string so it always // is, but the cost of guarding is one branch). dataDir: typeof SERVICES_DIR === 'string' && SERVICES_DIR ? SERVICES_DIR : platformPaths.dataDir, CONFIG_FILE, DNS_CREDENTIALS_FILE, TAILSCALE_CONFIG_FILE, NOTIFICATIONS_FILE, TOTP_CONFIG_FILE, ERROR_LOG_FILE, LICENSE_SECRET_FILE, BROWSE_ROOTS, };