From 9c06700380bf21430437e2e66d0ee60edf15a858 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 21 Mar 2023 22:48:11 +0530 Subject: [PATCH] Dart code generator --- lib/codegen/codegen.dart | 1 + lib/codegen/dart/pkg_http.dart | 143 ++++++++++++++++++ .../details_card/code_pane/code_pane.dart | 56 ++++++- pubspec.lock | 24 +++ pubspec.yaml | 1 + 5 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 lib/codegen/codegen.dart create mode 100644 lib/codegen/dart/pkg_http.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart new file mode 100644 index 00000000..8883a098 --- /dev/null +++ b/lib/codegen/codegen.dart @@ -0,0 +1 @@ +export 'dart/pkg_http.dart'; diff --git a/lib/codegen/dart/pkg_http.dart b/lib/codegen/dart/pkg_http.dart new file mode 100644 index 00000000..11808a3f --- /dev/null +++ b/lib/codegen/dart/pkg_http.dart @@ -0,0 +1,143 @@ +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/models/models.dart' show RequestModel, rowsToMap; + +String kTemplateUrl = """import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('{{url}}'); +"""; + +String kTemplateParams = """ + + var queryParams = {{params}}; +"""; + +String kStringUrlParams = """ + + var urlQueryParams = Map.from(uri.queryParameters); + urlQueryParams.addAll(queryParams); + uri = uri.replace(queryParameters: urlQueryParams); +"""; + +String kStringNoUrlParams = """ + + uri = uri.replace(queryParameters: queryParams); +"""; + +String kTemplateHeaders = """ + + var headers = {{headers}}; +"""; + +String kTemplateBody = """ + + String body = r'''{{body}}'''; +"""; + +String kTemplateRequest = """ + + response = await http.{{method}}(requestUrl"""; + +String kStringRequestHeaders = """, + headers: headers"""; + +String kStringRequestBody = """, + body: body"""; +String kStringRequestEnd = """); +"""; + +String kTemplateSingleSuccess = """ + + if (response.statusCode == {{code}}) { +"""; + +String kTemplateMultiSuccess = """ + + if ({{codes}}.contains(response.statusCode)) {\n"""; + +String kStringResult = r""" + + print('Status Code: ${response.statusCode}'); + print('Result: ${response.body}'); + } + else{ + print('Error Status Code: ${response.statusCode}'); + } +} +"""; + +String getDartHttpCode(RequestModel requestModel) { + //try { + String result = ""; + bool hasHeaders = false; + bool hasBody = false; + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = kDefaultUriScheme + url; + } + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + var paramsList = requestModel.requestParams; + if (paramsList != null) { + var params = rowsToMap(requestModel.requestParams) ?? {}; + if (params.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + result += templateParams.render({"params": encoder.convert(params)}); + Uri uri = Uri.parse(url); + if (uri.hasQuery) { + result += kStringUrlParams; + } else { + result += kStringNoUrlParams; + } + } + } + + var headersList = requestModel.requestHeaders; + if (headersList != null) { + var headers = rowsToMap(requestModel.requestHeaders) ?? {}; + if (headers.isNotEmpty) { + hasHeaders = true; + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": encoder.convert(headers)}); + } + } + + var method = requestModel.method; + if (kMethodsWithBody.contains(method) && requestModel.requestBody != null) { + var body = requestModel.requestBody; + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": body}); + } + + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({"method": method.name}); + + if (hasHeaders) { + result += kStringRequestHeaders; + } + + if (hasBody) { + result += kStringRequestBody; + } + + result += kStringRequestEnd; + + var success = kCodegenSuccessStatusCodes[method]!; + if (success.length > 1) { + var templateMultiSuccess = jj.Template(kTemplateMultiSuccess); + result += templateMultiSuccess.render({"codes": success}); + } else { + var templateSingleSuccess = jj.Template(kTemplateSingleSuccess); + result += templateSingleSuccess.render({"code": success[0]}); + } + result += kStringResult; + + return result; + //} catch (e) { + // return "An error was encountered while generating code. $kRaiseIssue"; + //} +} diff --git a/lib/screens/home_page/editor_pane/details_card/code_pane/code_pane.dart b/lib/screens/home_page/editor_pane/details_card/code_pane/code_pane.dart index d0ea6a6f..f46ca067 100644 --- a/lib/screens/home_page/editor_pane/details_card/code_pane/code_pane.dart +++ b/lib/screens/home_page/editor_pane/details_card/code_pane/code_pane.dart @@ -1,15 +1,63 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:apidash/providers/providers.dart'; +import 'package:apidash/widgets/widgets.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; -class CodePane extends StatefulWidget { +class CodePane extends ConsumerStatefulWidget { const CodePane({super.key}); @override - State createState() => _CodePaneState(); + ConsumerState createState() => _CodePaneState(); } -class _CodePaneState extends State { +class _CodePaneState extends ConsumerState { + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { - return Container(); + final activeId = ref.watch(activeIdStateProvider); + final collection = ref.watch(collectionStateNotifierProvider); + final idIdx = collection.indexWhere((m) => m.id == activeId); + final requestModel = collection[idIdx]; + print("update"); + var codeTheme = Theme.of(context).brightness == Brightness.light + ? kLightCodeTheme + : kDarkCodeTheme; + final textContainerdecoration = BoxDecoration( + color: Theme.of(context).brightness == Brightness.dark + ? Color.alphaBlend( + Theme.of(context).colorScheme.surface.withOpacity(0.8), + Colors.black) + : Color.alphaBlend( + Theme.of(context).colorScheme.surface.withOpacity(0.2), + Colors.white), + border: Border.all(color: Theme.of(context).colorScheme.surfaceVariant), + borderRadius: kBorderRadius8, + ); + return Padding( + padding: kP10, + child: Column( + children: [ + Expanded( + child: Container( + width: double.maxFinite, + padding: kP8, + decoration: textContainerdecoration, + child: CodePreviewer( + code: getDartHttpCode(requestModel), + theme: codeTheme, + language: 'dart', + textStyle: kCodeStyle, + ), + ), + ), + ], + ), + ); } } diff --git a/pubspec.lock b/pubspec.lock index 2009748c..fee4a48b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -139,6 +139,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.1" + html_unescape: + dependency: transitive + description: + name: html_unescape + sha256: "15362d7a18f19d7b742ef8dcb811f5fd2a2df98db9f80ea393c075189e0b61e3" + url: "https://pub.dev" + source: hosted + version: "2.0.0" http: dependency: "direct main" description: @@ -155,6 +163,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + jinja: + dependency: "direct main" + description: + name: jinja + sha256: "7b6fd9b8420e9db923a0852aa43f688b99381f45caee60b3ba8dcc445d5e60b9" + url: "https://pub.dev" + source: hosted + version: "0.4.2" js: dependency: transitive description: @@ -360,6 +376,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.16" + textwrap: + dependency: transitive + description: + name: textwrap + sha256: "342fb85c503a27c68e0dd21f7be35360acf3231f929e0dcb23cc8593d2919c36" + url: "https://pub.dev" + source: hosted + version: "1.2.0" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c34fa21b..4b1f3e98 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ dependencies: highlighter: ^0.1.1 string_scanner: ^1.2.0 xml: ^6.2.2 + jinja: ^0.4.2 dev_dependencies: flutter_test: