mirror of
https://github.com/foss42/apidash.git
synced 2025-05-21 00:09:55 +08:00
feat: env variable substitutions
This commit is contained in:
@ -4,7 +4,8 @@ import 'package:apidash/consts.dart';
|
|||||||
import 'providers.dart';
|
import 'providers.dart';
|
||||||
import '../models/models.dart';
|
import '../models/models.dart';
|
||||||
import '../services/services.dart' show hiveHandler, HiveHandler, request;
|
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);
|
final selectedIdStateProvider = StateProvider<String?>((ref) => null);
|
||||||
|
|
||||||
@ -205,6 +206,9 @@ class CollectionStateNotifier
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpRequestModel substitutedHttpRequestModel =
|
||||||
|
getSubstitutedHttpRequestModel(requestModel.httpRequestModel!);
|
||||||
|
|
||||||
// set current model's isWorking to true and update state
|
// set current model's isWorking to true and update state
|
||||||
var map = {...state!};
|
var map = {...state!};
|
||||||
map[id] = requestModel.copyWith(
|
map[id] = requestModel.copyWith(
|
||||||
@ -214,7 +218,7 @@ class CollectionStateNotifier
|
|||||||
state = map;
|
state = map;
|
||||||
|
|
||||||
(http.Response?, Duration?, String?)? responseRec = await request(
|
(http.Response?, Duration?, String?)? responseRec = await request(
|
||||||
requestModel.httpRequestModel!,
|
substitutedHttpRequestModel,
|
||||||
defaultUriScheme: defaultUriScheme,
|
defaultUriScheme: defaultUriScheme,
|
||||||
);
|
);
|
||||||
late final RequestModel newRequestModel;
|
late final RequestModel newRequestModel;
|
||||||
@ -311,4 +315,16 @@ class CollectionStateNotifier
|
|||||||
// "data": state!.map((e) => e.toJson(includeResponse: false)).toList()
|
// "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,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.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 '../services/services.dart' show hiveHandler, HiveHandler;
|
||||||
import '../consts.dart';
|
import '../consts.dart';
|
||||||
|
|
||||||
@ -10,6 +11,26 @@ final codegenLanguageStateProvider = StateProvider<CodegenLanguage>((ref) =>
|
|||||||
final activeEnvironmentIdStateProvider = StateProvider<String?>((ref) =>
|
final activeEnvironmentIdStateProvider = StateProvider<String?>((ref) =>
|
||||||
ref.watch(settingsProvider.select((value) => value.activeEnvironmentId)));
|
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>
|
final StateNotifierProvider<ThemeStateNotifier, SettingsModel>
|
||||||
settingsProvider =
|
settingsProvider =
|
||||||
StateNotifierProvider((ref) => ThemeStateNotifier(hiveHandler));
|
StateNotifierProvider((ref) => ThemeStateNotifier(hiveHandler));
|
||||||
|
@ -85,6 +85,7 @@ class EnvironmentDropdown extends ConsumerWidget {
|
|||||||
environments: environmentsList,
|
environments: environmentsList,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
ref.read(activeEnvironmentIdStateProvider.notifier).state = value?.id;
|
ref.read(activeEnvironmentIdStateProvider.notifier).state = value?.id;
|
||||||
|
ref.read(hasUnsavedChangesProvider.notifier).state = true;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -89,8 +89,10 @@ class EditEnvironmentSecretsState
|
|||||||
? null
|
? null
|
||||||
: (value) {
|
: (value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
setState(() {
|
||||||
secretRows[index] =
|
secretRows[index] =
|
||||||
secretRows[index].copyWith(enabled: value);
|
secretRows[index].copyWith(enabled: value);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_onFieldChange(selectedId!);
|
_onFieldChange(selectedId!);
|
||||||
},
|
},
|
||||||
|
@ -89,8 +89,10 @@ class EditEnvironmentVariablesState
|
|||||||
? null
|
? null
|
||||||
: (value) {
|
: (value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
setState(() {
|
||||||
variableRows[index] =
|
variableRows[index] =
|
||||||
variableRows[index].copyWith(enabled: value);
|
variableRows[index].copyWith(enabled: value);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_onFieldChange(selectedId!);
|
_onFieldChange(selectedId!);
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:apidash/providers/providers.dart';
|
import 'package:apidash/providers/providers.dart';
|
||||||
import 'package:apidash/widgets/widgets.dart';
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
import 'package:apidash/codegen/codegen.dart';
|
import 'package:apidash/codegen/codegen.dart';
|
||||||
|
import 'package:apidash/utils/utils.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
final Codegen codegen = Codegen();
|
final Codegen codegen = Codegen();
|
||||||
@ -19,8 +20,15 @@ class CodePane extends ConsumerWidget {
|
|||||||
final defaultUriScheme =
|
final defaultUriScheme =
|
||||||
ref.watch(settingsProvider.select((value) => value.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(
|
final code = codegen.getCode(
|
||||||
codegenLanguage, selectedRequestModel!, defaultUriScheme);
|
codegenLanguage, substitutedRequestModel!, defaultUriScheme);
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
return const ErrorMessage(
|
return const ErrorMessage(
|
||||||
message: "An error was encountered while generating code. $kRaiseIssue",
|
message: "An error was encountered while generating code. $kRaiseIssue",
|
||||||
|
@ -35,3 +35,53 @@ List<EnvironmentVariableModel> getEnvironmentSecrets(
|
|||||||
(removeEmptyModels ? element != kEnvironmentSecretEmptyModel : true))
|
(removeEmptyModels ? element != kEnvironmentSecretEmptyModel : true))
|
||||||
.toList();
|
.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;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user