Skip to content

Commit

Permalink
Merge pull request #374 from AcousticDeveloper/resolve-issue-147
Browse files Browse the repository at this point in the history
Added Code Generator For Ruby (Faraday)
  • Loading branch information
animator authored Apr 6, 2024
2 parents a4572b3 + 2c6b23c commit 90eed29
Show file tree
Hide file tree
Showing 4 changed files with 900 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/codegen/codegen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'php/guzzle.dart';
import 'php/curl.dart';
import 'python/http_client.dart';
import 'python/requests.dart';
import 'ruby/faraday.dart';
import 'rust/actix.dart';
import 'rust/curl_rust.dart';
import 'rust/reqwest.dart';
Expand Down Expand Up @@ -74,6 +75,8 @@ class Codegen {
.getCode(rM, boundary: boundary ?? getNewUuid());
case CodegenLanguage.pythonRequests:
return PythonRequestsCodeGen().getCode(rM, boundary: boundary);
case CodegenLanguage.rubyFaraday:
return RubyFaradayCodeGen().getCode(rM);
case CodegenLanguage.rustActix:
return RustActixCodeGen().getCode(rM, boundary: boundary);
case CodegenLanguage.rustCurl:
Expand Down
178 changes: 178 additions & 0 deletions lib/codegen/ruby/faraday.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import 'package:apidash/consts.dart';
import 'package:jinja/jinja.dart' as jj;
import 'package:apidash/utils/utils.dart' show getValidRequestUri;
import 'package:apidash/utils/http_utils.dart' show stripUriParams;

import 'package:apidash/models/models.dart' show RequestModel;

// Note that delete is a special case in Faraday as API Dash supports request
// body inside delete reqest, but Faraday does not. Hence we need to manually
// setup request body for delete request and add that to request.
//
// Refer https://lostisland.github.io/faraday/#/getting-started/quick-start?id=get-head-delete-trace
class RubyFaradayCodeGen {
final String kStringFaradayRequireStatement = """
require 'uri'
require 'faraday'
""";

final String kStringFaradayMultipartRequireStatement = '''
require 'faraday/multipart'
''';

final String kTemplateRequestUrl = """
REQUEST_URL = URI("{{ url }}")
""";

final String kTemplateBody = """
PAYLOAD = <<HEREDOC
{{ body }}
HEREDOC
""";

final String kTemplateFormParamsWithFile = """
PAYLOAD = {
{% for param in params %}{% if param.type == "text" %} "{{ param.name }}" => Faraday::Multipart::ParamPart.new("{{ param.value }}", "text/plain"),
{% elif param.type == "file" %} "{{ param.name }}" => Faraday::Multipart::FilePart.new("{{ param.value }}", "application/octet-stream"),{% endif %}{% endfor %}
}
""";

final String kTemplateFormParamsWithoutFile = """
PAYLOAD = URI.encode_www_form({\n{% for param in params %} "{{ param.name }}" => "{{ param.value }}",\n{% endfor %}})\n\n
""";

final String kTemplateConnection = """
conn = Faraday.new do |faraday|
faraday.adapter Faraday.default_adapter{% if hasFile %}\n faraday.request :multipart{% endif %}
end
""";

final String kTemplateRequestStart = """
response = conn.{{ method|lower }}(REQUEST_URL{% if doesMethodAcceptBody and containsBody %}, PAYLOAD{% endif %}) do |req|
""";

final String kTemplateRequestParams = """
req.params = {
{% for key, val in params %} "{{ key }}" => "{{ val }}",\n{% endfor %} }
""";

final String kTemplateRequestHeaders = """
req.headers = {
{% for key, val in headers %} "{{ key }}" => "{{ val }}",\n{% endfor %} }
""";

final String kStringDeleteRequestBody = """
req.body = PAYLOAD
""";

final String kStringRequestEnd = """
end
""";

final String kStringResponse = """
puts "Status Code: #{response.status}"
puts "Response Body: #{response.body}"
""";

String? getCode(
RequestModel requestModel,
) {
try {
String result = "";

var rec = getValidRequestUri(
requestModel.url,
requestModel.enabledRequestParams,
);

Uri? uri = rec.$1;

if (uri == null) {
return "";
}

var url = stripUriParams(uri);

result += kStringFaradayRequireStatement;
if (requestModel.hasFormDataContentType && requestModel.hasFileInFormData) {
result += kStringFaradayMultipartRequireStatement;
}

var templateRequestUrl = jj.Template(kTemplateRequestUrl);
result += templateRequestUrl.render({"url": url});

if (requestModel.hasFormData) {
jj.Template payload;
if (requestModel.hasFileInFormData) {
payload = jj.Template(kTemplateFormParamsWithFile);
} else {
payload = jj.Template(kTemplateFormParamsWithoutFile);
}
result += payload.render({"params": requestModel.formDataMapList});
} else if (requestModel.hasJsonData || requestModel.hasTextData) {
var templateBody = jj.Template(kTemplateBody);
result += templateBody.render({
"body": requestModel.requestBody,
});
}

// crreating faraday connection for request
var templateConnection = jj.Template(kTemplateConnection);
result += templateConnection.render({
"hasFile": requestModel.hasFormDataContentType && requestModel.hasFileInFormData //
});

// start of the request sending
var templateRequestStart = jj.Template(kTemplateRequestStart);
result += templateRequestStart.render({
"method": requestModel.method.name,
"doesMethodAcceptBody":
kMethodsWithBody.contains(requestModel.method) && requestModel.method != HTTPVerb.delete, //
"containsBody": requestModel.hasBody,
});

var headers = requestModel.enabledHeadersMap;
if (requestModel.hasBody && !requestModel.hasContentTypeHeader) {
if (requestModel.hasJsonData || requestModel.hasTextData) {
headers["Content-Type"] = requestModel.requestBodyContentType.header;
}
}

if (headers.isNotEmpty) {
var templateRequestHeaders = jj.Template(kTemplateRequestHeaders);
result += templateRequestHeaders.render({"headers": headers});
}

if (uri.hasQuery) {
var params = uri.queryParameters;
if (params.isNotEmpty) {
var templateRequestParams = jj.Template(kTemplateRequestParams);
result += templateRequestParams.render({"params": params});
}
}

if (requestModel.hasBody && requestModel.method == HTTPVerb.delete) {
result += kStringDeleteRequestBody;
}

result += kStringRequestEnd;
result += kStringResponse;
return result;
} catch (e) {
return null;
}
}
}
1 change: 1 addition & 0 deletions lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ enum CodegenLanguage {
kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"),
pythonRequests("Python (requests)", "python", "py"),
pythonHttpClient("Python (http.client)", "python", "py"),
rubyFaraday("Ruby (Faraday)", "ruby", "rb"),
rustActix("Rust (Actix Client)", "rust", "rs"),
rustReqwest("Rust (reqwest)", "rust", "rs"),
rustCurl("Rust (curl-rust)", "rust", "rs"),
Expand Down
Loading

0 comments on commit 90eed29

Please sign in to comment.