envStub function
Generates the env.g.dart file content with encrypted environment variables.
encryptedMap - Map of key-value pairs with encrypted values
appKey - The APP_KEY used for encryption (null if using --dart-define mode)
useDartDefine - Whether to use String.fromEnvironment for APP_KEY
Implementation
String envStub({
required Map<String, String> encryptedMap,
String? appKey,
bool useDartDefine = false,
}) {
final buffer = StringBuffer();
// Header comment
buffer.writeln('// GENERATED CODE - DO NOT MODIFY BY HAND');
buffer.writeln('// Generated by: metro make:env');
buffer.writeln(
'// **************************************************************************');
buffer.writeln('');
buffer.writeln("import 'dart:convert';");
buffer.writeln('');
// Start class
buffer.writeln('/// Auto-generated environment configuration.');
buffer.writeln(
'/// Do not edit this file manually. Run `metro make:env` to regenerate.');
buffer.writeln('class Env {');
buffer.writeln(' Env._();');
buffer.writeln('');
// APP_KEY - either embedded or from dart-define
if (useDartDefine) {
buffer.writeln(" /// APP_KEY injected via --dart-define at build time.");
buffer.writeln(
" static const String _appKey = String.fromEnvironment('APP_KEY');");
} else {
buffer
.writeln(' /// APP_KEY for decryption (obfuscated at compile time).');
buffer.writeln(" static const String _appKey = '$appKey';");
}
buffer.writeln('');
// Encrypted values map
buffer.writeln(' /// Encrypted environment values.');
buffer.writeln(' static const Map<String, String> _encrypted = {');
for (final entry in encryptedMap.entries) {
buffer.writeln(" '${entry.key}': '${entry.value}',");
}
buffer.writeln(' };');
buffer.writeln('');
// Cache for decrypted values
buffer.writeln(' /// Cache for decrypted values.');
buffer.writeln(' static final Map<String, dynamic> _cache = {};');
buffer.writeln('');
// XOR decrypt method
buffer.writeln(' /// Decrypts a base64-encoded XOR-encrypted string.');
buffer.writeln(' static String _decrypt(String encrypted) {');
buffer.writeln(' final encryptedBytes = base64Decode(encrypted);');
buffer.writeln(' final keyBytes = utf8.encode(_appKey);');
buffer.writeln(' final decryptedBytes = <int>[];');
buffer.writeln('');
buffer.writeln(' for (var i = 0; i < encryptedBytes.length; i++) {');
buffer.writeln(
' decryptedBytes.add(encryptedBytes[i] ^ keyBytes[i % keyBytes.length]);');
buffer.writeln(' }');
buffer.writeln('');
buffer.writeln(' return utf8.decode(decryptedBytes);');
buffer.writeln(' }');
buffer.writeln('');
// Parse value helper
buffer.writeln(' /// Parses a string value to the appropriate type.');
buffer.writeln(' static dynamic _parseValue(String value) {');
buffer.writeln(" if (value == 'null') return null;");
buffer.writeln(" if (value.toLowerCase() == 'true') return true;");
buffer.writeln(" if (value.toLowerCase() == 'false') return false;");
buffer.writeln(" if (value == '\"\"') return '';");
buffer.writeln(' return value;');
buffer.writeln(' }');
buffer.writeln('');
// Get method
buffer.writeln(' /// Gets an environment variable by key.');
buffer.writeln(' ///');
buffer.writeln(
' /// Returns the decrypted value, or [defaultValue] if the key is not found.');
buffer.writeln(' /// Values are automatically parsed:');
buffer.writeln(" /// - 'true'/'false' -> bool");
buffer.writeln(" /// - 'null' -> null");
buffer.writeln(" /// - '\"\"' -> empty string");
buffer.writeln(' static dynamic get(String key, {dynamic defaultValue}) {');
buffer.writeln(' // Return from cache if available');
buffer.writeln(' if (_cache.containsKey(key)) {');
buffer.writeln(' return _cache[key];');
buffer.writeln(' }');
buffer.writeln('');
buffer.writeln(' // Check if key exists');
buffer.writeln(' if (!_encrypted.containsKey(key)) {');
buffer.writeln(' return defaultValue;');
buffer.writeln(' }');
buffer.writeln('');
buffer.writeln(' // Decrypt and parse the value');
buffer.writeln(' final decrypted = _decrypt(_encrypted[key]!);');
buffer.writeln(' final parsed = _parseValue(decrypted);');
buffer.writeln('');
buffer.writeln(' // Cache the result');
buffer.writeln(' _cache[key] = parsed;');
buffer.writeln('');
buffer.writeln(' return parsed;');
buffer.writeln(' }');
buffer.writeln('');
// Contains key method
buffer.writeln(' /// Checks if an environment variable exists.');
buffer.writeln(' static bool containsKey(String key) {');
buffer.writeln(' return _encrypted.containsKey(key);');
buffer.writeln(' }');
buffer.writeln('');
// Get all keys method
buffer.writeln(' /// Returns all available environment variable keys.');
buffer.writeln(' static List<String> get keys => _encrypted.keys.toList();');
// Close class
buffer.writeln('}');
return buffer.toString();
}