import 'dart:convert'; /// ApiKeys는 네이버 API 인증 정보를 환경 변수로 로드한다. /// /// - `NAVER_CLIENT_ID`, `NAVER_CLIENT_SECRET`는 `flutter run`/`flutter test` /// 실행 시 `--dart-define`으로 주입한다. /// - 민감 정보는 base64(난독화) 형태로 전달하고, 런타임에서 복호화한다. class ApiKeys { static const String _encodedClientId = String.fromEnvironment( 'NAVER_CLIENT_ID', defaultValue: '', ); static const String _encodedClientSecret = String.fromEnvironment( 'NAVER_CLIENT_SECRET', defaultValue: '', ); static String get naverClientId => _decodeIfNeeded(_encodedClientId); static String get naverClientSecret => _decodeIfNeeded(_encodedClientSecret); static const String _encodedWeatherServiceKey = String.fromEnvironment( 'KMA_SERVICE_KEY', defaultValue: '', ); static String get weatherServiceKey => _decodeIfNeeded(_encodedWeatherServiceKey); static const String naverLocalSearchEndpoint = 'https://openapi.naver.com/v1/search/local.json'; // VWorld 지오코딩 키 (dart-define: VWORLD_API_KEY, base64 권장) static const String _encodedVworldApiKey = String.fromEnvironment( 'VWORLD_API_KEY', defaultValue: '', ); static String get vworldApiKey => _decodeIfNeeded(_encodedVworldApiKey); static bool areKeysConfigured() { return naverClientId.isNotEmpty && naverClientSecret.isNotEmpty; } /// 배포 스크립트에서 사용할 수 있는 편의 메서드. static String obfuscate(String value) { if (value.isEmpty) { return ''; } return base64.encode(utf8.encode(value)); } static String _decodeIfNeeded(String value) { if (value.isEmpty) { return ''; } try { return utf8.decode(base64.decode(value)); } on FormatException { // base64가 아니면 일반 문자열로 간주 (로컬 개발 편의용) return value; } } }