Merge pull request #635 from AffanShaikhsurab/patch-9

Added env variable support for form request body
This commit is contained in:
Ashita Prasad
2025-03-23 07:54:53 +05:30
committed by GitHub
7 changed files with 106 additions and 105 deletions

View File

@@ -27,22 +27,9 @@ class EnvCellField extends StatelessWidget {
style: kCodeStyle.copyWith( style: kCodeStyle.copyWith(
color: clrScheme.onSurface, color: clrScheme.onSurface,
), ),
decoration: InputDecoration( decoration: getTextFieldInputDecoration(
hintStyle: kCodeStyle.copyWith( clrScheme,
color: clrScheme.outlineVariant,
),
hintText: hintText, hintText: hintText,
contentPadding: const EdgeInsets.only(bottom: 12),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: clrScheme.outlineVariant,
),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: clrScheme.surfaceContainerHighest,
),
),
), ),
onChanged: onChanged, onChanged: onChanged,
); );

View File

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:data_table_2/data_table_2.dart'; import 'package:data_table_2/data_table_2.dart';
import 'package:apidash/providers/providers.dart'; import 'package:apidash/providers/providers.dart';
import 'package:apidash/screens/common_widgets/common_widgets.dart';
import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/utils/utils.dart'; import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
@@ -82,7 +83,7 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
key: ValueKey("$selectedId-$index-form-row-$seed"), key: ValueKey("$selectedId-$index-form-row-$seed"),
cells: <DataCell>[ cells: <DataCell>[
DataCell( DataCell(
CellField( EnvCellField(
keyId: "$selectedId-$index-form-k-$seed", keyId: "$selectedId-$index-form-k-$seed",
initialValue: formRows[index].name, initialValue: formRows[index].name,
hintText: kHintAddFieldName, hintText: kHintAddFieldName,
@@ -138,7 +139,7 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
}, },
initialValue: formRows[index].value, initialValue: formRows[index].value,
) )
: CellField( : EnvCellField(
keyId: "$selectedId-$index-form-v-$seed", keyId: "$selectedId-$index-form-v-$seed",
initialValue: formRows[index].value, initialValue: formRows[index].value,
hintText: kHintAddValue, hintText: kHintAddValue,

View File

@@ -37,59 +37,60 @@ List<EnvironmentVariableModel> getEnvironmentSecrets(
} }
String? substituteVariables( String? substituteVariables(
String? input, String? input,
Map<String?, List<EnvironmentVariableModel>> envMap, Map<String, String> envVarMap,
String? activeEnvironmentId) { ) {
if (input == null) return null; if (input == null) return null;
if (envVarMap.keys.isEmpty) {
final Map<String, String> combinedMap = {}; return input;
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("{{(${envVarMap.keys.join('|')})}}");
String result = input.replaceAllMapped(kEnvVarRegEx, (match) { String result = input.replaceAllMapped(regex, (match) {
final key = match.group(1)?.trim() ?? ''; final key = match.group(1)?.trim() ?? '';
return combinedMap[key] ?? ''; return envVarMap[key] ?? '{{$key}}';
}); });
return result; return result;
} }
HttpRequestModel substituteHttpRequestModel( HttpRequestModel substituteHttpRequestModel(
HttpRequestModel httpRequestModel, HttpRequestModel httpRequestModel,
Map<String?, List<EnvironmentVariableModel>> envMap, Map<String?, List<EnvironmentVariableModel>> envMap,
String? activeEnvironmentId) { String? activeEnvironmentId,
) {
final Map<String, String> combinedEnvVarMap = {};
final activeEnv = envMap[activeEnvironmentId] ?? [];
final globalEnv = envMap[kGlobalEnvironmentId] ?? [];
for (var variable in globalEnv) {
combinedEnvVarMap[variable.key] = variable.value;
}
for (var variable in activeEnv) {
combinedEnvVarMap[variable.key] = variable.value;
}
var newRequestModel = httpRequestModel.copyWith( var newRequestModel = httpRequestModel.copyWith(
url: substituteVariables( url: substituteVariables(httpRequestModel.url, combinedEnvVarMap)!,
httpRequestModel.url,
envMap,
activeEnvironmentId,
)!,
headers: httpRequestModel.headers?.map((header) { headers: httpRequestModel.headers?.map((header) {
return header.copyWith( return header.copyWith(
name: name: substituteVariables(header.name, combinedEnvVarMap) ?? "",
substituteVariables(header.name, envMap, activeEnvironmentId) ?? "", value: substituteVariables(header.value, combinedEnvVarMap),
value: substituteVariables(header.value, envMap, activeEnvironmentId),
); );
}).toList(), }).toList(),
params: httpRequestModel.params?.map((param) { params: httpRequestModel.params?.map((param) {
return param.copyWith( return param.copyWith(
name: name: substituteVariables(param.name, combinedEnvVarMap) ?? "",
substituteVariables(param.name, envMap, activeEnvironmentId) ?? "", value: substituteVariables(param.value, combinedEnvVarMap),
value: substituteVariables(param.value, envMap, activeEnvironmentId),
); );
}).toList(), }).toList(),
body: substituteVariables( formData: httpRequestModel.formData?.map((formData) {
httpRequestModel.body, return formData.copyWith(
envMap, name: substituteVariables(formData.name, combinedEnvVarMap) ?? "",
activeEnvironmentId, value: substituteVariables(formData.value, combinedEnvVarMap) ?? "",
), );
}).toList(),
body: substituteVariables(httpRequestModel.body, combinedEnvVarMap),
); );
return newRequestModel; return newRequestModel;
} }

View File

@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import '../tokens/tokens.dart';
InputDecoration getTextFieldInputDecoration(
ColorScheme clrScheme, {
Color? fillColor,
String? hintText,
TextStyle? hintTextStyle,
double? hintTextFontSize,
Color? hintTextColor,
EdgeInsetsGeometry? contentPadding,
Color? focussedBorderColor,
Color? enabledBorderColor,
bool? isDense,
}) {
return InputDecoration(
filled: true,
fillColor: fillColor ?? clrScheme.surfaceContainerLowest,
hintStyle: hintTextStyle ??
kCodeStyle.copyWith(
fontSize: hintTextFontSize,
color: hintTextColor ?? clrScheme.outlineVariant,
),
hintText: hintText,
contentPadding: contentPadding ?? kP10,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: focussedBorderColor ?? clrScheme.outline,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: enabledBorderColor ?? clrScheme.surfaceContainerHighest,
),
),
isDense: isDense,
);
}

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../tokens/tokens.dart'; import '../tokens/tokens.dart';
import 'decoration_input_textfield.dart';
class ADOutlinedTextField extends StatelessWidget { class ADOutlinedTextField extends StatelessWidget {
const ADOutlinedTextField({ const ADOutlinedTextField({
@@ -65,26 +66,16 @@ class ADOutlinedTextField extends StatelessWidget {
fontSize: textFontSize, fontSize: textFontSize,
color: textColor ?? clrScheme.onSurface, color: textColor ?? clrScheme.onSurface,
), ),
decoration: InputDecoration( decoration: getTextFieldInputDecoration(
filled: true, clrScheme,
fillColor: fillColor ?? clrScheme.surfaceContainerLowest, fillColor: fillColor,
hintStyle: hintTextStyle ??
kCodeStyle.copyWith(
fontSize: hintTextFontSize,
color: hintTextColor ?? clrScheme.outlineVariant,
),
hintText: hintText, hintText: hintText,
contentPadding: contentPadding ?? kP10, hintTextStyle: hintTextStyle,
focusedBorder: OutlineInputBorder( hintTextFontSize: hintTextFontSize,
borderSide: BorderSide( hintTextColor: hintTextColor,
color: focussedBorderColor ?? clrScheme.outline, contentPadding: contentPadding,
), focussedBorderColor: focussedBorderColor,
), enabledBorderColor: enabledBorderColor,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: enabledBorderColor ?? clrScheme.surfaceContainerHighest,
),
),
isDense: isDense, isDense: isDense,
), ),
onChanged: onChanged, onChanged: onChanged,

View File

@@ -2,6 +2,7 @@ export 'button_filled.dart';
export 'button_icon.dart'; export 'button_icon.dart';
export 'button_text.dart'; export 'button_text.dart';
export 'checkbox.dart'; export 'checkbox.dart';
export 'decoration_input_textfield.dart';
export 'dropdown.dart'; export 'dropdown.dart';
export 'popup_menu.dart'; export 'popup_menu.dart';
export 'snackbar.dart'; export 'snackbar.dart';

View File

@@ -48,10 +48,13 @@ const globalVars = [
EnvironmentVariableModel(key: "num", value: "5670000"), EnvironmentVariableModel(key: "num", value: "5670000"),
EnvironmentVariableModel(key: "token", value: "token"), EnvironmentVariableModel(key: "token", value: "token"),
]; ];
final globalVarsMap = {for (var item in globalVars) item.key: item.value};
const activeEnvVars = [ const activeEnvVars = [
EnvironmentVariableModel(key: "url", value: "api.apidash.dev"), EnvironmentVariableModel(key: "url", value: "api.apidash.dev"),
EnvironmentVariableModel(key: "num", value: "8940000"), EnvironmentVariableModel(key: "num", value: "8940000"),
]; ];
final activeEnvVarsMap = {for (var item in activeEnvVars) item.key: item.value};
final combinedEnvVarsMap = mergeMaps(globalVarsMap, activeEnvVarsMap);
void main() { void main() {
group("Testing getEnvironmentTitle function", () { group("Testing getEnvironmentTitle function", () {
@@ -125,66 +128,45 @@ void main() {
group("Testing substituteVariables function", () { group("Testing substituteVariables function", () {
test("Testing substituteVariables with null", () { test("Testing substituteVariables with null", () {
String? input; String? input;
Map<String?, List<EnvironmentVariableModel>> envMap = {}; Map<String, String> envMap = {};
String? activeEnvironmentId; expect(substituteVariables(input, envMap), null);
expect(substituteVariables(input, envMap, activeEnvironmentId), null);
}); });
test("Testing substituteVariables with empty input", () { test("Testing substituteVariables with empty input", () {
String input = ""; String input = "";
Map<String?, List<EnvironmentVariableModel>> envMap = {}; Map<String, String> envMap = {};
String? activeEnvironmentId; expect(substituteVariables(input, envMap), "");
expect(substituteVariables(input, envMap, activeEnvironmentId), "");
}); });
test("Testing substituteVariables with empty envMap", () { test("Testing substituteVariables with empty envMap", () {
String input = "{{url}}/humanize/social?num={{num}}"; String input = "{{url}}/humanize/social?num={{num}}";
Map<String?, List<EnvironmentVariableModel>> envMap = {}; Map<String, String> envMap = {};
String? activeEnvironmentId; String expected = "{{url}}/humanize/social?num={{num}}";
String expected = "/humanize/social?num="; expect(substituteVariables(input, envMap), expected);
expect(substituteVariables(input, envMap, activeEnvironmentId), expected);
}); });
test("Testing substituteVariables with empty activeEnvironmentId", () { test("Testing substituteVariables with empty activeEnvironmentId", () {
String input = "{{url}}/humanize/social?num={{num}}"; String input = "{{url}}/humanize/social?num={{num}}";
Map<String?, List<EnvironmentVariableModel>> envMap = {
kGlobalEnvironmentId: globalVars,
};
String expected = "api.foss42.com/humanize/social?num=5670000"; String expected = "api.foss42.com/humanize/social?num=5670000";
expect(substituteVariables(input, envMap, null), expected); expect(substituteVariables(input, globalVarsMap), expected);
}); });
test("Testing substituteVariables with non-empty activeEnvironmentId", () { test("Testing substituteVariables with non-empty activeEnvironmentId", () {
String input = "{{url}}/humanize/social?num={{num}}"; String input = "{{url}}/humanize/social?num={{num}}";
Map<String?, List<EnvironmentVariableModel>> envMap = {
kGlobalEnvironmentId: globalVars,
"activeEnvId": activeEnvVars,
};
String? activeEnvId = "activeEnvId";
String expected = "api.apidash.dev/humanize/social?num=8940000"; String expected = "api.apidash.dev/humanize/social?num=8940000";
expect(substituteVariables(input, envMap, activeEnvId), expected); expect(substituteVariables(input, combinedEnvVarsMap), expected);
}); });
test("Testing substituteVariables with incorrect paranthesis", () { test("Testing substituteVariables with incorrect paranthesis", () {
String input = "{{url}}}/humanize/social?num={{num}}"; String input = "{{url}}}/humanize/social?num={{num}}";
Map<String?, List<EnvironmentVariableModel>> envMap = {
kGlobalEnvironmentId: globalVars,
"activeEnvId": activeEnvVars,
};
String? activeEnvId = "activeEnvId";
String expected = "api.apidash.dev}/humanize/social?num=8940000"; String expected = "api.apidash.dev}/humanize/social?num=8940000";
expect(substituteVariables(input, envMap, activeEnvId), expected); expect(substituteVariables(input, combinedEnvVarsMap), expected);
}); });
test("Testing substituteVariables function with unavailable variables", () { test("Testing substituteVariables function with unavailable variables", () {
String input = "{{url1}}/humanize/social?num={{num}}"; String input = "{{url1}}/humanize/social?num={{num}}";
Map<String?, List<EnvironmentVariableModel>> envMap = { String expected = "{{url1}}/humanize/social?num=8940000";
kGlobalEnvironmentId: globalVars, expect(substituteVariables(input, combinedEnvVarsMap), expected);
"activeEnvId": activeEnvVars,
};
String? activeEnvironmentId = "activeEnvId";
String expected = "/humanize/social?num=8940000";
expect(substituteVariables(input, envMap, activeEnvironmentId), expected);
}); });
}); });
@@ -251,9 +233,9 @@ void main() {
}; };
String? activeEnvironmentId = "activeEnvId"; String? activeEnvironmentId = "activeEnvId";
const expected = HttpRequestModel( const expected = HttpRequestModel(
url: "/humanize/social", url: "{{url1}}/humanize/social",
headers: [ headers: [
NameValueModel(name: "Authorization", value: "Bearer "), NameValueModel(name: "Authorization", value: "Bearer {{token1}}"),
], ],
params: [ params: [
NameValueModel(name: "num", value: "8940000"), NameValueModel(name: "num", value: "8940000"),