Merge branch 'main' of https://github.com/foss42/apidash into add-rust-curl-codegen

This commit is contained in:
Apoorv Dwivedi
2024-03-16 23:25:50 +05:30
56 changed files with 12065 additions and 2358 deletions

View File

@ -1,50 +1,87 @@
import 'package:apidash/codegen/rust/curl-rust.dart';
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 'go/http.dart';
import 'kotlin/okhttp.dart';
import 'php/guzzle.dart';
import 'python/http_client.dart';
import 'python/requests.dart';
import 'rust/actix.dart';
import 'rust/reqwest.dart';
import 'rust/ureq.dart';
import 'js/axios.dart';
import 'js/fetch.dart';
import 'others/har.dart';
import 'others/curl.dart';
import 'julia/http.dart';
import 'java/okhttp.dart';
import 'java/async_http_client.dart';
import 'java/httpclient.dart';
class Codegen {
String? getCode(
CodegenLanguage codegenLanguage,
RequestModel requestModel,
String defaultUriScheme,
) {
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.goHttp:
return GoHttpCodeGen().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.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(requestModel, defaultUriScheme);
return KotlinOkHttpCodeGen().getCode(rM);
case CodegenLanguage.pythonHttpClient:
return PythonHttpClientCodeGen()
.getCode(requestModel, defaultUriScheme);
.getCode(rM, boundary: boundary ?? getNewUuid());
case CodegenLanguage.pythonRequests:
return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme);
return PythonRequestsCodeGen().getCode(rM, boundary: boundary);
case CodegenLanguage.rustActix:
return RustActixCodeGen().getCode(rM, boundary: boundary);
case CodegenLanguage.rustReqwest:
return RustReqwestCodeGen().getCode(rM);
case CodegenLanguage.rustCurl:
return RustCurlCodeGen().getCode(requestModel, defaultUriScheme);
return RustCurlCodeGen().getCode(rM);
case CodegenLanguage.rustUreq:
return RustUreqCodeGen().getCode(rM, boundary: boundary);
case CodegenLanguage.phpGuzzle:
return PhpGuzzleCodeGen().getCode(rM);
}
}
}

View File

@ -0,0 +1,15 @@
String jsonToPyDict(String jsonString) {
Map<String, String> 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;
}

View File

