Merge branch 'main' into add-feature-checkbox

This commit is contained in:
Ashita Prasad
2023-12-25 21:29:36 +05:30
committed by GitHub
30 changed files with 1193 additions and 660 deletions

View File

@ -1,7 +1,7 @@
import 'package:apidash/widgets/window_caption.dart';
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 'package:window_manager/window_manager.dart' hide WindowCaption; import 'package:window_manager/window_manager.dart' hide WindowCaption;
import 'widgets/widgets.dart' show WindowCaption;
import 'providers/providers.dart'; import 'providers/providers.dart';
import 'screens/screens.dart'; import 'screens/screens.dart';
import 'consts.dart'; import 'consts.dart';
@ -85,18 +85,19 @@ class _DashAppState extends ConsumerState<DashApp> {
scaffoldBody: CollectionPane(), scaffoldBody: CollectionPane(),
) )
: Stack( : Stack(
children: [ children: [
kIsLinux ? const Dashboard() : const App(), kIsLinux ? const Dashboard() : const App(),
if (kIsWindows) if (kIsWindows)
SizedBox( SizedBox(
height: 29, height: 29,
child: WindowCaption( child: WindowCaption(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
brightness: isDarkMode ? Brightness.dark : Brightness.light, brightness:
), isDarkMode ? Brightness.dark : Brightness.light,
),
),
],
), ),
],
),
); );
} }
} }

View File

@ -1,6 +1,7 @@
import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/models/models.dart' show RequestModel;
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
import 'dart/http.dart'; import 'dart/http.dart';
import 'dart/dio.dart';
import 'kotlin/okhttp.dart'; import 'kotlin/okhttp.dart';
import 'python/http_client.dart'; import 'python/http_client.dart';
import 'python/requests.dart'; import 'python/requests.dart';
@ -22,6 +23,8 @@ class Codegen {
return HARCodeGen().getCode(requestModel, defaultUriScheme); return HARCodeGen().getCode(requestModel, defaultUriScheme);
case CodegenLanguage.dartHttp: case CodegenLanguage.dartHttp:
return DartHttpCodeGen().getCode(requestModel, defaultUriScheme); return DartHttpCodeGen().getCode(requestModel, defaultUriScheme);
case CodegenLanguage.dartDio:
return DartDioCodeGen().getCode(requestModel, defaultUriScheme);
case CodegenLanguage.jsAxios: case CodegenLanguage.jsAxios:
return AxiosCodeGen().getCode(requestModel, defaultUriScheme); return AxiosCodeGen().getCode(requestModel, defaultUriScheme);
case CodegenLanguage.jsFetch: case CodegenLanguage.jsFetch:

127
lib/codegen/dart/dio.dart Normal file
View File

@ -0,0 +1,127 @@
import 'package:apidash/consts.dart';
import 'package:apidash/models/request_model.dart' show RequestModel;
import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';
import 'shared.dart';
class DartDioCodeGen {
String? getCode(
RequestModel requestModel,
String defaultUriScheme,
) {
try {
String url = requestModel.url;
if (!url.contains("://") && url.isNotEmpty) {
url = "$defaultUriScheme://$url";
}
final next = generatedDartCode(
url: url,
method: requestModel.method,
queryParams: requestModel.paramsMap,
headers: requestModel.headersMap,
body: requestModel.requestBody,
contentType: requestModel.requestBodyContentType,
);
return next;
} catch (e) {
return null;
}
}
String generatedDartCode({
required String url,
required HTTPVerb method,
required Map<String, String> queryParams,
required Map<String, String> headers,
required String? body,
required ContentType contentType,
}) {
final sbf = StringBuffer();
final emitter = DartEmitter();
final dioImport = Directive.import('package:dio/dio.dart', as: 'dio');
sbf.writeln(dioImport.accept(emitter));
Expression? queryParamExp;
if (queryParams.isNotEmpty) {
queryParamExp = declareFinal('queryParams').assign(
literalMap(queryParams.map((key, value) => MapEntry(key, value))),
);
}
Expression? headerExp;
if (headers.isNotEmpty) {
headerExp = declareFinal('headers').assign(
literalMap(headers.map((key, value) => MapEntry(key, value))),
);
}
Expression? dataExp;
if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) {
final strContent = CodeExpression(Code('r\'\'\'$body\'\'\''));
switch (contentType) {
// dio dosen't need pass `content-type` header when body is json or plain text
case ContentType.json:
final convertImport = Directive.import('dart:convert', as: 'convert');
sbf.writeln(convertImport.accept(emitter));
dataExp = declareFinal('data')
.assign(refer('convert.json.decode').call([strContent]));
case ContentType.text:
dataExp = declareFinal('data').assign(strContent);
// when add new type of [ContentType], need update [dataExp].
}
}
final responseExp = declareFinal('response').assign(InvokeExpression.newOf(
refer('dio.Dio'),
[literalString(url)],
{
if (queryParamExp != null) 'queryParameters': refer('queryParams'),
if (headerExp != null)
'options': refer('Options').newInstance(
[],
{'headers': refer('headers')},
),
if (dataExp != null) 'data': refer('data'),
},
[],
method.name,
).awaited);
final mainFunction = Method((m) {
final content = declareTryCatch(
showStackStrace: true,
body: [
if (queryParamExp != null) queryParamExp,
if (headerExp != null) headerExp,
if (dataExp != null) dataExp,
responseExp,
refer('print').call([refer('response').property('statusCode')]),
refer('print').call([refer('response').property('data')]),
],
onError: {
'DioException': [
refer('print').call([
refer('e').property('response').nullSafeProperty('statusCode'),
]),
refer('print').call([
refer('e').property('response').nullSafeProperty('data'),
]),
refer('print').call([refer('s')]),
],
null: [
refer('print').call([refer('e')]),
refer('print').call([refer('s')]),
],
},
);
m
..name = 'main'
..returns = refer('void')
..modifier = MethodModifier.async
..body = content;
});
sbf.writeln(mainFunction.accept(emitter));
return DartFormatter(pageWidth: 160).format(sbf.toString());
}
}

View File

