mirror of
https://github.com/foss42/apidash.git
synced 2025-12-09 23:02:21 +08:00
Merge pull request #635 from AffanShaikhsurab/patch-9
Added env variable support for form request body
This commit is contained in:
@@ -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,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
Reference in New Issue
Block a user