@ -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,
@ -60,12 +55,17 @@ class DartDioCodeGen {
final List<Map<String,String>> formDataList = ${json.encode(formData)};
for (var formField in formDataList) {
if (formField['type'] == 'file') {
formData.files.add(MapEntry(
formField['name'],
await 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 {
formData.fields.add(MapEntry(formField['name'], formField['value']));
if (formField['value'] != null) {
data.fields.add(MapEntry(formField['name']!, formField['value']!));
}
}
}
''');
@ -84,16 +84,16 @@ 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'),
if (headerExp != null)
'options': refer('Options').newInstance(
'options': refer('dio.Options').newInstance(
[],
{'headers': refer('headers')},
),
@ -117,7 +117,7 @@ class DartDioCodeGen {
refer('print').call([refer('response').property('data')]),
],
onError: {
'DioException': [
'dio.DioException': [
refer('print').call([
refer('e').property('response').nullSafeProperty('statusCode'),
]),

View File

@ -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},
@ -53,7 +48,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) {
@ -125,17 +122,29 @@ class DartHttpCodeGen {
final addHeaders = refer('request.headers.addAll').call([refer('headers')]);
const multiPartList = Code('''
for (Map<String, String> 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 =

172
lib/codegen/go/http.dart Normal file
View File

@ -0,0 +1,172 @@
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;
class GoHttpCodeGen {
final String kTemplateStart = """package main
import (
"fmt"
"io"
"net/http"
"net/url"{% if hasBody %}
"bytes"{% if hasFormData %}
"mime/multipart"{% if hasFileInFormData %}
"os"{% endif %}{% endif %}{% endif %}
)
func main() {
client := &http.Client{}
""";
String kTemplateUrl = """
url, _ := url.Parse("{{url}}")
""";
String kTemplateBody = """
{% if body %}payload := bytes.NewBuffer([]byte(`{{body}}`)){% endif %}
""";
String kTemplateFormData = """
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, _ = os.Open("{{field.value}}")
defer file.Close()
part, _ = writer.CreateFormFile("{{field.name}}", "{{field.value}}")
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 kStringFormDataHeader = """
req.Header.Set("Content-Type", writer.FormDataContentType())
""";
String kTemplateQueryParam = """
query := url.Query()
{% for key, value in params %}
query.Set("{{key}}", "{{value}}"){% endfor %}
url.RawQuery = query.Encode()
""";
String kTemplateRequest = """
req, _ := http.NewRequest("{{method}}", url.String(), {% if hasBody %}payload{% else %}nil{% endif %})
""";
final String kTemplateEnd = """
response, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer response.Body.Close()
fmt.Println("Status Code:", response.StatusCode)
body, _ := io.ReadAll(response.Body)
fmt.Println("Response body:", string(body))
}""";
String? getCode(
RequestModel requestModel,
) {
try {
String result = "";
var hasBody = false;
var requestBody = requestModel.requestBody;
String url = requestModel.url;
var templateStart = jj.Template(kTemplateStart);
result += templateStart.render({
"hasBody": requestModel.hasBody,
"hasFormData": requestModel.hasFormData,
"hasFileInFormData": requestModel.hasFileInFormData,
});
var templateUrl = jj.Template(kTemplateUrl);
result += templateUrl.render({"url": url});
var rec = getValidRequestUri(
url,
requestModel.enabledRequestParams,
);
Uri? uri = rec.$1;
if (uri != null) {
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) {
var params = uri.queryParameters;
if (params.isNotEmpty) {
var templateQueryParam = jj.Template(kTemplateQueryParam);
result += templateQueryParam.render({"params": params});
}
}
var method = requestModel.method.name.toUpperCase();
var templateRequest = jj.Template(kTemplateRequest);
result += templateRequest.render({
"method": method,
"hasBody": hasBody,
});
var headersList = requestModel.enabledRequestHeaders;
if (headersList != null || requestModel.hasBody) {
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,
});
}
}
if (requestModel.hasFormData) {
result += kStringFormDataHeader;
}
result += kTemplateEnd;
}
return result;
} catch (e) {
return null;
}
}
}

View File

@ -0,0 +1,189 @@
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 {
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<Response> 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
""";
String? getCode(
RequestModel requestModel,
) {
try {
String result = "";
bool hasBody = false;
var rec = getValidRequestUri(
requestModel.url,
requestModel.enabledRequestParams,
);
Uri? uri = rec.$1;
if (uri == null) {
return "";
}
var 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.hasFormData &&
kMethodsWithBody.contains(method) &&
requestBody != null) {
var contentLength = utf8.encode(requestBody).length;
if (contentLength > 0) {
var templateBodyContent = jj.Template(kTemplateRequestBodyContent);
hasBody = true;
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.hasFormData &&
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;
}
}
}

View File

@ -0,0 +1,183 @@
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<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}
\n
""";
String? getCode(
RequestModel requestModel,
) {
try {
String result = "";
bool hasQuery = false;
bool hasBody = false;
bool hasJsonBody = 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": 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.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']}&""",';
}
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<String, String> 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;
}
}

View File

@ -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<String, String> params) {
final paramStrings = params.entries.map((entry) => '.addQueryParameter("${entry.key}", "${entry.value}")').toList();
return paramStrings.join('\n ');
}
String getHeaders(Map<String, String> headers) {
String result = "";
for (final k in headers.keys) {
result = """$result .addHeader("$k", "${headers[k]}")\n""";
}
return result;
}
}

View File

@ -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 hasFileInFormData -%}
import fs from 'fs'
{% endif %}
{% endif %}{% if isFormDataRequest and isNodeJs %}const fs = require('fs');{% endif %}
""";
String kTemplateStart = """let config = {
String kTemplateStart = """const config = {
url: '{{url}}',
method: '{{method}}'
""";
@ -37,72 +38,36 @@ 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,
String defaultUriScheme,
) {
try {
jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode);
String importsData = kNodejsImportTemplate.render({
"isFormDataRequest": requestModel.isFormDataRequest,
"isNodeJs": isNodeJs,
"hasFileInFormData": requestModel.hasFileInFormData,
});
String result = importsData;
if (requestModel.isFormDataRequest &&
requestModel.formDataMapList.isNotEmpty) {
var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate);
var renderedMultiPartBody = templateMultiPartBody.render({
"isNodeJs": isNodeJs,
});
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);
String result = isNodeJs
? importsData
: requestModel.hasFileInFormData
? "// refer https://github.com/foss42/apidash/issues/293#issuecomment-1997568083 for details regarding integration\n\n"
: "";
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(),
});
@ -118,31 +83,35 @@ 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) {
m['Content-Type'] = 'multipart/form-data';
if (requestModel.hasFormData) {
m[kHeaderContentType] = 'multipart/form-data';
}
result += templateHeader
.render({"headers": padMultilineString(kEncoder.convert(m), 2)});
}
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) {
if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) {
// Manually Create a JS Object
Map<String, String> 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"])});
}
@ -152,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;
}
}

View File

@ -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 isFormDataRequest %}const fs = require('fs');{% endif %}
import fetch from 'node-fetch'
{% if hasFormData -%}
import { {% if hasFileInFormData %}fileFromSync, {% endif %}FormData } from 'node-fetch'
{% endif %}
""";
String kTemplateStart = """let url = '{{url}}';
String kTemplateStart = """const url = '{{url}}';
let options = {
const options = {
method: '{{method}}'
""";
@ -27,75 +28,63 @@ 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 defaultUriScheme,
) {
String? getCode(RequestModel requestModel) {
try {
jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode);
String importsData = kNodejsImportTemplate.render({
"isFormDataRequest": requestModel.isFormDataRequest,
"hasFormData": requestModel.hasFormData,
"hasFileInFormData": requestModel.hasFileInFormData,
});
String result = isNodeJs ? importsData : "";
if (requestModel.isFormDataRequest) {
String result = isNodeJs
? importsData
: requestModel.hasFileInFormData
? "// 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";
}
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({
@ -108,15 +97,18 @@ fetch(url, options)
if (headers.isNotEmpty) {
var templateHeader = jj.Template(kTemplateHeader);
var m = {};
if (requestModel.isFormDataRequest) {
m["Content-Type"] = "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) {
@ -124,7 +116,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',

198
lib/codegen/julia/http.dart Normal file
View File

@ -0,0 +1,198 @@
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
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) {
try {
String result = "";
bool hasQuery = false;
bool hasHeaders = false;
bool hasBody = false;
bool hasJsonBody = false;
String uuid = getNewUuid();
var rec = getValidRequestUri(
requestModel.url,
requestModel.enabledRequestParams,
);
Uri? uri = rec.$1;
if (uri != null) {
var templateStartUrl = jj.Template(kTemplateStart);
result += templateStartUrl.render({
"url": stripUriParams(uri),
});
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});
}
}
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.hasFormData) {
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.hasFormData) {
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": requestModel.method.name.toLowerCase(),
});
if (hasQuery) {
result += kStringRequestParams;
}
if (hasBody || requestModel.hasFormData) {
result += kStringRequestBody;
}
if (hasJsonBody || requestModel.hasFormData) {
result += kStringRequestJson;
}
if (hasHeaders || requestModel.hasFormData) {
result += kStringRequestHeaders;
}
result += kStringRequestEnd;
}
return result;
} catch (e) {
return null;
}
}
}

View File

