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()} @type identities_list_resp :: {:ok, API.IdentifyWithTraits.t()} | {:error, term()} @type identities_create_resp :: {:ok, API.IdentifyWithTraits.t()} | {:error, term()} @type identity :: String.t() @doc """ Returns a list of `API.FeatureStateSerializerFull.t()` for a given environment. """ @spec flags_list() :: flags_list_resp() def flags_list() do with {:ok, %Flagsmith.SDK.Client{} = client} <- Flagsmith.SDK.new() do flags_list(client) end end @spec flags_list(Flagsmith.SDK.Client.t()) :: flags_list_resp() def flags_list(%Flagsmith.SDK.Client{} = client) do case Tesla.get(new(client), @flags_path) 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 @doc """ Returns an `API.IdentifyWithTraits.t()` containing the flags and traits associated with a given identity. """ @spec identities_list(identity()) :: identities_list_resp() def identities_list(identity) do with {:ok, %Flagsmith.SDK.Client{} = client} <- Flagsmith.SDK.new() do identities_list(client, identity) end end @spec identities_list(Flagsmith.SDK.Client.t(), identity()) :: identities_list_resp() 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 @doc """ Creates and returns an `API.IdentifyWithTraits.t()` containing the flags and traits associated with that newly given identity. """ @spec identities_create(body_request()) :: identities_create_resp() def identities_create(body) do with {:ok, %Flagsmith.SDK.Client{} = client} <- Flagsmith.SDK.new() do identities_create(client, body) end end @spec identities_create(Flagsmith.SDK.Client.t(), body_request()) :: identities_create_resp() 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 @spec new(Flagsmith.SDK.Client.t()) :: Tesla.Client.t() def 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 return_error({:ok, %{body: body}}), do: {:error, body} defp return_error({:error, _} = error), do: error end