diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..ef40de30 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -1,3 +1,4 @@ +import 'package:apidash/codegen/go/http.dart'; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; import 'dart/http.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.goHttp: + return GoHttpCodeGen().getCode(requestModel, defaultUriScheme); } } } diff --git a/lib/codegen/go/http.dart b/lib/codegen/go/http.dart new file mode 100644 index 00000000..d9cf080e --- /dev/null +++ b/lib/codegen/go/http.dart @@ -0,0 +1,197 @@ +import 'dart:convert'; + +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' show getValidRequestUri; +import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; + +class GoHttpCodeGen { + final String kTemplateStart = """package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + {% if isBody %}"bytes" + {% if isFormDataRequest %}"mime/multipart" + "os"{% endif %}{% endif %} +) + +func main() { + client := &http.Client{} + +"""; + + String kTemplateUrl = """ + url, err := url.Parse("{{url}}") + if err != nil { + fmt.Println(err) + return + } + +"""; + + String kTemplateRawBody = """ + {% if body %}body := strings.NewReader(`{{body}}`){% endif %} + +"""; + + String kTemplateJsonBody = """ + {% if body %}body := bytes.NewBuffer([]byte(`{{body}}`)){% endif %} + +"""; + + String kTemplateFormData = """ + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + var ( + file *os.File + part io.Writer + ) + {% for field in fields %} + {% if field.type == "file" %}file, err = os.Open("{{field.value}}") + if err != nil { + fmt.Println(err) + return + } + defer file.Close() + + part, err = writer.CreateFormFile("{{field.name}}", "{{field.value}}") + if err != nil { + fmt.Println(err) + return + } + 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 kTemplateQueryParam = """ + query := url.Query() + {% for key, value in params %} + query.Set("{{key}}", "{{value}}") + {% endfor %} + url.RawQuery = query.Encode() + +"""; + + String kTemplateRequest = """ + req, err := http.NewRequest("{{method}}", url.String(), {% if hasBody %}body{% else %}nil{% endif %}) + if err != nil { + fmt.Println(err) + return + } + +"""; + + final String kTemplateEnd = """ + resp, err := client.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + + res, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(res)) +} +"""; + + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + var hasBody = false; + var requestBody = requestModel.requestBody; + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var templateStart = jj.Template(kTemplateStart); + result += templateStart.render({ + "isBody": kMethodsWithBody.contains(requestModel.method) && + requestBody != null, + "isFormDataRequest": requestModel.isFormDataRequest + }); + + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + + Uri? uri = rec.$1; + + if (uri != null) { + var method = requestModel.method.name.toUpperCase(); + if (kMethodsWithBody.contains(requestModel.method) && + requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + hasBody = true; + } + if (requestModel.requestBodyContentType == ContentType.text) { + var templateRawBody = jj.Template(kTemplateRawBody); + result += templateRawBody.render({"body": requestBody}); + } else if (requestModel.requestBodyContentType == ContentType.json) { + var templateJsonBody = jj.Template(kTemplateJsonBody); + result += templateJsonBody.render({"body": requestBody}); + } else if (requestModel.isFormDataRequest) { + hasBody = true; + var templateFormData = jj.Template(kTemplateFormData); + result += templateFormData.render({ + "fields": requestModel.formDataMapList, + }); + } + } + + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var templateQueryParam = jj.Template(kTemplateQueryParam); + result += templateQueryParam.render({"params": params}); + } + } + + var templateRequest = jj.Template(kTemplateRequest); + result += + templateRequest.render({"method": method, "hasBody": hasBody}); + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + var templateHeader = jj.Template(kTemplateHeader); + result += templateHeader.render({"headers": headers}); + } + } + + result += kTemplateEnd; + } + + return result; + } catch (e) { + return null; + } + } +} diff --git a/lib/consts.dart b/lib/consts.dart index d157b7fa..c5e6b447 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -271,7 +271,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + goHttp("Golang (http)", "go", "go"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label;