@ -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}}{{importForFile}}
fun main() {
val client = OkHttpClient()
@ -21,6 +21,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrl""";
final String kStringImportForBody = """
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.MediaType.Companion.toMediaType""";
final String kStringImportForFormData = """
import okhttp3.MultipartBody""";
final String kStringImportForFile = """
import java.io.File
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.MediaType.Companion.toMediaType""";
final String kTemplateUrl = '''
@ -64,27 +74,23 @@ import okhttp3.MediaType.Companion.toMediaType""";
// 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()
''';
String? getCode(
RequestModel requestModel,
String defaultUriScheme,
) {
try {
String result = "";
bool hasQuery = false;
bool hasBody = false;
String url = requestModel.url;
if (!url.contains("://") && url.isNotEmpty) {
url = "$defaultUriScheme://$url";
}
bool hasFormData = false;
bool hasFile = false;
var rec = getValidRequestUri(
url,
requestModel.url,
requestModel.enabledRequestParams,
);
Uri? uri = rec.$1;
@ -108,11 +114,38 @@ import okhttp3.MediaType.Companion.toMediaType""";
var method = requestModel.method;
var requestBody = requestModel.requestBody;
if (requestModel.isFormDataRequest) {
if (requestModel.hasFormData) {
hasFormData = true;
var formDataTemplate = jj.Template(kFormDataBody);
List<Map<String,String>> 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;
@ -128,7 +161,9 @@ 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 : "",
"importForFile": hasFile ? kStringImportForFile : "",
});
result = stringStart + result;
@ -145,7 +180,7 @@ import okhttp3.MediaType.Companion.toMediaType""";
var templateRequestEnd = jj.Template(kTemplateRequestEnd);
result += templateRequestEnd.render({
"method": method.name.toLowerCase(),
"hasBody": (hasBody || requestModel.isFormDataRequest) ? "body" : "",
"hasBody": (hasBody || requestModel.hasFormData) ? "body" : "",
});
}
return result;

View File

@ -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 = """ \\
@ -20,25 +21,21 @@ 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({
"method": switch (harJson["method"]) {
"GET" => "",
"HEAD" => " --head",
_ => " --request ${harJson["method"]} \\\n"
_ => " --request ${harJson["method"]} \\\n "
},
"url": harJson["url"],
});
@ -46,33 +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"]});
}
}
if (harJson['formData'] != null) {
var formDataList = harJson['formData'] as List<Map<String, dynamic>>;
for (var formData in formDataList) {
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['type'] != null &&
formData['name'] != null &&
formData['value'] != null &&
formData['name']!.isNotEmpty &&
formData['value']!.isNotEmpty) {
if (formData.name.isNotEmpty && formData.value.isNotEmpty) {
result += templateFormData.render({
"name": formData["name"],
"name": formData.name,
"value":
"${formData['type'] == 'file' ? '@' : ''}${formData["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;

View File

@ -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) {

161
lib/codegen/php/guzzle.dart Normal file
View File

@ -0,0 +1,161 @@
import 'package:jinja/jinja.dart' as jj;
import 'package:apidash/utils/utils.dart'
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 hasFormData %}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) {
try {
jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode);
String importsData = kNodejsImportTemplate.render({
"hasFormData": requestModel.hasFormData,
});
String result = importsData;
if (requestModel.hasFormData && 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;
}
var harJson =
requestModelToHARJsonRequest(requestModel, 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.hasFormData) {
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.hasFormData) {
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.hasFormData && requestModel.formDataMapList.isNotEmpty) {
result += templateBody.render({
"body": "new MultipartStream(\$multipart)",
});
}
if (harJson["postData"]?["text"] != null) {
result += templateBody
.render({"body": kEncoder.convert(harJson["postData"]["text"])});
}
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 or formdata is not present
}
var templateRequest = jj.Template(kStringRequest);
result += templateRequest.render({
"url": stripUrlParams(requestModel.url),
"method": harJson["method"].toLowerCase(),
"queryParams":
harJson["queryString"].isNotEmpty ? ". \$queryParamsStr," : "",
"headers": harJson["headers"].isNotEmpty ? " \$headers," : "",
"body": getRequestBody(harJson),
});
return result;
} catch (e) {
return null;
}
}
}

View File

@ -1,14 +1,13 @@
import 'dart:io';
import 'dart:convert';
import 'package:jinja/jinja.dart' as jj;
import 'package:apidash/utils/utils.dart'
show getNewUuid, getValidRequestUri, padMultilineString;
import 'package:apidash/utils/utils.dart' show getValidRequestUri;
import 'package:apidash/models/models.dart' show RequestModel;
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 %}
""";
@ -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}}")""";
@ -87,30 +83,23 @@ dataList = build_data_list({{fields_list}})
body = b'\r\n'.join(dataList)
''';
String? getCode(
RequestModel requestModel,
String defaultUriScheme,
) {
String uuid = getNewUuid();
RequestModel requestModel, {
String? boundary,
}) {
try {
String result = "";
bool hasHeaders = false;
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(
{
"isFormDataRequest": requestModel.isFormDataRequest,
"hasFormData": requestModel.hasFormData,
},
);
var rec = getValidRequestUri(
url,
requestModel.url,
requestModel.enabledRequestParams,
);
@ -123,51 +112,48 @@ 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) {
var contentLength = utf8.encode(requestBody).length;
if (contentLength > 0) {
hasBody = true;
if (requestModel.hasBody) {
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.isFormDataRequest) {
var formHeaderTemplate =
jj.Template(kTemplateFormHeaderContentType);
headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({
"boundary": uuid,
});
}
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});
}
}
if (requestModel.isFormDataRequest) {
if (requestModel.hasFormData) {
var formDataBodyData = jj.Template(kStringFormDataBody);
result += formDataBodyData.render(
{
"fields_list": json.encode(requestModel.formDataMapList),
"boundary": uuid,
"boundary": boundary,
},
);
}
@ -179,16 +165,16 @@ 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" : "",
});
if (hasBody || requestModel.isFormDataRequest) {
if (hasBody || requestModel.hasFormData) {
result += kStringRequestBody;
}
if (hasHeaders || requestModel.isFormDataRequest) {
if (hasHeaders || requestModel.hasFormData) {
result += kStringRequestHeaders;
}

View File

@ -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 getNewUuid, 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,25 +72,26 @@ 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,
) {
RequestModel requestModel, {
String? boundary,
}) {
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.url,
requestModel.enabledRequestParams,
);
Uri? uri = rec.$1;
@ -117,7 +99,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 +108,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 {
hasBody = true;
var templateBody = jj.Template(kTemplateBody);
result += templateBody.render({"body": requestBody});
if (requestModel.hasFormData) {
hasBody = true;
List<String> 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": uuid,
});
}
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": uuid,
},
);
}
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;
}