@ -1,147 +1,163 @@
import 'dart:io'; import 'dart:io';
import 'dart:convert';
import 'package:jinja/jinja.dart' as jj;
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
import 'package:apidash/utils/utils.dart' show padMultilineString;
import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/models/models.dart' show RequestModel;
import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';
import 'shared.dart';
class DartHttpCodeGen { class DartHttpCodeGen {
String kTemplateStart = """import 'package:http/http.dart' as http;
void main() async {
var uri = Uri.parse('{{url}}');
""";
String kTemplateParams = """
var queryParams = {{params}};
""";
int kParamsPadding = 20;
String kStringUrlParams = """
var urlQueryParams = Map<String,String>.from(uri.queryParameters);
urlQueryParams.addAll(queryParams);
uri = uri.replace(queryParameters: urlQueryParams);
""";
String kStringNoUrlParams = """
uri = uri.replace(queryParameters: queryParams);
""";
String kTemplateBody = """
String body = r'''{{body}}''';
""";
String kTemplateHeaders = """
var headers = {{headers}};
""";
int kHeadersPadding = 16;
String kTemplateRequest = """
final response = await http.{{method}}(uri""";
String kStringRequestHeaders = """,
headers: headers""";
String kStringRequestBody = """,
body: body""";
String kStringRequestEnd = r""");
int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode');
print('Response Body: ${response.body}');
}
else{
print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}');
}
}
""";
String? getCode( String? getCode(
RequestModel requestModel, RequestModel requestModel,
String defaultUriScheme, String defaultUriScheme,
) { ) {
try { try {
String result = "";
bool hasHeaders = false;
bool hasBody = false;
String url = requestModel.url; String url = requestModel.url;
if (!url.contains("://") && url.isNotEmpty) { if (!url.contains("://") && url.isNotEmpty) {
url = "$defaultUriScheme://$url"; url = "$defaultUriScheme://$url";
} }
var templateStartUrl = jj.Template(kTemplateStart); final next = generatedDartCode(
result += templateStartUrl.render({"url": url}); url: url,
method: requestModel.method,
var paramsList = requestModel.requestParams; queryParams: requestModel.enabledParamsMap,
if (paramsList != null) { headers: requestModel.enabledHeadersMap,
var params = requestModel.paramsMap; body: requestModel.requestBody,
if (params.isNotEmpty) { contentType: requestModel.requestBodyContentType,
var templateParams = jj.Template(kTemplateParams); );
var paramsString = kEncoder.convert(params); return next;
paramsString = padMultilineString(paramsString, kParamsPadding);
result += templateParams.render({"params": paramsString});
Uri uri = Uri.parse(url);
if (uri.hasQuery) {
result += kStringUrlParams;
} else {
result += kStringNoUrlParams;
}
}
}
var method = requestModel.method;
var requestBody = requestModel.requestBody;
if (kMethodsWithBody.contains(method) && requestBody != null) {
var contentLength = utf8.encode(requestBody).length;
if (contentLength > 0) {
hasBody = true;
var templateBody = jj.Template(kTemplateBody);
result += templateBody.render({"body": requestBody});
}
}
var headersList = requestModel.enabledRequestHeaders;
if (headersList != null || hasBody) {
var headers = requestModel.enabledHeadersMap;
if (headers.isNotEmpty || hasBody) {
hasHeaders = true;
if (hasBody) {
headers[HttpHeaders.contentTypeHeader] =
kContentTypeMap[requestModel.requestBodyContentType] ?? "";
}
var headersString = kEncoder.convert(headers);
headersString = padMultilineString(headersString, kHeadersPadding);
var templateHeaders = jj.Template(kTemplateHeaders);
result += templateHeaders.render({"headers": headersString});
}
}
var templateRequest = jj.Template(kTemplateRequest);
result += templateRequest.render({"method": method.name});
if (hasHeaders) {
result += kStringRequestHeaders;
}
if (hasBody) {
result += kStringRequestBody;
}
result += kStringRequestEnd;
return result;
} catch (e) { } catch (e) {
return null; return null;
} }
} }
String generatedDartCode({
required String url,
required HTTPVerb method,
required Map<String, String> queryParams,
required Map<String, String> headers,
required String? body,
required ContentType contentType,
}) {
final uri = Uri.parse(url);
final sbf = StringBuffer();
final emitter = DartEmitter();
final dioImport = Directive.import('package:http/http.dart', as: 'http');
sbf.writeln(dioImport.accept(emitter));
final uriExp =
declareVar('uri').assign(refer('Uri.parse').call([literalString(url)]));
final composeHeaders = headers;
Expression? dataExp;
if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) {
final strContent = CodeExpression(Code('r\'\'\'$body\'\'\''));
dataExp = declareVar('body', type: refer('String')).assign(strContent);
composeHeaders.putIfAbsent(HttpHeaders.contentTypeHeader,
() => kContentTypeMap[contentType] ?? '');
}
Expression? queryParamExp;
List<Expression>? uriReassignExps;
// var urlQueryParams = Map<String,String>.from(uri.queryParameters);
// urlQueryParams.addAll(queryParams);
// uri = uri.replace(queryParameters: urlQueryParams);
if (queryParams.isNotEmpty) {
queryParamExp = declareVar('queryParams').assign(
literalMap(queryParams.map((key, value) => MapEntry(key, value))),
);
uriReassignExps = [
if (uri.hasQuery)
declareVar('urlQueryParams').assign(
InvokeExpression.newOf(
refer('Map<String,String>'),
[refer('uri.queryParameters')],
{},
[],
'from',
),
),
if (uri.hasQuery)
refer('urlQueryParams')
.property('addAll')
.call([refer('queryParams')], {}),
refer('uri').assign(refer('uri').property('replace').call([], {
'queryParameters':
uri.hasQuery ? refer('urlQueryParams') : refer('queryParams'),
}))
];
}
Expression? headerExp;
if (headers.isNotEmpty) {
headerExp = declareVar('headers').assign(
literalMap(headers.map((key, value) => MapEntry(key, value))),
);
}
final responseExp = declareFinal('response').assign(InvokeExpression.newOf(
refer('http.${method.name}'),
[refer('uri')],
{
if (headerExp != null) 'headers': refer('headers'),
if (dataExp != null) 'body': refer('body'),
},
[],
).awaited);
final mainFunction = Method((m) {
final statusRef = refer('statusCode');
m
..name = 'main'
..returns = refer('void')
..modifier = MethodModifier.async
..body = Block((b) {
b.statements.add(uriExp.statement);
if (queryParamExp != null) {
b.statements.add(const Code('\n'));
b.statements.add(queryParamExp.statement);
}
if (uriReassignExps != null) {
b.statements.addAll(uriReassignExps.map((e) => e.statement));
}
if (dataExp != null) {
b.statements.add(const Code('\n'));
b.statements.add(dataExp.statement);
}
if (headerExp != null) {
b.statements.add(const Code('\n'));
b.statements.add(headerExp.statement);
}
b.statements.add(const Code('\n'));
b.statements.add(responseExp.statement);
b.statements.add(const Code('\n'));
b.statements.add(declareVar('statusCode', type: refer('int'))
.assign(refer('response').property('statusCode'))
.statement);
b.statements.add(declareIfElse(
condition: statusRef
.greaterOrEqualTo(literalNum(200))
.and(statusRef.lessThan(literalNum(300))),
body: [
refer('print').call([literalString(r'Status Code: $statusCode')]),
refer('print')
.call([literalString(r'Response Body: ${response.body}')]),
],
elseBody: [
refer('print')
.call([literalString(r'Error Status Code: $statusCode')]),
refer('print').call(
[literalString(r'Error Response Body: ${response.body}')]),
],
));
});
});
sbf.writeln(mainFunction.accept(emitter));
return DartFormatter(pageWidth: 160).format(sbf.toString());
}
} }

View File

@ -0,0 +1,52 @@
import 'package:code_builder/code_builder.dart';
Code _toStatement(Spec spec) {
if (spec is Expression) {
return spec.statement;
} else if (spec is Code) {
return spec;
} else {
throw UnimplementedError();
}
}
Block declareTryCatch({
required List<Spec> body,
required Map<String?, List<Spec>> onError,
bool showStackStrace = false,
}) {
return Block((b) {
b.statements.add(const Code('try'));
b.statements.add(const Code('{'));
b.statements.addAll(body.map(_toStatement).toList());
final entries = onError.entries;
for (var error in entries) {
b.statements.add(const Code('}'));
if (error.key != null) {
b.statements.add(Code('on ${error.key}'));
}
b.statements.add(Code(showStackStrace ? 'catch(e,s)' : 'catch(e)'));
b.statements.add(const Code('{'));
b.statements.addAll(error.value.map(_toStatement).toList());
if (entries.last.key == error.key) b.statements.add(const Code('}'));
}
});
}
Block declareIfElse({
required Expression condition,
required List<Spec> body,
required List<Spec> elseBody,
}) {
return Block.of([
const Code('if('),
condition.code,
const Code('){'),
...body.map(_toStatement),
const Code('} else {'),
...elseBody.map(_toStatement),
const Code('}'),
]);
}

20
lib/common/utils.dart Normal file
View File

@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/widgets/widgets.dart';
Future<void> saveCollection(
Map<String, dynamic> data, ScaffoldMessengerState sm) async {
var message = "";
try {
var pth = await getFileDownloadpath(null, "har");
if (pth != null) {
await saveFile(pth, jsonMapToBytes(data));
var sp = getShortPath(pth);
message = 'Saved to $sp';
}
} catch (e) {
message = "An error occurred while exporting.";
}
sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar(message, small: false));
}

View File

