You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.9 KiB
104 lines
3.9 KiB
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
import '../core/exceptions/invalid_environment_exception.dart';
|
|
import 'app_config.dart';
|
|
import '../data/firebase/models/firebase_config.dart';
|
|
|
|
/// Loads application configuration based on the specified environment.
|
|
///
|
|
/// This class provides a factory method to load configuration for either
|
|
/// 'dev' or 'prod' environments. It throws [InvalidEnvironmentException]
|
|
/// if an invalid environment is provided.
|
|
class ConfigLoader {
|
|
/// Private constructor to prevent instantiation.
|
|
ConfigLoader._();
|
|
|
|
/// Loads configuration for the specified environment.
|
|
///
|
|
/// Reads from .env file if available, falls back to hardcoded defaults.
|
|
///
|
|
/// [environment] - The environment to load ('dev' or 'prod').
|
|
///
|
|
/// Returns an [AppConfig] instance for the specified environment.
|
|
///
|
|
/// Throws [InvalidEnvironmentException] if [environment] is not 'dev' or 'prod'.
|
|
static AppConfig load(String environment) {
|
|
final env = environment.toLowerCase();
|
|
|
|
// Helper to get env var or fallback to default
|
|
// Handles case where dotenv is not initialized (e.g., in tests)
|
|
String getEnv(String key, String defaultValue) {
|
|
try {
|
|
return dotenv.env[key] ?? defaultValue;
|
|
} catch (e) {
|
|
// dotenv not initialized, use default
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
// Helper to parse boolean from env
|
|
bool getBoolEnv(String key, bool defaultValue) {
|
|
try {
|
|
final value = dotenv.env[key];
|
|
if (value == null) return defaultValue;
|
|
return value.toLowerCase() == 'true';
|
|
} catch (e) {
|
|
// dotenv not initialized, use default
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
// Helper to parse comma-separated list from env
|
|
List<String> getListEnv(String key, List<String> defaultValue) {
|
|
try {
|
|
final value = dotenv.env[key];
|
|
if (value == null || value.isEmpty) return defaultValue;
|
|
return value.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty).toList();
|
|
} catch (e) {
|
|
// dotenv not initialized, use default
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
// Helper to create FirebaseConfig from environment variables
|
|
FirebaseConfig createFirebaseConfig() {
|
|
return FirebaseConfig(
|
|
enabled: getBoolEnv('FIREBASE_ENABLED', false),
|
|
firestoreEnabled: getBoolEnv('FIREBASE_FIRESTORE_ENABLED', true),
|
|
storageEnabled: getBoolEnv('FIREBASE_STORAGE_ENABLED', true),
|
|
authEnabled: getBoolEnv('FIREBASE_AUTH_ENABLED', true),
|
|
messagingEnabled: getBoolEnv('FIREBASE_MESSAGING_ENABLED', true),
|
|
analyticsEnabled: getBoolEnv('FIREBASE_ANALYTICS_ENABLED', true),
|
|
);
|
|
}
|
|
|
|
switch (env) {
|
|
case 'dev':
|
|
return AppConfig(
|
|
apiBaseUrl: getEnv('API_BASE_URL_DEV', 'https://api-dev.example.com'),
|
|
enableLogging: getBoolEnv('ENABLE_LOGGING_DEV', true),
|
|
immichBaseUrl: getEnv('IMMICH_BASE_URL', 'https://photos.satoshinakamoto.win'),
|
|
immichApiKey: getEnv('IMMICH_API_KEY_DEV', 'your-dev-api-key-here'),
|
|
nostrRelays: getListEnv('NOSTR_RELAYS_DEV', [
|
|
'wss://nostrum.satoshinakamoto.win',
|
|
'wss://nos.lol',
|
|
]),
|
|
firebaseConfig: createFirebaseConfig(),
|
|
);
|
|
case 'prod':
|
|
return AppConfig(
|
|
apiBaseUrl: getEnv('API_BASE_URL_PROD', 'https://api.example.com'),
|
|
enableLogging: getBoolEnv('ENABLE_LOGGING_PROD', false),
|
|
immichBaseUrl: getEnv('IMMICH_BASE_URL', 'https://photos.satoshinakamoto.win'),
|
|
immichApiKey: getEnv('IMMICH_API_KEY_PROD', 'your-prod-api-key-here'),
|
|
nostrRelays: getListEnv('NOSTR_RELAYS_PROD', [
|
|
'wss://relay.damus.io',
|
|
]),
|
|
firebaseConfig: createFirebaseConfig(),
|
|
);
|
|
default:
|
|
throw InvalidEnvironmentException(environment);
|
|
}
|
|
}
|
|
}
|
|
|