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,