From 36ad610ffa0240add11e5debc7c9f0a87085742e Mon Sep 17 00:00:00 2001 From: Nikhil Date: Thu, 20 Mar 2025 02:56:32 +0530 Subject: [PATCH 01/23] changes made --- lib/codegen/dart/dio.dart | 2 +- lib/codegen/dart/http.dart | 2 +- lib/utils/har_utils.dart | 12 +++-- lib/widgets/table_request.dart | 6 +-- .../lib/models/http_request_model.dart | 6 +-- .../lib/utils/http_request_utils.dart | 48 +++++++++++++++++++ .../apidash_core/lib/utils/uri_utils.dart | 16 ++++--- 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index 488d3cc7f..9b60ab3aa 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -28,7 +28,7 @@ class DartDioCodeGen { String generatedDartCode({ required String url, required HTTPVerb method, - required Map queryParams, + required Map queryParams, required Map headers, required String? body, required ContentType contentType, diff --git a/lib/codegen/dart/http.dart b/lib/codegen/dart/http.dart index 2c7e66a54..58798c18b 100644 --- a/lib/codegen/dart/http.dart +++ b/lib/codegen/dart/http.dart @@ -30,7 +30,7 @@ class DartHttpCodeGen { String generatedDartCode({ required String url, required HTTPVerb method, - required Map queryParams, + required Map queryParams, required Map headers, required ContentType contentType, required String? body, diff --git a/lib/utils/har_utils.dart b/lib/utils/har_utils.dart index 31c466ceb..6e0f97e1f 100644 --- a/lib/utils/har_utils.dart +++ b/lib/utils/har_utils.dart @@ -110,14 +110,16 @@ Map requestModelToHARJsonRequest( json["queryString"] = []; json["headers"] = []; - var params = uri.queryParameters; + Map> params = uri.queryParametersAll; if (params.isNotEmpty) { for (final k in params.keys) { - var m = {"name": k, "value": params[k]}; - if (exportMode) { - m["comment"] = ""; + for (final val in params[k]!) { + var m = {"name": k, "value": val}; + if (exportMode) { + m["comment"] = ""; + } + json["queryString"].add(m); } - json["queryString"].add(m); } } diff --git a/lib/widgets/table_request.dart b/lib/widgets/table_request.dart index 7b57ebdf7..fe3e19e2b 100644 --- a/lib/widgets/table_request.dart +++ b/lib/widgets/table_request.dart @@ -12,7 +12,7 @@ class RequestDataTable extends StatelessWidget { this.valueName, }); - final Map rows; + final Map rows; final String? keyName; final String? valueName; @@ -57,7 +57,7 @@ class RequestDataTable extends StatelessWidget { final List dataRows = rows.entries .map( - (MapEntry entry) => DataRow( + (MapEntry entry) => DataRow( cells: [ const DataCell(kHSpacer5), DataCell( @@ -71,7 +71,7 @@ class RequestDataTable extends StatelessWidget { ), DataCell( ReadOnlyTextField( - initialValue: entry.value, + initialValue: entry.value is String ? entry.value : entry.value.toString(), decoration: fieldDecoration, ), ), diff --git a/packages/apidash_core/lib/models/http_request_model.dart b/packages/apidash_core/lib/models/http_request_model.dart index cc2d7411c..072a00942 100644 --- a/packages/apidash_core/lib/models/http_request_model.dart +++ b/packages/apidash_core/lib/models/http_request_model.dart @@ -3,7 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:seed/seed.dart'; import '../extensions/extensions.dart'; import '../utils/utils.dart' - show rowsToFormDataMapList, rowsToMap, getEnabledRows; + show rowsToFormDataMapList, rowsToMap, getEnabledRows,rowsToRequestMap; import '../consts.dart'; part 'http_request_model.freezed.dart'; @@ -34,14 +34,14 @@ class HttpRequestModel with _$HttpRequestModel { _$HttpRequestModelFromJson(json); Map get headersMap => rowsToMap(headers) ?? {}; - Map get paramsMap => rowsToMap(params) ?? {}; + Map get paramsMap => rowsToRequestMap(params) ?? {}; List? get enabledHeaders => getEnabledRows(headers, isHeaderEnabledList); List? get enabledParams => getEnabledRows(params, isParamEnabledList); Map get enabledHeadersMap => rowsToMap(enabledHeaders) ?? {}; - Map get enabledParamsMap => rowsToMap(enabledParams) ?? {}; + Map get enabledParamsMap => rowsToRequestMap(enabledParams) ?? {}; bool get hasContentTypeHeader => enabledHeadersMap.hasKeyContentType(); bool get hasFormDataContentType => bodyContentType == ContentType.formdata; diff --git a/packages/apidash_core/lib/utils/http_request_utils.dart b/packages/apidash_core/lib/utils/http_request_utils.dart index b5eab42cc..843273d0d 100644 --- a/packages/apidash_core/lib/utils/http_request_utils.dart +++ b/packages/apidash_core/lib/utils/http_request_utils.dart @@ -100,3 +100,51 @@ String? getRequestBody(APIType type, HttpRequestModel httpRequestModel) { APIType.graphql => getGraphQLBody(httpRequestModel), }; } +Map? rowsToRequestMap(List? rows) { + if (rows == null) { + return null; + } + + final Map finalMap = {}; + + for (var row in rows) { + final key = row.name.trim(); + if (key.isEmpty) continue; + + final value = row.value.toString(); + + if (finalMap.containsKey(key)) { + + if (finalMap[key] is List) { + (finalMap[key] as List).add(value); + } else { + finalMap[key] = [finalMap[key], value]; + } + } else { + + finalMap[key] = value; + } + } + + return finalMap; +} + +List? requestMapToRows(Map? requestMap) { + if (requestMap == null) { + return null; + } + + final List finalRows = []; + + requestMap.forEach((key, value) { + if (value is List) { + for (var item in value) { + finalRows.add(NameValueModel(name: key, value: item.toString())); + } + } else { + finalRows.add(NameValueModel(name: key, value: value.toString())); + } + }); + + return finalRows; +} \ No newline at end of file diff --git a/packages/apidash_core/lib/utils/uri_utils.dart b/packages/apidash_core/lib/utils/uri_utils.dart index b111a2e08..0b3785aa3 100644 --- a/packages/apidash_core/lib/utils/uri_utils.dart +++ b/packages/apidash_core/lib/utils/uri_utils.dart @@ -52,12 +52,16 @@ String stripUrlParams(String url) { uri = uri.removeFragment(); } - Map? queryParams = rowsToMap(requestParams); - if (queryParams != null && queryParams.isNotEmpty) { - if (uri.hasQuery) { - Map urlQueryParams = uri.queryParameters; - queryParams = mergeMaps(urlQueryParams, queryParams); - } + Map> queryParams = uri.queryParametersAll; + + Map? requestQueryParams = rowsToRequestMap(requestParams); + if (requestQueryParams != null) { + Map> queryParamsList = requestQueryParams.map((key, value) { + return MapEntry(key, List.from(value is String ? [value] : value)); + }); + queryParams = mergeMaps(queryParams, queryParamsList, value: (v1, v2) => v1 + v2); + } + if (queryParams.isNotEmpty) { uri = uri.replace(queryParameters: queryParams); } return (uri, null); From 5d291f1b1c98a26cbd3e5a006353ea850ba34754 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Thu, 20 Mar 2025 04:34:09 +0530 Subject: [PATCH 02/23] Codegen updated for dart(http/dio) --- lib/codegen/dart/dio.dart | 5 +++-- lib/codegen/dart/http.dart | 8 ++++---- .../lib/models/http_request_model.dart | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index 9b60ab3aa..5ade085fd 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -87,11 +87,12 @@ class DartDioCodeGen { dataExp = declareFinal('data').assign(refer('dio.FormData()')); } } + final parsedUrl = url.split('?').first; final responseExp = declareFinal('response').assign(InvokeExpression.newOf( refer('dio.Dio()'), - [literalString(url)], + [literalString(parsedUrl)], { - if (queryParamExp != null) 'queryParameters': refer('queryParams'), + if (queryParamExp != null) 'queryParameters': refer('queryParams'), if (headerExp != null) 'options': refer('dio.Options').newInstance( [], diff --git a/lib/codegen/dart/http.dart b/lib/codegen/dart/http.dart index 58798c18b..a6a6a0061 100644 --- a/lib/codegen/dart/http.dart +++ b/lib/codegen/dart/http.dart @@ -43,9 +43,9 @@ class DartHttpCodeGen { final emitter = DartEmitter(); final dioImport = Directive.import('package:http/http.dart', as: 'http'); sbf.writeln(dioImport.accept(emitter)); - + final parsedUrl = url.split('?').first; final uriExp = - declareVar('uri').assign(refer('Uri.parse').call([literalString(url)])); + declareVar('uri').assign(refer('Uri.parse').call([literalString(parsedUrl)])); Expression? dataExp; if (kMethodsWithBody.contains(method) && @@ -61,7 +61,7 @@ class DartHttpCodeGen { Expression? queryParamExp; List? uriReassignExps; - // var urlQueryParams = Map.from(uri.queryParameters); + // var urlQueryParams = Map.from(uri.queryParameters); // urlQueryParams.addAll(queryParams); // uri = uri.replace(queryParameters: urlQueryParams); @@ -74,7 +74,7 @@ class DartHttpCodeGen { if (uri.hasQuery) declareVar('urlQueryParams').assign( InvokeExpression.newOf( - refer('Map'), + refer('Map'), [refer('uri.queryParameters')], {}, [], diff --git a/packages/apidash_core/lib/models/http_request_model.dart b/packages/apidash_core/lib/models/http_request_model.dart index 072a00942..2b28016ee 100644 --- a/packages/apidash_core/lib/models/http_request_model.dart +++ b/packages/apidash_core/lib/models/http_request_model.dart @@ -41,7 +41,21 @@ class HttpRequestModel with _$HttpRequestModel { getEnabledRows(params, isParamEnabledList); Map get enabledHeadersMap => rowsToMap(enabledHeaders) ?? {}; - Map get enabledParamsMap => rowsToRequestMap(enabledParams) ?? {}; +Map get enabledParamsMap { + var extractedParams = Uri.parse(url).queryParametersAll; + var userParams = rowsToRequestMap(enabledParams) ?? {}; + + extractedParams.forEach((key, value) { + userParams[key] = [ + ...value, + if (userParams.containsKey(key)) + ...(userParams[key] is List ? List.from(userParams[key]) : [userParams[key]]) + ]; + }); + + return userParams; +} + bool get hasContentTypeHeader => enabledHeadersMap.hasKeyContentType(); bool get hasFormDataContentType => bodyContentType == ContentType.formdata; From 952439396f5824244305181eb566b6c8e691b548 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 21 Mar 2025 00:14:17 +0530 Subject: [PATCH 03/23] Updated GO --- lib/codegen/go/http.dart | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart index 28fd805a2..5342c9148 100644 --- a/lib/codegen/go/http.dart +++ b/lib/codegen/go/http.dart @@ -58,14 +58,15 @@ func main() { """; String kTemplateQueryParam = """ - query := url.Query() - {% for key, value in params %} - query.Set("{{key}}", "{{value}}"){% endfor %} +query := url.Query() +{% for param in params %} +query.Add("{{param.key}}", "{{param.value}}"){% endfor %} - url.RawQuery = query.Encode() +url.RawQuery = query.Encode() """; + String kTemplateRequest = """ req, _ := http.NewRequest("{{method}}", url.String(), {% if hasBody %}payload{% else %}nil{% endif %}) @@ -102,7 +103,7 @@ func main() { }); var templateUrl = jj.Template(kTemplateUrl); - result += templateUrl.render({"url": url}); + result += templateUrl.render({"url": url.split('?').first}); var rec = getValidRequestUri( url, @@ -124,15 +125,21 @@ func main() { "fields": requestModel.formDataMapList, }); } - - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - var templateQueryParam = jj.Template(kTemplateQueryParam); - result += templateQueryParam.render({"params": params}); + if (requestModel.enabledParamsMap.isNotEmpty) { + var queryParams = []; + requestModel.enabledParamsMap.forEach((key, value) { + if (value is List) { + for (var v in value) { + queryParams.add({'key': key, 'value': v}); } + } else { + queryParams.add({'key': key, 'value': value}); } + }); + var templateQueryParam = jj.Template(kTemplateQueryParam); + result += templateQueryParam.render({"params": queryParams}); + } var method = requestModel.method.name.toUpperCase(); var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ From bc4b5fb2b7b9a7fc7ecbc880102484ff59aee715 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 21 Mar 2025 20:30:47 +0530 Subject: [PATCH 04/23] Updated C# --- lib/codegen/csharp/http_client.dart | 58 +++++++++++++++++++---------- lib/codegen/csharp/rest_sharp.dart | 25 ++++++++----- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/lib/codegen/csharp/http_client.dart b/lib/codegen/csharp/http_client.dart index 6d086db83..e0590a887 100644 --- a/lib/codegen/csharp/http_client.dart +++ b/lib/codegen/csharp/http_client.dart @@ -5,19 +5,31 @@ class CSharpHttpClientCodeGen { final String kTemplateNamespaces = r''' using System; using System.Net.Http; +using System.Collections.Generic; +using System.Linq; {%- if formdata == 'multipart' %} using System.IO; -{%- elif formdata == 'urlencoded' %} -using System.Collections.Generic; {%- endif %} '''; - final String kTemplateUri = ''' -string uri = "{{ uri }}"; +final String kTemplateQueryParams = ''' +string baseUri = "{{ baseUri }}"; + +var query = new Dictionary>(); +{%- for key, values in queryParams %} +query["{{ key }}"] = new List(); +{%- for value in values %} +query["{{ key }}"].Add("{{ value }}"); +{%- endfor %} +{%- endfor %} + +var queryString = string.Join("&", query.SelectMany(kv => kv.Value.Select(v => string.Format("{0}={1}", kv.Key, v)))); +string uri = string.Format("{0}?{1}", baseUri, queryString); '''; + final String kTemplateHttpClientAndRequest = ''' using (var client = new HttpClient()) using (var request = new HttpRequestMessage(HttpMethod.{{ method | capitalize }}, uri)) @@ -81,17 +93,23 @@ using (var request = new HttpRequestMessage(HttpMethod.{{ method | capitalize }} StringBuffer result = StringBuffer(); // Include necessary C# namespace - String formdataImport = requestModel.hasFormData - ? "multipart" //(requestModel.hasFileInFormData ? "multipart" : "urlencoded") - : "nodata"; + String formdataImport = requestModel.hasFormData + ? "multipart" //(requestModel.hasFileInFormData ? "multipart" : "urlencoded") + : "nodata"; result.writeln(jj.Template(kTemplateNamespaces) - .render({"formdata": formdataImport})); - - // Set request URL - var (uri, _) = - getValidRequestUri(requestModel.url, requestModel.enabledParams); - if (uri != null) { - result.writeln(jj.Template(kTemplateUri).render({"uri": uri})); + .render({"formdata": formdataImport})); + + // Extract query parameters and URL + String baseUri = requestModel.url.split('?')[0]; + var queryParams = requestModel.enabledParamsMap; + + if (queryParams.isNotEmpty) { + result.writeln(jj.Template(kTemplateQueryParams).render({ + "baseUri": baseUri, + "queryParams": queryParams, + })); + } else { + result.writeln('string uri = "$baseUri";\n'); } // Initialize HttpClient and create HttpRequestMessage @@ -103,18 +121,18 @@ using (var request = new HttpRequestMessage(HttpMethod.{{ method | capitalize }} var headers = requestModel.enabledHeadersMap; if (headers.isNotEmpty) { result.writeln( - jj.Template(kTemplateHeaders).render({"headers": headers})); + jj.Template(kTemplateHeaders).render({"headers": headers})); } // Set request body if exists if (kMethodsWithBody.contains(requestModel.method) && - requestModel.hasBody) { + requestModel.hasBody) { var requestBody = requestModel.body; if (!requestModel.hasFormData && - requestBody != null && - requestBody.isNotEmpty) { - // if the request body is not formdata then render raw text body + requestBody != null && + requestBody.isNotEmpty) { + // if the request body is not formdata then render raw text body result.writeln(jj.Template(kTemplateRawBody).render({ "body": requestBody, "mediaType": requestModel.bodyContentType.header, @@ -133,7 +151,7 @@ using (var request = new HttpRequestMessage(HttpMethod.{{ method | capitalize }} result.writeln(kStringContentSetup); } - // Send request and get response + // Send request and get response result.write(kStringEnd); return result.toString(); } catch (e) { diff --git a/lib/codegen/csharp/rest_sharp.dart b/lib/codegen/csharp/rest_sharp.dart index efebb7cf9..fa5cc4a64 100644 --- a/lib/codegen/csharp/rest_sharp.dart +++ b/lib/codegen/csharp/rest_sharp.dart @@ -113,19 +113,24 @@ class Program }); result += methodType; - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - jj.Template templateParams = jj.Template(kTemplateParams); - String paramsResult = ""; - for (var item in params.entries) { - paramsResult += templateParams - .render({"param": item.key, "value": item.value}); + if (requestModel.enabledParamsMap.isNotEmpty) { + jj.Template templateParams = jj.Template(kTemplateParams); + String paramsResult = ""; + + requestModel.enabledParamsMap.forEach((key, values) { + if (values is List) { + for (var value in values) { + paramsResult += templateParams.render({"param": key, "value": value}); + } + } else { + paramsResult += templateParams.render({"param": key, "value": values}); } - result += "$paramsResult\n"; - } + }); + + result += "$paramsResult\n"; } + var headersList = requestModel.enabledHeaders; if (headersList != null || requestModel.hasJsonData || From 10f3ac3b38f5ffb8bb7e9a53036365dcc1a8f240 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sat, 22 Mar 2025 03:20:03 +0530 Subject: [PATCH 05/23] updated js --- lib/codegen/js/axios.dart | 17 ++++++++--------- lib/codegen/js/fetch.dart | 22 +++++++++++++++++----- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/lib/codegen/js/axios.dart b/lib/codegen/js/axios.dart index e6651976a..11338791a 100644 --- a/lib/codegen/js/axios.dart +++ b/lib/codegen/js/axios.dart @@ -69,16 +69,15 @@ axios(config) "method": harJson["method"].toLowerCase(), }); - var params = harJson["queryString"]; - if (params.isNotEmpty) { - var templateParams = jj.Template(kTemplateParams); - var m = {}; - for (var i in params) { - m[i["name"]] = i["value"]; + var enabledParams = requestModel.enabledParamsMap; + + if (enabledParams.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + result += templateParams.render({ + "params": padMultilineString(kJsonEncoder.convert(enabledParams), 2) + }); } - result += templateParams - .render({"params": padMultilineString(kJsonEncoder.convert(m), 2)}); - } + var headers = harJson["headers"]; if (headers.isNotEmpty || requestModel.hasFormData) { diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index 5f610738b..bb8937c17 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -15,8 +15,18 @@ import { {% if hasFileInFormData %}fileFromSync, {% endif %}FormData } from 'nod """; - String kTemplateStart = """const url = '{{url}}'; - + String kTemplateStart = """const url = new URL('{{url}}'); + +{% for key, value in params -%} +{% if value is iterable and (value is not string) -%} +{% for item in value -%} +url.searchParams.append('{{key}}', '{{item}}'); +{% endfor -%} +{% else -%} + +url.searchParams.append('{{key}}', '{{value}}'); +{% endif -%} +{% endfor -%} const options = { method: '{{method}}' """; @@ -63,7 +73,7 @@ fetch(url, options) : requestModel.hasFileInFormData ? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration\n\n" : ""; - if (requestModel.hasFormData) { + if (requestModel.hasFormData) { result += "const payload = new FormData();\n"; var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); var formFileCounter = 1; @@ -83,15 +93,17 @@ fetch(url, options) var harJson = requestModelToHARJsonRequest(requestModel, useEnabled: true); + var params = requestModel.enabledParamsMap; var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "url": harJson["url"], + "url": stripUrlParams(requestModel.url), "method": harJson["method"], + "params": params, }); var headers = harJson["headers"]; - + if (headers.isNotEmpty) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; From 34485a291c0de60786f1ca1a30a3a92e739b4e38 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sun, 23 Mar 2025 05:38:50 +0530 Subject: [PATCH 06/23] Updated Swift --- lib/codegen/swift/urlsession.dart | 45 ++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/codegen/swift/urlsession.dart b/lib/codegen/swift/urlsession.dart index 25cce35a6..133aa1b69 100644 --- a/lib/codegen/swift/urlsession.dart +++ b/lib/codegen/swift/urlsession.dart @@ -48,10 +48,17 @@ let postData = parameters.data(using: .utf8) '''; - final String kTemplateRequest = """ -var request = URLRequest(url: URL(string: "{{url}}")!) -request.httpMethod = "{{method}}" +final String kTemplateRequest = """ +var urlComponents = URLComponents(string: "{{url}}")! +var queryItems = [URLQueryItem]() + +{% for param in params %} +queryItems.append(URLQueryItem(name: "{{param.key}}", value: "{{param.value}}")){% if not loop.last %}{% else %}{% endif %}{% endfor %} +urlComponents.queryItems = queryItems +let requestUrl = urlComponents.url! +var request = URLRequest(url: requestUrl) +request.httpMethod = "{{method}}" """; final String kTemplateHeaders = """ @@ -67,9 +74,13 @@ request.httpBody = try! multipartFormData.encode() """; final String kTemplateEnd = """ +let semaphore = DispatchSemaphore(value: 0) + let task = URLSession.shared.dataTask(with: request) { data, response, error in + defer { semaphore.signal() } + if let error = error { - print("Error: (error.localizedDescription)") + print("Error: \\(error.localizedDescription)") return } guard let data = data else { @@ -77,10 +88,13 @@ let task = URLSession.shared.dataTask(with: request) { data, response, error in return } if let responseString = String(data: data, encoding: .utf8) { - print("Response: (responseString)") + print("Response: \\(responseString)") } } + task.resume() + +semaphore.wait() """; String? getCode(HttpRequestModel requestModel) { @@ -91,10 +105,22 @@ task.resume() result += kTemplateFormDataImport; } - var rec = - getValidRequestUri(requestModel.url, requestModel.enabledParams); + var rec = + getValidRequestUri(requestModel.url, requestModel.enabledParams); Uri? uri = rec.$1; + var params = requestModel.enabledParamsMap.entries.expand((entry) { + + var values = entry.value is Iterable ? entry.value : [entry.value]; + + return values.map((value) { + return {'key': entry.key, 'value': value}; + }); + }).toList(); + + + + if (requestModel.hasFormData) { var formDataList = requestModel.formDataMapList.map((param) { if (param['type'] == 'file') { @@ -139,13 +165,14 @@ task.resume() var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ "url": uri.toString(), - "method": requestModel.method.name.toUpperCase() + "method": requestModel.method.name.toUpperCase(), + "params": params, }); var headers = requestModel.enabledHeadersMap; if (requestModel.hasFormData) { headers.putIfAbsent("Content-Type", - () => "multipart/form-data; boundary=(boundary.stringValue)"); + () => "multipart/form-data; boundary=\\(boundary.stringValue)"); } else if (requestModel.hasJsonData || requestModel.hasTextData) { headers.putIfAbsent( kHeaderContentType, () => requestModel.bodyContentType.header); From d33bcd6fc69b0e55b2655c9234a61b04cd0daa98 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sun, 23 Mar 2025 06:04:30 +0530 Subject: [PATCH 07/23] fix swift --- lib/codegen/swift/urlsession.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/codegen/swift/urlsession.dart b/lib/codegen/swift/urlsession.dart index 133aa1b69..c49ad3b08 100644 --- a/lib/codegen/swift/urlsession.dart +++ b/lib/codegen/swift/urlsession.dart @@ -74,6 +74,7 @@ request.httpBody = try! multipartFormData.encode() """; final String kTemplateEnd = """ + let semaphore = DispatchSemaphore(value: 0) let task = URLSession.shared.dataTask(with: request) { data, response, error in @@ -164,7 +165,7 @@ semaphore.wait() var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "url": uri.toString(), + "url": uri.toString().split('?').first, "method": requestModel.method.name.toUpperCase(), "params": params, }); From a67f33bf6ea997bb920a933956ba76683a247a77 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Tue, 25 Mar 2025 04:47:45 +0530 Subject: [PATCH 08/23] Updated Java --- lib/codegen/csharp/http_client.dart | 14 ++++++++++---- lib/codegen/java/async_http_client.dart | 12 ++++++------ lib/codegen/java/okhttp.dart | 22 ++++++++++------------ lib/codegen/java/unirest.dart | 25 ++++++++++++++----------- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/lib/codegen/csharp/http_client.dart b/lib/codegen/csharp/http_client.dart index e0590a887..6d200051c 100644 --- a/lib/codegen/csharp/http_client.dart +++ b/lib/codegen/csharp/http_client.dart @@ -19,10 +19,15 @@ string baseUri = "{{ baseUri }}"; var query = new Dictionary>(); {%- for key, values in queryParams %} -query["{{ key }}"] = new List(); -{%- for value in values %} -query["{{ key }}"].Add("{{ value }}"); -{%- endfor %} + {%- if values is string %} + query["{{ key }}"] = new List(); + query["{{ key }}"].Add("{{ values }}"); + {%- else %} + query["{{ key }}"] = new List(); + {%- for value in values %} + query["{{ key }}"].Add("{{ value }}"); + {%- endfor %} + {%- endif %} {%- endfor %} var queryString = string.Join("&", query.SelectMany(kv => kv.Value.Select(v => string.Format("{0}={1}", kv.Key, v)))); @@ -30,6 +35,7 @@ string uri = string.Format("{0}?{1}", baseUri, queryString); '''; + final String kTemplateHttpClientAndRequest = ''' using (var client = new HttpClient()) using (var request = new HttpRequestMessage(HttpMethod.{{ method | capitalize }}, uri)) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index 4b1957389..f19282a42 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -36,14 +36,14 @@ public class Main { '''; final String kTemplateRequestCreation = ''' - BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("{{ method|upper }}", url);\n + BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("{{ method|upper }}", url); '''; - final String kTemplateUrlQueryParam = ''' - requestBuilder{% for name, value in queryParams %} - .addQueryParam("{{ name }}", "{{ value }}"){% endfor %};\n + final String kTemplateUrlQueryParam = ''' {% for name, value in queryParams %} +{% if value is not string %} + {% for v in value %} requestBuilder.addQueryParam("{{ name }}", "{{ v }}"); + {% endfor %} {% else %} requestBuilder.addQueryParam("{{ name }}", "{{ value }}");{% endif %}{% endfor %}\n\n '''; - final String kTemplateRequestHeader = ''' requestBuilder{% for name, value in headers %} .addHeader("{{ name }}", "{{ value }}"){% endfor %};\n @@ -158,7 +158,7 @@ public class Main { result += templateRequestCreation.render({"method": method.name}); // setting up query parameters - var params = uri.queryParameters; + var params = requestModel.enabledParamsMap; if (params.isNotEmpty) { var templateUrlQueryParam = jj.Template(kTemplateUrlQueryParam); result += templateUrlQueryParam.render({"queryParams": params}); diff --git a/lib/codegen/java/okhttp.dart b/lib/codegen/java/okhttp.dart index e9b849a72..020d17c72 100644 --- a/lib/codegen/java/okhttp.dart +++ b/lib/codegen/java/okhttp.dart @@ -36,14 +36,18 @@ import okhttp3.MultipartBody;"""; '''; - final String kTemplateUrlQuery = ''' +final String kTemplateUrlQuery = ''' - HttpUrl url = HttpUrl.parse("{{url}}").newBuilder() - {{params}} - .build(); + HttpUrl.Builder urlBuilder = HttpUrl.parse("{{url}}").newBuilder(); + {% for name, value in queryParams %}{% if value is not string %} {% for v in value %} urlBuilder.addQueryParameter("{{ name }}", "{{ v }}"); + {% endfor %} + {% else %} urlBuilder.addQueryParameter("{{ name }}", "{{ value }}"); {% endif %}{% endfor %} + + HttpUrl url = urlBuilder.build(); '''; + String kTemplateRequestBody = ''' MediaType mediaType = MediaType.parse("{{contentType}}"); @@ -107,12 +111,12 @@ import okhttp3.MultipartBody;"""; String url = stripUriParams(uri); if (uri.hasQuery) { - var params = uri.queryParameters; + var params = requestModel.enabledParamsMap; if (params.isNotEmpty) { hasQuery = true; var templateParams = jj.Template(kTemplateUrlQuery); result += templateParams - .render({"url": url, "params": getQueryParams(params)}); + .render({"url": url, "queryParams": params}); } } if (!hasQuery) { @@ -172,12 +176,6 @@ import okhttp3.MultipartBody;"""; } } - String getQueryParams(Map params) { - final paramStrings = params.entries - .map((entry) => '.addQueryParameter("${entry.key}", "${entry.value}")') - .toList(); - return paramStrings.join('\n '); - } String getHeaders(Map headers) { String result = ""; diff --git a/lib/codegen/java/unirest.dart b/lib/codegen/java/unirest.dart index ad3a3e99f..23f9b4537 100644 --- a/lib/codegen/java/unirest.dart +++ b/lib/codegen/java/unirest.dart @@ -3,7 +3,7 @@ import 'package:jinja/jinja.dart' as jj; class JavaUnirestGen { final String kStringUnirestImports = ''' -import kong.unirest.core.*; +import kong.unirest.*; '''; @@ -35,10 +35,16 @@ public class Main { .header("{{name}}", "{{value}}")\n '''; - final String kTemplateUrlQueryParam = ''' - .queryString("{{name}}", "{{value}}")\n + final String kTemplateUrlQueryParam = ''' + {% for name, value in queryParams %} + {% if value is iterable and value is not string %} {% for v in value -%} + .queryString("{{name}}", "{{v}}"){% if not loop.last %} {% endif %} + {% endfor %} {% else %} + .queryString("{{name}}", "{{value}}") {% endif %} {% if not loop.last %}{% endif %} {% endfor %} '''; + + final String kTemplateRequestTextFormData = ''' .field("{{name}}", "{{value}}")\n '''; @@ -125,14 +131,11 @@ public class Main { // ~~~~~~~~~~~~~~~~~~ query parameters start ~~~~~~~~~~~~~~~~~~ - if (uri.hasQuery) { - var params = uri.queryParameters; - var templateUrlQueryParam = jj.Template(kTemplateUrlQueryParam); - params.forEach((name, value) { - result += - templateUrlQueryParam.render({"name": name, "value": value}); - }); - } + + var params = requestModel.enabledParamsMap; + var templateUrlQueryParam = jj.Template(kTemplateUrlQueryParam); + result += templateUrlQueryParam.render({"queryParams": params}); + // ~~~~~~~~~~~~~~~~~~ query parameters end ~~~~~~~~~~~~~~~~~~ From 654a672c5bea6b0a18476baed6e2aec33a4a2eae Mon Sep 17 00:00:00 2001 From: Nikhil Date: Tue, 25 Mar 2025 05:06:06 +0530 Subject: [PATCH 09/23] julia --- lib/codegen/julia/http.dart | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/codegen/julia/http.dart b/lib/codegen/julia/http.dart index 3425dc099..c453346c4 100644 --- a/lib/codegen/julia/http.dart +++ b/lib/codegen/julia/http.dart @@ -13,15 +13,19 @@ url = "{{url}}" \n """; - String kTemplateParams = """ +String kTemplateParams = """ params = Dict( {%- for name, value in params %} - "{{ name }}" => "{{ value }}", + "{{ name }}" => {%- if value is iterable and not value is string -%}[ + {%- for v in value -%}"{{ v }}"{%- if not loop.last -%}, {%- endif -%}{%- endfor -%} + ]{%- else -%}"{{ value }}"{%- endif -%}, {%- endfor %} ) \n """; + + String kTemplateHeaders = """ headers = Dict( {%- for name, value in headers %} @@ -64,7 +68,7 @@ response = HTTP.request("{{ method | upper }}", url final String kStringRequestEnd = r""" , status_exception=false) -println("Status Code: $(response.status) $(HTTP.StatusCodes.statustext(response.status))") +println("Status Code: $(response.status)") println("Response Body: \n$(String(response.body))") """; @@ -91,14 +95,14 @@ println("Response Body: \n$(String(response.body))") final templateUrl = jj.Template(kTemplateUrl); result += templateUrl.render({"url": stripUriParams(uri)}); - if (uri.hasQuery) { - var params = uri.queryParameters; + + var params = requestModel.enabledParamsMap; if (params.isNotEmpty) { hasQuery = true; final templateParams = jj.Template(kTemplateParams); result += templateParams.render({"params": params}); } - } + if (requestModel.hasJsonData || requestModel.hasTextData) { addHeaderForBody = true; From 60f7b387a5109cf938eb1c6dc182cf4ad39db727 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Tue, 25 Mar 2025 05:28:09 +0530 Subject: [PATCH 10/23] kotlin --- lib/codegen/kotlin/okhttp.dart | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index 418c0ba96..610436701 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -36,12 +36,22 @@ import okhttp3.MediaType.Companion.toMediaType"""; '''; - final String kTemplateUrlQuery = ''' + final String kTemplateUrlQuery = """ val url = "{{url}}".toHttpUrl().newBuilder() -{{params}} .build() +{%- for name, values in params %} + {%- if values is iterable and not values is string %} + {%- for value in values %} + .addQueryParameter("{{ name }}", "{{ value }}") + {%- endfor %} + {%- else %} + .addQueryParameter("{{ name }}", "{{ values }}") + {%- endif %} +{%- endfor %} + .build() + +"""; -'''; String kTemplateRequestBody = ''' @@ -95,15 +105,13 @@ import okhttp3.MediaType.Companion.toMediaType"""; if (uri != null) { String url = stripUriParams(uri); - if (uri.hasQuery) { - var params = uri.queryParameters; + var params = requestModel.enabledParamsMap; if (params.isNotEmpty) { hasQuery = true; var templateParams = jj.Template(kTemplateUrlQuery); result += templateParams - .render({"url": url, "params": getQueryParams(params)}); + .render({"url": url, "params": params}); } - } if (!hasQuery) { var templateUrl = jj.Template(kTemplateUrl); result += templateUrl.render({"url": url}); From 883e71ed8ee96a5e4b5d14808b25a91a71b00a26 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Thu, 3 Apr 2025 07:17:39 +0530 Subject: [PATCH 11/23] php --- lib/codegen/php/curl.dart | 32 ++++++++++++++++++------------ lib/codegen/php/guzzle.dart | 35 ++++++++++++++++++++------------- lib/codegen/php/http_plug.dart | 36 ++++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/lib/codegen/php/curl.dart b/lib/codegen/php/curl.dart index 24ff2579f..3425a66d4 100644 --- a/lib/codegen/php/curl.dart +++ b/lib/codegen/php/curl.dart @@ -35,11 +35,9 @@ $request_body = '{{body}}'; //defining query parameters String kTemplateParams = r''' $queryParams = [ -{%- for name, value in params %} - '{{ name }}' => '{{ value }}', -{%- endfor %} +{{params}} ]; -$uri .= '?' . http_build_query($queryParams); +$uri .= '?' . http_build_query($queryParams, '', '&'); '''; @@ -82,9 +80,9 @@ curl_setopt_array($request, [ $response = curl_exec($request); +$httpCode = curl_getinfo($request, CURLINFO_HTTP_CODE); curl_close($request); -$httpCode = curl_getinfo($request, CURLINFO_HTTP_CODE); echo "Status Code: " . $httpCode . "\n"; echo $response . "\n"; '''; @@ -122,13 +120,23 @@ echo $response . "\n"; } //checking and adding query params - if (uri.hasQuery) { - if (requestModel.enabledParamsMap.isNotEmpty) { - var templateParams = jj.Template(kTemplateParams); - result += templateParams - .render({"params": requestModel.enabledParamsMap}); - } - } + var params = requestModel.enabledParamsMap; +if (params.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + List paramList = []; + + params.forEach((key, value) { + if (value is List) { + paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); + } else { + paramList.add("'$key' => '$value'"); + } + }); + + result += templateParams.render({ + "params": paramList.join(",\n"), + }); +} var headers = requestModel.enabledHeadersMap; if (requestModel.hasBody && !requestModel.hasContentTypeHeader) { diff --git a/lib/codegen/php/guzzle.dart b/lib/codegen/php/guzzle.dart index d6fe79f64..72aa3a73c 100644 --- a/lib/codegen/php/guzzle.dart +++ b/lib/codegen/php/guzzle.dart @@ -20,14 +20,14 @@ use GuzzleHttp\\Psr7\\Request; """; - String kTemplateParams = """ +String kTemplateParams = """ \$queryParams = [ {{params}} ]; -\$queryParamsStr = '?' . http_build_query(\$queryParams); +\$queryParamsStr = '?' . http_build_query(\$queryParams, '','&'); +"""; -"""; String kTemplateHeader = """ \$headers = [ @@ -80,17 +80,24 @@ echo $res->getBody(); result += renderedMultiPartBody; } - var params = requestModel.enabledParamsMap; - if (params.isNotEmpty) { - var templateParams = jj.Template(kTemplateParams); - List paramList = []; - params.forEach((key, value) { - paramList.add("'$key' => '$value'"); - }); - result += templateParams.render({ - "params": paramList.join(",\n"), - }); - } +var params = requestModel.enabledParamsMap; +if (params.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + List paramList = []; + + params.forEach((key, value) { + if (value is List) { + paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); + } else { + paramList.add("'$key' => '$value'"); + } + }); + + result += templateParams.render({ + "params": paramList.join(",\n"), + }); +} + var headers = requestModel.enabledHeadersMap; List headerList = []; diff --git a/lib/codegen/php/http_plug.dart b/lib/codegen/php/http_plug.dart index 299c1a93e..98162f472 100644 --- a/lib/codegen/php/http_plug.dart +++ b/lib/codegen/php/http_plug.dart @@ -19,10 +19,12 @@ use Http\\Discovery\\Psr18ClientDiscovery; """; String kTemplateParams = """ -\$queryParams = [{{params}}]; -\$uri .= '?' . http_build_query(\$queryParams); + \$queryParams = [ + {{params}} + ]; + \$uri .= '?' . http_build_query(\$queryParams,'','&'); -"""; + """; String kTemplateRequestInit = """ \$request = Psr17FactoryDiscovery::findRequestFactory()->createRequest('{{method}}', \$uri); @@ -89,19 +91,23 @@ echo \$response->getBody(); var templateUri = jj.Template(kTemplateUri); result += templateUri.render({"uri": stripUriParams(uri)}); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - var templateParams = jj.Template(kTemplateParams); - List queryList = []; - for (MapEntry entry in params.entries) { - String entryStr = "\"${entry.key}\" => \"${entry.value}\""; - queryList.add(entryStr); - } - String paramsString = "\n ${queryList.join(",\n ")}\n"; - result += templateParams.render({"params": paramsString}); + var params = requestModel.enabledParamsMap; + if (params.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + List paramList = []; + + params.forEach((key, value) { + if (value is List) { + paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); + } else { + paramList.add("'$key' => '$value'"); } - } + }); + + result += templateParams.render({ + "params": paramList.join(",\n"), + }); + } var templateRequestInit = jj.Template(kTemplateRequestInit); result += templateRequestInit From c6f60b49d65b274571dbc54c05c6c91152b0fe0c Mon Sep 17 00:00:00 2001 From: Nikhil Date: Thu, 3 Apr 2025 20:39:43 +0530 Subject: [PATCH 12/23] pythom --- lib/codegen/python/requests.dart | 33 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index ef2a19faa..803621677 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -12,11 +12,9 @@ url = '{{url}}' """; - String kTemplateParams = """ - -params = {{params}} - -"""; +String kTemplateParams = """ +params = { {{params}} } +"""; String kTemplateBody = """ @@ -100,15 +98,24 @@ print('Response Body:', response.text) 'hasFormData': requestModel.hasFormData }); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - hasQuery = true; - var templateParams = jj.Template(kTemplateParams); - var paramsString = kJsonEncoder.convert(params); - result += templateParams.render({"params": paramsString}); - } + var params = requestModel.enabledParamsMap; + if (params.isNotEmpty) { + hasQuery=true; + var templateParams = jj.Template(kTemplateParams); + List paramList = []; + + params.forEach((key, value) { + if (value is List) { + paramList.add("'$key': [${value.map((v) => "'$v'").join(", ")}]"); + } else { + paramList.add("'$key': '$value'"); } + }); + + result += templateParams.render({ + "params": paramList.join(",\n"), + }); + } if (requestModel.hasFormData) { hasBody = true; From 5e77e6cb02194a7d102068f0357349971ec13f4a Mon Sep 17 00:00:00 2001 From: Nikhil Date: Thu, 3 Apr 2025 21:50:47 +0530 Subject: [PATCH 13/23] python - httpclient --- lib/codegen/python/http_client.dart | 33 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index a2c018082..58867a2c6 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -12,9 +12,8 @@ from codecs import encode String kTemplateParams = """ from urllib.parse import urlencode - -queryParams = {{params}} -queryParamsStr = '?' + urlencode(queryParams) +params = { {{params}} } +queryParamsStr = '?' + urlencode(params,doseq=True) """; @@ -102,17 +101,27 @@ body = b'\r\n'.join(dataList) ); Uri? uri = rec.$1; + var params = requestModel.enabledParamsMap; + if (params.isNotEmpty) { + hasQuery=true; + var templateParams = jj.Template(kTemplateParams); + List paramList = []; + + params.forEach((key, value) { + if (value is List) { + paramList.add("'$key': [${value.map((v) => "'$v'").join(", ")}]"); + } else { + paramList.add("'$key': '$value'"); + } + }); + + result += templateParams.render({ + "params": paramList.join(",\n"), + }); + } if (uri != null) { - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - hasQuery = true; - var templateParams = jj.Template(kTemplateParams); - var paramsString = kJsonEncoder.convert(params); - result += templateParams.render({"params": paramsString}); - } - } + if (requestModel.hasBody) { hasBody = true; From 4e9d709dadbbf96f44648c7cefdb0c0c8cb184b4 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 4 Apr 2025 02:31:09 +0530 Subject: [PATCH 14/23] rust-actix-hyper --- lib/codegen/rust/actix.dart | 61 ++++++++++++------------ lib/codegen/rust/hyper.dart | 92 +++++++++++++++++++++++-------------- 2 files changed, 89 insertions(+), 64 deletions(-) diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index acc752ead..f346cbaae 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -13,11 +13,24 @@ use std::io::Read; async fn main() -> Result<(), Box> { let url = "{{url}}"; let client = awc::Client::default(); - + let mut request = client.{{method}}(url); """; - String kTemplateParams = - """\n .query(&{{ params }})\n .unwrap()"""; +String kTemplateParams = """ + + let query_params = [ + {%- for key, values in params %} + {%- if values is iterable and values is not string %} + {%- for val in values %} + ("{{key}}", "{{val}}"), + {%- endfor %} + {%- else %} + ("{{key}}", "{{values}}"), + {%- endif %} + {%- endfor %} + ]; + request = request.query(&query_params).unwrap(); +"""; String kTemplateBody = """ @@ -37,11 +50,6 @@ async fn main() -> Result<(), Box> { String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; - String kTemplateRequest = """ - - let mut response = client\n .{{method}}(url) -"""; - final String kStringFormDataBody = r""" struct FormDataItem { @@ -92,11 +100,11 @@ multipart/form-data; boundary={{boundary}}'''; let payload = build_data_list(form_data_items); """; - String kStringRequestBody = """\n .send_body(payload)"""; + String kStringRequestBody = """\n let mut response = request.send_body(payload)"""; - String kStringRequestJson = """\n .send_json(&payload)"""; + String kStringRequestJson = """\n let mut response = request.send_json(&payload)"""; - String kStringRequestNormal = """\n .send()"""; + String kStringRequestNormal = """\n let mut response = request.send()"""; final String kStringRequestEnd = """\n .await\n .unwrap(); @@ -127,9 +135,10 @@ multipart/form-data; boundary={{boundary}}'''; ); Uri? uri = rec.$1; if (uri != null) { + var baseUrl = stripUriParams(uri); var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render({ - "url": stripUriParams(uri), + "url": baseUrl, 'isFormDataRequest': requestModel.hasFormData, "method": requestModel.method.name.toLowerCase() }); @@ -160,23 +169,17 @@ multipart/form-data; boundary={{boundary}}'''; }, ); } - var templateRequest = jj.Template(kTemplateRequest); - result += templateRequest.render({ - "method": method.name.toLowerCase(), - }); - - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - var tupleStrings = params.entries - .map((entry) => '("${entry.key}", "${entry.value}")') - .toList(); - var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParms = jj.Template(kTemplateParams); - result += templateParms.render({"params": paramsString}); - } - } - + + var params = requestModel.enabledParamsMap; + + if (params.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + result += templateParams.render({ + "method": method.name.toLowerCase(), + "params": params, + }); + } + var headersList = requestModel.enabledHeaders; if (headersList != null || hasBody || requestModel.hasFormData) { var headers = requestModel.enabledHeadersMap; diff --git a/lib/codegen/rust/hyper.dart b/lib/codegen/rust/hyper.dart index 1acaab55c..23b918d0c 100644 --- a/lib/codegen/rust/hyper.dart +++ b/lib/codegen/rust/hyper.dart @@ -5,82 +5,90 @@ import 'package:jinja/jinja.dart' as jj; class RustHyperCodeGen { final String kTemplateStart = """ {% if hasForm %}extern crate hyper_multipart_rfc7578 as hyper_multipart; -{% endif %}use hyper::{Body, Client, Request, Uri}; +{% endif %}use hyper::{Body, Client, Request}; {% if isHttps %}use hyper_tls::HttpsConnector; {% else %}use hyper::client::HttpConnector; {% endif %}{% if hasForm %}use hyper_multipart::client::multipart; {% endif %}{% if hasJsonBody %}use serde_json::json; {% endif %}use tokio; +use url::Url; #[tokio::main] async fn main() -> Result<(), Box> { let http{% if isHttps %}s{% endif %} = Http{% if isHttps %}s{% endif %}Connector::new(); let client = Client::builder().build::<_, hyper::Body>(http{% if isHttps %}s{% endif %}); - let url = "{{ url }}".parse::().unwrap(); - + let mut url = Url::parse("{{ baseUrl }}")?;\n + """; + + final String kTemplateParams = """ + {% for key, values in params %}{% if values is iterable and values is not string %}{% for val in values %}\n url.query_pairs_mut().append_pair("{{ key }}", "{{ val }}");{% endfor %} + {% else %} + url.query_pairs_mut().append_pair("{{ key }}", "{{ values }}"); + {% endif %} + {% endfor %} """; final String kTemplateMethod = """ let req_builder = Request::builder() - .method("{{ method }}") - .uri(url) + .method("{{ method }}").uri(url.as_str()) """; + final String kTemplateMethodNoHeadersButForm = """ let req_builder = Request::builder() - .method("{{ method }}") - .uri(url); + .method("{{ method }}") + .uri(url.as_str()); """; final String kTemplateHeaders = """ - {% for key, val in headers %} - .header("{{ key }}", "{{ val }}") - {% endfor %}"""; + {% for key, val in headers %} + .header("{{ key }}", "{{ val }}") + {% endfor %}"""; final String kTemplateHeadersFormData = """ - {% for key, val in headers %} - .header("{{ key }}", "{{ val }}"){% if loop.last %};{% endif %} - {% endfor %} + {% for key, val in headers %} + .header("{{ key }}", "{{ val }}"){% if loop.last %};{% endif %} + {% endfor %} """; final String kTemplateBody = """ - - .body(Body::from(r#"{{ body }}"#))?;\n + + .body(Body::from(r#"{{ body }}"#))?;\n """; final String kTemplateJsonBody = """ - - .body(Body::from(json!({{ body }}).to_string()))?;\n + + .body(Body::from(json!({{ body }}).to_string()))?;\n """; final String kTemplateEmptyBody = """ - .body(Body::empty())?;\n + .body(Body::empty())?;\n """; final String kTemplateFormData = """ - + let mut form = multipart::Form::default(); {%- for field in fields_list %} - {%- if field.type == "file" %} + {%- if field.type == "file" %} form.add_file("{{ field.name }}", r"{{ field.value }}").unwrap(); - {%- else %} + {%- else %} form.add_text("{{ field.name }}", "{{ field.value }}"); - {%- endif %} + {%- endif %} {%- endfor %} let req = form.set_body_convert::(req_builder).unwrap(); - - """; + +"""; final String kTemplateEndForm = """ - let res = client.request(req).await?; + let res = client.request(req).await?; let status = res.status(); let body_bytes = hyper::body::to_bytes(res).await?; let body = String::from_utf8(body_bytes.to_vec())?; println!("Response Status: {}", status); println!("Response: {:?}", body); - + """; @@ -108,16 +116,30 @@ async fn main() -> Result<(), Box> { String url = requestModel.url; var rec = getValidRequestUri(url, requestModel.enabledParams); Uri? uri = rec.$1; - + if (uri != null) { + var baseUrl = url.split('?').first; + + // Get query parameters + var params = requestModel.enabledParamsMap; + var headers = requestModel.enabledHeadersMap; + + // Generate template start with base URL result += jj.Template(kTemplateStart).render({ - "url": uri, + "baseUrl": baseUrl, "isHttps": uri.scheme == "https" ? true : false, 'hasJsonBody': requestModel.hasJsonData, 'hasForm': requestModel.hasFormData, }); - + + // Add query parameters if available + if (params.isNotEmpty) { + result += jj.Template(kTemplateParams).render({ + "params": params, + }); + } + if (requestModel.hasFormData && headers.isEmpty) { result += jj.Template(kTemplateMethodNoHeadersButForm).render({ "method": requestModel.method.name.toUpperCase(), @@ -127,9 +149,8 @@ async fn main() -> Result<(), Box> { "method": requestModel.method.name.toUpperCase(), }); } - + // Add headers if available - if (headers.isNotEmpty) { if (requestModel.hasFormData) { result += jj.Template(kTemplateHeadersFormData) @@ -139,7 +160,7 @@ async fn main() -> Result<(), Box> { jj.Template(kTemplateHeaders).render({"headers": headers}); } } - + // Handle body (JSON or raw) var requestBody = requestModel.body; if (requestModel.hasFormData) { @@ -157,19 +178,20 @@ async fn main() -> Result<(), Box> { } else if (requestModel.hasTextData) { result += jj.Template(kTemplateBody).render({"body": requestBody}); } + // End request - if (requestModel.hasFormData && requestModel.method != HTTPVerb.get) { result += kTemplateEndForm; } else { result += kTemplateRequestEnd; } + result += kTemplateEnd; } - + return result; } catch (e) { return null; } } -} +} \ No newline at end of file From d5d7d5728e10136fb63af951c6c353c6c1753721 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 4 Apr 2025 04:12:52 +0530 Subject: [PATCH 15/23] rust all --- lib/codegen/rust/curl_rust.dart | 56 +++++++++++++++++++++++---------- lib/codegen/rust/reqwest.dart | 53 +++++++++++++++++-------------- lib/codegen/rust/ureq.dart | 27 +++++++++------- 3 files changed, 84 insertions(+), 52 deletions(-) diff --git a/lib/codegen/rust/curl_rust.dart b/lib/codegen/rust/curl_rust.dart index 727f0b2cd..9284cdf2e 100644 --- a/lib/codegen/rust/curl_rust.dart +++ b/lib/codegen/rust/curl_rust.dart @@ -1,6 +1,6 @@ + import 'package:apidash_core/apidash_core.dart'; import 'package:jinja/jinja.dart' as jj; -import '../../utils/utils.dart'; class RustCurlCodeGen { final String kTemplateStart = """use curl::easy::Easy; @@ -10,11 +10,27 @@ class RustCurlCodeGen { fn main() { let mut easy = Easy::new(); let mut data = Vec::new(); - + let base_url = "{{baseUrl}}"; """; - String kTemplateUrl = """ - easy.url("{{url}}").unwrap(); + String kTemplateUrlParams = """ + + {% if params %} + let params: Vec<(&str, Vec<&str>)> = vec![ + {%- for key, values in params %} + ("{{key}}", vec![{% if values is iterable and values is not string %}{% for val in values %}"{{val}}", {% endfor %}{% else %}"{{values}}"{% endif %}]), + {%- endfor %} + ]; + let query_string: String = params + .iter() + .flat_map(|(key, values)| values.iter().map(move |val| format!("{}={}", key, val))) + .collect::>() + .join("&"); + let url = format!("{}?{}", base_url, query_string); + {% else %} + let url = base_url.to_string(); + {% endif %} + """; String kTemplateMethod = """ @@ -50,7 +66,7 @@ fn main() { .add().unwrap(); {% endfor %} easy.httppost(form).unwrap(); - """; +"""; String kTemplateHeader = """ {% if headers %}let mut list = List::new();{% for header, value in headers %} @@ -62,6 +78,7 @@ fn main() { final String kTemplateEnd = """ { + easy.url(&url).unwrap(); let mut transfer = easy.transfer(); transfer.write_function(|new_data| { data.extend_from_slice(new_data); @@ -71,7 +88,6 @@ fn main() { } let response_body = String::from_utf8_lossy(&data); - println!("Response body: {}", response_body); println!("Response code: {}", easy.response_code().unwrap()); }"""; @@ -86,7 +102,8 @@ fn main() { "hasJsonBody": requestModel.hasJsonData, "hasHeaders": (requestModel.enabledHeaders != null && requestModel.enabledHeaders!.isNotEmpty) || - (requestModel.hasJsonData || requestModel.hasTextData) + (requestModel.hasJsonData || requestModel.hasTextData), + "baseUrl": url.split('?').first, }); var rec = getValidRequestUri( @@ -95,16 +112,21 @@ fn main() { ); Uri? uri = rec.$1; - var harJson = - requestModelToHARJsonRequest(requestModel, useEnabled: true); + + if (uri != null) { - var templateUrl = jj.Template(kTemplateUrl); - result += templateUrl.render({"url": harJson["url"]}); + var params = requestModel.enabledParamsMap; - var methodTemplate = jj.Template(kTemplateMethod); - result += methodTemplate.render({"method": requestModel.method.name}); + var templateUrlParams = jj.Template(kTemplateUrlParams); + result += templateUrlParams.render({ + "params": params.isNotEmpty ? params : null, + }); - if (uri != null) { + // Method + var methodTemplate = jj.Template(kTemplateMethod); + result += methodTemplate.render({"method": requestModel.method.name.toLowerCase()}); + + // Request body if (requestModel.hasTextData) { var templateBody = jj.Template(kTemplateRawBody); result += templateBody.render({"body": requestModel.body}); @@ -117,7 +139,7 @@ fn main() { "fields": requestModel.formDataMapList, }); } - + var headersList = requestModel.enabledHeaders; if (headersList != null || requestModel.hasBody) { var headers = requestModel.enabledHeadersMap; @@ -129,10 +151,10 @@ fn main() { var templateHeader = jj.Template(kTemplateHeader); result += templateHeader.render({ "headers": headers, - }); + }); } } - + result += kTemplateEnd; } diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart index 1e72807b0..c51b0fe90 100644 --- a/lib/codegen/rust/reqwest.dart +++ b/lib/codegen/rust/reqwest.dart @@ -7,26 +7,37 @@ class RustReqwestCodeGen { final String kTemplateStart = """fn main() -> Result<(), Box> { let client = reqwest::blocking::Client::new(); - let url = "{{url}}"; + let url = "{{url}}";\n +"""; + String kTemplateParamsDef = """ + let query_params = [ + {%- for key, values in params %} + {%- if values is iterable and values is not string %} + {%- for val in values %} + ("{{key}}", "{{val}}"), + {%- endfor %} + {%- else %} + ("{{key}}", "{{values}}"), + {%- endif %} + {%- endfor %} + ]; """; - String kTemplateParams = """\n .query(&{{params}})"""; + String kTemplateParamsChain = """\n .query(&query_params)"""; String kTemplateBody = """ let payload = r#"{{body}}"#; - """; String kTemplateJson = """ let payload = serde_json::json!({{body}}); - """; String kTemplateHeaders = - """\n {% for key, val in headers -%}.header("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + """\n {% for key, val in headers -%}.header("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; String kTemplateRequest = """ @@ -79,7 +90,7 @@ class RustReqwestCodeGen { String? getCode( HttpRequestModel requestModel, - ) { + ) { try { String result = ""; bool hasBody = false; @@ -90,14 +101,12 @@ class RustReqwestCodeGen { var rec = getValidRequestUri( url, requestModel.enabledParams, - ); + ); Uri? uri = rec.$1; if (uri != null) { var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render({ - "url": stripUriParams(uri), - 'isFormDataRequest': requestModel.hasFormData, - 'isJson': requestModel.bodyContentType == ContentType.json + "url": url.split('?').first }); var method = requestModel.method; @@ -121,28 +130,26 @@ class RustReqwestCodeGen { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { - "fields_list": requestModel.formDataMapList, - }, + "fields_list": requestModel.formDataMapList, + }, ); } + var params = requestModel.enabledParamsMap; + if (params.isNotEmpty) { + var templateParamsDef = jj.Template(kTemplateParamsDef); + result += templateParamsDef.render({"params": params}); + } + var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ "method": method.name.toLowerCase(), }); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - var tupleStrings = params.entries - .map((entry) => '("${entry.key}", "${entry.value}")') - .toList(); - var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParams = jj.Template(kTemplateParams); - result += templateParams.render({"params": paramsString}); - } + if (params.isNotEmpty) { + result += kTemplateParamsChain; } - var headersList = requestModel.enabledHeaders; + var headersList = requestModel.enabledHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; if (hasBody) { diff --git a/lib/codegen/rust/ureq.dart b/lib/codegen/rust/ureq.dart index 0a8a07440..0fe9d2afa 100644 --- a/lib/codegen/rust/ureq.dart +++ b/lib/codegen/rust/ureq.dart @@ -13,20 +13,26 @@ fn main() -> Result<(), ureq::Error> { let url = "{{url}}"; """; - // String kTemplateParams = """\n .query_pairs({{ params }})"""; - String kTemplateParams = - """\n {% for key, val in params -%}.query("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + String kTemplateParams = """ + {%- for key, values in params %} + {%- if values is iterable and values is not string %} + {%- for val in values %} + .query("{{key}}", "{{val}}") + {%- endfor %} + {%- else %} + .query("{{key}}", "{{values}}") + {%- endif %} + {%- endfor %} +"""; String kTemplateBody = """ let payload = r#"{{body}}"#; - """; String kTemplateJson = """ let payload = ureq::json!({{body}}); - """; String kTemplateHeaders = @@ -128,7 +134,6 @@ multipart/form-data; boundary={{boundary}}'''; result += templateStartUrl.render({ "url": stripUriParams(uri), 'isFormDataRequest': requestModel.hasFormData, - "method": requestModel.method.name.toLowerCase() }); var method = requestModel.method; @@ -162,12 +167,10 @@ multipart/form-data; boundary={{boundary}}'''; "method": method.name.toLowerCase(), }); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - var templateParms = jj.Template(kTemplateParams); - result += templateParms.render({"params": params}); - } + var params = requestModel.enabledParamsMap; + if (params.isNotEmpty) { + var templateParams = jj.Template(kTemplateParams); + result += templateParams.render({"params": params}); } var headersList = requestModel.enabledHeaders; From c7b3b30bdc5e4fd0a30ddcb4d38131ba60a327ed Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sat, 5 Apr 2025 04:31:30 +0530 Subject: [PATCH 16/23] ruby --- lib/codegen/ruby/faraday.dart | 12 ++++----- lib/codegen/ruby/net_http.dart | 44 ++++++++++++++++++++++++--------- lib/codegen/rust/curl_rust.dart | 6 +---- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/lib/codegen/ruby/faraday.dart b/lib/codegen/ruby/faraday.dart index 11d73946d..1a903c34c 100644 --- a/lib/codegen/ruby/faraday.dart +++ b/lib/codegen/ruby/faraday.dart @@ -59,7 +59,8 @@ response = conn.{{ method|lower }}(REQUEST_URL{% if doesMethodAcceptBody and con final String kTemplateRequestParams = """ req.params = { -{% for key, val in params %} "{{ key }}" => "{{ val }}",\n{% endfor %} } + {% for key, val in params %}"{{ key }}" => {% if val is list %}[{% for v in val %}"{{ v|string }}"{% if not loop.last %}, {% endif %}{% endfor %}]{% else %}"{{ val|string }}"{% endif %}, + {% endfor %}} """; @@ -155,12 +156,9 @@ puts "Response Body: #{response.body}" result += templateRequestHeaders.render({"headers": headers}); } - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - var templateRequestParams = jj.Template(kTemplateRequestParams); - result += templateRequestParams.render({"params": params}); - } + if (requestModel.enabledParamsMap.isNotEmpty) { + var templateRequestParams = jj.Template(kTemplateRequestParams); + result += templateRequestParams.render({"params": requestModel.enabledParamsMap}); } if (requestModel.hasBody && requestModel.method == HTTPVerb.delete) { diff --git a/lib/codegen/ruby/net_http.dart b/lib/codegen/ruby/net_http.dart index 519c5cfa7..93a5f9c76 100644 --- a/lib/codegen/ruby/net_http.dart +++ b/lib/codegen/ruby/net_http.dart @@ -6,6 +6,16 @@ class RubyNetHttpCodeGen { require "net/http" url = URI("{{url}}") +"""; + + String kTemplateRequestParams = """ +\nparams = { +{% for key, val in params %} "{{ key }}" => {% if val is list %}[{% for v in val %}"{{ v|string }}"{% if not loop.last %}, {% endif %}{% endfor %}]{% else %}"{{ val|string }}"{% endif %}, +{% endfor %}} +url.query = URI.encode_www_form(params)\n +"""; + + String kTemplateConnectionAndRequest = """ https = Net::HTTP.new(url.host, url.port) {% if check == "https" %}https.use_ssl = true{% endif %} request = Net::HTTP::{{method}}.new(url) @@ -13,7 +23,8 @@ request = Net::HTTP::{{method}}.new(url) String kTemplateHeader = """ {% for key, value in headers %} -request["{{key}}"] = "{{value}}"{% endfor %} +request["{{key}}"] = "{{value}}" +{% endfor %} """; String kTemplateBody = """ @@ -31,7 +42,11 @@ HEREDOC response = https.request(request) puts "Response Code: #{response.code}" -{% if method != "head" %}puts "Response Body: #{response.body}"{% else %}puts "Response Body: #{response.to_hash}"{% endif %} +{% if method != "head" %} +puts "Response Body: #{response.body}" +{% else %} +puts "Response Headers: #{response.to_hash}" +{% endif %} """; @@ -52,7 +67,17 @@ puts "Response Code: #{response.code}" var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "url": uri.query.isEmpty ? stripUriParams(uri) : uri, + "url": uri.toString().split('?').first, + }); + if (requestModel.enabledParamsMap.isNotEmpty) { + var templateRequestParams = jj.Template(kTemplateRequestParams); + result += templateRequestParams.render({ + "params": requestModel.enabledParamsMap, + }); + } + + var connectionTemplate = jj.Template(kTemplateConnectionAndRequest); + result += connectionTemplate.render({ "method": requestModel.method.name.capitalize(), "check": uri.scheme, }); @@ -78,8 +103,7 @@ puts "Response Code: #{response.code}" } if (requestModel.hasFormData) { - result += "\n"; - result += "form_data = ["; + result += "\nform_data = ["; var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); int length = requestModel.formDataMapList.length; @@ -90,16 +114,12 @@ puts "Response Code: #{response.code}" "value": element["value"], "type": element["type"] }); - length -= 1; - if (length == 0) { - result += "]"; - } else { - result += "],"; - } + result += "]"; + if (--length > 0) result += ", "; } result += "]\n"; result += - "request.set_form form_data, '${ContentType.formdata.header}'"; + "request.set_form form_data, '${ContentType.formdata.header}'\n"; } result += jj.Template(kStringRequest) diff --git a/lib/codegen/rust/curl_rust.dart b/lib/codegen/rust/curl_rust.dart index 9284cdf2e..64dba161b 100644 --- a/lib/codegen/rust/curl_rust.dart +++ b/lib/codegen/rust/curl_rust.dart @@ -21,11 +21,7 @@ fn main() { ("{{key}}", vec![{% if values is iterable and values is not string %}{% for val in values %}"{{val}}", {% endfor %}{% else %}"{{values}}"{% endif %}]), {%- endfor %} ]; - let query_string: String = params - .iter() - .flat_map(|(key, values)| values.iter().map(move |val| format!("{}={}", key, val))) - .collect::>() - .join("&"); + let query_string: String = params.iter().flat_map(|(key, values)| values.iter().map(move |val| format!("{}={}", key, val))) .collect::>().join("&"); let url = format!("{}?{}", base_url, query_string); {% else %} let url = base_url.to_string(); From 17ea029508bcd646fed27e7dc3726287378bcd3f Mon Sep 17 00:00:00 2001 From: Nikhil Date: Mon, 7 Apr 2025 00:50:03 +0530 Subject: [PATCH 17/23] datatype changes --- .../lib/models/http_request_model.dart | 20 +++++------ .../lib/utils/http_request_utils.dart | 34 +++++-------------- .../apidash_core/lib/utils/uri_utils.dart | 12 +++---- 3 files changed, 23 insertions(+), 43 deletions(-) diff --git a/packages/apidash_core/lib/models/http_request_model.dart b/packages/apidash_core/lib/models/http_request_model.dart index 2b28016ee..f521a1ce7 100644 --- a/packages/apidash_core/lib/models/http_request_model.dart +++ b/packages/apidash_core/lib/models/http_request_model.dart @@ -34,25 +34,25 @@ class HttpRequestModel with _$HttpRequestModel { _$HttpRequestModelFromJson(json); Map get headersMap => rowsToMap(headers) ?? {}; - Map get paramsMap => rowsToRequestMap(params) ?? {}; + Map> get paramsMap => rowsToRequestMap(params) ?? {}; List? get enabledHeaders => getEnabledRows(headers, isHeaderEnabledList); List? get enabledParams => getEnabledRows(params, isParamEnabledList); Map get enabledHeadersMap => rowsToMap(enabledHeaders) ?? {}; -Map get enabledParamsMap { +Map> get enabledParamsMap { var extractedParams = Uri.parse(url).queryParametersAll; var userParams = rowsToRequestMap(enabledParams) ?? {}; - - extractedParams.forEach((key, value) { - userParams[key] = [ - ...value, - if (userParams.containsKey(key)) - ...(userParams[key] is List ? List.from(userParams[key]) : [userParams[key]]) - ]; + + extractedParams.forEach((key, values) { + if (userParams.containsKey(key)) { + userParams[key]!.addAll(values); + } else { + userParams[key] = List.from(values); + } }); - + return userParams; } diff --git a/packages/apidash_core/lib/utils/http_request_utils.dart b/packages/apidash_core/lib/utils/http_request_utils.dart index 843273d0d..c195a8aa8 100644 --- a/packages/apidash_core/lib/utils/http_request_utils.dart +++ b/packages/apidash_core/lib/utils/http_request_utils.dart @@ -100,51 +100,33 @@ String? getRequestBody(APIType type, HttpRequestModel httpRequestModel) { APIType.graphql => getGraphQLBody(httpRequestModel), }; } -Map? rowsToRequestMap(List? rows) { +Map>? rowsToRequestMap(List? rows) { if (rows == null) { return null; } - - final Map finalMap = {}; - + final Map> finalMap = {}; for (var row in rows) { final key = row.name.trim(); if (key.isEmpty) continue; - final value = row.value.toString(); - if (finalMap.containsKey(key)) { - - if (finalMap[key] is List) { - (finalMap[key] as List).add(value); - } else { - finalMap[key] = [finalMap[key], value]; - } + finalMap[key]!.add(value); } else { - - finalMap[key] = value; + finalMap[key] = [value]; } } - return finalMap; } -List? requestMapToRows(Map? requestMap) { +List? requestMapToRows(Map>? requestMap) { if (requestMap == null) { return null; } - final List finalRows = []; - - requestMap.forEach((key, value) { - if (value is List) { - for (var item in value) { - finalRows.add(NameValueModel(name: key, value: item.toString())); - } - } else { - finalRows.add(NameValueModel(name: key, value: value.toString())); + requestMap.forEach((key, values) { + for (var value in values) { + finalRows.add(NameValueModel(name: key, value: value)); } }); - return finalRows; } \ No newline at end of file diff --git a/packages/apidash_core/lib/utils/uri_utils.dart b/packages/apidash_core/lib/utils/uri_utils.dart index 0b3785aa3..901d7f73b 100644 --- a/packages/apidash_core/lib/utils/uri_utils.dart +++ b/packages/apidash_core/lib/utils/uri_utils.dart @@ -54,13 +54,11 @@ String stripUrlParams(String url) { Map> queryParams = uri.queryParametersAll; - Map? requestQueryParams = rowsToRequestMap(requestParams); - if (requestQueryParams != null) { - Map> queryParamsList = requestQueryParams.map((key, value) { - return MapEntry(key, List.from(value is String ? [value] : value)); - }); - queryParams = mergeMaps(queryParams, queryParamsList, value: (v1, v2) => v1 + v2); - } + Map>? requestQueryParams = rowsToRequestMap(requestParams); + if (requestQueryParams != null) { + queryParams = mergeMaps(queryParams, requestQueryParams, value: (v1, v2) => v1 + v2); +} + if (queryParams.isNotEmpty) { uri = uri.replace(queryParameters: queryParams); } From 8a71c905859ce4fba270d1b5ff66a59d8fd4be40 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 11 Apr 2025 04:08:23 +0530 Subject: [PATCH 18/23] updated datatypes --- .../history_widgets/his_request_pane.dart | 23 ++++----- lib/widgets/table_request.dart | 51 +++++++++---------- test/widgets/table_request_test.dart | 20 ++++---- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/lib/screens/history/history_widgets/his_request_pane.dart b/lib/screens/history/history_widgets/his_request_pane.dart index a64b96f88..02ce2d708 100644 --- a/lib/screens/history/history_widgets/his_request_pane.dart +++ b/lib/screens/history/history_widgets/his_request_pane.dart @@ -20,15 +20,15 @@ class HistoryRequestPane extends ConsumerWidget { final codePaneVisible = ref.watch(historyCodePaneVisibleStateProvider); final apiType = ref.watch(selectedHistoryRequestModelProvider .select((value) => value?.metaData.apiType)); - final headersMap = ref.watch(selectedHistoryRequestModelProvider - .select((value) => value?.httpRequestModel.headersMap)) ?? - {}; - final headerLength = headersMap.length; + final headers = ref.watch(selectedHistoryRequestModelProvider + .select((value) => value?.httpRequestModel.headers)) ?? + []; + final headerLength = headers.length; - final paramsMap = ref.watch(selectedHistoryRequestModelProvider - .select((value) => value?.httpRequestModel.paramsMap)) ?? - {}; - final paramLength = paramsMap.length; + final params = ref.watch(selectedHistoryRequestModelProvider + .select((value) => value?.httpRequestModel.params)) ?? + []; + final paramLength = params.length; final hasBody = ref.watch(selectedHistoryRequestModelProvider .select((value) => value?.httpRequestModel.hasBody)) ?? @@ -60,11 +60,11 @@ class HistoryRequestPane extends ConsumerWidget { ], children: [ RequestDataTable( - rows: paramsMap, + rows: params, keyName: kNameURLParam, ), RequestDataTable( - rows: headersMap, + rows: headers, keyName: kNameHeader, ), const HisRequestBody(), @@ -89,7 +89,7 @@ class HistoryRequestPane extends ConsumerWidget { ], children: [ RequestDataTable( - rows: headersMap, + rows: headers, keyName: kNameHeader, ), const HisRequestBody(), @@ -137,7 +137,6 @@ class HisRequestBody extends ConsumerWidget { padding: kPh4, child: RequestFormDataTable( rows: requestModel?.formData ?? [])), - // TODO: Fix JsonTextFieldEditor & plug it here ContentType.json => Padding( padding: kPt5o10, child: JsonTextFieldEditor( diff --git a/lib/widgets/table_request.dart b/lib/widgets/table_request.dart index fe3e19e2b..d3c6a57c9 100644 --- a/lib/widgets/table_request.dart +++ b/lib/widgets/table_request.dart @@ -2,6 +2,7 @@ import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:apidash/consts.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'field_read_only.dart'; class RequestDataTable extends StatelessWidget { @@ -12,7 +13,7 @@ class RequestDataTable extends StatelessWidget { this.valueName, }); - final Map rows; + final List rows; final String? keyName; final String? valueName; @@ -55,31 +56,29 @@ class RequestDataTable extends StatelessWidget { ), ); - final List dataRows = rows.entries - .map( - (MapEntry entry) => DataRow( - cells: [ - const DataCell(kHSpacer5), - DataCell( - ReadOnlyTextField( - initialValue: entry.key, - decoration: fieldDecoration, - ), - ), - const DataCell( - Text('='), - ), - DataCell( - ReadOnlyTextField( - initialValue: entry.value is String ? entry.value : entry.value.toString(), - decoration: fieldDecoration, - ), - ), - const DataCell(kHSpacer5), - ], + final List dataRows = rows.map((NameValueModel row) { + return DataRow( + cells: [ + const DataCell(kHSpacer5), + DataCell( + ReadOnlyTextField( + initialValue: row.name, + decoration: fieldDecoration, + ), ), - ) - .toList(); + const DataCell( + Text('='), + ), + DataCell( + ReadOnlyTextField( + initialValue: row.value, + decoration: fieldDecoration, + ), + ), + const DataCell(kHSpacer5), + ], + ); + }).toList(); return Container( margin: kP10, @@ -106,4 +105,4 @@ class RequestDataTable extends StatelessWidget { ), ); } -} +} \ No newline at end of file diff --git a/test/widgets/table_request_test.dart b/test/widgets/table_request_test.dart index cc0e33242..0c94e03ee 100644 --- a/test/widgets/table_request_test.dart +++ b/test/widgets/table_request_test.dart @@ -1,4 +1,5 @@ import 'package:apidash/widgets/widgets.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -6,10 +7,10 @@ import 'package:flutter_test/flutter_test.dart'; void main() { dataTableShowLogs = false; testWidgets('Testing RequestDataTable', (WidgetTester tester) async { - final Map sampleData = { - 'Key1': 'Value1', - 'Key2': 'Value2', - }; + final List sampleData = [ + const NameValueModel(name: 'key1', value: 'Value1'), + const NameValueModel(name: 'key2', value: 'value2'), + ]; await tester.pumpWidget( MaterialApp( @@ -22,12 +23,13 @@ void main() { ), ), ); + expect(find.byType(DataTable2), findsOneWidget); - expect(find.byType(ReadOnlyTextField), findsNWidgets(4)); + expect(find.byType(ReadOnlyTextField), findsNWidgets(4)); - expect(find.text('Key1'), findsOneWidget); + expect(find.text('key1'), findsOneWidget); expect(find.text('Value1'), findsOneWidget); - expect(find.text('Key2'), findsOneWidget); - expect(find.text('Value2'), findsOneWidget); + expect(find.text('key2'), findsOneWidget); + expect(find.text('value2'), findsOneWidget); }); -} +} \ No newline at end of file From a14bc695f60a74b9f2403381260a1946e89ad755 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sat, 10 May 2025 16:27:57 +0530 Subject: [PATCH 19/23] updated test --- test/models/http_request_model_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/models/http_request_model_test.dart b/test/models/http_request_model_test.dart index 78a520978..9cab2832e 100644 --- a/test/models/http_request_model_test.dart +++ b/test/models/http_request_model_test.dart @@ -33,7 +33,7 @@ void main() { 'User-Agent': 'Test Agent', 'Content-Type': 'application/json; charset=utf-8' }); - expect(httpRequestModel.paramsMap, {'size': '2', 'len': '3'}); + expect(httpRequestModel.paramsMap, {'size': ['2'], 'len': ['3']}); expect(httpRequestModel.enabledHeaders, const [ NameValueModel( name: 'Content-Type', value: 'application/json; charset=utf-8') @@ -44,7 +44,7 @@ void main() { ]); expect(httpRequestModel.enabledHeadersMap, {'Content-Type': 'application/json; charset=utf-8'}); - expect(httpRequestModel.enabledParamsMap, {'size': '2', 'len': '3'}); + expect(httpRequestModel.enabledParamsMap, {'size': ['2'], 'len': ['3']}); expect(httpRequestModel.hasContentTypeHeader, true); expect(httpRequestModel.hasFormDataContentType, false); From 5fae77d3568766d3bcfd14c0ae196caa044d7cca Mon Sep 17 00:00:00 2001 From: Nikhil <72620320+badnikhil@users.noreply.github.com> Date: Mon, 12 May 2025 00:18:59 +0530 Subject: [PATCH 20/23] Update codegen.dart From 31a236d6c2b4884bd49c6a625f14f6a9a3ccd0c8 Mon Sep 17 00:00:00 2001 From: Nikhil <72620320+badnikhil@users.noreply.github.com> Date: Mon, 12 May 2025 00:20:35 +0530 Subject: [PATCH 21/23] Update main.dart --- lib/main.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index d8a4dd7f3..63dff5813 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,6 @@ import 'package:apidash_design_system/apidash_design_system.dart'; + + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'models/models.dart'; From eecf617388b6cf68fb6b2389607e772982bac771 Mon Sep 17 00:00:00 2001 From: Nikhil <72620320+badnikhil@users.noreply.github.com> Date: Mon, 12 May 2025 00:21:22 +0530 Subject: [PATCH 22/23] Update main.dart --- lib/main.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 63dff5813..2830a9087 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,5 @@ import 'package:apidash_design_system/apidash_design_system.dart'; - import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'models/models.dart'; From f19e84b4cc3a689f469a741067eb79fe18e3136c Mon Sep 17 00:00:00 2001 From: Nikhil Date: Thu, 15 May 2025 03:41:08 +0530 Subject: [PATCH 23/23] minor optimisation/fixes in codegen --- lib/codegen/csharp/http_client.dart | 5 --- lib/codegen/csharp/rest_sharp.dart | 10 ++---- lib/codegen/go/http.dart | 10 ++---- lib/codegen/java/async_http_client.dart | 7 ++-- lib/codegen/java/okhttp.dart | 14 +++----- lib/codegen/java/unirest.dart | 13 +++---- lib/codegen/js/fetch.dart | 8 +---- lib/codegen/julia/http.dart | 4 +-- lib/codegen/kotlin/okhttp.dart | 6 +--- lib/codegen/php/curl.dart | 8 ++--- lib/codegen/php/guzzle.dart | 8 ++--- lib/codegen/php/http_plug.dart | 8 ++--- lib/codegen/python/http_client.dart | 8 ++--- lib/codegen/python/requests.dart | 8 ++--- lib/codegen/ruby/net_http.dart | 2 +- lib/codegen/rust/actix.dart | 4 --- lib/codegen/rust/curl_rust.dart | 2 +- lib/codegen/rust/hyper.dart | 9 ++--- lib/codegen/rust/reqwest.dart | 4 --- lib/codegen/rust/ureq.dart | 4 --- lib/codegen/swift/alamofire.dart | 46 +++++++++++++++++++++---- lib/codegen/swift/urlsession.dart | 2 +- 22 files changed, 79 insertions(+), 111 deletions(-) diff --git a/lib/codegen/csharp/http_client.dart b/lib/codegen/csharp/http_client.dart index 6d200051c..370638163 100644 --- a/lib/codegen/csharp/http_client.dart +++ b/lib/codegen/csharp/http_client.dart @@ -19,15 +19,10 @@ string baseUri = "{{ baseUri }}"; var query = new Dictionary>(); {%- for key, values in queryParams %} - {%- if values is string %} - query["{{ key }}"] = new List(); - query["{{ key }}"].Add("{{ values }}"); - {%- else %} query["{{ key }}"] = new List(); {%- for value in values %} query["{{ key }}"].Add("{{ value }}"); {%- endfor %} - {%- endif %} {%- endfor %} var queryString = string.Join("&", query.SelectMany(kv => kv.Value.Select(v => string.Format("{0}={1}", kv.Key, v)))); diff --git a/lib/codegen/csharp/rest_sharp.dart b/lib/codegen/csharp/rest_sharp.dart index fa5cc4a64..0d0747d0d 100644 --- a/lib/codegen/csharp/rest_sharp.dart +++ b/lib/codegen/csharp/rest_sharp.dart @@ -118,14 +118,10 @@ class Program String paramsResult = ""; requestModel.enabledParamsMap.forEach((key, values) { - if (values is List) { - for (var value in values) { - paramsResult += templateParams.render({"param": key, "value": value}); - } - } else { - paramsResult += templateParams.render({"param": key, "value": values}); + for (var value in values) { + paramsResult += templateParams.render({"param": key, "value": value}); } - }); + }); result += "$paramsResult\n"; } diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart index 5342c9148..36b958c93 100644 --- a/lib/codegen/go/http.dart +++ b/lib/codegen/go/http.dart @@ -128,14 +128,10 @@ url.RawQuery = query.Encode() if (requestModel.enabledParamsMap.isNotEmpty) { var queryParams = []; requestModel.enabledParamsMap.forEach((key, value) { - if (value is List) { - for (var v in value) { - queryParams.add({'key': key, 'value': v}); - } - } else { - queryParams.add({'key': key, 'value': value}); + for (var v in value) { + queryParams.add({'key': key, 'value': v}); } - }); + }); var templateQueryParam = jj.Template(kTemplateQueryParam); result += templateQueryParam.render({"params": queryParams}); diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index f19282a42..e4060995e 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -39,10 +39,9 @@ public class Main { BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("{{ method|upper }}", url); '''; - final String kTemplateUrlQueryParam = ''' {% for name, value in queryParams %} -{% if value is not string %} - {% for v in value %} requestBuilder.addQueryParam("{{ name }}", "{{ v }}"); - {% endfor %} {% else %} requestBuilder.addQueryParam("{{ name }}", "{{ value }}");{% endif %}{% endfor %}\n\n + final String kTemplateUrlQueryParam = ''' + {% for name, value in queryParams %} {% for v in value %} + requestBuilder.addQueryParam("{{ name }}", "{{ v }}"); {% endfor %}{% endfor %}\n '''; final String kTemplateRequestHeader = ''' requestBuilder{% for name, value in headers %} diff --git a/lib/codegen/java/okhttp.dart b/lib/codegen/java/okhttp.dart index 020d17c72..31e0e7be0 100644 --- a/lib/codegen/java/okhttp.dart +++ b/lib/codegen/java/okhttp.dart @@ -37,19 +37,15 @@ import okhttp3.MultipartBody;"""; '''; final String kTemplateUrlQuery = ''' - HttpUrl.Builder urlBuilder = HttpUrl.parse("{{url}}").newBuilder(); - {% for name, value in queryParams %}{% if value is not string %} {% for v in value %} urlBuilder.addQueryParameter("{{ name }}", "{{ v }}"); - {% endfor %} - {% else %} urlBuilder.addQueryParameter("{{ name }}", "{{ value }}"); {% endif %}{% endfor %} - - HttpUrl url = urlBuilder.build(); - -'''; + {% for name, value in queryParams %}{% for v in value %} + urlBuilder.addQueryParameter("{{ name }}", "{{ v }}");{% endfor %}{% endfor %} + HttpUrl url = urlBuilder.build(); + '''; String kTemplateRequestBody = ''' - + MediaType mediaType = MediaType.parse("{{contentType}}"); RequestBody body = RequestBody.create({{body}}, mediaType); diff --git a/lib/codegen/java/unirest.dart b/lib/codegen/java/unirest.dart index 23f9b4537..563476770 100644 --- a/lib/codegen/java/unirest.dart +++ b/lib/codegen/java/unirest.dart @@ -27,8 +27,7 @@ public class Main { '''; final String kTemplateRequestCreation = ''' - HttpResponse response = Unirest - .{{method}}(requestURL)\n + HttpResponse response = Unirest.{{method}}(requestURL)\n '''; final String kTemplateRequestHeader = ''' @@ -36,11 +35,9 @@ public class Main { '''; final String kTemplateUrlQueryParam = ''' - {% for name, value in queryParams %} - {% if value is iterable and value is not string %} {% for v in value -%} - .queryString("{{name}}", "{{v}}"){% if not loop.last %} {% endif %} - {% endfor %} {% else %} - .queryString("{{name}}", "{{value}}") {% endif %} {% if not loop.last %}{% endif %} {% endfor %} + {% for name, value in queryParams %}{% for v in value -%} + .queryString("{{name}}", "{{v}}") + {% endfor %}{% endfor %} '''; @@ -58,7 +55,7 @@ public class Main { '''; final String kStringRequestEnd = """ - .asJson(); + .asJson(); System.out.println(response.getStatus()); System.out.println(response.getBody()); } diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index bb8937c17..d08b2daa9 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -15,17 +15,11 @@ import { {% if hasFileInFormData %}fileFromSync, {% endif %}FormData } from 'nod """; - String kTemplateStart = """const url = new URL('{{url}}'); - + String kTemplateStart = """const url = new URL('{{url}}'); {% for key, value in params -%} -{% if value is iterable and (value is not string) -%} {% for item in value -%} url.searchParams.append('{{key}}', '{{item}}'); {% endfor -%} -{% else -%} - -url.searchParams.append('{{key}}', '{{value}}'); -{% endif -%} {% endfor -%} const options = { method: '{{method}}' diff --git a/lib/codegen/julia/http.dart b/lib/codegen/julia/http.dart index c453346c4..60224964c 100644 --- a/lib/codegen/julia/http.dart +++ b/lib/codegen/julia/http.dart @@ -16,9 +16,9 @@ url = "{{url}}" String kTemplateParams = """ params = Dict( {%- for name, value in params %} - "{{ name }}" => {%- if value is iterable and not value is string -%}[ + "{{ name }}" =>[ {%- for v in value -%}"{{ v }}"{%- if not loop.last -%}, {%- endif -%}{%- endfor -%} - ]{%- else -%}"{{ value }}"{%- endif -%}, + ], {%- endfor %} ) \n diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index 610436701..319ca80e3 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -40,15 +40,11 @@ import okhttp3.MediaType.Companion.toMediaType"""; val url = "{{url}}".toHttpUrl().newBuilder() {%- for name, values in params %} - {%- if values is iterable and not values is string %} {%- for value in values %} .addQueryParameter("{{ name }}", "{{ value }}") {%- endfor %} - {%- else %} - .addQueryParameter("{{ name }}", "{{ values }}") - {%- endif %} {%- endfor %} - .build() + .build() """; diff --git a/lib/codegen/php/curl.dart b/lib/codegen/php/curl.dart index 3425a66d4..b7eab3fa3 100644 --- a/lib/codegen/php/curl.dart +++ b/lib/codegen/php/curl.dart @@ -126,12 +126,8 @@ if (params.isNotEmpty) { List paramList = []; params.forEach((key, value) { - if (value is List) { - paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); - } else { - paramList.add("'$key' => '$value'"); - } - }); + paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); + }); result += templateParams.render({ "params": paramList.join(",\n"), diff --git a/lib/codegen/php/guzzle.dart b/lib/codegen/php/guzzle.dart index 72aa3a73c..9a6697bf2 100644 --- a/lib/codegen/php/guzzle.dart +++ b/lib/codegen/php/guzzle.dart @@ -86,12 +86,8 @@ if (params.isNotEmpty) { List paramList = []; params.forEach((key, value) { - if (value is List) { - paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); - } else { - paramList.add("'$key' => '$value'"); - } - }); + paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); + }); result += templateParams.render({ "params": paramList.join(",\n"), diff --git a/lib/codegen/php/http_plug.dart b/lib/codegen/php/http_plug.dart index 98162f472..f6e6d5b73 100644 --- a/lib/codegen/php/http_plug.dart +++ b/lib/codegen/php/http_plug.dart @@ -97,12 +97,8 @@ echo \$response->getBody(); List paramList = []; params.forEach((key, value) { - if (value is List) { - paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); - } else { - paramList.add("'$key' => '$value'"); - } - }); + paramList.add("'$key' => [${value.map((v) => "'$v'").join(", ")}]"); + }); result += templateParams.render({ "params": paramList.join(",\n"), diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 58867a2c6..9240e670a 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -108,12 +108,8 @@ body = b'\r\n'.join(dataList) List paramList = []; params.forEach((key, value) { - if (value is List) { - paramList.add("'$key': [${value.map((v) => "'$v'").join(", ")}]"); - } else { - paramList.add("'$key': '$value'"); - } - }); + paramList.add("'$key': [${value.map((v) => "'$v'").join(", ")}]"); + }); result += templateParams.render({ "params": paramList.join(",\n"), diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index 803621677..fd22c7743 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -105,12 +105,8 @@ print('Response Body:', response.text) List paramList = []; params.forEach((key, value) { - if (value is List) { - paramList.add("'$key': [${value.map((v) => "'$v'").join(", ")}]"); - } else { - paramList.add("'$key': '$value'"); - } - }); + paramList.add("'$key': [${value.map((v) => "'$v'").join(", ")}]"); + }); result += templateParams.render({ "params": paramList.join(",\n"), diff --git a/lib/codegen/ruby/net_http.dart b/lib/codegen/ruby/net_http.dart index 93a5f9c76..e58957372 100644 --- a/lib/codegen/ruby/net_http.dart +++ b/lib/codegen/ruby/net_http.dart @@ -10,7 +10,7 @@ url = URI("{{url}}") String kTemplateRequestParams = """ \nparams = { -{% for key, val in params %} "{{ key }}" => {% if val is list %}[{% for v in val %}"{{ v|string }}"{% if not loop.last %}, {% endif %}{% endfor %}]{% else %}"{{ val|string }}"{% endif %}, +{% for key, val in params %} "{{ key }}" => [{% for v in val %}"{{ v|string }}"{% if not loop.last %}, {% endif %}{% endfor %}], {% endfor %}} url.query = URI.encode_www_form(params)\n """; diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index f346cbaae..e9485aa1f 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -20,13 +20,9 @@ String kTemplateParams = """ let query_params = [ {%- for key, values in params %} - {%- if values is iterable and values is not string %} {%- for val in values %} ("{{key}}", "{{val}}"), {%- endfor %} - {%- else %} - ("{{key}}", "{{values}}"), - {%- endif %} {%- endfor %} ]; request = request.query(&query_params).unwrap(); diff --git a/lib/codegen/rust/curl_rust.dart b/lib/codegen/rust/curl_rust.dart index 64dba161b..b612d4b47 100644 --- a/lib/codegen/rust/curl_rust.dart +++ b/lib/codegen/rust/curl_rust.dart @@ -18,7 +18,7 @@ fn main() { {% if params %} let params: Vec<(&str, Vec<&str>)> = vec![ {%- for key, values in params %} - ("{{key}}", vec![{% if values is iterable and values is not string %}{% for val in values %}"{{val}}", {% endfor %}{% else %}"{{values}}"{% endif %}]), + ("{{key}}", vec![{% for val in values %}"{{val}}", {% endfor %}]), {%- endfor %} ]; let query_string: String = params.iter().flat_map(|(key, values)| values.iter().map(move |val| format!("{}={}", key, val))) .collect::>().join("&"); diff --git a/lib/codegen/rust/hyper.dart b/lib/codegen/rust/hyper.dart index 23b918d0c..f88f46689 100644 --- a/lib/codegen/rust/hyper.dart +++ b/lib/codegen/rust/hyper.dart @@ -17,15 +17,12 @@ use url::Url; async fn main() -> Result<(), Box> { let http{% if isHttps %}s{% endif %} = Http{% if isHttps %}s{% endif %}Connector::new(); let client = Client::builder().build::<_, hyper::Body>(http{% if isHttps %}s{% endif %}); - let mut url = Url::parse("{{ baseUrl }}")?;\n + let mut url = Url::parse("{{ baseUrl }}")?; """; final String kTemplateParams = """ - {% for key, values in params %}{% if values is iterable and values is not string %}{% for val in values %}\n url.query_pairs_mut().append_pair("{{ key }}", "{{ val }}");{% endfor %} - {% else %} - url.query_pairs_mut().append_pair("{{ key }}", "{{ values }}"); - {% endif %} - {% endfor %} + {% for key, values in params %}{% for val in values %} + url.query_pairs_mut().append_pair("{{ key }}", "{{ val }}");{% endfor %}{% endfor %} """; final String kTemplateMethod = """ diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart index c51b0fe90..aa260fb38 100644 --- a/lib/codegen/rust/reqwest.dart +++ b/lib/codegen/rust/reqwest.dart @@ -13,13 +13,9 @@ class RustReqwestCodeGen { String kTemplateParamsDef = """ let query_params = [ {%- for key, values in params %} - {%- if values is iterable and values is not string %} {%- for val in values %} ("{{key}}", "{{val}}"), {%- endfor %} - {%- else %} - ("{{key}}", "{{values}}"), - {%- endif %} {%- endfor %} ]; """; diff --git a/lib/codegen/rust/ureq.dart b/lib/codegen/rust/ureq.dart index 990250ec7..9f90214ca 100644 --- a/lib/codegen/rust/ureq.dart +++ b/lib/codegen/rust/ureq.dart @@ -18,13 +18,9 @@ fn main() -> Result<(), ureq::Error> { String kTemplateParams = """ {%- for key, values in params %} - {%- if values is iterable and values is not string %} {%- for val in values %} .query("{{key}}", "{{val}}") {%- endfor %} - {%- else %} - .query("{{key}}", "{{values}}") - {%- endif %} {%- endfor %} """; diff --git a/lib/codegen/swift/alamofire.dart b/lib/codegen/swift/alamofire.dart index b128a7278..8886124f1 100644 --- a/lib/codegen/swift/alamofire.dart +++ b/lib/codegen/swift/alamofire.dart @@ -8,6 +8,15 @@ import Foundation import Alamofire """; + final String kTemplateQueryItems = ''' +var urlComponents = URLComponents(string: "{{baseUrl}}")! +var queryItems = [URLQueryItem]() +{% for param in queryParams %}queryItems.append(URLQueryItem(name: "{{param.name}}", value: "{{param.value}}")) +{% endfor %} +urlComponents.queryItems = queryItems +let url = urlComponents.url! +'''; + final String kTemplateFormData = ''' let multipartFormData = MultipartFormData() {% for param in formData %} {% if param.type == 'text' %}multipartFormData.append(Data("{{param.value}}".utf8), withName: "{{param.name}}") {% elif param.type == 'file' %} @@ -32,8 +41,6 @@ let textData = textString.data(using: .utf8)\n '''; final String kTemplateRequest = """ -let url = "{{url}}" - {% if hasFormData %} AF.upload(multipartFormData: multipartFormData, to: url, method: .{{method}}{% if hasHeaders %}, headers: {{headers}}{% endif %}) {% elif hasBody %} @@ -60,9 +67,37 @@ dispatchMain() try { String result = kTemplateStart; - var rec = - getValidRequestUri(requestModel.url, requestModel.enabledParams); + // Extract base URL and query parameters + var rec = getValidRequestUri(requestModel.url, requestModel.enabledParams); Uri? uri = rec.$1; + if (uri == null) return null; + + // Get base URL without query parameters + String baseUrl = uri.replace(query: '').toString(); + if (baseUrl.endsWith('?')) { + baseUrl = baseUrl.substring(0, baseUrl.length - 1); + } + + // Handle query parameters using URLComponents + var queryParamsList = >[]; + requestModel.enabledParamsMap.forEach((key, values) { + for (var value in values) { + queryParamsList.add({ + 'name': key, + 'value': value, + }); + } + }); + + if (queryParamsList.isNotEmpty) { + var templateQueryItems = jj.Template(kTemplateQueryItems); + result += templateQueryItems.render({ + "baseUrl": baseUrl, + "queryParams": queryParamsList, + }); + } else { + result += 'let url = "$baseUrl"\n'; + } var headers = requestModel.enabledHeadersMap; @@ -105,7 +140,7 @@ dispatchMain() hasBody = true; hasJsonData = true; } - // Handle text data + // Handle text data else if (requestModel.hasTextData) { var templateTextData = jj.Template(kTemplateTextData); result += templateTextData.render({ @@ -131,7 +166,6 @@ dispatchMain() var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "url": uri.toString(), "method": requestModel.method.name.toLowerCase(), "headers": headersString, "hasHeaders": hasHeaders, diff --git a/lib/codegen/swift/urlsession.dart b/lib/codegen/swift/urlsession.dart index 955c3b3d3..a1cc5c3f2 100644 --- a/lib/codegen/swift/urlsession.dart +++ b/lib/codegen/swift/urlsession.dart @@ -114,7 +114,7 @@ semaphore.wait() var params = requestModel.enabledParamsMap.entries.expand((entry) { - var values = entry.value is Iterable ? entry.value : [entry.value]; + var values = entry.value; return values.map((value) { return {'key': entry.key, 'value': value};