defmodule Typesense do @moduledoc """ HTTP client for the Typesense API. """ alias HTTPoison.{AsyncResponse, Base, Error, Request, Response} use Base @default_headers [{"Content-Type", "application/json"}] @default_options [parse: :json] @impl Base def process_request_options(options) do Keyword.merge(@default_options, options) end @impl Base def process_url(url) do Application.fetch_env!(:ecto_typesense, :url) <> url end @impl Base def process_request_headers(headers) do api_key = Application.fetch_env!(:ecto_typesense, :api_key) @default_headers ++ [{"X-TYPESENSE-API-KEY", api_key}] ++ headers end @impl Base def process_request_body(body) when is_map(body) do Jason.encode!(body) end def process_request_body(body) do body end @impl Base def process_response(%Response{ status_code: status, body: body, request: %Request{ options: options } }) when status in 200..299 do case options[:parse] do :json -> json(body) :jsonl -> jsonl(body) _ -> {:ok, body} end end @impl Base def process_response(response), do: response @spec health() :: {:ok, Response.t() | AsyncResponse.t()} | {:error, Error.t()} def health, do: HTTPoison.get("/health") defp jsonl(string) do string |> String.split("\n") |> Enum.map(&json/1) end defp json(string) do case Jason.decode(string) do {:ok, json} -> json {:error, _} -> string end end end