{"results":{"result":{"added-files":{"code-health":0.0,"old-code-health":0.0,"files":[]},"external-review-url":"https://github.com/jaeyson/open_api_typesense/pull/24","old-code-health":9.288070973167928,"modified-files":{"code-health":9.13223758675516,"old-code-health":9.288070973167928,"files":[{"file":"test/operations/collections_test.exs","loc":162,"old-loc":162,"code-health":8.545379580978913,"old-code-health":8.545379580978913},{"file":"lib/open_api_typesense/client.ex","loc":171,"old-loc":169,"code-health":9.6882083290695,"old-code-health":10.0}]},"removed-files":{"code-health":0.0,"old-code-health":0.0,"files":[]},"external-review-id":"24","analysis-time":"2025-02-11T03:07:56Z","negative-impact-count":1,"suppressions":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"affected-hotspots":2,"commits":["1d247a6f976739d16cee1834641265d88d6c3081","f0a327ba32ca0997b7c6540e4ade5df589b7e3e2","b5e1b398f2a2e5758a770b25e3b3742864962e51"],"is-negative-review":true,"negative-findings":{"number-of-types":1,"number-of-files-touched":1,"findings":[{"method":"default_client","why-it-occurs":"A Complex Method has a high cyclomatic complexity. The recommended threshold for the Elixir language is a cyclomatic complexity lower than 9.","name":"Complex Method","file":"lib/open_api_typesense/client.ex","refactoring-examples":[{"architectural-component-id":null,"author-name":"Jaeyson Anthony Y. ⚗️","training-data":{"loc-added":"2","loc-deleted":"20","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"10.0"},"author-email":"hello@jaeyson.dev","commit-full-message":"","commit-date":"2025-01-30T03:21:03Z","current-rev":"5298c5e","filename":"open_api_typesense/lib/open_api_typesense/client.ex","previous-rev":"03f4055","commit-title":"remove checking of env during test (#22)","language":"Elixir","id":"153b8bac9a23ddb728cd9a6150e9800092092119","model-score":0.62,"author-id":null,"project-id":63240,"delta-file-score":0.31179166,"diff":"diff --git a/lib/open_api_typesense/client.ex b/lib/open_api_typesense/client.ex\nindex d6467b8..b493021 100644\n--- a/lib/open_api_typesense/client.ex\n+++ b/lib/open_api_typesense/client.ex\n@@ -98,20 +98,2 @@ defmodule OpenApiTypesense.Client do\n     # NOTE: look at source code in Github\n-    retry =\n-      if Mix.env() === :test do\n-        # disabled in order to cut time in tests\n-        false\n-      else\n-        # default is :safe_transient\n-        opts[:req][:retry] || :safe_transient\n-      end\n-\n-    max_retries =\n-      if Mix.env() === :test do\n-        # disabled in order to cut time in tests\n-        0\n-      else\n-        # default is 3\n-        opts[:req][:max_retries] || 3\n-      end\n-\n     url =\n@@ -130,4 +112,4 @@ defmodule OpenApiTypesense.Client do\n         url: url,\n-        retry: retry,\n-        max_retries: max_retries,\n+        max_retries: opts[:req][:max_retries] || 3,\n+        retry: opts[:req][:retry] || :safe_transient,\n         compress_body: opts[:req][:compress] || false,\n","improvement-type":"Complex Method"},{"architectural-component-id":null,"author-name":"Kian-Meng Ang","training-data":{"loc-added":"22","loc-deleted":"19","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"10.0"},"author-email":"kianmeng@cpan.org","commit-full-message":"This commit refactors the existing default Req HTTP client to provide\nfull support for all options documented in https://hexdocs.pm/req/Req.html#new/1.\n\nKey changes:\n- the client now accepts all options defined in Req.new/1\n- global configuration can be set in `config.exs`\n- per-function call overrides are possible using the `req` argument\n- the Req client configuration has been deprecated and moved from the\n  Client module to the Connection module","commit-date":"2025-03-02T06:19:51Z","current-rev":"a89717a","filename":"open_api_typesense/lib/open_api_typesense/client.ex","previous-rev":"15d6b32","commit-title":"Refactor default Req client (#25)","language":"Elixir","id":"afbd22c0018f2670780f2f3e49386ce41692ff06","model-score":0.6,"author-id":null,"project-id":63240,"delta-file-score":0.31179166,"diff":"diff --git a/lib/open_api_typesense/client.ex b/lib/open_api_typesense/client.ex\nindex 512fe6d..d9c94f8 100644\n--- a/lib/open_api_typesense/client.ex\n+++ b/lib/open_api_typesense/client.ex\n@@ -25,2 +25,3 @@ defmodule OpenApiTypesense.Client do\n   @spec get_host :: String.t() | nil\n+  @deprecated \"Use OpenApiTypesense.Connection.config(:host) instead\"\n   def get_host, do: Application.get_env(:open_api_typesense, :host)\n@@ -29,2 +30,3 @@ defmodule OpenApiTypesense.Client do\n   @spec get_scheme :: String.t() | nil\n+  @deprecated \"Use OpenApiTypesense.Connection.config(:scheme) instead\"\n   def get_scheme, do: Application.get_env(:open_api_typesense, :scheme)\n@@ -33,2 +35,3 @@ defmodule OpenApiTypesense.Client do\n   @spec get_port :: non_neg_integer() | nil\n+  @deprecated \"Use OpenApiTypesense.Connection.config(:port) instead\"\n   def get_port, do: Application.get_env(:open_api_typesense, :port)\n@@ -37,7 +40,5 @@ defmodule OpenApiTypesense.Client do\n   @spec get_client :: keyword() | nil\n+  @deprecated \"Use OpenApiTypesense.Connection.config(:client) instead\"\n   def get_client, do: Application.get_env(:open_api_typesense, :client)\n \n-  defp test_max_retries, do: Application.get_env(:open_api_typesense, :max_retries)\n-  defp test_retry, do: Application.get_env(:open_api_typesense, :retry)\n-\n   @doc \"\"\"\n@@ -92,3 +93,4 @@ defmodule OpenApiTypesense.Client do\n     else\n-      default_client(conn, opts)\n+      req_client = build_req_client(conn, opts)\n+      req_request(req_client, opts)\n     end\n@@ -96,7 +98,11 @@ defmodule OpenApiTypesense.Client do\n \n-  defp default_client(conn, opts) do\n-    # Req.Request.append_error_steps and its retry option are used here.\n-    # options like retry, max_retries, etc. can be found in:\n-    # https://hexdocs.pm/req/Req.Steps.html#retry/1\n-    # NOTE: look at source code in Github\n+  def build_req_client(conn, opts) do\n+    # Default request options. These can be overridden in this hierarchy:\n+    # 1. Via the `:options` key in `config.exs`.\n+    # 2. By passing `:req` key to `opts` arg to request/2.\n+    req_options =\n+      conn\n+      |> Map.get(:options, [])\n+      |> Keyword.merge(Access.get(opts, :req, []))\n+\n     url =\n@@ -106,22 +112,19 @@ defmodule OpenApiTypesense.Client do\n         port: conn.port,\n-        path: opts[:url],\n-        query: URI.encode_query(opts[:query] || [])\n+        path: Access.get(opts, :url),\n+        query: URI.encode_query(Access.get(opts, :query, []))\n       }\n \n-    {_req, resp} =\n-      [\n-        method: opts[:method] || :get,\n-        body: encode_body(opts),\n-        url: url,\n-        max_retries: test_max_retries() || opts[:req][:max_retries] || 3,\n-        retry: test_retry() || opts[:req][:retry] || :safe_transient,\n-        compress_body: opts[:req][:compress] || false,\n-        cache: opts[:req][:cache] || false,\n-        decode_json: [keys: :atoms]\n-      ]\n-      |> Req.new()\n-      |> Req.Request.merge_options(Map.to_list(Map.get(conn, :options, %{})))\n-      |> Req.Request.put_header(\"x-typesense-api-key\", Map.get(conn, :api_key))\n-      |> Req.Request.run_request()\n+    [\n+      method: Access.get(opts, :method, :get),\n+      body: encode_body(opts),\n+      url: url,\n+      decode_json: [keys: :atoms]\n+    ]\n+    |> Req.new()\n+    |> Req.Request.merge_options(req_options)\n+    |> Req.Request.put_header(\"x-typesense-api-key\", Map.get(conn, :api_key))\n+  end\n \n+  defp req_request(req_client, opts) do\n+    {_req, resp} = Req.Request.run_request(req_client)\n     parse_resp(resp, opts[:response])\n","improvement-type":"Complex Method"}],"change-level":"warning","is-hotspot?":true,"line":97,"what-changed":"default_client has a cyclomatic complexity of 9, threshold = 9","how-to-fix":"There are many reasons for Complex Method. Sometimes, another design approach is beneficial such as a) modeling state using an explicit state machine rather than conditionals, or b) using table lookup rather than long chains of logic. In other scenarios, the function can be split using [EXTRACT FUNCTION](https://refactoring.com/catalog/extractFunction.html). Just make sure you extract natural and cohesive functions. Complex Methods can also be addressed by identifying complex conditional expressions and then using the [DECOMPOSE CONDITIONAL](https://refactoring.com/catalog/decomposeConditional.html) refactoring.","change-type":"introduced"}]},"positive-impact-count":0,"repo":"open_api_typesense","code-health":9.13223758675516,"version":"3.0","authors":["jaeyson"],"directives":{"added":[],"removed":[]},"positive-findings":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"notices":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"external-review-provider":"GitHub"},"analysistime":"2025-02-11T03:07:56.000Z","project-name":"open_api_typesense","repository":"https://github.com/jaeyson/open_api_typesense.git"}}