/// Runtime config from `.env`, with optional `--dart-define` overrides. library; import 'package:flutter_dotenv/flutter_dotenv.dart'; /// Loads once at startup from the `.env` asset (see `.env.example`). /// Pass `--dart-define=KEY=value` to override for CI / one-off builds. abstract final class AppConfig { static var _loaded = false; static late String apiBaseUrl; static late String pocketBaseUrl; static late String pocketBaseUsersCollection; static Future load() async { if (_loaded) return; try { await dotenv.load(fileName: '.env', isOptional: true); if (dotenv.env.isEmpty) { await dotenv.load(fileName: '.env.example', isOptional: true); } } catch (_) { // Missing asset in tests is fine — use fallbacks / loadForTest. } apiBaseUrl = _resolve( dartDefine: const String.fromEnvironment('API_BASE_URL'), envKey: 'API_BASE_URL', fallback: 'https://ingtrak.satoshinakamoto.win', ); pocketBaseUrl = _resolve( dartDefine: const String.fromEnvironment('POCKETBASE_URL'), envKey: 'POCKETBASE_URL', fallback: 'http://127.0.0.1:8090', ); pocketBaseUsersCollection = _resolve( dartDefine: const String.fromEnvironment('POCKETBASE_USERS_COLLECTION'), envKey: 'POCKETBASE_USERS_COLLECTION', fallback: 'usersapp', ); _loaded = true; } /// For widget tests that don't go through [main]. static void loadForTest({ String apiBaseUrl = 'https://ingtrak.satoshinakamoto.win', String pocketBaseUrl = 'http://127.0.0.1:8090', String pocketBaseUsersCollection = 'usersapp', }) { AppConfig.apiBaseUrl = apiBaseUrl; AppConfig.pocketBaseUrl = pocketBaseUrl; AppConfig.pocketBaseUsersCollection = pocketBaseUsersCollection; _loaded = true; } static String _resolve({ required String dartDefine, required String envKey, required String fallback, }) { if (dartDefine.isNotEmpty) return dartDefine; final fromEnv = dotenv.maybeGet(envKey)?.trim(); if (fromEnv != null && fromEnv.isNotEmpty) return fromEnv; return fallback; } }