From 2dead8f52028f5da4e77319ca2f2f34847834b2e Mon Sep 17 00:00:00 2001 From: Alberto Zabeo <alberto.zabeo@pocketlaw.com> Date: Sun, 16 Feb 2025 02:11:15 +0100 Subject: [PATCH] feat: dart support --- src/helpers/__snapshots__/utils.test.ts.snap | 14 +++ src/targets/dart/http/client.test.ts | 40 +++++++ src/targets/dart/http/client.ts | 101 ++++++++++++++++++ .../fixtures/application-form-encoded.dart | 18 ++++ .../dart/http/fixtures/application-json.dart | 18 ++++ .../http/fixtures/boilerplate-option.dart | 14 +++ src/targets/dart/http/fixtures/cookies.dart | 17 +++ .../dart/http/fixtures/custom-method.dart | 13 +++ src/targets/dart/http/fixtures/full.dart | 20 ++++ src/targets/dart/http/fixtures/headers.dart | 19 ++++ src/targets/dart/http/fixtures/https.dart | 13 +++ .../dart/http/fixtures/jsonObj-multiline.dart | 18 ++++ .../http/fixtures/jsonObj-null-value.dart | 18 ++++ .../dart/http/fixtures/multipart-data.dart | 18 ++++ .../dart/http/fixtures/multipart-file.dart | 18 ++++ .../multipart-form-data-no-params.dart | 17 +++ .../http/fixtures/multipart-form-data.dart | 18 ++++ src/targets/dart/http/fixtures/nested.dart | 13 +++ .../dart/http/fixtures/print-body-option.dart | 19 ++++ src/targets/dart/http/fixtures/query.dart | 13 +++ src/targets/dart/http/fixtures/short.dart | 13 +++ .../dart/http/fixtures/text-plain.dart | 18 ++++ .../dart/http/fixtures/timeout-option.dart | 23 ++++ src/targets/dart/target.ts | 14 +++ src/targets/targets.ts | 2 + 25 files changed, 509 insertions(+) create mode 100644 src/targets/dart/http/client.test.ts create mode 100644 src/targets/dart/http/client.ts create mode 100644 src/targets/dart/http/fixtures/application-form-encoded.dart create mode 100644 src/targets/dart/http/fixtures/application-json.dart create mode 100644 src/targets/dart/http/fixtures/boilerplate-option.dart create mode 100644 src/targets/dart/http/fixtures/cookies.dart create mode 100644 src/targets/dart/http/fixtures/custom-method.dart create mode 100644 src/targets/dart/http/fixtures/full.dart create mode 100644 src/targets/dart/http/fixtures/headers.dart create mode 100644 src/targets/dart/http/fixtures/https.dart create mode 100644 src/targets/dart/http/fixtures/jsonObj-multiline.dart create mode 100644 src/targets/dart/http/fixtures/jsonObj-null-value.dart create mode 100644 src/targets/dart/http/fixtures/multipart-data.dart create mode 100644 src/targets/dart/http/fixtures/multipart-file.dart create mode 100644 src/targets/dart/http/fixtures/multipart-form-data-no-params.dart create mode 100644 src/targets/dart/http/fixtures/multipart-form-data.dart create mode 100644 src/targets/dart/http/fixtures/nested.dart create mode 100644 src/targets/dart/http/fixtures/print-body-option.dart create mode 100644 src/targets/dart/http/fixtures/query.dart create mode 100644 src/targets/dart/http/fixtures/short.dart create mode 100644 src/targets/dart/http/fixtures/text-plain.dart create mode 100644 src/targets/dart/http/fixtures/timeout-option.dart create mode 100644 src/targets/dart/target.ts diff --git a/src/helpers/__snapshots__/utils.test.ts.snap b/src/helpers/__snapshots__/utils.test.ts.snap index 6ba3a2d2..9bfc4966 100644 --- a/src/helpers/__snapshots__/utils.test.ts.snap +++ b/src/helpers/__snapshots__/utils.test.ts.snap @@ -64,6 +64,20 @@ Array [ "key": "csharp", "title": "C#", }, + Object { + "clients": Array [ + Object { + "description": "Dart HTTP client request using the http package", + "key": "http", + "link": "https://pub.dev/packages/http", + "title": "HTTP", + }, + ], + "default": "http", + "extname": ".dart", + "key": "dart", + "title": "Dart", + }, Object { "clients": Array [ Object { diff --git a/src/targets/dart/http/client.test.ts b/src/targets/dart/http/client.test.ts new file mode 100644 index 00000000..de9ae059 --- /dev/null +++ b/src/targets/dart/http/client.test.ts @@ -0,0 +1,40 @@ +import full from '../../../fixtures/requests/full.json'; +import { runCustomFixtures } from '../../../fixtures/runCustomFixtures'; +import { Request } from '../../../httpsnippet'; + +runCustomFixtures({ + targetId: 'dart', + clientId: 'http', + tests: [ + { + it: 'should support false boilerplate option', + input: full as Request, + options: { + showBoilerplate: false, + }, + expected: 'boilerplate-option.dart', + }, + { + it: 'should support printBody option', + input: full as Request, + options: { + printBody: false, + }, + expected: 'print-body-option.dart', + }, + { + it: 'should support timeout option', + input: full as Request, + options: { + timeout: 30, + }, + expected: 'timeout-option.dart', + }, + { + it: 'should generate full request', + input: full as Request, + options: {}, + expected: 'full.dart', + }, + ], +}); \ No newline at end of file diff --git a/src/targets/dart/http/client.ts b/src/targets/dart/http/client.ts new file mode 100644 index 00000000..d600368c --- /dev/null +++ b/src/targets/dart/http/client.ts @@ -0,0 +1,101 @@ +/** + * @description + * HTTP code snippet generator for Dart http package. + * + * @author + * @AI-Generated + * + * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author. + */ + +import { CodeBuilder } from '../../../helpers/code-builder'; +import { escapeForSingleQuotes } from '../../../helpers/escape'; +import { Client } from '../../targets'; + +export interface DartHttpOptions { + showBoilerplate?: boolean; + checkErrors?: boolean; + printBody?: boolean; + timeout?: number; + insecureSkipVerify?: boolean; +} + +export const http: Client<DartHttpOptions> = { + info: { + key: 'http', + title: 'HTTP', + link: 'https://pub.dev/packages/http', + description: 'Dart HTTP client request using the http package', + }, + convert: ({ postData, method, allHeaders, fullUrl }, options = {}) => { + const { blank, push, join } = new CodeBuilder({ indent: ' ' }); + + const { + showBoilerplate = true, + checkErrors = false, + printBody = true, + timeout = -1, + insecureSkipVerify = false, + } = options; + + const indent = showBoilerplate ? 1 : 0; + + // Create boilerplate + if (showBoilerplate) { + push('import \'package:http/http.dart\' as http;'); + + blank(); + push('void main() async {'); + blank(); + } + + // Create client with timeout if specified + if (timeout > 0) { + push('final client = http.Client();', indent); + push(`client.timeout = Duration(seconds: ${timeout});`, indent); + blank(); + } + + // Add headers setup + if (Object.keys(allHeaders).length) { + push('final headers = {', indent); + Object.keys(allHeaders).forEach(key => { + push(`'${key}': '${escapeForSingleQuotes(allHeaders[key])}',`, indent + 1); + }); + push('};', indent); + blank(); + } + + // Prepare request + const headersVar = Object.keys(allHeaders).length ? 'headers' : '{}'; + + if (postData.text) { + push(`final response = await http.${method.toLowerCase()}(`, indent); + push(` Uri.parse('${fullUrl}'),`, indent); + push(` headers: ${headersVar},`, indent); + push(` body: ${JSON.stringify(postData.text)},`, indent); + push(');', indent); + } else { + push(`final response = await http.${method.toLowerCase()}(`, indent); + push(` Uri.parse('${fullUrl}'),`, indent); + push(` headers: ${headersVar},`, indent); + push(');', indent); + } + + // Print response + blank(); + push('print(response.statusCode);', indent); + + if (printBody) { + push('print(response.body);', indent); + } + + // End main block + if (showBoilerplate) { + blank(); + push('}'); + } + + return join(); + }, +}; \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/application-form-encoded.dart b/src/targets/dart/http/fixtures/application-form-encoded.dart new file mode 100644 index 00000000..9090c091 --- /dev/null +++ b/src/targets/dart/http/fixtures/application-form-encoded.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'application/x-www-form-urlencoded', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "foo=bar&hello=world", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/application-json.dart b/src/targets/dart/http/fixtures/application-json.dart new file mode 100644 index 00000000..7bcefea2 --- /dev/null +++ b/src/targets/dart/http/fixtures/application-json.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'application/json', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":{}}],\"boolean\":false}", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/boilerplate-option.dart b/src/targets/dart/http/fixtures/boilerplate-option.dart new file mode 100644 index 00000000..c838c0aa --- /dev/null +++ b/src/targets/dart/http/fixtures/boilerplate-option.dart @@ -0,0 +1,14 @@ +final headers = { + 'cookie': 'foo=bar; bar=baz', + 'accept': 'application/json', + 'content-type': 'application/x-www-form-urlencoded', +}; + +final response = await http.post( + Uri.parse('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value'), + headers: headers, + body: "foo=bar", +); + +print(response.statusCode); +print(response.body); \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/cookies.dart b/src/targets/dart/http/fixtures/cookies.dart new file mode 100644 index 00000000..2e685c5e --- /dev/null +++ b/src/targets/dart/http/fixtures/cookies.dart @@ -0,0 +1,17 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'cookie': 'foo=bar; bar=baz', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/custom-method.dart b/src/targets/dart/http/fixtures/custom-method.dart new file mode 100644 index 00000000..a1ac39c1 --- /dev/null +++ b/src/targets/dart/http/fixtures/custom-method.dart @@ -0,0 +1,13 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final response = await http.propfind( + Uri.parse('http://mockbin.com/har'), + headers: {}, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/full.dart b/src/targets/dart/http/fixtures/full.dart new file mode 100644 index 00000000..1108eeb9 --- /dev/null +++ b/src/targets/dart/http/fixtures/full.dart @@ -0,0 +1,20 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'cookie': 'foo=bar; bar=baz', + 'accept': 'application/json', + 'content-type': 'application/x-www-form-urlencoded', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value'), + headers: headers, + body: "foo=bar", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/headers.dart b/src/targets/dart/http/fixtures/headers.dart new file mode 100644 index 00000000..f5236e5f --- /dev/null +++ b/src/targets/dart/http/fixtures/headers.dart @@ -0,0 +1,19 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'accept': 'application/json', + 'x-foo': 'Bar', + 'quoted-value': '"quoted" \'string\'', + }; + + final response = await http.get( + Uri.parse('http://mockbin.com/har'), + headers: headers, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/https.dart b/src/targets/dart/http/fixtures/https.dart new file mode 100644 index 00000000..a8a8762c --- /dev/null +++ b/src/targets/dart/http/fixtures/https.dart @@ -0,0 +1,13 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final response = await http.get( + Uri.parse('https://mockbin.com/har'), + headers: {}, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/jsonObj-multiline.dart b/src/targets/dart/http/fixtures/jsonObj-multiline.dart new file mode 100644 index 00000000..5e4035e9 --- /dev/null +++ b/src/targets/dart/http/fixtures/jsonObj-multiline.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'application/json', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "{\n \"foo\": \"bar\"\n}", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/jsonObj-null-value.dart b/src/targets/dart/http/fixtures/jsonObj-null-value.dart new file mode 100644 index 00000000..d9d4f54f --- /dev/null +++ b/src/targets/dart/http/fixtures/jsonObj-null-value.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'application/json', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "{\"foo\":null}", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/multipart-data.dart b/src/targets/dart/http/fixtures/multipart-data.dart new file mode 100644 index 00000000..297cffd6 --- /dev/null +++ b/src/targets/dart/http/fixtures/multipart-data.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'multipart/form-data; boundary=---011000010111000001101001', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"bar\"\r\n\r\nBonjour le monde\r\n-----011000010111000001101001--\r\n", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/multipart-file.dart b/src/targets/dart/http/fixtures/multipart-file.dart new file mode 100644 index 00000000..7ba71f34 --- /dev/null +++ b/src/targets/dart/http/fixtures/multipart-file.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'multipart/form-data; boundary=---011000010111000001101001', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\n\r\n-----011000010111000001101001--\r\n", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/multipart-form-data-no-params.dart b/src/targets/dart/http/fixtures/multipart-form-data-no-params.dart new file mode 100644 index 00000000..21b1f16b --- /dev/null +++ b/src/targets/dart/http/fixtures/multipart-form-data-no-params.dart @@ -0,0 +1,17 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'Content-Type': 'multipart/form-data', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/multipart-form-data.dart b/src/targets/dart/http/fixtures/multipart-form-data.dart new file mode 100644 index 00000000..3515013d --- /dev/null +++ b/src/targets/dart/http/fixtures/multipart-form-data.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n-----011000010111000001101001--\r\n", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/nested.dart b/src/targets/dart/http/fixtures/nested.dart new file mode 100644 index 00000000..97a4aa74 --- /dev/null +++ b/src/targets/dart/http/fixtures/nested.dart @@ -0,0 +1,13 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final response = await http.get( + Uri.parse('http://mockbin.com/har?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value'), + headers: {}, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/print-body-option.dart b/src/targets/dart/http/fixtures/print-body-option.dart new file mode 100644 index 00000000..56b0b26a --- /dev/null +++ b/src/targets/dart/http/fixtures/print-body-option.dart @@ -0,0 +1,19 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'cookie': 'foo=bar; bar=baz', + 'accept': 'application/json', + 'content-type': 'application/x-www-form-urlencoded', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value'), + headers: headers, + body: "foo=bar", + ); + + print(response.statusCode); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/query.dart b/src/targets/dart/http/fixtures/query.dart new file mode 100644 index 00000000..d246a2db --- /dev/null +++ b/src/targets/dart/http/fixtures/query.dart @@ -0,0 +1,13 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final response = await http.get( + Uri.parse('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value'), + headers: {}, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/short.dart b/src/targets/dart/http/fixtures/short.dart new file mode 100644 index 00000000..05f186a7 --- /dev/null +++ b/src/targets/dart/http/fixtures/short.dart @@ -0,0 +1,13 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final response = await http.get( + Uri.parse('http://mockbin.com/har'), + headers: {}, + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/text-plain.dart b/src/targets/dart/http/fixtures/text-plain.dart new file mode 100644 index 00000000..08c430ec --- /dev/null +++ b/src/targets/dart/http/fixtures/text-plain.dart @@ -0,0 +1,18 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final headers = { + 'content-type': 'text/plain', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har'), + headers: headers, + body: "Hello World", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/http/fixtures/timeout-option.dart b/src/targets/dart/http/fixtures/timeout-option.dart new file mode 100644 index 00000000..93529116 --- /dev/null +++ b/src/targets/dart/http/fixtures/timeout-option.dart @@ -0,0 +1,23 @@ +import 'package:http/http.dart' as http; + +void main() async { + + final client = http.Client(); + client.timeout = Duration(seconds: 30); + + final headers = { + 'cookie': 'foo=bar; bar=baz', + 'accept': 'application/json', + 'content-type': 'application/x-www-form-urlencoded', + }; + + final response = await http.post( + Uri.parse('http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value'), + headers: headers, + body: "foo=bar", + ); + + print(response.statusCode); + print(response.body); + +} \ No newline at end of file diff --git a/src/targets/dart/target.ts b/src/targets/dart/target.ts new file mode 100644 index 00000000..7303e6e4 --- /dev/null +++ b/src/targets/dart/target.ts @@ -0,0 +1,14 @@ +import { Target } from '../targets'; +import { http } from './http/client'; + +export const dart: Target = { + info: { + key: 'dart', + title: 'Dart', + extname: '.dart', + default: 'http', + }, + clientsById: { + http, + }, +}; \ No newline at end of file diff --git a/src/targets/targets.ts b/src/targets/targets.ts index 7f9362d4..44044c02 100644 --- a/src/targets/targets.ts +++ b/src/targets/targets.ts @@ -6,6 +6,7 @@ import { c } from './c/target'; import { clojure } from './clojure/target'; import { crystal } from './crystal/target'; import { csharp } from './csharp/target'; +import { dart } from './dart/target'; import { go } from './go/target'; import { http } from './http/target'; import { java } from './java/target'; @@ -63,6 +64,7 @@ export const targets = { clojure, crystal, csharp, + dart, go, http, java,