From 32d246caded9641c02670ba65da4462a55324664 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Fri, 23 Feb 2024 13:09:40 +0530 Subject: [PATCH 01/91] feat: add codegen for rust(reqwest) --- lib/codegen/codegen.dart | 3 + lib/codegen/rust/reqwest.dart | 220 ++++++++ lib/consts.dart | 3 +- test/codegen/rust_reqwest_codegen_test.dart | 546 ++++++++++++++++++++ 4 files changed, 771 insertions(+), 1 deletion(-) create mode 100644 lib/codegen/rust/reqwest.dart create mode 100644 test/codegen/rust_reqwest_codegen_test.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..0787c157 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -5,6 +5,7 @@ import 'dart/dio.dart'; import 'kotlin/okhttp.dart'; import 'python/http_client.dart'; import 'python/requests.dart'; +import 'rust/reqwest.dart'; import 'js/axios.dart'; import 'js/fetch.dart'; import 'others/har.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.rustReqwest: + return RustReqwestCodeGen().getCode(requestModel, defaultUriScheme); } } } diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart new file mode 100644 index 00000000..d242eb0b --- /dev/null +++ b/lib/codegen/rust/reqwest.dart @@ -0,0 +1,220 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class RustReqwestCodeGen { + final String kTemplateStart = + """fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "{{url}}"; + +"""; + + String kTemplateParams = """ + + let params = {{params}}; + +"""; + int kParamsPadding = 9; + + String kTemplateBody = """ + + let payload = b"{{body}}"; + +"""; + + String kTemplateJson = """ + + let payload = serde_json::json!({{body}}); + +"""; + + String kTemplateHeaders = """ + + let header_str = r#"{{headers}}"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + +"""; + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + int kHeadersPadding = 10; + + String kTemplateRequest = """ + + let response = client.{{method}}(url) +"""; + + final String kStringFormDataBody = r''' + #[derive(serde::Deserialize)] + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + let data_str = r#"{{fields_list}}"#; + let form_data_items: Vec = serde_json::from_str(data_str).unwrap(); + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } +'''; + + String kStringRequestParams = """\n .query(¶ms)"""; + + String kStringRequestBody = """\n .body(payload.to_vec())"""; + + String kStringRequestJson = """\n .json(&payload)"""; + + String kStringRequestForm = """\n .multipart(form)"""; + + String kStringRequestHeaders = """\n .headers(headers)"""; + + final String kStringRequestEnd = """\n .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasQuery = false; + bool hasHeaders = false; + bool hasBody = false; + bool hasJsonBody = false; + String uuid = getNewUuid(); + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.isFormDataRequest, + 'isJson': requestModel.requestBodyContentType == ContentType.json + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var tupleStrings = params.entries + .map((entry) => '("${entry.key}", "${entry.value}")') + .toList(); + var paramsString = "[${tupleStrings.join(', ')}]"; + var templateParams = jj.Template(kTemplateParams); + paramsString = padMultilineString(paramsString, kParamsPadding); + result += templateParams.render({"params": paramsString}); + } + } + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else if (!requestModel.isFormDataRequest) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.isFormDataRequest) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } + if (headers.isNotEmpty || hasBody) { + hasHeaders = true; + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + var headersString = kEncoder.convert(headers); + headersString = padMultilineString(headersString, kHeadersPadding); + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headersString}); + } + } + if (requestModel.isFormDataRequest) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": json.encode(requestModel.formDataMapList), + "boundary": uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method.name.toLowerCase(), + }); + + if (hasQuery) { + result += kStringRequestParams; + } + + if (hasBody && !requestModel.isFormDataRequest) { + result += kStringRequestBody; + } + + if (hasJsonBody) { + result += kStringRequestJson; + } + + if (requestModel.isFormDataRequest) { + result += kStringRequestForm; + } + + if (hasHeaders || requestModel.isFormDataRequest) { + result += kStringRequestHeaders; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index f8f9f97c..8094480c 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -268,7 +268,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + rustReqwest("Rust (reqwest)", "rust", "rs"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; diff --git a/test/codegen/rust_reqwest_codegen_test.dart b/test/codegen/rust_reqwest_codegen_test.dart new file mode 100644 index 00000000..7814791a --- /dev/null +++ b/test/codegen/rust_reqwest_codegen_test.dart @@ -0,0 +1,546 @@ +import 'package:apidash/codegen/rust/reqwest.dart'; +import '../request_models.dart'; +import 'package:test/test.dart'; + +void main() { + final rustReqwestCodeGen = RustReqwestCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com"; + + let response = client.get(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet1, "https"), expectedCode); + }); + + test('GET 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/country/data"; + + let params = [("code", "US")]; + + let response = client.get(url) + .query(¶ms) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet2, "https"), expectedCode); + }); + + test('GET 3', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/country/data"; + + let params = [("code", "IND")]; + + let response = client.get(url) + .query(¶ms) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet3, "https"), expectedCode); + }); + + test('GET 4', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; + + let params = [("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]; + + let response = client.get(url) + .query(¶ms) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet4, "https"), expectedCode); + }); + + test('GET 5', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; + + let header_str = r#"{ + "User-Agent": "Test Agent" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.get(url) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet5, "https"), expectedCode); + }); + + test('GET 6', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; + + let params = [("raw", "true")]; + + let header_str = r#"{ + "User-Agent": "Test Agent" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.get(url) + .query(¶ms) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet6, "https"), expectedCode); + }); + + test('GET 7', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com"; + + let response = client.get(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet7, "https"), expectedCode); + }); + + test('GET 8', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; + + let params = [("raw", "true")]; + + let header_str = r#"{ + "User-Agent": "Test Agent" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.get(url) + .query(¶ms) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet8, "https"), expectedCode); + }); + + test('GET 9', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; + + let params = [("num", "8700000"), ("add_space", "true")]; + + let response = client.get(url) + .query(¶ms) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet9, "https"), expectedCode); + }); + + test('GET 10', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; + + let header_str = r#"{ + "User-Agent": "Test Agent" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.get(url) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode( + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; + + let params = [("num", "8700000"), ("digits", "3")]; + + let header_str = r#"{ + "User-Agent": "Test Agent" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.get(url) + .query(¶ms) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet11, "https"), expectedCode); + }); + + test('GET 12', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; + + let response = client.get(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelGet12, "https"), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com"; + + let response = client.head(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelHead1, "https"), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "http://api.foss42.com"; + + let response = client.head(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelHead2, "http"), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/case/lower"; + + let payload = b"{ +"text": "I LOVE Flutter" +}"; + + let header_str = r#"{ + "content-type": "text/plain" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.post(url) + .body(payload.to_vec()) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelPost1, "https"), expectedCode); + }); + + test('POST 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/case/lower"; + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let response = client.post(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelPost2, "https"), expectedCode); + }); + + test('POST 3', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/case/lower"; + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let header_str = r#"{ + "User-Agent": "Test Agent" + }"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str + let mut headers = reqwest::header::HeaderMap::new(); + for (key, val) in headers_map { + headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); + } + + let response = client.post(url) + .json(&payload) + .headers(headers) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelPost3, "https"), expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let payload = serde_json::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let response = client.put(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + rustReqwestCodeGen.getCode(requestModelPut1, "https"), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = client.patch(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect(rustReqwestCodeGen.getCode(requestModelPatch1, "https"), + expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let response = client.delete(url) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect(rustReqwestCodeGen.getCode(requestModelDelete1, "https"), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = client.delete(url) + .json(&payload) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect(rustReqwestCodeGen.getCode(requestModelDelete2, "https"), + expectedCode); + }); + }); +} From 693b4bda70449d411d8debc50906ce487f7170d9 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Fri, 23 Feb 2024 13:50:29 +0530 Subject: [PATCH 02/91] fix: remove redundant body payload from codegen --- lib/codegen/python/http_client.dart | 4 +++- lib/codegen/python/requests.dart | 2 +- lib/utils/har_utils.dart | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 4406effb..196b10df 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -130,7 +130,9 @@ body = b'\r\n'.join(dataList) var method = requestModel.method; var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { + if (kMethodsWithBody.contains(method) && + requestBody != null && + !requestModel.isFormDataRequest) { var contentLength = utf8.encode(requestBody).length; if (contentLength > 0) { hasBody = true; diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index 3a5beeb6..cd79ccde 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -140,7 +140,7 @@ print('Response Body:', response.text) hasJsonBody = true; var templateBody = jj.Template(kTemplateJson); result += templateBody.render({"body": requestBody}); - } else { + } else if (!requestModel.isFormDataRequest) { hasBody = true; var templateBody = jj.Template(kTemplateBody); result += templateBody.render({"body": requestBody}); diff --git a/lib/utils/har_utils.dart b/lib/utils/har_utils.dart index 38913c6e..b5e1de72 100644 --- a/lib/utils/har_utils.dart +++ b/lib/utils/har_utils.dart @@ -112,7 +112,9 @@ Map requestModelToHARJsonRequest( var method = requestModel.method; var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { + if (kMethodsWithBody.contains(method) && + requestBody != null && + !requestModel.isFormDataRequest) { var contentLength = utf8.encode(requestBody).length; if (contentLength > 0) { hasBody = true; From bff2ca892dbaeb39df4147f21893aded4f70a1b0 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Fri, 23 Feb 2024 19:19:32 +0530 Subject: [PATCH 03/91] fix: redundant dart(http) codegen --- lib/codegen/dart/http.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/codegen/dart/http.dart b/lib/codegen/dart/http.dart index 3e423743..42c44ecb 100644 --- a/lib/codegen/dart/http.dart +++ b/lib/codegen/dart/http.dart @@ -53,7 +53,9 @@ class DartHttpCodeGen { declareVar('uri').assign(refer('Uri.parse').call([literalString(url)])); Expression? dataExp; - if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) { + if (kMethodsWithBody.contains(method) && + (body?.isNotEmpty ?? false) && + contentType != ContentType.formdata) { final strContent = CodeExpression(Code('r\'\'\'$body\'\'\'')); dataExp = declareVar('body', type: refer('String')).assign(strContent); if (!hasContentTypeHeader) { From a105b085862fcadcf304df461775482a3811d3b3 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Fri, 23 Feb 2024 21:08:51 +0530 Subject: [PATCH 04/91] fix: remove redundant multipart header - reqwest crate will add the headers and boundary itself. --- lib/codegen/rust/reqwest.dart | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart index d242eb0b..6406fba8 100644 --- a/lib/codegen/rust/reqwest.dart +++ b/lib/codegen/rust/reqwest.dart @@ -43,8 +43,6 @@ class RustReqwestCodeGen { } """; - String kTemplateFormHeaderContentType = ''' -multipart/form-data; boundary={{boundary}}'''; int kHeadersPadding = 10; @@ -157,13 +155,6 @@ multipart/form-data; boundary={{boundary}}'''; var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, - }); - } if (headers.isNotEmpty || hasBody) { hasHeaders = true; if (hasBody) { @@ -181,7 +172,6 @@ multipart/form-data; boundary={{boundary}}'''; result += formDataBodyData.render( { "fields_list": json.encode(requestModel.formDataMapList), - "boundary": uuid, }, ); } @@ -206,7 +196,7 @@ multipart/form-data; boundary={{boundary}}'''; result += kStringRequestForm; } - if (hasHeaders || requestModel.isFormDataRequest) { + if (hasHeaders) { result += kStringRequestHeaders; } From c341218391ce55b755a36a49b77b714aef44cd5b Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sat, 24 Feb 2024 01:19:09 +0530 Subject: [PATCH 05/91] feat: add codegen for rust(actix) --- lib/codegen/codegen.dart | 3 + lib/codegen/rust/actix.dart | 244 ++++++++++++++++++++++++++++++++++++ lib/consts.dart | 1 + 3 files changed, 248 insertions(+) create mode 100644 lib/codegen/rust/actix.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..976b1c3c 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -7,6 +7,7 @@ import 'python/http_client.dart'; import 'python/requests.dart'; import 'js/axios.dart'; import 'js/fetch.dart'; +import 'rust/actix.dart'; import 'others/har.dart'; import 'others/curl.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.rustActix: + return RustActixCodeGen().getCode(requestModel, defaultUriScheme); } } } diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart new file mode 100644 index 00000000..191ed7eb --- /dev/null +++ b/lib/codegen/rust/actix.dart @@ -0,0 +1,244 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class RustActixCodeGen { + final String kTemplateStart = + """{% if isFormDataRequest %}use std::io::Read;{% endif %} +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "{{url}}"; + let mut client = awc::Client::default().{{method}}(url); + +"""; + + String kTemplateParams = """ + + let params = {{params}}; + +"""; + int kParamsPadding = 9; + + String kTemplateBody = """ + + let payload = "{{body}}"; + +"""; + + String kTemplateJson = """ + + let payload = serde_json::json!({{body}}); + +"""; + + String kTemplateHeaders = """ + + let header_str = r#"{{headers}}"#; + let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; + for (key, val) in headers_map { + client = client.insert_header((key, val)); + } + +"""; + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + int kHeadersPadding = 10; + + String kTemplateRequest = """ + + let mut response = client +"""; + + final String kStringFormDataBody = r''' + #[derive(serde::Deserialize)] + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + let data_str = r#"{{fields_list}}"#; + let form_data_items: Vec = serde_json::from_str(data_str).unwrap(); + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--{{boundary}}\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice( + format!( + "Content-Disposition: form-data; name=\"{}\"\r\n", + field.name + ) + .as_bytes(), + ); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice( + format!( + "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", + field.name, field.value + ) + .as_bytes(), + ); + + let mime_type = mime_guess::from_path(&field.value) + .first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list + .extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--{{boundary}}--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); +'''; + + String kStringRequestParams = """\n .query(¶ms)\n .unwrap() + """; + + String kStringRequestBody = """\n .send_body(payload)"""; + + String kStringRequestJson = """\n .send_json(&payload)"""; + + final String kStringRequestEnd = """\n .await\n .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasQuery = false; + bool hasBody = false; + bool hasJsonBody = false; + String uuid = getNewUuid(); + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.isFormDataRequest, + "method": requestModel.method.name.toLowerCase() + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var tupleStrings = params.entries + .map((entry) => '("${entry.key}", "${entry.value}")') + .toList(); + var paramsString = "[${tupleStrings.join(', ')}]"; + var templateParams = jj.Template(kTemplateParams); + paramsString = padMultilineString(paramsString, kParamsPadding); + result += templateParams.render({"params": paramsString}); + } + } + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else if (!requestModel.isFormDataRequest) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.isFormDataRequest) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } + if (headers.isNotEmpty || hasBody) { + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + var headersString = kEncoder.convert(headers); + headersString = padMultilineString(headersString, kHeadersPadding); + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headersString}); + } + } + if (requestModel.isFormDataRequest) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": json.encode(requestModel.formDataMapList), + "boundary": uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method.name.toLowerCase(), + }); + + if (hasQuery) { + result += kStringRequestParams; + } + + if (hasBody || requestModel.isFormDataRequest) { + result += kStringRequestBody; + } + + if (hasJsonBody) { + result += kStringRequestJson; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index f8f9f97c..d67ec213 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -267,6 +267,7 @@ enum CodegenLanguage { nodejsAxios("node.js (axios)", "javascript", "js"), nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), + rustActix("Rust (Actix Client)", "rust", "rs"), pythonHttpClient("Python (http.client)", "python", "py"), pythonRequests("Python (requests)", "python", "py"); From 0623f6e02b1b167842fa199b2f8599b1227538a7 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sat, 24 Feb 2024 06:16:19 +0530 Subject: [PATCH 06/91] codegen(actix): use some jinja magic to reduce the generated code --- lib/codegen/rust/actix.dart | 148 ++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 82 deletions(-) diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index 191ed7eb..7e0cd9a8 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/consts.dart'; import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; + show getNewUuid, getValidRequestUri, stripUriParams; import 'package:apidash/models/models.dart' show RequestModel; class RustActixCodeGen { @@ -12,7 +12,7 @@ class RustActixCodeGen { #[actix_rt::main] async fn main() -> Result<(), Box> { let url = "{{url}}"; - let mut client = awc::Client::default().{{method}}(url); + let client = awc::Client::default(); """; @@ -35,15 +35,6 @@ async fn main() -> Result<(), Box> { """; - String kTemplateHeaders = """ - - let header_str = r#"{{headers}}"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; - for (key, val) in headers_map { - client = client.insert_header((key, val)); - } - -"""; String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; @@ -51,18 +42,27 @@ multipart/form-data; boundary={{boundary}}'''; String kTemplateRequest = """ - let mut response = client + let mut response = client\n .{{method}}(url) """; - final String kStringFormDataBody = r''' - #[derive(serde::Deserialize)] + final String kStringFormDataBody = r""" + struct FormDataItem { name: String, value: String, field_type: String, } - let data_str = r#"{{fields_list}}"#; - let form_data_items: Vec = serde_json::from_str(data_str).unwrap(); + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; + fn build_data_list(fields: Vec) -> Vec { let mut data_list = Vec::new(); @@ -70,29 +70,15 @@ multipart/form-data; boundary={{boundary}}'''; data_list.extend_from_slice(b"--{{boundary}}\r\n"); if field.field_type == "text" { - data_list.extend_from_slice( - format!( - "Content-Disposition: form-data; name=\"{}\"\r\n", - field.name - ) - .as_bytes(), - ); + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); data_list.extend_from_slice(field.value.as_bytes()); data_list.extend_from_slice(b"\r\n"); } else if field.field_type == "file" { - data_list.extend_from_slice( - format!( - "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", - field.name, field.value - ) - .as_bytes(), - ); + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); - let mime_type = mime_guess::from_path(&field.value) - .first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); - data_list - .extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); let mut file = std::fs::File::open(&field.value).unwrap(); let mut file_contents = Vec::new(); @@ -107,16 +93,21 @@ multipart/form-data; boundary={{boundary}}'''; } let payload = build_data_list(form_data_items); -'''; +"""; - String kStringRequestParams = """\n .query(¶ms)\n .unwrap() - """; + String kTemplateRequestParams = + """\n .query(&{{ params }})\n .unwrap()"""; - String kStringRequestBody = """\n .send_body(payload)"""; + String kStringRequestBody = """\n .send_body(payload)"""; - String kStringRequestJson = """\n .send_json(&payload)"""; + String kStringRequestJson = """\n .send_json(&payload)"""; - final String kStringRequestEnd = """\n .await\n .unwrap(); + String kStringRequestNormal = """\n .send()"""; + + String kTemplateRequestHeaders = + """\n {% for key, val in headers %}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{% endfor %}"""; + + final String kStringRequestEnd = """\n .await\n .unwrap(); let body_bytes = response.body().await.unwrap(); let body = std::str::from_utf8(&body_bytes).unwrap(); @@ -133,7 +124,6 @@ multipart/form-data; boundary={{boundary}}'''; ) { try { String result = ""; - bool hasQuery = false; bool hasBody = false; bool hasJsonBody = false; String uuid = getNewUuid(); @@ -156,20 +146,6 @@ multipart/form-data; boundary={{boundary}}'''; "method": requestModel.method.name.toLowerCase() }); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - hasQuery = true; - var tupleStrings = params.entries - .map((entry) => '("${entry.key}", "${entry.value}")') - .toList(); - var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParams = jj.Template(kTemplateParams); - paramsString = padMultilineString(paramsString, kParamsPadding); - result += templateParams.render({"params": paramsString}); - } - } - var method = requestModel.method; var requestBody = requestModel.requestBody; if (kMethodsWithBody.contains(method) && requestBody != null) { @@ -187,32 +163,11 @@ multipart/form-data; boundary={{boundary}}'''; } } - var headersList = requestModel.enabledRequestHeaders; - if (headersList != null || hasBody) { - var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, - }); - } - if (headers.isNotEmpty || hasBody) { - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); - var templateHeaders = jj.Template(kTemplateHeaders); - result += templateHeaders.render({"headers": headersString}); - } - } if (requestModel.isFormDataRequest) { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { - "fields_list": json.encode(requestModel.formDataMapList), + "fields_list": requestModel.formDataMapList, "boundary": uuid, }, ); @@ -222,16 +177,45 @@ multipart/form-data; boundary={{boundary}}'''; "method": method.name.toLowerCase(), }); - if (hasQuery) { - result += kStringRequestParams; + 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(kTemplateRequestParams); + result += templateParms.render({"params": paramsString}); + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + } + if (requestModel.isFormDataRequest) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } + + var templateHeaders = jj.Template(kTemplateRequestHeaders); + result += templateHeaders.render({"headers": headers}); } if (hasBody || requestModel.isFormDataRequest) { result += kStringRequestBody; - } - - if (hasJsonBody) { + } else if (hasJsonBody) { result += kStringRequestJson; + } else { + result += kStringRequestNormal; } result += kStringRequestEnd; From e722b67d7d3c41f8411db781bf6238c644268dd1 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sat, 24 Feb 2024 10:09:31 +0530 Subject: [PATCH 07/91] codegen(actix): some formatting fixes --- lib/codegen/rust/actix.dart | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index 7e0cd9a8..be560c53 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -7,8 +7,10 @@ import 'package:apidash/utils/utils.dart' import 'package:apidash/models/models.dart' show RequestModel; class RustActixCodeGen { - final String kTemplateStart = - """{% if isFormDataRequest %}use std::io::Read;{% endif %} + final String kTemplateStart = """ +{%- if isFormDataRequest -%} +use std::io::Read; +{% endif -%} #[actix_rt::main] async fn main() -> Result<(), Box> { let url = "{{url}}"; @@ -105,7 +107,7 @@ multipart/form-data; boundary={{boundary}}'''; String kStringRequestNormal = """\n .send()"""; String kTemplateRequestHeaders = - """\n {% for key, val in headers %}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{% endfor %}"""; + """\n {% for key, val in headers -%}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; final String kStringRequestEnd = """\n .await\n .unwrap(); @@ -192,12 +194,6 @@ multipart/form-data; boundary={{boundary}}'''; var headersList = requestModel.enabledRequestHeaders; if (headersList != null) { var headers = requestModel.enabledHeadersMap; - if (headers.isNotEmpty) { - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - } if (requestModel.isFormDataRequest) { var formHeaderTemplate = jj.Template(kTemplateFormHeaderContentType); @@ -206,8 +202,15 @@ multipart/form-data; boundary={{boundary}}'''; }); } - var templateHeaders = jj.Template(kTemplateRequestHeaders); - result += templateHeaders.render({"headers": headers}); + if (headers.isNotEmpty) { + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + + var templateHeaders = jj.Template(kTemplateRequestHeaders); + result += templateHeaders.render({"headers": headers}); + } } if (hasBody || requestModel.isFormDataRequest) { From 456cea6f5f30b93d0a9a00d2b53a03851f242b22 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sat, 24 Feb 2024 10:38:40 +0530 Subject: [PATCH 08/91] codegen(reqwest): replace header generation from string map --- lib/codegen/rust/reqwest.dart | 157 ++++++++++++++-------------------- 1 file changed, 66 insertions(+), 91 deletions(-) diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart index 6406fba8..9c93f697 100644 --- a/lib/codegen/rust/reqwest.dart +++ b/lib/codegen/rust/reqwest.dart @@ -3,91 +3,80 @@ import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/consts.dart'; import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; + show getValidRequestUri, stripUriParams; import 'package:apidash/models/models.dart' show RequestModel; class RustReqwestCodeGen { final String kTemplateStart = """fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "{{url}}"; + let client = reqwest::blocking::Client::new(); + let url = "{{url}}"; """; - String kTemplateParams = """ - - let params = {{params}}; - -"""; - int kParamsPadding = 9; + String kTemplateParams = """\n .query(&{{params}})"""; String kTemplateBody = """ - let payload = b"{{body}}"; + let payload = b"{{body}}"; """; String kTemplateJson = """ - let payload = serde_json::json!({{body}}); + let payload = serde_json::json!({{body}}); """; - String kTemplateHeaders = """ - - let header_str = r#"{{headers}}"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } - -"""; - - int kHeadersPadding = 10; + String kTemplateHeaders = + """\n {% for key, val in headers -%}.header("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; String kTemplateRequest = """ - let response = client.{{method}}(url) + let response = client\n .{{method}}(url) """; final String kStringFormDataBody = r''' - #[derive(serde::Deserialize)] - struct FormDataItem { - name: String, - value: String, - field_type: String, - } - let data_str = r#"{{fields_list}}"#; - let form_data_items: Vec = serde_json::from_str(data_str).unwrap(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; - let mut form = reqwest::blocking::multipart::Form::new(); - - for item in form_data_items { - if item.field_type == "text" { - form = form.text(item.name, item.value); - } else if item.field_type == "file" { - form = form.file(item.name, &item.value)?; - } - } + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } '''; - String kStringRequestParams = """\n .query(¶ms)"""; + String kStringRequestBody = """\n .body(payload.to_vec())"""; - String kStringRequestBody = """\n .body(payload.to_vec())"""; + String kStringRequestJson = """\n .json(&payload)"""; - String kStringRequestJson = """\n .json(&payload)"""; + String kStringRequestForm = """\n .multipart(form)"""; - String kStringRequestForm = """\n .multipart(form)"""; + final String kStringRequestEnd = """\n .send()?; - String kStringRequestHeaders = """\n .headers(headers)"""; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - final String kStringRequestEnd = """\n .send()?; - - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; @@ -97,11 +86,8 @@ class RustReqwestCodeGen { ) { try { String result = ""; - bool hasQuery = false; - bool hasHeaders = false; bool hasBody = false; bool hasJsonBody = false; - String uuid = getNewUuid(); String url = requestModel.url; if (!url.contains("://") && url.isNotEmpty) { @@ -121,20 +107,6 @@ class RustReqwestCodeGen { 'isJson': requestModel.requestBodyContentType == ContentType.json }); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - hasQuery = true; - var tupleStrings = params.entries - .map((entry) => '("${entry.key}", "${entry.value}")') - .toList(); - var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParams = jj.Template(kTemplateParams); - paramsString = padMultilineString(paramsString, kParamsPadding); - result += templateParams.render({"params": paramsString}); - } - } - var method = requestModel.method; var requestBody = requestModel.requestBody; if (kMethodsWithBody.contains(method) && requestBody != null) { @@ -152,26 +124,11 @@ class RustReqwestCodeGen { } } - var headersList = requestModel.enabledRequestHeaders; - if (headersList != null || hasBody) { - var headers = requestModel.enabledHeadersMap; - if (headers.isNotEmpty || hasBody) { - hasHeaders = true; - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); - var templateHeaders = jj.Template(kTemplateHeaders); - result += templateHeaders.render({"headers": headersString}); - } - } if (requestModel.isFormDataRequest) { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { - "fields_list": json.encode(requestModel.formDataMapList), + "fields_list": requestModel.formDataMapList, }, ); } @@ -180,8 +137,30 @@ class RustReqwestCodeGen { "method": method.name.toLowerCase(), }); - if (hasQuery) { - result += kStringRequestParams; + 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}); + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headers}); + } } if (hasBody && !requestModel.isFormDataRequest) { @@ -196,10 +175,6 @@ class RustReqwestCodeGen { result += kStringRequestForm; } - if (hasHeaders) { - result += kStringRequestHeaders; - } - result += kStringRequestEnd; } return result; From 838cd5f1cc18ba09f32d18fb7fc8d9280ed8cd2b Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sat, 24 Feb 2024 10:46:21 +0530 Subject: [PATCH 09/91] codegen(reqwest): fix tests --- test/codegen/rust_reqwest_codegen_test.dart | 443 +++++++++----------- 1 file changed, 193 insertions(+), 250 deletions(-) diff --git a/test/codegen/rust_reqwest_codegen_test.dart b/test/codegen/rust_reqwest_codegen_test.dart index 7814791a..2030d6ac 100644 --- a/test/codegen/rust_reqwest_codegen_test.dart +++ b/test/codegen/rust_reqwest_codegen_test.dart @@ -9,16 +9,17 @@ void main() { test('GET 1', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com"; - let response = client.get(url) - .send()?; + let response = client + .get(url) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -28,19 +29,18 @@ void main() { test('GET 2', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/country/data"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/country/data"; - let params = [("code", "US")]; + let response = client + .get(url) + .query(&[("code", "US")]) + .send()?; - let response = client.get(url) - .query(¶ms) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -50,19 +50,18 @@ void main() { test('GET 3', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/country/data"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/country/data"; - let params = [("code", "IND")]; + let response = client + .get(url) + .query(&[("code", "IND")]) + .send()?; - let response = client.get(url) - .query(¶ms) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -72,19 +71,18 @@ void main() { test('GET 4', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/humanize/social"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; - let params = [("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]; + let response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]) + .send()?; - let response = client.get(url) - .query(¶ms) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -94,26 +92,18 @@ void main() { test('GET 5', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.github.com/repos/foss42/apidash"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; - let header_str = r#"{ - "User-Agent": "Test Agent" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + let response = client + .get(url) + .header("User-Agent", "Test Agent") + .send()?; - let response = client.get(url) - .headers(headers) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -123,29 +113,19 @@ void main() { test('GET 6', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.github.com/repos/foss42/apidash"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; - let params = [("raw", "true")]; + let response = client + .get(url) + .query(&[("raw", "true")]) + .header("User-Agent", "Test Agent") + .send()?; - let header_str = r#"{ - "User-Agent": "Test Agent" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - let response = client.get(url) - .query(¶ms) - .headers(headers) - .send()?; - - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -155,16 +135,17 @@ void main() { test('GET 7', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com"; - let response = client.get(url) - .send()?; + let response = client + .get(url) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -174,29 +155,19 @@ void main() { test('GET 8', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.github.com/repos/foss42/apidash"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.github.com/repos/foss42/apidash"; - let params = [("raw", "true")]; + let response = client + .get(url) + .query(&[("raw", "true")]) + .header("User-Agent", "Test Agent") + .send()?; - let header_str = r#"{ - "User-Agent": "Test Agent" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - let response = client.get(url) - .query(¶ms) - .headers(headers) - .send()?; - - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -206,19 +177,18 @@ void main() { test('GET 9', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/humanize/social"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; - let params = [("num", "8700000"), ("add_space", "true")]; + let response = client + .get(url) + .query(&[("num", "8700000"), ("add_space", "true")]) + .send()?; - let response = client.get(url) - .query(¶ms) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -228,26 +198,18 @@ void main() { test('GET 10', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/humanize/social"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; - let header_str = r#"{ - "User-Agent": "Test Agent" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + let response = client + .get(url) + .header("User-Agent", "Test Agent") + .send()?; - let response = client.get(url) - .headers(headers) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -261,29 +223,19 @@ void main() { test('GET 11', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/humanize/social"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; - let params = [("num", "8700000"), ("digits", "3")]; + let response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3")]) + .header("User-Agent", "Test Agent") + .send()?; - let header_str = r#"{ - "User-Agent": "Test Agent" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - let response = client.get(url) - .query(¶ms) - .headers(headers) - .send()?; - - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -293,16 +245,17 @@ void main() { test('GET 12', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/humanize/social"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/humanize/social"; - let response = client.get(url) - .send()?; + let response = client + .get(url) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -314,16 +267,17 @@ void main() { test('HEAD 1', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com"; - let response = client.head(url) - .send()?; + let response = client + .head(url) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -333,16 +287,17 @@ void main() { test('HEAD 2', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "http://api.foss42.com"; + let client = reqwest::blocking::Client::new(); + let url = "http://api.foss42.com"; - let response = client.head(url) - .send()?; + let response = client + .head(url) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -354,31 +309,22 @@ void main() { test('POST 1', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/case/lower"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/case/lower"; - let payload = b"{ + let payload = b"{ "text": "I LOVE Flutter" }"; - let header_str = r#"{ - "content-type": "text/plain" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + let response = client + .post(url) + .body(payload.to_vec()) + .send()?; - let response = client.post(url) - .body(payload.to_vec()) - .headers(headers) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -388,21 +334,22 @@ void main() { test('POST 2', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/case/lower"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/case/lower"; - let payload = serde_json::json!({ + let payload = serde_json::json!({ "text": "I LOVE Flutter" }); - let response = client.post(url) - .json(&payload) - .send()?; + let response = client + .post(url) + .json(&payload) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -412,31 +359,23 @@ void main() { test('POST 3', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://api.foss42.com/case/lower"; + let client = reqwest::blocking::Client::new(); + let url = "https://api.foss42.com/case/lower"; - let payload = serde_json::json!({ + let payload = serde_json::json!({ "text": "I LOVE Flutter" }); - let header_str = r#"{ - "User-Agent": "Test Agent" - }"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; // Deserialize as &str - let mut headers = reqwest::header::HeaderMap::new(); - for (key, val) in headers_map { - headers.insert(key, reqwest::header::HeaderValue::from_str(val)?); - } + let response = client + .post(url) + .header("User-Agent", "Test Agent") + .json(&payload) + .send()?; - let response = client.post(url) - .json(&payload) - .headers(headers) - .send()?; + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); - - Ok(()) + Ok(()) } """; expect( @@ -448,22 +387,23 @@ void main() { test('PUT 1', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://reqres.in/api/users/2"; + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; - let payload = serde_json::json!({ + let payload = serde_json::json!({ "name": "morpheus", "job": "zion resident" }); - let response = client.put(url) - .json(&payload) - .send()?; + let response = client + .put(url) + .json(&payload) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect( @@ -475,22 +415,23 @@ void main() { test('PATCH 1', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://reqres.in/api/users/2"; + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; - let payload = serde_json::json!({ + let payload = serde_json::json!({ "name": "marfeus", "job": "accountant" }); - let response = client.patch(url) - .json(&payload) - .send()?; + let response = client + .patch(url) + .json(&payload) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect(rustReqwestCodeGen.getCode(requestModelPatch1, "https"), @@ -502,16 +443,17 @@ void main() { test('DELETE 1', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://reqres.in/api/users/2"; + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; - let response = client.delete(url) - .send()?; + let response = client + .delete(url) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect(rustReqwestCodeGen.getCode(requestModelDelete1, "https"), @@ -521,22 +463,23 @@ void main() { test('DELETE 2', () { const expectedCode = r"""fn main() -> Result<(), Box> { - let client = reqwest::blocking::Client::new(); - let url = "https://reqres.in/api/users/2"; + let client = reqwest::blocking::Client::new(); + let url = "https://reqres.in/api/users/2"; - let payload = serde_json::json!({ + let payload = serde_json::json!({ "name": "marfeus", "job": "accountant" }); - let response = client.delete(url) - .json(&payload) - .send()?; + let response = client + .delete(url) + .json(&payload) + .send()?; - println!("Status Code: {}", response.status()); - println!("Response Body: {}", response.text()?); + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); - Ok(()) + Ok(()) } """; expect(rustReqwestCodeGen.getCode(requestModelDelete2, "https"), From ac7950efe7f301e848e424ac11aaa8e10545ea26 Mon Sep 17 00:00:00 2001 From: PCoder23 Date: Sat, 24 Feb 2024 11:02:05 +0530 Subject: [PATCH 10/91] Added codegen for java htttpclient with test cases --- lib/codegen/codegen.dart | 3 + lib/codegen/java/httpclient.dart | 181 ++++ lib/consts.dart | 4 +- .../java_http_client_codegen_test.dart | 800 ++++++++++++++++++ 4 files changed, 987 insertions(+), 1 deletion(-) create mode 100644 lib/codegen/java/httpclient.dart create mode 100644 test/codegen/java_http_client_codegen_test.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..7276ed29 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -9,6 +9,7 @@ import 'js/axios.dart'; import 'js/fetch.dart'; import 'others/har.dart'; import 'others/curl.dart'; +import 'java/httpclient.dart'; class Codegen { String? getCode( @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.javaHttpClient: + return JavaHttpClientCodeGen().getCode(requestModel, defaultUriScheme); } } } diff --git a/lib/codegen/java/httpclient.dart b/lib/codegen/java/httpclient.dart new file mode 100644 index 00000000..d57c73f3 --- /dev/null +++ b/lib/codegen/java/httpclient.dart @@ -0,0 +1,181 @@ + +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' show getValidRequestUri, requestModelToHARJsonRequest, stripUriParams; +import '../../models/request_model.dart'; +import 'package:apidash/consts.dart'; + +class JavaHttpClientCodeGen { + final String kTemplateStart = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); +"""; + final String kTemplateUrl = ''' + + String url = "{{url}}"; + +'''; + + final String kTemplateUrlQuery = ''' + + String url = "{{url}}"; + try { + URI uri = new URI(url); + url = uri.resolve("{{params}}").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + +'''; + + String kTemplateRequestBody = ''' + + String body = "{{body}}"; + +'''; + + final String kStringRequestStart = """ + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) +"""; + + final String kTemplateRequestEnd = """ + .{{method}}({{body}}) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} +\n +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasQuery = false; + bool hasBody = false; + bool hasJsonBody = false; + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + + if (uri != null) { + String url = stripUriParams(uri); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var templateParams = jj.Template(kTemplateUrlQuery); + result += templateParams.render({"url": url, "params": uri.query}); + } + } + + if(!hasQuery) { + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + } + var rM = requestModel.copyWith(url: url); + + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (requestModel.isFormDataRequest && requestModel.formDataMapList.isNotEmpty && kMethodsWithBody.contains(method)) { + var formDataList = requestModel.formDataMapList; + result += """ + StringBuilder formData = new StringBuilder(); + formData.append("""; + + for (var formDataMap in formDataList) { + result += '"""${formDataMap['name']}=${formDataMap['value']}&""",'; + } + + result = result.substring(0, result.length - 1); + result += ");\n"; + hasBody = true; + } else if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + var templateBody = jj.Template(kTemplateRequestBody);hasBody = true; + hasJsonBody = requestBody.startsWith("{") && requestBody.endsWith("}"); + if (harJson["postData"]?["text"] != null) { + result += templateBody + .render({"body": kEncoder.convert(harJson["postData"]["text"]).substring(1, kEncoder.convert(harJson["postData"]["text"]).length - 1)}); + } + } + } + + result = kTemplateStart + result; + result += kStringRequestStart; + + var headersList = requestModel.enabledRequestHeaders; + var contentType = requestModel.requestBodyContentType.header; + if(hasBody && !requestModel.enabledHeadersMap.containsKey('Content-Type')){ + result = """$result .header("Content-Type", "$contentType")\n"""; + } + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + result += getHeaders(headers,hasJsonBody); + } + } + + var templateRequestEnd = jj.Template(kTemplateRequestEnd); + + if(kMethodsWithBody.contains(method)){ + result += templateRequestEnd.render({ + "method": method.name.toUpperCase(), + "body": hasBody ? "BodyPublishers.ofString(body)" : "BodyPublishers.noBody()" + }); + } else { + result += templateRequestEnd.render({ + "method": method.name.toUpperCase(), + "body": "" + }); + } + } + return result; + } catch (e) { + return null; + } + } + + String getHeaders(Map headers,hasJsonBody) { + String result = ""; + for (final k in headers.keys) { + if(k.toLowerCase() == 'authorization') { + result = """$result .header("$k", "${headers[k]}")\n"""; + } else { + result = """$result .header("$k", "${headers[k]}")\n"""; + } + } + return result; + } +} diff --git a/lib/consts.dart b/lib/consts.dart index f8f9f97c..5c460043 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -268,7 +268,9 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + javaHttpClient("Java (HttpClient)", "java", "java") + ; const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; diff --git a/test/codegen/java_http_client_codegen_test.dart b/test/codegen/java_http_client_codegen_test.dart new file mode 100644 index 00000000..83b71d2f --- /dev/null +++ b/test/codegen/java_http_client_codegen_test.dart @@ -0,0 +1,800 @@ +import 'package:test/test.dart'; +import 'package:apidash/codegen/java/httpclient.dart'; +import '../request_models.dart'; + +void main() { + final javaHttpClientCodeGen = JavaHttpClientCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet1, "https"), expectedCode); + }); + + test('GET 2', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/country/data"; + try { + URI uri = new URI(url); + url = uri.resolve("code=US").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet2, "https"), expectedCode); + }); + + test('GET 3', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/country/data"; + try { + URI uri = new URI(url); + url = uri.resolve("code=IND").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet3, "https"), expectedCode); + }); + + test('GET 4', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/humanize/social"; + try { + URI uri = new URI(url); + url = uri.resolve("num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet4, "https"), expectedCode); + }); + + test('GET 5', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.github.com/repos/foss42/apidash"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", "Test Agent") + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet5, "https"), expectedCode); + }); + + test('GET 6', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.github.com/repos/foss42/apidash"; + try { + URI uri = new URI(url); + url = uri.resolve("raw=true").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", "Test Agent") + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet6, "https"), expectedCode); + }); + + test('GET 7', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet7, "https"), expectedCode); + }); + + test('GET 8', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.github.com/repos/foss42/apidash"; + try { + URI uri = new URI(url); + url = uri.resolve("raw=true").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", "Test Agent") + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet8, "https"), expectedCode); + }); + + test('GET 9', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/humanize/social"; + try { + URI uri = new URI(url); + url = uri.resolve("num=8700000&add_space=true").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet9, "https"), expectedCode); + }); + + test('GET 10', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/humanize/social"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", "Test Agent") + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet10, "https"), expectedCode); + }); + + test('GET 11', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/humanize/social"; + try { + URI uri = new URI(url); + url = uri.resolve("num=8700000&digits=3").toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", "Test Agent") + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet11, "https"), expectedCode); + }); + + test('GET 12', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/humanize/social"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelGet12, "https"), expectedCode); + }); + + test('HEAD 1', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .HEAD() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelHead1, "https"), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .HEAD() + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelHead2, "https"), expectedCode); + }); +}); + +group('POST Request', () { + test('POST 1', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/case/lower"; + + String body = "{\\n\\"text\\": \\"I LOVE Flutter\\"\\n}"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-Type", "text/plain") + .POST(BodyPublishers.ofString(body)) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelPost1, "https"), expectedCode); + }); + + test('POST 2', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/case/lower"; + + String body = "{\\n\\"text\\": \\"I LOVE Flutter\\"\\n}"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-Type", "application/json") + .POST(BodyPublishers.ofString(body)) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelPost2, "https"), expectedCode); + }); + + test('POST 3', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://api.foss42.com/case/lower"; + + String body = "{\\n\\"text\\": \\"I LOVE Flutter\\"\\n}"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-Type", "application/json") + .header("User-Agent", "Test Agent") + .POST(BodyPublishers.ofString(body)) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelPost3, "https"), expectedCode); + }); +}); + +group('PUT Request', () { + test('PUT 1', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://reqres.in/api/users/2"; + + String body = "{\\n\\"name\\": \\"morpheus\\",\\n\\"job\\": \\"zion resident\\"\\n}"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-Type", "application/json") + .PUT(BodyPublishers.ofString(body)) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelPut1, "https"), expectedCode); + }); +}); + +group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://reqres.in/api/users/2"; + + String body = "{\\n\\"name\\": \\"marfeus\\",\\n\\"job\\": \\"accountant\\"\\n}"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-Type", "application/json") + .PATCH(BodyPublishers.ofString(body)) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + }); +}); + +group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://reqres.in/api/users/2"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .DELETE(BodyPublishers.noBody()) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = """ +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; + +public class JavaHttpClientExample { + + public static void main(String[] args) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + String url = "https://reqres.in/api/users/2"; + + String body = "{\\n\\"name\\": \\"marfeus\\",\\n\\"job\\": \\"accountant\\"\\n}"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("Content-Type", "application/json") + .DELETE(BodyPublishers.ofString(body)) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + System.out.println(response.statusCode()); + System.out.println(response.body()); + } +} + +"""; + expect(javaHttpClientCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + }); +}); + + + +} \ No newline at end of file From 7e1ca33a28921789f0720542e63b2c520e553fcf Mon Sep 17 00:00:00 2001 From: ch1nru5t Date: Sat, 24 Feb 2024 12:48:53 +0530 Subject: [PATCH 11/91] fixed curl code gen error for empty url --- lib/codegen/others/curl.dart | 65 +++++++++++++++++++---------- pubspec.lock | 40 ++++++++++++++---- test/codegen/curl_codegen_test.dart | 5 ++- 3 files changed, 78 insertions(+), 32 deletions(-) diff --git a/lib/codegen/others/curl.dart b/lib/codegen/others/curl.dart index 4ae610de..638e9da5 100644 --- a/lib/codegen/others/curl.dart +++ b/lib/codegen/others/curl.dart @@ -1,6 +1,7 @@ -import 'package:jinja/jinja.dart' as jj; -import 'package:apidash/utils/utils.dart' show requestModelToHARJsonRequest; import 'package:apidash/models/models.dart' show RequestModel; +import 'package:jinja/jinja.dart' as jj; + +import '../../consts.dart'; // ignore: camel_case_types class cURLCodeGen { @@ -29,30 +30,48 @@ class cURLCodeGen { if (!url.contains("://") && url.isNotEmpty) { url = "$defaultUriScheme://$url"; } + if (requestModel.enabledParamsMap.isNotEmpty) { + if (!url.contains('?')) { + url += "?"; + } else { + url += "&"; + } + for (MapEntry entry + in requestModel.enabledParamsMap.entries) { + url += "${Uri.encodeFull(entry.key)}=${Uri.encodeFull(entry.value)}&"; + } + url = url.substring(0, url.length - 1); + } var rM = requestModel.copyWith(url: url); - - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); - var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "method": switch (harJson["method"]) { + "method": switch (rM.method.name.toUpperCase()) { "GET" => "", "HEAD" => " --head", - _ => " --request ${harJson["method"]} \\\n" + _ => " --request ${rM.method.name.toUpperCase()} \\\n" }, - "url": harJson["url"], + "url": rM.url, }); - var headers = harJson["headers"]; - if (headers.isNotEmpty) { - for (var item in headers) { - var templateHeader = jj.Template(kTemplateHeader); - result += templateHeader - .render({"name": item["name"], "value": item["value"]}); - } + Map headers = rM.enabledHeadersMap; + if (rM.requestBody != null && + rM.requestBody!.isNotEmpty && + rM.method != HTTPVerb.get && + rM.requestBodyContentType != ContentType.formdata) { + var templateHeader = jj.Template(kTemplateHeader); + result += templateHeader.render({ + "name": "Content-Type", + "value": rM.requestBodyContentType.header + }); } - if (harJson['formData'] != null) { - var formDataList = harJson['formData'] as List>; + for (MapEntry header in headers.entries) { + var templateHeader = jj.Template(kTemplateHeader); + result += + templateHeader.render({"name": header.key, "value": header.value}); + } + + if (rM.requestBodyContentType == ContentType.formdata) { + List> formDataList = rM.formDataMapList; for (var formData in formDataList) { var templateFormData = jj.Template(kTemplateFormData); if (formData['type'] != null && @@ -67,11 +86,13 @@ class cURLCodeGen { }); } } - } - - if (harJson["postData"]?["text"] != null) { - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": harJson["postData"]["text"]}); + } else { + if (rM.requestBody != null && + rM.requestBody!.isNotEmpty && + rM.method != HTTPVerb.get) { + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": rM.requestBody}); + } } return result; } catch (e) { diff --git a/pubspec.lock b/pubspec.lock index 2f3f7f55..1737f75f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -625,6 +625,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -661,26 +685,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -757,10 +781,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index e9bb7f60..b62de8b4 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -1,7 +1,8 @@ import 'package:apidash/codegen/others/curl.dart'; -import '../request_models.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; + void main() { final curlCodeGen = cURLCodeGen(); @@ -19,7 +20,7 @@ void main() { test('GET 3', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/country/data?code=IND'"""; + r"""curl --url 'https://api.foss42.com/country/data?code=US&code=IND'"""; expect(curlCodeGen.getCode(requestModelGet3, "https"), expectedCode); }); From 50d6b8cd064f0a3f931ae1667749e974442951a7 Mon Sep 17 00:00:00 2001 From: Levan Mebonia Date: Sat, 24 Feb 2024 16:19:54 +0100 Subject: [PATCH 12/91] julia_http_codegen_levo-777 --- lib/codegen/julia/http.dart | 215 +++++++++++ pubspec.lock | 40 ++- test/codegen/julia_http_codegen_test.dart | 415 ++++++++++++++++++++++ 3 files changed, 662 insertions(+), 8 deletions(-) create mode 100644 lib/codegen/julia/http.dart create mode 100644 test/codegen/julia_http_codegen_test.dart diff --git a/lib/codegen/julia/http.dart b/lib/codegen/julia/http.dart new file mode 100644 index 00000000..afb6015d --- /dev/null +++ b/lib/codegen/julia/http.dart @@ -0,0 +1,215 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class JuliaHttpClientCodeGen { + final String kTemplateStart = """using HTTP,JSON +{% if isFormDataRequest %}using Base:MIME +{% endif %} +url = "{{url}}" + +"""; + + String kTemplateParams = """ +{% set new_params = params | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +params = Dict{{new_params}} +"""; + + int kParamsPadding = 9; + + String kTemplateBody = ''' +{% set new_params = body | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +payload = Dict{{new_params}} +'''; + + String kTemplateJson = """ +{% set new_params = body | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +payload = Dict{{new_params}} +"""; + + String kTemplateHeaders = """ +{% set new_params = headers | replace(":", "=>") | replace("{", "(") | replace("}", ")") %} + +headers = Dict{{new_params}} +"""; + + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + int kHeadersPadding = 10; + + String kTemplateRequest = """ + + +response = HTTP.{{method}}(url +"""; + + final String kStringFormDataBody = r''' +function build_data_list(fields) + dataList = [] + for field in fields + name = field["name"] + value = field["value"] + type_ = get(field, "type", "text") + + push!(dataList, b"--{{boundary}}") + if type_ == "text" + push!(dataList, b"Content-Disposition: form-data; name=\"$name\"") + push!(dataList, b"Content-Type: text/plain") + push!(dataList, b"") + push!(dataList, codeunits(value)) + elseif type_ == "file" + push!(dataList, b"Content-Disposition: form-data; name=\"$name\"; filename=\"$value\"") + push!(dataList, b"Content-Type: $value") + push!(dataList, b"") + push!(dataList, String(read(value))) + end + end + push!(dataList, "--{{boundary}}--") + push!(dataList, b"") + return dataList +end + +dataList = build_data_list({{fields_list}}) +payload = join(dataList, b"\r\n") +'''; + + String kStringRequestParams = """, query=params"""; + + String kStringRequestBody = """, payload=payload"""; + + String kStringRequestJson = """, JSON.json(payload)"""; + + String kStringRequestHeaders = """, headers=headers"""; + + final String kStringRequestEnd = """ +) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasQuery = false; + bool hasHeaders = false; + bool hasBody = false; + bool hasJsonBody = false; + String uuid = getNewUuid(); + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.isFormDataRequest + }); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var templateParams = jj.Template(kTemplateParams); + var paramsString = kEncoder.convert(params); + paramsString = padMultilineString(paramsString, kParamsPadding); + result += templateParams.render({"params": paramsString}); + } + } + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.isFormDataRequest) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } + if (headers.isNotEmpty || hasBody) { + hasHeaders = true; + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + var headersString = kEncoder.convert(headers); + headersString = padMultilineString(headersString, kHeadersPadding); + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headersString}); + } + } + if (requestModel.isFormDataRequest) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": json.encode(requestModel.formDataMapList), + "boundary": uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "method": method.name.toLowerCase(), + }); + + if (hasQuery) { + result += kStringRequestParams; + } + + if (hasBody || requestModel.isFormDataRequest) { + result += kStringRequestBody; + } + + if (hasJsonBody || requestModel.isFormDataRequest) { + result += kStringRequestJson; + } + + if (hasHeaders || requestModel.isFormDataRequest) { + result += kStringRequestHeaders; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/pubspec.lock b/pubspec.lock index 2f3f7f55..1737f75f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -625,6 +625,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -661,26 +685,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -757,10 +781,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: diff --git a/test/codegen/julia_http_codegen_test.dart b/test/codegen/julia_http_codegen_test.dart new file mode 100644 index 00000000..eae1f7a5 --- /dev/null +++ b/test/codegen/julia_http_codegen_test.dart @@ -0,0 +1,415 @@ +import 'package:apidash/codegen/julia/http.dart'; +import '../request_models.dart'; +import 'package:test/test.dart'; + +void main() { + final juliaHttpClientCodeGen = JuliaHttpClientCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com" + + +response = HTTP.get(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet1, "https"), + expectedCode); + }); + test('GET 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/country/data" + + +params = Dict( + "code"=> "US" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet2, "https"), + expectedCode); + }); + test('GET 3', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/country/data" + + +params = Dict( + "code"=> "IND" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet3, "https"), + expectedCode); + }); + test('GET 4', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/humanize/social" + + +params = Dict( + "num"=> "8700000", + "digits"=> "3", + "system"=> "SS", + "add_space"=> "true", + "trailing_zeros"=> "true" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet4, "https"), + expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.github.com/repos/foss42/apidash" + + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet5, "https"), + expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.github.com/repos/foss42/apidash" + + +params = Dict( + "raw"=> "true" + ) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, query=params, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet6, "https"), + expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com" + + +response = HTTP.get(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet7, "https"), + expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.github.com/repos/foss42/apidash" + + +params = Dict( + "raw"=> "true" + ) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, query=params, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet8, "https"), + expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/humanize/social" + + +params = Dict( + "num"=> "8700000", + "add_space"=> "true" + ) + +response = HTTP.get(url, query=params) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet9, "https"), + expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/humanize/social" + + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet10, "https"), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/humanize/social" + + +params = Dict( + "num"=> "8700000", + "digits"=> "3" + ) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.get(url, query=params, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet11, "https"), + expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/humanize/social" + + +response = HTTP.get(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelGet12, "https"), + expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com" + + +response = HTTP.head(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelHead1, "https"), + expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com" + + +response = HTTP.head(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelHead2, "https"), + expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/case/lower" + + +payload = Dict( +"text"=> "I LOVE Flutter" +) + +headers = Dict( + "content-type"=> "text/plain" + ) + +response = HTTP.post(url, payload=payload, headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelPost1, "https"), + expectedCode); + }); + + test('POST 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/case/lower" + + +payload = Dict( +"text"=> "I LOVE Flutter" +) + +response = HTTP.post(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelPost2, "https"), + expectedCode); + }); + test('POST 3', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://api.foss42.com/case/lower" + + +payload = Dict( +"text"=> "I LOVE Flutter" +) + +headers = Dict( + "User-Agent"=> "Test Agent" + ) + +response = HTTP.post(url, JSON.json(payload), headers=headers) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelPost3, "https"), + expectedCode); + }); + }); + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +payload = Dict( +"name"=> "morpheus", +"job"=> "zion resident" +) + +response = HTTP.put(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelPut1, "https"), + expectedCode); + }); + }); + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +payload = Dict( +"name"=> "marfeus", +"job"=> "accountant" +) + +response = HTTP.patch(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelPatch1, "https"), + expectedCode); + }); + }); + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +response = HTTP.delete(url) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelDelete1, "https"), + expectedCode); + }); + test('DELETE 2', () { + const expectedCode = r"""using HTTP,JSON + +url = "https://reqres.in/api/users/2" + + +payload = Dict( +"name"=> "marfeus", +"job"=> "accountant" +) + +response = HTTP.delete(url, JSON.json(payload)) + +println("Status Code:", response.status) +println("Response Body:", String(response.body)) +"""; + expect(juliaHttpClientCodeGen.getCode(requestModelDelete2, "https"), + expectedCode); + }); + }); +} From 7e956c81aad1ea9d89269fe5645187d14554a4bc Mon Sep 17 00:00:00 2001 From: Levan Mebonia Date: Sat, 24 Feb 2024 16:25:49 +0100 Subject: [PATCH 13/91] update const.dart CodeGen Julia --- lib/consts.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/consts.dart b/lib/consts.dart index f8f9f97c..69cf30d2 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -268,7 +268,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + juliaHttpRequests("Julia (HTTP)", "julia", "jl"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; From 944d5b180fe43f5d8c2bb0caabf4402d899ecf38 Mon Sep 17 00:00:00 2001 From: Levan Mebonia Date: Sat, 24 Feb 2024 16:31:59 +0100 Subject: [PATCH 14/91] Update codegen.dart --- lib/codegen/codegen.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..8f3fd7da 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,3 +1,4 @@ +import 'package:apidash/codegen/julia/http.dart'; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; import 'dart/http.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.juliaHttpRequests: + return JuliaHttpClientCodeGen().getCode(requestModel, defaultUriScheme); } } } From 895007aa402155ca317558cd3b878a6aefb2fa34 Mon Sep 17 00:00:00 2001 From: Levan Mebonia Date: Sat, 24 Feb 2024 16:46:54 +0100 Subject: [PATCH 15/91] Update http.dart --- lib/codegen/julia/http.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/codegen/julia/http.dart b/lib/codegen/julia/http.dart index afb6015d..250dadc5 100644 --- a/lib/codegen/julia/http.dart +++ b/lib/codegen/julia/http.dart @@ -8,8 +8,8 @@ import 'package:apidash/models/models.dart' show RequestModel; class JuliaHttpClientCodeGen { final String kTemplateStart = """using HTTP,JSON -{% if isFormDataRequest %}using Base:MIME -{% endif %} + + url = "{{url}}" """; From f28666444bddef89f4b75acf0b53cfdd3a5a0d0d Mon Sep 17 00:00:00 2001 From: Levan Mebonia Date: Sat, 24 Feb 2024 23:07:44 +0100 Subject: [PATCH 16/91] Update codegen.dart --- lib/codegen/codegen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 8f3fd7da..9cfed8c2 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,4 +1,3 @@ -import 'package:apidash/codegen/julia/http.dart'; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; import 'dart/http.dart'; @@ -10,6 +9,7 @@ import 'js/axios.dart'; import 'js/fetch.dart'; import 'others/har.dart'; import 'others/curl.dart'; +import 'julia/http.dart'; class Codegen { String? getCode( From 7a6bb125c9955d85269f745ff5f6d8c5433cf5c9 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sun, 25 Feb 2024 05:20:54 +0530 Subject: [PATCH 17/91] codegen(reqwest): small fix for payload and null headerList --- lib/codegen/rust/reqwest.dart | 15 +++++++-------- test/codegen/rust_reqwest_codegen_test.dart | 7 ++++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/codegen/rust/reqwest.dart b/lib/codegen/rust/reqwest.dart index 9c93f697..645d1fcf 100644 --- a/lib/codegen/rust/reqwest.dart +++ b/lib/codegen/rust/reqwest.dart @@ -18,7 +18,7 @@ class RustReqwestCodeGen { String kTemplateBody = """ - let payload = b"{{body}}"; + let payload = r#"{{body}}"#; """; @@ -65,7 +65,7 @@ class RustReqwestCodeGen { } '''; - String kStringRequestBody = """\n .body(payload.to_vec())"""; + String kStringRequestBody = """\n .body(payload)"""; String kStringRequestJson = """\n .json(&payload)"""; @@ -150,14 +150,13 @@ class RustReqwestCodeGen { } var headersList = requestModel.enabledRequestHeaders; - if (headersList != null) { + if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } if (headers.isNotEmpty) { - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headers}); } diff --git a/test/codegen/rust_reqwest_codegen_test.dart b/test/codegen/rust_reqwest_codegen_test.dart index 2030d6ac..8cdb4078 100644 --- a/test/codegen/rust_reqwest_codegen_test.dart +++ b/test/codegen/rust_reqwest_codegen_test.dart @@ -312,13 +312,14 @@ void main() { let client = reqwest::blocking::Client::new(); let url = "https://api.foss42.com/case/lower"; - let payload = b"{ + let payload = r#"{ "text": "I LOVE Flutter" -}"; +}"#; let response = client .post(url) - .body(payload.to_vec()) + .header("content-type", "text/plain") + .body(payload) .send()?; println!("Status Code: {}", response.status()); From cdda439f0f4ab5a81d5dcaea75474f1ea86d28ca Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sun, 25 Feb 2024 04:51:56 +0530 Subject: [PATCH 18/91] feat: add codegen for rust(ureq) --- lib/codegen/codegen.dart | 3 + lib/codegen/rust/ureq.dart | 214 +++++++++++++++++++++++++++++++++++++ lib/consts.dart | 3 +- 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 lib/codegen/rust/ureq.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..2fb2f7ba 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,3 +1,4 @@ +import 'package:apidash/codegen/rust/ureq.dart'; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; import 'dart/http.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.rustUreq: + return RustUreqCodeGen().getCode(requestModel, defaultUriScheme); } } } diff --git a/lib/codegen/rust/ureq.dart b/lib/codegen/rust/ureq.dart new file mode 100644 index 00000000..3be8971c --- /dev/null +++ b/lib/codegen/rust/ureq.dart @@ -0,0 +1,214 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' + show getNewUuid, getValidRequestUri, stripUriParams; +import 'package:apidash/models/models.dart' show RequestModel; + +class RustUreqCodeGen { + final String kTemplateStart = """ +{%- if isFormDataRequest -%} +use std::io::Read; +{% endif -%} +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 kTemplateBody = """ + + let payload = r#"{{body}}"#; + +"""; + + String kTemplateJson = """ + + let payload = ureq::json!({{body}}); + +"""; + + String kTemplateHeaders = + """\n {% for key, val in headers -%}.set("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + + String kTemplateFormHeaderContentType = ''' +multipart/form-data; boundary={{boundary}}'''; + + String kTemplateRequest = """ + + let response = ureq::{{method}}(url) +"""; + + final String kStringFormDataBody = r""" + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--{{boundary}}\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--{{boundary}}--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); +"""; + + String kStringRequestBody = """\n .send_string(payload)?;"""; + + String kStringRequestForm = """\n .send_bytes(&payload)?;"""; + + String kStringRequestJson = """\n .send_json(payload)?;"""; + + String kStringRequestNormal = """\n .call()?;"""; + + final String kStringRequestEnd = """\n + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasBody = false; + bool hasJsonBody = false; + String uuid = getNewUuid(); + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + if (uri != null) { + var templateStartUrl = jj.Template(kTemplateStart); + result += templateStartUrl.render({ + "url": stripUriParams(uri), + 'isFormDataRequest': requestModel.isFormDataRequest, + "method": requestModel.method.name.toLowerCase() + }); + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + if (requestModel.requestBodyContentType == ContentType.json) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestBody}); + } else if (!requestModel.isFormDataRequest) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestBody}); + } + } + } + + if (requestModel.isFormDataRequest) { + var formDataBodyData = jj.Template(kStringFormDataBody); + result += formDataBodyData.render( + { + "fields_list": requestModel.formDataMapList, + "boundary": uuid, + }, + ); + } + var templateRequest = jj.Template(kTemplateRequest); + result += templateRequest.render({ + "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 headersList = requestModel.enabledRequestHeaders; + if (headersList != null || hasBody || requestModel.isFormDataRequest) { + var headers = requestModel.enabledHeadersMap; + if (requestModel.isFormDataRequest) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } else if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + + if (headers.isNotEmpty) { + var templateHeaders = jj.Template(kTemplateHeaders); + result += templateHeaders.render({"headers": headers}); + } + } + if (requestModel.isFormDataRequest) { + result += kStringRequestForm; + } else if (hasBody) { + result += kStringRequestBody; + } else if (hasJsonBody) { + result += kStringRequestJson; + } else { + result += kStringRequestNormal; + } + + result += kStringRequestEnd; + } + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index f8f9f97c..58e482ab 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -268,7 +268,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + rustUreq("Rust (ureq)", "rust", "rs"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; From 7389545030b7bcdb659fd8088df4590de6c061c0 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sun, 25 Feb 2024 05:51:07 +0530 Subject: [PATCH 19/91] codegen(ureq): add tests --- test/codegen/rust_ureq_codegen_test.dart | 389 +++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 test/codegen/rust_ureq_codegen_test.dart diff --git a/test/codegen/rust_ureq_codegen_test.dart b/test/codegen/rust_ureq_codegen_test.dart new file mode 100644 index 00000000..95b7f44b --- /dev/null +++ b/test/codegen/rust_ureq_codegen_test.dart @@ -0,0 +1,389 @@ +import 'package:apidash/codegen/rust/ureq.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final rustUreqCodeGen = RustUreqCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com"; + let response = ureq::get(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet1, "https"), expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/country/data"; + let response = ureq::get(url) + .query("code", "US") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet2, "https"), expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/country/data"; + let response = ureq::get(url) + .query("code", "IND") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet3, "https"), expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/humanize/social"; + let response = ureq::get(url) + .query("num", "8700000") + .query("digits", "3") + .query("system", "SS") + .query("add_space", "true") + .query("trailing_zeros", "true") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet4, "https"), expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.github.com/repos/foss42/apidash"; + let response = ureq::get(url) + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet5, "https"), expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.github.com/repos/foss42/apidash"; + let response = ureq::get(url) + .query("raw", "true") + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet6, "https"), expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com"; + let response = ureq::get(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet7, "https"), expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.github.com/repos/foss42/apidash"; + let response = ureq::get(url) + .query("raw", "true") + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet8, "https"), expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/humanize/social"; + let response = ureq::get(url) + .query("num", "8700000") + .query("add_space", "true") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet9, "https"), expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/humanize/social"; + let response = ureq::get(url) + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + rustUreqCodeGen.getCode( + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/humanize/social"; + let response = ureq::get(url) + .query("num", "8700000") + .query("digits", "3") + .set("User-Agent", "Test Agent") + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet11, "https"), expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/humanize/social"; + let response = ureq::get(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelGet12, "https"), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com"; + let response = ureq::head(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelHead1, "https"), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "http://api.foss42.com"; + let response = ureq::head(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect(rustUreqCodeGen.getCode(requestModelHead2, "http"), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/case/lower"; + let payload = r#"{ +"text": "I LOVE Flutter" +}"#; + + let response = ureq::post(url) + .set("content-type", "text/plain") + .send_string(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect(rustUreqCodeGen.getCode(requestModelPost1, "https"), expectedCode); + }); + + test('POST 2', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/case/lower"; + let payload = ureq::json!({ +"text": "I LOVE Flutter" +}); + + let response = ureq::post(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect(rustUreqCodeGen.getCode(requestModelPost2, "https"), expectedCode); + }); + + test('POST 3', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://api.foss42.com/case/lower"; + let payload = ureq::json!({ +"text": "I LOVE Flutter" +}); + + let response = ureq::post(url) + .set("User-Agent", "Test Agent") + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect(rustUreqCodeGen.getCode(requestModelPost3, "https"), expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let payload = ureq::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let response = ureq::put(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect(rustUreqCodeGen.getCode(requestModelPut1, "https"), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let payload = ureq::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = ureq::patch(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + rustUreqCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let response = ureq::delete(url) + .call()?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + rustUreqCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r'''fn main() -> Result<(), ureq::Error> { + let url = "https://reqres.in/api/users/2"; + let payload = ureq::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let response = ureq::delete(url) + .send_json(payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +'''; + expect( + rustUreqCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + }); + }); +} From b5fb769a894ba6e6f4df1b23f34c10801cf65cd7 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Sat, 24 Feb 2024 10:09:52 +0530 Subject: [PATCH 20/91] codegen(actix): add tests --- lib/codegen/rust/actix.dart | 35 +- test/codegen/rust_actix_codegen_test.dart | 564 ++++++++++++++++++++++ 2 files changed, 576 insertions(+), 23 deletions(-) create mode 100644 test/codegen/rust_actix_codegen_test.dart diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index be560c53..a1d581e6 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -18,16 +18,12 @@ async fn main() -> Result<(), Box> { """; - String kTemplateParams = """ - - let params = {{params}}; - -"""; - int kParamsPadding = 9; + String kTemplateParams = + """\n .query(&{{ params }})\n .unwrap()"""; String kTemplateBody = """ - let payload = "{{body}}"; + let payload = r#"{{body}}"#; """; @@ -37,11 +33,12 @@ async fn main() -> Result<(), Box> { """; + String kTemplateHeaders = + """\n {% for key, val in headers -%}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; - int kHeadersPadding = 10; - String kTemplateRequest = """ let mut response = client\n .{{method}}(url) @@ -97,18 +94,12 @@ multipart/form-data; boundary={{boundary}}'''; let payload = build_data_list(form_data_items); """; - String kTemplateRequestParams = - """\n .query(&{{ params }})\n .unwrap()"""; - String kStringRequestBody = """\n .send_body(payload)"""; String kStringRequestJson = """\n .send_json(&payload)"""; String kStringRequestNormal = """\n .send()"""; - String kTemplateRequestHeaders = - """\n {% for key, val in headers -%}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; - final String kStringRequestEnd = """\n .await\n .unwrap(); let body_bytes = response.body().await.unwrap(); @@ -186,13 +177,13 @@ multipart/form-data; boundary={{boundary}}'''; .map((entry) => '("${entry.key}", "${entry.value}")') .toList(); var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParms = jj.Template(kTemplateRequestParams); + var templateParms = jj.Template(kTemplateParams); result += templateParms.render({"params": paramsString}); } } var headersList = requestModel.enabledRequestHeaders; - if (headersList != null) { + if (headersList != null || hasBody || requestModel.isFormDataRequest) { var headers = requestModel.enabledHeadersMap; if (requestModel.isFormDataRequest) { var formHeaderTemplate = @@ -200,15 +191,13 @@ multipart/form-data; boundary={{boundary}}'''; headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ "boundary": uuid, }); + } else if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; } if (headers.isNotEmpty) { - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - - var templateHeaders = jj.Template(kTemplateRequestHeaders); + var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headers}); } } diff --git a/test/codegen/rust_actix_codegen_test.dart b/test/codegen/rust_actix_codegen_test.dart new file mode 100644 index 00000000..567f64b6 --- /dev/null +++ b/test/codegen/rust_actix_codegen_test.dart @@ -0,0 +1,564 @@ +import 'package:apidash/codegen/rust/actix.dart'; +import '../request_models.dart'; +import 'package:test/test.dart'; + +void main() { + final rustActixCodeGen = RustActixCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet1, "https"), expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/country/data"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("code", "US")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet2, "https"), expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/country/data"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("code", "IND")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet3, "https"), expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet4, "https"), expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet5, "https"), expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("raw", "true")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet6, "https"), expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet7, "https"), expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("raw", "true")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet8, "https"), expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("add_space", "true")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet9, "https"), expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode( + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelGet11, "https"), expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelGet12, "https"), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .head(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelHead1, "https"), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "http://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .head(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelHead2, "http"), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/case/lower"; + let client = awc::Client::default(); + + let payload = r#"{ +"text": "I LOVE Flutter" +}"#; + + let mut response = client + .post(url) + .insert_header(("content-type", "text/plain")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPost1, "https"), expectedCode); + }); + + test('POST 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/case/lower"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let mut response = client + .post(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPost2, "https"), expectedCode); + }); + + test('POST 3', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/case/lower"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let mut response = client + .post(url) + .insert_header(("User-Agent", "Test Agent")) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPost3, "https"), expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let mut response = client + .put(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelPut1, "https"), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let mut response = client + .patch(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let mut response = client + .delete(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let mut response = client + .delete(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + }); + }); +} From 3cf677e89bfa8040187ad9db8cba6a7c6796c30a Mon Sep 17 00:00:00 2001 From: Elise Date: Sun, 25 Feb 2024 21:17:19 -0800 Subject: [PATCH 21/91] Fix Kotlin codegen to import MultipartBody --- lib/codegen/kotlin/okhttp.dart | 11 ++++++-- test/codegen/kotlin_okhttp_codegen_test.dart | 27 ++++++++++++++++++++ test/request_models.dart | 14 +++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index 07e5a92b..bd8f0489 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -7,7 +7,7 @@ import 'package:apidash/consts.dart'; class KotlinOkHttpCodeGen { final String kTemplateStart = """import okhttp3.OkHttpClient -import okhttp3.Request{{importForQuery}}{{importForBody}} +import okhttp3.Request{{importForQuery}}{{importForBody}}{{importForFormData}} fun main() { val client = OkHttpClient() @@ -23,6 +23,10 @@ import okhttp3.HttpUrl.Companion.toHttpUrl"""; import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.MediaType.Companion.toMediaType"""; + final String kStringImportForFormData = """ + +import okhttp3.MultipartBody"""; + final String kTemplateUrl = ''' val url = "{{url}}" @@ -77,6 +81,7 @@ import okhttp3.MediaType.Companion.toMediaType"""; String result = ""; bool hasQuery = false; bool hasBody = false; + bool hasFormData = false; String url = requestModel.url; if (!url.contains("://") && url.isNotEmpty) { @@ -109,6 +114,7 @@ import okhttp3.MediaType.Companion.toMediaType"""; var method = requestModel.method; var requestBody = requestModel.requestBody; if (requestModel.isFormDataRequest) { + hasFormData = true; var formDataTemplate = jj.Template(kFormDataBody); result += formDataTemplate.render({ @@ -128,7 +134,8 @@ import okhttp3.MediaType.Companion.toMediaType"""; var templateStart = jj.Template(kTemplateStart); var stringStart = templateStart.render({ "importForQuery": hasQuery ? kStringImportForQuery : "", - "importForBody": hasBody ? kStringImportForBody : "" + "importForBody": hasBody ? kStringImportForBody : "", + "importForFormData": hasFormData ? kStringImportForFormData : "" }); result = stringStart + result; diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index 4f3220fa..ef8ca190 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -478,6 +478,33 @@ fun main() { expect(kotlinOkHttpCodeGen.getCode(requestModelPost3, "https"), expectedCode); }); + + test('POST 4', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.foss42.com/case/lower" + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("text","I LOVE Flutter") + .build() + val request = Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect(kotlinOkHttpCodeGen.getCode(requestModelPost4, "https"), + expectedCode); + }); }); group('PUT Request', () { diff --git a/test/request_models.dart b/test/request_models.dart index d7f7df21..e19c08a0 100644 --- a/test/request_models.dart +++ b/test/request_models.dart @@ -1,4 +1,4 @@ -import 'package:apidash/models/models.dart' show NameValueModel, RequestModel; +import 'package:apidash/models/models.dart' show NameValueModel, RequestModel, FormDataModel; import 'package:apidash/consts.dart'; /// Basic GET request model @@ -226,6 +226,18 @@ const requestModelPost3 = RequestModel( ], ); +/// POST request model with FormData +const requestModelPost4 = RequestModel( + id: 'post3', + url: 'https://api.foss42.com/case/lower', + method: HTTPVerb.post, + requestFormDataList: [FormDataModel(name: "text", value: "I LOVE Flutter", type: FormDataType.text)], + requestBodyContentType: ContentType.formdata, + requestHeaders: [ + NameValueModel(name: 'User-Agent', value: 'Test Agent'), + ], +); + /// PUT request model const requestModelPut1 = RequestModel( id: 'put1', From 8f66d25de4f7a5cabc19b25bdfd52efab49b1cef Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:42:58 +0530 Subject: [PATCH 22/91] ADD: javaAsyncHttpClient as Codegen Language enum --- lib/consts.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/consts.dart b/lib/consts.dart index d157b7fa..7f090a65 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -271,7 +271,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + javaAsyncHttpClient("Java (async-http-client)", "java", "java"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; From 220d58e6389e6af84b0b593123c4e23a671123a3 Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:43:23 +0530 Subject: [PATCH 23/91] ADD: switch case for generating javaAsyncHttpClient code generation --- lib/codegen/codegen.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..76aed61b 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -5,6 +5,7 @@ import 'dart/dio.dart'; import 'kotlin/okhttp.dart'; import 'python/http_client.dart'; import 'python/requests.dart'; +import 'java/async_http_client.dart'; import 'js/axios.dart'; import 'js/fetch.dart'; import 'others/har.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.javaAsyncHttpClient: + return JavaAsyncHttpClientGen().getCode(requestModel, defaultUriScheme); } } } From c9f90a5d56e98fa2b0728ec53e1dd8e71c168789 Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:46:10 +0530 Subject: [PATCH 24/91] ADD: JavaAsyncHttpClientGen class --- lib/codegen/java/async_http_client.dart | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 lib/codegen/java/async_http_client.dart diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart new file mode 100644 index 00000000..daaa2103 --- /dev/null +++ b/lib/codegen/java/async_http_client.dart @@ -0,0 +1,9 @@ +import 'dart:convert'; +import 'package:apidash/utils/har_utils.dart'; +import 'package:apidash/utils/http_utils.dart'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; + +class JavaAsyncHttpClientGen { +} From c13c788ea9876acb889709b347bab8c9d6b13b5f Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:54:07 +0530 Subject: [PATCH 25/91] ADD: templates for code generation --- lib/codegen/java/async_http_client.dart | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index daaa2103..c6aa368d 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -6,4 +6,72 @@ import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; class JavaAsyncHttpClientGen { + final String kTemplateStart = ''' +import org.asynchttpclient.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +public class Main { + public static void main(String[] args) { + try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { +'''; + + final String kTemplateUrl = ''' + String url = "{{url}}";\n +'''; + + final String kTemplateRequestCreation = ''' + Request request = asyncHttpClient + .prepare("{{method}}", url)\n +'''; + + final String kTemplateUrlQueryParam = ''' + .addQueryParam("{{name}}", "{{value}}")\n +'''; + + final String kTemplateRequestHeader = ''' + .addHeader("{{name}}", "{{value}}")\n +'''; + final String kTemplateRequestFormData = ''' + .addFormParam("{{name}}", "{{value}}")\n +'''; + + String kTemplateRequestBodyContent = ''' + String bodyContent = "{{body}}";\n +'''; + String kTemplateRequestBodySetup = ''' + .setBody(bodyContent)\n +'''; + + final String kTemplateRequestEnd = """ + .build(); + ListenableFuture listenableFuture = asyncHttpClient.executeRequest(request); + listenableFuture.addListener(() -> { + try { + Response response = listenableFuture.get(); + InputStream is = response.getResponseBodyAsStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + String respBody = br.lines().collect(Collectors.joining("\\n")); + System.out.println(response.getStatusCode()); + System.out.println(respBody); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); + listenableFuture.get(); + } catch (InterruptedException | ExecutionException | IOException ignored) { + + } + } +} +\n +"""; + } From b9750ef8b16f061fe0d1357adb72c4c1ae508885 Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:58:14 +0530 Subject: [PATCH 26/91] ADD: getCode function to return the generted code string --- lib/codegen/java/async_http_client.dart | 126 ++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index c6aa368d..f0f688c6 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -74,4 +74,130 @@ public class Main { \n """; + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasBody = false; + bool hasJsonBody = false; + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + + if (uri == null) { + return ""; + } + + url = stripUriParams(uri); + + // contains the HTTP method associated with the request + var method = requestModel.method; + + // contains the entire request body as a string if body is present + var requestBody = requestModel.requestBody; + + // generating the URL to which the request has to be submitted + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + // creating request body if available + var rM = requestModel.copyWith(url: url); + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + + // if request type is not form data, the request method can include + // a body, and the body of the request is not null, in that case + // we need to parse the body as it is, and write it to the body + if (!requestModel.isFormDataRequest && + kMethodsWithBody.contains(method) && + requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + var templateBodyContent = jj.Template(kTemplateRequestBodyContent); + hasBody = true; + + // every JSON should be enclosed within a pair of curly braces + // very simple check for JSON, for stronger check, we may validate + // the JSON in the JSON editor itself + hasJsonBody = + requestBody.startsWith("{") && requestBody.endsWith("}"); + + if (harJson["postData"]?["text"] != null) { + result += templateBodyContent.render({ + "body": kEncoder.convert(harJson["postData"]["text"]).substring( + 1, kEncoder.convert(harJson["postData"]["text"]).length - 1) + }); + } + } + } + + var templateRequestCreation = jj.Template(kTemplateRequestCreation); + result += + templateRequestCreation.render({"method": method.name.toUpperCase()}); + + // setting up query parameters + if (uri.hasQuery) { + var params = uri.queryParameters; + var templateUrlQueryParam = jj.Template(kTemplateUrlQueryParam); + params.forEach((name, value) { + result += + templateUrlQueryParam.render({"name": name, "value": value}); + }); + } + + result = kTemplateStart + result; + + var contentType = requestModel.requestBodyContentType.header; + var templateRequestHeader = jj.Template(kTemplateRequestHeader); + + // especially sets up Content-Type header if the request has a body + // and Content-Type is not explicitely set by the developer + if (hasBody && + !requestModel.enabledHeadersMap.containsKey('Content-Type')) { + result += templateRequestHeader + .render({"name": 'Content-Type', "value": contentType}); + } + + // setting up rest of the request headers + var headers = requestModel.enabledHeadersMap; + headers.forEach((name, value) { + result += templateRequestHeader.render({"name": name, "value": value}); + }); + + // handling form data + if (requestModel.isFormDataRequest && + requestModel.formDataMapList.isNotEmpty && + kMethodsWithBody.contains(method)) { + // including form data into the request + var formDataList = requestModel.formDataMapList; + var templateRequestFormData = jj.Template(kTemplateRequestFormData); + for (var formDataMap in formDataList) { + result += templateRequestFormData.render( + {"name": formDataMap['name'], "value": formDataMap['value']}); + } + hasBody = true; + } + + var templateRequestBodySetup = jj.Template(kTemplateRequestBodySetup); + if (kMethodsWithBody.contains(method) && hasBody) { + result += templateRequestBodySetup.render(); + } + + var templateRequestBodyEnd = jj.Template(kTemplateRequestEnd); + result += templateRequestBodyEnd.render(); + + return result; + } catch (e) { + return null; + } + } } From 827e0d6b3a3f3d4b599d757b5bb303f6911c3d64 Mon Sep 17 00:00:00 2001 From: Aashutosh soni Date: Mon, 4 Mar 2024 15:07:56 +0530 Subject: [PATCH 27/91] added php Guzzle support --- lib/codegen/codegen.dart | 3 + lib/codegen/php/guzzle.dart | 514 ++++++++++++++++++++++++++++++++++++ lib/consts.dart | 1 + 3 files changed, 518 insertions(+) create mode 100644 lib/codegen/php/guzzle.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..aed1074d 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -3,6 +3,7 @@ import 'package:apidash/consts.dart'; import 'dart/http.dart'; import 'dart/dio.dart'; import 'kotlin/okhttp.dart'; +import 'php/guzzle.dart'; import 'python/http_client.dart'; import 'python/requests.dart'; import 'js/axios.dart'; @@ -37,6 +38,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.kotlinOkHttp: return KotlinOkHttpCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.phpGuzzle: + return PhpGuzzleCodeGen().getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonHttpClient: return PythonHttpClientCodeGen() .getCode(requestModel, defaultUriScheme); diff --git a/lib/codegen/php/guzzle.dart b/lib/codegen/php/guzzle.dart new file mode 100644 index 00000000..34ca744a --- /dev/null +++ b/lib/codegen/php/guzzle.dart @@ -0,0 +1,514 @@ +// import 'dart:convert'; +// import 'package:jinja/jinja.dart' as jj; +// import 'package:apidash/utils/utils.dart' +// show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; +// import 'package:apidash/models/models.dart' show RequestModel; +// import 'package:apidash/consts.dart'; + +// class PhpGuzzleCodeGen { +// String kStringImportNode = """use GuzzleHttp\\Client; +// use GuzzleHttp\\Psr7\\Request; +// {% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream;;{% endif %} +// \ + +// """; + +// String kTemplateParams = """ +// \$queryParams = [ +// {{params}} +// ]; + +// \$queryParamsStr = '?' . http_build_query(\$queryParams); +// \ + +// """; + +// String kTemplateHeader = """ +// \$headers = [ +// {{headers}} +// ]; +// \ + +// """; + +// String kTemplateBody = """ +// \$body = {{body}}; +// \ + +// """; + +// String kMultiPartBodyTemplate = r''' +// //body tempalte + +// '''; +// var kGetFormDataTemplate = """ +// \$multipart = [ +// [ +// 'name' => 'formfield1', +// 'contents' => 'formdata1' +// ], +// [ +// 'name' => 'formfield2', +// 'contents' => 'formdata2' +// ], +// [ +// 'name' => 'formfile1', +// 'contents' => fopen('C:\\Users\\Ashut\\Downloads\\8h45la.png', 'r') +// ] +// ]; + +// {{fields_list}}; +// """; + +// String kTemplateStart = """ +// \$client = new Client(); +// \ + +// """; + +// String kStringRequest = """ +// \$request = new Request('{{method}}', '{{url}}' . \$queryParamsStr, \$headers, \$body); + +// \$res = \$client->sendAsync(\$request)->wait(); + +// echo \$res->getBody(); + +// """; + +// String? getCode( +// RequestModel requestModel, +// String defaultUriScheme, +// ) { +// try { +// jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); +// String importsData = kNodejsImportTemplate.render({ +// "isFormDataRequest": requestModel.isFormDataRequest, +// }); + +// String result = importsData; + +// if (requestModel.isFormDataRequest && +// requestModel.formDataMapList.isNotEmpty) { +// var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); +// var renderedMultiPartBody = templateMultiPartBody.render({}); +// result += renderedMultiPartBody; +// } + +// String url = requestModel.url; +// if (!url.contains("://") && url.isNotEmpty) { +// url = "$defaultUriScheme://$url"; +// } +// var rM = requestModel.copyWith(url: url); + +// var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + +// 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 jsonString = ''; +// m.forEach((key, value) { +// jsonString += "\t\t\t\t'$key' => '$value', \n"; +// }); +// jsonString = jsonString.substring( +// 0, jsonString.length - 2); // Removing trailing comma and space +// result += templateParams.render({ +// "params": jsonString, +// }); +// } + +// var headers = harJson["headers"]; +// if (headers.isNotEmpty || requestModel.isFormDataRequest) { +// var templateHeader = jj.Template(kTemplateHeader); +// var m = {}; +// for (var i in headers) { +// m[i["name"]] = i["value"]; +// } +// var headersString = ''; +// m.forEach((key, value) { +// headersString += "\t\t\t\t'$key' => '$value', \n"; +// }); +// headersString = headersString.substring( +// 0, headersString.length - 2); // Removing trailing comma and space +// result += templateHeader.render({ +// "headers": headersString, +// }); +// } + +// var templateBody = jj.Template(kTemplateBody); + +// if (requestModel.isFormDataRequest && +// requestModel.formDataMapList.isNotEmpty) { +// var getFieldDataTemplate = jj.Template(kGetFormDataTemplate); + +// result += templateBody.render({ +// "body": getFieldDataTemplate.render({ +// "fields_list": json.encode(requestModel.formDataMapList), +// }) +// }); +// } +// if (harJson["postData"]?["text"] != null) { +// result += templateBody +// .render({"body": kEncoder.convert(harJson["postData"]["text"])}); +// } +// result += kStringRequest; + +// var templateStart = jj.Template(kTemplateStart); +// result += templateStart.render({ +// // "url": stripUrlParams(url), +// // "method": harJson["method"].toLowerCase(), +// }); + +// var templateRequest = jj.Template(kStringRequest); +// result += templateRequest.render({ +// "url": stripUrlParams(url), +// "method": harJson["method"].toLowerCase(), +// }); + +// return result; +// } catch (e) { +// return null; +// } +// } +// } + +// import 'dart:convert'; +// import 'package:jinja/jinja.dart' as jj; +// import 'package:apidash/utils/utils.dart' +// show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; +// import 'package:apidash/models/models.dart' show RequestModel; +// import 'package:apidash/consts.dart'; + +// class PhpGuzzleCodeGen { +// String kStringImportNode = """use GuzzleHttp\\Client; +// use GuzzleHttp\\Psr7\\Request; +// {% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream; +// use GuzzleHttp\\Psr7\\Utils;{% endif %} +// \ + +// """; + +// String kTemplateParams = """ +// \$queryParams = [ +// {{params}} +// ]; + +// \$queryParamsStr = '?' . http_build_query(\$queryParams); +// \ + +// """; + +// String kTemplateHeader = """ +// \$headers = [ +// {{headers}} +// ]; +// \ + +// """; + +// String kTemplateBody = """ +// \$body = {{body}}; +// \ + +// """; + +// String kMultiPartBodyTemplate = """ +// \$multipart = [ +// {{fields_list}} +// ]; +// """; + +// String kTemplateStart = """ +// \$client = new Client(); +// \ + +// """; + +// String kStringRequest = """ +// \$request = new Request('{{method}}', '{{url}}' . \$queryParamsStr, \$headers, {{body}}); +// \$res = \$client->sendAsync(\$request)->wait(); +// echo \$res->getBody(); +// """; + +// String? getCode( +// RequestModel requestModel, +// String defaultUriScheme, +// ) { +// try { +// jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); +// String importsData = kNodejsImportTemplate.render({ +// "isFormDataRequest": requestModel.isFormDataRequest, +// }); + +// String result = importsData; + +// if (requestModel.isFormDataRequest && +// requestModel.formDataMapList.isNotEmpty) { +// var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); +// var renderedMultiPartBody = templateMultiPartBody.render({ +// "fields_list": requestModel.formDataMapList.map(( +// field, +// ) { +// return ''' +// [ +// 'name' => '${field['name']}', +// 'contents' => '${field['contents']}' +// ], +// '''; +// }).join(), +// }); +// result += renderedMultiPartBody; +// } + +// String url = requestModel.url; +// if (!url.contains("://") && url.isNotEmpty) { +// url = "$defaultUriScheme://$url"; +// } +// var rM = requestModel.copyWith(url: url); + +// var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + +// 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 jsonString = ''; +// m.forEach((key, value) { +// jsonString += "\t\t\t\t'$key' => '$value', \n"; +// }); +// jsonString = jsonString.substring( +// 0, jsonString.length - 2); // Removing trailing comma and space +// result += templateParams.render({ +// "params": jsonString, +// }); +// } + +// var headers = harJson["headers"]; +// if (headers.isNotEmpty || requestModel.isFormDataRequest) { +// var templateHeader = jj.Template(kTemplateHeader); +// var m = {}; +// for (var i in headers) { +// m[i["name"]] = i["value"]; +// } +// var headersString = ''; +// m.forEach((key, value) { +// headersString += "\t\t\t\t'$key' => '$value', \n"; +// }); +// headersString = headersString.substring( +// 0, headersString.length - 2); // Removing trailing comma and space +// result += templateHeader.render({ +// "headers": headersString, +// }); +// } + +// var templateBody = jj.Template(kTemplateBody); + +// if (requestModel.isFormDataRequest && +// requestModel.formDataMapList.isNotEmpty) { +// result += templateBody.render({ +// "body": "new MultipartStream(\$multipart)", +// }); +// } +// if (harJson["postData"]?["text"] != null) { +// result += templateBody +// .render({"body": kEncoder.convert(harJson["postData"]["text"])}); +// } + +// var templateStart = jj.Template(kTemplateStart); +// result += templateStart.render({ +// // "url": stripUrlParams(url), +// // "method": harJson["method"].toLowerCase(), +// }); + +// var templateRequest = jj.Template(kStringRequest); +// result += templateRequest.render({ +// "url": stripUrlParams(url), +// "method": harJson["method"].toLowerCase(), +// }); + +// return result; +// } catch (e) { +// return null; +// } +// } +// } + +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' + show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; +import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; + +class PhpGuzzleCodeGen { + String kStringImportNode = """use GuzzleHttp\\Client; +use GuzzleHttp\\Psr7\\Request; +{% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream;{% endif %} +\ + +"""; + + String kMultiPartBodyTemplate = """ +\$multipart = [ +{{fields_list}} +]; +\ + +"""; + + String kTemplateParams = """ +\$queryParams = [ +{{params}} +]; +\$queryParamsStr = '?' . http_build_query(\$queryParams); +\ + +"""; + + String kTemplateHeader = """ +\$headers = [ +{{headers}} +]; +\ + +"""; + + String kTemplateBody = """ +\$body = {{body}}; +\ + +"""; + + String kStringRequest = """ +\$client = new Client(); +\ +\$request = new Request('{{method}}', '{{url}}'{{queryParams}} {{headers}} {{body}}); +\$res = \$client->sendAsync(\$request)->wait(); +echo \$res->getBody(); +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); + String importsData = kNodejsImportTemplate.render({ + "isFormDataRequest": requestModel.isFormDataRequest, + }); + + String result = importsData; + + if (requestModel.isFormDataRequest && + requestModel.formDataMapList.isNotEmpty) { + var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); + var renderedMultiPartBody = templateMultiPartBody.render({ + "fields_list": requestModel.formDataMapList.map((field) { + return ''' + [ + 'name' => '${field['name']}', + 'contents' => '${field['value']}' + ],'''; + }).join(), + }); + result += renderedMultiPartBody; + } + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + var rM = requestModel.copyWith(url: url); + + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + + 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 jsonString = ''; + m.forEach((key, value) { + jsonString += "\t\t\t\t'$key' => '$value', \n"; + }); + jsonString = jsonString.substring( + 0, jsonString.length - 2); // Removing trailing comma and space + result += templateParams.render({ + "params": jsonString, + }); + } + + var headers = harJson["headers"]; + if (headers.isNotEmpty || requestModel.isFormDataRequest) { + var templateHeader = jj.Template(kTemplateHeader); + var m = {}; + for (var i in headers) { + m[i["name"]] = i["value"]; + } + var headersString = ''; + m.forEach((key, value) { + headersString += "\t\t\t\t'$key' => '$value', \n"; + }); + if (requestModel.isFormDataRequest) { + m['Content-Type'] = 'multipart/form-data'; + } + headersString = headersString.substring( + 0, headersString.length - 2); // Removing trailing comma and space + result += templateHeader.render({ + "headers": headersString, + }); + } + + var templateBody = jj.Template(kTemplateBody); + if (requestModel.isFormDataRequest && + requestModel.formDataMapList.isNotEmpty) { + result += templateBody.render({ + "body": "new MultipartStream(\$multipart)", + }); + } + + if (harJson["postData"]?["text"] != null) { + result += templateBody + .render({"body": kEncoder.convert(harJson["postData"]["text"])}); + } + + //result += kStringRequest; + + String getRequestBody(Map harJson) { + if (harJson.containsKey("postData")) { + var postData = harJson["postData"]; + if (postData.containsKey("mimeType")) { + var mimeType = postData["mimeType"]; + if (mimeType == "text/plain" || mimeType == "application/json") { + return " \$body"; + } else if (mimeType == "multipart/form-data") { + return " new MultipartStream(\$multipart)"; + } + } + } + return ""; // Return empty string if postData is not present or if mimeType is not supported + } + + var templateRequest = jj.Template(kStringRequest); + result += templateRequest.render({ + "url": stripUrlParams(url), + "method": harJson["method"].toLowerCase(), + "queryParams": + harJson["queryString"].isNotEmpty ? " \$queryParamsStr," : "", + "headers": harJson["headers"].isNotEmpty ? " \$headers," : "", + "body": getRequestBody(harJson), + }); + + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index 90096f83..b430794e 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -270,6 +270,7 @@ enum CodegenLanguage { nodejsAxios("node.js (axios)", "javascript", "js"), nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), + phpGuzzle("PHP (guzzle)", "php", "php"), pythonHttpClient("Python (http.client)", "python", "py"), pythonRequests("Python (requests)", "python", "py"); From 5b81f179451df395280b53b45db2f107a169a5ed Mon Sep 17 00:00:00 2001 From: Aashutosh soni Date: Mon, 4 Mar 2024 22:27:03 +0530 Subject: [PATCH 28/91] update: bugfixes --- lib/codegen/php/guzzle.dart | 347 +----------------------------------- 1 file changed, 2 insertions(+), 345 deletions(-) diff --git a/lib/codegen/php/guzzle.dart b/lib/codegen/php/guzzle.dart index 34ca744a..2857c526 100644 --- a/lib/codegen/php/guzzle.dart +++ b/lib/codegen/php/guzzle.dart @@ -1,344 +1,3 @@ -// import 'dart:convert'; -// import 'package:jinja/jinja.dart' as jj; -// import 'package:apidash/utils/utils.dart' -// show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; -// import 'package:apidash/models/models.dart' show RequestModel; -// import 'package:apidash/consts.dart'; - -// class PhpGuzzleCodeGen { -// String kStringImportNode = """use GuzzleHttp\\Client; -// use GuzzleHttp\\Psr7\\Request; -// {% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream;;{% endif %} -// \ - -// """; - -// String kTemplateParams = """ -// \$queryParams = [ -// {{params}} -// ]; - -// \$queryParamsStr = '?' . http_build_query(\$queryParams); -// \ - -// """; - -// String kTemplateHeader = """ -// \$headers = [ -// {{headers}} -// ]; -// \ - -// """; - -// String kTemplateBody = """ -// \$body = {{body}}; -// \ - -// """; - -// String kMultiPartBodyTemplate = r''' -// //body tempalte - -// '''; -// var kGetFormDataTemplate = """ -// \$multipart = [ -// [ -// 'name' => 'formfield1', -// 'contents' => 'formdata1' -// ], -// [ -// 'name' => 'formfield2', -// 'contents' => 'formdata2' -// ], -// [ -// 'name' => 'formfile1', -// 'contents' => fopen('C:\\Users\\Ashut\\Downloads\\8h45la.png', 'r') -// ] -// ]; - -// {{fields_list}}; -// """; - -// String kTemplateStart = """ -// \$client = new Client(); -// \ - -// """; - -// String kStringRequest = """ -// \$request = new Request('{{method}}', '{{url}}' . \$queryParamsStr, \$headers, \$body); - -// \$res = \$client->sendAsync(\$request)->wait(); - -// echo \$res->getBody(); - -// """; - -// String? getCode( -// RequestModel requestModel, -// String defaultUriScheme, -// ) { -// try { -// jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); -// String importsData = kNodejsImportTemplate.render({ -// "isFormDataRequest": requestModel.isFormDataRequest, -// }); - -// String result = importsData; - -// if (requestModel.isFormDataRequest && -// requestModel.formDataMapList.isNotEmpty) { -// var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); -// var renderedMultiPartBody = templateMultiPartBody.render({}); -// result += renderedMultiPartBody; -// } - -// String url = requestModel.url; -// if (!url.contains("://") && url.isNotEmpty) { -// url = "$defaultUriScheme://$url"; -// } -// var rM = requestModel.copyWith(url: url); - -// var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); - -// 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 jsonString = ''; -// m.forEach((key, value) { -// jsonString += "\t\t\t\t'$key' => '$value', \n"; -// }); -// jsonString = jsonString.substring( -// 0, jsonString.length - 2); // Removing trailing comma and space -// result += templateParams.render({ -// "params": jsonString, -// }); -// } - -// var headers = harJson["headers"]; -// if (headers.isNotEmpty || requestModel.isFormDataRequest) { -// var templateHeader = jj.Template(kTemplateHeader); -// var m = {}; -// for (var i in headers) { -// m[i["name"]] = i["value"]; -// } -// var headersString = ''; -// m.forEach((key, value) { -// headersString += "\t\t\t\t'$key' => '$value', \n"; -// }); -// headersString = headersString.substring( -// 0, headersString.length - 2); // Removing trailing comma and space -// result += templateHeader.render({ -// "headers": headersString, -// }); -// } - -// var templateBody = jj.Template(kTemplateBody); - -// if (requestModel.isFormDataRequest && -// requestModel.formDataMapList.isNotEmpty) { -// var getFieldDataTemplate = jj.Template(kGetFormDataTemplate); - -// result += templateBody.render({ -// "body": getFieldDataTemplate.render({ -// "fields_list": json.encode(requestModel.formDataMapList), -// }) -// }); -// } -// if (harJson["postData"]?["text"] != null) { -// result += templateBody -// .render({"body": kEncoder.convert(harJson["postData"]["text"])}); -// } -// result += kStringRequest; - -// var templateStart = jj.Template(kTemplateStart); -// result += templateStart.render({ -// // "url": stripUrlParams(url), -// // "method": harJson["method"].toLowerCase(), -// }); - -// var templateRequest = jj.Template(kStringRequest); -// result += templateRequest.render({ -// "url": stripUrlParams(url), -// "method": harJson["method"].toLowerCase(), -// }); - -// return result; -// } catch (e) { -// return null; -// } -// } -// } - -// import 'dart:convert'; -// import 'package:jinja/jinja.dart' as jj; -// import 'package:apidash/utils/utils.dart' -// show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; -// import 'package:apidash/models/models.dart' show RequestModel; -// import 'package:apidash/consts.dart'; - -// class PhpGuzzleCodeGen { -// String kStringImportNode = """use GuzzleHttp\\Client; -// use GuzzleHttp\\Psr7\\Request; -// {% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream; -// use GuzzleHttp\\Psr7\\Utils;{% endif %} -// \ - -// """; - -// String kTemplateParams = """ -// \$queryParams = [ -// {{params}} -// ]; - -// \$queryParamsStr = '?' . http_build_query(\$queryParams); -// \ - -// """; - -// String kTemplateHeader = """ -// \$headers = [ -// {{headers}} -// ]; -// \ - -// """; - -// String kTemplateBody = """ -// \$body = {{body}}; -// \ - -// """; - -// String kMultiPartBodyTemplate = """ -// \$multipart = [ -// {{fields_list}} -// ]; -// """; - -// String kTemplateStart = """ -// \$client = new Client(); -// \ - -// """; - -// String kStringRequest = """ -// \$request = new Request('{{method}}', '{{url}}' . \$queryParamsStr, \$headers, {{body}}); -// \$res = \$client->sendAsync(\$request)->wait(); -// echo \$res->getBody(); -// """; - -// String? getCode( -// RequestModel requestModel, -// String defaultUriScheme, -// ) { -// try { -// jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); -// String importsData = kNodejsImportTemplate.render({ -// "isFormDataRequest": requestModel.isFormDataRequest, -// }); - -// String result = importsData; - -// if (requestModel.isFormDataRequest && -// requestModel.formDataMapList.isNotEmpty) { -// var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); -// var renderedMultiPartBody = templateMultiPartBody.render({ -// "fields_list": requestModel.formDataMapList.map(( -// field, -// ) { -// return ''' -// [ -// 'name' => '${field['name']}', -// 'contents' => '${field['contents']}' -// ], -// '''; -// }).join(), -// }); -// result += renderedMultiPartBody; -// } - -// String url = requestModel.url; -// if (!url.contains("://") && url.isNotEmpty) { -// url = "$defaultUriScheme://$url"; -// } -// var rM = requestModel.copyWith(url: url); - -// var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); - -// 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 jsonString = ''; -// m.forEach((key, value) { -// jsonString += "\t\t\t\t'$key' => '$value', \n"; -// }); -// jsonString = jsonString.substring( -// 0, jsonString.length - 2); // Removing trailing comma and space -// result += templateParams.render({ -// "params": jsonString, -// }); -// } - -// var headers = harJson["headers"]; -// if (headers.isNotEmpty || requestModel.isFormDataRequest) { -// var templateHeader = jj.Template(kTemplateHeader); -// var m = {}; -// for (var i in headers) { -// m[i["name"]] = i["value"]; -// } -// var headersString = ''; -// m.forEach((key, value) { -// headersString += "\t\t\t\t'$key' => '$value', \n"; -// }); -// headersString = headersString.substring( -// 0, headersString.length - 2); // Removing trailing comma and space -// result += templateHeader.render({ -// "headers": headersString, -// }); -// } - -// var templateBody = jj.Template(kTemplateBody); - -// if (requestModel.isFormDataRequest && -// requestModel.formDataMapList.isNotEmpty) { -// result += templateBody.render({ -// "body": "new MultipartStream(\$multipart)", -// }); -// } -// if (harJson["postData"]?["text"] != null) { -// result += templateBody -// .render({"body": kEncoder.convert(harJson["postData"]["text"])}); -// } - -// var templateStart = jj.Template(kTemplateStart); -// result += templateStart.render({ -// // "url": stripUrlParams(url), -// // "method": harJson["method"].toLowerCase(), -// }); - -// var templateRequest = jj.Template(kStringRequest); -// result += templateRequest.render({ -// "url": stripUrlParams(url), -// "method": harJson["method"].toLowerCase(), -// }); - -// return result; -// } catch (e) { -// return null; -// } -// } -// } - import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; @@ -479,8 +138,6 @@ echo \$res->getBody(); .render({"body": kEncoder.convert(harJson["postData"]["text"])}); } - //result += kStringRequest; - String getRequestBody(Map harJson) { if (harJson.containsKey("postData")) { var postData = harJson["postData"]; @@ -493,7 +150,7 @@ echo \$res->getBody(); } } } - return ""; // Return empty string if postData is not present or if mimeType is not supported + return ""; // Return empty string if postData or formdata is not present } var templateRequest = jj.Template(kStringRequest); @@ -501,7 +158,7 @@ echo \$res->getBody(); "url": stripUrlParams(url), "method": harJson["method"].toLowerCase(), "queryParams": - harJson["queryString"].isNotEmpty ? " \$queryParamsStr," : "", + harJson["queryString"].isNotEmpty ? ". \$queryParamsStr," : "", "headers": harJson["headers"].isNotEmpty ? " \$headers," : "", "body": getRequestBody(harJson), }); From f14c024dd0a8ddf84ee701c9dae559d2a76082e7 Mon Sep 17 00:00:00 2001 From: Aashutosh soni Date: Tue, 5 Mar 2024 11:52:12 +0530 Subject: [PATCH 29/91] update: removed unneccessary "\" characters from templates. --- lib/codegen/php/guzzle.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/codegen/php/guzzle.dart b/lib/codegen/php/guzzle.dart index 2857c526..04acd213 100644 --- a/lib/codegen/php/guzzle.dart +++ b/lib/codegen/php/guzzle.dart @@ -8,7 +8,7 @@ class PhpGuzzleCodeGen { String kStringImportNode = """use GuzzleHttp\\Client; use GuzzleHttp\\Psr7\\Request; {% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream;{% endif %} -\ + """; @@ -16,7 +16,7 @@ use GuzzleHttp\\Psr7\\Request; \$multipart = [ {{fields_list}} ]; -\ + """; @@ -25,7 +25,7 @@ use GuzzleHttp\\Psr7\\Request; {{params}} ]; \$queryParamsStr = '?' . http_build_query(\$queryParams); -\ + """; @@ -33,19 +33,19 @@ use GuzzleHttp\\Psr7\\Request; \$headers = [ {{headers}} ]; -\ + """; String kTemplateBody = """ \$body = {{body}}; -\ + """; String kStringRequest = """ \$client = new Client(); -\ + \$request = new Request('{{method}}', '{{url}}'{{queryParams}} {{headers}} {{body}}); \$res = \$client->sendAsync(\$request)->wait(); echo \$res->getBody(); From 750a5af12be260302f9b5ee2dcf5fed51f295e9c Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sat, 9 Mar 2024 21:22:25 +0530 Subject: [PATCH 30/91] fix test case --- test/codegen/kotlin_okhttp_codegen_test.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index acca0a66..1b9ac764 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -479,7 +479,7 @@ fun main() { expectedCode); }); - test('POST 4', () { + test('POST 5', () { const expectedCode = r'''import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.MultipartBody @@ -487,8 +487,10 @@ import okhttp3.MultipartBody fun main() { val client = OkHttpClient() - val url = "https://api.foss42.com/case/lower" - val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("text","I LOVE Flutter") + val url = "https://api.apidash.dev/io/form" + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") .build() val request = Request.Builder() .url(url) @@ -502,7 +504,7 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost4, "https"), + expect(kotlinOkHttpCodeGen.getCode(requestModelPost5, "https"), expectedCode); }); }); From 3c35352b4e7ee6aef44ae22351bc5646cec50475 Mon Sep 17 00:00:00 2001 From: Apoorv Dwivedi Date: Sun, 10 Mar 2024 00:43:59 +0530 Subject: [PATCH 31/91] Added go http codegen --- lib/codegen/codegen.dart | 3 + lib/codegen/go/http.dart | 197 +++++++++++++++++++++++++++++++++++++++ lib/consts.dart | 3 +- 3 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 lib/codegen/go/http.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..ef40de30 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,3 +1,4 @@ +import 'package:apidash/codegen/go/http.dart'; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; import 'dart/http.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.goHttp: + return GoHttpCodeGen().getCode(requestModel, defaultUriScheme); } } } diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart new file mode 100644 index 00000000..d9cf080e --- /dev/null +++ b/lib/codegen/go/http.dart @@ -0,0 +1,197 @@ +import 'dart:convert'; + +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' show getValidRequestUri; +import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; + +class GoHttpCodeGen { + final String kTemplateStart = """package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + {% if isBody %}"bytes" + {% if isFormDataRequest %}"mime/multipart" + "os"{% endif %}{% endif %} +) + +func main() { + client := &http.Client{} + +"""; + + String kTemplateUrl = """ + url, err := url.Parse("{{url}}") + if err != nil { + fmt.Println(err) + return + } + +"""; + + String kTemplateRawBody = """ + {% if body %}body := strings.NewReader(`{{body}}`){% endif %} + +"""; + + String kTemplateJsonBody = """ + {% if body %}body := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} + +"""; + + String kTemplateFormData = """ + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + var ( + file *os.File + part io.Writer + ) + {% for field in fields %} + {% if field.type == "file" %}file, err = os.Open("{{field.value}}") + if err != nil { + fmt.Println(err) + return + } + defer file.Close() + + part, err = writer.CreateFormFile("{{field.name}}", "{{field.value}}") + if err != nil { + fmt.Println(err) + return + } + io.Copy(part, file) + {% else %}writer.WriteField("{{field.name}}", "{{field.value}}"){% endif %}{% endfor %} + writer.Close() + + +"""; + + String kTemplateHeader = """ +{% if headers %}{% for header, value in headers %} + req.Header.Set("{{header}}", "{{value}}") +{% endfor %} +{% endif %} +"""; + + String kTemplateQueryParam = """ + query := url.Query() + {% for key, value in params %} + query.Set("{{key}}", "{{value}}") + {% endfor %} + url.RawQuery = query.Encode() + +"""; + + String kTemplateRequest = """ + req, err := http.NewRequest("{{method}}", url.String(), {% if hasBody %}body{% else %}nil{% endif %}) + if err != nil { + fmt.Println(err) + return + } + +"""; + + final String kTemplateEnd = """ + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +} +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + var hasBody = false; + var requestBody = requestModel.requestBody; + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var templateStart = jj.Template(kTemplateStart); + result += templateStart.render({ + "isBody": kMethodsWithBody.contains(requestModel.method) && + requestBody != null, + "isFormDataRequest": requestModel.isFormDataRequest + }); + + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + + Uri? uri = rec.$1; + + if (uri != null) { + var method = requestModel.method.name.toUpperCase(); + if (kMethodsWithBody.contains(requestModel.method) && + requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + hasBody = true; + } + if (requestModel.requestBodyContentType == ContentType.text) { + var templateRawBody = jj.Template(kTemplateRawBody); + result += templateRawBody.render({"body": requestBody}); + } else if (requestModel.requestBodyContentType == ContentType.json) { + var templateJsonBody = jj.Template(kTemplateJsonBody); + result += templateJsonBody.render({"body": requestBody}); + } else if (requestModel.isFormDataRequest) { + hasBody = true; + var templateFormData = jj.Template(kTemplateFormData); + result += templateFormData.render({ + "fields": requestModel.formDataMapList, + }); + } + } + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var templateQueryParam = jj.Template(kTemplateQueryParam); + result += templateQueryParam.render({"params": params}); + } + } + + var templateRequest = jj.Template(kTemplateRequest); + result += + templateRequest.render({"method": method, "hasBody": hasBody}); + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + var templateHeader = jj.Template(kTemplateHeader); + result += templateHeader.render({"headers": headers}); + } + } + + result += kTemplateEnd; + } + + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index d157b7fa..c5e6b447 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -271,7 +271,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + goHttp("Golang (http)", "go", "go"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; From be33809173feb7fb193d5f9ded3803d8b127a837 Mon Sep 17 00:00:00 2001 From: Apoorv Dwivedi Date: Sun, 10 Mar 2024 02:03:14 +0530 Subject: [PATCH 32/91] Added tests for go_http_codegen --- lib/codegen/go/http.dart | 5 +- test/codegen/go_http_codegen_test.dart | 1267 ++++++++++++++++++++++++ 2 files changed, 1269 insertions(+), 3 deletions(-) create mode 100644 test/codegen/go_http_codegen_test.dart diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart index d9cf080e..48882710 100644 --- a/lib/codegen/go/http.dart +++ b/lib/codegen/go/http.dart @@ -33,7 +33,7 @@ func main() { """; String kTemplateRawBody = """ - {% if body %}body := strings.NewReader(`{{body}}`){% endif %} + {% if body %}body := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} """; @@ -108,8 +108,7 @@ func main() { return } fmt.Println(string(res)) -} -"""; +}"""; String? getCode( RequestModel requestModel, diff --git a/test/codegen/go_http_codegen_test.dart b/test/codegen/go_http_codegen_test.dart new file mode 100644 index 00000000..f056cb38 --- /dev/null +++ b/test/codegen/go_http_codegen_test.dart @@ -0,0 +1,1267 @@ +import 'package:apidash/codegen/go/http.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final goHttpCodeGen = GoHttpCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet1, "https"), expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/country/data") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("code", "US") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/country/data?code=US") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("code", "IND") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet3, "https"), expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/humanize/social") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("num", "8700000") + + query.Set("digits", "3") + + query.Set("system", "SS") + + query.Set("add_space", "true") + + query.Set("trailing_zeros", "true") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet4, "https"), expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.github.com/repos/foss42/apidash") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet5, "https"), expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.github.com/repos/foss42/apidash") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("raw", "true") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet6, "https"), expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet7, "https"), expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.github.com/repos/foss42/apidash") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("raw", "true") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet8, "https"), expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/humanize/social") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("num", "8700000") + + query.Set("add_space", "true") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet9, "https"), expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/humanize/social") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect( + goHttpCodeGen.getCode( + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/humanize/social") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("num", "8700000") + + query.Set("digits", "3") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet11, "https"), expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/humanize/social") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelGet12, "https"), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("HEAD", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelHead1, "https"), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("http://api.apidash.dev") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("HEAD", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelHead2, "http"), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/case/lower") + if err != nil { + fmt.Println(err) + return + } + body := bytes.NewBuffer([]byte(`{ +"text": "I LOVE Flutter" +}`)) + req, err := http.NewRequest("POST", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost1, "https"), expectedCode); + }); + + test('POST 2', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/case/lower") + if err != nil { + fmt.Println(err) + return + } + body := bytes.NewBuffer([]byte(`{ +"text": "I LOVE Flutter" +}`)) + req, err := http.NewRequest("POST", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost2, "https"), expectedCode); + }); + + test('POST 3', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/case/lower") + if err != nil { + fmt.Println(err) + return + } + body := bytes.NewBuffer([]byte(`{ +"text": "I LOVE Flutter" +}`)) + req, err := http.NewRequest("POST", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost3, "https"), expectedCode); + }); + + test('POST 4', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/io/form") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("POST", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost4, "https"), expectedCode); + }); + + test('POST 5', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/io/form") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("POST", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost5, "https"), expectedCode); + }); + }); + + test("POST 6", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/io/img") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("POST", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost6, "https"), expectedCode); + }); + test("POST 7", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" + "os" +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/io/img") + if err != nil { + fmt.Println(err) + return + } + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + var ( + file *os.File + part io.Writer + ) + + writer.WriteField("token", "xyz") + file, err = os.Open("/Documents/up/1.png") + if err != nil { + fmt.Println(err) + return + } + defer file.Close() + + part, err = writer.CreateFormFile("imfile", "/Documents/up/1.png") + if err != nil { + fmt.Println(err) + return + } + io.Copy(part, file) + + writer.Close() + + req, err := http.NewRequest("POST", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost7, "https"), expectedCode); + }); + test("POST 8", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/io/form") + if err != nil { + fmt.Println(err) + return + } + query := url.Query() + + query.Set("size", "2") + + query.Set("len", "3") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("POST", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost8, "https"), expectedCode); + }); + test("POST 9", () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + "mime/multipart" + "os" +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://api.apidash.dev/io/img") + if err != nil { + fmt.Println(err) + return + } + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + var ( + file *os.File + part io.Writer + ) + + writer.WriteField("token", "xyz") + file, err = os.Open("/Documents/up/1.png") + if err != nil { + fmt.Println(err) + return + } + defer file.Close() + + part, err = writer.CreateFormFile("imfile", "/Documents/up/1.png") + if err != nil { + fmt.Println(err) + return + } + io.Copy(part, file) + + writer.Close() + + query := url.Query() + + query.Set("size", "2") + + query.Set("len", "3") + + url.RawQuery = query.Encode() + req, err := http.NewRequest("POST", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + + req.Header.Set("User-Agent", "Test Agent") + + req.Header.Set("Keep-Alive", "true") + + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPost9, "https"), expectedCode); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://reqres.in/api/users/2") + if err != nil { + fmt.Println(err) + return + } + body := bytes.NewBuffer([]byte(`{ +"name": "morpheus", +"job": "zion resident" +}`)) + req, err := http.NewRequest("PUT", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPut1, "https"), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://reqres.in/api/users/2") + if err != nil { + fmt.Println(err) + return + } + body := bytes.NewBuffer([]byte(`{ +"name": "marfeus", +"job": "accountant" +}`)) + req, err := http.NewRequest("PATCH", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://reqres.in/api/users/2") + if err != nil { + fmt.Println(err) + return + } + req, err := http.NewRequest("DELETE", url.String(), nil) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}"""; + expect(goHttpCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r'''package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "bytes" + +) + +func main() { + client := &http.Client{} + url, err := url.Parse("https://reqres.in/api/users/2") + if err != nil { + fmt.Println(err) + return + } + body := bytes.NewBuffer([]byte(`{ +"name": "marfeus", +"job": "accountant" +}`)) + req, err := http.NewRequest("DELETE", url.String(), body) + if err != nil { + fmt.Println(err) + return + } + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +}'''; + expect(goHttpCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + }); + }); +} From 1b4a5caa7ae5160926f2b9a1203ca27d75c20950 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 10 Mar 2024 05:33:53 +0530 Subject: [PATCH 33/91] Update cURL codegen --- lib/codegen/others/curl.dart | 45 ++++++++++--------- test/codegen/curl_codegen_test.dart | 68 ++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 27 deletions(-) diff --git a/lib/codegen/others/curl.dart b/lib/codegen/others/curl.dart index 4ae610de..6c0e02fc 100644 --- a/lib/codegen/others/curl.dart +++ b/lib/codegen/others/curl.dart @@ -1,6 +1,7 @@ import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show requestModelToHARJsonRequest; import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; // ignore: camel_case_types class cURLCodeGen { @@ -11,7 +12,7 @@ class cURLCodeGen { --header '{{name}}: {{value}}' """; String kTemplateFormData = """ \\ - --form '{{name}}: {{value}}' + --form '{{name}}={{value}}' """; String kTemplateBody = """ \\ @@ -38,7 +39,7 @@ class cURLCodeGen { "method": switch (harJson["method"]) { "GET" => "", "HEAD" => " --head", - _ => " --request ${harJson["method"]} \\\n" + _ => " --request ${harJson["method"]} \\\n " }, "url": harJson["url"], }); @@ -51,27 +52,31 @@ class cURLCodeGen { .render({"name": item["name"], "value": item["value"]}); } } - if (harJson['formData'] != null) { - var formDataList = harJson['formData'] as List>; - for (var formData in formDataList) { - var templateFormData = jj.Template(kTemplateFormData); - if (formData['type'] != null && - formData['name'] != null && - formData['value'] != null && - formData['name']!.isNotEmpty && - formData['value']!.isNotEmpty) { - result += templateFormData.render({ - "name": formData["name"], - "value": - "${formData['type'] == 'file' ? '@' : ''}${formData["value"]}", - }); + + var method = requestModel.method; + if (kMethodsWithBody.contains(method)) { + if (harJson['formData'] != null) { + var formDataList = harJson['formData'] as List>; + for (var formData in formDataList) { + var templateFormData = jj.Template(kTemplateFormData); + if (formData['type'] != null && + formData['name'] != null && + formData['value'] != null && + formData['name']!.isNotEmpty && + formData['value']!.isNotEmpty) { + result += templateFormData.render({ + "name": formData["name"], + "value": + "${formData['type'] == 'file' ? '@' : ''}${formData["value"]}", + }); + } } } - } - if (harJson["postData"]?["text"] != null) { - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": harJson["postData"]["text"]}); + if (harJson["postData"]?["text"] != null) { + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": harJson["postData"]["text"]}); + } } return result; } catch (e) { diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index 212a82ce..cde41db3 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -102,7 +102,7 @@ void main() { group('POST Request', () { test('POST 1', () { const expectedCode = r"""curl --request POST \ - --url 'https://api.apidash.dev/case/lower' \ + --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: text/plain' \ --data '{ "text": "I LOVE Flutter" @@ -112,7 +112,7 @@ void main() { test('POST 2', () { const expectedCode = r"""curl --request POST \ - --url 'https://api.apidash.dev/case/lower' \ + --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: application/json' \ --data '{ "text": "I LOVE Flutter" @@ -122,7 +122,7 @@ void main() { test('POST 3', () { const expectedCode = r"""curl --request POST \ - --url 'https://api.apidash.dev/case/lower' \ + --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: application/json' \ --header 'User-Agent: Test Agent' \ --data '{ @@ -130,12 +130,66 @@ void main() { }'"""; expect(curlCodeGen.getCode(requestModelPost3, "https"), expectedCode); }); + + test('POST 4', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/form' \ + --form 'text=API' \ + --form 'sep=|' \ + --form 'times=3'"""; + expect(curlCodeGen.getCode(requestModelPost4, "https"), expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/form' \ + --header 'User-Agent: Test Agent' \ + --form 'text=API' \ + --form 'sep=|' \ + --form 'times=3'"""; + expect(curlCodeGen.getCode(requestModelPost5, "https"), expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/img' \ + --form 'token=xyz' \ + --form 'imfile=@/Documents/up/1.png'"""; + expect(curlCodeGen.getCode(requestModelPost6, "https"), expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/img' \ + --form 'token=xyz' \ + --form 'imfile=@/Documents/up/1.png'"""; + expect(curlCodeGen.getCode(requestModelPost7, "https"), expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/form?size=2&len=3' \ + --form 'text=API' \ + --form 'sep=|' \ + --form 'times=3'"""; + expect(curlCodeGen.getCode(requestModelPost8, "https"), expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""curl --request POST \ + --url 'https://api.apidash.dev/io/img?size=2&len=3' \ + --header 'User-Agent: Test Agent' \ + --header 'Keep-Alive: true' \ + --form 'token=xyz' \ + --form 'imfile=@/Documents/up/1.png'"""; + expect(curlCodeGen.getCode(requestModelPost9, "https"), expectedCode); + }); }); group('PUT Request', () { test('PUT 1', () { const expectedCode = r"""curl --request PUT \ - --url 'https://reqres.in/api/users/2' \ + --url 'https://reqres.in/api/users/2' \ --header 'Content-Type: application/json' \ --data '{ "name": "morpheus", @@ -148,7 +202,7 @@ void main() { group('PATCH Request', () { test('PATCH 1', () { const expectedCode = r"""curl --request PATCH \ - --url 'https://reqres.in/api/users/2' \ + --url 'https://reqres.in/api/users/2' \ --header 'Content-Type: application/json' \ --data '{ "name": "marfeus", @@ -161,13 +215,13 @@ void main() { group('DELETE Request', () { test('DELETE 1', () { const expectedCode = r"""curl --request DELETE \ - --url 'https://reqres.in/api/users/2'"""; + --url 'https://reqres.in/api/users/2'"""; expect(curlCodeGen.getCode(requestModelDelete1, "https"), expectedCode); }); test('DELETE 2', () { const expectedCode = r"""curl --request DELETE \ - --url 'https://reqres.in/api/users/2' \ + --url 'https://reqres.in/api/users/2' \ --header 'Content-Type: application/json' \ --data '{ "name": "marfeus", From beb6d52c79ae59ca703b057b35cf4b7258df8cca Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 10 Mar 2024 06:06:28 +0530 Subject: [PATCH 34/91] Fix multipart request --- lib/providers/collection_providers.dart | 2 - lib/services/http_service.dart | 75 +++++++++++++------------ 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/lib/providers/collection_providers.dart b/lib/providers/collection_providers.dart index a1afa070..8768773d 100644 --- a/lib/providers/collection_providers.dart +++ b/lib/providers/collection_providers.dart @@ -173,8 +173,6 @@ class CollectionStateNotifier (http.Response?, Duration?, String?)? responseRec = await request( requestModel, defaultUriScheme: defaultUriScheme, - isMultiPartRequest: - requestModel.requestBodyContentType == ContentType.formdata, ); late final RequestModel newRequestModel; if (responseRec.$1 == null) { diff --git a/lib/services/http_service.dart b/lib/services/http_service.dart index c5a7b4ce..dec0b516 100644 --- a/lib/services/http_service.dart +++ b/lib/services/http_service.dart @@ -9,7 +9,6 @@ import 'package:apidash/consts.dart'; Future<(http.Response?, Duration?, String?)> request( RequestModel requestModel, { String defaultUriScheme = kDefaultUriScheme, - bool isMultiPartRequest = false, }) async { (Uri?, String?) uriRec = getValidRequestUri( requestModel.url, @@ -22,44 +21,48 @@ Future<(http.Response?, Duration?, String?)> request( http.Response response; String? body; try { - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(requestModel.method) && - requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - body = requestBody; - headers[HttpHeaders.contentLengthHeader] = contentLength.toString(); - if (!requestModel.hasContentTypeHeader) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - } - } Stopwatch stopwatch = Stopwatch()..start(); - if (isMultiPartRequest) { - var multiPartRequest = http.MultipartRequest( - requestModel.method.name.toUpperCase(), - requestUrl, - ); - multiPartRequest.headers.addAll(headers); - for (FormDataModel formData - in (requestModel.requestFormDataList ?? [])) { - if (formData.type == FormDataType.text) { - multiPartRequest.fields.addAll({formData.name: formData.value}); - } else { - multiPartRequest.files.add( - await http.MultipartFile.fromPath( - formData.name, - formData.value, - ), - ); + var isMultiPartRequest = + requestModel.requestBodyContentType == ContentType.formdata; + if (kMethodsWithBody.contains(requestModel.method)) { + var requestBody = requestModel.requestBody; + if (requestBody != null && !isMultiPartRequest) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + body = requestBody; + headers[HttpHeaders.contentLengthHeader] = contentLength.toString(); + if (!requestModel.hasContentTypeHeader) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } } } - http.StreamedResponse multiPartResponse = await multiPartRequest.send(); - stopwatch.stop(); - http.Response convertedMultiPartResponse = - await convertStreamedResponse(multiPartResponse); - return (convertedMultiPartResponse, stopwatch.elapsed, null); + if (isMultiPartRequest) { + var multiPartRequest = http.MultipartRequest( + requestModel.method.name.toUpperCase(), + requestUrl, + ); + multiPartRequest.headers.addAll(headers); + for (var formData + in (requestModel.requestFormDataList ?? [])) { + if (formData.type == FormDataType.text) { + multiPartRequest.fields.addAll({formData.name: formData.value}); + } else { + multiPartRequest.files.add( + await http.MultipartFile.fromPath( + formData.name, + formData.value, + ), + ); + } + } + http.StreamedResponse multiPartResponse = + await multiPartRequest.send(); + stopwatch.stop(); + http.Response convertedMultiPartResponse = + await convertStreamedResponse(multiPartResponse); + return (convertedMultiPartResponse, stopwatch.elapsed, null); + } } switch (requestModel.method) { case HTTPVerb.get: From 28516cd1c92ec4b2604b572cf79b70fdc33ac226 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 10 Mar 2024 06:59:31 +0530 Subject: [PATCH 35/91] Revert "fixed curl code gen error for empty url" This reverts commit 7e1ca33a28921789f0720542e63b2c520e553fcf. --- lib/codegen/others/curl.dart | 65 ++++++++++------------------- pubspec.lock | 40 ++++-------------- test/codegen/curl_codegen_test.dart | 5 +-- 3 files changed, 32 insertions(+), 78 deletions(-) diff --git a/lib/codegen/others/curl.dart b/lib/codegen/others/curl.dart index 638e9da5..4ae610de 100644 --- a/lib/codegen/others/curl.dart +++ b/lib/codegen/others/curl.dart @@ -1,7 +1,6 @@ -import 'package:apidash/models/models.dart' show RequestModel; import 'package:jinja/jinja.dart' as jj; - -import '../../consts.dart'; +import 'package:apidash/utils/utils.dart' show requestModelToHARJsonRequest; +import 'package:apidash/models/models.dart' show RequestModel; // ignore: camel_case_types class cURLCodeGen { @@ -30,48 +29,30 @@ class cURLCodeGen { if (!url.contains("://") && url.isNotEmpty) { url = "$defaultUriScheme://$url"; } - if (requestModel.enabledParamsMap.isNotEmpty) { - if (!url.contains('?')) { - url += "?"; - } else { - url += "&"; - } - for (MapEntry entry - in requestModel.enabledParamsMap.entries) { - url += "${Uri.encodeFull(entry.key)}=${Uri.encodeFull(entry.value)}&"; - } - url = url.substring(0, url.length - 1); - } var rM = requestModel.copyWith(url: url); + + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "method": switch (rM.method.name.toUpperCase()) { + "method": switch (harJson["method"]) { "GET" => "", "HEAD" => " --head", - _ => " --request ${rM.method.name.toUpperCase()} \\\n" + _ => " --request ${harJson["method"]} \\\n" }, - "url": rM.url, + "url": harJson["url"], }); - Map headers = rM.enabledHeadersMap; - if (rM.requestBody != null && - rM.requestBody!.isNotEmpty && - rM.method != HTTPVerb.get && - rM.requestBodyContentType != ContentType.formdata) { - var templateHeader = jj.Template(kTemplateHeader); - result += templateHeader.render({ - "name": "Content-Type", - "value": rM.requestBodyContentType.header - }); + var headers = harJson["headers"]; + if (headers.isNotEmpty) { + for (var item in headers) { + var templateHeader = jj.Template(kTemplateHeader); + result += templateHeader + .render({"name": item["name"], "value": item["value"]}); + } } - for (MapEntry header in headers.entries) { - var templateHeader = jj.Template(kTemplateHeader); - result += - templateHeader.render({"name": header.key, "value": header.value}); - } - - if (rM.requestBodyContentType == ContentType.formdata) { - List> formDataList = rM.formDataMapList; + if (harJson['formData'] != null) { + var formDataList = harJson['formData'] as List>; for (var formData in formDataList) { var templateFormData = jj.Template(kTemplateFormData); if (formData['type'] != null && @@ -86,13 +67,11 @@ class cURLCodeGen { }); } } - } else { - if (rM.requestBody != null && - rM.requestBody!.isNotEmpty && - rM.method != HTTPVerb.get) { - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": rM.requestBody}); - } + } + + if (harJson["postData"]?["text"] != null) { + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": harJson["postData"]["text"]}); } return result; } catch (e) { diff --git a/pubspec.lock b/pubspec.lock index 1737f75f..2f3f7f55 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -625,30 +625,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" - source: hosted - version: "10.0.0" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" - source: hosted - version: "2.0.1" lints: dependency: transitive description: @@ -685,26 +661,26 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.5.0" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.10.0" mime: dependency: transitive description: @@ -781,10 +757,10 @@ packages: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.3" path_parsing: dependency: transitive description: diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index b62de8b4..e9bb7f60 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -1,7 +1,6 @@ import 'package:apidash/codegen/others/curl.dart'; -import 'package:test/test.dart'; - import '../request_models.dart'; +import 'package:test/test.dart'; void main() { final curlCodeGen = cURLCodeGen(); @@ -20,7 +19,7 @@ void main() { test('GET 3', () { const expectedCode = - r"""curl --url 'https://api.foss42.com/country/data?code=US&code=IND'"""; + r"""curl --url 'https://api.foss42.com/country/data?code=IND'"""; expect(curlCodeGen.getCode(requestModelGet3, "https"), expectedCode); }); From d23019a43d911ecad964d03635ae0877b2cded4e Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 10 Mar 2024 07:02:23 +0530 Subject: [PATCH 36/91] Accept test change --- test/codegen/curl_codegen_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index e9bb7f60..6ba9c01b 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -1,6 +1,6 @@ +import 'package:test/test.dart'; import 'package:apidash/codegen/others/curl.dart'; import '../request_models.dart'; -import 'package:test/test.dart'; void main() { final curlCodeGen = cURLCodeGen(); From f9c32cddfd296719aebf84b3b4b9c494c5f55dca Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 10 Mar 2024 23:10:19 +0530 Subject: [PATCH 37/91] replace by getNewUuid --- lib/providers/collection_providers.dart | 8 ++++---- lib/utils/file_utils.dart | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/providers/collection_providers.dart b/lib/providers/collection_providers.dart index 8768773d..4ecc51ab 100644 --- a/lib/providers/collection_providers.dart +++ b/lib/providers/collection_providers.dart @@ -3,7 +3,7 @@ import 'settings_providers.dart'; import 'ui_providers.dart'; import '../models/models.dart'; import '../services/services.dart' show hiveHandler, HiveHandler, request; -import '../utils/utils.dart' show uuid, collectionToHAR; +import '../utils/utils.dart' show getNewUuid, collectionToHAR; import '../consts.dart'; import 'package:http/http.dart' as http; @@ -54,7 +54,7 @@ class CollectionStateNotifier } void add() { - final id = uuid.v1(); + final id = getNewUuid(); final newRequestModel = RequestModel( id: id, ); @@ -97,7 +97,7 @@ class CollectionStateNotifier } void duplicate(String id) { - final newId = uuid.v1(); + final newId = getNewUuid(); var itemIds = ref.read(requestSequenceProvider); int idx = itemIds.indexOf(id); @@ -213,7 +213,7 @@ class CollectionStateNotifier bool loadData() { var ids = hiveHandler.getIds(); if (ids == null || ids.length == 0) { - String newId = uuid.v1(); + String newId = getNewUuid(); state = { newId: RequestModel( id: newId, diff --git a/lib/utils/file_utils.dart b/lib/utils/file_utils.dart index 41a6d4a3..4f5c2228 100644 --- a/lib/utils/file_utils.dart +++ b/lib/utils/file_utils.dart @@ -49,7 +49,7 @@ String getShortPath(String path) { } String getTempFileName() { - return uuid.v1(); + return getNewUuid(); } Future pickFile() async { From 5776d9b840d3a566f753be99e9896fee77727020 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 10 Mar 2024 23:27:00 +0530 Subject: [PATCH 38/91] set boundary --- lib/codegen/codegen.dart | 14 ++++++++++---- lib/codegen/python/http_client.dart | 9 ++++----- lib/codegen/python/requests.dart | 8 ++++---- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..d39e4d10 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,5 +1,6 @@ import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; +import 'package:apidash/utils/utils.dart' show getNewUuid; import 'dart/http.dart'; import 'dart/dio.dart'; import 'kotlin/okhttp.dart'; @@ -14,8 +15,12 @@ class Codegen { String? getCode( CodegenLanguage codegenLanguage, RequestModel requestModel, - String defaultUriScheme, - ) { + String defaultUriScheme, { + String? boundary, + }) { + if (requestModel.isFormDataRequest) { + boundary = boundary ?? getNewUuid(); + } switch (codegenLanguage) { case CodegenLanguage.curl: return cURLCodeGen().getCode(requestModel, defaultUriScheme); @@ -39,9 +44,10 @@ class Codegen { return KotlinOkHttpCodeGen().getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonHttpClient: return PythonHttpClientCodeGen() - .getCode(requestModel, defaultUriScheme); + .getCode(requestModel, defaultUriScheme, boundary); case CodegenLanguage.pythonRequests: - return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + return PythonRequestsCodeGen() + .getCode(requestModel, defaultUriScheme, boundary); } } } diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 196b10df..c9082bb1 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString; + show getValidRequestUri, padMultilineString; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; @@ -89,9 +89,8 @@ body = b'\r\n'.join(dataList) String? getCode( RequestModel requestModel, String defaultUriScheme, + String? boundary, ) { - String uuid = getNewUuid(); - try { String result = ""; bool hasHeaders = false; @@ -148,7 +147,7 @@ body = b'\r\n'.join(dataList) var formHeaderTemplate = jj.Template(kTemplateFormHeaderContentType); headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, + "boundary": boundary, }); } @@ -169,7 +168,7 @@ body = b'\r\n'.join(dataList) result += formDataBodyData.render( { "fields_list": json.encode(requestModel.formDataMapList), - "boundary": uuid, + "boundary": boundary, }, ); } diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index cd79ccde..b9ea1bca 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/consts.dart'; import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; + show getValidRequestUri, padMultilineString, stripUriParams; import 'package:apidash/models/models.dart' show RequestModel; class PythonRequestsCodeGen { @@ -94,6 +94,7 @@ print('Response Body:', response.text) String? getCode( RequestModel requestModel, String defaultUriScheme, + String? boundary, ) { try { String result = ""; @@ -101,7 +102,6 @@ print('Response Body:', response.text) bool hasHeaders = false; bool hasBody = false; bool hasJsonBody = false; - String uuid = getNewUuid(); String url = requestModel.url; if (!url.contains("://") && url.isNotEmpty) { @@ -155,7 +155,7 @@ print('Response Body:', response.text) var formHeaderTemplate = jj.Template(kTemplateFormHeaderContentType); headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, + "boundary": boundary, }); } if (headers.isNotEmpty || hasBody) { @@ -175,7 +175,7 @@ print('Response Body:', response.text) result += formDataBodyData.render( { "fields_list": json.encode(requestModel.formDataMapList), - "boundary": uuid, + "boundary": boundary, }, ); } From 5af2fe885e8bbd458b82d8a8b6bd66b1769d1873 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 01:50:33 +0530 Subject: [PATCH 39/91] Update file_utils.dart --- lib/utils/file_utils.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/utils/file_utils.dart b/lib/utils/file_utils.dart index 4f5c2228..68554153 100644 --- a/lib/utils/file_utils.dart +++ b/lib/utils/file_utils.dart @@ -48,6 +48,11 @@ String getShortPath(String path) { return path; } +String getFilenameFromPath(String path) { + var f = p.split(path); + return f.last; +} + String getTempFileName() { return getNewUuid(); } From 20d99e02586350ef569fd82649ef3e517518157b Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 01:50:57 +0530 Subject: [PATCH 40/91] Update POST Model 2 --- test/request_models.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/request_models.dart b/test/request_models.dart index 0c3d85e2..67ff2835 100644 --- a/test/request_models.dart +++ b/test/request_models.dart @@ -209,7 +209,12 @@ const requestModelPost2 = RequestModel( url: 'https://api.apidash.dev/case/lower', method: HTTPVerb.post, requestBody: r"""{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }""", ); From e517e9d919ddc4a42ef90070d53167f8eb355598 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 01:51:12 +0530 Subject: [PATCH 41/91] Update request_model_test.dart --- test/models/request_model_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models/request_model_test.dart b/test/models/request_model_test.dart index 1bb40ec7..b7dbb413 100644 --- a/test/models/request_model_test.dart +++ b/test/models/request_model_test.dart @@ -175,7 +175,7 @@ void main() { }); expect(requestModel.paramsMap, {}); expect(requestModel.formDataMapList, []); - expect(requestModel.isFormDataRequest, false); + expect(requestModel.hasFormData, false); expect(requestModel.hasContentTypeHeader, true); }); From e8fd13cbcef2ad3a65153bc3089b2b6060b94cb7 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 01:52:24 +0530 Subject: [PATCH 42/91] Update Python requests codegen --- lib/codegen/codegen.dart | 64 +++-- lib/codegen/codegen_utils.dart | 15 ++ lib/codegen/python/requests.dart | 144 ++++++----- .../codegen/python_requests_codegen_test.dart | 235 +++++++++++++++--- 4 files changed, 331 insertions(+), 127 deletions(-) create mode 100644 lib/codegen/codegen_utils.dart diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index d39e4d10..f6fdaa5f 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -18,36 +18,64 @@ class Codegen { String defaultUriScheme, { String? boundary, }) { - if (requestModel.isFormDataRequest) { - boundary = boundary ?? getNewUuid(); - } switch (codegenLanguage) { case CodegenLanguage.curl: - return cURLCodeGen().getCode(requestModel, defaultUriScheme); + return cURLCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.har: - return HARCodeGen().getCode(requestModel, defaultUriScheme); + return HARCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.dartHttp: - return DartHttpCodeGen().getCode(requestModel, defaultUriScheme); + return DartHttpCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.dartDio: - return DartDioCodeGen().getCode(requestModel, defaultUriScheme); + return DartDioCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.jsAxios: - return AxiosCodeGen().getCode(requestModel, defaultUriScheme); + return AxiosCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.jsFetch: - return FetchCodeGen().getCode(requestModel, defaultUriScheme); + return FetchCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.nodejsAxios: - return AxiosCodeGen(isNodeJs: true) - .getCode(requestModel, defaultUriScheme); + return AxiosCodeGen(isNodeJs: true).getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.nodejsFetch: - return FetchCodeGen(isNodeJs: true) - .getCode(requestModel, defaultUriScheme); + return FetchCodeGen(isNodeJs: true).getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.kotlinOkHttp: - return KotlinOkHttpCodeGen().getCode(requestModel, defaultUriScheme); + return KotlinOkHttpCodeGen().getCode( + requestModel, + defaultUriScheme, + ); case CodegenLanguage.pythonHttpClient: - return PythonHttpClientCodeGen() - .getCode(requestModel, defaultUriScheme, boundary); + return PythonHttpClientCodeGen().getCode( + requestModel, + defaultUriScheme, + boundary: boundary ?? getNewUuid(), + ); case CodegenLanguage.pythonRequests: - return PythonRequestsCodeGen() - .getCode(requestModel, defaultUriScheme, boundary); + return PythonRequestsCodeGen().getCode( + requestModel, + defaultUriScheme, + boundary: boundary, + ); } } } diff --git a/lib/codegen/codegen_utils.dart b/lib/codegen/codegen_utils.dart new file mode 100644 index 00000000..2d7a1846 --- /dev/null +++ b/lib/codegen/codegen_utils.dart @@ -0,0 +1,15 @@ +String jsonToPyDict(String jsonString) { + Map replaceWithMap = { + "null": "None", + "true": "True", + "false": "False" + }; + String pyDict = jsonString; + for (var k in replaceWithMap.keys) { + RegExp regExp = RegExp(k + r'(?=([^"]*"[^"]*")*[^"]*$)'); + pyDict = pyDict.replaceAllMapped(regExp, (match) { + return replaceWithMap[match.group(0)] ?? match.group(0)!; + }); + } + return pyDict; +} diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index b9ea1bca..8a700122 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -1,15 +1,14 @@ import 'dart:io'; -import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/consts.dart'; import 'package:apidash/utils/utils.dart' - show getValidRequestUri, padMultilineString, stripUriParams; + show getValidRequestUri, stripUriParams, getFilenameFromPath; import 'package:apidash/models/models.dart' show RequestModel; +import '../codegen_utils.dart'; class PythonRequestsCodeGen { final String kTemplateStart = """import requests -{% if isFormDataRequest %}import mimetypes -from codecs import encode +{% if hasFormData %}from requests_toolbelt.multipart.encoder import MultipartEncoder {% endif %} url = '{{url}}' @@ -20,7 +19,6 @@ url = '{{url}}' params = {{params}} """; - int kParamsPadding = 9; String kTemplateBody = """ @@ -39,44 +37,27 @@ payload = {{body}} headers = {{headers}} """; - String kTemplateFormHeaderContentType = ''' -multipart/form-data; boundary={{boundary}}'''; - - int kHeadersPadding = 10; String kTemplateRequest = """ response = requests.{{method}}(url """; - final String kStringFormDataBody = r''' + final String kTemplateFormDataBody = r''' -def build_data_list(fields): - dataList = [] - for field in fields: - name = field.get('name', '') - value = field.get('value', '') - type_ = field.get('type', 'text') +payload = MultipartEncoder({ +{{formdata_payload}} +}{% if boundary != '' %}, + boundary="{{boundary}}" +{% endif %}) - dataList.append(encode('--{{boundary}}')) - if type_ == 'text': - dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) - dataList.append(encode('Content-Type: text/plain')) - dataList.append(encode('')) - dataList.append(encode(value)) - elif type_ == 'file': - dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) - dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) - dataList.append(encode('')) - dataList.append(open(value, 'rb').read()) - dataList.append(encode('--{{boundary}}--')) - dataList.append(encode('')) - return dataList - -dataList = build_data_list({{fields_list}}) -payload = b'\r\n'.join(dataList) '''; + String kTemplateFormDataRowText = r""" "{{name}}": "{{value}}","""; + + String kTemplateFormDataRowFile = + r""" "{{name}}": ("{{filename}}", open("{{path}}", "rb")),"""; + String kStringRequestParams = """, params=params"""; String kStringRequestBody = """, data=payload"""; @@ -91,11 +72,18 @@ print('Status Code:', response.status_code) print('Response Body:', response.text) """; + String kStringFormDataContentType = "payload.content_type"; + + String refactorHeaderString(String headerString) { + return headerString.replaceAll( + '"$kStringFormDataContentType"', kStringFormDataContentType); + } + String? getCode( RequestModel requestModel, - String defaultUriScheme, + String defaultUriScheme, { String? boundary, - ) { + }) { try { String result = ""; bool hasQuery = false; @@ -117,7 +105,7 @@ print('Response Body:', response.text) var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render({ "url": stripUriParams(uri), - 'isFormDataRequest': requestModel.isFormDataRequest + 'hasFormData': requestModel.hasFormData }); if (uri.hasQuery) { @@ -126,77 +114,85 @@ print('Response Body:', response.text) hasQuery = true; var templateParams = jj.Template(kTemplateParams); var paramsString = kEncoder.convert(params); - paramsString = padMultilineString(paramsString, kParamsPadding); result += templateParams.render({"params": paramsString}); } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - if (requestModel.requestBodyContentType == ContentType.json) { - hasJsonBody = true; - var templateBody = jj.Template(kTemplateJson); - result += templateBody.render({"body": requestBody}); - } else if (!requestModel.isFormDataRequest) { - hasBody = true; - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": requestBody}); + if (requestModel.hasFormData) { + hasBody = true; + List formdataPayload = []; + for (var item in requestModel.formDataList) { + if (item.type == FormDataType.text) { + formdataPayload.add(jj.Template(kTemplateFormDataRowText).render({ + "name": item.name, + "value": item.value, + })); + } + if (item.type == FormDataType.file) { + formdataPayload.add(jj.Template(kTemplateFormDataRowFile).render({ + "name": item.name, + "filename": getFilenameFromPath(item.value), + "path": item.value, + })); } } + var formDataBodyData = jj.Template(kTemplateFormDataBody); + result += formDataBodyData.render( + { + "formdata_payload": formdataPayload.join("\n"), + "boundary": boundary ?? '', + }, + ); + } else if (requestModel.hasJsonData) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + var pyDict = jsonToPyDict(requestModel.requestBody ?? ""); + result += templateBody.render({"body": pyDict}); + } else if (requestModel.hasTextData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestModel.requestBody}); } var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": boundary, - }); - } - if (headers.isNotEmpty || hasBody) { - hasHeaders = true; - if (hasBody) { + if (hasBody) { + if (requestModel.hasFormData) { + headers[HttpHeaders.contentTypeHeader] = + kStringFormDataContentType; + } else { headers[HttpHeaders.contentTypeHeader] = requestModel.requestBodyContentType.header; } + } + if (headers.isNotEmpty) { + hasHeaders = true; var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); + headersString = refactorHeaderString(headersString); var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headersString}); } } - if (requestModel.isFormDataRequest) { - var formDataBodyData = jj.Template(kStringFormDataBody); - result += formDataBodyData.render( - { - "fields_list": json.encode(requestModel.formDataMapList), - "boundary": boundary, - }, - ); - } + var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "method": method.name.toLowerCase(), + "method": requestModel.method.name.toLowerCase(), }); if (hasQuery) { result += kStringRequestParams; } - if (hasBody || requestModel.isFormDataRequest) { + if (hasBody) { result += kStringRequestBody; } - if (hasJsonBody || requestModel.isFormDataRequest) { + if (hasJsonBody) { result += kStringRequestJson; } - if (hasHeaders || requestModel.isFormDataRequest) { + if (hasHeaders) { result += kStringRequestHeaders; } diff --git a/test/codegen/python_requests_codegen_test.dart b/test/codegen/python_requests_codegen_test.dart index 3ed0a38a..babe65d6 100644 --- a/test/codegen/python_requests_codegen_test.dart +++ b/test/codegen/python_requests_codegen_test.dart @@ -26,8 +26,8 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/country/data' params = { - "code": "US" - } + "code": "US" +} response = requests.get(url, params=params) @@ -44,8 +44,8 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/country/data' params = { - "code": "IND" - } + "code": "IND" +} response = requests.get(url, params=params) @@ -62,12 +62,12 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/humanize/social' params = { - "num": "8700000", - "digits": "3", - "system": "SS", - "add_space": "true", - "trailing_zeros": "true" - } + "num": "8700000", + "digits": "3", + "system": "SS", + "add_space": "true", + "trailing_zeros": "true" +} response = requests.get(url, params=params) @@ -84,8 +84,8 @@ print('Response Body:', response.text) url = 'https://api.github.com/repos/foss42/apidash' headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, headers=headers) @@ -102,12 +102,12 @@ print('Response Body:', response.text) url = 'https://api.github.com/repos/foss42/apidash' params = { - "raw": "true" - } + "raw": "true" +} headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, params=params, headers=headers) @@ -138,12 +138,12 @@ print('Response Body:', response.text) url = 'https://api.github.com/repos/foss42/apidash' params = { - "raw": "true" - } + "raw": "true" +} headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, params=params, headers=headers) @@ -160,9 +160,9 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/humanize/social' params = { - "num": "8700000", - "add_space": "true" - } + "num": "8700000", + "add_space": "true" +} response = requests.get(url, params=params) @@ -179,8 +179,8 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/humanize/social' headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, headers=headers) @@ -201,13 +201,13 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/humanize/social' params = { - "num": "8700000", - "digits": "3" - } + "num": "8700000", + "digits": "3" +} headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.get(url, params=params, headers=headers) @@ -274,8 +274,8 @@ payload = r'''{ }''' headers = { - "content-type": "text/plain" - } + "content-type": "text/plain" +} response = requests.post(url, data=payload, headers=headers) @@ -292,7 +292,12 @@ print('Response Body:', response.text) url = 'https://api.apidash.dev/case/lower' payload = { -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": None, +"male": True, +"female": False, +"no": 1.2, +"arr": ["null", "true", "false", None] } response = requests.post(url, json=payload) @@ -314,8 +319,8 @@ payload = { } headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} response = requests.post(url, json=payload, headers=headers) @@ -325,6 +330,166 @@ print('Response Body:', response.text) expect(pythonRequestsCodeGen.getCode(requestModelPost3, "https"), expectedCode); }); + + test('POST 4', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/form' + +payload = MultipartEncoder({ + "text": "API", + "sep": "|", + "times": "3", +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect(pythonRequestsCodeGen.getCode(requestModelPost4, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/form' + +payload = MultipartEncoder({ + "text": "API", + "sep": "|", + "times": "3", +}) + +headers = { + "User-Agent": "Test Agent", + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect(pythonRequestsCodeGen.getCode(requestModelPost5, "https"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/img' + +payload = MultipartEncoder({ + "token": "xyz", + "imfile": ("1.png", open("/Documents/up/1.png", "rb")), +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect(pythonRequestsCodeGen.getCode(requestModelPost6, "https"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/img' + +payload = MultipartEncoder({ + "token": "xyz", + "imfile": ("1.png", open("/Documents/up/1.png", "rb")), +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect(pythonRequestsCodeGen.getCode(requestModelPost7, "https"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/form' + +params = { + "size": "2", + "len": "3" +} + +payload = MultipartEncoder({ + "text": "API", + "sep": "|", + "times": "3", +}) + +headers = { + "content-type": payload.content_type +} + +response = requests.post(url, params=params, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect(pythonRequestsCodeGen.getCode(requestModelPost8, "https"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""import requests +from requests_toolbelt.multipart.encoder import MultipartEncoder + +url = 'https://api.apidash.dev/io/img' + +params = { + "size": "2", + "len": "3" +} + +payload = MultipartEncoder({ + "token": "xyz", + "imfile": ("1.png", open("/Documents/up/1.png", "rb")), +}) + +headers = { + "User-Agent": "Test Agent", + "Keep-Alive": "true", + "content-type": payload.content_type +} + +response = requests.post(url, params=params, data=payload, headers=headers) + +print('Status Code:', response.status_code) +print('Response Body:', response.text) +"""; + expect(pythonRequestsCodeGen.getCode(requestModelPost9, "https"), + expectedCode); + }); }); group('PUT Request', () { From 4d4380f3aab9f1b168c3dc133d93464e9fdb2868 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 01:53:06 +0530 Subject: [PATCH 43/91] Update request model --- lib/codegen/js/axios.dart | 14 ++++++-------- lib/codegen/js/fetch.dart | 10 +++++----- lib/codegen/kotlin/okhttp.dart | 4 ++-- lib/codegen/python/http_client.dart | 18 +++++++++--------- lib/models/request_model.dart | 21 ++++++++++++++++++++- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/lib/codegen/js/axios.dart b/lib/codegen/js/axios.dart index 1aeee285..424aa710 100644 --- a/lib/codegen/js/axios.dart +++ b/lib/codegen/js/axios.dart @@ -12,7 +12,7 @@ class AxiosCodeGen { String kStringImportNode = """{% if isNodeJs %}import axios from 'axios'; -{% endif %}{% if isFormDataRequest and isNodeJs %}const fs = require('fs');{% endif %} +{% endif %}{% if hasFormData and isNodeJs %}const fs = require('fs');{% endif %} """; String kTemplateStart = """let config = { @@ -78,13 +78,12 @@ async function buildFormData(fields) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, "isNodeJs": isNodeJs, }); String result = importsData; - if (requestModel.isFormDataRequest && - requestModel.formDataMapList.isNotEmpty) { + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); var renderedMultiPartBody = templateMultiPartBody.render({ "isNodeJs": isNodeJs, @@ -118,13 +117,13 @@ async function buildFormData(fields) { } var headers = harJson["headers"]; - if (headers.isNotEmpty || requestModel.isFormDataRequest) { + if (headers.isNotEmpty || requestModel.hasFormData) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; for (var i in headers) { m[i["name"]] = i["value"]; } - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { m['Content-Type'] = 'multipart/form-data'; } result += templateHeader @@ -132,8 +131,7 @@ async function buildFormData(fields) { } var templateBody = jj.Template(kTemplateBody); - if (requestModel.isFormDataRequest && - requestModel.formDataMapList.isNotEmpty) { + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { var getFieldDataTemplate = jj.Template(kGetFormDataTemplate); result += templateBody.render({ diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index 4ef2e551..3241e311 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -12,7 +12,7 @@ class FetchCodeGen { String kStringImportNode = """ import fetch from 'node-fetch'; -{% if isFormDataRequest %}const fs = require('fs');{% endif %} +{% if hasFormData %}const fs = require('fs');{% endif %} """; @@ -78,11 +78,11 @@ fetch(url, options) try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, }); String result = isNodeJs ? importsData : ""; - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); result += templateMultiPartBody.render({ "isNodeJs": isNodeJs, @@ -108,7 +108,7 @@ fetch(url, options) if (headers.isNotEmpty) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { m["Content-Type"] = "multipart/form-data"; } for (var i in headers) { @@ -124,7 +124,7 @@ fetch(url, options) result += templateBody.render({ "body": kEncoder.convert(harJson["postData"]["text"]), }); - } else if (requestModel.isFormDataRequest) { + } else if (requestModel.hasFormData) { var templateBody = jj.Template(kTemplateBody); result += templateBody.render({ "body": 'payload', diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index bd8f0489..856d8f0c 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -113,7 +113,7 @@ import okhttp3.MultipartBody"""; var method = requestModel.method; var requestBody = requestModel.requestBody; - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { hasFormData = true; var formDataTemplate = jj.Template(kFormDataBody); @@ -152,7 +152,7 @@ import okhttp3.MultipartBody"""; var templateRequestEnd = jj.Template(kTemplateRequestEnd); result += templateRequestEnd.render({ "method": method.name.toLowerCase(), - "hasBody": (hasBody || requestModel.isFormDataRequest) ? "body" : "", + "hasBody": (hasBody || requestModel.hasFormData) ? "body" : "", }); } return result; diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index c9082bb1..1d042e96 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -8,7 +8,7 @@ import 'package:apidash/consts.dart'; class PythonHttpClientCodeGen { final String kTemplateStart = """import http.client -{% if isFormDataRequest %}import mimetypes +{% if hasFormData %}import mimetypes from codecs import encode {% endif %} """; @@ -88,9 +88,9 @@ body = b'\r\n'.join(dataList) '''; String? getCode( RequestModel requestModel, - String defaultUriScheme, + String defaultUriScheme, { String? boundary, - ) { + }) { try { String result = ""; bool hasHeaders = false; @@ -105,7 +105,7 @@ body = b'\r\n'.join(dataList) var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render( { - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, }, ); var rec = getValidRequestUri( @@ -131,7 +131,7 @@ body = b'\r\n'.join(dataList) var requestBody = requestModel.requestBody; if (kMethodsWithBody.contains(method) && requestBody != null && - !requestModel.isFormDataRequest) { + !requestModel.hasFormData) { var contentLength = utf8.encode(requestBody).length; if (contentLength > 0) { hasBody = true; @@ -143,7 +143,7 @@ body = b'\r\n'.join(dataList) var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { var formHeaderTemplate = jj.Template(kTemplateFormHeaderContentType); headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ @@ -163,7 +163,7 @@ body = b'\r\n'.join(dataList) result += templateHeaders.render({"headers": headersString}); } } - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { @@ -185,11 +185,11 @@ body = b'\r\n'.join(dataList) "queryParamsStr": hasQuery ? " + queryParamsStr" : "", }); - if (hasBody || requestModel.isFormDataRequest) { + if (hasBody || requestModel.hasFormData) { result += kStringRequestBody; } - if (hasHeaders || requestModel.isFormDataRequest) { + if (hasHeaders || requestModel.hasFormData) { result += kStringRequestHeaders; } diff --git a/lib/models/request_model.dart b/lib/models/request_model.dart index a8d3569a..290681f6 100644 --- a/lib/models/request_model.dart +++ b/lib/models/request_model.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'dart:convert'; import 'package:flutter/foundation.dart'; import '../utils/utils.dart' show @@ -62,9 +63,27 @@ class RequestModel { Map get headersMap => rowsToMap(requestHeaders) ?? {}; Map get paramsMap => rowsToMap(requestParams) ?? {}; + bool get hasFormDataContentType => + requestBodyContentType == ContentType.formdata; + bool get hasJsonContentType => requestBodyContentType == ContentType.json; + bool get hasTextContentType => requestBodyContentType == ContentType.text; + int get contentLength => utf8.encode(requestBody ?? "").length; + bool get hasJsonData => + kMethodsWithBody.contains(method) && + hasJsonContentType && + contentLength > 0; + bool get hasTextData => + kMethodsWithBody.contains(method) && + hasTextContentType && + contentLength > 0; + bool get hasFormData => + kMethodsWithBody.contains(method) && + hasFormDataContentType && + (requestFormDataList ?? []).isNotEmpty; + List get formDataList => + requestFormDataList ?? []; List> get formDataMapList => rowsToFormDataMapList(requestFormDataList) ?? []; - bool get isFormDataRequest => requestBodyContentType == ContentType.formdata; bool get hasContentTypeHeader => enabledHeadersMap.keys .any((k) => k.toLowerCase() == HttpHeaders.contentTypeHeader); From 2d5186bdf8f7d355178602a5024c186b3fd864fa Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 02:04:01 +0530 Subject: [PATCH 44/91] Update for POST 2 --- test/codegen/dart_dio_codegen_test.dart | 7 ++++++- test/codegen/kotlin_okhttp_codegen_test.dart | 7 ++++++- test/codegen/python_http_client_codegen_test.dart | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 5b981fde..1576070c 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -398,7 +398,12 @@ import 'dart:convert' as convert; void main() async { try { final data = convert.json.decode(r'''{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }'''); final response = await dio.Dio.post( 'https://api.apidash.dev/case/lower', diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index 1b9ac764..3170028f 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -428,7 +428,12 @@ fun main() { val mediaType = "application/json".toMediaType() val body = """{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }""".toRequestBody(mediaType) val request = Request.Builder() diff --git a/test/codegen/python_http_client_codegen_test.dart b/test/codegen/python_http_client_codegen_test.dart index 0ca712c2..0665e186 100644 --- a/test/codegen/python_http_client_codegen_test.dart +++ b/test/codegen/python_http_client_codegen_test.dart @@ -326,7 +326,12 @@ print(data.decode("utf-8")) const expectedCode = r"""import http.client body = r'''{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }''' headers = { From 9be445072cfaf93919cd54d0a90443576a29479b Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 02:06:21 +0530 Subject: [PATCH 45/91] Update har_utils_test.dart --- test/utils/har_utils_test.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/utils/har_utils_test.dart b/test/utils/har_utils_test.dart index 174ab180..9655e7c1 100644 --- a/test/utils/har_utils_test.dart +++ b/test/utils/har_utils_test.dart @@ -261,14 +261,19 @@ void main() { 'postData': { 'mimeType': 'application/json', 'text': '{\n' - '"text": "I LOVE Flutter"\n' + '"text": "I LOVE Flutter",\n' + '"flag": null,\n' + '"male": true,\n' + '"female": false,\n' + '"no": 1.2,\n' + '"arr": ["null", "true", "false", null]\n' '}', 'comment': '' }, 'comment': '', 'cookies': [], 'headersSize': -1, - 'bodySize': 28 + 'bodySize': 124 }; expect( requestModelToHARJsonRequest( From fc7a051285bfe4293f447c0a91efeaa704036d6a Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 02:24:35 +0530 Subject: [PATCH 46/91] POST 2 test updates --- test/codegen/curl_codegen_test.dart | 7 ++++++- test/codegen/dart_http_codegen_test.dart | 7 ++++++- test/codegen/js_axios_codegen_test.dart | 2 +- test/codegen/js_fetch_codegen_test.dart | 2 +- test/codegen/nodejs_axios_codegen_test.dart | 2 +- test/codegen/nodejs_fetch_codegen_test.dart | 2 +- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index 4481e819..29f9a406 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -115,7 +115,12 @@ void main() { --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: application/json' \ --data '{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }'"""; expect(curlCodeGen.getCode(requestModelPost2, "https"), expectedCode); }); diff --git a/test/codegen/dart_http_codegen_test.dart b/test/codegen/dart_http_codegen_test.dart index 790658b1..696646b0 100644 --- a/test/codegen/dart_http_codegen_test.dart +++ b/test/codegen/dart_http_codegen_test.dart @@ -409,7 +409,12 @@ void main() async { var uri = Uri.parse('https://api.apidash.dev/case/lower'); String body = r'''{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }'''; var headers = {'content-type': 'application/json'}; diff --git a/test/codegen/js_axios_codegen_test.dart b/test/codegen/js_axios_codegen_test.dart index c364dbdb..cf2d5a18 100644 --- a/test/codegen/js_axios_codegen_test.dart +++ b/test/codegen/js_axios_codegen_test.dart @@ -383,7 +383,7 @@ axios(config) headers: { "Content-Type": "application/json" }, - data: "{\n\"text\": \"I LOVE Flutter\"\n}" + data: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; axios(config) diff --git a/test/codegen/js_fetch_codegen_test.dart b/test/codegen/js_fetch_codegen_test.dart index c29f93b9..2c2ec049 100644 --- a/test/codegen/js_fetch_codegen_test.dart +++ b/test/codegen/js_fetch_codegen_test.dart @@ -429,7 +429,7 @@ let options = { "Content-Type": "application/json" }, body: -"{\n\"text\": \"I LOVE Flutter\"\n}" +"{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; let status; diff --git a/test/codegen/nodejs_axios_codegen_test.dart b/test/codegen/nodejs_axios_codegen_test.dart index d4a12902..f3e77570 100644 --- a/test/codegen/nodejs_axios_codegen_test.dart +++ b/test/codegen/nodejs_axios_codegen_test.dart @@ -415,7 +415,7 @@ let config = { headers: { "Content-Type": "application/json" }, - data: "{\n\"text\": \"I LOVE Flutter\"\n}" + data: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; axios(config) diff --git a/test/codegen/nodejs_fetch_codegen_test.dart b/test/codegen/nodejs_fetch_codegen_test.dart index 592610ee..0c98ac35 100644 --- a/test/codegen/nodejs_fetch_codegen_test.dart +++ b/test/codegen/nodejs_fetch_codegen_test.dart @@ -451,7 +451,7 @@ let options = { "Content-Type": "application/json" }, body: -"{\n\"text\": \"I LOVE Flutter\"\n}" +"{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; let status; From cb8bfebecdbe118e853a576dc44a4890d38398c7 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 05:19:03 +0530 Subject: [PATCH 47/91] Refactor codegen --- lib/codegen/codegen.dart | 68 ++++------- lib/codegen/dart/dio.dart | 7 +- lib/codegen/dart/http.dart | 7 +- lib/codegen/js/axios.dart | 16 +-- lib/codegen/js/fetch.dart | 13 +- lib/codegen/kotlin/okhttp.dart | 8 +- lib/codegen/others/har.dart | 6 +- lib/codegen/python/http_client.dart | 10 +- lib/codegen/python/requests.dart | 10 +- test/codegen/curl_codegen_test.dart | 88 +++++++++----- test/codegen/dart_dio_codegen_test.dart | 89 ++++++++++---- test/codegen/dart_http_codegen_test.dart | 89 ++++++++++---- test/codegen/js_axios_codegen_test.dart | 92 ++++++++++---- test/codegen/js_fetch_codegen_test.dart | 92 ++++++++++---- test/codegen/kotlin_okhttp_codegen_test.dart | 92 ++++++++++---- test/codegen/nodejs_axios_codegen_test.dart | 110 +++++++++++++---- test/codegen/nodejs_fetch_codegen_test.dart | 110 +++++++++++++---- .../python_http_client_codegen_test.dart | 90 ++++++++++---- .../codegen/python_requests_codegen_test.dart | 114 +++++++++++++----- 19 files changed, 759 insertions(+), 352 deletions(-) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index f6fdaa5f..ad348e24 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -18,64 +18,40 @@ class Codegen { String defaultUriScheme, { String? boundary, }) { + String url = requestModel.url; + + if (url.isEmpty) { + url = kDefaultUri; + } + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + var rM = requestModel.copyWith(url: url); + switch (codegenLanguage) { case CodegenLanguage.curl: - return cURLCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return cURLCodeGen().getCode(rM); case CodegenLanguage.har: - return HARCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return HARCodeGen().getCode(rM, defaultUriScheme, boundary: boundary); case CodegenLanguage.dartHttp: - return DartHttpCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return DartHttpCodeGen().getCode(rM); case CodegenLanguage.dartDio: - return DartDioCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return DartDioCodeGen().getCode(rM); case CodegenLanguage.jsAxios: - return AxiosCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return AxiosCodeGen().getCode(rM); case CodegenLanguage.jsFetch: - return FetchCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return FetchCodeGen().getCode(rM); case CodegenLanguage.nodejsAxios: - return AxiosCodeGen(isNodeJs: true).getCode( - requestModel, - defaultUriScheme, - ); + return AxiosCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.nodejsFetch: - return FetchCodeGen(isNodeJs: true).getCode( - requestModel, - defaultUriScheme, - ); + return FetchCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.kotlinOkHttp: - return KotlinOkHttpCodeGen().getCode( - requestModel, - defaultUriScheme, - ); + return KotlinOkHttpCodeGen().getCode(rM); case CodegenLanguage.pythonHttpClient: - return PythonHttpClientCodeGen().getCode( - requestModel, - defaultUriScheme, - boundary: boundary ?? getNewUuid(), - ); + return PythonHttpClientCodeGen() + .getCode(rM, boundary: boundary ?? getNewUuid()); case CodegenLanguage.pythonRequests: - return PythonRequestsCodeGen().getCode( - requestModel, - defaultUriScheme, - boundary: boundary, - ); + return PythonRequestsCodeGen().getCode(rM, boundary: boundary); } } } diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index c4a7ed8e..c05b0b68 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -8,15 +8,10 @@ import 'shared.dart'; class DartDioCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } final next = generatedDartCode( - url: url, + url: requestModel.url, method: requestModel.method, queryParams: requestModel.enabledParamsMap, headers: requestModel.enabledHeadersMap, diff --git a/lib/codegen/dart/http.dart b/lib/codegen/dart/http.dart index 42c44ecb..89e8062c 100644 --- a/lib/codegen/dart/http.dart +++ b/lib/codegen/dart/http.dart @@ -9,15 +9,10 @@ import 'shared.dart'; class DartHttpCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } final next = generatedDartCode( - url: url, + url: requestModel.url, method: requestModel.method, queryParams: requestModel.enabledParamsMap, headers: {...requestModel.enabledHeadersMap}, diff --git a/lib/codegen/js/axios.dart b/lib/codegen/js/axios.dart index 424aa710..71456d6e 100644 --- a/lib/codegen/js/axios.dart +++ b/lib/codegen/js/axios.dart @@ -73,7 +73,6 @@ async function buildFormData(fields) { '''; String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); @@ -91,17 +90,14 @@ async function buildFormData(fields) { result += renderedMultiPartBody; } - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = requestModelToHARJsonRequest( + requestModel, + useEnabled: true, + ); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "url": stripUrlParams(url), + "url": stripUrlParams(requestModel.url), "method": harJson["method"].toLowerCase(), }); @@ -124,7 +120,7 @@ async function buildFormData(fields) { m[i["name"]] = i["value"]; } if (requestModel.hasFormData) { - m['Content-Type'] = 'multipart/form-data'; + m[kHeaderContentType] = 'multipart/form-data'; } result += templateHeader .render({"headers": padMultilineString(kEncoder.convert(m), 2)}); diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index 3241e311..2ff88a9b 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -73,7 +73,6 @@ fetch(url, options) String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); @@ -89,13 +88,11 @@ fetch(url, options) "fields_list": json.encode(requestModel.formDataMapList), }); } - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = requestModelToHARJsonRequest( + requestModel, + useEnabled: true, + ); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ @@ -109,7 +106,7 @@ fetch(url, options) var templateHeader = jj.Template(kTemplateHeader); var m = {}; if (requestModel.hasFormData) { - m["Content-Type"] = "multipart/form-data"; + m[kHeaderContentType] = "multipart/form-data"; } for (var i in headers) { m[i["name"]] = i["value"]; diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index 856d8f0c..c717dc97 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -75,7 +75,6 @@ import okhttp3.MultipartBody"""; String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; @@ -83,13 +82,8 @@ import okhttp3.MultipartBody"""; bool hasBody = false; bool hasFormData = false; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; diff --git a/lib/codegen/others/har.dart b/lib/codegen/others/har.dart index 77d78f58..72ab8731 100644 --- a/lib/codegen/others/har.dart +++ b/lib/codegen/others/har.dart @@ -5,13 +5,15 @@ import 'package:apidash/models/models.dart' show RequestModel; class HARCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, - ) { + String defaultUriScheme, { + String? boundary, + }) { try { var harString = kEncoder.convert(requestModelToHARJsonRequest( requestModel, defaultUriScheme: defaultUriScheme, useEnabled: true, + boundary: boundary, )); return harString; } catch (e) { diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 1d042e96..6913314a 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -87,8 +87,7 @@ dataList = build_data_list({{fields_list}}) body = b'\r\n'.join(dataList) '''; String? getCode( - RequestModel requestModel, - String defaultUriScheme, { + RequestModel requestModel, { String? boundary, }) { try { @@ -97,11 +96,6 @@ body = b'\r\n'.join(dataList) bool hasQuery = false; bool hasBody = false; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render( { @@ -109,7 +103,7 @@ body = b'\r\n'.join(dataList) }, ); var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); diff --git a/lib/codegen/python/requests.dart b/lib/codegen/python/requests.dart index 8a700122..6fb07908 100644 --- a/lib/codegen/python/requests.dart +++ b/lib/codegen/python/requests.dart @@ -80,8 +80,7 @@ print('Response Body:', response.text) } String? getCode( - RequestModel requestModel, - String defaultUriScheme, { + RequestModel requestModel, { String? boundary, }) { try { @@ -91,13 +90,8 @@ print('Response Body:', response.text) bool hasBody = false; bool hasJsonBody = false; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; diff --git a/test/codegen/curl_codegen_test.dart b/test/codegen/curl_codegen_test.dart index 29f9a406..ec0df5db 100644 --- a/test/codegen/curl_codegen_test.dart +++ b/test/codegen/curl_codegen_test.dart @@ -1,64 +1,74 @@ +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; -import 'package:apidash/codegen/others/curl.dart'; import '../request_models.dart'; void main() { - final curlCodeGen = cURLCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""curl --url 'https://api.apidash.dev'"""; - expect(curlCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { const expectedCode = r"""curl --url 'https://api.apidash.dev/country/data?code=US'"""; - expect(curlCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { const expectedCode = r"""curl --url 'https://api.apidash.dev/country/data?code=IND'"""; - expect(curlCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { const expectedCode = r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'"""; - expect(curlCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { const expectedCode = r"""curl --url 'https://api.github.com/repos/foss42/apidash' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { const expectedCode = r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { const expectedCode = r"""curl --url 'https://api.apidash.dev'"""; - expect(curlCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { const expectedCode = r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { const expectedCode = r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'"""; - expect(curlCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -66,7 +76,8 @@ void main() { r"""curl --url 'https://api.apidash.dev/humanize/social' \ --header 'User-Agent: Test Agent'"""; expect( - curlCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.curl, requestModelGet10, "https", ), @@ -77,25 +88,29 @@ void main() { const expectedCode = r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3' \ --header 'User-Agent: Test Agent'"""; - expect(curlCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { const expectedCode = r"""curl --url 'https://api.apidash.dev/humanize/social'"""; - expect(curlCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet12, "https"), + expectedCode); }); }); group('HEAD Request', () { test('HEAD 1', () { const expectedCode = r"""curl --head --url 'https://api.apidash.dev'"""; - expect(curlCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { const expectedCode = r"""curl --head --url 'http://api.apidash.dev'"""; - expect(curlCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelHead2, "http"), + expectedCode); }); }); @@ -107,7 +122,8 @@ void main() { --data '{ "text": "I LOVE Flutter" }'"""; - expect(curlCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -122,7 +138,8 @@ void main() { "no": 1.2, "arr": ["null", "true", "false", null] }'"""; - expect(curlCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -133,7 +150,8 @@ void main() { --data '{ "text": "I LOVE Flutter" }'"""; - expect(curlCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost3, "https"), + expectedCode); }); test('POST 4', () { @@ -142,7 +160,8 @@ void main() { --form 'text=API' \ --form 'sep=|' \ --form 'times=3'"""; - expect(curlCodeGen.getCode(requestModelPost4, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost4, "https"), + expectedCode); }); test('POST 5', () { @@ -152,7 +171,8 @@ void main() { --form 'text=API' \ --form 'sep=|' \ --form 'times=3'"""; - expect(curlCodeGen.getCode(requestModelPost5, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost5, "https"), + expectedCode); }); test('POST 6', () { @@ -160,7 +180,8 @@ void main() { --url 'https://api.apidash.dev/io/img' \ --form 'token=xyz' \ --form 'imfile=@/Documents/up/1.png'"""; - expect(curlCodeGen.getCode(requestModelPost6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost6, "https"), + expectedCode); }); test('POST 7', () { @@ -168,7 +189,8 @@ void main() { --url 'https://api.apidash.dev/io/img' \ --form 'token=xyz' \ --form 'imfile=@/Documents/up/1.png'"""; - expect(curlCodeGen.getCode(requestModelPost7, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost7, "https"), + expectedCode); }); test('POST 8', () { @@ -177,7 +199,8 @@ void main() { --form 'text=API' \ --form 'sep=|' \ --form 'times=3'"""; - expect(curlCodeGen.getCode(requestModelPost8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost8, "https"), + expectedCode); }); test('POST 9', () { @@ -187,7 +210,8 @@ void main() { --header 'Keep-Alive: true' \ --form 'token=xyz' \ --form 'imfile=@/Documents/up/1.png'"""; - expect(curlCodeGen.getCode(requestModelPost9, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPost9, "https"), + expectedCode); }); }); @@ -200,7 +224,8 @@ void main() { "name": "morpheus", "job": "zion resident" }'"""; - expect(curlCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPut1, "https"), + expectedCode); }); }); @@ -213,7 +238,8 @@ void main() { "name": "marfeus", "job": "accountant" }'"""; - expect(curlCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.curl, requestModelPatch1, "https"), + expectedCode); }); }); @@ -221,7 +247,9 @@ void main() { test('DELETE 1', () { const expectedCode = r"""curl --request DELETE \ --url 'https://reqres.in/api/users/2'"""; - expect(curlCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.curl, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -232,7 +260,9 @@ void main() { "name": "marfeus", "job": "accountant" }'"""; - expect(curlCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.curl, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 1576070c..84ae29d4 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -1,10 +1,10 @@ -import 'package:apidash/codegen/dart/dio.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; - import '../request_models.dart'; void main() { - final dartDioCodeGen = DartDioCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -25,7 +25,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -50,7 +52,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -75,7 +79,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -106,7 +112,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -131,7 +139,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -158,7 +168,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -179,7 +191,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -206,7 +220,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -234,7 +250,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -260,7 +278,8 @@ void main() async { } """; expect( - dartDioCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.dartDio, requestModelGet10, "https", ), @@ -294,7 +313,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -315,7 +336,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelGet12, "https"), + expectedCode); }); }); @@ -338,7 +361,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -359,7 +384,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelHead2, "http"), + expectedCode); }); }); @@ -388,7 +415,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -421,7 +450,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -451,7 +482,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost3, "https"), + expectedCode); }); }); @@ -482,7 +515,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPut1, "https"), + expectedCode); }); }); @@ -513,7 +548,9 @@ void main() async { } } """; - expect(dartDioCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartDio, requestModelPatch1, "https"), + expectedCode); }); }); @@ -537,7 +574,9 @@ void main() async { } """; expect( - dartDioCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartDio, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -567,7 +606,9 @@ void main() async { } """; expect( - dartDioCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartDio, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/dart_http_codegen_test.dart b/test/codegen/dart_http_codegen_test.dart index 696646b0..b8530555 100644 --- a/test/codegen/dart_http_codegen_test.dart +++ b/test/codegen/dart_http_codegen_test.dart @@ -1,10 +1,10 @@ -import 'package:apidash/codegen/dart/http.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; - import '../request_models.dart'; void main() { - final dartHttpCodeGen = DartHttpCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -25,7 +25,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -50,7 +52,9 @@ void main() async { } """; - expect(dartHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -76,7 +80,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -106,7 +112,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -132,7 +140,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -161,7 +171,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -182,7 +194,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -211,7 +225,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -238,7 +254,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -265,7 +283,8 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelGet10, "https", ), @@ -301,7 +320,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -322,7 +343,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet12, "https"), + expectedCode); }); }); @@ -345,7 +368,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -366,7 +391,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelHead2, "http"), + expectedCode); }); }); @@ -399,7 +426,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -435,7 +464,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -469,7 +500,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost3, "https"), + expectedCode); }); }); @@ -503,7 +536,9 @@ void main() async { } } """; - expect(dartHttpCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.dartHttp, requestModelPut1, "https"), + expectedCode); }); }); @@ -538,7 +573,9 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPatch1, "https"), + expectedCode); }); }); @@ -562,7 +599,9 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -595,7 +634,9 @@ void main() async { } """; expect( - dartHttpCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/js_axios_codegen_test.dart b/test/codegen/js_axios_codegen_test.dart index cf2d5a18..40b420e4 100644 --- a/test/codegen/js_axios_codegen_test.dart +++ b/test/codegen/js_axios_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/js/axios.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final axiosCodeGen = AxiosCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -24,7 +25,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -48,7 +51,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -72,7 +77,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -100,7 +107,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -124,7 +133,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -151,7 +162,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -172,7 +185,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -199,7 +214,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -224,7 +241,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -249,7 +268,8 @@ axios(config) }); """; expect( - axiosCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.jsAxios, requestModelGet10, "https", ), @@ -281,7 +301,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -302,7 +324,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet12, "https"), + expectedCode); }); }); @@ -325,7 +349,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -346,7 +372,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelHead2, "http"), + expectedCode); }); }); @@ -373,7 +401,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -398,7 +428,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -424,7 +456,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost3, "https"), + expectedCode); }); }); @@ -451,7 +485,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPut1, "https"), + expectedCode); }); }); @@ -478,7 +514,9 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsAxios, requestModelPatch1, "https"), + expectedCode); }); }); @@ -501,7 +539,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -526,7 +567,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/js_fetch_codegen_test.dart b/test/codegen/js_fetch_codegen_test.dart index 2c2ec049..4f070142 100644 --- a/test/codegen/js_fetch_codegen_test.dart +++ b/test/codegen/js_fetch_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/js/fetch.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final fetchCodeGen = FetchCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -28,7 +29,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -54,7 +57,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -80,7 +85,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -106,7 +113,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -135,7 +144,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -164,7 +175,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -189,7 +202,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -218,7 +233,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -244,7 +261,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -274,7 +293,8 @@ fetch(url, options) }); """; expect( - fetchCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.jsFetch, requestModelGet10, "https", ), @@ -307,7 +327,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -333,7 +355,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet12, "https"), + expectedCode); }); }); @@ -360,7 +384,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -385,7 +411,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelHead2, "http"), + expectedCode); }); }); @@ -417,7 +445,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -447,7 +477,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -478,7 +510,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost3, "https"), + expectedCode); }); }); @@ -510,7 +544,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPut1, "https"), + expectedCode); }); }); @@ -542,7 +578,9 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.jsFetch, requestModelPatch1, "https"), + expectedCode); }); }); @@ -569,7 +607,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -599,7 +640,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index 3170028f..f91f183c 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/kotlin/okhttp.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; import '../request_models.dart'; void main() { - final kotlinOkHttpCodeGen = KotlinOkHttpCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -27,7 +28,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -54,7 +57,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -81,7 +86,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet3, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -112,7 +119,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet4, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -137,7 +146,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet5, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -165,7 +176,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet6, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -189,7 +202,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet7, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -217,7 +232,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet8, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -245,7 +262,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelGet9, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -270,7 +289,8 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet10, "https", ), @@ -302,7 +322,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet11, "https"), expectedCode); }); @@ -326,7 +348,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelGet12, "https"), expectedCode); }); }); @@ -352,7 +376,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelHead1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelHead1, "https"), expectedCode); }); @@ -377,7 +403,9 @@ fun main() { } """; expect( - kotlinOkHttpCodeGen.getCode(requestModelHead2, "http"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelHead2, "http"), + expectedCode); }); }); @@ -410,7 +438,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost1, "https"), expectedCode); }); @@ -447,7 +477,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost2, "https"), expectedCode); }); @@ -480,7 +512,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost3, "https"), expectedCode); }); @@ -509,7 +543,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPost5, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost5, "https"), expectedCode); }); }); @@ -545,7 +581,9 @@ fun main() { } '''; expect( - kotlinOkHttpCodeGen.getCode(requestModelPut1, "https"), expectedCode); + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPut1, "https"), + expectedCode); }); }); @@ -579,7 +617,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPatch1, "https"), expectedCode); }); }); @@ -605,7 +645,9 @@ fun main() { println(response.body?.string()) } """; - expect(kotlinOkHttpCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelDelete1, "https"), expectedCode); }); @@ -638,7 +680,9 @@ fun main() { println(response.body?.string()) } '''; - expect(kotlinOkHttpCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelDelete2, "https"), expectedCode); }); }); diff --git a/test/codegen/nodejs_axios_codegen_test.dart b/test/codegen/nodejs_axios_codegen_test.dart index f3e77570..ab4c2bf5 100644 --- a/test/codegen/nodejs_axios_codegen_test.dart +++ b/test/codegen/nodejs_axios_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/js/axios.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final axiosCodeGen = AxiosCodeGen(isNodeJs: true); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -26,7 +27,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -52,7 +56,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -78,7 +85,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -108,7 +118,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -134,7 +147,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -163,7 +179,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -186,7 +205,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -215,7 +237,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -242,7 +267,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -269,7 +297,8 @@ axios(config) }); """; expect( - axiosCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet10, "https", ), @@ -303,7 +332,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -326,7 +358,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelGet12, "https"), + expectedCode); }); }); @@ -351,7 +386,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -374,7 +412,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelHead2, "http"), + expectedCode); }); }); @@ -403,7 +444,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -430,7 +474,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -458,7 +505,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPost3, "https"), + expectedCode); }); }); @@ -487,7 +537,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPut1, "https"), + expectedCode); }); }); @@ -516,7 +569,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelPatch1, "https"), + expectedCode); }); }); @@ -541,7 +597,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -568,7 +627,10 @@ axios(config) console.log(error); }); """; - expect(axiosCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/nodejs_fetch_codegen_test.dart b/test/codegen/nodejs_fetch_codegen_test.dart index 0c98ac35..831fd2e0 100644 --- a/test/codegen/nodejs_fetch_codegen_test.dart +++ b/test/codegen/nodejs_fetch_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/js/fetch.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final fetchCodeGen = FetchCodeGen(isNodeJs: true); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -30,7 +31,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -57,7 +61,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -84,7 +91,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -111,7 +121,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -141,7 +154,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -171,7 +187,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -198,7 +217,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -228,7 +250,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -255,7 +280,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -286,7 +314,8 @@ fetch(url, options) }); """; expect( - fetchCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet10, "https", ), @@ -320,7 +349,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -347,7 +379,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelGet12, "https"), + expectedCode); }); }); @@ -376,7 +411,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -403,7 +441,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelHead2, "http"), + expectedCode); }); }); @@ -437,7 +478,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -469,7 +513,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -502,7 +549,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost3, "https"), + expectedCode); }); }); @@ -536,7 +586,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPut1, "https"), + expectedCode); }); }); @@ -570,7 +623,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPatch1, "https"), + expectedCode); }); }); @@ -599,7 +655,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -631,7 +690,10 @@ fetch(url, options) console.error('error:' + err); }); """; - expect(fetchCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelDelete2, "https"), + expectedCode); }); }); } diff --git a/test/codegen/python_http_client_codegen_test.dart b/test/codegen/python_http_client_codegen_test.dart index 0665e186..b5774809 100644 --- a/test/codegen/python_http_client_codegen_test.dart +++ b/test/codegen/python_http_client_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/python/http_client.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final pythonHttpClientCodeGen = PythonHttpClientCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -17,7 +18,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet1, "https"), expectedCode); }); @@ -38,7 +41,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet2, "https"), expectedCode); }); @@ -59,7 +64,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet3, "https"), expectedCode); }); @@ -84,7 +91,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet4, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet4, "https"), expectedCode); }); @@ -104,7 +113,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet5, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet5, "https"), expectedCode); }); @@ -130,7 +141,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet6, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet6, "https"), expectedCode); }); @@ -145,7 +158,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet7, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet7, "https"), expectedCode); }); @@ -171,7 +186,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet8, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet8, "https"), expectedCode); }); @@ -193,7 +210,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet9, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet9, "https"), expectedCode); }); @@ -214,7 +233,8 @@ data = res.read() print(data.decode("utf-8")) """; expect( - pythonHttpClientCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet10, "https", ), @@ -244,7 +264,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet11, "https"), expectedCode); }); @@ -259,7 +281,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelGet12, "https"), expectedCode); }); }); @@ -276,7 +300,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelHead1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelHead1, "https"), expectedCode); }); @@ -291,7 +317,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelHead2, "http"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelHead2, "http"), expectedCode); }); }); @@ -318,7 +346,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost1, "https"), expectedCode); }); @@ -348,7 +378,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost2, "https"), expectedCode); }); @@ -374,7 +406,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost3, "https"), expectedCode); }); }); @@ -402,7 +436,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPut1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPut1, "https"), expectedCode); }); }); @@ -430,7 +466,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPatch1, "https"), expectedCode); }); }); @@ -447,7 +485,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelDelete1, "https"), expectedCode); }); @@ -473,7 +513,9 @@ data = res.read() print(data.decode("utf-8")) """; - expect(pythonHttpClientCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelDelete2, "https"), expectedCode); }); }); diff --git a/test/codegen/python_requests_codegen_test.dart b/test/codegen/python_requests_codegen_test.dart index babe65d6..057c09c6 100644 --- a/test/codegen/python_requests_codegen_test.dart +++ b/test/codegen/python_requests_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/python/requests.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final pythonRequestsCodeGen = PythonRequestsCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -16,7 +17,9 @@ response = requests.get(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet1, "https"), expectedCode); }); @@ -34,7 +37,9 @@ response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet2, "https"), expectedCode); }); @@ -52,7 +57,9 @@ response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet3, "https"), expectedCode); }); @@ -74,7 +81,9 @@ response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet4, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet4, "https"), expectedCode); }); @@ -92,7 +101,9 @@ response = requests.get(url, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet5, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet5, "https"), expectedCode); }); @@ -114,7 +125,9 @@ response = requests.get(url, params=params, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet6, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet6, "https"), expectedCode); }); @@ -128,7 +141,9 @@ response = requests.get(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet7, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet7, "https"), expectedCode); }); @@ -150,7 +165,9 @@ response = requests.get(url, params=params, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet8, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet8, "https"), expectedCode); }); @@ -169,7 +186,9 @@ response = requests.get(url, params=params) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet9, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet9, "https"), expectedCode); }); @@ -188,7 +207,8 @@ print('Status Code:', response.status_code) print('Response Body:', response.text) """; expect( - pythonRequestsCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet10, "https", ), @@ -214,7 +234,9 @@ response = requests.get(url, params=params, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet11, "https"), expectedCode); }); @@ -228,7 +250,9 @@ response = requests.get(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelGet12, "https"), expectedCode); }); }); @@ -244,7 +268,9 @@ response = requests.head(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelHead1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelHead1, "https"), expectedCode); }); @@ -258,7 +284,9 @@ response = requests.head(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelHead2, "http"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelHead2, "http"), expectedCode); }); }); @@ -282,7 +310,9 @@ response = requests.post(url, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost1, "https"), expectedCode); }); @@ -305,7 +335,9 @@ response = requests.post(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost2, "https"), expectedCode); }); @@ -327,7 +359,9 @@ response = requests.post(url, json=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost3, "https"), expectedCode); }); @@ -352,7 +386,9 @@ response = requests.post(url, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost4, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost4, "https"), expectedCode); }); @@ -378,7 +414,9 @@ response = requests.post(url, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost5, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost5, "https"), expectedCode); }); @@ -402,7 +440,9 @@ response = requests.post(url, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost6, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost6, "https"), expectedCode); }); @@ -426,7 +466,9 @@ response = requests.post(url, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost7, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost7, "https"), expectedCode); }); @@ -456,7 +498,9 @@ response = requests.post(url, params=params, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost8, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost8, "https"), expectedCode); }); @@ -487,7 +531,9 @@ response = requests.post(url, params=params, data=payload, headers=headers) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPost9, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost9, "https"), expectedCode); }); }); @@ -508,7 +554,9 @@ response = requests.put(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPut1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPut1, "https"), expectedCode); }); }); @@ -529,7 +577,9 @@ response = requests.patch(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPatch1, "https"), expectedCode); }); }); @@ -545,7 +595,9 @@ response = requests.delete(url) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelDelete1, "https"), expectedCode); }); @@ -564,7 +616,9 @@ response = requests.delete(url, json=payload) print('Status Code:', response.status_code) print('Response Body:', response.text) """; - expect(pythonRequestsCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelDelete2, "https"), expectedCode); }); }); From 11a38fcb541fc2b1a3d4f237a9456c876e728f8a Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 05:19:37 +0530 Subject: [PATCH 48/91] Add default uri --- lib/consts.dart | 11 ++++++++--- lib/screens/settings_page.dart | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/consts.dart b/lib/consts.dart index d7c2689c..40f51633 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -8,6 +8,7 @@ import 'package:davi/davi.dart'; const kDiscordUrl = "https://bit.ly/heyfoss"; const kGitUrl = "https://github.com/foss42/apidash"; const kIssueUrl = "$kGitUrl/issues"; +const kDefaultUri = "api.apidash.dev"; final kIsMacOS = !kIsWeb && Platform.isMacOS; final kIsWindows = !kIsWeb && Platform.isWindows; @@ -282,6 +283,8 @@ enum CodegenLanguage { const JsonEncoder kEncoder = JsonEncoder.withIndent(' '); const LineSplitter kSplitter = LineSplitter(); +const kHeaderContentType = "Content-Type"; + const kTypeApplication = 'application'; // application const kSubTypeJson = 'json'; @@ -312,12 +315,15 @@ const kSubTypeSvg = 'svg+xml'; const kTypeAudio = 'audio'; const kTypeVideo = 'video'; +const kTypeMultipart = "multipart"; +const kSubTypeFormData = "form-data"; + const kSubTypeDefaultViewOptions = 'all'; enum ContentType { json("$kTypeApplication/$kSubTypeJson"), text("$kTypeText/$kSubTypePlain"), - formdata("multipart/form-data"); + formdata("$kTypeMultipart/$kSubTypeFormData"); const ContentType(this.header); final String header; @@ -499,8 +505,7 @@ const kRaiseIssue = const kCsvError = "There seems to be an issue rendering this CSV. Please raise an issue in API Dash GitHub repo so that we can resolve it."; -const kHintTextUrlCard = - "Enter API endpoint like api.apidash.dev/country/codes"; +const kHintTextUrlCard = "Enter API endpoint like https://$kDefaultUri/"; const kLabelPlusNew = "+ New"; const kLabelSend = "Send"; const kLabelSending = "Sending.."; diff --git a/lib/screens/settings_page.dart b/lib/screens/settings_page.dart index 44e67330..fde7dce7 100644 --- a/lib/screens/settings_page.dart +++ b/lib/screens/settings_page.dart @@ -65,7 +65,7 @@ class SettingsPage extends ConsumerWidget { hoverColor: kColorTransparent, title: const Text('Default URI Scheme'), subtitle: Text( - 'api.apidash.dev → ${settings.defaultUriScheme}://api.apidash.dev'), + '$kDefaultUri → ${settings.defaultUriScheme}://$kDefaultUri'), trailing: DropdownMenu( onSelected: (value) { ref From e4f0633eca28e8426cbaf46b4ca9039c7a8bd2e9 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 05:20:15 +0530 Subject: [PATCH 49/91] Update curl.dart --- lib/codegen/others/curl.dart | 50 +++++++++++++++--------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/lib/codegen/others/curl.dart b/lib/codegen/others/curl.dart index 6c0e02fc..2ba59765 100644 --- a/lib/codegen/others/curl.dart +++ b/lib/codegen/others/curl.dart @@ -21,18 +21,14 @@ class cURLCodeGen { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = requestModelToHARJsonRequest( + requestModel, + useEnabled: true, + ); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ @@ -47,37 +43,31 @@ class cURLCodeGen { var headers = harJson["headers"]; if (headers.isNotEmpty) { for (var item in headers) { + if (requestModel.hasFormData && item["name"] == kHeaderContentType) { + continue; + } var templateHeader = jj.Template(kTemplateHeader); result += templateHeader .render({"name": item["name"], "value": item["value"]}); } } - var method = requestModel.method; - if (kMethodsWithBody.contains(method)) { - if (harJson['formData'] != null) { - var formDataList = harJson['formData'] as List>; - for (var formData in formDataList) { - var templateFormData = jj.Template(kTemplateFormData); - if (formData['type'] != null && - formData['name'] != null && - formData['value'] != null && - formData['name']!.isNotEmpty && - formData['value']!.isNotEmpty) { - result += templateFormData.render({ - "name": formData["name"], - "value": - "${formData['type'] == 'file' ? '@' : ''}${formData["value"]}", - }); - } + if (requestModel.hasJsonData || requestModel.hasTextData) { + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestModel.requestBody}); + } else if (requestModel.hasFormData) { + for (var formData in requestModel.formDataList) { + var templateFormData = jj.Template(kTemplateFormData); + if (formData.name.isNotEmpty && formData.value.isNotEmpty) { + result += templateFormData.render({ + "name": formData.name, + "value": + "${formData.type == FormDataType.file ? '@' : ''}${formData.value}", + }); } } - - if (harJson["postData"]?["text"] != null) { - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": harJson["postData"]["text"]}); - } } + return result; } catch (e) { return null; From 67fcc66aa2f8aa3a00f24202c76cf8466fca960b Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 05:23:27 +0530 Subject: [PATCH 50/91] Update HAR codegen --- lib/utils/har_utils.dart | 61 ++++-- test/codegen/har_codegen_test.dart | 306 ++++++++++++++++++++++++++--- 2 files changed, 321 insertions(+), 46 deletions(-) diff --git a/lib/utils/har_utils.dart b/lib/utils/har_utils.dart index b5e1de72..86ada7fe 100644 --- a/lib/utils/har_utils.dart +++ b/lib/utils/har_utils.dart @@ -1,6 +1,10 @@ +// http://www.softwareishard.com/blog/har-12-spec/ +// https://github.com/ahmadnassri/har-spec/blob/master/versions/1.2.md + import 'dart:convert'; import 'package:apidash/consts.dart'; -import 'package:apidash/utils/utils.dart' show getValidRequestUri; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, getNewUuid, getFilenameFromPath; import 'package:apidash/models/models.dart' show RequestModel; import 'package:package_info_plus/package_info_plus.dart'; @@ -75,6 +79,7 @@ Map requestModelToHARJsonRequest( defaultUriScheme = kDefaultUriScheme, bool exportMode = false, bool useEnabled = false, + String? boundary, }) { Map json = {}; bool hasBody = false; @@ -110,21 +115,37 @@ Map requestModelToHARJsonRequest( } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && - requestBody != null && - !requestModel.isFormDataRequest) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - hasBody = true; - json["postData"] = {}; - json["postData"]["mimeType"] = - requestModel.requestBodyContentType.header; - json["postData"]["text"] = requestBody; - if (exportMode) { - json["postData"]["comment"] = ""; + if (requestModel.hasJsonData || requestModel.hasTextData) { + hasBody = true; + json["postData"] = {}; + json["postData"]["mimeType"] = requestModel.requestBodyContentType.header; + json["postData"]["text"] = requestModel.requestBody; + if (exportMode) { + json["postData"]["comment"] = ""; + } + } + + if (requestModel.hasFormData) { + boundary = boundary ?? getNewUuid(); + hasBody = true; + json["postData"] = {}; + json["postData"]["mimeType"] = + "${requestModel.requestBodyContentType.header}; boundary=$boundary"; + json["postData"]["params"] = []; + for (var item in requestModel.formDataList) { + Map d = exportMode ? {"comment": ""} : {}; + if (item.type == FormDataType.text) { + d["name"] = item.name; + d["value"] = item.value; } + if (item.type == FormDataType.file) { + d["name"] = item.name; + d["fileName"] = getFilenameFromPath(item.value); + } + json["postData"]["params"].add(d); + } + if (exportMode) { + json["postData"]["comment"] = ""; } } @@ -137,8 +158,8 @@ Map requestModelToHARJsonRequest( if (headers.isNotEmpty || hasBody) { if (hasBody && !requestModel.hasContentTypeHeader) { var m = { - "name": "Content-Type", - "value": requestModel.requestBodyContentType.header + "name": kHeaderContentType, + "value": json["postData"]["mimeType"] }; if (exportMode) { m["comment"] = ""; @@ -154,14 +175,12 @@ Map requestModelToHARJsonRequest( } } } - if (requestModel.isFormDataRequest) { - json["formData"] = requestModel.formDataMapList; - } if (exportMode) { json["comment"] = ""; json["cookies"] = []; json["headersSize"] = -1; - json["bodySize"] = hasBody ? utf8.encode(requestBody!).length : 0; + json["bodySize"] = + hasBody ? utf8.encode(json["postData"]["text"] ?? "").length : 0; } } return json; diff --git a/test/codegen/har_codegen_test.dart b/test/codegen/har_codegen_test.dart index ea40bf93..767afc98 100644 --- a/test/codegen/har_codegen_test.dart +++ b/test/codegen/har_codegen_test.dart @@ -1,9 +1,10 @@ -import 'package:apidash/codegen/others/har.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final harCodeGen = HARCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -14,7 +15,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -30,7 +32,8 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -46,7 +49,8 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -78,7 +82,8 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -94,7 +99,8 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -115,7 +121,8 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -126,7 +133,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -147,7 +155,8 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -167,7 +176,8 @@ void main() { ], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -184,7 +194,8 @@ void main() { ] }"""; expect( - harCodeGen.getCode( + codeGen.getCode( + CodegenLanguage.har, requestModelGet10, "https", ), @@ -213,7 +224,8 @@ void main() { } ] }"""; - expect(harCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -224,7 +236,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelGet12, "https"), + expectedCode); }); }); @@ -237,7 +250,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -248,7 +262,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelHead2, "http"), + expectedCode); }); }); @@ -270,7 +285,8 @@ void main() { "text": "{\n\"text\": \"I LOVE Flutter\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -287,10 +303,11 @@ void main() { ], "postData": { "mimeType": "application/json", - "text": "{\n\"text\": \"I LOVE Flutter\"\n}" + "text": "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" } }"""; - expect(harCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -314,7 +331,242 @@ void main() { "text": "{\n\"text\": \"I LOVE Flutter\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPost3, "https"), + expectedCode); + }); + + test('POST 4', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/form", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=d43e2510-a25e-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=d43e2510-a25e-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "text", + "value": "API" + }, + { + "name": "sep", + "value": "|" + }, + { + "name": "times", + "value": "3" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost4, "https", + boundary: "d43e2510-a25e-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/form", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=ce268b20-a3e6-1f08-b0a5-591aeb704467" + }, + { + "name": "User-Agent", + "value": "Test Agent" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=ce268b20-a3e6-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "text", + "value": "API" + }, + { + "name": "sep", + "value": "|" + }, + { + "name": "times", + "value": "3" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost5, "https", + boundary: "ce268b20-a3e6-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/img", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=c90d21a0-a44d-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=c90d21a0-a44d-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "token", + "value": "xyz" + }, + { + "name": "imfile", + "fileName": "1.png" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost6, "https", + boundary: "c90d21a0-a44d-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/img", + "httpVersion": "HTTP/1.1", + "queryString": [], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=4ac86770-a4dc-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=4ac86770-a4dc-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "token", + "value": "xyz" + }, + { + "name": "imfile", + "fileName": "1.png" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost7, "https", + boundary: "4ac86770-a4dc-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/form?size=2&len=3", + "httpVersion": "HTTP/1.1", + "queryString": [ + { + "name": "size", + "value": "2" + }, + { + "name": "len", + "value": "3" + } + ], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=78403a20-a54a-1f08-b0a5-591aeb704467" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=78403a20-a54a-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "text", + "value": "API" + }, + { + "name": "sep", + "value": "|" + }, + { + "name": "times", + "value": "3" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost8, "https", + boundary: "78403a20-a54a-1f08-b0a5-591aeb704467"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""{ + "method": "POST", + "url": "https://api.apidash.dev/io/img?size=2&len=3", + "httpVersion": "HTTP/1.1", + "queryString": [ + { + "name": "size", + "value": "2" + }, + { + "name": "len", + "value": "3" + } + ], + "headers": [ + { + "name": "Content-Type", + "value": "multipart/form-data; boundary=2d9cd390-a593-1f08-b0a5-591aeb704467" + }, + { + "name": "User-Agent", + "value": "Test Agent" + }, + { + "name": "Keep-Alive", + "value": "true" + } + ], + "postData": { + "mimeType": "multipart/form-data; boundary=2d9cd390-a593-1f08-b0a5-591aeb704467", + "params": [ + { + "name": "token", + "value": "xyz" + }, + { + "name": "imfile", + "fileName": "1.png" + } + ] + } +}"""; + expect( + codeGen.getCode(CodegenLanguage.har, requestModelPost9, "https", + boundary: "2d9cd390-a593-1f08-b0a5-591aeb704467"), + expectedCode); }); }); @@ -336,7 +588,8 @@ void main() { "text": "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPut1, "https"), + expectedCode); }); }); @@ -358,7 +611,8 @@ void main() { "text": "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelPatch1, "https"), + expectedCode); }); }); @@ -371,7 +625,8 @@ void main() { "queryString": [], "headers": [] }"""; - expect(harCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -391,7 +646,8 @@ void main() { "text": "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" } }"""; - expect(harCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.har, requestModelDelete2, "https"), + expectedCode); }); }); } From 897160f388d52f7225edc60a7f6cfe5465e2ad1f Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Tue, 12 Mar 2024 12:04:07 +0530 Subject: [PATCH 51/91] Removed as it is not required after refactoring --- test/codegen/codegen_test.dart | 239 --------------------------------- 1 file changed, 239 deletions(-) delete mode 100644 test/codegen/codegen_test.dart diff --git a/test/codegen/codegen_test.dart b/test/codegen/codegen_test.dart deleted file mode 100644 index 2e5b58a6..00000000 --- a/test/codegen/codegen_test.dart +++ /dev/null @@ -1,239 +0,0 @@ -import 'package:apidash/codegen/codegen.dart'; -import 'package:apidash/consts.dart'; -import '../request_models.dart'; -import 'package:test/test.dart'; - -void main() { - final codeGen = Codegen(); - - group('Test various Code generators', () { - test('cURL', () { - const expectedCode = r"""curl --url 'https://api.apidash.dev'"""; - expect(codeGen.getCode(CodegenLanguage.curl, requestModelGet1, "https"), - expectedCode); - }); - - test('Dart Dio', () { - const expectedCode = r"""import 'package:dio/dio.dart' as dio; - -void main() async { - try { - final response = await dio.Dio.get('https://api.apidash.dev'); - print(response.statusCode); - print(response.data); - } on DioException catch (e, s) { - print(e.response?.statusCode); - print(e.response?.data); - print(s); - } catch (e, s) { - print(e); - print(s); - } -} -"""; - expect( - codeGen.getCode(CodegenLanguage.dartDio, requestModelGet1, "https"), - expectedCode); - }); - - test('Dart HTTP', () { - const expectedCode = r"""import 'package:http/http.dart' as http; - -void main() async { - var uri = Uri.parse('https://api.apidash.dev'); - - final response = await http.get(uri); - - int statusCode = response.statusCode; - if (statusCode >= 200 && statusCode < 300) { - print('Status Code: $statusCode'); - print('Response Body: ${response.body}'); - } else { - print('Error Status Code: $statusCode'); - print('Error Response Body: ${response.body}'); - } -} -"""; - expect( - codeGen.getCode(CodegenLanguage.dartHttp, requestModelGet1, "https"), - expectedCode); - }); - - test('HAR', () { - const expectedCode = r"""{ - "method": "GET", - "url": "https://api.apidash.dev", - "httpVersion": "HTTP/1.1", - "queryString": [], - "headers": [] -}"""; - expect(codeGen.getCode(CodegenLanguage.har, requestModelGet1, "https"), - expectedCode); - }); - - test('JS Axios', () { - const expectedCode = r"""let config = { - url: 'https://api.apidash.dev', - method: 'get' -}; - -axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); -"""; - expect( - codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet1, "https"), - expectedCode); - }); - - test('JS Fetch', () { - const expectedCode = r"""let url = 'https://api.apidash.dev'; - -let options = { - method: 'GET' -}; - -let status; -fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); -"""; - expect( - codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet1, "https"), - expectedCode); - }); - - test('Kotlin OkHttp', () { - const expectedCode = r"""import okhttp3.OkHttpClient -import okhttp3.Request - -fun main() { - val client = OkHttpClient() - - val url = "https://api.apidash.dev" - - val request = Request.Builder() - .url(url) - .get() - .build() - - val response = client.newCall(request).execute() - - println(response.code) - println(response.body?.string()) -} -"""; - expect( - codeGen.getCode( - CodegenLanguage.kotlinOkHttp, requestModelGet1, "https"), - expectedCode); - }); - - test('NodeJs Axios', () { - const expectedCode = r"""import axios from 'axios'; - -let config = { - url: 'https://api.apidash.dev', - method: 'get' -}; - -axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); -"""; - expect( - codeGen.getCode( - CodegenLanguage.nodejsAxios, requestModelGet1, "https"), - expectedCode); - }); - - test('Nodejs Fetch', () { - const expectedCode = r"""import fetch from 'node-fetch'; - -let url = 'https://api.apidash.dev'; - -let options = { - method: 'GET' -}; - -let status; -fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); -"""; - expect( - codeGen.getCode( - CodegenLanguage.nodejsFetch, requestModelGet1, "https"), - expectedCode); - }); - - test('Python http.client', () { - const expectedCode = r"""import http.client - -conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("GET", "") - -res = conn.getresponse() -data = res.read() - -print(data.decode("utf-8")) -"""; - expect( - codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelGet1, "https"), - expectedCode); - }); - - test('Python requests', () { - const expectedCode = r"""import requests - -url = 'https://api.apidash.dev' - -response = requests.get(url) - -print('Status Code:', response.status_code) -print('Response Body:', response.text) -"""; - expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelGet1, "https"), - expectedCode); - }); - }); -} From 6c2dc7540b65d678b72221d7ccf18a9d437f4f52 Mon Sep 17 00:00:00 2001 From: Apoorv Dwivedi Date: Tue, 12 Mar 2024 12:33:36 +0530 Subject: [PATCH 52/91] Refactored go http codegen and test file --- lib/codegen/go/http.dart | 8 +- test/codegen/go_http_codegen_test.dart | 105 ++++++++++++++++++------- 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart index 48882710..0b7b2a6c 100644 --- a/lib/codegen/go/http.dart +++ b/lib/codegen/go/http.dart @@ -112,7 +112,6 @@ func main() { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; @@ -120,15 +119,12 @@ func main() { var requestBody = requestModel.requestBody; String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ "isBody": kMethodsWithBody.contains(requestModel.method) && requestBody != null, - "isFormDataRequest": requestModel.isFormDataRequest + "isFormDataRequest": requestModel.hasFormData, }); var templateUrl = jj.Template(kTemplateUrl); @@ -155,7 +151,7 @@ func main() { } else if (requestModel.requestBodyContentType == ContentType.json) { var templateJsonBody = jj.Template(kTemplateJsonBody); result += templateJsonBody.render({"body": requestBody}); - } else if (requestModel.isFormDataRequest) { + } else if (requestModel.hasFormData) { hasBody = true; var templateFormData = jj.Template(kTemplateFormData); result += templateFormData.render({ diff --git a/test/codegen/go_http_codegen_test.dart b/test/codegen/go_http_codegen_test.dart index f056cb38..7e59dd70 100644 --- a/test/codegen/go_http_codegen_test.dart +++ b/test/codegen/go_http_codegen_test.dart @@ -1,9 +1,11 @@ -import 'package:apidash/codegen/go/http.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; +import 'package:apidash/screens/home_page/editor_pane/details_card/code_pane.dart'; import 'package:test/test.dart'; import '../request_models.dart'; void main() { - final goHttpCodeGen = GoHttpCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { @@ -43,7 +45,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet1, "https"), + expectedCode); }); test('GET 2', () { @@ -88,7 +91,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet2, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet2, "https"), + expectedCode); }); test('GET 3', () { @@ -133,7 +137,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet3, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet3, "https"), + expectedCode); }); test('GET 4', () { @@ -186,7 +191,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet4, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet4, "https"), + expectedCode); }); test('GET 5', () { @@ -229,7 +235,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet5, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet5, "https"), + expectedCode); }); test('GET 6', () { @@ -277,7 +284,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet6, "https"), + expectedCode); }); test('GET 7', () { @@ -317,7 +325,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet7, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet7, "https"), + expectedCode); }); test('GET 8', () { @@ -365,7 +374,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet8, "https"), + expectedCode); }); test('GET 9', () { @@ -412,7 +422,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet9, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet9, "https"), + expectedCode); }); test('GET 10', () { @@ -456,7 +467,8 @@ func main() { fmt.Println(string(res)) }"""; expect( - goHttpCodeGen.getCode( + codegen.getCode( + CodegenLanguage.goHttp, requestModelGet10, "https", ), @@ -510,7 +522,9 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet11, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelGet11, "https"), + expectedCode); }); test('GET 12', () { @@ -550,7 +564,9 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelGet12, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelGet12, "https"), + expectedCode); }); }); @@ -592,7 +608,9 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelHead1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelHead1, "https"), + expectedCode); }); test('HEAD 2', () { @@ -632,7 +650,8 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelHead2, "http"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelHead2, "http"), + expectedCode); }); }); @@ -678,7 +697,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost1, "https"), + expectedCode); }); test('POST 2', () { @@ -701,7 +722,12 @@ func main() { return } body := bytes.NewBuffer([]byte(`{ -"text": "I LOVE Flutter" +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] }`)) req, err := http.NewRequest("POST", url.String(), body) if err != nil { @@ -722,7 +748,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost2, "https"), + expectedCode); }); test('POST 3', () { @@ -769,7 +797,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost3, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost3, "https"), + expectedCode); }); test('POST 4', () { @@ -809,7 +839,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost4, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost4, "https"), + expectedCode); }); test('POST 5', () { @@ -852,7 +884,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost5, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPost5, "https"), + expectedCode); }); }); @@ -893,7 +927,8 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost6, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost6, "https"), + expectedCode); }); test("POST 7", () { const expectedCode = r'''package main @@ -958,7 +993,8 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost7, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost7, "https"), + expectedCode); }); test("POST 8", () { const expectedCode = r'''package main @@ -1004,7 +1040,8 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost8, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost8, "https"), + expectedCode); }); test("POST 9", () { const expectedCode = r'''package main @@ -1081,7 +1118,8 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPost9, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost9, "https"), + expectedCode); }); group('PUT Request', () { @@ -1127,7 +1165,8 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPut1, "https"), expectedCode); + expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPut1, "https"), + expectedCode); }); }); @@ -1174,7 +1213,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelPatch1, "https"), + expectedCode); }); }); @@ -1216,7 +1257,9 @@ func main() { } fmt.Println(string(res)) }"""; - expect(goHttpCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelDelete1, "https"), + expectedCode); }); test('DELETE 2', () { @@ -1261,7 +1304,9 @@ func main() { } fmt.Println(string(res)) }'''; - expect(goHttpCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + expect( + codeGen.getCode(CodegenLanguage.goHttp, requestModelDelete2, "https"), + expectedCode); }); }); } From cdc86b57fb7a6c08bc33498055dd1e180d416da4 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Tue, 12 Mar 2024 18:06:03 +0530 Subject: [PATCH 53/91] test(rust_actix_codegen): add multipart tests --- lib/codegen/rust/actix.dart | 11 +- test/codegen/rust_actix_codegen_test.dart | 483 ++++++++++++++++++++++ 2 files changed, 489 insertions(+), 5 deletions(-) diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index bf617e55..4e13b0f1 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -53,11 +53,11 @@ multipart/form-data; boundary={{boundary}}'''; } let form_data_items: Vec = vec![ - {%- for formitem in fields_list %} + {%- for formitem in fields_list %} FormDataItem { {%- for key, val in formitem %} {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} - {%- endfor %} + {%- endfor %} }, {%- endfor %} ]; @@ -116,6 +116,7 @@ multipart/form-data; boundary={{boundary}}'''; String? boundary, }) { try { + String uuid = getNewUuid(); String result = ""; bool hasBody = false; bool hasJsonBody = false; @@ -157,7 +158,7 @@ multipart/form-data; boundary={{boundary}}'''; result += formDataBodyData.render( { "fields_list": requestModel.formDataMapList, - "boundary": boundary ?? getNewUuid(), + "boundary": boundary ?? uuid, }, ); } @@ -179,13 +180,13 @@ multipart/form-data; boundary={{boundary}}'''; } var headersList = requestModel.enabledRequestHeaders; - if (headersList != null || hasBody || requestModel.hasTextData) { + if (headersList != null || hasBody || requestModel.hasFormData) { var headers = requestModel.enabledHeadersMap; if (requestModel.hasFormData) { var formHeaderTemplate = jj.Template(kTemplateFormHeaderContentType); headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": boundary ?? getNewUuid(), + "boundary": boundary ?? uuid, }); } else if (hasBody) { headers[HttpHeaders.contentTypeHeader] = diff --git a/test/codegen/rust_actix_codegen_test.dart b/test/codegen/rust_actix_codegen_test.dart index 904f0b57..8e215295 100644 --- a/test/codegen/rust_actix_codegen_test.dart +++ b/test/codegen/rust_actix_codegen_test.dart @@ -483,6 +483,489 @@ async fn main() -> Result<(), Box> { CodegenLanguage.rustActix, requestModelPost3, "https"), expectedCode); }); + + test('POST 4', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/form"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustActix, + requestModelPost4, + "https", + boundary: "test", + ), + expectedCode); + }); + test('POST 5', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/form"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("User-Agent", "Test Agent")) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/img"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/img"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/form"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .unwrap() + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""use std::io::Read; +#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.apidash.dev/io/img"; + let client = awc::Client::default(); + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let mut response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .insert_header(("Keep-Alive", "true")) + .insert_header(("content-type", "multipart/form-data; boundary=test")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustActix, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); }); group('PUT Request', () { From c06c0fc2e8a57ef31799e1d8a624ad172ef808d1 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Tue, 12 Mar 2024 18:30:53 +0530 Subject: [PATCH 54/91] test(rust_ureq_codegen): add multipart tests --- test/codegen/rust_ureq_codegen_test.dart | 435 +++++++++++++++++++++++ 1 file changed, 435 insertions(+) diff --git a/test/codegen/rust_ureq_codegen_test.dart b/test/codegen/rust_ureq_codegen_test.dart index 740ba867..b6985f3f 100644 --- a/test/codegen/rust_ureq_codegen_test.dart +++ b/test/codegen/rust_ureq_codegen_test.dart @@ -340,6 +340,441 @@ void main() { codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost3, "https"), expectedCode); }); + + test('POST 4', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/form"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustUreq, + requestModelPost4, + "https", + boundary: "test", + ), + expectedCode); + }); + test('POST 5', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/form"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("User-Agent", "Test Agent") + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/img"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/img"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/form"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .query("size", "2") + .query("len", "3") + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""use std::io::Read; +fn main() -> Result<(), ureq::Error> { + let url = "https://api.apidash.dev/io/img"; + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + fn build_data_list(fields: Vec) -> Vec { + let mut data_list = Vec::new(); + + for field in fields { + data_list.extend_from_slice(b"--test\r\n"); + + if field.field_type == "text" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); + data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); + data_list.extend_from_slice(field.value.as_bytes()); + data_list.extend_from_slice(b"\r\n"); + } else if field.field_type == "file" { + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); + + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + + let mut file = std::fs::File::open(&field.value).unwrap(); + let mut file_contents = Vec::new(); + file.read_to_end(&mut file_contents).unwrap(); + data_list.extend_from_slice(&file_contents); + data_list.extend_from_slice(b"\r\n"); + } + } + + data_list.extend_from_slice(b"--test--\r\n"); + data_list + } + + let payload = build_data_list(form_data_items); + let response = ureq::post(url) + .query("size", "2") + .query("len", "3") + .set("User-Agent", "Test Agent") + .set("Keep-Alive", "true") + .set("content-type", "multipart/form-data; boundary=test") + .send_bytes(&payload)?; + + println!("Response Status: {}", response.status()); + println!("Response: {}", response.into_string()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode(CodegenLanguage.rustUreq, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); }); group('PUT Request', () { From 351b79d78f7b174497bbfb2bc781a444c05c54a8 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Tue, 12 Mar 2024 18:44:20 +0530 Subject: [PATCH 55/91] test(rust_reqwest_codegen): add multipart tests --- test/codegen/rust_reqwest_codegen_test.dart | 329 ++++++++++++++++++++ 1 file changed, 329 insertions(+) diff --git a/test/codegen/rust_reqwest_codegen_test.dart b/test/codegen/rust_reqwest_codegen_test.dart index 089ca510..c262a64e 100644 --- a/test/codegen/rust_reqwest_codegen_test.dart +++ b/test/codegen/rust_reqwest_codegen_test.dart @@ -421,6 +421,335 @@ void main() { CodegenLanguage.rustReqwest, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/form"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, + requestModelPost4, + "https", + boundary: "test", + ), + expectedCode); + }); + test('POST 5', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/form"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .header("User-Agent", "Test Agent") + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/img"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/img"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/form"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "text".to_string(), + value: "API".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "sep".to_string(), + value: "|".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "times".to_string(), + value: "3".to_string(), + field_type: "text".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = + r"""fn main() -> Result<(), Box> { + let client = reqwest::blocking::Client::new(); + let url = "https://api.apidash.dev/io/img"; + + struct FormDataItem { + name: String, + value: String, + field_type: String, + } + + let form_data_items: Vec = vec![ + FormDataItem { + name: "token".to_string(), + value: "xyz".to_string(), + field_type: "text".to_string(), + }, + FormDataItem { + name: "imfile".to_string(), + value: "/Documents/up/1.png".to_string(), + field_type: "file".to_string(), + }, + ]; + + let mut form = reqwest::blocking::multipart::Form::new(); + + for item in form_data_items { + if item.field_type == "text" { + form = form.text(item.name, item.value); + } else if item.field_type == "file" { + form = form.file(item.name, &item.value)?; + } + } + let response = client + .post(url) + .query(&[("size", "2"), ("len", "3")]) + .header("User-Agent", "Test Agent") + .header("Keep-Alive", "true") + .multipart(form) + .send()?; + + println!("Status Code: {}", response.status()); + println!("Response Body: {}", response.text()?); + + Ok(()) +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.rustReqwest, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); }); group('PUT Request', () { From 493ead5212345562a42659ddf1f6e2ad2beb7aec Mon Sep 17 00:00:00 2001 From: Ashita Prasad Date: Tue, 12 Mar 2024 20:08:15 +0530 Subject: [PATCH 56/91] golang fixes and updates --- lib/codegen/go/http.dart | 134 ++-- lib/models/request_model.dart | 4 + test/codegen/go_http_codegen_test.dart | 867 +++++++++---------------- 3 files changed, 362 insertions(+), 643 deletions(-) diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart index 0b7b2a6c..4bdecf48 100644 --- a/lib/codegen/go/http.dart +++ b/lib/codegen/go/http.dart @@ -1,9 +1,7 @@ -import 'dart:convert'; - +import 'package:apidash/consts.dart'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show getValidRequestUri; import 'package:apidash/models/models.dart' show RequestModel; -import 'package:apidash/consts.dart'; class GoHttpCodeGen { final String kTemplateStart = """package main @@ -12,10 +10,10 @@ import ( "fmt" "io" "net/http" - "net/url" - {% if isBody %}"bytes" - {% if isFormDataRequest %}"mime/multipart" - "os"{% endif %}{% endif %} + "net/url"{% if hasBody %} + "bytes"{% if hasFormData %} + "mime/multipart"{% if hasFileInFormData %} + "os"{% endif %}{% endif %}{% endif %} ) func main() { @@ -24,44 +22,26 @@ func main() { """; String kTemplateUrl = """ - url, err := url.Parse("{{url}}") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("{{url}}") """; - String kTemplateRawBody = """ - {% if body %}body := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} - -"""; - - String kTemplateJsonBody = """ - {% if body %}body := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} + String kTemplateBody = """ + {% if body %}payload := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} """; String kTemplateFormData = """ - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload){% if hasFileInFormData %} var ( file *os.File part io.Writer - ) + ){% endif %} {% for field in fields %} - {% if field.type == "file" %}file, err = os.Open("{{field.value}}") - if err != nil { - fmt.Println(err) - return - } + {% if field.type == "file" %}file, _ = os.Open("{{field.value}}") defer file.Close() - - part, err = writer.CreateFormFile("{{field.name}}", "{{field.value}}") - if err != nil { - fmt.Println(err) - return - } + part, _ = writer.CreateFormFile("{{field.name}}", "{{field.value}}") io.Copy(part, file) {% else %}writer.WriteField("{{field.name}}", "{{field.value}}"){% endif %}{% endfor %} writer.Close() @@ -71,43 +51,40 @@ func main() { String kTemplateHeader = """ {% if headers %}{% for header, value in headers %} - req.Header.Set("{{header}}", "{{value}}") -{% endfor %} + req.Header.Set("{{header}}", "{{value}}"){% endfor %} {% endif %} """; + String kStringFormDataHeader = """ + req.Header.Set("Content-Type", writer.FormDataContentType()) +"""; + String kTemplateQueryParam = """ query := url.Query() {% for key, value in params %} - query.Set("{{key}}", "{{value}}") - {% endfor %} + query.Set("{{key}}", "{{value}}"){% endfor %} + url.RawQuery = query.Encode() """; String kTemplateRequest = """ - req, err := http.NewRequest("{{method}}", url.String(), {% if hasBody %}body{% else %}nil{% endif %}) - if err != nil { - fmt.Println(err) - return - } + req, _ := http.NewRequest("{{method}}", url.String(), {% if hasBody %}payload{% else %}nil{% endif %}) """; final String kTemplateEnd = """ - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; String? getCode( @@ -122,9 +99,9 @@ func main() { var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "isBody": kMethodsWithBody.contains(requestModel.method) && - requestBody != null, - "isFormDataRequest": requestModel.hasFormData, + "hasBody": requestModel.hasData, + "hasFormData": requestModel.hasFormData, + "hasFileInFormData": requestModel.hasFileInFormData, }); var templateUrl = jj.Template(kTemplateUrl); @@ -138,26 +115,17 @@ func main() { Uri? uri = rec.$1; if (uri != null) { - var method = requestModel.method.name.toUpperCase(); - if (kMethodsWithBody.contains(requestModel.method) && - requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - hasBody = true; - } - if (requestModel.requestBodyContentType == ContentType.text) { - var templateRawBody = jj.Template(kTemplateRawBody); - result += templateRawBody.render({"body": requestBody}); - } else if (requestModel.requestBodyContentType == ContentType.json) { - var templateJsonBody = jj.Template(kTemplateJsonBody); - result += templateJsonBody.render({"body": requestBody}); - } else if (requestModel.hasFormData) { - hasBody = true; - var templateFormData = jj.Template(kTemplateFormData); - result += templateFormData.render({ - "fields": requestModel.formDataMapList, - }); - } + if (requestModel.hasTextData || requestModel.hasJsonData) { + hasBody = true; + var templateRawBody = jj.Template(kTemplateBody); + result += templateRawBody.render({"body": requestBody}); + } else if (requestModel.hasFormData) { + hasBody = true; + var templateFormData = jj.Template(kTemplateFormData); + result += templateFormData.render({ + "hasFileInFormData": requestModel.hasFileInFormData, + "fields": requestModel.formDataMapList, + }); } if (uri.hasQuery) { @@ -168,18 +136,30 @@ func main() { } } + var method = requestModel.method.name.toUpperCase(); var templateRequest = jj.Template(kTemplateRequest); - result += - templateRequest.render({"method": method, "hasBody": hasBody}); + result += templateRequest.render({ + "method": method, + "hasBody": hasBody, + }); var headersList = requestModel.enabledRequestHeaders; - if (headersList != null) { + if (headersList != null || requestModel.hasData) { var headers = requestModel.enabledHeadersMap; + if (requestModel.hasJsonData || requestModel.hasTextData) { + headers.putIfAbsent(kHeaderContentType, + () => requestModel.requestBodyContentType.header); + } if (headers.isNotEmpty) { var templateHeader = jj.Template(kTemplateHeader); - result += templateHeader.render({"headers": headers}); + result += templateHeader.render({ + "headers": headers, + }); } } + if (requestModel.hasFormData) { + result += kStringFormDataHeader; + } result += kTemplateEnd; } diff --git a/lib/models/request_model.dart b/lib/models/request_model.dart index 290681f6..8a1fea7e 100644 --- a/lib/models/request_model.dart +++ b/lib/models/request_model.dart @@ -68,6 +68,7 @@ class RequestModel { bool get hasJsonContentType => requestBodyContentType == ContentType.json; bool get hasTextContentType => requestBodyContentType == ContentType.text; int get contentLength => utf8.encode(requestBody ?? "").length; + bool get hasData => hasJsonData || hasTextData || hasFormData; bool get hasJsonData => kMethodsWithBody.contains(method) && hasJsonContentType && @@ -84,6 +85,9 @@ class RequestModel { requestFormDataList ?? []; List> get formDataMapList => rowsToFormDataMapList(requestFormDataList) ?? []; + bool get hasFileInFormData => formDataList + .map((e) => e.type == FormDataType.file) + .any((element) => element); bool get hasContentTypeHeader => enabledHeadersMap.keys .any((k) => k.toLowerCase() == HttpHeaders.contentTypeHeader); diff --git a/test/codegen/go_http_codegen_test.dart b/test/codegen/go_http_codegen_test.dart index 7e59dd70..421f8018 100644 --- a/test/codegen/go_http_codegen_test.dart +++ b/test/codegen/go_http_codegen_test.dart @@ -16,34 +16,23 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://api.apidash.dev") + req, _ := http.NewRequest("GET", url.String(), nil) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet1, "https"), expectedCode); @@ -57,39 +46,28 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/country/data") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/country/data") query := url.Query() query.Set("code", "US") - - url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - res, err := io.ReadAll(resp.Body) + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet2, "https"), expectedCode); @@ -103,39 +81,28 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/country/data?code=US") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/country/data?code=US") query := url.Query() query.Set("code", "IND") - - url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - res, err := io.ReadAll(resp.Body) + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet3, "https"), expectedCode); @@ -149,47 +116,32 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/humanize/social") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/humanize/social") query := url.Query() query.Set("num", "8700000") - query.Set("digits", "3") - query.Set("system", "SS") - query.Set("add_space", "true") - query.Set("trailing_zeros", "true") - - url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - res, err := io.ReadAll(resp.Body) + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet4, "https"), expectedCode); @@ -203,37 +155,25 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.github.com/repos/foss42/apidash") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.github.com/repos/foss42/apidash") + req, _ := http.NewRequest("GET", url.String(), nil) req.Header.Set("User-Agent", "Test Agent") - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet5, "https"), expectedCode); @@ -247,42 +187,30 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.github.com/repos/foss42/apidash") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.github.com/repos/foss42/apidash") query := url.Query() query.Set("raw", "true") - + url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } + req, _ := http.NewRequest("GET", url.String(), nil) req.Header.Set("User-Agent", "Test Agent") - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet6, "https"), expectedCode); @@ -296,34 +224,23 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://api.apidash.dev") + req, _ := http.NewRequest("GET", url.String(), nil) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet7, "https"), expectedCode); @@ -337,42 +254,30 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.github.com/repos/foss42/apidash") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.github.com/repos/foss42/apidash") query := url.Query() query.Set("raw", "true") - + url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } + req, _ := http.NewRequest("GET", url.String(), nil) req.Header.Set("User-Agent", "Test Agent") - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet8, "https"), expectedCode); @@ -386,41 +291,29 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/humanize/social") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/humanize/social") query := url.Query() query.Set("num", "8700000") - query.Set("add_space", "true") - - url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - res, err := io.ReadAll(resp.Body) + url.RawQuery = query.Encode() + req, _ := http.NewRequest("GET", url.String(), nil) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelGet9, "https"), expectedCode); @@ -434,37 +327,25 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/humanize/social") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + req, _ := http.NewRequest("GET", url.String(), nil) req.Header.Set("User-Agent", "Test Agent") - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect( codegen.getCode( @@ -483,44 +364,31 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/humanize/social") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/humanize/social") query := url.Query() query.Set("num", "8700000") - query.Set("digits", "3") - + url.RawQuery = query.Encode() - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } + req, _ := http.NewRequest("GET", url.String(), nil) req.Header.Set("User-Agent", "Test Agent") - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelGet11, "https"), @@ -535,34 +403,23 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/humanize/social") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://api.apidash.dev/humanize/social") + req, _ := http.NewRequest("GET", url.String(), nil) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelGet12, "https"), @@ -579,34 +436,23 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("HEAD", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://api.apidash.dev") + req, _ := http.NewRequest("HEAD", url.String(), nil) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelHead1, "https"), @@ -621,34 +467,23 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("http://api.apidash.dev") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("HEAD", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("http://api.apidash.dev") + req, _ := http.NewRequest("HEAD", url.String(), nil) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelHead2, "http"), expectedCode); @@ -665,37 +500,28 @@ import ( "net/http" "net/url" "bytes" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/case/lower") - if err != nil { - fmt.Println(err) - return - } - body := bytes.NewBuffer([]byte(`{ + url, _ := url.Parse("https://api.apidash.dev/case/lower") + payload := bytes.NewBuffer([]byte(`{ "text": "I LOVE Flutter" }`)) - req, err := http.NewRequest("POST", url.String(), body) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + req, _ := http.NewRequest("POST", url.String(), payload) - res, err := io.ReadAll(resp.Body) + req.Header.Set("Content-Type", "text/plain") + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelPost1, "https"), @@ -711,17 +537,12 @@ import ( "net/http" "net/url" "bytes" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/case/lower") - if err != nil { - fmt.Println(err) - return - } - body := bytes.NewBuffer([]byte(`{ + url, _ := url.Parse("https://api.apidash.dev/case/lower") + payload := bytes.NewBuffer([]byte(`{ "text": "I LOVE Flutter", "flag": null, "male": true, @@ -729,24 +550,20 @@ func main() { "no": 1.2, "arr": ["null", "true", "false", null] }`)) - req, err := http.NewRequest("POST", url.String(), body) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + req, _ := http.NewRequest("POST", url.String(), payload) - res, err := io.ReadAll(resp.Body) + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelPost2, "https"), @@ -762,40 +579,29 @@ import ( "net/http" "net/url" "bytes" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/case/lower") - if err != nil { - fmt.Println(err) - return - } - body := bytes.NewBuffer([]byte(`{ + url, _ := url.Parse("https://api.apidash.dev/case/lower") + payload := bytes.NewBuffer([]byte(`{ "text": "I LOVE Flutter" }`)) - req, err := http.NewRequest("POST", url.String(), body) - if err != nil { - fmt.Println(err) - return - } + req, _ := http.NewRequest("POST", url.String(), payload) req.Header.Set("User-Agent", "Test Agent") + req.Header.Set("Content-Type", "application/json") - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelPost3, "https"), @@ -810,34 +616,34 @@ import ( "io" "net/http" "net/url" - + "bytes" + "mime/multipart" ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/io/form") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("POST", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://api.apidash.dev/io/form") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + + writer.WriteField("text", "API") + writer.WriteField("sep", "|") + writer.WriteField("times", "3") + writer.Close() - res, err := io.ReadAll(resp.Body) + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelPost4, "https"), @@ -852,37 +658,36 @@ import ( "io" "net/http" "net/url" - + "bytes" + "mime/multipart" ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/io/form") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("POST", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/io/form") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + + writer.WriteField("text", "API") + writer.WriteField("sep", "|") + writer.WriteField("times", "3") + writer.Close() + + req, _ := http.NewRequest("POST", url.String(), payload) req.Header.Set("User-Agent", "Test Agent") + req.Header.Set("Content-Type", writer.FormDataContentType()) - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelPost5, "https"), @@ -898,34 +703,42 @@ import ( "io" "net/http" "net/url" - + "bytes" + "mime/multipart" + "os" ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/io/img") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("POST", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://api.apidash.dev/io/img") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + var ( + file *os.File + part io.Writer + ) + + writer.WriteField("token", "xyz") + file, _ = os.Open("/Documents/up/1.png") + defer file.Close() + part, _ = writer.CreateFormFile("imfile", "/Documents/up/1.png") + io.Copy(part, file) + + writer.Close() - res, err := io.ReadAll(resp.Body) + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost6, "https"), expectedCode); @@ -945,53 +758,35 @@ import ( func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/io/img") - if err != nil { - fmt.Println(err) - return - } - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) + url, _ := url.Parse("https://api.apidash.dev/io/img") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) var ( file *os.File part io.Writer ) writer.WriteField("token", "xyz") - file, err = os.Open("/Documents/up/1.png") - if err != nil { - fmt.Println(err) - return - } + file, _ = os.Open("/Documents/up/1.png") defer file.Close() - - part, err = writer.CreateFormFile("imfile", "/Documents/up/1.png") - if err != nil { - fmt.Println(err) - return - } + part, _ = writer.CreateFormFile("imfile", "/Documents/up/1.png") io.Copy(part, file) writer.Close() - req, err := http.NewRequest("POST", url.String(), body) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost7, "https"), expectedCode); @@ -1004,41 +799,40 @@ import ( "io" "net/http" "net/url" - + "bytes" + "mime/multipart" ) func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/io/form") - if err != nil { - fmt.Println(err) - return - } + url, _ := url.Parse("https://api.apidash.dev/io/form") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) + + writer.WriteField("text", "API") + writer.WriteField("sep", "|") + writer.WriteField("times", "3") + writer.Close() + query := url.Query() query.Set("size", "2") - query.Set("len", "3") - - url.RawQuery = query.Encode() - req, err := http.NewRequest("POST", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - res, err := io.ReadAll(resp.Body) + url.RawQuery = query.Encode() + req, _ := http.NewRequest("POST", url.String(), payload) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost8, "https"), expectedCode); @@ -1058,31 +852,18 @@ import ( func main() { client := &http.Client{} - url, err := url.Parse("https://api.apidash.dev/io/img") - if err != nil { - fmt.Println(err) - return - } - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) + url, _ := url.Parse("https://api.apidash.dev/io/img") + payload := &bytes.Buffer{} + writer := multipart.NewWriter(payload) var ( file *os.File part io.Writer ) writer.WriteField("token", "xyz") - file, err = os.Open("/Documents/up/1.png") - if err != nil { - fmt.Println(err) - return - } + file, _ = os.Open("/Documents/up/1.png") defer file.Close() - - part, err = writer.CreateFormFile("imfile", "/Documents/up/1.png") - if err != nil { - fmt.Println(err) - return - } + part, _ = writer.CreateFormFile("imfile", "/Documents/up/1.png") io.Copy(part, file) writer.Close() @@ -1090,33 +871,25 @@ func main() { query := url.Query() query.Set("size", "2") - query.Set("len", "3") - + url.RawQuery = query.Encode() - req, err := http.NewRequest("POST", url.String(), body) - if err != nil { - fmt.Println(err) - return - } + req, _ := http.NewRequest("POST", url.String(), payload) req.Header.Set("User-Agent", "Test Agent") - req.Header.Set("Keep-Alive", "true") + req.Header.Set("Content-Type", writer.FormDataContentType()) - resp, err := client.Do(req) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - defer resp.Body.Close() + defer response.Body.Close() - res, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(res)) + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPost9, "https"), expectedCode); @@ -1132,38 +905,29 @@ import ( "net/http" "net/url" "bytes" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://reqres.in/api/users/2") - if err != nil { - fmt.Println(err) - return - } - body := bytes.NewBuffer([]byte(`{ + url, _ := url.Parse("https://reqres.in/api/users/2") + payload := bytes.NewBuffer([]byte(`{ "name": "morpheus", "job": "zion resident" }`)) - req, err := http.NewRequest("PUT", url.String(), body) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + req, _ := http.NewRequest("PUT", url.String(), payload) - res, err := io.ReadAll(resp.Body) + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect(codeGen.getCode(CodegenLanguage.goHttp, requestModelPut1, "https"), expectedCode); @@ -1180,38 +944,29 @@ import ( "net/http" "net/url" "bytes" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://reqres.in/api/users/2") - if err != nil { - fmt.Println(err) - return - } - body := bytes.NewBuffer([]byte(`{ + url, _ := url.Parse("https://reqres.in/api/users/2") + payload := bytes.NewBuffer([]byte(`{ "name": "marfeus", "job": "accountant" }`)) - req, err := http.NewRequest("PATCH", url.String(), body) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + req, _ := http.NewRequest("PATCH", url.String(), payload) - res, err := io.ReadAll(resp.Body) + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelPatch1, "https"), @@ -1228,34 +983,23 @@ import ( "io" "net/http" "net/url" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://reqres.in/api/users/2") - if err != nil { - fmt.Println(err) - return - } - req, err := http.NewRequest("DELETE", url.String(), nil) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + url, _ := url.Parse("https://reqres.in/api/users/2") + req, _ := http.NewRequest("DELETE", url.String(), nil) - res, err := io.ReadAll(resp.Body) + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }"""; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelDelete1, "https"), @@ -1271,38 +1015,29 @@ import ( "net/http" "net/url" "bytes" - ) func main() { client := &http.Client{} - url, err := url.Parse("https://reqres.in/api/users/2") - if err != nil { - fmt.Println(err) - return - } - body := bytes.NewBuffer([]byte(`{ + url, _ := url.Parse("https://reqres.in/api/users/2") + payload := bytes.NewBuffer([]byte(`{ "name": "marfeus", "job": "accountant" }`)) - req, err := http.NewRequest("DELETE", url.String(), body) - if err != nil { - fmt.Println(err) - return - } - resp, err := client.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() + req, _ := http.NewRequest("DELETE", url.String(), payload) - res, err := io.ReadAll(resp.Body) + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) if err != nil { fmt.Println(err) return } - fmt.Println(string(res)) + defer response.Body.Close() + + fmt.Println("Status Code:", response.StatusCode) + body, _ := io.ReadAll(response.Body) + fmt.Println("Response body:", string(body)) }'''; expect( codeGen.getCode(CodegenLanguage.goHttp, requestModelDelete2, "https"), From a8637ea609c1458324cd6845ccd158ab763f5143 Mon Sep 17 00:00:00 2001 From: Ashita Prasad Date: Tue, 12 Mar 2024 20:12:57 +0530 Subject: [PATCH 57/91] Update codegen order --- lib/consts.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/consts.dart b/lib/consts.dart index 8c4cfe8f..28818b62 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -266,14 +266,14 @@ enum CodegenLanguage { har("HAR", "json", "har"), dartHttp("Dart (http)", "dart", "dart"), dartDio("Dart (dio)", "dart", "dart"), + goHttp("Go (http)", "go", "go"), jsAxios("JavaScript (axios)", "javascript", "js"), jsFetch("JavaScript (fetch)", "javascript", "js"), nodejsAxios("node.js (axios)", "javascript", "js"), nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"), - goHttp("Golang (http)", "go", "go"); + pythonRequests("Python (requests)", "python", "py"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; From f495d7b2336e2225cdc95d73e6b53e07c7f0f39a Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Tue, 12 Mar 2024 23:57:42 +0530 Subject: [PATCH 58/91] fix: testcases and dart dio codegen --- lib/codegen/dart/dio.dart | 8 +- test/codegen/dart_dio_codegen_test.dart | 336 +++++++++++++++++++++++- 2 files changed, 339 insertions(+), 5 deletions(-) diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index c05b0b68..a32ba18c 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -55,12 +55,12 @@ class DartDioCodeGen { final List> formDataList = ${json.encode(formData)}; for (var formField in formDataList) { if (formField['type'] == 'file') { - formData.files.add(MapEntry( + data.files.add(MapEntry( formField['name'], await MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { - formData.fields.add(MapEntry(formField['name'], formField['value'])); + data.fields.add(MapEntry(formField['name'], formField['value'])); } } '''); @@ -79,11 +79,11 @@ class DartDioCodeGen { dataExp = declareFinal('data').assign(strContent); // when add new type of [ContentType], need update [dataExp]. case ContentType.formdata: - dataExp = declareFinal('data').assign(refer('FormData()')); + dataExp = declareFinal('data').assign(refer('dio.FormData()')); } } final responseExp = declareFinal('response').assign(InvokeExpression.newOf( - refer('dio.Dio'), + refer('dio.Dio()'), [literalString(url)], { if (queryParamExp != null) 'queryParameters': refer('queryParams'), diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 84ae29d4..8439b291 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -486,8 +486,342 @@ void main() async { codeGen.getCode(CodegenLanguage.dartDio, requestModelPost3, "https"), expectedCode); }); - }); + test('POST 4', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + data.files.add(MapEntry( + formField['name'], + await MultipartFile.fromFile(formField['value'], + filename: formField['value']), + )); + } else { + data.fields + .add(MapEntry(formField['name'], formField['value'])); + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/form', + queryParameters: queryParams, + options: Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost4, "https"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final headers = { + 'User-Agent': 'Test Agent', + 'Keep-Alive': 'true', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + data.files.add(MapEntry( + formField['name'], + await MultipartFile.fromFile(formField['value'], + filename: formField['value']), + )); + } else { + data.fields + .add(MapEntry(formField['name'], formField['value'])); + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/form', + queryParameters: queryParams, + options: Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost5, "https"), + expectedCode); + }); + + test('POST 6', () { + const expectedCode = r"""iimport 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + { + "name": "imfile", + "value": + "/Desktop/mp.jpg", + "type": "file" + } + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + data.files.add(MapEntry( + formField['name'], + await MultipartFile.fromFile(formField['value'], + filename: formField['value']), + )); + } else { + data.fields + .add(MapEntry(formField['name'], formField['value'])); + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/img', + queryParameters: queryParams, + options: Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost6, "https"), + expectedCode); + }); + + test('POST 7', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + { + "name": "imfile", + "value": + "/Desktop/mp.jpg", + "type": "file" + } + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + data.files.add(MapEntry( + formField['name'], + await MultipartFile.fromFile(formField['value'], + filename: formField['value']), + )); + } else { + data.fields + .add(MapEntry(formField['name'], formField['value'])); + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/img', + queryParameters: queryParams, + options: Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost7, "https"), + expectedCode); + }); + + test('POST 8', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final headers = { + 'User-Agent': 'Test Agent', + 'Keep-Alive': 'true', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + data.files.add(MapEntry( + formField['name'], + await MultipartFile.fromFile(formField['value'], + filename: formField['value']), + )); + } else { + data.fields + .add(MapEntry(formField['name'], formField['value'])); + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/form', + queryParameters: queryParams, + options: Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost8, "https"), + expectedCode); + }); + + test('POST 9', () { + const expectedCode = r"""import 'package:dio/dio.dart' as dio; + +void main() async { + try { + final queryParams = { + 'size': '2', + 'len': '3', + }; + final headers = { + 'User-Agent': 'Test Agent', + 'Keep-Alive': 'true', + }; + final data = dio.FormData(); + final List> formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + { + "name": "imfile", + "value": + "/Desktop/mp.jpg", + "type": "file" + } + ]; + for (var formField in formDataList) { + if (formField['type'] == 'file') { + data.files.add(MapEntry( + formField['name'], + await MultipartFile.fromFile(formField['value'], + filename: formField['value']), + )); + } else { + data.fields + .add(MapEntry(formField['name'], formField['value'])); + } + } + + final response = await dio.Dio().post( + 'https://api.apidash.dev/io/img', + queryParameters: queryParams, + options: Options(headers: headers), + data: data, + ); + print(response.statusCode); + print(response.data); + } on DioException catch (e, s) { + print(e.response?.statusCode); + print(e.response?.data); + print(s); + } catch (e, s) { + print(e); + print(s); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonRequests, requestModelPost9, "https"), + expectedCode); + }); + }); group('PUT Request', () { test('PUT 1', () { const expectedCode = r"""import 'package:dio/dio.dart' as dio; From 378f16035bac555546b2abb6fb16db43e1c92e45 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Wed, 13 Mar 2024 00:09:12 +0530 Subject: [PATCH 59/91] package updation --- lib/codegen/dart/dio.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index a32ba18c..63569e28 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -57,7 +57,7 @@ class DartDioCodeGen { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], filename: formField['value']), + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { data.fields.add(MapEntry(formField['name'], formField['value'])); @@ -88,7 +88,7 @@ class DartDioCodeGen { { if (queryParamExp != null) 'queryParameters': refer('queryParams'), if (headerExp != null) - 'options': refer('Options').newInstance( + 'options': refer('dio.Options').newInstance( [], {'headers': refer('headers')}, ), @@ -112,7 +112,7 @@ class DartDioCodeGen { refer('print').call([refer('response').property('data')]), ], onError: { - 'DioException': [ + 'dio.DioException': [ refer('print').call([ refer('e').property('response').nullSafeProperty('statusCode'), ]), From 8bfa8246771d66b7ed56cb41f66803c6293efc55 Mon Sep 17 00:00:00 2001 From: "qiang.zeng" Date: Wed, 13 Mar 2024 11:14:28 +0800 Subject: [PATCH 60/91] fix: when snapshot.hasError is true, text has not been initialized --- lib/widgets/intro_message.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/widgets/intro_message.dart b/lib/widgets/intro_message.dart index 970596d3..7e7ff2e0 100644 --- a/lib/widgets/intro_message.dart +++ b/lib/widgets/intro_message.dart @@ -23,6 +23,9 @@ class IntroMessage extends StatelessWidget { return FutureBuilder( future: introData(), builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasError) { + return const ErrorMessage(message: "An error occured"); + } if (snapshot.connectionState == ConnectionState.done) { if (Theme.of(context).brightness == Brightness.dark) { text = text.replaceAll("{{mode}}", "dark"); @@ -37,9 +40,6 @@ class IntroMessage extends StatelessWidget { padding: kPh60, ); } - if (snapshot.hasError) { - return const ErrorMessage(message: "An error occured"); - } return const Center(child: CircularProgressIndicator()); }, ); From 990b1f5e2a80ae701a5bedb83ff65ff918b17a0c Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Wed, 13 Mar 2024 09:39:34 +0530 Subject: [PATCH 61/91] Update python_http_client_codegen_test.dart --- .../python_http_client_codegen_test.dart | 164 +++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/test/codegen/python_http_client_codegen_test.dart b/test/codegen/python_http_client_codegen_test.dart index b5774809..770870a5 100644 --- a/test/codegen/python_http_client_codegen_test.dart +++ b/test/codegen/python_http_client_codegen_test.dart @@ -411,7 +411,169 @@ print(data.decode("utf-8")) CodegenLanguage.pythonHttpClient, requestModelPost3, "https"), expectedCode); }); - }); + + test('POST 4', () { + const expectedCode = r"""import http.client + +body = r'''{ +"text": "I LOVE Flutter" +}''' + +headers = { + "content-type": "text/plain" + } + +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/case/lower", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost4, "https"), + expectedCode); + }, skip: true); + + test('POST 5', () { + const expectedCode = r"""import http.client + +body = r'''{ +"text": "I LOVE Flutter" +}''' + +headers = { + "content-type": "text/plain" + } + +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/case/lower", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost5, "https"), + expectedCode); + }, skip: true); + + test('POST 6', () { + const expectedCode = r"""import http.client + +body = r'''{ +"text": "I LOVE Flutter" +}''' + +headers = { + "content-type": "text/plain" + } + +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/case/lower", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost6, "https"), + expectedCode); + }, skip: true); + + test('POST 7', () { + const expectedCode = r"""import http.client + +body = r'''{ +"text": "I LOVE Flutter" +}''' + +headers = { + "content-type": "text/plain" + } + +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/case/lower", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost7, "https"), + expectedCode); + }, skip: true); + + test('POST 8', () { + const expectedCode = r"""import http.client + +body = r'''{ +"text": "I LOVE Flutter" +}''' + +headers = { + "content-type": "text/plain" + } + +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/case/lower", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost8, "https"), + expectedCode); + }, skip: true); + + test('POST 9', () { + const expectedCode = r"""import http.client + +body = r'''{ +"text": "I LOVE Flutter" +}''' + +headers = { + "content-type": "text/plain" + } + +conn = http.client.HTTPSConnection("api.apidash.dev") +conn.request("POST", "/case/lower", + body= body, + headers= headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +"""; + expect( + codeGen.getCode( + CodegenLanguage.pythonHttpClient, requestModelPost9, "https"), + expectedCode); + }); + }, skip: true); group('PUT Request', () { test('PUT 1', () { From 62551f05f483861215b504a3f4047a4f07bb4b16 Mon Sep 17 00:00:00 2001 From: Ashita Prasad Date: Wed, 13 Mar 2024 11:09:13 +0530 Subject: [PATCH 62/91] python http.client update --- lib/codegen/python/http_client.dart | 43 +-- .../python_http_client_codegen_test.dart | 339 +++++++++++++----- 2 files changed, 261 insertions(+), 121 deletions(-) diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 6913314a..05fb8253 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -1,8 +1,7 @@ import 'dart:io'; import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; -import 'package:apidash/utils/utils.dart' - show getValidRequestUri, padMultilineString; +import 'package:apidash/utils/utils.dart' show getValidRequestUri; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; @@ -20,7 +19,6 @@ queryParams = {{params}} queryParamsStr = '?' + urlencode(queryParams) """; - int kParamsPadding = 14; String kTemplateBody = """ @@ -36,8 +34,6 @@ headers = {{headers}} String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; - int kHeadersPadding = 10; - String kTemplateConnection = """ conn = http.client.HTTP{{isHttps}}Connection("{{authority}}")"""; @@ -116,43 +112,38 @@ body = b'\r\n'.join(dataList) hasQuery = true; var templateParams = jj.Template(kTemplateParams); var paramsString = kEncoder.convert(params); - paramsString = padMultilineString(paramsString, kParamsPadding); result += templateParams.render({"params": paramsString}); } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && - requestBody != null && - !requestModel.hasFormData) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - hasBody = true; + if (requestModel.hasData) { + hasBody = true; + if (requestModel.hasJsonData || requestModel.hasTextData) { var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": requestBody}); + result += templateBody.render({"body": requestModel.requestBody}); } } var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.hasFormData) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": boundary, - }); - } if (headers.isNotEmpty || hasBody) { hasHeaders = true; if (hasBody && !requestModel.hasContentTypeHeader) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; + if (requestModel.hasJsonData || requestModel.hasTextData) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } else if (requestModel.hasFormData) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = + formHeaderTemplate.render({ + "boundary": boundary, + }); + } } var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headersString}); } @@ -174,7 +165,7 @@ body = b'\r\n'.join(dataList) var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "method": method.name.toUpperCase(), + "method": requestModel.method.name.toUpperCase(), "path": uri.path, "queryParamsStr": hasQuery ? " + queryParamsStr" : "", }); diff --git a/test/codegen/python_http_client_codegen_test.dart b/test/codegen/python_http_client_codegen_test.dart index 770870a5..c1d68702 100644 --- a/test/codegen/python_http_client_codegen_test.dart +++ b/test/codegen/python_http_client_codegen_test.dart @@ -29,8 +29,8 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "code": "US" - } + "code": "US" +} queryParamsStr = '?' + urlencode(queryParams) conn = http.client.HTTPSConnection("api.apidash.dev") @@ -52,8 +52,8 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "code": "IND" - } + "code": "IND" +} queryParamsStr = '?' + urlencode(queryParams) conn = http.client.HTTPSConnection("api.apidash.dev") @@ -75,12 +75,12 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "num": "8700000", - "digits": "3", - "system": "SS", - "add_space": "true", - "trailing_zeros": "true" - } + "num": "8700000", + "digits": "3", + "system": "SS", + "add_space": "true", + "trailing_zeros": "true" +} queryParamsStr = '?' + urlencode(queryParams) conn = http.client.HTTPSConnection("api.apidash.dev") @@ -101,8 +101,8 @@ print(data.decode("utf-8")) const expectedCode = r"""import http.client headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.github.com") conn.request("GET", "/repos/foss42/apidash", @@ -124,13 +124,13 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "raw": "true" - } + "raw": "true" +} queryParamsStr = '?' + urlencode(queryParams) headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.github.com") conn.request("GET", "/repos/foss42/apidash" + queryParamsStr, @@ -169,13 +169,13 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "raw": "true" - } + "raw": "true" +} queryParamsStr = '?' + urlencode(queryParams) headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.github.com") conn.request("GET", "/repos/foss42/apidash" + queryParamsStr, @@ -197,9 +197,9 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "num": "8700000", - "add_space": "true" - } + "num": "8700000", + "add_space": "true" +} queryParamsStr = '?' + urlencode(queryParams) conn = http.client.HTTPSConnection("api.apidash.dev") @@ -220,8 +220,8 @@ print(data.decode("utf-8")) const expectedCode = r"""import http.client headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social", @@ -246,14 +246,14 @@ print(data.decode("utf-8")) from urllib.parse import urlencode queryParams = { - "num": "8700000", - "digits": "3" - } + "num": "8700000", + "digits": "3" +} queryParamsStr = '?' + urlencode(queryParams) headers = { - "User-Agent": "Test Agent" - } + "User-Agent": "Test Agent" +} conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("GET", "/humanize/social" + queryParamsStr, @@ -333,8 +333,8 @@ body = r'''{ }''' headers = { - "content-type": "text/plain" - } + "content-type": "text/plain" +} conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("POST", "/case/lower", @@ -365,8 +365,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("POST", "/case/lower", @@ -392,9 +392,9 @@ body = r'''{ }''' headers = { - "User-Agent": "Test Agent", - "content-type": "application/json" - } + "User-Agent": "Test Agent", + "content-type": "application/json" +} conn = http.client.HTTPSConnection("api.apidash.dev") conn.request("POST", "/case/lower", @@ -414,17 +414,38 @@ print(data.decode("utf-8")) test('POST 4', () { const expectedCode = r"""import http.client - -body = r'''{ -"text": "I LOVE Flutter" -}''' +import mimetypes +from codecs import encode headers = { - "content-type": "text/plain" - } + "content-type": "multipart/form-data; boundary=b9826c20-773c-1f0c-814d-a1b3d90cd6b3" +} +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--b9826c20-773c-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--b9826c20-773c-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"text","value":"API","type":"text"},{"name":"sep","value":"|","type":"text"},{"name":"times","value":"3","type":"text"}]) +body = b'\r\n'.join(dataList) conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("POST", "/case/lower", +conn.request("POST", "/io/form", body= body, headers= headers) @@ -435,23 +456,46 @@ print(data.decode("utf-8")) """; expect( codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelPost4, "https"), + CodegenLanguage.pythonHttpClient, requestModelPost4, "https", + boundary: "b9826c20-773c-1f0c-814d-a1b3d90cd6b3"), expectedCode); - }, skip: true); + }); test('POST 5', () { const expectedCode = r"""import http.client - -body = r'''{ -"text": "I LOVE Flutter" -}''' +import mimetypes +from codecs import encode headers = { - "content-type": "text/plain" - } + "User-Agent": "Test Agent", + "content-type": "multipart/form-data; boundary=929dc910-7714-1f0c-814d-a1b3d90cd6b3" +} +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--929dc910-7714-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--929dc910-7714-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"text","value":"API","type":"text"},{"name":"sep","value":"|","type":"text"},{"name":"times","value":"3","type":"text"}]) +body = b'\r\n'.join(dataList) conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("POST", "/case/lower", +conn.request("POST", "/io/form", body= body, headers= headers) @@ -462,23 +506,45 @@ print(data.decode("utf-8")) """; expect( codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelPost5, "https"), + CodegenLanguage.pythonHttpClient, requestModelPost5, "https", + boundary: "929dc910-7714-1f0c-814d-a1b3d90cd6b3"), expectedCode); - }, skip: true); + }); test('POST 6', () { const expectedCode = r"""import http.client - -body = r'''{ -"text": "I LOVE Flutter" -}''' +import mimetypes +from codecs import encode headers = { - "content-type": "text/plain" - } + "content-type": "multipart/form-data; boundary=9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3" +} +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"token","value":"xyz","type":"text"},{"name":"imfile","value":"/Documents/up/1.png","type":"file"}]) +body = b'\r\n'.join(dataList) conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("POST", "/case/lower", +conn.request("POST", "/io/img", body= body, headers= headers) @@ -489,23 +555,45 @@ print(data.decode("utf-8")) """; expect( codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelPost6, "https"), + CodegenLanguage.pythonHttpClient, requestModelPost6, "https", + boundary: "9b1374c0-76e0-1f0c-814d-a1b3d90cd6b3"), expectedCode); - }, skip: true); + }); test('POST 7', () { const expectedCode = r"""import http.client - -body = r'''{ -"text": "I LOVE Flutter" -}''' +import mimetypes +from codecs import encode headers = { - "content-type": "text/plain" - } + "content-type": "multipart/form-data; boundary=defdf240-76b4-1f0c-814d-a1b3d90cd6b3" +} +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--defdf240-76b4-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--defdf240-76b4-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"token","value":"xyz","type":"text"},{"name":"imfile","value":"/Documents/up/1.png","type":"file"}]) +body = b'\r\n'.join(dataList) conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("POST", "/case/lower", +conn.request("POST", "/io/img", body= body, headers= headers) @@ -516,23 +604,52 @@ print(data.decode("utf-8")) """; expect( codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelPost7, "https"), + CodegenLanguage.pythonHttpClient, requestModelPost7, "https", + boundary: "defdf240-76b4-1f0c-814d-a1b3d90cd6b3"), expectedCode); - }, skip: true); + }); test('POST 8', () { const expectedCode = r"""import http.client +import mimetypes +from codecs import encode +from urllib.parse import urlencode -body = r'''{ -"text": "I LOVE Flutter" -}''' +queryParams = { + "size": "2", + "len": "3" +} +queryParamsStr = '?' + urlencode(queryParams) headers = { - "content-type": "text/plain" - } + "content-type": "multipart/form-data; boundary=a990b150-7683-1f0c-814d-a1b3d90cd6b3" +} +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--a990b150-7683-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--a990b150-7683-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"text","value":"API","type":"text"},{"name":"sep","value":"|","type":"text"},{"name":"times","value":"3","type":"text"}]) +body = b'\r\n'.join(dataList) conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("POST", "/case/lower", +conn.request("POST", "/io/form" + queryParamsStr, body= body, headers= headers) @@ -543,23 +660,54 @@ print(data.decode("utf-8")) """; expect( codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelPost8, "https"), + CodegenLanguage.pythonHttpClient, requestModelPost8, "https", + boundary: "a990b150-7683-1f0c-814d-a1b3d90cd6b3"), expectedCode); - }, skip: true); + }); test('POST 9', () { const expectedCode = r"""import http.client +import mimetypes +from codecs import encode +from urllib.parse import urlencode -body = r'''{ -"text": "I LOVE Flutter" -}''' +queryParams = { + "size": "2", + "len": "3" +} +queryParamsStr = '?' + urlencode(queryParams) headers = { - "content-type": "text/plain" - } + "User-Agent": "Test Agent", + "Keep-Alive": "true", + "content-type": "multipart/form-data; boundary=79088e00-75ec-1f0c-814d-a1b3d90cd6b3" +} +def build_data_list(fields): + dataList = [] + for field in fields: + name = field.get('name', '') + value = field.get('value', '') + type_ = field.get('type', 'text') + dataList.append(encode('--79088e00-75ec-1f0c-814d-a1b3d90cd6b3')) + if type_ == 'text': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"')) + dataList.append(encode('Content-Type: text/plain')) + dataList.append(encode('')) + dataList.append(encode(value)) + elif type_ == 'file': + dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"')) + dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}')) + dataList.append(encode('')) + dataList.append(open(value, 'rb').read()) + dataList.append(encode(f'--79088e00-75ec-1f0c-814d-a1b3d90cd6b3--')) + dataList.append(encode('')) + return dataList + +dataList = build_data_list([{"name":"token","value":"xyz","type":"text"},{"name":"imfile","value":"/Documents/up/1.png","type":"file"}]) +body = b'\r\n'.join(dataList) conn = http.client.HTTPSConnection("api.apidash.dev") -conn.request("POST", "/case/lower", +conn.request("POST", "/io/img" + queryParamsStr, body= body, headers= headers) @@ -570,10 +718,11 @@ print(data.decode("utf-8")) """; expect( codeGen.getCode( - CodegenLanguage.pythonHttpClient, requestModelPost9, "https"), + CodegenLanguage.pythonHttpClient, requestModelPost9, "https", + boundary: "79088e00-75ec-1f0c-814d-a1b3d90cd6b3"), expectedCode); }); - }, skip: true); + }); group('PUT Request', () { test('PUT 1', () { @@ -585,8 +734,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("reqres.in") conn.request("PUT", "/api/users/2", @@ -615,8 +764,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("reqres.in") conn.request("PATCH", "/api/users/2", @@ -662,8 +811,8 @@ body = r'''{ }''' headers = { - "content-type": "application/json" - } + "content-type": "application/json" +} conn = http.client.HTTPSConnection("reqres.in") conn.request("DELETE", "/api/users/2", From 7740505ee48b5e00f23baf5d1e20271729ab8048 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Wed, 13 Mar 2024 15:10:58 +0530 Subject: [PATCH 63/91] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d8b258e5..1beea998 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,17 @@ [![Discord Server Invite](https://img.shields.io/badge/DISCORD-JOIN%20SERVER-5663F7?style=for-the-badge&logo=discord&logoColor=white)](https://bit.ly/heyfoss) -We are participating in GSoC 2024 🎉 [More Details ...](https://summerofcode.withgoogle.com/programs/2024/organizations/api-dash) +🚨 We are participating in GSoC 2024 🎉 + +GSoC + +| | Link | +|--|--| +| Learn about GSoC | [Link](https://summerofcode.withgoogle.com) | +| Organization page on GSoC | [Link](https://summerofcode.withgoogle.com/programs/2024/organizations/api-dash) | +| Project Ideas List | [Link](https://github.com/foss42/apidash/discussions/112) | +| Application Guide | [Link](https://github.com/foss42/apidash/discussions/111) | +| Discord Channel | [Link](https://discord.com/invite/2s49SCNfyJ) | ### Please support this initiative by giving this project a Star ⭐️ From 5ae4d0415683204635c2a6a3d191301cf4d0c77f Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Wed, 13 Mar 2024 21:53:03 +0530 Subject: [PATCH 64/91] all test cases has been updated regarding dart dio --- test/codegen/dart_dio_codegen_test.dart | 116 ++++++++++++------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 8439b291..d12d7307 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -12,10 +12,10 @@ void main() { void main() async { try { - final response = await dio.Dio.get('https://api.apidash.dev'); + final response = await dio.Dio().get('https://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -36,13 +36,13 @@ void main() async { void main() async { try { final queryParams = {'code': 'US'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.apidash.dev/country/data', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -63,13 +63,13 @@ void main() async { void main() async { try { final queryParams = {'code': 'IND'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.apidash.dev/country/data?code=US', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -96,13 +96,13 @@ void main() async { 'add_space': 'true', 'trailing_zeros': 'true', }; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.apidash.dev/humanize/social', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -123,13 +123,13 @@ void main() async { void main() async { try { final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', options: Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -151,14 +151,14 @@ void main() async { try { final queryParams = {'raw': 'true'}; final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -178,10 +178,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.get('https://api.apidash.dev'); + final response = await dio.Dio().get('https://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -203,14 +203,14 @@ void main() async { try { final queryParams = {'raw': 'true'}; final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -234,13 +234,13 @@ void main() async { 'num': '8700000', 'add_space': 'true', }; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.apidash.dev/humanize/social', queryParameters: queryParams, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -261,13 +261,13 @@ void main() async { void main() async { try { final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.apidash.dev/humanize/social', - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -296,14 +296,14 @@ void main() async { 'digits': '3', }; final headers = {'User-Agent': 'Test Agent'}; - final response = await dio.Dio.get( + final response = await dio.Dio().get( 'https://api.apidash.dev/humanize/social', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -323,10 +323,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.get('https://api.apidash.dev/humanize/social'); + final response = await dio.Dio().get('https://api.apidash.dev/humanize/social'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -348,10 +348,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.head('https://api.apidash.dev'); + final response = await dio.Dio().head('https://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -371,10 +371,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.head('http://api.apidash.dev'); + final response = await dio.Dio().head('http://api.apidash.dev'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -399,13 +399,13 @@ void main() async { final data = r'''{ "text": "I LOVE Flutter" }'''; - final response = await dio.Dio.post( + final response = await dio.Dio().post( 'https://api.apidash.dev/case/lower', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -434,13 +434,13 @@ void main() async { "no": 1.2, "arr": ["null", "true", "false", null] }'''); - final response = await dio.Dio.post( + final response = await dio.Dio().post( 'https://api.apidash.dev/case/lower', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -465,14 +465,14 @@ void main() async { final data = convert.json.decode(r'''{ "text": "I LOVE Flutter" }'''); - final response = await dio.Dio.post( + final response = await dio.Dio().post( 'https://api.apidash.dev/case/lower', options: Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -517,12 +517,12 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/form', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -573,12 +573,12 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/form', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -629,12 +629,12 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/img', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -685,12 +685,12 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/img', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -741,12 +741,12 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/form', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -801,12 +801,12 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/img', queryParameters: queryParams, - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -833,13 +833,13 @@ void main() async { "name": "morpheus", "job": "zion resident" }'''); - final response = await dio.Dio.put( + final response = await dio.Dio().put( 'https://reqres.in/api/users/2', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -866,13 +866,13 @@ void main() async { "name": "marfeus", "job": "accountant" }'''); - final response = await dio.Dio.patch( + final response = await dio.Dio().patch( 'https://reqres.in/api/users/2', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -894,10 +894,10 @@ void main() async { void main() async { try { - final response = await dio.Dio.delete('https://reqres.in/api/users/2'); + final response = await dio.Dio().delete('https://reqres.in/api/users/2'); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); @@ -923,13 +923,13 @@ void main() async { "name": "marfeus", "job": "accountant" }'''); - final response = await dio.Dio.delete( + final response = await dio.Dio().delete( 'https://reqres.in/api/users/2', data: data, ); print(response.statusCode); print(response.data); - } on DioException catch (e, s) { + } on dio.DioException catch (e, s) { print(e.response?.statusCode); print(e.response?.data); print(s); From bacc221452659012483fcb188bbc3866313fbd5d Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Wed, 13 Mar 2024 22:24:11 +0530 Subject: [PATCH 65/91] minor changes in test cases --- test/codegen/dart_dio_codegen_test.dart | 77 ++++++++----------------- 1 file changed, 24 insertions(+), 53 deletions(-) diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index d12d7307..1a612a9a 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -125,7 +125,7 @@ void main() async { final headers = {'User-Agent': 'Test Agent'}; final response = await dio.Dio().get( 'https://api.github.com/repos/foss42/apidash', - options: Options(headers: headers), + options: dio.Options(headers: headers), ); print(response.statusCode); print(response.data); @@ -467,7 +467,7 @@ void main() async { }'''); final response = await dio.Dio().post( 'https://api.apidash.dev/case/lower', - options: Options(headers: headers), + options: dio.Options(headers: headers), data: data, ); print(response.statusCode); @@ -491,13 +491,9 @@ void main() async { void main() async { try { - final queryParams = { - 'size': '2', - 'len': '3', - }; final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "xyz", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; @@ -505,7 +501,7 @@ void main() async { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { @@ -533,8 +529,7 @@ void main() async { } """; expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelPost4, "https"), + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost4, "https"), expectedCode); }); @@ -543,17 +538,13 @@ void main() async { void main() async { try { - final queryParams = { - 'size': '2', - 'len': '3', - }; final headers = { 'User-Agent': 'Test Agent', 'Keep-Alive': 'true', }; final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "xyz", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; @@ -561,7 +552,7 @@ void main() async { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { @@ -589,27 +580,21 @@ void main() async { } """; expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelPost5, "https"), + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost5, "https"), expectedCode); }); test('POST 6', () { - const expectedCode = r"""iimport 'package:dio/dio.dart' as dio; + const expectedCode = r"""import 'package:dio/dio.dart' as dio; void main() async { try { - final queryParams = { - 'size': '2', - 'len': '3', - }; final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "xyz", "type": "text"}, { "name": "imfile", - "value": - "/Desktop/mp.jpg", + "value": "/Desktop/mp.jpg", "type": "file" } ]; @@ -617,7 +602,7 @@ void main() async { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { @@ -645,8 +630,7 @@ void main() async { } """; expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelPost6, "https"), + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost6, "https"), expectedCode); }); @@ -655,17 +639,12 @@ void main() async { void main() async { try { - final queryParams = { - 'size': '2', - 'len': '3', - }; final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "xyz", "type": "text"}, { "name": "imfile", - "value": - "/Desktop/mp.jpg", + "value": "/Desktop/mp.jpg", "type": "file" } ]; @@ -673,7 +652,7 @@ void main() async { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { @@ -701,8 +680,7 @@ void main() async { } """; expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelPost7, "https"), + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost7, "https"), expectedCode); }); @@ -715,13 +693,9 @@ void main() async { 'size': '2', 'len': '3', }; - final headers = { - 'User-Agent': 'Test Agent', - 'Keep-Alive': 'true', - }; final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "xyz", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; @@ -729,7 +703,7 @@ void main() async { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { @@ -757,8 +731,7 @@ void main() async { } """; expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelPost8, "https"), + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost8, "https"), expectedCode); }); @@ -777,11 +750,10 @@ void main() async { }; final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "xyz", "type": "text"}, { "name": "imfile", - "value": - "/Desktop/mp.jpg", + "value": "/Documents/up/1.png", "type": "file" } ]; @@ -789,7 +761,7 @@ void main() async { if (formField['type'] == 'file') { data.files.add(MapEntry( formField['name'], - await MultipartFile.fromFile(formField['value'], + await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), )); } else { @@ -817,8 +789,7 @@ void main() async { } """; expect( - codeGen.getCode( - CodegenLanguage.pythonRequests, requestModelPost9, "https"), + codeGen.getCode(CodegenLanguage.dartDio, requestModelPost9, "https"), expectedCode); }); }); From 1c43e8d8634a0a70e8ce21c25fd31f9e19715073 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Thu, 14 Mar 2024 00:11:15 +0530 Subject: [PATCH 66/91] cofigured with mail --- test/codegen/dart_dio_codegen_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 1a612a9a..f14af748 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -493,7 +493,7 @@ void main() async { try { final data = dio.FormData(); final List> formDataList = [ - {"name": "text", "value": "xyz", "type": "text"}, + {"name": "token", "value": "xyz", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; From 41d72d21d74af655d90865b8bbd0815584976e0e Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Thu, 14 Mar 2024 00:25:09 +0530 Subject: [PATCH 67/91] flutter test all cases passed --- test/codegen/dart_dio_codegen_test.dart | 29 ++++++++----------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index f14af748..22fb3159 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -493,7 +493,7 @@ void main() async { try { final data = dio.FormData(); final List> formDataList = [ - {"name": "token", "value": "xyz", "type": "text"}, + {"name": "text", "value": "API", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; @@ -512,8 +512,6 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/form', - queryParameters: queryParams, - options: dio.Options(headers: headers), data: data, ); print(response.statusCode); @@ -538,13 +536,10 @@ void main() async { void main() async { try { - final headers = { - 'User-Agent': 'Test Agent', - 'Keep-Alive': 'true', - }; + final headers = {'User-Agent': 'Test Agent'}; final data = dio.FormData(); final List> formDataList = [ - {"name": "text", "value": "xyz", "type": "text"}, + {"name": "text", "value": "API", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; @@ -563,7 +558,6 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/form', - queryParameters: queryParams, options: dio.Options(headers: headers), data: data, ); @@ -591,10 +585,10 @@ void main() async { try { final data = dio.FormData(); final List> formDataList = [ - {"name": "text", "value": "xyz", "type": "text"}, + {"name": "token", "value": "xyz", "type": "text"}, { "name": "imfile", - "value": "/Desktop/mp.jpg", + "value": "/Documents/up/1.png", "type": "file" } ]; @@ -613,8 +607,6 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/img', - queryParameters: queryParams, - options: dio.Options(headers: headers), data: data, ); print(response.statusCode); @@ -641,10 +633,10 @@ void main() async { try { final data = dio.FormData(); final List> formDataList = [ - {"name": "text", "value": "xyz", "type": "text"}, + {"name": "token", "value": "xyz", "type": "text"}, { "name": "imfile", - "value": "/Desktop/mp.jpg", + "value": "/Documents/up/1.png", "type": "file" } ]; @@ -663,8 +655,6 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/img', - queryParameters: queryParams, - options: dio.Options(headers: headers), data: data, ); print(response.statusCode); @@ -695,7 +685,7 @@ void main() async { }; final data = dio.FormData(); final List> formDataList = [ - {"name": "text", "value": "xyz", "type": "text"}, + {"name": "text", "value": "API", "type": "text"}, {"name": "sep", "value": "|", "type": "text"}, {"name": "times", "value": "3", "type": "text"} ]; @@ -715,7 +705,6 @@ void main() async { final response = await dio.Dio().post( 'https://api.apidash.dev/io/form', queryParameters: queryParams, - options: dio.Options(headers: headers), data: data, ); print(response.statusCode); @@ -750,7 +739,7 @@ void main() async { }; final data = dio.FormData(); final List> formDataList = [ - {"name": "text", "value": "xyz", "type": "text"}, + {"name": "token", "value": "xyz", "type": "text"}, { "name": "imfile", "value": "/Documents/up/1.png", From d56b2b6489c2cf3ce1b4c79834133b211880d8e3 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Thu, 14 Mar 2024 02:13:01 +0530 Subject: [PATCH 68/91] handling of null string and test cases updated --- lib/codegen/dart/dio.dart | 11 ++- test/codegen/dart_dio_codegen_test.dart | 108 +++++++++++++++--------- 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/lib/codegen/dart/dio.dart b/lib/codegen/dart/dio.dart index 63569e28..e9590f79 100644 --- a/lib/codegen/dart/dio.dart +++ b/lib/codegen/dart/dio.dart @@ -55,12 +55,17 @@ class DartDioCodeGen { final List> formDataList = ${json.encode(formData)}; for (var formField in formDataList) { if (formField['type'] == 'file') { + if (formField['value'] != null) { data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], filename: formField['value']), + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), )); + } } else { - data.fields.add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields.add(MapEntry(formField['name']!, formField['value']!)); + } } } '''); diff --git a/test/codegen/dart_dio_codegen_test.dart b/test/codegen/dart_dio_codegen_test.dart index 22fb3159..8f111d41 100644 --- a/test/codegen/dart_dio_codegen_test.dart +++ b/test/codegen/dart_dio_codegen_test.dart @@ -499,14 +499,18 @@ void main() async { ]; for (var formField in formDataList) { if (formField['type'] == 'file') { - data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], - filename: formField['value']), - )); + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } } else { - data.fields - .add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } } } @@ -545,14 +549,18 @@ void main() async { ]; for (var formField in formDataList) { if (formField['type'] == 'file') { - data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], - filename: formField['value']), - )); + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } } else { - data.fields - .add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } } } @@ -594,14 +602,18 @@ void main() async { ]; for (var formField in formDataList) { if (formField['type'] == 'file') { - data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], - filename: formField['value']), - )); + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } } else { - data.fields - .add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } } } @@ -642,14 +654,18 @@ void main() async { ]; for (var formField in formDataList) { if (formField['type'] == 'file') { - data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], - filename: formField['value']), - )); + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } } else { - data.fields - .add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } } } @@ -691,14 +707,18 @@ void main() async { ]; for (var formField in formDataList) { if (formField['type'] == 'file') { - data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], - filename: formField['value']), - )); + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } } else { - data.fields - .add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } } } @@ -748,14 +768,18 @@ void main() async { ]; for (var formField in formDataList) { if (formField['type'] == 'file') { - data.files.add(MapEntry( - formField['name'], - await dio.MultipartFile.fromFile(formField['value'], - filename: formField['value']), - )); + if (formField['value'] != null) { + data.files.add(MapEntry( + formField['name']!, + await dio.MultipartFile.fromFile(formField['value']!, + filename: formField['value']!), + )); + } } else { - data.fields - .add(MapEntry(formField['name'], formField['value'])); + if (formField['value'] != null) { + data.fields + .add(MapEntry(formField['name']!, formField['value']!)); + } } } From 872c5a5cd3deec9b0ca69a852ee160b3ddbe2a99 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Thu, 14 Mar 2024 03:11:53 +0530 Subject: [PATCH 69/91] fixes --- lib/codegen/codegen.dart | 6 +- lib/codegen/julia/http.dart | 49 +++------ test/codegen/julia_http_codegen_test.dart | 116 ++++++++++++++-------- 3 files changed, 96 insertions(+), 75 deletions(-) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 8a66f952..854ca241 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -58,14 +58,14 @@ class Codegen { case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(rM, boundary: boundary); case CodegenLanguage.rustActix: - return RustActixCodeGen().getCode(rM, boundary: boundary); + return RustActixCodeGen().getCode(rM, boundary: boundary); case CodegenLanguage.rustReqwest: return RustReqwestCodeGen().getCode(rM); case CodegenLanguage.rustUreq: - return RustUreqCodeGen().getCode(rM, boundary: boundary); + return RustUreqCodeGen().getCode(rM, boundary: boundary); case CodegenLanguage.goHttp: return GoHttpCodeGen().getCode(rM); - case CodegenLanguage.juliaHttpRequests: + case CodegenLanguage.juliaHttp: return JuliaHttpClientCodeGen().getCode(rM); } } diff --git a/lib/codegen/julia/http.dart b/lib/codegen/julia/http.dart index 250dadc5..b1d1e96b 100644 --- a/lib/codegen/julia/http.dart +++ b/lib/codegen/julia/http.dart @@ -9,7 +9,6 @@ import 'package:apidash/models/models.dart' show RequestModel; class JuliaHttpClientCodeGen { final String kTemplateStart = """using HTTP,JSON - url = "{{url}}" """; @@ -96,10 +95,7 @@ println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - String? getCode( - RequestModel requestModel, - String defaultUriScheme, - ) { + String? getCode(RequestModel requestModel) { try { String result = ""; bool hasQuery = false; @@ -108,13 +104,8 @@ println("Response Body:", String(response.body)) bool hasJsonBody = false; String uuid = getNewUuid(); - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; @@ -122,7 +113,6 @@ println("Response Body:", String(response.body)) var templateStartUrl = jj.Template(kTemplateStart); result += templateStartUrl.render({ "url": stripUriParams(uri), - 'isFormDataRequest': requestModel.isFormDataRequest }); if (uri.hasQuery) { @@ -136,27 +126,20 @@ println("Response Body:", String(response.body)) } } - var method = requestModel.method; - var requestBody = requestModel.requestBody; - if (kMethodsWithBody.contains(method) && requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - if (requestModel.requestBodyContentType == ContentType.json) { - hasJsonBody = true; - var templateBody = jj.Template(kTemplateJson); - result += templateBody.render({"body": requestBody}); - } else { - hasBody = true; - var templateBody = jj.Template(kTemplateBody); - result += templateBody.render({"body": requestBody}); - } - } + if (requestModel.hasJsonData) { + hasJsonBody = true; + var templateBody = jj.Template(kTemplateJson); + result += templateBody.render({"body": requestModel.requestBody}); + } else if (requestModel.hasTextData) { + hasBody = true; + var templateBody = jj.Template(kTemplateBody); + result += templateBody.render({"body": requestModel.requestBody}); } var headersList = requestModel.enabledRequestHeaders; if (headersList != null || hasBody) { var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { var formHeaderTemplate = jj.Template(kTemplateFormHeaderContentType); headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ @@ -175,7 +158,7 @@ println("Response Body:", String(response.body)) result += templateHeaders.render({"headers": headersString}); } } - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { @@ -186,22 +169,22 @@ println("Response Body:", String(response.body)) } var templateRequest = jj.Template(kTemplateRequest); result += templateRequest.render({ - "method": method.name.toLowerCase(), + "method": requestModel.method.name.toLowerCase(), }); if (hasQuery) { result += kStringRequestParams; } - if (hasBody || requestModel.isFormDataRequest) { + if (hasBody || requestModel.hasFormData) { result += kStringRequestBody; } - if (hasJsonBody || requestModel.isFormDataRequest) { + if (hasJsonBody || requestModel.hasFormData) { result += kStringRequestJson; } - if (hasHeaders || requestModel.isFormDataRequest) { + if (hasHeaders || requestModel.hasFormData) { result += kStringRequestHeaders; } diff --git a/test/codegen/julia_http_codegen_test.dart b/test/codegen/julia_http_codegen_test.dart index eae1f7a5..2b5161eb 100644 --- a/test/codegen/julia_http_codegen_test.dart +++ b/test/codegen/julia_http_codegen_test.dart @@ -1,15 +1,16 @@ -import 'package:apidash/codegen/julia/http.dart'; -import '../request_models.dart'; +import 'package:apidash/codegen/codegen.dart'; +import 'package:apidash/consts.dart'; import 'package:test/test.dart'; +import '../request_models.dart'; void main() { - final juliaHttpClientCodeGen = JuliaHttpClientCodeGen(); + final codeGen = Codegen(); group('GET Request', () { test('GET 1', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com" +url = "https://api.apidash.dev" response = HTTP.get(url) @@ -17,13 +18,14 @@ response = HTTP.get(url) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet1, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet1, "https"), expectedCode); }); test('GET 2', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/country/data" +url = "https://api.apidash.dev/country/data" params = Dict( @@ -35,13 +37,14 @@ response = HTTP.get(url, query=params) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet2, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet2, "https"), expectedCode); }); test('GET 3', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/country/data" +url = "https://api.apidash.dev/country/data" params = Dict( @@ -53,13 +56,14 @@ response = HTTP.get(url, query=params) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet3, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet3, "https"), expectedCode); }); test('GET 4', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/humanize/social" +url = "https://api.apidash.dev/humanize/social" params = Dict( @@ -75,7 +79,8 @@ response = HTTP.get(url, query=params) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet4, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet4, "https"), expectedCode); }); @@ -94,7 +99,8 @@ response = HTTP.get(url, headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet5, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet5, "https"), expectedCode); }); @@ -117,14 +123,15 @@ response = HTTP.get(url, query=params, headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet6, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet6, "https"), expectedCode); }); test('GET 7', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com" +url = "https://api.apidash.dev" response = HTTP.get(url) @@ -132,7 +139,8 @@ response = HTTP.get(url) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet7, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet7, "https"), expectedCode); }); @@ -155,14 +163,15 @@ response = HTTP.get(url, query=params, headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet8, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet8, "https"), expectedCode); }); test('GET 9', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/humanize/social" +url = "https://api.apidash.dev/humanize/social" params = Dict( @@ -175,14 +184,15 @@ response = HTTP.get(url, query=params) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet9, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelGet9, "https"), expectedCode); }); test('GET 10', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/humanize/social" +url = "https://api.apidash.dev/humanize/social" headers = Dict( @@ -194,14 +204,16 @@ response = HTTP.get(url, headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet10, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelGet10, "https"), expectedCode); }); test('GET 11', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/humanize/social" +url = "https://api.apidash.dev/humanize/social" params = Dict( @@ -218,14 +230,16 @@ response = HTTP.get(url, query=params, headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet11, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelGet11, "https"), expectedCode); }); test('GET 12', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/humanize/social" +url = "https://api.apidash.dev/humanize/social" response = HTTP.get(url) @@ -233,7 +247,9 @@ response = HTTP.get(url) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelGet12, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelGet12, "https"), expectedCode); }); }); @@ -242,7 +258,7 @@ println("Response Body:", String(response.body)) test('HEAD 1', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com" +url = "https://api.apidash.dev" response = HTTP.head(url) @@ -250,14 +266,16 @@ response = HTTP.head(url) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelHead1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelHead1, "https"), expectedCode); }); test('HEAD 2', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com" +url = "https://api.apidash.dev" response = HTTP.head(url) @@ -265,7 +283,9 @@ response = HTTP.head(url) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelHead2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelHead2, "https"), expectedCode); }); }); @@ -274,7 +294,7 @@ println("Response Body:", String(response.body)) test('POST 1', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/case/lower" +url = "https://api.apidash.dev/case/lower" payload = Dict( @@ -290,18 +310,25 @@ response = HTTP.post(url, payload=payload, headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelPost1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPost1, "https"), expectedCode); }); test('POST 2', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/case/lower" +url = "https://api.apidash.dev/case/lower" payload = Dict( -"text"=> "I LOVE Flutter" +"text"=> "I LOVE Flutter", +"flag"=> null, +"male"=> true, +"female"=> false, +"no"=> 1.2, +"arr"=> ["null", "true", "false", null] ) response = HTTP.post(url, JSON.json(payload)) @@ -309,13 +336,15 @@ response = HTTP.post(url, JSON.json(payload)) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelPost2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPost2, "https"), expectedCode); }); test('POST 3', () { const expectedCode = r"""using HTTP,JSON -url = "https://api.foss42.com/case/lower" +url = "https://api.apidash.dev/case/lower" payload = Dict( @@ -331,7 +360,9 @@ response = HTTP.post(url, JSON.json(payload), headers=headers) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelPost3, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPost3, "https"), expectedCode); }); }); @@ -352,7 +383,8 @@ response = HTTP.put(url, JSON.json(payload)) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelPut1, "https"), + expect( + codeGen.getCode(CodegenLanguage.juliaHttp, requestModelPut1, "https"), expectedCode); }); }); @@ -373,7 +405,9 @@ response = HTTP.patch(url, JSON.json(payload)) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelPatch1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelPatch1, "https"), expectedCode); }); }); @@ -389,7 +423,9 @@ response = HTTP.delete(url) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelDelete1, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelDelete1, "https"), expectedCode); }); test('DELETE 2', () { @@ -408,7 +444,9 @@ response = HTTP.delete(url, JSON.json(payload)) println("Status Code:", response.status) println("Response Body:", String(response.body)) """; - expect(juliaHttpClientCodeGen.getCode(requestModelDelete2, "https"), + expect( + codeGen.getCode( + CodegenLanguage.juliaHttp, requestModelDelete2, "https"), expectedCode); }); }); From 12177fcff3a14e4ca91e5a4a33142dc4e9dc244d Mon Sep 17 00:00:00 2001 From: Elise Date: Thu, 14 Mar 2024 00:05:55 -0700 Subject: [PATCH 70/91] Add codegen for java okhttp and test cases --- README.md | 1 + lib/codegen/codegen.dart | 3 + lib/codegen/java/okhttp.dart | 190 ++++ lib/consts.dart | 1 + test/codegen/java_okhttp_codegen_test.dart | 1032 ++++++++++++++++++++ 5 files changed, 1227 insertions(+) create mode 100644 lib/codegen/java/okhttp.dart create mode 100644 test/codegen/java_okhttp_codegen_test.dart diff --git a/README.md b/README.md index 1beea998..c2760f5d 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ API Dash currently supports API integration code generation for the following la | Python | `http.client` | | Python | `requests` | | Kotlin | `okhttp3` | +| Java | `okhttp3` | We welcome contributions to support other programming languages/libraries/frameworks. Please check out more details [here](https://github.com/foss42/apidash/discussions/80). diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 854ca241..2409bb63 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -15,6 +15,7 @@ import 'js/fetch.dart'; import 'others/har.dart'; import 'others/curl.dart'; import 'julia/http.dart'; +import 'java/okhttp.dart'; class Codegen { String? getCode( @@ -52,6 +53,8 @@ class Codegen { return FetchCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.kotlinOkHttp: return KotlinOkHttpCodeGen().getCode(rM); + case CodegenLanguage.javaOkHttp: + return JavaOkHttpCodeGen().getCode(rM); case CodegenLanguage.pythonHttpClient: return PythonHttpClientCodeGen() .getCode(rM, boundary: boundary ?? getNewUuid()); diff --git a/lib/codegen/java/okhttp.dart b/lib/codegen/java/okhttp.dart new file mode 100644 index 00000000..ac7a6b09 --- /dev/null +++ b/lib/codegen/java/okhttp.dart @@ -0,0 +1,190 @@ +import 'dart:convert'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, stripUriParams; +import '../../models/request_model.dart'; +import 'package:apidash/consts.dart'; + +class JavaOkHttpCodeGen { + final String kTemplateStart = """ +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response;{{importForQuery}}{{importForBody}}{{importForFormData}} + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + +"""; + + final String kStringImportForQuery = """ + +import okhttp3.HttpUrl;"""; + + final String kStringImportForBody = """ + +import okhttp3.RequestBody; +import okhttp3.MediaType;"""; + + final String kStringImportForFormData = """ + +import okhttp3.RequestBody; +import okhttp3.MultipartBody;"""; + + final String kTemplateUrl = ''' + + String url = "{{url}}"; + +'''; + + final String kTemplateUrlQuery = ''' + + HttpUrl url = HttpUrl.parse("{{url}}").newBuilder() + {{params}} + .build(); + +'''; + + String kTemplateRequestBody = ''' + + MediaType mediaType = MediaType.parse("{{contentType}}"); + + RequestBody body = RequestBody.create({{body}}, mediaType); + +'''; + + final String kStringRequestStart = """ + + Request request = new Request.Builder() + .url(url) +"""; + + final String kTemplateRequestEnd = """ + .{{method}}({{hasBody}}) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} + +"""; +// Converting list of form data objects to kolin multi part data + String kFormDataBody = ''' + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + {%- for item in formDataList -%} + {% if item.type == 'file' %} + .addFormDataPart("{{ item.name }}",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("{{ item.value }}"))) + {%- else %} + .addFormDataPart("{{ item.name }}","{{ item.value }}") + {%- endif %} + {%- endfor %} + .build(); + +'''; + + String? getCode( + RequestModel requestModel, + ) { + try { + String result = ""; + bool hasQuery = false; + bool hasBody = false; + bool hasFormData = false; + + var rec = getValidRequestUri( + requestModel.url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + + if (uri != null) { + String url = stripUriParams(uri); + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + hasQuery = true; + var templateParams = jj.Template(kTemplateUrlQuery); + result += templateParams + .render({"url": url, "params": getQueryParams(params)}); + } + } + if (!hasQuery) { + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + } + + var method = requestModel.method; + var requestBody = requestModel.requestBody; + if (requestModel.hasFormData) { + hasFormData = true; + var formDataTemplate = jj.Template(kFormDataBody); + + result += formDataTemplate.render({ + "formDataList": requestModel.formDataMapList, + }); + } else if (kMethodsWithBody.contains(method) && requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + hasBody = true; + String contentType = requestModel.requestBodyContentType.header; + var templateBody = jj.Template(kTemplateRequestBody); + result += templateBody.render({ + "contentType": contentType, + "body": kEncoder.convert(requestBody) + }); + } + } + + var templateStart = jj.Template(kTemplateStart); + var stringStart = templateStart.render({ + "importForQuery": hasQuery ? kStringImportForQuery : "", + "importForBody": hasBody ? kStringImportForBody : "", + "importForFormData": hasFormData ? kStringImportForFormData : "" + }); + + result = stringStart + result; + result += kStringRequestStart; + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + result += getHeaders(headers); + } + } + + var templateRequestEnd = jj.Template(kTemplateRequestEnd); + result += templateRequestEnd.render({ + "method": method.name.toLowerCase(), + "hasBody": (hasBody || requestModel.hasFormData) ? "body" : "", + }); + } + return result; + } catch (e) { + return null; + } + } + + 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 = ""; + for (final k in headers.keys) { + result = """$result .addHeader("$k", "${headers[k]}")\n"""; + } + return result; + } +} \ No newline at end of file diff --git a/lib/consts.dart b/lib/consts.dart index a557023d..b912db9b 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -272,6 +272,7 @@ enum CodegenLanguage { nodejsAxios("node.js (axios)", "javascript", "js"), nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), + javaOkHttp("Java (okhttp3)", "java", 'java'), pythonHttpClient("Python (http.client)", "python", "py"), pythonRequests("Python (requests)", "python", "py"), rustActix("Rust (Actix Client)", "rust", "rs"), diff --git a/test/codegen/java_okhttp_codegen_test.dart b/test/codegen/java_okhttp_codegen_test.dart new file mode 100644 index 00000000..20a8a17a --- /dev/null +++ b/test/codegen/java_okhttp_codegen_test.dart @@ -0,0 +1,1032 @@ +import 'package:apidash/codegen/java/okhttp.dart'; +import 'package:test/test.dart'; +import '../request_models.dart'; + +void main() { + final javaOkHttpCodeGen = JavaOkHttpCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet1), expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/country/data").newBuilder() + .addQueryParameter("code", "US") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet2), expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/country/data").newBuilder() + .addQueryParameter("code", "IND") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet3), expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/humanize/social").newBuilder() + .addQueryParameter("num", "8700000") + .addQueryParameter("digits", "3") + .addQueryParameter("system", "SS") + .addQueryParameter("add_space", "true") + .addQueryParameter("trailing_zeros", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet4), expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.github.com/repos/foss42/apidash"; + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet5), expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.github.com/repos/foss42/apidash").newBuilder() + .addQueryParameter("raw", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet6), expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet7), expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.github.com/repos/foss42/apidash").newBuilder() + .addQueryParameter("raw", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet8), expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/humanize/social").newBuilder() + .addQueryParameter("num", "8700000") + .addQueryParameter("add_space", "true") + .build(); + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet9), expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/humanize/social"; + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode( + requestModelGet10, + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/humanize/social").newBuilder() + .addQueryParameter("num", "8700000") + .addQueryParameter("digits", "3") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet11), expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/humanize/social"; + + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelGet12), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .head() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelHead1), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev"; + + Request request = new Request.Builder() + .url(url) + .head() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect( + javaOkHttpCodeGen.getCode(requestModelHead2), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/case/lower"; + + MediaType mediaType = MediaType.parse("text/plain"); + + RequestBody body = RequestBody.create("{\n\"text\": \"I LOVE Flutter\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost1), expectedCode); + }); + + test('POST 2', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/case/lower"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost2), expectedCode); + }); + + test('POST 3', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/case/lower"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"text\": \"I LOVE Flutter\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost3), expectedCode); + }); + + test('POST 4', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/form"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost4), expectedCode); + }); + + test('POST 5', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/form"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost5), expectedCode); + }); + + test('POST 6', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/img"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("token","xyz") + .addFormDataPart("imfile",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("/Documents/up/1.png"))) + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost6), expectedCode); + }); + + test('POST 7', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://api.apidash.dev/io/img"; + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("token","xyz") + .addFormDataPart("imfile",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("/Documents/up/1.png"))) + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost7), expectedCode); + }); + + test('POST 8', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/io/form").newBuilder() + .addQueryParameter("size", "2") + .addQueryParameter("len", "3") + .build(); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost8), expectedCode); + }); + + test('POST 9', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; +import okhttp3.RequestBody; +import okhttp3.MultipartBody; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + HttpUrl url = HttpUrl.parse("https://api.apidash.dev/io/img").newBuilder() + .addQueryParameter("size", "2") + .addQueryParameter("len", "3") + .build(); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("token","xyz") + .addFormDataPart("imfile",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("/Documents/up/1.png"))) + .build(); + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .addHeader("Keep-Alive", "true") + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPost9), expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .put(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPut1), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .patch(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect( + javaOkHttpCodeGen.getCode(requestModelPatch1), expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + Request request = new Request.Builder() + .url(url) + .delete() + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +"""; + expect(javaOkHttpCodeGen.getCode(requestModelDelete1), + expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r'''import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.MediaType; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + String url = "https://reqres.in/api/users/2"; + + MediaType mediaType = MediaType.parse("application/json"); + + RequestBody body = RequestBody.create("{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}", mediaType); + + Request request = new Request.Builder() + .url(url) + .delete(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println(response.code()); + if (response.body() != null) { + System.out.println(response.body().string()); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } +} +'''; + expect(javaOkHttpCodeGen.getCode(requestModelDelete2), + expectedCode); + }); + }); +} \ No newline at end of file From 4eb67294d7198c4827f1b2e390a3d51306c4fab8 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Thu, 14 Mar 2024 13:55:21 +0530 Subject: [PATCH 71/91] test cases added from POST4 to POST9 for dio http --- test/codegen/dart_http_codegen_test.dart | 295 +++++++++++++++++++++++ 1 file changed, 295 insertions(+) diff --git a/test/codegen/dart_http_codegen_test.dart b/test/codegen/dart_http_codegen_test.dart index b8530555..ce634d23 100644 --- a/test/codegen/dart_http_codegen_test.dart +++ b/test/codegen/dart_http_codegen_test.dart @@ -504,6 +504,301 @@ void main() async { codeGen.getCode(CodegenLanguage.dartHttp, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/form'); + + final formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (Map formData in formDataList) { + if (formData['type'] == 'text') { + request.fields.addAll({formData['name']: formData['value']}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + formData['name'], + formData['value'], + ), + ); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost4, "https"), + expectedCode); + }); + test('POST 5', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/form'); + + var headers = {'User-Agent': 'Test Agent'}; + + final formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (Map formData in formDataList) { + if (formData['type'] == 'text') { + request.fields.addAll({formData['name']: formData['value']}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + formData['name'], + formData['value'], + ), + ); + } + } + + request.headers.addAll(headers); + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost5, "https"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/img'); + + final formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "imfile", "value": "/Documents/up/1.png", "type": "file"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (Map formData in formDataList) { + if (formData['type'] == 'text') { + request.fields.addAll({formData['name']: formData['value']}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + formData['name'], + formData['value'], + ), + ); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost6, "https"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/img'); + + final formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "imfile", "value": "/Documents/up/1.png", "type": "file"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (Map formData in formDataList) { + if (formData['type'] == 'text') { + request.fields.addAll({formData['name']: formData['value']}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + formData['name'], + formData['value'], + ), + ); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost7, "https"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/form'); + + var queryParams = { + 'size': '2', + 'len': '3', + }; + uri = uri.replace(queryParameters: queryParams); + + final formDataList = [ + {"name": "text", "value": "API", "type": "text"}, + {"name": "sep", "value": "|", "type": "text"}, + {"name": "times", "value": "3", "type": "text"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (Map formData in formDataList) { + if (formData['type'] == 'text') { + request.fields.addAll({formData['name']: formData['value']}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + formData['name'], + formData['value'], + ), + ); + } + } + + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost8, "https"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""import 'package:http/http.dart' as http; + +void main() async { + var uri = Uri.parse('https://api.apidash.dev/io/img'); + + var queryParams = { + 'size': '2', + 'len': '3', + }; + uri = uri.replace(queryParameters: queryParams); + + var headers = { + 'User-Agent': 'Test Agent', + 'Keep-Alive': 'true', + }; + + final formDataList = [ + {"name": "token", "value": "xyz", "type": "text"}, + {"name": "imfile", "value": "/Documents/up/1.png", "type": "file"} + ]; + final request = http.MultipartRequest( + "POST", + uri, + ); + for (Map formData in formDataList) { + if (formData['type'] == 'text') { + request.fields.addAll({formData['name']: formData['value']}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + formData['name'], + formData['value'], + ), + ); + } + } + + request.headers.addAll(headers); + final response = await request.send(); + final responseBody = await response.stream.bytesToString(); + int statusCode = response.statusCode; + + if (statusCode >= 200 && statusCode < 300) { + print('Status Code: $statusCode'); + print('Response Body: :$responseBody'); + } else { + print('Error Status Code: $statusCode'); + print('Error Response Body: :$responseBody'); + } +} +"""; + expect( + codeGen.getCode( + CodegenLanguage.dartHttp, requestModelPost9, "https"), + expectedCode); + }); + }); group('PUT Request', () { From 926ca3ad96bfd3125fc012b988b06d1fc9bde3f8 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Thu, 14 Mar 2024 18:03:23 +0530 Subject: [PATCH 72/91] handled null cases and updated test cases POST4 to POST9 --- lib/codegen/dart/http.dart | 34 +++-- test/codegen/dart_http_codegen_test.dart | 180 ++++++++++++++++------- 2 files changed, 149 insertions(+), 65 deletions(-) diff --git a/lib/codegen/dart/http.dart b/lib/codegen/dart/http.dart index 89e8062c..8419757c 100644 --- a/lib/codegen/dart/http.dart +++ b/lib/codegen/dart/http.dart @@ -122,17 +122,29 @@ class DartHttpCodeGen { final addHeaders = refer('request.headers.addAll').call([refer('headers')]); const multiPartList = Code(''' - for (Map formData in formDataList){ - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); - } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); - } + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } + } else { + print('Error: formData is null.'); + } } '''); var multiPartRequestSend = diff --git a/test/codegen/dart_http_codegen_test.dart b/test/codegen/dart_http_codegen_test.dart index ce634d23..6bf16114 100644 --- a/test/codegen/dart_http_codegen_test.dart +++ b/test/codegen/dart_http_codegen_test.dart @@ -519,16 +519,28 @@ void main() async { "POST", uri, ); - for (Map formData in formDataList) { - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); + print('Error: formData is null.'); } } @@ -567,16 +579,28 @@ void main() async { "POST", uri, ); - for (Map formData in formDataList) { - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); + print('Error: formData is null.'); } } @@ -613,16 +637,28 @@ void main() async { "POST", uri, ); - for (Map formData in formDataList) { - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); + print('Error: formData is null.'); } } @@ -658,16 +694,28 @@ void main() async { "POST", uri, ); - for (Map formData in formDataList) { - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); + print('Error: formData is null.'); } } @@ -710,16 +758,28 @@ void main() async { "POST", uri, ); - for (Map formData in formDataList) { - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); + print('Error: formData is null.'); } } @@ -766,16 +826,28 @@ void main() async { "POST", uri, ); - for (Map formData in formDataList) { - if (formData['type'] == 'text') { - request.fields.addAll({formData['name']: formData['value']}); + for (var formData in formDataList) { + if (formData != null) { + final name = formData['name']; + final value = formData['value']; + final type = formData['type']; + + if (name != null && value != null && type != null) { + if (type == 'text') { + request.fields.addAll({name: value}); + } else { + request.files.add( + await http.MultipartFile.fromPath( + name, + value, + ), + ); + } + } else { + print('Error: formData has null name, value, or type.'); + } } else { - request.files.add( - await http.MultipartFile.fromPath( - formData['name'], - formData['value'], - ), - ); + print('Error: formData is null.'); } } From c37fed89975176a1498afaa4cf205c9d3cc1b269 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Thu, 14 Mar 2024 02:36:06 +0530 Subject: [PATCH 73/91] fix(codgen-fetch): fix the broken codegen for multipart requests as well as refactor it --- lib/codegen/js/fetch.dart | 104 ++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 55 deletions(-) diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index 2ff88a9b..e1da4d4c 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show padMultilineString, requestModelToHARJsonRequest; @@ -11,14 +10,16 @@ class FetchCodeGen { final bool isNodeJs; String kStringImportNode = """ -import fetch from 'node-fetch'; -{% if hasFormData %}const fs = require('fs');{% endif %} +import fetch from 'node-fetch' +{% if hasFormData -%} +import { fileFromSync, FormData } from 'node-fetch' +{% endif %} """; - String kTemplateStart = """let url = '{{url}}'; + String kTemplateStart = """const url = '{{url}}'; -let options = { +const options = { method: '{{method}}' """; @@ -27,72 +28,62 @@ let options = { """; String kTemplateBody = """, - body: -{{body}} + body: {{body}} """; String kMultiPartBodyTemplate = r''' -async function buildDataList(fields) { - var formdata = new FormData(); - for (const field of fields) { - const name = field.name || ''; - const value = field.value || ''; - const type = field.type || 'text'; - - if (type === 'text') { - formdata.append(name, value); - } else if (type === 'file') { - formdata.append(name,{% if isNodeJs %} fs.createReadStream(value){% else %} fileInput.files[0],value{% endif %}); - } - } - return formdata; -} - -const payload = buildDataList({{fields_list}}); +payload.append("{{name}}", {{value}}) '''; String kStringRequest = """ }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:\${err}`); + }); """; - String? getCode( - RequestModel requestModel, - ) { + String? getCode(RequestModel requestModel) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ "hasFormData": requestModel.hasFormData, }); - String result = isNodeJs ? importsData : ""; + String result = isNodeJs + ? importsData + : requestModel.hasFormData + ? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration\n\n" + : ""; if (requestModel.hasFormData) { + result += "const payload = new FormData();\n"; var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); - result += templateMultiPartBody.render({ - "isNodeJs": isNodeJs, - "fields_list": json.encode(requestModel.formDataMapList), - }); + var formFileCounter = 1; + for (var element in requestModel.formDataMapList) { + result += templateMultiPartBody.render({ + "name": element["name"], + "value": element["type"] == "text" + ? "\"${element["value"]}\"" + : isNodeJs + ? "fileFromSync(\"${element["value"]}\")" + : "fileInput$formFileCounter.files[0]" + }); + if (element["type"] != "text") formFileCounter++; + } + result += "\n"; } - var harJson = requestModelToHARJsonRequest( - requestModel, - useEnabled: true, - ); + var harJson = + requestModelToHARJsonRequest(requestModel, useEnabled: true); var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ @@ -105,15 +96,18 @@ fetch(url, options) if (headers.isNotEmpty) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; - if (requestModel.hasFormData) { - m[kHeaderContentType] = "multipart/form-data"; - } for (var i in headers) { + // fetch can automatically add the Content-Type header when FormData is passed as body + if (i["name"] == "Content-Type" && requestModel.hasFormData) { + continue; + } m[i["name"]] = i["value"]; } - result += templateHeader.render({ - "headers": padMultilineString(kEncoder.convert(m), 2), - }); + if (m.isNotEmpty) { + result += templateHeader.render({ + "headers": padMultilineString(kEncoder.convert(m), 2), + }); + } } if (harJson["postData"]?["text"] != null) { From 2be85a11157bb8034ad18f881f7fe0f61931af9f Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Thu, 14 Mar 2024 02:45:12 +0530 Subject: [PATCH 74/91] test(fetch): update tests with respect to new changes --- test/codegen/js_fetch_codegen_test.dart | 806 +++++++++++-------- test/codegen/nodejs_fetch_codegen_test.dart | 836 ++++++++++++-------- 2 files changed, 967 insertions(+), 675 deletions(-) diff --git a/test/codegen/js_fetch_codegen_test.dart b/test/codegen/js_fetch_codegen_test.dart index 4f070142..c6863709 100644 --- a/test/codegen/js_fetch_codegen_test.dart +++ b/test/codegen/js_fetch_codegen_test.dart @@ -8,26 +8,23 @@ void main() { group('GET Request', () { test('GET 1', () { - const expectedCode = r"""let url = 'https://api.apidash.dev'; + const expectedCode = r"""const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet1, "https"), @@ -36,26 +33,23 @@ fetch(url, options) test('GET 2', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/country/data?code=US'; + r"""const url = 'https://api.apidash.dev/country/data?code=US'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet2, "https"), @@ -64,26 +58,23 @@ fetch(url, options) test('GET 3', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/country/data?code=IND'; + r"""const url = 'https://api.apidash.dev/country/data?code=IND'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet3, "https"), @@ -92,26 +83,23 @@ fetch(url, options) test('GET 4', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; + r"""const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet4, "https"), @@ -120,29 +108,26 @@ fetch(url, options) test('GET 5', () { const expectedCode = - r"""let url = 'https://api.github.com/repos/foss42/apidash'; + r"""const url = 'https://api.github.com/repos/foss42/apidash'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet5, "https"), @@ -151,29 +136,26 @@ fetch(url, options) test('GET 6', () { const expectedCode = - r"""let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; + r"""const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet6, "https"), @@ -181,26 +163,23 @@ fetch(url, options) }); test('GET 7', () { - const expectedCode = r"""let url = 'https://api.apidash.dev'; + const expectedCode = r"""const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet7, "https"), @@ -209,29 +188,26 @@ fetch(url, options) test('GET 8', () { const expectedCode = - r"""let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; + r"""const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet8, "https"), @@ -240,26 +216,23 @@ fetch(url, options) test('GET 9', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'; + r"""const url = 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet9, "https"), @@ -268,29 +241,26 @@ fetch(url, options) test('GET 10', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/humanize/social'; + r"""const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -303,29 +273,26 @@ fetch(url, options) test('GET 11', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3'; + r"""const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet11, "https"), @@ -334,26 +301,23 @@ fetch(url, options) test('GET 12', () { const expectedCode = - r"""let url = 'https://api.apidash.dev/humanize/social'; + r"""const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelGet12, "https"), @@ -363,26 +327,23 @@ fetch(url, options) group('HEAD Request', () { test('HEAD 1', () { - const expectedCode = r"""let url = 'https://api.apidash.dev'; + const expectedCode = r"""const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelHead1, "https"), @@ -390,26 +351,23 @@ fetch(url, options) }); test('HEAD 2', () { - const expectedCode = r"""let url = 'http://api.apidash.dev'; + const expectedCode = r"""const url = 'http://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelHead2, "http"), @@ -419,31 +377,27 @@ fetch(url, options) group('POST Request', () { test('POST 1', () { - const expectedCode = r"""let url = 'https://api.apidash.dev/case/lower'; + const expectedCode = r"""const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "text/plain" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost1, "https"), @@ -451,31 +405,27 @@ fetch(url, options) }); test('POST 2', () { - const expectedCode = r"""let url = 'https://api.apidash.dev/case/lower'; + const expectedCode = r"""const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json" }, - body: -"{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" + body: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost2, "https"), @@ -483,66 +433,279 @@ fetch(url, options) }); test('POST 3', () { - const expectedCode = r"""let url = 'https://api.apidash.dev/case/lower'; + const expectedCode = r"""const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json", "User-Agent": "Test Agent" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost4, + "https", + ), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost5, + "https", + ), + expectedCode); + }); + test('POST 6', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileInput1.files[0]) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost6, + "https", + ), + expectedCode); + }); + test('POST 7', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileInput1.files[0]) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost7, + "https", + ), + expectedCode); + }); + test('POST 8', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form?size=2&len=3'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost8, + "https", + ), + expectedCode); + }); + test('POST 9', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileInput1.files[0]) + +const url = 'https://api.apidash.dev/io/img?size=2&len=3'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent", + "Keep-Alive": "true" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsFetch, + requestModelPost9, + "https", + ), + expectedCode); + }); }); group('PUT Request', () { test('PUT 1', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PUT', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" + body: "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelPut1, "https"), @@ -552,31 +715,27 @@ fetch(url, options) group('PATCH Request', () { test('PATCH 1', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PATCH', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode(CodegenLanguage.jsFetch, requestModelPatch1, "https"), @@ -586,26 +745,23 @@ fetch(url, options) group('DELETE Request', () { test('DELETE 1', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -614,31 +770,27 @@ fetch(url, options) }); test('DELETE 2', () { - const expectedCode = r"""let url = 'https://reqres.in/api/users/2'; + const expectedCode = r"""const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( diff --git a/test/codegen/nodejs_fetch_codegen_test.dart b/test/codegen/nodejs_fetch_codegen_test.dart index 831fd2e0..4b81bae0 100644 --- a/test/codegen/nodejs_fetch_codegen_test.dart +++ b/test/codegen/nodejs_fetch_codegen_test.dart @@ -8,28 +8,25 @@ void main() { group('GET Request', () { test('GET 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev'; +const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -38,28 +35,25 @@ fetch(url, options) }); test('GET 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/country/data?code=US'; +const url = 'https://api.apidash.dev/country/data?code=US'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -68,28 +62,25 @@ fetch(url, options) }); test('GET 3', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/country/data?code=IND'; +const url = 'https://api.apidash.dev/country/data?code=IND'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -98,28 +89,25 @@ fetch(url, options) }); test('GET 4', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; +const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -128,31 +116,28 @@ fetch(url, options) }); test('GET 5', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.github.com/repos/foss42/apidash'; +const url = 'https://api.github.com/repos/foss42/apidash'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -161,31 +146,28 @@ fetch(url, options) }); test('GET 6', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; +const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -194,28 +176,25 @@ fetch(url, options) }); test('GET 7', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev'; +const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -224,31 +203,28 @@ fetch(url, options) }); test('GET 8', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.github.com/repos/foss42/apidash?raw=true'; +const url = 'https://api.github.com/repos/foss42/apidash?raw=true'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -257,28 +233,25 @@ fetch(url, options) }); test('GET 9', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'; +const url = 'https://api.apidash.dev/humanize/social?num=8700000&add_space=true'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -287,31 +260,28 @@ fetch(url, options) }); test('GET 10', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/humanize/social'; +const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -323,31 +293,28 @@ fetch(url, options) }); test('GET 11', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3'; +const url = 'https://api.apidash.dev/humanize/social?num=8700000&digits=3'; -let options = { +const options = { method: 'GET', headers: { "User-Agent": "Test Agent" } }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -356,28 +323,25 @@ fetch(url, options) }); test('GET 12', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/humanize/social'; +const url = 'https://api.apidash.dev/humanize/social'; -let options = { +const options = { method: 'GET' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -388,28 +352,25 @@ fetch(url, options) group('HEAD Request', () { test('HEAD 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev'; +const url = 'https://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -418,28 +379,25 @@ fetch(url, options) }); test('HEAD 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'http://api.apidash.dev'; +const url = 'http://api.apidash.dev'; -let options = { +const options = { method: 'HEAD' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -450,33 +408,29 @@ fetch(url, options) group('POST Request', () { test('POST 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/case/lower'; +const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "text/plain" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -485,33 +439,29 @@ fetch(url, options) }); test('POST 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/case/lower'; +const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json" }, - body: -"{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" + body: "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -520,71 +470,272 @@ fetch(url, options) }); test('POST 3', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://api.apidash.dev/case/lower'; +const url = 'https://api.apidash.dev/case/lower'; -let options = { +const options = { method: 'POST', headers: { "Content-Type": "application/json", "User-Agent": "Test Agent" }, - body: -"{\n\"text\": \"I LOVE Flutter\"\n}" + body: "{\n\"text\": \"I LOVE Flutter\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( CodegenLanguage.nodejsFetch, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost4, "https", + boundary: "test"), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost5, "https", + boundary: "test"), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileFromSync("/Documents/up/1.png")) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost6, "https", + boundary: "test"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileFromSync("/Documents/up/1.png")) + +const url = 'https://api.apidash.dev/io/img'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost7, "https", + boundary: "test"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("text", "API") +payload.append("sep", "|") +payload.append("times", "3") + +const url = 'https://api.apidash.dev/io/form?size=2&len=3'; + +const options = { + method: 'POST', + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost8, "https", + boundary: "test"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""import fetch from 'node-fetch' +import { fileFromSync, FormData } from 'node-fetch' + +const payload = new FormData(); +payload.append("token", "xyz") +payload.append("imfile", fileFromSync("/Documents/up/1.png")) + +const url = 'https://api.apidash.dev/io/img?size=2&len=3'; + +const options = { + method: 'POST', + headers: { + "User-Agent": "Test Agent", + "Keep-Alive": "true" + }, + body: payload +}; + +fetch(url, options) + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsFetch, requestModelPost9, "https", + boundary: "test"), + expectedCode); + }); }); group('PUT Request', () { test('PUT 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PUT', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" + body: "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -595,33 +746,29 @@ fetch(url, options) group('PATCH Request', () { test('PATCH 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'PATCH', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -632,28 +779,25 @@ fetch(url, options) group('DELETE Request', () { test('DELETE 1', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE' }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( @@ -662,33 +806,29 @@ fetch(url, options) }); test('DELETE 2', () { - const expectedCode = r"""import fetch from 'node-fetch'; + const expectedCode = r"""import fetch from 'node-fetch' -let url = 'https://reqres.in/api/users/2'; +const url = 'https://reqres.in/api/users/2'; -let options = { +const options = { method: 'DELETE', headers: { "Content-Type": "application/json" }, - body: -"{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" + body: "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}" }; -let status; fetch(url, options) - .then(res => { - status = res.status; - return res.json() - }) - .then(body => { - console.log(status); - console.log(body); - }) - .catch(err => { - console.log(status); - console.error('error:' + err); - }); + .then(res => { + console.log(res.status); + return res.text() + }) + .then(body => { + console.log(body); + }) + .catch(err => { + console.error(`error:${err}`); + }); """; expect( codeGen.getCode( From 3e2cc9026308548183548d50161409361634d64d Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 04:50:32 +0530 Subject: [PATCH 75/91] fixes --- lib/codegen/js/fetch.dart | 3 ++- test/codegen/nodejs_fetch_codegen_test.dart | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index e1da4d4c..caf27a47 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -12,7 +12,7 @@ class FetchCodeGen { String kStringImportNode = """ import fetch from 'node-fetch' {% if hasFormData -%} -import { fileFromSync, FormData } from 'node-fetch' +import { {% if hasFileInFormData %}fileFromSync, {% endif %}FormData } from 'node-fetch' {% endif %} """; @@ -57,6 +57,7 @@ fetch(url, options) jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ "hasFormData": requestModel.hasFormData, + "hasFileInFormData": requestModel.hasFileInFormData, }); String result = isNodeJs diff --git a/test/codegen/nodejs_fetch_codegen_test.dart b/test/codegen/nodejs_fetch_codegen_test.dart index 4b81bae0..88ca7072 100644 --- a/test/codegen/nodejs_fetch_codegen_test.dart +++ b/test/codegen/nodejs_fetch_codegen_test.dart @@ -502,7 +502,7 @@ fetch(url, options) }); test('POST 4', () { const expectedCode = r"""import fetch from 'node-fetch' -import { fileFromSync, FormData } from 'node-fetch' +import { FormData } from 'node-fetch' const payload = new FormData(); payload.append("text", "API") @@ -537,7 +537,7 @@ fetch(url, options) test('POST 5', () { const expectedCode = r"""import fetch from 'node-fetch' -import { fileFromSync, FormData } from 'node-fetch' +import { FormData } from 'node-fetch' const payload = new FormData(); payload.append("text", "API") @@ -640,7 +640,7 @@ fetch(url, options) }); test('POST 8', () { const expectedCode = r"""import fetch from 'node-fetch' -import { fileFromSync, FormData } from 'node-fetch' +import { FormData } from 'node-fetch' const payload = new FormData(); payload.append("text", "API") From 6aaa29cb9841d6960cf14666be195064d6aca0da Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 05:24:50 +0530 Subject: [PATCH 76/91] js minor fix --- lib/codegen/js/fetch.dart | 2 +- test/codegen/js_fetch_codegen_test.dart | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/codegen/js/fetch.dart b/lib/codegen/js/fetch.dart index caf27a47..9b5f8161 100644 --- a/lib/codegen/js/fetch.dart +++ b/lib/codegen/js/fetch.dart @@ -62,7 +62,7 @@ fetch(url, options) String result = isNodeJs ? importsData - : requestModel.hasFormData + : requestModel.hasFileInFormData ? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration\n\n" : ""; if (requestModel.hasFormData) { diff --git a/test/codegen/js_fetch_codegen_test.dart b/test/codegen/js_fetch_codegen_test.dart index c6863709..83ee687c 100644 --- a/test/codegen/js_fetch_codegen_test.dart +++ b/test/codegen/js_fetch_codegen_test.dart @@ -461,10 +461,7 @@ fetch(url, options) expectedCode); }); test('POST 4', () { - const expectedCode = - r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration - -const payload = new FormData(); + const expectedCode = r"""const payload = new FormData(); payload.append("text", "API") payload.append("sep", "|") payload.append("times", "3") @@ -498,10 +495,7 @@ fetch(url, options) }); test('POST 5', () { - const expectedCode = - r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration - -const payload = new FormData(); + const expectedCode = r"""const payload = new FormData(); payload.append("text", "API") payload.append("sep", "|") payload.append("times", "3") @@ -607,10 +601,7 @@ fetch(url, options) expectedCode); }); test('POST 8', () { - const expectedCode = - r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1995208098 for details regarding integration - -const payload = new FormData(); + const expectedCode = r"""const payload = new FormData(); payload.append("text", "API") payload.append("sep", "|") payload.append("times", "3") From 15c38c61275bb8a47cf13d59dba556be665fd54c Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 08:12:56 +0530 Subject: [PATCH 77/91] removed errors --- lib/codegen/java/async_http_client.dart | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index f0f688c6..ec804cc1 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -76,20 +76,13 @@ public class Main { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; bool hasBody = false; - bool hasJsonBody = false; - - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; @@ -98,7 +91,7 @@ public class Main { return ""; } - url = stripUriParams(uri); + var url = stripUriParams(uri); // contains the HTTP method associated with the request var method = requestModel.method; @@ -117,20 +110,13 @@ public class Main { // if request type is not form data, the request method can include // a body, and the body of the request is not null, in that case // we need to parse the body as it is, and write it to the body - if (!requestModel.isFormDataRequest && + if (!requestModel.hasFormData && kMethodsWithBody.contains(method) && requestBody != null) { var contentLength = utf8.encode(requestBody).length; if (contentLength > 0) { var templateBodyContent = jj.Template(kTemplateRequestBodyContent); hasBody = true; - - // every JSON should be enclosed within a pair of curly braces - // very simple check for JSON, for stronger check, we may validate - // the JSON in the JSON editor itself - hasJsonBody = - requestBody.startsWith("{") && requestBody.endsWith("}"); - if (harJson["postData"]?["text"] != null) { result += templateBodyContent.render({ "body": kEncoder.convert(harJson["postData"]["text"]).substring( @@ -174,7 +160,7 @@ public class Main { }); // handling form data - if (requestModel.isFormDataRequest && + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty && kMethodsWithBody.contains(method)) { // including form data into the request From 9e2cf7fac1f91c2384b88266391fe3caa6195829 Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Thu, 14 Mar 2024 18:19:04 +0530 Subject: [PATCH 78/91] fix(codgen-axios): fix the broken codegen for multipart requests as well as refactor it --- lib/codegen/js/axios.dart | 103 +++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lib/codegen/js/axios.dart b/lib/codegen/js/axios.dart index 71456d6e..51859fc6 100644 --- a/lib/codegen/js/axios.dart +++ b/lib/codegen/js/axios.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; @@ -10,12 +9,14 @@ class AxiosCodeGen { final bool isNodeJs; - String kStringImportNode = """{% if isNodeJs %}import axios from 'axios'; + String kStringImportNode = """import axios from 'axios'; +{%if hasFormData -%} +import fs from 'fs' +{% endif %} -{% endif %}{% if hasFormData and isNodeJs %}const fs = require('fs');{% endif %} """; - String kTemplateStart = """let config = { + String kTemplateStart = """const config = { url: '{{url}}', method: '{{method}}' """; @@ -37,40 +38,14 @@ class AxiosCodeGen { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; - String kMultiPartBodyTemplate = r''' - - -async function buildFormData(fields) { - var formdata = new FormData(); - for (const field of fields) { - const name = field.name || ''; - const value = field.value || ''; - const type = field.type || 'text'; - - if (type === 'text') { - formdata.append(name, value); - } else if (type === 'file') { - formdata.append(name,{% if isNodeJs %} fs.createReadStream(value){% else %} fileInput.files[0],value{% endif %}); - } - } - return formdata; -} - - -'''; - var kGetFormDataTemplate = '''buildFormData({{fields_list}}); -'''; String? getCode( RequestModel requestModel, ) { @@ -78,18 +53,13 @@ async function buildFormData(fields) { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ "hasFormData": requestModel.hasFormData, - "isNodeJs": isNodeJs, }); - String result = importsData; - if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { - var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); - var renderedMultiPartBody = templateMultiPartBody.render({ - "isNodeJs": isNodeJs, - }); - result += renderedMultiPartBody; - } - + String result = isNodeJs + ? importsData + : requestModel.hasFormData + ? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration\n\n" + : ""; var harJson = requestModelToHARJsonRequest( requestModel, useEnabled: true, @@ -126,17 +96,22 @@ async function buildFormData(fields) { .render({"headers": padMultilineString(kEncoder.convert(m), 2)}); } var templateBody = jj.Template(kTemplateBody); - if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { - var getFieldDataTemplate = jj.Template(kGetFormDataTemplate); - - result += templateBody.render({ - "body": getFieldDataTemplate.render({ - "fields_list": json.encode(requestModel.formDataMapList), - }) - }); - } - if (harJson["postData"]?["text"] != null) { + // Manually Create a JS Object + Map formParams = {}; + int formFileCounter = 1; + for (var element in requestModel.formDataMapList) { + formParams["${element["name"]}"] = element["type"] == "text" + ? "${element["value"]}" + : isNodeJs + ? "fs.createReadStream(${element["value"]})" + : "fileInput$formFileCounter.files[0]"; + if (element["type"] == "file") formFileCounter++; + } + var sanitizedJSObject = sanitzeJSObject(kEncoder.convert(formParams)); + result += templateBody + .render({"body": padMultilineString(sanitizedJSObject, 2)}); + } else if (harJson["postData"]?["text"] != null) { result += templateBody .render({"body": kEncoder.convert(harJson["postData"]["text"])}); } @@ -146,4 +121,18 @@ async function buildFormData(fields) { return null; } } + + // escape function and variables in JS Object + String sanitzeJSObject(String jsObject) { + RegExp pattern = isNodeJs + ? RegExp(r'"fs\.createReadStream\((.*?)\)"') + : RegExp(r'"fileInput(\d+)\.files\[0\]"'); + + var sanitizedJSObject = jsObject.replaceAllMapped(pattern, (match) { + return isNodeJs + ? 'fs.createReadStream("${match.group(1)}")' + : 'fileInput${match.group(1)}.files[0]'; + }); + return sanitizedJSObject; + } } From f80b6b343d00f7396d4f74c78b3ccef8973cb29b Mon Sep 17 00:00:00 2001 From: Tanish2002 Date: Thu, 14 Mar 2024 20:05:06 +0530 Subject: [PATCH 79/91] test(axios): update tests with respect to new changes --- test/codegen/js_axios_codegen_test.dart | 612 ++++++++++++-------- test/codegen/nodejs_axios_codegen_test.dart | 612 ++++++++++++-------- 2 files changed, 762 insertions(+), 462 deletions(-) diff --git a/test/codegen/js_axios_codegen_test.dart b/test/codegen/js_axios_codegen_test.dart index 40b420e4..1c417b63 100644 --- a/test/codegen/js_axios_codegen_test.dart +++ b/test/codegen/js_axios_codegen_test.dart @@ -8,22 +8,19 @@ void main() { group('GET Request', () { test('GET 1', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev', method: 'get' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet1, "https"), @@ -31,7 +28,7 @@ axios(config) }); test('GET 2', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/country/data', method: 'get', params: { @@ -40,16 +37,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet2, "https"), @@ -57,7 +51,7 @@ axios(config) }); test('GET 3', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/country/data', method: 'get', params: { @@ -66,16 +60,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet3, "https"), @@ -83,7 +74,7 @@ axios(config) }); test('GET 4', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { @@ -96,16 +87,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet4, "https"), @@ -113,7 +101,7 @@ axios(config) }); test('GET 5', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.github.com/repos/foss42/apidash', method: 'get', headers: { @@ -122,16 +110,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet5, "https"), @@ -139,7 +124,7 @@ axios(config) }); test('GET 6', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.github.com/repos/foss42/apidash', method: 'get', params: { @@ -151,16 +136,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet6, "https"), @@ -168,22 +150,19 @@ axios(config) }); test('GET 7', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev', method: 'get' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet7, "https"), @@ -191,7 +170,7 @@ axios(config) }); test('GET 8', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.github.com/repos/foss42/apidash', method: 'get', params: { @@ -203,16 +182,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet8, "https"), @@ -220,7 +196,7 @@ axios(config) }); test('GET 9', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { @@ -230,16 +206,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet9, "https"), @@ -247,7 +220,7 @@ axios(config) }); test('GET 10', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', headers: { @@ -256,16 +229,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -277,7 +247,7 @@ axios(config) }); test('GET 11', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { @@ -290,16 +260,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet11, "https"), @@ -307,22 +274,19 @@ axios(config) }); test('GET 12', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelGet12, "https"), @@ -332,22 +296,19 @@ axios(config) group('HEAD Request', () { test('HEAD 1', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev', method: 'head' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelHead1, "https"), @@ -355,22 +316,19 @@ axios(config) }); test('HEAD 2', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'http://api.apidash.dev', method: 'head' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelHead2, "http"), @@ -380,7 +338,7 @@ axios(config) group('POST Request', () { test('POST 1', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { @@ -390,16 +348,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost1, "https"), @@ -407,7 +362,7 @@ axios(config) }); test('POST 2', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { @@ -417,16 +372,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost2, "https"), @@ -434,7 +386,7 @@ axios(config) }); test('POST 3', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { @@ -445,26 +397,236 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration + +const config = { + url: 'https://api.apidash.dev/io/form', + method: 'post', + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "text": "API", + "sep": "|", + "times": "3" + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, + requestModelPost4, + "https", + ), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration + +const config = { + url: 'https://api.apidash.dev/io/form', + method: 'post', + headers: { + "Content-Type": "multipart/form-data", + "User-Agent": "Test Agent" + }, + data: { + "text": "API", + "sep": "|", + "times": "3" + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, + requestModelPost5, + "https", + ), + expectedCode); + }); + test('POST 6', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration + +const config = { + url: 'https://api.apidash.dev/io/img', + method: 'post', + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "token": "xyz", + "imfile": fileInput1.files[0] + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, + requestModelPost6, + "https", + ), + expectedCode); + }); + test('POST 7', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration + +const config = { + url: 'https://api.apidash.dev/io/img', + method: 'post', + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "token": "xyz", + "imfile": fileInput1.files[0] + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, + requestModelPost7, + "https", + ), + expectedCode); + }); + test('POST 8', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration + +const config = { + url: 'https://api.apidash.dev/io/form', + method: 'post', + params: { + "size": "2", + "len": "3" + }, + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "text": "API", + "sep": "|", + "times": "3" + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, + requestModelPost8, + "https", + ), + expectedCode); + }); + test('POST 9', () { + const expectedCode = + r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration + +const config = { + url: 'https://api.apidash.dev/io/img', + method: 'post', + params: { + "size": "2", + "len": "3" + }, + headers: { + "Content-Type": "multipart/form-data", + "User-Agent": "Test Agent", + "Keep-Alive": "true" + }, + data: { + "token": "xyz", + "imfile": fileInput1.files[0] + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.jsAxios, + requestModelPost9, + "https", + ), + expectedCode); + }); }); group('PUT Request', () { test('PUT 1', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://reqres.in/api/users/2', method: 'put', headers: { @@ -474,16 +636,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelPut1, "https"), @@ -493,7 +652,7 @@ axios(config) group('PATCH Request', () { test('PATCH 1', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://reqres.in/api/users/2', method: 'patch', headers: { @@ -503,16 +662,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode(CodegenLanguage.jsAxios, requestModelPatch1, "https"), @@ -522,22 +678,19 @@ axios(config) group('DELETE Request', () { test('DELETE 1', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://reqres.in/api/users/2', method: 'delete' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -546,7 +699,7 @@ axios(config) }); test('DELETE 2', () { - const expectedCode = r"""let config = { + const expectedCode = r"""const config = { url: 'https://reqres.in/api/users/2', method: 'delete', headers: { @@ -556,16 +709,13 @@ axios(config) }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( diff --git a/test/codegen/nodejs_axios_codegen_test.dart b/test/codegen/nodejs_axios_codegen_test.dart index ab4c2bf5..84a7ae1d 100644 --- a/test/codegen/nodejs_axios_codegen_test.dart +++ b/test/codegen/nodejs_axios_codegen_test.dart @@ -10,22 +10,19 @@ void main() { test('GET 1', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev', method: 'get' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -36,7 +33,7 @@ axios(config) test('GET 2', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/country/data', method: 'get', params: { @@ -45,16 +42,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -65,7 +59,7 @@ axios(config) test('GET 3', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/country/data', method: 'get', params: { @@ -74,16 +68,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -94,7 +85,7 @@ axios(config) test('GET 4', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { @@ -107,16 +98,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -127,7 +115,7 @@ axios(config) test('GET 5', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.github.com/repos/foss42/apidash', method: 'get', headers: { @@ -136,16 +124,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -156,7 +141,7 @@ axios(config) test('GET 6', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.github.com/repos/foss42/apidash', method: 'get', params: { @@ -168,16 +153,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -188,22 +170,19 @@ axios(config) test('GET 7', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev', method: 'get' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -214,7 +193,7 @@ axios(config) test('GET 8', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.github.com/repos/foss42/apidash', method: 'get', params: { @@ -226,16 +205,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -246,7 +222,7 @@ axios(config) test('GET 9', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { @@ -256,16 +232,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -276,7 +249,7 @@ axios(config) test('GET 10', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', headers: { @@ -285,16 +258,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -308,7 +278,7 @@ axios(config) test('GET 11', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get', params: { @@ -321,16 +291,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -341,22 +308,19 @@ axios(config) test('GET 12', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/humanize/social', method: 'get' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -369,22 +333,19 @@ axios(config) test('HEAD 1', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev', method: 'head' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -395,22 +356,19 @@ axios(config) test('HEAD 2', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'http://api.apidash.dev', method: 'head' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -423,7 +381,7 @@ axios(config) test('POST 1', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { @@ -433,16 +391,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -453,7 +408,7 @@ axios(config) test('POST 2', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { @@ -463,16 +418,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -483,7 +435,7 @@ axios(config) test('POST 3', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://api.apidash.dev/case/lower', method: 'post', headers: { @@ -494,29 +446,239 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( CodegenLanguage.nodejsAxios, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = r"""import axios from 'axios'; +import fs from 'fs' + +const config = { + url: 'https://api.apidash.dev/io/form', + method: 'post', + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "text": "API", + "sep": "|", + "times": "3" + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, + requestModelPost4, + "https", + ), + expectedCode); + }); + + test('POST 5', () { + const expectedCode = r"""import axios from 'axios'; +import fs from 'fs' + +const config = { + url: 'https://api.apidash.dev/io/form', + method: 'post', + headers: { + "Content-Type": "multipart/form-data", + "User-Agent": "Test Agent" + }, + data: { + "text": "API", + "sep": "|", + "times": "3" + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, + requestModelPost5, + "https", + ), + expectedCode); + }); + test('POST 6', () { + const expectedCode = r"""import axios from 'axios'; +import fs from 'fs' + +const config = { + url: 'https://api.apidash.dev/io/img', + method: 'post', + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "token": "xyz", + "imfile": fs.createReadStream("/Documents/up/1.png") + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, + requestModelPost6, + "https", + ), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r"""import axios from 'axios'; +import fs from 'fs' + +const config = { + url: 'https://api.apidash.dev/io/img', + method: 'post', + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "token": "xyz", + "imfile": fs.createReadStream("/Documents/up/1.png") + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, + requestModelPost7, + "https", + ), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r"""import axios from 'axios'; +import fs from 'fs' + +const config = { + url: 'https://api.apidash.dev/io/form', + method: 'post', + params: { + "size": "2", + "len": "3" + }, + headers: { + "Content-Type": "multipart/form-data" + }, + data: { + "text": "API", + "sep": "|", + "times": "3" + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, + requestModelPost8, + "https", + ), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r"""import axios from 'axios'; +import fs from 'fs' + +const config = { + url: 'https://api.apidash.dev/io/img', + method: 'post', + params: { + "size": "2", + "len": "3" + }, + headers: { + "Content-Type": "multipart/form-data", + "User-Agent": "Test Agent", + "Keep-Alive": "true" + }, + data: { + "token": "xyz", + "imfile": fs.createReadStream("/Documents/up/1.png") + } +}; + +axios(config) + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); +"""; + expect( + codeGen.getCode( + CodegenLanguage.nodejsAxios, + requestModelPost9, + "https", + ), + expectedCode); + }); }); group('PUT Request', () { test('PUT 1', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://reqres.in/api/users/2', method: 'put', headers: { @@ -526,16 +688,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -548,7 +707,7 @@ axios(config) test('PATCH 1', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://reqres.in/api/users/2', method: 'patch', headers: { @@ -558,16 +717,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -580,22 +736,19 @@ axios(config) test('DELETE 1', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://reqres.in/api/users/2', method: 'delete' }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( @@ -606,7 +759,7 @@ axios(config) test('DELETE 2', () { const expectedCode = r"""import axios from 'axios'; -let config = { +const config = { url: 'https://reqres.in/api/users/2', method: 'delete', headers: { @@ -616,16 +769,13 @@ let config = { }; axios(config) - .then(function (response) { - // handle success - console.log(response.status); - console.log(response.data); - }) - .catch(function (error) { - // handle error - console.log(error.response.status); - console.log(error); - }); + .then(res => { + console.log(res.status); + console.log(res.data); + }) + .catch(err => { + console.log(err); + }); """; expect( codeGen.getCode( From 81e6511f6e1237822531b210b137bcef818674d5 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 15:56:57 +0530 Subject: [PATCH 80/91] fixes --- lib/codegen/java/httpclient.dart | 84 +- lib/consts.dart | 2 +- .../java_http_client_codegen_test.dart | 800 ------------------ 3 files changed, 44 insertions(+), 842 deletions(-) delete mode 100644 test/codegen/java_http_client_codegen_test.dart diff --git a/lib/codegen/java/httpclient.dart b/lib/codegen/java/httpclient.dart index d57c73f3..037a9a87 100644 --- a/lib/codegen/java/httpclient.dart +++ b/lib/codegen/java/httpclient.dart @@ -1,7 +1,7 @@ - import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; -import 'package:apidash/utils/utils.dart' show getValidRequestUri, requestModelToHARJsonRequest, stripUriParams; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, requestModelToHARJsonRequest, stripUriParams; import '../../models/request_model.dart'; import 'package:apidash/consts.dart'; @@ -66,7 +66,6 @@ public class JavaHttpClientExample { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; @@ -74,13 +73,8 @@ public class JavaHttpClientExample { bool hasBody = false; bool hasJsonBody = false; - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; @@ -95,40 +89,46 @@ public class JavaHttpClientExample { var templateParams = jj.Template(kTemplateUrlQuery); result += templateParams.render({"url": url, "params": uri.query}); } - } - - if(!hasQuery) { + } + + if (!hasQuery) { var templateUrl = jj.Template(kTemplateUrl); result += templateUrl.render({"url": url}); } var rM = requestModel.copyWith(url: url); - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); var method = requestModel.method; var requestBody = requestModel.requestBody; - if (requestModel.isFormDataRequest && requestModel.formDataMapList.isNotEmpty && kMethodsWithBody.contains(method)) { - var formDataList = requestModel.formDataMapList; - result += """ + if (requestModel.hasFormData && + requestModel.formDataMapList.isNotEmpty && + kMethodsWithBody.contains(method)) { + var formDataList = requestModel.formDataMapList; + result += """ StringBuilder formData = new StringBuilder(); formData.append("""; - for (var formDataMap in formDataList) { - result += '"""${formDataMap['name']}=${formDataMap['value']}&""",'; - } + for (var formDataMap in formDataList) { + result += '"""${formDataMap['name']}=${formDataMap['value']}&""",'; + } - result = result.substring(0, result.length - 1); - result += ");\n"; - hasBody = true; + result = result.substring(0, result.length - 1); + result += ");\n"; + hasBody = true; } else if (kMethodsWithBody.contains(method) && requestBody != null) { var contentLength = utf8.encode(requestBody).length; if (contentLength > 0) { - var templateBody = jj.Template(kTemplateRequestBody);hasBody = true; - hasJsonBody = requestBody.startsWith("{") && requestBody.endsWith("}"); + var templateBody = jj.Template(kTemplateRequestBody); + hasBody = true; + hasJsonBody = + requestBody.startsWith("{") && requestBody.endsWith("}"); if (harJson["postData"]?["text"] != null) { - result += templateBody - .render({"body": kEncoder.convert(harJson["postData"]["text"]).substring(1, kEncoder.convert(harJson["postData"]["text"]).length - 1)}); - } + result += templateBody.render({ + "body": kEncoder.convert(harJson["postData"]["text"]).substring( + 1, kEncoder.convert(harJson["postData"]["text"]).length - 1) + }); + } } } @@ -137,28 +137,30 @@ public class JavaHttpClientExample { var headersList = requestModel.enabledRequestHeaders; var contentType = requestModel.requestBodyContentType.header; - if(hasBody && !requestModel.enabledHeadersMap.containsKey('Content-Type')){ - result = """$result .header("Content-Type", "$contentType")\n"""; + if (hasBody && + !requestModel.enabledHeadersMap.containsKey('Content-Type')) { + result = + """$result .header("Content-Type", "$contentType")\n"""; } if (headersList != null) { var headers = requestModel.enabledHeadersMap; if (headers.isNotEmpty) { - result += getHeaders(headers,hasJsonBody); + result += getHeaders(headers, hasJsonBody); } } var templateRequestEnd = jj.Template(kTemplateRequestEnd); - - if(kMethodsWithBody.contains(method)){ + + if (kMethodsWithBody.contains(method)) { result += templateRequestEnd.render({ - "method": method.name.toUpperCase(), - "body": hasBody ? "BodyPublishers.ofString(body)" : "BodyPublishers.noBody()" - }); + "method": method.name.toUpperCase(), + "body": hasBody + ? "BodyPublishers.ofString(body)" + : "BodyPublishers.noBody()" + }); } else { - result += templateRequestEnd.render({ - "method": method.name.toUpperCase(), - "body": "" - }); + result += templateRequestEnd + .render({"method": method.name.toUpperCase(), "body": ""}); } } return result; @@ -167,10 +169,10 @@ public class JavaHttpClientExample { } } - String getHeaders(Map headers,hasJsonBody) { + String getHeaders(Map headers, hasJsonBody) { String result = ""; for (final k in headers.keys) { - if(k.toLowerCase() == 'authorization') { + if (k.toLowerCase() == 'authorization') { result = """$result .header("$k", "${headers[k]}")\n"""; } else { result = """$result .header("$k", "${headers[k]}")\n"""; diff --git a/lib/consts.dart b/lib/consts.dart index c290d79c..33c0190b 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -279,7 +279,7 @@ enum CodegenLanguage { rustUreq("Rust (ureq)", "rust", "rs"), javaOkHttp("Java (okhttp3)", "java", 'java'), javaAsyncHttpClient("Java (async-http-client)", "java", "java"), - javaHttpClient("Java (HttpClient)", "java", "java") + javaHttpClient("Java (HttpClient)", "java", "java"), juliaHttp("Julia (HTTP)", "julia", "jl"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); diff --git a/test/codegen/java_http_client_codegen_test.dart b/test/codegen/java_http_client_codegen_test.dart deleted file mode 100644 index 83b71d2f..00000000 --- a/test/codegen/java_http_client_codegen_test.dart +++ /dev/null @@ -1,800 +0,0 @@ -import 'package:test/test.dart'; -import 'package:apidash/codegen/java/httpclient.dart'; -import '../request_models.dart'; - -void main() { - final javaHttpClientCodeGen = JavaHttpClientCodeGen(); - - group('GET Request', () { - test('GET 1', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet1, "https"), expectedCode); - }); - - test('GET 2', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/country/data"; - try { - URI uri = new URI(url); - url = uri.resolve("code=US").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet2, "https"), expectedCode); - }); - - test('GET 3', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/country/data"; - try { - URI uri = new URI(url); - url = uri.resolve("code=IND").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet3, "https"), expectedCode); - }); - - test('GET 4', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/humanize/social"; - try { - URI uri = new URI(url); - url = uri.resolve("num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet4, "https"), expectedCode); - }); - - test('GET 5', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.github.com/repos/foss42/apidash"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("User-Agent", "Test Agent") - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet5, "https"), expectedCode); - }); - - test('GET 6', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.github.com/repos/foss42/apidash"; - try { - URI uri = new URI(url); - url = uri.resolve("raw=true").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("User-Agent", "Test Agent") - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet6, "https"), expectedCode); - }); - - test('GET 7', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet7, "https"), expectedCode); - }); - - test('GET 8', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.github.com/repos/foss42/apidash"; - try { - URI uri = new URI(url); - url = uri.resolve("raw=true").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("User-Agent", "Test Agent") - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet8, "https"), expectedCode); - }); - - test('GET 9', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/humanize/social"; - try { - URI uri = new URI(url); - url = uri.resolve("num=8700000&add_space=true").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet9, "https"), expectedCode); - }); - - test('GET 10', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/humanize/social"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("User-Agent", "Test Agent") - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet10, "https"), expectedCode); - }); - - test('GET 11', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/humanize/social"; - try { - URI uri = new URI(url); - url = uri.resolve("num=8700000&digits=3").toString(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("User-Agent", "Test Agent") - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet11, "https"), expectedCode); - }); - - test('GET 12', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/humanize/social"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelGet12, "https"), expectedCode); - }); - - test('HEAD 1', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .HEAD() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelHead1, "https"), expectedCode); - }); - - test('HEAD 2', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .HEAD() - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelHead2, "https"), expectedCode); - }); -}); - -group('POST Request', () { - test('POST 1', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/case/lower"; - - String body = "{\\n\\"text\\": \\"I LOVE Flutter\\"\\n}"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "text/plain") - .POST(BodyPublishers.ofString(body)) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelPost1, "https"), expectedCode); - }); - - test('POST 2', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/case/lower"; - - String body = "{\\n\\"text\\": \\"I LOVE Flutter\\"\\n}"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "application/json") - .POST(BodyPublishers.ofString(body)) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelPost2, "https"), expectedCode); - }); - - test('POST 3', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://api.foss42.com/case/lower"; - - String body = "{\\n\\"text\\": \\"I LOVE Flutter\\"\\n}"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "application/json") - .header("User-Agent", "Test Agent") - .POST(BodyPublishers.ofString(body)) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelPost3, "https"), expectedCode); - }); -}); - -group('PUT Request', () { - test('PUT 1', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://reqres.in/api/users/2"; - - String body = "{\\n\\"name\\": \\"morpheus\\",\\n\\"job\\": \\"zion resident\\"\\n}"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "application/json") - .PUT(BodyPublishers.ofString(body)) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelPut1, "https"), expectedCode); - }); -}); - -group('PATCH Request', () { - test('PATCH 1', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://reqres.in/api/users/2"; - - String body = "{\\n\\"name\\": \\"marfeus\\",\\n\\"job\\": \\"accountant\\"\\n}"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "application/json") - .PATCH(BodyPublishers.ofString(body)) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelPatch1, "https"), expectedCode); - }); -}); - -group('DELETE Request', () { - test('DELETE 1', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://reqres.in/api/users/2"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .DELETE(BodyPublishers.noBody()) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelDelete1, "https"), expectedCode); - }); - - test('DELETE 2', () { - const expectedCode = """ -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; - -public class JavaHttpClientExample { - - public static void main(String[] args) throws IOException, InterruptedException { - HttpClient client = HttpClient.newHttpClient(); - - String url = "https://reqres.in/api/users/2"; - - String body = "{\\n\\"name\\": \\"marfeus\\",\\n\\"job\\": \\"accountant\\"\\n}"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "application/json") - .DELETE(BodyPublishers.ofString(body)) - .build(); - - HttpResponse response = client.send(request, BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.body()); - } -} - -"""; - expect(javaHttpClientCodeGen.getCode(requestModelDelete2, "https"), expectedCode); - }); -}); - - - -} \ No newline at end of file From 1228ac4e465bc4558fcea1cd82d85f90ba746721 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 17:35:25 +0530 Subject: [PATCH 81/91] Update seq --- lib/codegen/codegen.dart | 20 ++++++++++---------- lib/consts.dart | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 5100f7aa..df07492f 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -45,6 +45,8 @@ class Codegen { return DartHttpCodeGen().getCode(rM); case CodegenLanguage.dartDio: return DartDioCodeGen().getCode(rM); + case CodegenLanguage.goHttp: + return GoHttpCodeGen().getCode(rM); case CodegenLanguage.jsAxios: return AxiosCodeGen().getCode(rM); case CodegenLanguage.jsFetch: @@ -53,10 +55,16 @@ class Codegen { return AxiosCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.nodejsFetch: return FetchCodeGen(isNodeJs: true).getCode(rM); + case CodegenLanguage.javaAsyncHttpClient: + return JavaAsyncHttpClientGen().getCode(rM); + case CodegenLanguage.javaHttpClient: + return JavaHttpClientCodeGen().getCode(rM); + case CodegenLanguage.javaOkHttp: + return JavaOkHttpCodeGen().getCode(rM); + case CodegenLanguage.juliaHttp: + return JuliaHttpClientCodeGen().getCode(rM); case CodegenLanguage.kotlinOkHttp: return KotlinOkHttpCodeGen().getCode(rM); - case CodegenLanguage.javaOkHttp: - return JavaOkHttpCodeGen().getCode(rM); case CodegenLanguage.pythonHttpClient: return PythonHttpClientCodeGen() .getCode(rM, boundary: boundary ?? getNewUuid()); @@ -68,14 +76,6 @@ class Codegen { return RustReqwestCodeGen().getCode(rM); case CodegenLanguage.rustUreq: return RustUreqCodeGen().getCode(rM, boundary: boundary); - case CodegenLanguage.goHttp: - return GoHttpCodeGen().getCode(rM); - case CodegenLanguage.juliaHttp: - return JuliaHttpClientCodeGen().getCode(rM); - case CodegenLanguage.javaAsyncHttpClient: - return JavaAsyncHttpClientGen().getCode(rM); - case CodegenLanguage.javaHttpClient: - return JavaHttpClientCodeGen().getCode(rM); } } } diff --git a/lib/consts.dart b/lib/consts.dart index 33c0190b..af4b6524 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -272,8 +272,8 @@ enum CodegenLanguage { nodejsAxios("node.js (axios)", "javascript", "js"), nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), - pythonHttpClient("Python (http.client)", "python", "py"), pythonRequests("Python (requests)", "python", "py"), + pythonHttpClient("Python (http.client)", "python", "py"), rustActix("Rust (Actix Client)", "rust", "rs"), rustReqwest("Rust (reqwest)", "rust", "rs"), rustUreq("Rust (ureq)", "rust", "rs"), From d4723abe60c72816eb1d7b2f8b51781566eea746 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 17:44:51 +0530 Subject: [PATCH 82/91] fixes --- lib/codegen/php/guzzle.dart | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/lib/codegen/php/guzzle.dart b/lib/codegen/php/guzzle.dart index 04acd213..c0e5562e 100644 --- a/lib/codegen/php/guzzle.dart +++ b/lib/codegen/php/guzzle.dart @@ -1,13 +1,13 @@ import 'package:jinja/jinja.dart' as jj; import 'package:apidash/utils/utils.dart' - show padMultilineString, requestModelToHARJsonRequest, stripUrlParams; + show requestModelToHARJsonRequest, stripUrlParams; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; class PhpGuzzleCodeGen { String kStringImportNode = """use GuzzleHttp\\Client; use GuzzleHttp\\Psr7\\Request; -{% if isFormDataRequest %}use GuzzleHttp\\Psr7\\MultipartStream;{% endif %} +{% if hasFormData %}use GuzzleHttp\\Psr7\\MultipartStream;{% endif %} """; @@ -51,20 +51,16 @@ use GuzzleHttp\\Psr7\\Request; echo \$res->getBody(); """; - String? getCode( - RequestModel requestModel, - String defaultUriScheme, - ) { + String? getCode(RequestModel requestModel) { try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ - "isFormDataRequest": requestModel.isFormDataRequest, + "hasFormData": requestModel.hasFormData, }); String result = importsData; - if (requestModel.isFormDataRequest && - requestModel.formDataMapList.isNotEmpty) { + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate); var renderedMultiPartBody = templateMultiPartBody.render({ "fields_list": requestModel.formDataMapList.map((field) { @@ -78,13 +74,8 @@ echo \$res->getBody(); result += renderedMultiPartBody; } - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } - var rM = requestModel.copyWith(url: url); - - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + var harJson = + requestModelToHARJsonRequest(requestModel, useEnabled: true); var params = harJson["queryString"]; if (params.isNotEmpty) { @@ -105,7 +96,7 @@ echo \$res->getBody(); } var headers = harJson["headers"]; - if (headers.isNotEmpty || requestModel.isFormDataRequest) { + if (headers.isNotEmpty || requestModel.hasFormData) { var templateHeader = jj.Template(kTemplateHeader); var m = {}; for (var i in headers) { @@ -115,7 +106,7 @@ echo \$res->getBody(); m.forEach((key, value) { headersString += "\t\t\t\t'$key' => '$value', \n"; }); - if (requestModel.isFormDataRequest) { + if (requestModel.hasFormData) { m['Content-Type'] = 'multipart/form-data'; } headersString = headersString.substring( @@ -126,8 +117,7 @@ echo \$res->getBody(); } var templateBody = jj.Template(kTemplateBody); - if (requestModel.isFormDataRequest && - requestModel.formDataMapList.isNotEmpty) { + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) { result += templateBody.render({ "body": "new MultipartStream(\$multipart)", }); @@ -155,7 +145,7 @@ echo \$res->getBody(); var templateRequest = jj.Template(kStringRequest); result += templateRequest.render({ - "url": stripUrlParams(url), + "url": stripUrlParams(requestModel.url), "method": harJson["method"].toLowerCase(), "queryParams": harJson["queryString"].isNotEmpty ? ". \$queryParamsStr," : "", From 9e007faf101a542d8e3fcc602957980009566661 Mon Sep 17 00:00:00 2001 From: PCoder23 Date: Fri, 15 Mar 2024 17:51:41 +0530 Subject: [PATCH 83/91] added post test 4, and 6 to 9 --- test/codegen/kotlin_okhttp_codegen_test.dart | 155 +++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index f91f183c..076339c9 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -517,6 +517,35 @@ fun main() { CodegenLanguage.kotlinOkHttp, requestModelPost3, "https"), expectedCode); }); + test('POST 4', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.apidash.dev/io/form" + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build() + val request = Request.Builder() + .url(url) + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost4, "https"), + expectedCode); + }); test('POST 5', () { const expectedCode = r'''import okhttp3.OkHttpClient @@ -548,6 +577,132 @@ fun main() { CodegenLanguage.kotlinOkHttp, requestModelPost5, "https"), expectedCode); }); + test('POST 6', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.apidash.dev/io/img" + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("token","xyz") + + .addFormDataPart("imfile",null,File("/Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) + .build() + val request = Request.Builder() + .url(url) + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost6, "https"), + expectedCode); + }); + test('POST 7', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.apidash.dev/io/img" + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("token","xyz") + + .addFormDataPart("imfile",null,File("/Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) + .build() + val request = Request.Builder() + .url(url) + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost7, "https"), + expectedCode); + }); + test('POST 8', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.apidash.dev/io/form".toHttpUrl().newBuilder() + .addQueryParameter("size", "2") + .addQueryParameter("len", "3") + .build() + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("text","API") + .addFormDataPart("sep","|") + .addFormDataPart("times","3") + .build() + val request = Request.Builder() + .url(url) + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost8, "https"), + expectedCode); + }); + test('POST 9', () { + const expectedCode = r'''import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MultipartBody + +fun main() { + val client = OkHttpClient() + + val url = "https://api.apidash.dev/io/img".toHttpUrl().newBuilder() + .addQueryParameter("size", "2") + .addQueryParameter("len", "3") + .build() + val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("token","xyz") + + .addFormDataPart("imfile",null,File("/Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) + .build() + val request = Request.Builder() + .url(url) + .addHeader("User-Agent", "Test Agent") + .addHeader("Keep-Alive", "true") + .post(body) + .build() + + val response = client.newCall(request).execute() + + println(response.code) + println(response.body?.string()) +} +'''; + expect( + codeGen.getCode( + CodegenLanguage.kotlinOkHttp, requestModelPost9, "https"), + expectedCode); + }); }); group('PUT Request', () { From 8d624dddaae23024ff6fd438d5b107be7194b34a Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 18:09:00 +0530 Subject: [PATCH 84/91] Update README.md --- README.md | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c2760f5d..3202681c 100644 --- a/README.md +++ b/README.md @@ -123,19 +123,28 @@ API Dash can be downloaded from the links below: API Dash currently supports API integration code generation for the following languages/libraries. -| Language | Library | -| ---------------------- | ------------- | -| cURL | | -| HAR | | -| Dart | `http` | -| JavaScript | `axios` | -| JavaScript | `fetch` | -| JavaScript (`node.js`) | `axios` | -| JavaScript (`node.js`) | `fetch` | -| Python | `http.client` | -| Python | `requests` | -| Kotlin | `okhttp3` | -| Java | `okhttp3` | +| Language | Library | Comment/Issues | +| ---------------------- | ------------- | ------- | +| cURL | | | +| HAR | | | +| Dart | `http` | | +| Dart | `dio` | | +| Go | `net/http` | | +| JavaScript | `axios` | | +| JavaScript | `fetch` | | +| JavaScript (`node.js`) | `axios` | | +| JavaScript (`node.js`) | `fetch` | | +| Python | `requests` | | +| Python | `http.client` | | +| Kotlin | `okhttp3` | https://github.com/foss42/apidash/issues/280 | +| Rust | `reqwest` | | +| Rust | `ureq` | | +| Rust | `Actix Client` | | +| Java | `asynchttpclient` | https://github.com/foss42/apidash/issues/136 | +| Java | `HttpClient` | https://github.com/foss42/apidash/issues/137 | +| Java | `okhttp3` | | +| Julia | `HTTP` | https://github.com/foss42/apidash/issues/154 | +| PHP | `guzzle` | https://github.com/foss42/apidash/issues/143 | We welcome contributions to support other programming languages/libraries/frameworks. Please check out more details [here](https://github.com/foss42/apidash/discussions/80). From 67aadaabec92897d4b6c43911ab12a857261c208 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 18:12:07 +0530 Subject: [PATCH 85/91] Update consts.dart --- lib/consts.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/consts.dart b/lib/consts.dart index 3222a75b..e3d2dc6b 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -278,11 +278,11 @@ enum CodegenLanguage { rustReqwest("Rust (reqwest)", "rust", "rs"), rustUreq("Rust (ureq)", "rust", "rs"), javaOkHttp("Java (okhttp3)", "java", 'java'), - javaAsyncHttpClient("Java (async-http-client)", "java", "java"), + javaAsyncHttpClient("Java (asynchttpclient)", "java", "java"), javaHttpClient("Java (HttpClient)", "java", "java"), juliaHttp("Julia (HTTP)", "julia", "jl"), phpGuzzle("PHP (guzzle)", "php", "php"); - + const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; final String codeHighlightLang; From a3fd05f9057af0dc3e8efebf941bdcf647b85f26 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 18:56:06 +0530 Subject: [PATCH 86/91] fixes --- lib/codegen/js/axios.dart | 6 +++--- test/codegen/js_axios_codegen_test.dart | 15 +++------------ test/codegen/nodejs_axios_codegen_test.dart | 3 --- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/lib/codegen/js/axios.dart b/lib/codegen/js/axios.dart index 51859fc6..301ecf46 100644 --- a/lib/codegen/js/axios.dart +++ b/lib/codegen/js/axios.dart @@ -10,7 +10,7 @@ class AxiosCodeGen { final bool isNodeJs; String kStringImportNode = """import axios from 'axios'; -{%if hasFormData -%} +{%if hasFileInFormData -%} import fs from 'fs' {% endif %} @@ -52,12 +52,12 @@ axios(config) try { jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode); String importsData = kNodejsImportTemplate.render({ - "hasFormData": requestModel.hasFormData, + "hasFileInFormData": requestModel.hasFileInFormData, }); String result = isNodeJs ? importsData - : requestModel.hasFormData + : requestModel.hasFileInFormData ? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration\n\n" : ""; var harJson = requestModelToHARJsonRequest( diff --git a/test/codegen/js_axios_codegen_test.dart b/test/codegen/js_axios_codegen_test.dart index 1c417b63..15bbeff1 100644 --- a/test/codegen/js_axios_codegen_test.dart +++ b/test/codegen/js_axios_codegen_test.dart @@ -410,10 +410,7 @@ axios(config) expectedCode); }); test('POST 4', () { - const expectedCode = - r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration - -const config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/io/form', method: 'post', headers: { @@ -445,10 +442,7 @@ axios(config) }); test('POST 5', () { - const expectedCode = - r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration - -const config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/io/form', method: 'post', headers: { @@ -546,10 +540,7 @@ axios(config) expectedCode); }); test('POST 8', () { - const expectedCode = - r"""// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration - -const config = { + const expectedCode = r"""const config = { url: 'https://api.apidash.dev/io/form', method: 'post', params: { diff --git a/test/codegen/nodejs_axios_codegen_test.dart b/test/codegen/nodejs_axios_codegen_test.dart index 84a7ae1d..31f359ea 100644 --- a/test/codegen/nodejs_axios_codegen_test.dart +++ b/test/codegen/nodejs_axios_codegen_test.dart @@ -461,7 +461,6 @@ axios(config) }); test('POST 4', () { const expectedCode = r"""import axios from 'axios'; -import fs from 'fs' const config = { url: 'https://api.apidash.dev/io/form', @@ -496,7 +495,6 @@ axios(config) test('POST 5', () { const expectedCode = r"""import axios from 'axios'; -import fs from 'fs' const config = { url: 'https://api.apidash.dev/io/form', @@ -597,7 +595,6 @@ axios(config) }); test('POST 8', () { const expectedCode = r"""import axios from 'axios'; -import fs from 'fs' const config = { url: 'https://api.apidash.dev/io/form', From 8b3a3568d89660554ba1f08783a942371afacb43 Mon Sep 17 00:00:00 2001 From: PCoder23 Date: Fri, 15 Mar 2024 22:43:57 +0530 Subject: [PATCH 87/91] fixed issues --- lib/codegen/kotlin/okhttp.dart | 42 ++++++++++++++++++-- test/codegen/kotlin_okhttp_codegen_test.dart | 15 +++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/lib/codegen/kotlin/okhttp.dart b/lib/codegen/kotlin/okhttp.dart index c717dc97..a3a2fb89 100644 --- a/lib/codegen/kotlin/okhttp.dart +++ b/lib/codegen/kotlin/okhttp.dart @@ -7,7 +7,7 @@ import 'package:apidash/consts.dart'; class KotlinOkHttpCodeGen { final String kTemplateStart = """import okhttp3.OkHttpClient -import okhttp3.Request{{importForQuery}}{{importForBody}}{{importForFormData}} +import okhttp3.Request{{importForQuery}}{{importForBody}}{{importForFormData}}{{importForFile}} fun main() { val client = OkHttpClient() @@ -27,6 +27,12 @@ import okhttp3.MediaType.Companion.toMediaType"""; import okhttp3.MultipartBody"""; + final String kStringImportForFile = """ + +import java.io.File +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.MediaType.Companion.toMediaType"""; + final String kTemplateUrl = ''' val url = "{{url}}" @@ -68,7 +74,7 @@ import okhttp3.MultipartBody"""; // Converting list of form data objects to kolin multi part data String kFormDataBody = ''' val body = MultipartBody.Builder().setType(MultipartBody.FORM){% for item in formDataList %}{% if item.type == 'file' %} - .addFormDataPart("{{item.name}}",null,File("{{item.value}}").asRequestBody("application/octet-stream".toMediaType())) + .addFormDataPart("{{item.name}}",File("{{item.value}}").name,File("{{item.value}}").asRequestBody("application/octet-stream".toMediaType())) {% else %}.addFormDataPart("{{item.name}}","{{item.value}}") {% endif %}{% endfor %}.build() '''; @@ -81,6 +87,7 @@ import okhttp3.MultipartBody"""; bool hasQuery = false; bool hasBody = false; bool hasFormData = false; + bool hasFile = false; var rec = getValidRequestUri( requestModel.url, @@ -111,8 +118,34 @@ import okhttp3.MultipartBody"""; hasFormData = true; var formDataTemplate = jj.Template(kFormDataBody); + List> modifiedFormDataList = []; + for (var item in requestModel.formDataList) { + if (item.type == FormDataType.file ) { + if (item.value[0] == "/") { + modifiedFormDataList.add({ + "name": item.name, + "value": item.value.substring(1), + "type": "file" + }); + }else{ + modifiedFormDataList.add({ + "name": item.name, + "value": item.value, + "type": "file" + }); + } + hasFile = true; + }else{ + modifiedFormDataList.add({ + "name": item.name, + "value": item.value, + "type": "text" + }); + } + } + result += formDataTemplate.render({ - "formDataList": requestModel.formDataMapList, + "formDataList": modifiedFormDataList, }); } else if (kMethodsWithBody.contains(method) && requestBody != null) { var contentLength = utf8.encode(requestBody).length; @@ -129,7 +162,8 @@ import okhttp3.MultipartBody"""; var stringStart = templateStart.render({ "importForQuery": hasQuery ? kStringImportForQuery : "", "importForBody": hasBody ? kStringImportForBody : "", - "importForFormData": hasFormData ? kStringImportForFormData : "" + "importForFormData": hasFormData ? kStringImportForFormData : "", + "importForFile": hasFile ? kStringImportForFile : "", }); result = stringStart + result; diff --git a/test/codegen/kotlin_okhttp_codegen_test.dart b/test/codegen/kotlin_okhttp_codegen_test.dart index 076339c9..7b6850f3 100644 --- a/test/codegen/kotlin_okhttp_codegen_test.dart +++ b/test/codegen/kotlin_okhttp_codegen_test.dart @@ -581,6 +581,9 @@ fun main() { const expectedCode = r'''import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.MultipartBody +import java.io.File +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.MediaType.Companion.toMediaType fun main() { val client = OkHttpClient() @@ -588,7 +591,7 @@ fun main() { val url = "https://api.apidash.dev/io/img" val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("token","xyz") - .addFormDataPart("imfile",null,File("/Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) + .addFormDataPart("imfile",File("Documents/up/1.png").name,File("Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) .build() val request = Request.Builder() .url(url) @@ -610,6 +613,9 @@ fun main() { const expectedCode = r'''import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.MultipartBody +import java.io.File +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.MediaType.Companion.toMediaType fun main() { val client = OkHttpClient() @@ -617,7 +623,7 @@ fun main() { val url = "https://api.apidash.dev/io/img" val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("token","xyz") - .addFormDataPart("imfile",null,File("/Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) + .addFormDataPart("imfile",File("Documents/up/1.png").name,File("Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) .build() val request = Request.Builder() .url(url) @@ -673,6 +679,9 @@ fun main() { import okhttp3.Request import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MultipartBody +import java.io.File +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.MediaType.Companion.toMediaType fun main() { val client = OkHttpClient() @@ -683,7 +692,7 @@ fun main() { .build() val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("token","xyz") - .addFormDataPart("imfile",null,File("/Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) + .addFormDataPart("imfile",File("Documents/up/1.png").name,File("Documents/up/1.png").asRequestBody("application/octet-stream".toMediaType())) .build() val request = Request.Builder() .url(url) From 21dfa85e8ec214b711e962d96be0566c777d8a95 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sat, 16 Mar 2024 01:17:31 +0530 Subject: [PATCH 88/91] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3202681c..f6f73d62 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ API Dash currently supports API integration code generation for the following la | JavaScript (`node.js`) | `fetch` | | | Python | `requests` | | | Python | `http.client` | | -| Kotlin | `okhttp3` | https://github.com/foss42/apidash/issues/280 | +| Kotlin | `okhttp3` | | | Rust | `reqwest` | | | Rust | `ureq` | | | Rust | `Actix Client` | | From 0b669390ffba4162342b1950132558d77719aba7 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sat, 16 Mar 2024 05:18:00 +0530 Subject: [PATCH 89/91] Fix tab indicator for formdata --- lib/codegen/go/http.dart | 4 ++-- lib/codegen/python/http_client.dart | 2 +- lib/models/request_model.dart | 2 +- .../request_pane/request_headers.dart | 2 +- .../details_card/request_pane/request_pane.dart | 17 ++++++++++------- .../request_pane/request_params.dart | 2 +- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart index 4bdecf48..a93d47e0 100644 --- a/lib/codegen/go/http.dart +++ b/lib/codegen/go/http.dart @@ -99,7 +99,7 @@ func main() { var templateStart = jj.Template(kTemplateStart); result += templateStart.render({ - "hasBody": requestModel.hasData, + "hasBody": requestModel.hasBody, "hasFormData": requestModel.hasFormData, "hasFileInFormData": requestModel.hasFileInFormData, }); @@ -144,7 +144,7 @@ func main() { }); var headersList = requestModel.enabledRequestHeaders; - if (headersList != null || requestModel.hasData) { + if (headersList != null || requestModel.hasBody) { var headers = requestModel.enabledHeadersMap; if (requestModel.hasJsonData || requestModel.hasTextData) { headers.putIfAbsent(kHeaderContentType, diff --git a/lib/codegen/python/http_client.dart b/lib/codegen/python/http_client.dart index 05fb8253..2df5132c 100644 --- a/lib/codegen/python/http_client.dart +++ b/lib/codegen/python/http_client.dart @@ -116,7 +116,7 @@ body = b'\r\n'.join(dataList) } } - if (requestModel.hasData) { + if (requestModel.hasBody) { hasBody = true; if (requestModel.hasJsonData || requestModel.hasTextData) { var templateBody = jj.Template(kTemplateBody); diff --git a/lib/models/request_model.dart b/lib/models/request_model.dart index 8a1fea7e..6bdff603 100644 --- a/lib/models/request_model.dart +++ b/lib/models/request_model.dart @@ -68,7 +68,7 @@ class RequestModel { bool get hasJsonContentType => requestBodyContentType == ContentType.json; bool get hasTextContentType => requestBodyContentType == ContentType.text; int get contentLength => utf8.encode(requestBody ?? "").length; - bool get hasData => hasJsonData || hasTextData || hasFormData; + bool get hasBody => hasJsonData || hasTextData || hasFormData; bool get hasJsonData => kMethodsWithBody.contains(method) && hasJsonContentType && diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart index 7658c8a0..503355f8 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart @@ -37,7 +37,7 @@ class EditRequestHeadersState extends ConsumerState { @override Widget build(BuildContext context) { final selectedId = ref.watch(selectedIdStateProvider); - final length = ref.watch(selectedRequestModelProvider + ref.watch(selectedRequestModelProvider .select((value) => value?.requestHeaders?.length)); var rH = ref.read(selectedRequestModelProvider)?.requestHeaders; rows = (rH == null || rH.isEmpty) diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_pane.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_pane.dart index a09c4609..337f0785 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_pane.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_pane.dart @@ -17,11 +17,14 @@ class EditRequestPane extends ConsumerWidget { selectedRequestModelProvider.select((value) => value?.requestTabIndex)); final headerLength = ref.watch(selectedRequestModelProvider - .select((value) => value?.headersMap.length)); + .select((value) => value?.headersMap.length)) ?? + 0; final paramLength = ref.watch(selectedRequestModelProvider - .select((value) => value?.paramsMap.length)); - final bodyLength = ref.watch(selectedRequestModelProvider - .select((value) => value?.requestBody?.length)); + .select((value) => value?.paramsMap.length)) ?? + 0; + final hasBody = ref.watch( + selectedRequestModelProvider.select((value) => value?.hasBody)) ?? + false; return RequestPane( selectedId: selectedId, @@ -37,9 +40,9 @@ class EditRequestPane extends ConsumerWidget { .update(selectedId!, requestTabIndex: index); }, showIndicators: [ - paramLength != null && paramLength > 0, - headerLength != null && headerLength > 0, - bodyLength != null && bodyLength > 0, + paramLength > 0, + headerLength > 0, + hasBody, ], children: const [ EditRequestURLParams(), diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart index 01005df6..6e3aca4b 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart @@ -38,7 +38,7 @@ class EditRequestURLParamsState extends ConsumerState { @override Widget build(BuildContext context) { final selectedId = ref.watch(selectedIdStateProvider); - final length = ref.watch(selectedRequestModelProvider + ref.watch(selectedRequestModelProvider .select((value) => value?.requestParams?.length)); var rP = ref.read(selectedRequestModelProvider)?.requestParams; rows = (rP == null || rP.isEmpty) From c287ce83aaec8e6b401c89b67b735456961b9604 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sat, 16 Mar 2024 17:13:49 +0530 Subject: [PATCH 90/91] Update CONTRIBUTING.md --- CONTRIBUTING.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 46a9b053..211eaf06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -129,21 +129,28 @@ flutter test test/widgets/codegen_previewer_test.dart Instead of copy pasting from pub.dev, it is recommended that you use `flutter pub add package_name` to add a new package to `pubspec.yaml`. You can read more [here](https://docs.flutter.dev/packages-and-plugins/using-packages#adding-a-package-dependency-to-an-app-using-flutter-pub-add). -## Troubleshooting Common Issues +## Platform-specific Additional Instructions -### Network Connection Issues on macOS +### macOS -If you encounter a network connection error similar to the following while running your Flutter app on macOS: +Add below keys to `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`. + +``` + com.apple.security.network.server + + com.apple.security.network.client + + com.apple.security.files.downloads.read-write + + com.apple.security.files.user-selected.read-write + +``` + +If not added, you can encounter a network connection error similar to the following while running your Flutter app on macOS: ``` ClientException with SocketException: Connection failed (OS Error: Operation not permitted, errno = 1) ``` -Add below key to `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`. - -``` - com.apple.security.network.client - -``` You can read more [here](https://docs.flutter.dev/platform-integration/macos/building#setting-up-entitlements) From 09c572c2908599f74d834455ab752a6e6155053d Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sat, 16 Mar 2024 17:20:53 +0530 Subject: [PATCH 91/91] chore: bump pubspec --- pubspec.lock | 122 +++++++++++++++++++++++++++------------------------ pubspec.yaml | 57 ++++++++++++------------ 2 files changed, 95 insertions(+), 84 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 4125ed98..a4e54dfb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -117,10 +117,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" url: "https://pub.dev" source: hosted - version: "2.4.7" + version: "2.4.8" build_runner_core: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: "direct main" description: name: code_builder - sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.10.0" collection: dependency: "direct main" description: @@ -221,18 +221,18 @@ packages: dependency: "direct main" description: name: csv - sha256: "63ed2871dd6471193dffc52c0e6c76fb86269c00244d244297abbb355c84a86e" + sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "6.0.0" dart_style: dependency: "direct main" description: name: dart_style - sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.6" davi: dependency: "direct main" description: @@ -293,10 +293,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6" + sha256: caa6bc229eab3e32eb2f37b53a5f9d22a6981474afd210c512a7546c1e1a04f6 url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.2.0" fixnum: dependency: transitive description: @@ -378,10 +378,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "35108526a233cc0755664d445f8a6b4b61e6f8fe993b3658b80b4a26827fc196" + sha256: cb44f7831b23a6bdd0f501718b0d2e8045cbc625a15f668af37ddb80314821db url: "https://pub.dev" source: hosted - version: "0.6.18+2" + version: "0.6.21" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -394,18 +394,18 @@ packages: dependency: "direct main" description: name: flutter_riverpod - sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5 + sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.5.1" flutter_svg: dependency: "direct main" description: name: flutter_svg - sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c + sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.0.10+1" flutter_test: dependency: "direct dev" description: flutter @@ -428,10 +428,10 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "6c5031daae12c7072b3a87eff98983076434b4889ef2a44384d0cae3f82372ba" + sha256: "57247f692f35f068cae297549a46a9a097100685c6780fe67177503eea5ed4e5" url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.7" freezed_annotation: dependency: "direct main" description: @@ -460,10 +460,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8 + sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.2.1" graphs: dependency: transitive description: @@ -572,8 +572,8 @@ packages: dependency: "direct main" description: path: "." - ref: "9fa58d7b51e65174ab11cbcae17bba88a4194dde" - resolved-ref: "9fa58d7b51e65174ab11cbcae17bba88a4194dde" + ref: b7dde2f85dff4f482eed7eda4ef2a71344ef8b3a + resolved-ref: b7dde2f85dff4f482eed7eda4ef2a71344ef8b3a url: "https://github.com/foss42/json_data_explorer.git" source: git version: "0.1.2" @@ -677,18 +677,18 @@ packages: dependency: "direct main" description: name: lottie - sha256: a93542cc2d60a7057255405f62252533f8e8956e7e06754955669fd32fb4b216 + sha256: ce2bb2605753915080e4ee47f036a64228c88dc7f56f7bc1dbe912d75b55b1e2 url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "3.1.0" markdown: dependency: "direct main" description: name: markdown - sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd + sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 url: "https://pub.dev" source: hosted - version: "7.1.1" + version: "7.2.2" matcher: dependency: transitive description: @@ -773,10 +773,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "5.0.1" package_info_plus_platform_interface: dependency: transitive description: @@ -805,10 +805,10 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: @@ -857,6 +857,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.10.7" + pdf_widget_wrapper: + dependency: transitive + description: + name: pdf_widget_wrapper + sha256: "9c3ca36e5000c9682d52bbdc486867ba7c5ee4403d1a5d6d03ed72157753377b" + url: "https://pub.dev" + source: hosted + version: "1.0.3" petitparser: dependency: transitive description: @@ -909,10 +917,10 @@ packages: dependency: transitive description: name: pointer_interceptor_web - sha256: a6237528b46c411d8d55cdfad8fcb3269fc4cbb26060b14bff94879165887d1e + sha256: "9386e064097fd16419e935c23f08f35b58e6aaec155dd39bd6a003b88f9c14b4" url: "https://pub.dev" source: hosted - version: "0.10.2" + version: "0.10.1+2" pointycastle: dependency: transitive description: @@ -933,18 +941,18 @@ packages: dependency: "direct main" description: name: printing - sha256: ad39a42a5f83125952457dfd94f395c8cf0eb1f7759583dadb769be5c7f99d24 + sha256: "1c99cab90ebcc1fff65831d264627d5b529359d563e53f33ab9b8117f2d280bc" url: "https://pub.dev" source: hosted - version: "5.11.1" + version: "5.12.0" provider: dependency: "direct main" description: name: provider - sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.1.2" pub_semver: dependency: transitive description: @@ -970,13 +978,13 @@ packages: source: hosted version: "3.0.1" riverpod: - dependency: transitive + dependency: "direct main" description: name: riverpod - sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11" + sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.5.1" rxdart: dependency: transitive description: @@ -997,10 +1005,10 @@ packages: dependency: "direct main" description: name: scrollable_positioned_list - sha256: "9566352ab9ba05794ee6c8864f154afba5d36c5637d0e3e32c615ba4ceb92772" + sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.3.8" shelf: dependency: transitive description: @@ -1186,10 +1194,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 + sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.2.5" url_launcher_android: dependency: transitive description: @@ -1234,10 +1242,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.3" url_launcher_windows: dependency: transitive description: @@ -1250,34 +1258,34 @@ packages: dependency: "direct main" description: name: uuid - sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" + sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.3.3" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43" + sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.11+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7" + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.11+1" vector_graphics_compiler: dependency: "direct main" description: name: vector_graphics_compiler - sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26 + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" url: "https://pub.dev" source: hosted - version: "1.1.9+1" + version: "1.1.11+1" vector_math: dependency: transitive description: @@ -1303,7 +1311,7 @@ packages: source: hosted version: "1.1.0" web: - dependency: "direct main" + dependency: "direct overridden" description: name: web sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" @@ -1338,10 +1346,10 @@ packages: dependency: "direct main" description: name: window_manager - sha256: dcc865277f26a7dad263a47d0e405d77e21f12cb71f30333a52710a408690bd7 + sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494 url: "https://pub.dev" source: hosted - version: "0.3.7" + version: "0.3.8" window_size: dependency: "direct main" description: @@ -1377,4 +1385,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + flutter: ">=3.19.2" diff --git a/pubspec.yaml b/pubspec.yaml index ab250f26..6f78ae1e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,25 +1,25 @@ name: apidash description: API Dash is a beautiful open-source cross-platform API Client built using Flutter which can help you easily create & customize your API requests, visually inspect responses and generate Dart code on the go. publish_to: "none" -version: 0.3.0+3 +version: 0.4.0+4 environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.16.0" + flutter: ">=3.19.0" dependencies: flutter: sdk: flutter - web: ^0.5.0 multi_split_view: ^2.4.0 - url_launcher: ^6.1.12 - flutter_riverpod: ^2.3.7 - uuid: ^4.1.0 + url_launcher: ^6.2.5 + flutter_riverpod: ^2.5.1 + riverpod: ^2.5.1 + uuid: ^4.3.3 davi: ^3.4.1 - http: ^1.1.0 + http: ^1.2.1 http_parser: ^4.0.2 collection: ^1.17.2 - google_fonts: ^6.1.0 + google_fonts: ^6.2.1 highlighter: ^0.1.1 xml: ^6.3.0 jinja: ^0.5.0 @@ -28,43 +28,46 @@ dependencies: url: https://github.com/google/flutter-desktop-embedding.git path: plugins/window_size hive_flutter: ^1.1.0 - lottie: ^2.6.0 + lottie: ^3.1.0 mime_dart: ^3.0.0 - path_provider: ^2.1.0 - window_manager: ^0.3.5 + path_provider: ^2.1.2 + window_manager: ^0.3.8 path: ^1.8.3 - flutter_markdown: ^0.6.17+1 - markdown: ^7.1.1 + flutter_markdown: ^0.6.21 + markdown: ^7.2.2 just_audio: ^0.9.34 just_audio_mpv: ^0.1.7 just_audio_windows: ^0.2.0 freezed_annotation: ^2.4.1 json_annotation: ^4.8.1 - printing: ^5.11.1 - package_info_plus: ^4.1.0 + printing: ^5.12.0 + package_info_plus: ^5.0.1 flutter_typeahead: ^5.2.0 - provider: ^6.0.5 + provider: ^6.1.2 json_data_explorer: git: url: https://github.com/foss42/json_data_explorer.git - ref: 9fa58d7b51e65174ab11cbcae17bba88a4194dde - scrollable_positioned_list: ^0.2.3 - file_picker: ^6.1.1 - flutter_svg: ^2.0.9 + ref: b7dde2f85dff4f482eed7eda4ef2a71344ef8b3a + scrollable_positioned_list: ^0.3.8 + file_picker: ^6.2.0 + flutter_svg: ^2.0.10+1 vector_graphics_compiler: ^1.1.9+1 - code_builder: ^4.9.0 - dart_style: ^2.3.4 + code_builder: ^4.10.0 + dart_style: ^2.3.6 json_text_field: ^1.1.0 - csv: ^5.1.1 + csv: ^6.0.0 + +dependency_overrides: + web: ^0.5.0 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^3.0.0 + flutter_lints: ^3.0.1 flutter_launcher_icons: ^0.13.1 - test: ^1.24.3 - build_runner: ^2.4.6 - freezed: ^2.4.1 + test: ^1.24.9 + build_runner: ^2.4.8 + freezed: ^2.4.7 json_serializable: ^6.7.1 flutter: