defmodule Flagsmith.SDK.API do @flags_path "/flags/" @identities_path "/identities/" alias Flagsmith.API @type body_request :: String.t() | map() @type feature_list :: list(API.FeatureStateSerializerFull.t()) @type flags_list_resp :: {:ok, feature_list()} | {:error, term()} @spec flags_list() :: flags_list_resp() @spec flags_list(Flagsmith.SDK.Client.t() | non_neg_integer()) :: flags_list_resp() @spec flags_list(Flagsmith.SDK.Client.t(), page :: non_neg_integer() | nil) :: flags_list_resp() def flags_list(client \\ new(), page \\ nil) def flags_list(%Flagsmith.SDK.Client{} = client, page) do case Tesla.get(new(client), @flags_path, query: maybe_add_query(page: page)) do {:ok, %{status: status, body: body}} when status >= 200 and status < 300 -> {:ok, API.FeatureStateSerializerFull.from_response(body)} error_resp -> return_error(error_resp) end end def flags_list(page, _), do: flags_list(new(), page) @spec identities_list() :: Tesla.Env.result() @spec identities_list(Flagsmith.SDK.Client.t()) :: Tesla.Env.result() def identities_list(client \\ new()) def identities_list(%Flagsmith.SDK.Client{} = _client), do: {:error, :deprecated} # Tesla.get(new(client), @identities_path) def identities_list(id), do: identities_list(new(), id) def identities_list(%Flagsmith.SDK.Client{} = client, id) do case Tesla.get(new(client), "#{@identities_path}?identifier=#{id}") do {:ok, %{status: status, body: body}} when status >= 200 and status < 300 -> {:ok, API.IdentifyWithTraits.from_response(body)} error_resp -> return_error(error_resp) end end @spec identities_create(body_request()) :: Tesla.Env.result() @spec identities_create(Flagsmith.SDK.Client.t(), body_request()) :: Tesla.Env.result() def identities_create(sdk_client \\ new(), body) def identities_create(%Flagsmith.SDK.Client{} = client, body) do case Tesla.post(new(client), @identities_path, body) do {:ok, %{status: status, body: body}} when status >= 200 and status < 300 -> {:ok, API.IdentifyWithTraits.from_response(body)} error_resp -> return_error(error_resp) end end defp new() do with {:ok, %Flagsmith.SDK.Client{} = client} <- Flagsmith.SDK.new() do client end end defp new(%Flagsmith.SDK.Client{} = client) do Tesla.client([ Flagsmith.SDK.Client.base_url_middleware(client.base_url), Flagsmith.SDK.Client.auth_middleware(client.environment_key), Tesla.Middleware.JSON, {Tesla.Middleware.FollowRedirects, max_redirects: 5}, {Tesla.Middleware.Timeout, timeout: 5_000} ]) end defp maybe_add_query(list_of_params) do Enum.reduce(list_of_params, [], fn {_k, nil}, acc -> acc key_val, acc -> [key_val | acc] end) |> Enum.reverse() end defp return_error({:ok, %{body: body}}), do: {:error, body} defp return_error({:error, _} = error), do: error end