feat: env variable substitutions

This commit is contained in:
DenserMeerkat
2024-06-16 22:14:27 +05:30
parent 41a7f2ccf9
commit ebe576a118
7 changed files with 108 additions and 8 deletions

View File

@ -4,7 +4,8 @@ import 'package:apidash/consts.dart';
import 'providers.dart';
import '../models/models.dart';
import '../services/services.dart' show hiveHandler, HiveHandler, request;
import '../utils/utils.dart' show getNewUuid, collectionToHAR;
import '../utils/utils.dart'
show getNewUuid, collectionToHAR, substituteHttpRequestModel;
final selectedIdStateProvider = StateProvider<String?>((ref) => null);
@ -205,6 +206,9 @@ class CollectionStateNotifier
return;
}
HttpRequestModel substitutedHttpRequestModel =
getSubstitutedHttpRequestModel(requestModel.httpRequestModel!);
// set current model's isWorking to true and update state
var map = {...state!};
map[id] = requestModel.copyWith(
@ -214,7 +218,7 @@ class CollectionStateNotifier
state = map;
(http.Response?, Duration?, String?)? responseRec = await request(
requestModel.httpRequestModel!,
substitutedHttpRequestModel,
defaultUriScheme: defaultUriScheme,
);
late final RequestModel newRequestModel;
@ -311,4 +315,16 @@ class CollectionStateNotifier
// "data": state!.map((e) => e.toJson(includeResponse: false)).toList()
// };
}
HttpRequestModel getSubstitutedHttpRequestModel(
HttpRequestModel httpRequestModel) {
var envMap = ref.read(availableEnvironmentVariablesStateProvider);
var activeEnvId = ref.read(activeEnvironmentIdStateProvider);
return substituteHttpRequestModel(
httpRequestModel,
envMap,
activeEnvId,
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/models.dart' show SettingsModel;
import '../models/models.dart';
import 'environment_provider.dart';
import '../services/services.dart' show hiveHandler, HiveHandler;
import '../consts.dart';
@ -10,6 +11,26 @@ final codegenLanguageStateProvider = StateProvider<CodegenLanguage>((ref) =>
final activeEnvironmentIdStateProvider = StateProvider<String?>((ref) =>
ref.watch(settingsProvider.select((value) => value.activeEnvironmentId)));
final availableEnvironmentVariablesStateProvider =
StateProvider<Map<String, List<EnvironmentVariableModel>>>((ref) {
Map<String, List<EnvironmentVariableModel>> result = {};
final environments = ref.watch(environmentsStateNotifierProvider);
final activeEnviormentId = ref.watch(activeEnvironmentIdStateProvider);
if (activeEnviormentId != null) {
result[activeEnviormentId] = environments?[activeEnviormentId]
?.values
.where((element) => element.enabled)
.toList() ??
[];
}
result[kGlobalEnvironmentId] = environments?[kGlobalEnvironmentId]
?.values
.where((element) => element.enabled)
.toList() ??
[];
return result;
});
final StateNotifierProvider<ThemeStateNotifier, SettingsModel>
settingsProvider =
StateNotifierProvider((ref) => ThemeStateNotifier(hiveHandler));

View File

@ -85,6 +85,7 @@ class EnvironmentDropdown extends ConsumerWidget {
environments: environmentsList,
onChanged: (value) {
ref.read(activeEnvironmentIdStateProvider.notifier).state = value?.id;
ref.read(hasUnsavedChangesProvider.notifier).state = true;
},
),
);

View File

@ -89,8 +89,10 @@ class EditEnvironmentSecretsState
? null
: (value) {
if (value != null) {
secretRows[index] =
secretRows[index].copyWith(enabled: value);
setState(() {
secretRows[index] =
secretRows[index].copyWith(enabled: value);
});
}
_onFieldChange(selectedId!);
},

View File

@ -89,8 +89,10 @@ class EditEnvironmentVariablesState
? null
: (value) {
if (value != null) {
variableRows[index] =
variableRows[index].copyWith(enabled: value);
setState(() {
variableRows[index] =
variableRows[index].copyWith(enabled: value);
});
}
_onFieldChange(selectedId!);
},

View File

@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/codegen/codegen.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart';
final Codegen codegen = Codegen();
@ -19,8 +20,15 @@ class CodePane extends ConsumerWidget {
final defaultUriScheme =
ref.watch(settingsProvider.select((value) => value.defaultUriScheme));
var envMap = ref.watch(availableEnvironmentVariablesStateProvider);
var activeEnvId = ref.watch(activeEnvironmentIdStateProvider);
final substitutedRequestModel = selectedRequestModel?.copyWith(
httpRequestModel: substituteHttpRequestModel(
selectedRequestModel.httpRequestModel!, envMap, activeEnvId));
final code = codegen.getCode(
codegenLanguage, selectedRequestModel!, defaultUriScheme);
codegenLanguage, substitutedRequestModel!, defaultUriScheme);
if (code == null) {
return const ErrorMessage(
message: "An error was encountered while generating code. $kRaiseIssue",

View File

@ -35,3 +35,53 @@ List<EnvironmentVariableModel> getEnvironmentSecrets(
(removeEmptyModels ? element != kEnvironmentSecretEmptyModel : true))
.toList();
}
String? substituteVariables(
String? input,
Map<String?, List<EnvironmentVariableModel>> envMap,
String? activeEnvironmentId) {
if (input == null) return null;
final Map<String, String> combinedMap = {};
final activeEnv = envMap[activeEnvironmentId] ?? [];
final globalEnv = envMap[kGlobalEnvironmentId] ?? [];
for (var variable in globalEnv) {
combinedMap[variable.key] = variable.value;
}
for (var variable in activeEnv) {
combinedMap[variable.key] = variable.value;
}
final regex = RegExp(r'{{(.*?)}}');
String result = input.replaceAllMapped(regex, (match) {
final key = match.group(1)?.trim() ?? '';
return combinedMap[key] ?? '';
});
return result;
}
HttpRequestModel substituteHttpRequestModel(
HttpRequestModel httpRequestModel,
Map<String?, List<EnvironmentVariableModel>> envMap,
String? activeEnvironmentId) {
var newRequestModel = httpRequestModel.copyWith(
url: substituteVariables(
httpRequestModel.url,
envMap,
activeEnvironmentId,
)!,
headers: httpRequestModel.headers?.map((header) {
return header.copyWith(
value: substituteVariables(header.value, envMap, activeEnvironmentId),
);
}).toList(),
params: httpRequestModel.params?.map((param) {
return param.copyWith(
value: substituteVariables(param.value, envMap, activeEnvironmentId),
);
}).toList(),
);
return newRequestModel;
}