import { config } from 'dotenv'; import { existsSync } from 'node:fs'; import { homedir } from 'node:os'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { detectFromEnv, loadConfig } from '@mosaicstack/config'; type TierSource = | 'process environment' | 'daemon .env' | 'monorepo-root .env' | 'gateway-local .env' | 'default'; type BootSource = TierSource | 'mosaic.config.json'; const here = dirname(fileURLToPath(import.meta.url)); const daemonEnv = join(homedir(), '.config', 'mosaic', 'gateway', '.env'); const monorepoRootEnv = resolve(here, '../../..', '.env'); const gatewayLocalEnv = resolve(here, '..', '.env'); const inheritedTier = process.env['MOSAIC_STORAGE_TIER']; let tierSource: TierSource = inheritedTier === undefined ? 'default' : 'process environment'; const inheritedDatabaseUrl = process.env['DATABASE_URL']; let databaseUrlSource: TierSource = inheritedDatabaseUrl === undefined ? 'default' : 'process environment'; function loadAnchoredDotenv( path: string, sourceLabel: Exclude, ): void { if (!existsSync(path)) { return; } const beforeTier = process.env['MOSAIC_STORAGE_TIER']; const beforeDatabaseUrl = process.env['DATABASE_URL']; config({ path, quiet: true }); if ( beforeTier === undefined && process.env['MOSAIC_STORAGE_TIER'] !== undefined && tierSource === 'default' ) { tierSource = sourceLabel; } if ( beforeDatabaseUrl === undefined && process.env['DATABASE_URL'] !== undefined && databaseUrlSource === 'default' ) { databaseUrlSource = sourceLabel; } } // Load .env from daemon config dir (global install / daemon mode) first. // It takes precedence over file-based local-dev configuration. loadAnchoredDotenv(daemonEnv, 'daemon .env'); // Load .env from the anchored monorepo root, then fill any remaining values // from apps/gateway/.env when present. loadAnchoredDotenv(monorepoRootEnv, 'monorepo-root .env'); loadAnchoredDotenv(gatewayLocalEnv, 'gateway-local .env'); const envOnlyTier = detectFromEnv().tier; const resolvedTier = loadConfig().tier; let source: BootSource; if (resolvedTier !== envOnlyTier) { source = 'mosaic.config.json'; } else if (tierSource !== 'default') { source = tierSource; } else if (envOnlyTier === 'standalone' && databaseUrlSource !== 'default') { source = databaseUrlSource; } else { source = 'default'; } console.info(`[gateway env] storage tier=${resolvedTier} source=${source}`);