@ -63,14 +63,27 @@ const kP10 = EdgeInsets.all(10);
const kPt24o8 = EdgeInsets.only(top: 24, left: 8.0, right: 8.0, bottom: 8.0); const kPt24o8 = EdgeInsets.only(top: 24, left: 8.0, right: 8.0, bottom: 8.0);
const kPt5o10 = const kPt5o10 =
EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 10.0); EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 10.0);
const kPh20 = EdgeInsets.symmetric(
horizontal: 20,
);
const kPh20t40 = EdgeInsets.only( const kPh20t40 = EdgeInsets.only(
left: 20, left: 20,
right: 20, right: 20,
top: 40, top: 40,
); );
const kPh60 = EdgeInsets.symmetric(horizontal: 60); const kPh60 = EdgeInsets.symmetric(horizontal: 60);
const kP24CollectionPane = EdgeInsets.only(top: 24, left: 8.0, bottom: 8.0); const kP24CollectionPane = EdgeInsets.only(
const kP8CollectionPane = EdgeInsets.only(top: 8.0, left: 8.0, bottom: 8.0); top: 24,
left: 4.0,
//right: 4.0,
// bottom: 8.0,
);
const kP8CollectionPane = EdgeInsets.only(
top: 8.0,
left: 4.0,
//right: 4.0,
// bottom: 8.0,
);
const kPr8CollectionPane = EdgeInsets.only(right: 8.0); const kPr8CollectionPane = EdgeInsets.only(right: 8.0);
const kHSpacer4 = SizedBox(width: 4); const kHSpacer4 = SizedBox(width: 4);
@ -242,6 +255,7 @@ enum CodegenLanguage {
curl("cURL", "bash", "curl"), curl("cURL", "bash", "curl"),
har("HAR", "json", "har"), har("HAR", "json", "har"),
dartHttp("Dart (http)", "dart", "dart"), dartHttp("Dart (http)", "dart", "dart"),
dartDio("Dart (dio)", "dart", "dart"),
jsAxios("JavaScript (axios)", "javascript", "js"), jsAxios("JavaScript (axios)", "javascript", "js"),
jsFetch("JavaScript (fetch)", "javascript", "js"), jsFetch("JavaScript (fetch)", "javascript", "js"),
nodejsAxios("node.js (axios)", "javascript", "js"), nodejsAxios("node.js (axios)", "javascript", "js"),

View File

@ -6,16 +6,11 @@ import 'home_page/home_page.dart';
import 'intro_page.dart'; import 'intro_page.dart';
import 'settings_page.dart'; import 'settings_page.dart';
class Dashboard extends ConsumerStatefulWidget { class Dashboard extends ConsumerWidget {
const Dashboard({super.key}); const Dashboard({super.key});
@override @override
ConsumerState<Dashboard> createState() => _DashboardState(); Widget build(BuildContext context, WidgetRef ref) {
}
class _DashboardState extends ConsumerState<Dashboard> {
@override
Widget build(BuildContext context) {
final railIdx = ref.watch(navRailIndexStateProvider); final railIdx = ref.watch(navRailIndexStateProvider);
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
@ -50,13 +45,13 @@ class _DashboardState extends ConsumerState<Dashboard> {
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(bottom: 16.0), padding: const EdgeInsets.only(bottom: 16.0),
child: bottomButton(context, railIdx, 1, Icons.help, child: bottomButton(context, ref, railIdx, 1,
Icons.help_outline), Icons.help, Icons.help_outline),
), ),
Padding( Padding(
padding: const EdgeInsets.only(bottom: 16.0), padding: const EdgeInsets.only(bottom: 16.0),
child: bottomButton(context, railIdx, 2, Icons.settings, child: bottomButton(context, ref, railIdx, 2,
Icons.settings_outlined), Icons.settings, Icons.settings_outlined),
), ),
], ],
), ),
@ -99,6 +94,7 @@ class _DashboardState extends ConsumerState<Dashboard> {
TextButton bottomButton( TextButton bottomButton(
BuildContext context, BuildContext context,
WidgetRef ref,
int railIdx, int railIdx,
int buttonIdx, int buttonIdx,
IconData selectedIcon, IconData selectedIcon,

View File

@ -4,20 +4,9 @@ import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
class EditorPaneRequestURLCard extends StatefulWidget { class EditorPaneRequestURLCard extends StatelessWidget {
const EditorPaneRequestURLCard({super.key}); const EditorPaneRequestURLCard({super.key});
@override
State<EditorPaneRequestURLCard> createState() =>
_EditorPaneRequestURLCardState();
}
class _EditorPaneRequestURLCardState extends State<EditorPaneRequestURLCard> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Card(
@ -52,25 +41,13 @@ class _EditorPaneRequestURLCardState extends State<EditorPaneRequestURLCard> {
} }
} }
class DropdownButtonHTTPMethod extends ConsumerStatefulWidget { class DropdownButtonHTTPMethod extends ConsumerWidget {
const DropdownButtonHTTPMethod({ const DropdownButtonHTTPMethod({
super.key, super.key,
}); });
@override @override
ConsumerState<DropdownButtonHTTPMethod> createState() => Widget build(BuildContext context, WidgetRef ref) {
_DropdownButtonHTTPMethodState();
}
class _DropdownButtonHTTPMethodState
extends ConsumerState<DropdownButtonHTTPMethod> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final method = final method =
ref.watch(activeRequestModelProvider.select((value) => value?.method)); ref.watch(activeRequestModelProvider.select((value) => value?.method));
return DropdownButtonHttpMethod( return DropdownButtonHttpMethod(
@ -85,23 +62,13 @@ class _DropdownButtonHTTPMethodState
} }
} }
class URLTextField extends ConsumerStatefulWidget { class URLTextField extends ConsumerWidget {
const URLTextField({ const URLTextField({
super.key, super.key,
}); });
@override @override
ConsumerState<URLTextField> createState() => _URLTextFieldState(); Widget build(BuildContext context, WidgetRef ref) {
}
class _URLTextFieldState extends ConsumerState<URLTextField> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final activeId = ref.watch(activeIdStateProvider); final activeId = ref.watch(activeIdStateProvider);
return URLField( return URLField(
activeId: activeId!, activeId: activeId!,
@ -118,23 +85,13 @@ class _URLTextFieldState extends ConsumerState<URLTextField> {
} }
} }
class SendButton extends ConsumerStatefulWidget { class SendButton extends ConsumerWidget {
const SendButton({ const SendButton({
super.key, super.key,
}); });
@override @override
ConsumerState<SendButton> createState() => _SendButtonState(); Widget build(BuildContext context, WidgetRef ref) {
}
class _SendButtonState extends ConsumerState<SendButton> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final activeId = ref.watch(activeIdStateProvider); final activeId = ref.watch(activeIdStateProvider);
final sentRequestId = ref.watch(sentRequestIdStateProvider); final sentRequestId = ref.watch(sentRequestIdStateProvider);
return SendRequestButton( return SendRequestButton(

View File

@ -3,14 +3,9 @@ import 'package:apidash/widgets/widgets.dart';
import 'editor_pane/editor_pane.dart'; import 'editor_pane/editor_pane.dart';
import 'collection_pane.dart'; import 'collection_pane.dart';
class HomePage extends StatefulWidget { class HomePage extends StatelessWidget {
const HomePage({super.key}); const HomePage({super.key});
@override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Column( return const Column(

View File

@ -1,14 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/widgets/widgets.dart';
class IntroPage extends StatefulWidget { class IntroPage extends StatelessWidget {
const IntroPage({super.key}); const IntroPage({super.key});
@override
State<IntroPage> createState() => _IntroPageState();
}
class _IntroPageState extends State<IntroPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const IntroMessage(); return const IntroMessage();

View File

@ -2,36 +2,40 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/providers.dart'; import '../providers/providers.dart';
import '../widgets/widgets.dart'; import '../widgets/widgets.dart';
import '../utils/utils.dart'; import '../common/utils.dart';
import 'package:apidash/consts.dart'; import '../consts.dart';
class SettingsPage extends ConsumerStatefulWidget { class SettingsPage extends ConsumerWidget {
const SettingsPage({super.key}); const SettingsPage({super.key});
@override @override
ConsumerState<SettingsPage> createState() => _SettingsPageState(); Widget build(BuildContext context, WidgetRef ref) {
}
class _SettingsPageState extends ConsumerState<SettingsPage> {
@override
Widget build(BuildContext context) {
final settings = ref.watch(settingsProvider); final settings = ref.watch(settingsProvider);
final clearingData = ref.watch(clearDataStateProvider); final clearingData = ref.watch(clearDataStateProvider);
var sm = ScaffoldMessenger.of(context); var sm = ScaffoldMessenger.of(context);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Container( Padding(
constraints: const BoxConstraints(maxWidth: 800), padding: kPh20t40,
child: kIsDesktop
? Text("Settings",
style: Theme.of(context).textTheme.headlineLarge)
: const SizedBox.shrink(),
),
kIsDesktop
? const Padding(
padding: kPh20,
child: Divider(
height: 1,
),
)
: const SizedBox.shrink(),
Expanded(
child: ListView( child: ListView(
padding: kPh20t40,
shrinkWrap: true, shrinkWrap: true,
padding: kPh20,
children: [ children: [
kIsDesktop
? Text("Settings",
style: Theme.of(context).textTheme.headlineLarge)
: const SizedBox.shrink(),
kIsDesktop ? const Divider() : const SizedBox.shrink(),
SwitchListTile( SwitchListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
hoverColor: kColorTransparent, hoverColor: kColorTransparent,
@ -114,26 +118,18 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
title: const Text('Export Data'), title: const Text('Export Data'),
subtitle: const Text( subtitle: const Text(
'Export your collection to HAR (HTTP Archive format).\nVersion control this file or import in other API clients.'), 'Export your collection to HAR (HTTP Archive format).\nVersion control this file or import in other API clients.'),
trailing: FilledButton( trailing: FilledButton.icon(
onPressed: () async { onPressed: () async {
var message = ""; var data = await ref
try { .read(collectionStateNotifierProvider.notifier)
var data = await ref .exportDataToHAR();
.read(collectionStateNotifierProvider.notifier) await saveCollection(data, sm);
.exportDataToHAR();
var pth = await getFileDownloadpath(null, "har");
if (pth != null) {
await saveFile(pth, jsonMapToBytes(data));
var sp = getShortPath(pth);
message = 'Saved to $sp';
}
} catch (e) {
message = "An error occurred while exporting.";
}
sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar(message, small: false));
}, },
child: const Text("Export Data"), label: const Text("Export"),
icon: const Icon(
Icons.arrow_outward_rounded,
size: 20,
),
), ),
), ),
ListTile( ListTile(
@ -141,7 +137,7 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
hoverColor: kColorTransparent, hoverColor: kColorTransparent,
title: const Text('Clear Data'), title: const Text('Clear Data'),
subtitle: const Text('Delete all requests data from the disk'), subtitle: const Text('Delete all requests data from the disk'),
trailing: FilledButton.tonal( trailing: FilledButton.tonalIcon(
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
backgroundColor: settings.isDark backgroundColor: settings.isDark
? kColorDarkDanger ? kColorDarkDanger
@ -185,7 +181,11 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
], ],
), ),
), ),
child: const Text("Clear Data"), label: const Text("Clear"),
icon: const Icon(
Icons.delete_forever_rounded,
size: 20,
),
), ),
), ),
], ],

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
const String kDataBox = "data"; const String kDataBox = "apidash-data";
const String kKeyDataBoxIds = "ids"; const String kKeyDataBoxIds = "ids";
const String kSettingsBox = "settings"; const String kSettingsBox = "apidash-settings";
Future<void> openBoxes() async { Future<void> openBoxes() async {
await Hive.initFlutter(); await Hive.initFlutter();

View File

@ -7,6 +7,10 @@ import 'package:path_provider/path_provider.dart';
const uuid = Uuid(); const uuid = Uuid();
String getNewUuid() {
return uuid.v1();
}
String? getFileExtension(String? mimeType) { String? getFileExtension(String? mimeType) {
if (mimeType == null) { if (mimeType == null) {
return null; return null;

View File

@ -5,7 +5,7 @@ import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
import "snackbars.dart"; import "snackbars.dart";
class CopyButton extends StatefulWidget { class CopyButton extends StatelessWidget {
const CopyButton({ const CopyButton({
super.key, super.key,
required this.toCopy, required this.toCopy,
@ -15,21 +15,16 @@ class CopyButton extends StatefulWidget {
final String toCopy; final String toCopy;
final bool showLabel; final bool showLabel;
@override
State<CopyButton> createState() => _CopyButtonState();
}
class _CopyButtonState extends State<CopyButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var sm = ScaffoldMessenger.of(context); var sm = ScaffoldMessenger.of(context);
return Tooltip( return Tooltip(
message: widget.showLabel ? '' : kLabelCopy, message: showLabel ? '' : kLabelCopy,
child: SizedBox( child: SizedBox(
width: widget.showLabel ? null : kTextButtonMinWidth, width: showLabel ? null : kTextButtonMinWidth,
child: TextButton( child: TextButton(
onPressed: () async { onPressed: () async {
await Clipboard.setData(ClipboardData(text: widget.toCopy)); await Clipboard.setData(ClipboardData(text: toCopy));
sm.hideCurrentSnackBar(); sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar("Copied")); sm.showSnackBar(getSnackBar("Copied"));
}, },
@ -40,7 +35,7 @@ class _CopyButtonState extends State<CopyButton> {
Icons.content_copy, Icons.content_copy,
size: 20, size: 20,
), ),
if (widget.showLabel) const Text(kLabelCopy) if (showLabel) const Text(kLabelCopy)
], ],
), ),
), ),
@ -49,7 +44,7 @@ class _CopyButtonState extends State<CopyButton> {
} }
} }
class SendRequestButton extends StatefulWidget { class SendRequestButton extends StatelessWidget {
const SendRequestButton({ const SendRequestButton({
super.key, super.key,
required this.activeId, required this.activeId,
@ -61,29 +56,17 @@ class SendRequestButton extends StatefulWidget {
final String? sentRequestId; final String? sentRequestId;
final void Function() onTap; final void Function() onTap;
@override
State<SendRequestButton> createState() => _SendRequestButtonState();
}
class _SendRequestButtonState extends State<SendRequestButton> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool disable = widget.sentRequestId != null; bool disable = sentRequestId != null;
return FilledButton( return FilledButton(
onPressed: disable ? null : widget.onTap, onPressed: disable ? null : onTap,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
disable disable
? (widget.activeId == widget.sentRequestId ? (activeId == sentRequestId ? kLabelSending : kLabelBusy)
? kLabelSending
: kLabelBusy)
: kLabelSend, : kLabelSend,
style: kTextStyleButton, style: kTextStyleButton,
), ),
@ -99,7 +82,7 @@ class _SendRequestButtonState extends State<SendRequestButton> {
} }
} }
class SaveInDownloadsButton extends StatefulWidget { class SaveInDownloadsButton extends StatelessWidget {
const SaveInDownloadsButton({ const SaveInDownloadsButton({
super.key, super.key,
this.content, this.content,
@ -115,29 +98,24 @@ class SaveInDownloadsButton extends StatefulWidget {
final String? name; final String? name;
final bool showLabel; final bool showLabel;
@override
State<SaveInDownloadsButton> createState() => _SaveInDownloadsButtonState();
}
class _SaveInDownloadsButtonState extends State<SaveInDownloadsButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var sm = ScaffoldMessenger.of(context); var sm = ScaffoldMessenger.of(context);
return Tooltip( return Tooltip(
message: widget.showLabel ? '' : kLabelDownload, message: showLabel ? '' : kLabelDownload,
child: SizedBox( child: SizedBox(
width: widget.showLabel ? null : kTextButtonMinWidth, width: showLabel ? null : kTextButtonMinWidth,
child: TextButton( child: TextButton(
onPressed: (widget.content != null) onPressed: (content != null)
? () async { ? () async {
var message = ""; var message = "";
var path = await getFileDownloadpath( var path = await getFileDownloadpath(
widget.name, name,
widget.ext ?? getFileExtension(widget.mimeType), ext ?? getFileExtension(mimeType),
); );
if (path != null) { if (path != null) {
try { try {
await saveFile(path, widget.content!); await saveFile(path, content!);
var sp = getShortPath(path); var sp = getShortPath(path);
message = 'Saved to $sp'; message = 'Saved to $sp';
} catch (e) { } catch (e) {
@ -157,7 +135,7 @@ class _SaveInDownloadsButtonState extends State<SaveInDownloadsButton> {
Icons.download, Icons.download,
size: 20, size: 20,
), ),
if (widget.showLabel) const Text(kLabelDownload) if (showLabel) const Text(kLabelDownload)
], ],
), ),
), ),
@ -166,7 +144,7 @@ class _SaveInDownloadsButtonState extends State<SaveInDownloadsButton> {
} }
} }
class RepoButton extends StatefulWidget { class RepoButton extends StatelessWidget {
const RepoButton({ const RepoButton({
super.key, super.key,
this.text, this.text,
@ -176,15 +154,10 @@ class RepoButton extends StatefulWidget {
final String? text; final String? text;
final IconData? icon; final IconData? icon;
@override
State<RepoButton> createState() => _RepoButtonState();
}
class _RepoButtonState extends State<RepoButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var label = widget.text ?? "GitHub"; var label = text ?? "GitHub";
if (widget.icon == null) { if (icon == null) {
return FilledButton( return FilledButton(
onPressed: () { onPressed: () {
launchUrl(Uri.parse(kGitUrl)); launchUrl(Uri.parse(kGitUrl));
@ -200,7 +173,7 @@ class _RepoButtonState extends State<RepoButton> {
launchUrl(Uri.parse(kGitUrl)); launchUrl(Uri.parse(kGitUrl));
}, },
icon: Icon( icon: Icon(
widget.icon, icon,
size: 20.0, size: 20.0,
), ),
label: Text( label: Text(
@ -211,7 +184,7 @@ class _RepoButtonState extends State<RepoButton> {
} }
} }
class DiscordButton extends StatefulWidget { class DiscordButton extends StatelessWidget {
const DiscordButton({ const DiscordButton({
super.key, super.key,
this.text, this.text,
@ -219,14 +192,9 @@ class DiscordButton extends StatefulWidget {
final String? text; final String? text;
@override
State<DiscordButton> createState() => _DiscordButtonState();
}
class _DiscordButtonState extends State<DiscordButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var label = widget.text ?? 'Discord Server'; var label = text ?? 'Discord Server';
return FilledButton.icon( return FilledButton.icon(
onPressed: () { onPressed: () {
launchUrl(Uri.parse(kDiscordUrl)); launchUrl(Uri.parse(kDiscordUrl));
@ -242,3 +210,27 @@ class _DiscordButtonState extends State<DiscordButton> {
); );
} }
} }
class SaveButton extends StatelessWidget {
const SaveButton({
super.key,
this.onPressed,
});
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
return TextButton.icon(
onPressed: onPressed,
icon: const Icon(
Icons.save,
size: 20,
),
label: const Text(
kLabelSave,
style: kTextStyleButton,
),
);
}
}

View File

@ -129,15 +129,11 @@ class SidebarRequestCard extends StatelessWidget {
} }
} }
class RequestDetailsCard extends StatefulWidget { class RequestDetailsCard extends StatelessWidget {
const RequestDetailsCard({super.key, this.child}); const RequestDetailsCard({super.key, this.child});
final Widget? child; final Widget? child;
@override @override
State<RequestDetailsCard> createState() => _RequestDetailsCardState();
}
class _RequestDetailsCardState extends State<RequestDetailsCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Card(
@ -148,7 +144,7 @@ class _RequestDetailsCardState extends State<RequestDetailsCard> {
borderRadius: kBorderRadius12, borderRadius: kBorderRadius12,
), ),
elevation: 0, elevation: 0,
child: widget.child, child: child,
); );
} }
} }

View File

@ -97,7 +97,7 @@ List<TextSpan> generateSpans(
return spans; return spans;
} }
class ViewCodePane extends StatefulWidget { class ViewCodePane extends StatelessWidget {
const ViewCodePane({ const ViewCodePane({
super.key, super.key,
required this.code, required this.code,
@ -109,11 +109,6 @@ class ViewCodePane extends StatefulWidget {
final CodegenLanguage codegenLanguage; final CodegenLanguage codegenLanguage;
final Function(CodegenLanguage?) onChangedCodegenLanguage; final Function(CodegenLanguage?) onChangedCodegenLanguage;
@override
State<ViewCodePane> createState() => _ViewCodePaneState();
}
class _ViewCodePaneState extends State<ViewCodePane> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var codeTheme = Theme.of(context).brightness == Brightness.light var codeTheme = Theme.of(context).brightness == Brightness.light
@ -145,17 +140,17 @@ class _ViewCodePaneState extends State<ViewCodePane> {
children: [ children: [
Expanded( Expanded(
child: DropdownButtonCodegenLanguage( child: DropdownButtonCodegenLanguage(
codegenLanguage: widget.codegenLanguage, codegenLanguage: codegenLanguage,
onChanged: widget.onChangedCodegenLanguage, onChanged: onChangedCodegenLanguage,
), ),
), ),
CopyButton( CopyButton(
toCopy: widget.code, toCopy: code,
showLabel: showLabel, showLabel: showLabel,
), ),
SaveInDownloadsButton( SaveInDownloadsButton(
content: stringToBytes(widget.code), content: stringToBytes(code),
ext: widget.codegenLanguage.ext, ext: codegenLanguage.ext,
showLabel: showLabel, showLabel: showLabel,
) )
], ],
@ -168,9 +163,9 @@ class _ViewCodePaneState extends State<ViewCodePane> {
padding: kP8, padding: kP8,
decoration: textContainerdecoration, decoration: textContainerdecoration,
child: CodeGenPreviewer( child: CodeGenPreviewer(
code: widget.code, code: code,
theme: codeTheme, theme: codeTheme,
language: widget.codegenLanguage.codeHighlightLang, language: codegenLanguage.codeHighlightLang,
textStyle: kCodeStyle, textStyle: kCodeStyle,
), ),
), ),

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:apidash/utils/utils.dart'; import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
class DropdownButtonHttpMethod extends StatefulWidget { class DropdownButtonHttpMethod extends StatelessWidget {
const DropdownButtonHttpMethod({ const DropdownButtonHttpMethod({
super.key, super.key,
this.method, this.method,
@ -12,30 +12,19 @@ class DropdownButtonHttpMethod extends StatefulWidget {
final HTTPVerb? method; final HTTPVerb? method;
final void Function(HTTPVerb? value)? onChanged; final void Function(HTTPVerb? value)? onChanged;
@override
State<DropdownButtonHttpMethod> createState() =>
_DropdownButtonHttpMethodState();
}
class _DropdownButtonHttpMethodState extends State<DropdownButtonHttpMethod> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface; final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<HTTPVerb>( return DropdownButton<HTTPVerb>(
focusColor: surfaceColor, focusColor: surfaceColor,
value: widget.method, value: method,
icon: const Icon(Icons.unfold_more_rounded), icon: const Icon(Icons.unfold_more_rounded),
elevation: 4, elevation: 4,
underline: Container( underline: Container(
height: 0, height: 0,
), ),
borderRadius: kBorderRadius12, borderRadius: kBorderRadius12,
onChanged: widget.onChanged, onChanged: onChanged,
items: HTTPVerb.values.map<DropdownMenuItem<HTTPVerb>>((HTTPVerb value) { items: HTTPVerb.values.map<DropdownMenuItem<HTTPVerb>>((HTTPVerb value) {
return DropdownMenuItem<HTTPVerb>( return DropdownMenuItem<HTTPVerb>(
value: value, value: value,
@ -58,7 +47,7 @@ class _DropdownButtonHttpMethodState extends State<DropdownButtonHttpMethod> {
} }
} }
class DropdownButtonContentType extends StatefulWidget { class DropdownButtonContentType extends StatelessWidget {
const DropdownButtonContentType({ const DropdownButtonContentType({
super.key, super.key,
this.contentType, this.contentType,
@ -68,18 +57,12 @@ class DropdownButtonContentType extends StatefulWidget {
final ContentType? contentType; final ContentType? contentType;
final void Function(ContentType?)? onChanged; final void Function(ContentType?)? onChanged;
@override
State<DropdownButtonContentType> createState() =>
_DropdownButtonContentTypeState();
}
class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface; final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<ContentType>( return DropdownButton<ContentType>(
focusColor: surfaceColor, focusColor: surfaceColor,
value: widget.contentType, value: contentType,
icon: const Icon( icon: const Icon(
Icons.unfold_more_rounded, Icons.unfold_more_rounded,
size: 16, size: 16,
@ -91,7 +74,7 @@ class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
underline: Container( underline: Container(
height: 0, height: 0,
), ),
onChanged: widget.onChanged, onChanged: onChanged,
borderRadius: kBorderRadius12, borderRadius: kBorderRadius12,
items: ContentType.values items: ContentType.values
.map<DropdownMenuItem<ContentType>>((ContentType value) { .map<DropdownMenuItem<ContentType>>((ContentType value) {
@ -110,28 +93,22 @@ class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
} }
} }
class DropdownButtonCodegenLanguage extends StatefulWidget { class DropdownButtonCodegenLanguage extends StatelessWidget {
const DropdownButtonCodegenLanguage({ const DropdownButtonCodegenLanguage({
super.key, super.key,
this.codegenLanguage, this.codegenLanguage,
this.onChanged, this.onChanged,
}); });
@override
State<DropdownButtonCodegenLanguage> createState() =>
_DropdownButtonCodegenLanguageState();
final CodegenLanguage? codegenLanguage; final CodegenLanguage? codegenLanguage;
final void Function(CodegenLanguage?)? onChanged; final void Function(CodegenLanguage?)? onChanged;
}
class _DropdownButtonCodegenLanguageState
extends State<DropdownButtonCodegenLanguage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface; final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<CodegenLanguage>( return DropdownButton<CodegenLanguage>(
focusColor: surfaceColor, focusColor: surfaceColor,
value: widget.codegenLanguage, value: codegenLanguage,
icon: const Icon( icon: const Icon(
Icons.unfold_more_rounded, Icons.unfold_more_rounded,
size: 16, size: 16,
@ -143,7 +120,7 @@ class _DropdownButtonCodegenLanguageState
underline: Container( underline: Container(
height: 0, height: 0,
), ),
onChanged: widget.onChanged, onChanged: onChanged,
borderRadius: kBorderRadius12, borderRadius: kBorderRadius12,
items: CodegenLanguage.values items: CodegenLanguage.values
.map<DropdownMenuItem<CodegenLanguage>>((CodegenLanguage value) { .map<DropdownMenuItem<CodegenLanguage>>((CodegenLanguage value) {

View File

@ -5,16 +5,11 @@ import '../consts.dart';
import 'markdown.dart'; import 'markdown.dart';
import 'error_message.dart'; import 'error_message.dart';
class IntroMessage extends StatefulWidget { class IntroMessage extends StatelessWidget {
const IntroMessage({ const IntroMessage({
super.key, super.key,
}); });
@override
State<IntroMessage> createState() => _IntroMessageState();
}
class _IntroMessageState extends State<IntroMessage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
late String text; late String text;

View File

@ -4,7 +4,7 @@ import 'package:markdown/markdown.dart' as md;
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'buttons.dart'; import 'buttons.dart';
class CustomMarkdown extends StatefulWidget { class CustomMarkdown extends StatelessWidget {
const CustomMarkdown({ const CustomMarkdown({
super.key, super.key,
required this.data, required this.data,
@ -13,11 +13,6 @@ class CustomMarkdown extends StatefulWidget {
final String data; final String data;
final EdgeInsets padding; final EdgeInsets padding;
@override
State<CustomMarkdown> createState() => _CustomMarkdownState();
}
class _CustomMarkdownState extends State<CustomMarkdown> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mdStyleSheet = MarkdownStyleSheet( final mdStyleSheet = MarkdownStyleSheet(
@ -25,9 +20,9 @@ class _CustomMarkdownState extends State<CustomMarkdown> {
p: Theme.of(context).textTheme.titleMedium, p: Theme.of(context).textTheme.titleMedium,
); );
return Markdown( return Markdown(
padding: widget.padding, padding: padding,
styleSheet: mdStyleSheet, styleSheet: mdStyleSheet,
data: widget.data, data: data,
selectable: true, selectable: true,
extensionSet: md.ExtensionSet.gitHubFlavored, extensionSet: md.ExtensionSet.gitHubFlavored,
onTapLink: (text, href, title) { onTapLink: (text, href, title) {

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
class RequestCardMenu extends StatefulWidget { class RequestCardMenu extends StatelessWidget {
const RequestCardMenu({ const RequestCardMenu({
super.key, super.key,
this.onSelected, this.onSelected,
@ -9,18 +9,13 @@ class RequestCardMenu extends StatefulWidget {
final Function(RequestItemMenuOption)? onSelected; final Function(RequestItemMenuOption)? onSelected;
@override
State<RequestCardMenu> createState() => _RequestCardMenuState();
}
class _RequestCardMenuState extends State<RequestCardMenu> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PopupMenuButton<RequestItemMenuOption>( return PopupMenuButton<RequestItemMenuOption>(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
splashRadius: 14, splashRadius: 14,
iconSize: 14, iconSize: 14,
onSelected: widget.onSelected, onSelected: onSelected,
itemBuilder: (BuildContext context) => itemBuilder: (BuildContext context) =>
<PopupMenuEntry<RequestItemMenuOption>>[ <PopupMenuEntry<RequestItemMenuOption>>[
const PopupMenuItem<RequestItemMenuOption>( const PopupMenuItem<RequestItemMenuOption>(

View File

@ -49,7 +49,7 @@ class SendingWidget extends StatelessWidget {
} }
} }
class ResponsePaneHeader extends StatefulWidget { class ResponsePaneHeader extends StatelessWidget {
const ResponsePaneHeader({ const ResponsePaneHeader({
super.key, super.key,
this.responseStatus, this.responseStatus,
@ -60,11 +60,7 @@ class ResponsePaneHeader extends StatefulWidget {
final int? responseStatus; final int? responseStatus;
final String? message; final String? message;
final Duration? time; final Duration? time;
@override
State<ResponsePaneHeader> createState() => _ResponsePaneHeaderState();
}
class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
@ -81,10 +77,10 @@ class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
text: "Response (", text: "Response (",
), ),
TextSpan( TextSpan(
text: "${widget.responseStatus}", text: "$responseStatus",
style: TextStyle( style: TextStyle(
color: getResponseStatusCodeColor( color: getResponseStatusCodeColor(
widget.responseStatus, responseStatus,
brightness: Theme.of(context).brightness, brightness: Theme.of(context).brightness,
), ),
fontFamily: kCodeStyle.fontFamily, fontFamily: kCodeStyle.fontFamily,
@ -100,13 +96,13 @@ class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
kHSpacer20, kHSpacer20,
Expanded( Expanded(
child: Text( child: Text(
widget.message ?? "", message ?? "",
softWrap: false, softWrap: false,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.titleMedium!.copyWith( style: Theme.of(context).textTheme.titleMedium!.copyWith(
fontFamily: kCodeStyle.fontFamily, fontFamily: kCodeStyle.fontFamily,
color: getResponseStatusCodeColor( color: getResponseStatusCodeColor(
widget.responseStatus, responseStatus,
brightness: Theme.of(context).brightness, brightness: Theme.of(context).brightness,
), ),
), ),
@ -114,7 +110,7 @@ class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
), ),
kHSpacer20, kHSpacer20,
Text( Text(
humanizeDuration(widget.time), humanizeDuration(time),
style: Theme.of(context).textTheme.titleMedium!.copyWith( style: Theme.of(context).textTheme.titleMedium!.copyWith(
fontFamily: kCodeStyle.fontFamily, fontFamily: kCodeStyle.fontFamily,
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
@ -207,7 +203,7 @@ class _ResponseTabViewState extends State<ResponseTabView>
} }
} }
class ResponseHeadersHeader extends StatefulWidget { class ResponseHeadersHeader extends StatelessWidget {
const ResponseHeadersHeader({ const ResponseHeadersHeader({
super.key, super.key,
required this.map, required this.map,
@ -216,11 +212,7 @@ class ResponseHeadersHeader extends StatefulWidget {
final Map map; final Map map;
final String name; final String name;
@override
State<ResponseHeadersHeader> createState() => _ResponseHeadersHeaderState();
}
class _ResponseHeadersHeaderState extends State<ResponseHeadersHeader> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(
@ -229,15 +221,15 @@ class _ResponseHeadersHeaderState extends State<ResponseHeadersHeader> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"${widget.name} (${widget.map.length} items)", "$name (${map.length} items)",
style: Theme.of(context).textTheme.labelLarge!.copyWith( style: Theme.of(context).textTheme.labelLarge!.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
if (widget.map.isNotEmpty) if (map.isNotEmpty)
CopyButton( CopyButton(
toCopy: kEncoder.convert(widget.map), toCopy: kEncoder.convert(map),
), ),
], ],
), ),
@ -247,7 +239,7 @@ class _ResponseHeadersHeaderState extends State<ResponseHeadersHeader> {
const kHeaderRow = ["Header Name", "Header Value"]; const kHeaderRow = ["Header Name", "Header Value"];
class ResponseHeaders extends StatefulWidget { class ResponseHeaders extends StatelessWidget {
const ResponseHeaders({ const ResponseHeaders({
super.key, super.key,
required this.responseHeaders, required this.responseHeaders,
@ -256,11 +248,7 @@ class ResponseHeaders extends StatefulWidget {
final Map responseHeaders; final Map responseHeaders;
final Map requestHeaders; final Map requestHeaders;
@override
State<ResponseHeaders> createState() => _ResponseHeadersState();
}
class _ResponseHeadersState extends State<ResponseHeaders> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
@ -268,25 +256,25 @@ class _ResponseHeadersState extends State<ResponseHeaders> {
child: ListView( child: ListView(
children: [ children: [
ResponseHeadersHeader( ResponseHeadersHeader(
map: widget.responseHeaders, map: responseHeaders,
name: "Response Headers", name: "Response Headers",
), ),
if (widget.responseHeaders.isNotEmpty) kVSpacer5, if (responseHeaders.isNotEmpty) kVSpacer5,
if (widget.responseHeaders.isNotEmpty) if (responseHeaders.isNotEmpty)
MapTable( MapTable(
map: widget.responseHeaders, map: responseHeaders,
colNames: kHeaderRow, colNames: kHeaderRow,
firstColumnHeaderCase: true, firstColumnHeaderCase: true,
), ),
kVSpacer10, kVSpacer10,
ResponseHeadersHeader( ResponseHeadersHeader(
map: widget.requestHeaders, map: requestHeaders,
name: "Request Headers", name: "Request Headers",
), ),
if (widget.requestHeaders.isNotEmpty) kVSpacer5, if (requestHeaders.isNotEmpty) kVSpacer5,
if (widget.requestHeaders.isNotEmpty) if (requestHeaders.isNotEmpty)
MapTable( MapTable(
map: widget.requestHeaders, map: requestHeaders,
colNames: kHeaderRow, colNames: kHeaderRow,
firstColumnHeaderCase: true, firstColumnHeaderCase: true,
), ),
@ -296,21 +284,17 @@ class _ResponseHeadersState extends State<ResponseHeaders> {
} }
} }
class ResponseBody extends StatefulWidget { class ResponseBody extends StatelessWidget {
const ResponseBody({ const ResponseBody({
super.key, super.key,
this.activeRequestModel, this.activeRequestModel,
}); });
final RequestModel? activeRequestModel; final RequestModel? activeRequestModel;
@override
State<ResponseBody> createState() => _ResponseBodyState();
}
class _ResponseBodyState extends State<ResponseBody> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final responseModel = widget.activeRequestModel?.responseModel; final responseModel = activeRequestModel?.responseModel;
if (responseModel == null) { if (responseModel == null) {
return const ErrorMessage( return const ErrorMessage(
message: message:
@ -348,7 +332,7 @@ class _ResponseBodyState extends State<ResponseBody> {
} }
return BodySuccess( return BodySuccess(
key: Key("${widget.activeRequestModel!.id}-response"), key: Key("${activeRequestModel!.id}-response"),
mediaType: mediaType, mediaType: mediaType,
options: options, options: options,
bytes: responseModel.bodyBytes!, bytes: responseModel.bodyBytes!,

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:apidash/utils/utils.dart'; import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
class MapTable extends StatefulWidget { class MapTable extends StatelessWidget {
const MapTable( const MapTable(
{super.key, {super.key,
required this.map, required this.map,
@ -13,11 +13,6 @@ class MapTable extends StatefulWidget {
final List<String> colNames; final List<String> colNames;
final bool firstColumnHeaderCase; final bool firstColumnHeaderCase;
@override
State<MapTable> createState() => _MapTableState();
}
class _MapTableState extends State<MapTable> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Table( return Table(
@ -33,7 +28,7 @@ class _MapTableState extends State<MapTable> {
defaultVerticalAlignment: TableCellVerticalAlignment.middle, defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [ children: [
TableRow( TableRow(
children: widget.colNames children: colNames
.map<TableCell>( .map<TableCell>(
(e) => TableCell( (e) => TableCell(
verticalAlignment: TableCellVerticalAlignment.top, verticalAlignment: TableCellVerticalAlignment.top,
@ -51,7 +46,7 @@ class _MapTableState extends State<MapTable> {
) )
.toList(), .toList(),
), ),
...widget.map.entries.map<TableRow>( ...map.entries.map<TableRow>(
(entry) => TableRow( (entry) => TableRow(
children: [ children: [
TableCell( TableCell(
@ -59,7 +54,7 @@ class _MapTableState extends State<MapTable> {
child: Padding( child: Padding(
padding: kP1, padding: kP1,
child: SelectableText( child: SelectableText(
widget.firstColumnHeaderCase firstColumnHeaderCase
? formatHeaderCase(entry.key) ? formatHeaderCase(entry.key)
: entry.key, : entry.key,
style: kCodeStyle.copyWith( style: kCodeStyle.copyWith(

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
class URLField extends StatefulWidget { class URLField extends StatelessWidget {
const URLField({ const URLField({
super.key, super.key,
required this.activeId, required this.activeId,
@ -13,21 +13,11 @@ class URLField extends StatefulWidget {
final String? initialValue; final String? initialValue;
final void Function(String)? onChanged; final void Function(String)? onChanged;
@override
State<URLField> createState() => _URLFieldState();
}
class _URLFieldState extends State<URLField> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextFormField( return TextFormField(
key: Key("url-${widget.activeId}"), key: Key("url-$activeId"),
initialValue: widget.initialValue, initialValue: initialValue,
style: kCodeStyle, style: kCodeStyle,
decoration: InputDecoration( decoration: InputDecoration(
hintText: kHintTextUrlCard, hintText: kHintTextUrlCard,
@ -38,12 +28,12 @@ class _URLFieldState extends State<URLField> {
), ),
border: InputBorder.none, border: InputBorder.none,
), ),
onChanged: widget.onChanged, onChanged: onChanged,
); );
} }
} }
class CellField extends StatefulWidget { class CellField extends StatelessWidget {
const CellField({ const CellField({
super.key, super.key,
required this.keyId, required this.keyId,
@ -59,41 +49,36 @@ class CellField extends StatefulWidget {
final void Function(String)? onChanged; final void Function(String)? onChanged;
final ColorScheme? colorScheme; final ColorScheme? colorScheme;
@override
State<CellField> createState() => _CellFieldState();
}
class _CellFieldState extends State<CellField> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var colorScheme = widget.colorScheme ?? Theme.of(context).colorScheme; var clrScheme = colorScheme ?? Theme.of(context).colorScheme;
return TextFormField( return TextFormField(
key: Key(widget.keyId), key: Key(keyId),
initialValue: widget.initialValue, initialValue: initialValue,
style: kCodeStyle.copyWith( style: kCodeStyle.copyWith(
color: colorScheme.onSurface, color: clrScheme.onSurface,
), ),
decoration: InputDecoration( decoration: InputDecoration(
hintStyle: kCodeStyle.copyWith( hintStyle: kCodeStyle.copyWith(
color: colorScheme.outline.withOpacity( color: clrScheme.outline.withOpacity(
kHintOpacity, kHintOpacity,
), ),
), ),
hintText: widget.hintText, hintText: hintText,
focusedBorder: UnderlineInputBorder( focusedBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: colorScheme.primary.withOpacity( color: clrScheme.primary.withOpacity(
kHintOpacity, kHintOpacity,
), ),
), ),
), ),
enabledBorder: UnderlineInputBorder( enabledBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: colorScheme.surfaceVariant, color: clrScheme.surfaceVariant,
), ),
), ),
), ),
onChanged: widget.onChanged, onChanged: onChanged,
); );
} }
} }

View File

@ -12,10 +12,14 @@ class MethodBox extends StatelessWidget {
if (method == HTTPVerb.delete) { if (method == HTTPVerb.delete) {
text = "DEL"; text = "DEL";
} }
if (method == HTTPVerb.patch) {
text = "PAT";
}
return SizedBox( return SizedBox(
width: 28, width: 24,
child: Text( child: Text(
text, text,
textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 8, fontSize: 8,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View File

@ -1,23 +1,24 @@
export 'editor.dart';
export 'buttons.dart'; export 'buttons.dart';
export 'tables.dart'; export 'cards.dart';
export 'previewer.dart'; export 'checkbox.dart';
export 'code_previewer.dart'; export 'code_previewer.dart';
export 'codegen_previewer.dart'; export 'codegen_previewer.dart';
export 'error_message.dart';
export 'dropdowns.dart'; export 'dropdowns.dart';
export 'splitviews.dart'; export 'editor.dart';
export 'texts.dart'; export 'error_message.dart';
export 'checkbox.dart';
export 'textfields.dart';
export 'headerfield.dart'; export 'headerfield.dart';
export 'menus.dart';
export 'cards.dart';
export 'intro_message.dart'; export 'intro_message.dart';
export 'json_previewer.dart';
export 'markdown.dart';
export 'menus.dart';
export 'previewer.dart';
export 'request_widgets.dart'; export 'request_widgets.dart';
export 'response_widgets.dart'; export 'response_widgets.dart';
export 'snackbars.dart'; export 'snackbars.dart';
export 'markdown.dart'; export 'splitviews.dart';
export 'uint8_audio_player.dart'; export 'tables.dart';
export 'tabs.dart'; export 'tabs.dart';
export 'json_previewer.dart'; export 'textfields.dart';
export 'texts.dart';
export 'uint8_audio_player.dart';
export 'window_caption.dart';

View File

@ -5,26 +5,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _fe_analyzer_shared name: _fe_analyzer_shared
sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "61.0.0" version: "64.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.13.0" version: "6.2.0"
archive: archive:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03" sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.4.6" version: "3.4.9"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -45,10 +45,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: audio_session name: audio_session
sha256: "8a2bc5e30520e18f3fb0e366793d78057fb64cd5287862c76af0c8771f2a52ad" sha256: "6fdf255ed3af86535c96452c33ecff1245990bb25a605bfb1958661ccc3d467f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.16" version: "0.1.18"
axis_layout: axis_layout:
dependency: transitive dependency: transitive
description: description:
@ -61,10 +61,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: barcode name: barcode
sha256: "789f898eef0bd88312470bdb2cc996f895ad7dd5f89e9adde84b204546a90b45" sha256: "2a8b2ee065f419c2aeda141436cc556d91ae772d220fd80679f4d431d6c2ab43"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.4" version: "2.2.5"
bidi: bidi:
dependency: transitive dependency: transitive
description: description:
@ -101,26 +101,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: build_daemon name: build_daemon
sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.1"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
name: build_resolvers name: build_resolvers
sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8" sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.2"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.6" version: "2.4.7"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
@ -141,10 +141,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: built_value name: built_value
sha256: a8de5955205b4d1dbbbc267daddf2178bd737e4bab8987c04a500478c9651e74 sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.6.3" version: "8.8.1"
characters: characters:
dependency: transitive dependency: transitive
description: description:
@ -165,10 +165,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: cli_util name: cli_util
sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.0" version: "0.4.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -178,13 +178,13 @@ packages:
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
code_builder: code_builder:
dependency: transitive dependency: "direct main"
description: description:
name: code_builder name: code_builder
sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.7.0" version: "4.9.0"
collection: collection:
dependency: "direct main" dependency: "direct main"
description: description:
@ -205,10 +205,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: coverage name: coverage
sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb" sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.6.4" version: "1.7.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -218,13 +218,13 @@ packages:
source: hosted source: hosted
version: "3.0.3" version: "3.0.3"
dart_style: dart_style:
dependency: transitive dependency: "direct main"
description: description:
name: dart_style name: dart_style
sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.4"
davi: davi:
dependency: "direct main" dependency: "direct main"
description: description:
@ -338,26 +338,26 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: flutter_lints name: flutter_lints
sha256: ad76540d21c066228ee3f9d1dad64a9f7e46530e8bb7c85011a88bc1fd874bc5 sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.0" version: "3.0.1"
flutter_markdown: flutter_markdown:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_markdown name: flutter_markdown
sha256: "8afc9a6aa6d8e8063523192ba837149dbf3d377a37c0b0fc579149a1fbd4a619" sha256: "35108526a233cc0755664d445f8a6b4b61e6f8fe993b3658b80b4a26827fc196"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.18" version: "0.6.18+2"
flutter_riverpod: flutter_riverpod:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_riverpod name: flutter_riverpod
sha256: bdba94be666ecb1beeb0f5a748d96cdd6a37215f27e6b48c7673b95cecb800c8 sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.4" version: "2.4.9"
flutter_svg: flutter_svg:
dependency: "direct main" dependency: "direct main"
description: description:
@ -388,10 +388,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: freezed name: freezed
sha256: "21bf2825311de65501d22e563e3d7605dff57fb5e6da982db785ae5372ff018a" sha256: "6c5031daae12c7072b3a87eff98983076434b4889ef2a44384d0cae3f82372ba"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.5" version: "2.4.6"
freezed_annotation: freezed_annotation:
dependency: "direct main" dependency: "direct main"
description: description:
@ -468,10 +468,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: http name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.2"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@ -549,10 +549,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: just_audio name: just_audio
sha256: "5ed0cd723e17dfd8cd4b0253726221e67f6546841ea4553635cf895061fc335b" sha256: b607cd1a43bac03d85c3aaee00448ff4a589ef2a77104e3d409889ff079bf823
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.35" version: "0.9.36"
just_audio_mpv: just_audio_mpv:
dependency: "direct main" dependency: "direct main"
description: description:
@ -565,18 +565,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: just_audio_platform_interface name: just_audio_platform_interface
sha256: d8409da198bbc59426cd45d4c92fca522a2ec269b576ce29459d6d6fcaeb44df sha256: c3dee0014248c97c91fe6299edb73dc4d6c6930a2f4f713579cd692d9e47f4a1
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.1" version: "4.2.2"
just_audio_web: just_audio_web:
dependency: transitive dependency: transitive
description: description:
name: just_audio_web name: just_audio_web
sha256: ff62f733f437b25a0ff590f0e295fa5441dcb465f1edbdb33b3dea264705bc13 sha256: "134356b0fe3d898293102b33b5fd618831ffdc72bb7a1b726140abdf22772b70"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.8" version: "0.4.9"
just_audio_windows: just_audio_windows:
dependency: "direct main" dependency: "direct main"
description: description:
@ -741,10 +741,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.2.1"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
@ -781,18 +781,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pdf name: pdf
sha256: "9f75fc7f5580ea5e635b5724de58fb27f684c9ad03ed46fdc1aac768e4557315" sha256: "93cbb2c06de9bab91844550f19896b2373e7a5ce25173995e7e5ec5e1741429d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.10.4" version: "3.10.7"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
name: petitparser name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.4.0" version: "6.0.2"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -805,18 +805,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.6" version: "2.1.7"
pointer_interceptor: pointer_interceptor:
dependency: transitive dependency: transitive
description: description:
name: pointer_interceptor name: pointer_interceptor
sha256: "7626e034489820fd599380d2bb4d3f4a0a5e3529370b62bfce53ab736b91adb2" sha256: adf7a637f97c077041d36801b43be08559fd4322d2127b3f20bb7be1b9eebc22
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.3+6" version: "0.9.3+7"
pointycastle: pointycastle:
dependency: transitive dependency: transitive
description: description:
@ -845,10 +845,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: provider name: provider
sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.5" version: "6.1.1"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
@ -877,10 +877,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: riverpod name: riverpod
sha256: "2af3d127a6e4e34b89b8f1f018086f5ded04b8e538174f0510bba3e4c0d878b1" sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.4" version: "2.4.9"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@ -946,10 +946,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_gen name: source_gen
sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.5.0"
source_helper: source_helper:
dependency: transitive dependency: transitive
description: description:
@ -1090,74 +1090,74 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: url_launcher name: url_launcher
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.14" version: "6.2.2"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.0" version: "6.2.0"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.5" version: "6.2.1"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_linux name: url_launcher_linux
sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.6" version: "3.1.1"
url_launcher_macos: url_launcher_macos:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.7" version: "3.1.0"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_platform_interface name: url_launcher_platform_interface
sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.2.0"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5" sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.20" version: "2.2.2"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_windows name: url_launcher_windows
sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.8" version: "3.1.1"
uuid: uuid:
dependency: "direct main" dependency: "direct main"
description: description:
name: uuid name: uuid
sha256: b715b8d3858b6fa9f68f87d20d98830283628014750c2b09b6f516c1da4af2a7 sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.0" version: "4.2.2"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:
@ -1194,10 +1194,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "11.10.0" version: "13.0.0"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -1234,10 +1234,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.9" version: "5.1.1"
window_manager: window_manager:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1267,10 +1267,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: xml name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.0" version: "6.5.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:

View File

@ -50,6 +50,8 @@ dependencies:
scrollable_positioned_list: ^0.2.3 scrollable_positioned_list: ^0.2.3
flutter_svg: ^2.0.9 flutter_svg: ^2.0.9
vector_graphics_compiler: ^1.1.9+1 vector_graphics_compiler: ^1.1.9+1
code_builder: ^4.9.0
dart_style: ^2.3.4
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -0,0 +1,458 @@
import 'package:apidash/codegen/dart/dio.dart';
import 'package:test/test.dart';
import '../request_models.dart';
void main() {
final dartDioCodeGen = DartDioCodeGen();
group('GET Request', () {
test('GET 1', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final response = await dio.Dio.get('https://api.foss42.com');
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet1, "https"), expectedCode);
});
test('GET 2', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final queryParams = {'code': 'US'};
final response = await dio.Dio.get(
'https://api.foss42.com/country/data',
queryParameters: queryParams,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet2, "https"), expectedCode);
});
test('GET 3', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final queryParams = {'code': 'IND'};
final response = await dio.Dio.get(
'https://api.foss42.com/country/data?code=US',
queryParameters: queryParams,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet3, "https"), expectedCode);
});
test('GET 4', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final queryParams = {
'num': '8700000',
'digits': '3',
'system': 'SS',
'add_space': 'true',
'trailing_zeros': 'true',
};
final response = await dio.Dio.get(
'https://api.foss42.com/humanize/social',
queryParameters: queryParams,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet4, "https"), expectedCode);
});
test('GET 5', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final headers = {'User-Agent': 'Test Agent'};
final response = await dio.Dio.get(
'https://api.github.com/repos/foss42/apidash',
options: Options(headers: headers),
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet5, "https"), expectedCode);
});
test('GET 6', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final queryParams = {'raw': 'true'};
final headers = {'User-Agent': 'Test Agent'};
final response = await dio.Dio.get(
'https://api.github.com/repos/foss42/apidash',
queryParameters: queryParams,
options: Options(headers: headers),
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet6, "https"), expectedCode);
});
test('GET 7', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final response = await dio.Dio.get('https://api.foss42.com');
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet7, "https"), expectedCode);
});
test('GET 8', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final queryParams = {'raw': 'true'};
final headers = {'User-Agent': 'Test Agent'};
final response = await dio.Dio.get(
'https://api.github.com/repos/foss42/apidash',
queryParameters: queryParams,
options: Options(headers: headers),
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelGet8, "https"), expectedCode);
});
});
group('HEAD Request', () {
test('HEAD 1', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final response = await dio.Dio.head('https://api.foss42.com');
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelHead1, "https"), expectedCode);
});
test('HEAD 2', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final response = await dio.Dio.head('http://api.foss42.com');
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelHead2, "http"), expectedCode);
});
});
group('POST Request', () {
test('POST 1', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final data = r'''{
"text": "I LOVE Flutter"
}''';
final response = await dio.Dio.post(
'https://api.foss42.com/case/lower',
data: data,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelPost1, "https"), expectedCode);
});
test('POST 2', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
import 'dart:convert' as convert;
void main() async {
try {
final data = convert.json.decode(r'''{
"text": "I LOVE Flutter"
}''');
final response = await dio.Dio.post(
'https://api.foss42.com/case/lower',
data: data,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelPost2, "https"), expectedCode);
});
test('POST 3', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
import 'dart:convert' as convert;
void main() async {
try {
final headers = {'User-Agent': 'Test Agent'};
final data = convert.json.decode(r'''{
"text": "I LOVE Flutter"
}''');
final response = await dio.Dio.post(
'https://api.foss42.com/case/lower',
options: Options(headers: headers),
data: data,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelPost3, "https"), expectedCode);
});
});
group('PUT Request', () {
test('PUT 1', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
import 'dart:convert' as convert;
void main() async {
try {
final data = convert.json.decode(r'''{
"name": "morpheus",
"job": "zion resident"
}''');
final response = await dio.Dio.put(
'https://reqres.in/api/users/2',
data: data,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelPut1, "https"), expectedCode);
});
});
group('PATCH Request', () {
test('PATCH 1', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
import 'dart:convert' as convert;
void main() async {
try {
final data = convert.json.decode(r'''{
"name": "marfeus",
"job": "accountant"
}''');
final response = await dio.Dio.patch(
'https://reqres.in/api/users/2',
data: data,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(dartDioCodeGen.getCode(requestModelPatch1, "https"), expectedCode);
});
});
group('DELETE Request', () {
test('DELETE 1', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
void main() async {
try {
final response = await dio.Dio.delete('https://reqres.in/api/users/2');
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(
dartDioCodeGen.getCode(requestModelDelete1, "https"), expectedCode);
});
test('DELETE 2', () {
const expectedCode = r"""import 'package:dio/dio.dart' as dio;
import 'dart:convert' as convert;
void main() async {
try {
final data = convert.json.decode(r'''{
"name": "marfeus",
"job": "accountant"
}''');
final response = await dio.Dio.delete(
'https://reqres.in/api/users/2',
data: data,
);
print(response.statusCode);
print(response.data);
} on DioException catch (e, s) {
print(e.response?.statusCode);
print(e.response?.data);
print(s);
} catch (e, s) {
print(e);
print(s);
}
}
""";
expect(
dartDioCodeGen.getCode(requestModelDelete2, "https"), expectedCode);
});
});
}

View File

@ -1,5 +1,6 @@
import 'package:apidash/codegen/dart/http.dart'; import 'package:apidash/codegen/dart/http.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../request_models.dart'; import '../request_models.dart';
void main() { void main() {
@ -18,8 +19,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -34,9 +34,7 @@ void main() async {
void main() async { void main() async {
var uri = Uri.parse('https://api.foss42.com/country/data'); var uri = Uri.parse('https://api.foss42.com/country/data');
var queryParams = { var queryParams = {'code': 'US'};
"code": "US"
};
uri = uri.replace(queryParameters: queryParams); uri = uri.replace(queryParameters: queryParams);
final response = await http.get(uri); final response = await http.get(uri);
@ -45,13 +43,13 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
} }
"""; """;
expect(dartHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); expect(dartHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode);
}); });
@ -61,10 +59,8 @@ void main() async {
void main() async { void main() async {
var uri = Uri.parse('https://api.foss42.com/country/data?code=US'); var uri = Uri.parse('https://api.foss42.com/country/data?code=US');
var queryParams = { var queryParams = {'code': 'IND'};
"code": "IND" var urlQueryParams = Map<String, String>.from(uri.queryParameters);
};
var urlQueryParams = Map<String,String>.from(uri.queryParameters);
urlQueryParams.addAll(queryParams); urlQueryParams.addAll(queryParams);
uri = uri.replace(queryParameters: urlQueryParams); uri = uri.replace(queryParameters: urlQueryParams);
@ -74,8 +70,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -91,12 +86,12 @@ void main() async {
var uri = Uri.parse('https://api.foss42.com/humanize/social'); var uri = Uri.parse('https://api.foss42.com/humanize/social');
var queryParams = { var queryParams = {
"num": "8700000", 'num': '8700000',
"digits": "3", 'digits': '3',
"system": "SS", 'system': 'SS',
"add_space": "true", 'add_space': 'true',
"trailing_zeros": "true" 'trailing_zeros': 'true',
}; };
uri = uri.replace(queryParameters: queryParams); uri = uri.replace(queryParameters: queryParams);
final response = await http.get(uri); final response = await http.get(uri);
@ -105,8 +100,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -121,19 +115,18 @@ void main() async {
void main() async { void main() async {
var uri = Uri.parse('https://api.github.com/repos/foss42/apidash'); var uri = Uri.parse('https://api.github.com/repos/foss42/apidash');
var headers = { var headers = {'User-Agent': 'Test Agent'};
"User-Agent": "Test Agent"
};
final response = await http.get(uri, final response = await http.get(
headers: headers); uri,
headers: headers,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -148,24 +141,21 @@ void main() async {
void main() async { void main() async {
var uri = Uri.parse('https://api.github.com/repos/foss42/apidash'); var uri = Uri.parse('https://api.github.com/repos/foss42/apidash');
var queryParams = { var queryParams = {'raw': 'true'};
"raw": "true"
};
uri = uri.replace(queryParameters: queryParams); uri = uri.replace(queryParameters: queryParams);
var headers = { var headers = {'User-Agent': 'Test Agent'};
"User-Agent": "Test Agent"
};
final response = await http.get(uri, final response = await http.get(
headers: headers); uri,
headers: headers,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -186,8 +176,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -202,24 +191,21 @@ void main() async {
void main() async { void main() async {
var uri = Uri.parse('https://api.github.com/repos/foss42/apidash'); var uri = Uri.parse('https://api.github.com/repos/foss42/apidash');
var queryParams = { var queryParams = {'raw': 'true'};
"raw": "true"
};
uri = uri.replace(queryParameters: queryParams); uri = uri.replace(queryParameters: queryParams);
var headers = { var headers = {'User-Agent': 'Test Agent'};
"User-Agent": "Test Agent"
};
final response = await http.get(uri, final response = await http.get(
headers: headers); uri,
headers: headers,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -242,8 +228,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -264,8 +249,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -286,20 +270,19 @@ void main() async {
"text": "I LOVE Flutter" "text": "I LOVE Flutter"
}'''; }''';
var headers = { var headers = {'content-type': 'text/plain'};
"content-type": "text/plain"
};
final response = await http.post(uri, final response = await http.post(
headers: headers, uri,
body: body); headers: headers,
body: body,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -318,20 +301,19 @@ void main() async {
"text": "I LOVE Flutter" "text": "I LOVE Flutter"
}'''; }''';
var headers = { var headers = {'content-type': 'application/json'};
"content-type": "application/json"
};
final response = await http.post(uri, final response = await http.post(
headers: headers, uri,
body: body); headers: headers,
body: body,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -351,20 +333,21 @@ void main() async {
}'''; }''';
var headers = { var headers = {
"User-Agent": "Test Agent", 'User-Agent': 'Test Agent',
"content-type": "application/json" 'content-type': 'application/json',
}; };
final response = await http.post(uri, final response = await http.post(
headers: headers, uri,
body: body); headers: headers,
body: body,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -385,20 +368,19 @@ void main() async {
"job": "zion resident" "job": "zion resident"
}'''; }''';
var headers = { var headers = {'content-type': 'application/json'};
"content-type": "application/json"
};
final response = await http.put(uri, final response = await http.put(
headers: headers, uri,
body: body); headers: headers,
body: body,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -420,20 +402,19 @@ void main() async {
"job": "accountant" "job": "accountant"
}'''; }''';
var headers = { var headers = {'content-type': 'application/json'};
"content-type": "application/json"
};
final response = await http.patch(uri, final response = await http.patch(
headers: headers, uri,
body: body); headers: headers,
body: body,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -457,8 +438,7 @@ void main() async {
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }
@ -479,20 +459,19 @@ void main() async {
"job": "accountant" "job": "accountant"
}'''; }''';
var headers = { var headers = {'content-type': 'application/json'};
"content-type": "application/json"
};
final response = await http.delete(uri, final response = await http.delete(
headers: headers, uri,
body: body); headers: headers,
body: body,
);
int statusCode = response.statusCode; int statusCode = response.statusCode;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
print('Status Code: $statusCode'); print('Status Code: $statusCode');
print('Response Body: ${response.body}'); print('Response Body: ${response.body}');
} } else {
else{
print('Error Status Code: $statusCode'); print('Error Status Code: $statusCode');
print('Error Response Body: ${response.body}'); print('Error Response Body: ${response.body}');
} }