217
lib/codegen/rust/actix.dart Normal file
View File

@ -0,0 +1,217 @@
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 RustActixCodeGen {
final String kTemplateStart = """
{%- if isFormDataRequest -%}
use std::io::Read;
{% endif -%}
#[actix_rt::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = "{{url}}";
let client = awc::Client::default();
""";
String kTemplateParams =
"""\n .query(&{{ params }})\n .unwrap()""";
String kTemplateBody = """
let payload = r#"{{body}}"#;
""";
String kTemplateJson = """
let payload = serde_json::json!({{body}});
""";
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}}''';
String kTemplateRequest = """
let mut response = client\n .{{method}}(url)
""";
final String kStringFormDataBody = r"""
struct FormDataItem {
name: String,
value: String,
field_type: String,
}
let form_data_items: Vec<FormDataItem> = 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<FormDataItem>) -> Vec<u8> {
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_body(payload)""";
String kStringRequestJson = """\n .send_json(&payload)""";
String kStringRequestNormal = """\n .send()""";
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? boundary,
}) {
try {
String uuid = getNewUuid();
String result = "";
bool hasBody = false;
bool hasJsonBody = false;
String url = requestModel.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.hasFormData,
"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.hasFormData) {
hasBody = true;
var templateBody = jj.Template(kTemplateBody);
result += templateBody.render({"body": requestBody});
}
}
}
if (requestModel.hasFormData) {
var formDataBodyData = jj.Template(kStringFormDataBody);
result += formDataBodyData.render(
{
"fields_list": requestModel.formDataMapList,
"boundary": 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 tupleStrings = params.entries
.map((entry) => '("${entry.key}", "${entry.value}")')
.toList();
var paramsString = "[${tupleStrings.join(', ')}]";
var templateParms = jj.Template(kTemplateParams);
result += templateParms.render({"params": paramsString});
}
}
var headersList = requestModel.enabledRequestHeaders;
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 ?? uuid,
});
} else if (hasBody) {
headers[HttpHeaders.contentTypeHeader] =
requestModel.requestBodyContentType.header;
}
if (headers.isNotEmpty) {
var templateHeaders = jj.Template(kTemplateHeaders);
result += templateHeaders.render({"headers": headers});
}
}
if (hasBody || requestModel.hasFormData) {
result += kStringRequestBody;
} else if (hasJsonBody) {
result += kStringRequestJson;
} else {
result += kStringRequestNormal;
}
result += kStringRequestEnd;
}
return result;
} catch (e) {
return null;
}
}
}

View File

@ -0,0 +1,180 @@
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, stripUriParams;
import 'package:apidash/models/models.dart' show RequestModel;
class RustReqwestCodeGen {
final String kTemplateStart =
"""fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::blocking::Client::new();
let url = "{{url}}";
""";
String kTemplateParams = """\n .query(&{{params}})""";
String kTemplateBody = """
let payload = r#"{{body}}"#;
""";
String kTemplateJson = """
let payload = serde_json::json!({{body}});
""";
String kTemplateHeaders =
"""\n {% for key, val in headers -%}.header("{{key}}", "{{val}}"){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}""";
String kTemplateRequest = """
let response = client\n .{{method}}(url)
""";
final String kStringFormDataBody = r'''
struct FormDataItem {
name: String,
value: String,
field_type: String,
}
let form_data_items: Vec<FormDataItem> = 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)?;
}
}
''';
String kStringRequestBody = """\n .body(payload)""";
String kStringRequestJson = """\n .json(&payload)""";
String kStringRequestForm = """\n .multipart(form)""";
final String kStringRequestEnd = """\n .send()?;
println!("Status Code: {}", response.status());
println!("Response Body: {}", response.text()?);
Ok(())
}
""";
String? getCode(
RequestModel requestModel,
) {
try {
String result = "";
bool hasBody = false;
bool hasJsonBody = false;
String url = requestModel.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.hasFormData,
'isJson': requestModel.requestBodyContentType == ContentType.json
});
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.hasFormData) {
hasBody = true;
var templateBody = jj.Template(kTemplateBody);
result += templateBody.render({"body": requestBody});
}
}
}
if (requestModel.hasFormData) {
var formDataBodyData = jj.Template(kStringFormDataBody);
result += formDataBodyData.render(
{
"fields_list": requestModel.formDataMapList,
},
);
}
var templateRequest = jj.Template(kTemplateRequest);
result += templateRequest.render({
"method": method.name.toLowerCase(),
});
if (uri.hasQuery) {
var params = uri.queryParameters;
if (params.isNotEmpty) {
var tupleStrings = params.entries
.map((entry) => '("${entry.key}", "${entry.value}")')
.toList();
var paramsString = "[${tupleStrings.join(', ')}]";
var templateParams = jj.Template(kTemplateParams);
result += templateParams.render({"params": paramsString});
}
}
var headersList = requestModel.enabledRequestHeaders;
if (headersList != null || hasBody) {
var headers = requestModel.enabledHeadersMap;
if (hasBody) {
headers[HttpHeaders.contentTypeHeader] =
requestModel.requestBodyContentType.header;
}
if (headers.isNotEmpty) {
var templateHeaders = jj.Template(kTemplateHeaders);
result += templateHeaders.render({"headers": headers});
}
}
if (hasBody && !requestModel.hasFormData) {
result += kStringRequestBody;
}
if (hasJsonBody) {
result += kStringRequestJson;
}
if (requestModel.hasFormData) {
result += kStringRequestForm;
}
result += kStringRequestEnd;
}
return result;
} catch (e) {
return null;
}
}
}

211
lib/codegen/rust/ureq.dart Normal file
View File

@ -0,0 +1,211 @@
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<FormDataItem> = 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<FormDataItem>) -> Vec<u8> {
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? boundary,
}) {
try {
String result = "";
bool hasBody = false;
bool hasJsonBody = false;
String uuid = getNewUuid();
String url = requestModel.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.hasFormData,
"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.hasFormData) {
hasBody = true;
var templateBody = jj.Template(kTemplateBody);
result += templateBody.render({"body": requestBody});
}
}
}
if (requestModel.hasFormData) {
var formDataBodyData = jj.Template(kStringFormDataBody);
result += formDataBodyData.render(
{
"fields_list": requestModel.formDataMapList,
"boundary": 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.hasFormData) {
var headers = requestModel.enabledHeadersMap;
if (requestModel.hasFormData) {
var formHeaderTemplate =
jj.Template(kTemplateFormHeaderContentType);
headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({
"boundary": 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.hasFormData) {
result += kStringRequestForm;
} else if (hasBody) {
result += kStringRequestBody;
} else if (hasJsonBody) {
result += kStringRequestJson;
} else {
result += kStringRequestNormal;
}
result += kStringRequestEnd;
}
return result;
} catch (e) {
return null;
}
}
}