Skip to content

Commit 10348c7

Browse files
authored
Merge branch 'main' into AdtD1
2 parents cc200fb + b87cb08 commit 10348c7

File tree

77 files changed

+12637
-2588
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+12637
-2588
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ _Add your description_
99

1010
### Checklist
1111
- [ ] I have gone through the [contributing guide](https://github.com/foss42/apidash/blob/main/CONTRIBUTING.md)
12+
- [ ] I have updated my branch and synced it with project `main` branch before making this PR
1213
- [ ] I have run the tests (`flutter test`) and all tests are passing
1314

1415
## Added/updated tests?
1516
_We encourage you to add relevant test cases._
1617

1718
- [ ] Yes
1819
- [ ] No, and this is why: _please replace this line with details on why tests have not been included_
19-
- [ ] I need help with writing tests

CONTRIBUTING.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,30 @@ flutter test test/widgets/codegen_previewer_test.dart
128128
### How to add a new package to pubspec.yaml?
129129

130130
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).
131+
132+
## Platform-specific Additional Instructions
133+
134+
### macOS
135+
136+
Add below keys to `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`.
137+
138+
```
139+
<key>com.apple.security.network.server</key>
140+
<true/>
141+
<key>com.apple.security.network.client</key>
142+
<true/>
143+
<key>com.apple.security.files.downloads.read-write</key>
144+
<true/>
145+
<key>com.apple.security.files.user-selected.read-write</key>
146+
<true/>
147+
```
148+
149+
If not added, you can encounter a network connection error similar to the following while running your Flutter app on macOS:
150+
151+
```
152+
ClientException with SocketException: Connection failed (OS Error: Operation not permitted, errno = 1)
153+
```
154+
155+
You can read more [here](https://docs.flutter.dev/platform-integration/macos/building#setting-up-entitlements)
156+
157+

README.md

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@
22

33
[![Discord Server Invite](https://img.shields.io/badge/DISCORD-JOIN%20SERVER-5663F7?style=for-the-badge&logo=discord&logoColor=white)](https://bit.ly/heyfoss)
44

5-
We are participating in GSoC 2024 🎉 [More Details ...](https://summerofcode.withgoogle.com/programs/2024/organizations/api-dash)
5+
🚨 We are participating in GSoC 2024 🎉
6+
7+
<img src="https://github.com/foss42/apidash/assets/615622/493ce57f-06c3-4789-b7ae-9fa63bca8183" alt="GSoC" width="500">
8+
9+
| | Link |
10+
|--|--|
11+
| Learn about GSoC | [Link](https://summerofcode.withgoogle.com) |
12+
| Organization page on GSoC | [Link](https://summerofcode.withgoogle.com/programs/2024/organizations/api-dash) |
13+
| Project Ideas List | [Link](https://github.com/foss42/apidash/discussions/112) |
14+
| Application Guide | [Link](https://github.com/foss42/apidash/discussions/111) |
15+
| Discord Channel | [Link](https://discord.com/invite/2s49SCNfyJ) |
616

717
### Please support this initiative by giving this project a Star ⭐️
818

@@ -113,18 +123,28 @@ API Dash can be downloaded from the links below:
113123

114124
API Dash currently supports API integration code generation for the following languages/libraries.
115125

116-
| Language | Library |
117-
| ---------------------- | ------------- |
118-
| cURL | |
119-
| HAR | |
120-
| Dart | `http` |
121-
| JavaScript | `axios` |
122-
| JavaScript | `fetch` |
123-
| JavaScript (`node.js`) | `axios` |
124-
| JavaScript (`node.js`) | `fetch` |
125-
| Python | `http.client` |
126-
| Python | `requests` |
127-
| Kotlin | `okhttp3` |
126+
| Language | Library | Comment/Issues |
127+
| ---------------------- | ------------- | ------- |
128+
| cURL | | |
129+
| HAR | | |
130+
| Dart | `http` | |
131+
| Dart | `dio` | |
132+
| Go | `net/http` | |
133+
| JavaScript | `axios` | |
134+
| JavaScript | `fetch` | |
135+
| JavaScript (`node.js`) | `axios` | |
136+
| JavaScript (`node.js`) | `fetch` | |
137+
| Python | `requests` | |
138+
| Python | `http.client` | |
139+
| Kotlin | `okhttp3` | |
140+
| Rust | `reqwest` | |
141+
| Rust | `ureq` | |
142+
| Rust | `Actix Client` | |
143+
| Java | `asynchttpclient` | https://github.com/foss42/apidash/issues/136 |
144+
| Java | `HttpClient` | https://github.com/foss42/apidash/issues/137 |
145+
| Java | `okhttp3` | |
146+
| Julia | `HTTP` | https://github.com/foss42/apidash/issues/154 |
147+
| PHP | `guzzle` | https://github.com/foss42/apidash/issues/143 |
128148

129149
We welcome contributions to support other programming languages/libraries/frameworks. Please check out more details [here](https://github.com/foss42/apidash/discussions/80).
130150

@@ -137,6 +157,7 @@ Here is the complete list of mimetypes that can be directly previewed in API Das
137157
| File Type | Mimetype | Extension | Comment |
138158
| --------- | -------------------------- | ----------------- | -------- |
139159
| PDF | `application/pdf` | `.pdf` | |
160+
| CSV | `text/csv` | `.csv` | Can be improved |
140161
| Image | `image/apng` | `.apng` | Animated |
141162
| Image | `image/avif` | `.avif` | |
142163
| Image | `image/bmp` | `.bmp` | |
@@ -177,14 +198,14 @@ Here is the complete list of mimetypes that are syntax highlighted in API Dash:
177198
| ------------------ | --------- | ------------------------------------------------------------------------------------------------------------------ |
178199
| `application/json` | `.json` | Other mimetypes like `application/geo+json`, `application/vcard+json` that are based on `json` are also supported. |
179200
| `application/xml` | `.xml` | Other mimetypes like `application/xhtml+xml`, `application/vcard+xml` that are based on `xml` are also supported. |
180-
| `text/xml` | `.xml` | |
181-
| `application/yaml` | `.yaml` | Others - `application/x-yaml` or `application/x-yml` |
182-
| `text/yaml` | `.yaml` | Others - `text/yml` |
183-
| `application/sql` | `.sql` | |
184-
| `text/css` | `.css` | |
185-
| `text/html` | `.html` | Only syntax highlighting, no web preview. |
186-
| `text/javascript` | `.js` | |
187-
| `text/markdown` | `.md` | |
201+
| `text/xml` | `.xml` | |
202+
| `application/yaml` | `.yaml` | Others - `application/x-yaml` or `application/x-yml` |
203+
| `text/yaml` | `.yaml` | Others - `text/yml` |
204+
| `application/sql` | `.sql` | |
205+
| `text/css` | `.css` | |
206+
| `text/html` | `.html` | Only syntax highlighting, no web preview. |
207+
| `text/javascript` | `.js` | |
208+
| `text/markdown` | `.md` | |
188209

189210
## What's new in v0.3.0?
190211

lib/codegen/codegen.dart

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,84 @@
11
import 'package:apidash/models/models.dart' show RequestModel;
22
import 'package:apidash/consts.dart';
3+
import 'package:apidash/utils/utils.dart' show getNewUuid;
34
import 'dart/http.dart';
45
import 'dart/dio.dart';
6+
import 'go/http.dart';
57
import 'kotlin/okhttp.dart';
8+
import 'php/guzzle.dart';
69
import 'python/http_client.dart';
710
import 'python/requests.dart';
11+
import 'rust/actix.dart';
12+
import 'rust/reqwest.dart';
13+
import 'rust/ureq.dart';
814
import 'js/axios.dart';
915
import 'js/fetch.dart';
1016
import 'others/har.dart';
1117
import 'others/curl.dart';
18+
import 'julia/http.dart';
19+
import 'java/okhttp.dart';
20+
import 'java/async_http_client.dart';
21+
import 'java/httpclient.dart';
1222

1323
class Codegen {
1424
String? getCode(
1525
CodegenLanguage codegenLanguage,
1626
RequestModel requestModel,
17-
String defaultUriScheme,
18-
) {
27+
String defaultUriScheme, {
28+
String? boundary,
29+
}) {
30+
String url = requestModel.url;
31+
32+
if (url.isEmpty) {
33+
url = kDefaultUri;
34+
}
35+
if (!url.contains("://") && url.isNotEmpty) {
36+
url = "$defaultUriScheme://$url";
37+
}
38+
var rM = requestModel.copyWith(url: url);
39+
1940
switch (codegenLanguage) {
2041
case CodegenLanguage.curl:
21-
return cURLCodeGen().getCode(requestModel, defaultUriScheme);
42+
return cURLCodeGen().getCode(rM);
2243
case CodegenLanguage.har:
23-
return HARCodeGen().getCode(requestModel, defaultUriScheme);
44+
return HARCodeGen().getCode(rM, defaultUriScheme, boundary: boundary);
2445
case CodegenLanguage.dartHttp:
25-
return DartHttpCodeGen().getCode(requestModel, defaultUriScheme);
46+
return DartHttpCodeGen().getCode(rM);
2647
case CodegenLanguage.dartDio:
27-
return DartDioCodeGen().getCode(requestModel, defaultUriScheme);
48+
return DartDioCodeGen().getCode(rM);
49+
case CodegenLanguage.goHttp:
50+
return GoHttpCodeGen().getCode(rM);
2851
case CodegenLanguage.jsAxios:
29-
return AxiosCodeGen().getCode(requestModel, defaultUriScheme);
52+
return AxiosCodeGen().getCode(rM);
3053
case CodegenLanguage.jsFetch:
31-
return FetchCodeGen().getCode(requestModel, defaultUriScheme);
54+
return FetchCodeGen().getCode(rM);
3255
case CodegenLanguage.nodejsAxios:
33-
return AxiosCodeGen(isNodeJs: true)
34-
.getCode(requestModel, defaultUriScheme);
56+
return AxiosCodeGen(isNodeJs: true).getCode(rM);
3557
case CodegenLanguage.nodejsFetch:
36-
return FetchCodeGen(isNodeJs: true)
37-
.getCode(requestModel, defaultUriScheme);
58+
return FetchCodeGen(isNodeJs: true).getCode(rM);
59+
case CodegenLanguage.javaAsyncHttpClient:
60+
return JavaAsyncHttpClientGen().getCode(rM);
61+
case CodegenLanguage.javaHttpClient:
62+
return JavaHttpClientCodeGen().getCode(rM);
63+
case CodegenLanguage.javaOkHttp:
64+
return JavaOkHttpCodeGen().getCode(rM);
65+
case CodegenLanguage.juliaHttp:
66+
return JuliaHttpClientCodeGen().getCode(rM);
3867
case CodegenLanguage.kotlinOkHttp:
39-
return KotlinOkHttpCodeGen().getCode(requestModel, defaultUriScheme);
68+
return KotlinOkHttpCodeGen().getCode(rM);
4069
case CodegenLanguage.pythonHttpClient:
4170
return PythonHttpClientCodeGen()
42-
.getCode(requestModel, defaultUriScheme);
71+
.getCode(rM, boundary: boundary ?? getNewUuid());
4372
case CodegenLanguage.pythonRequests:
44-
return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme);
73+
return PythonRequestsCodeGen().getCode(rM, boundary: boundary);
74+
case CodegenLanguage.rustActix:
75+
return RustActixCodeGen().getCode(rM, boundary: boundary);
76+
case CodegenLanguage.rustReqwest:
77+
return RustReqwestCodeGen().getCode(rM);
78+
case CodegenLanguage.rustUreq:
79+
return RustUreqCodeGen().getCode(rM, boundary: boundary);
80+
case CodegenLanguage.phpGuzzle:
81+
return PhpGuzzleCodeGen().getCode(rM);
4582
}
4683
}
4784
}

lib/codegen/codegen_utils.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
String jsonToPyDict(String jsonString) {
2+
Map<String, String> replaceWithMap = {
3+
"null": "None",
4+
"true": "True",
5+
"false": "False"
6+
};
7+
String pyDict = jsonString;
8+
for (var k in replaceWithMap.keys) {
9+
RegExp regExp = RegExp(k + r'(?=([^"]*"[^"]*")*[^"]*$)');
10+
pyDict = pyDict.replaceAllMapped(regExp, (match) {
11+
return replaceWithMap[match.group(0)] ?? match.group(0)!;
12+
});
13+
}
14+
return pyDict;
15+
}

lib/codegen/dart/dio.dart

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,10 @@ import 'shared.dart';
88
class DartDioCodeGen {
99
String? getCode(
1010
RequestModel requestModel,
11-
String defaultUriScheme,
1211
) {
1312
try {
14-
String url = requestModel.url;
15-
if (!url.contains("://") && url.isNotEmpty) {
16-
url = "$defaultUriScheme://$url";
17-
}
1813
final next = generatedDartCode(
19-
url: url,
14+
url: requestModel.url,
2015
method: requestModel.method,
2116
queryParams: requestModel.enabledParamsMap,
2217
headers: requestModel.enabledHeadersMap,
@@ -60,12 +55,17 @@ class DartDioCodeGen {
6055
final List<Map<String,String>> formDataList = ${json.encode(formData)};
6156
for (var formField in formDataList) {
6257
if (formField['type'] == 'file') {
63-
formData.files.add(MapEntry(
64-
formField['name'],
65-
await MultipartFile.fromFile(formField['value'], filename: formField['value']),
58+
if (formField['value'] != null) {
59+
data.files.add(MapEntry(
60+
formField['name']!,
61+
await dio.MultipartFile.fromFile(formField['value']!,
62+
filename: formField['value']!),
6663
));
64+
}
6765
} else {
68-
formData.fields.add(MapEntry(formField['name'], formField['value']));
66+
if (formField['value'] != null) {
67+
data.fields.add(MapEntry(formField['name']!, formField['value']!));
68+
}
6969
}
7070
}
7171
''');
@@ -84,16 +84,16 @@ class DartDioCodeGen {
8484
dataExp = declareFinal('data').assign(strContent);
8585
// when add new type of [ContentType], need update [dataExp].
8686
case ContentType.formdata:
87-
dataExp = declareFinal('data').assign(refer('FormData()'));
87+
dataExp = declareFinal('data').assign(refer('dio.FormData()'));
8888
}
8989
}
9090
final responseExp = declareFinal('response').assign(InvokeExpression.newOf(
91-
refer('dio.Dio'),
91+
refer('dio.Dio()'),
9292
[literalString(url)],
9393
{
9494
if (queryParamExp != null) 'queryParameters': refer('queryParams'),
9595
if (headerExp != null)
96-
'options': refer('Options').newInstance(
96+
'options': refer('dio.Options').newInstance(
9797
[],
9898
{'headers': refer('headers')},
9999
),
@@ -117,7 +117,7 @@ class DartDioCodeGen {
117117
refer('print').call([refer('response').property('data')]),
118118
],
119119
onError: {
120-
'DioException': [
120+
'dio.DioException': [
121121
refer('print').call([
122122
refer('e').property('response').nullSafeProperty('statusCode'),
123123
]),

lib/codegen/dart/http.dart

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,10 @@ import 'shared.dart';
99
class DartHttpCodeGen {
1010
String? getCode(
1111
RequestModel requestModel,
12-
String defaultUriScheme,
1312
) {
1413
try {
15-
String url = requestModel.url;
16-
if (!url.contains("://") && url.isNotEmpty) {
17-
url = "$defaultUriScheme://$url";
18-
}
1914
final next = generatedDartCode(
20-
url: url,
15+
url: requestModel.url,
2116
method: requestModel.method,
2217
queryParams: requestModel.enabledParamsMap,
2318
headers: {...requestModel.enabledHeadersMap},
@@ -53,7 +48,9 @@ class DartHttpCodeGen {
5348
declareVar('uri').assign(refer('Uri.parse').call([literalString(url)]));
5449

5550
Expression? dataExp;
56-
if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) {
51+
if (kMethodsWithBody.contains(method) &&
52+
(body?.isNotEmpty ?? false) &&
53+
contentType != ContentType.formdata) {
5754
final strContent = CodeExpression(Code('r\'\'\'$body\'\'\''));
5855
dataExp = declareVar('body', type: refer('String')).assign(strContent);
5956
if (!hasContentTypeHeader) {
@@ -125,17 +122,29 @@ class DartHttpCodeGen {
125122

126123
final addHeaders = refer('request.headers.addAll').call([refer('headers')]);
127124
const multiPartList = Code('''
128-
for (Map<String, String> formData in formDataList){
129-
if (formData['type'] == 'text') {
130-
request.fields.addAll({formData['name']: formData['value']});
131-
} else {
132-
request.files.add(
133-
await http.MultipartFile.fromPath(
134-
formData['name'],
135-
formData['value'],
136-
),
137-
);
138-
}
125+
for (var formData in formDataList) {
126+
if (formData != null) {
127+
final name = formData['name'];
128+
final value = formData['value'];
129+
final type = formData['type'];
130+
131+
if (name != null && value != null && type != null) {
132+
if (type == 'text') {
133+
request.fields.addAll({name: value});
134+
} else {
135+
request.files.add(
136+
await http.MultipartFile.fromPath(
137+
name,
138+
value,
139+
),
140+
);
141+
}
142+
} else {
143+
print('Error: formData has null name, value, or type.');
144+
}
145+
} else {
146+
print('Error: formData is null.');
147+
}
139148
}
140149
''');
141150
var multiPartRequestSend =

0 commit comments

Comments
 (0)