diff --git a/lib/botchini/services/twitch/auth_middleware.ex b/lib/botchini/services/twitch/auth_middleware.ex index eb1ebd8..a4d2bda 100644 --- a/lib/botchini/services/twitch/auth_middleware.ex +++ b/lib/botchini/services/twitch/auth_middleware.ex @@ -4,28 +4,25 @@ defmodule Botchini.Services.Twitch.AuthMiddleware do """ use Agent - use Tesla - - alias Botchini.Services.Twitch def start_link(_initial_value) do Agent.start_link(fn -> %{exp: nil, access_token: ""} end, name: __MODULE__) end - @behaviour Tesla.Middleware - def call(env, next, _) do - env - |> Tesla.put_header("authorization", "Bearer " <> get_token()) - |> Tesla.run(next) - end - - defp get_token do + def get_token do %{exp: exp, access_token: access_token} = Agent.get(__MODULE__, & &1) if NaiveDateTime.utc_now() < exp do access_token else - auth_resp = Twitch.authenticate() + auth_resp = + Req.post!("https://id.twitch.tv/oauth2/token", + params: [ + grant_type: "client_credentials", + client_id: Application.fetch_env!(:botchini, :twitch_client_id), + client_secret: Application.fetch_env!(:botchini, :twitch_client_secret) + ] + ).body Agent.update(__MODULE__, fn _ -> %{ diff --git a/lib/botchini/services/twitch/twitch.ex b/lib/botchini/services/twitch/twitch.ex index dee0e5a..0038a7b 100644 --- a/lib/botchini/services/twitch/twitch.ex +++ b/lib/botchini/services/twitch/twitch.ex @@ -3,34 +3,34 @@ defmodule Botchini.Services.Twitch do Handles communication with Twitch API """ - use Tesla - + alias Botchini.Services.Twitch.AuthMiddleware alias Botchini.Services.Twitch.Structs.{Channel, Stream, User} - plug(Tesla.Middleware.JSON) - plug(Tesla.Middleware.Logger) - plug(Botchini.Services.Twitch.AuthMiddleware) - plug(Tesla.Middleware.BaseUrl, "https://api.twitch.tv/helix") - - plug(Tesla.Middleware.Headers, [ - {"Client-ID", Application.fetch_env!(:botchini, :twitch_client_id)} - ]) - @spec search_channels(String.t()) :: list(Channel.t()) def search_channels(term) do - {:ok, %{body: body}} = get("/search/channels", query: [query: term, first: 10]) - - body + resp = + Req.get!( + api(), + url: "/search/channels", + params: [query: term, first: 10] + ) + + resp.body |> Map.get("data") |> Enum.map(&Channel.new/1) end @spec get_user(String.t()) :: User.t() | nil def get_user(user_id) do - {:ok, %{body: body}} = get("/users", query: [id: user_id]) + resp = + Req.get!( + api(), + url: "/users", + params: [id: user_id] + ) user = - body + resp.body |> Map.get("data") |> List.first() @@ -39,10 +39,15 @@ defmodule Botchini.Services.Twitch do @spec get_user_by_user_login(String.t()) :: User.t() | nil def get_user_by_user_login(user_login) do - {:ok, %{body: body}} = get("/users", query: [login: String.downcase(user_login)]) + resp = + Req.get!( + api(), + url: "/users", + params: [login: String.downcase(user_login)] + ) user = - body + resp.body |> Map.get("data") |> List.first() @@ -51,10 +56,15 @@ defmodule Botchini.Services.Twitch do @spec get_stream(String.t()) :: Stream.t() | nil def get_stream(user_id) do - {:ok, %{body: body}} = get("/streams", query: [user_id: user_id]) + resp = + Req.get!( + api(), + url: "/streams", + params: [user_id: user_id] + ) stream = - body + resp.body |> Map.get("data") |> List.first() @@ -63,39 +73,41 @@ defmodule Botchini.Services.Twitch do @spec add_stream_webhook(String.t()) :: any() def add_stream_webhook(user_id) do - {:ok, %{body: body}} = - post("/eventsub/subscriptions", %{ - type: "stream.online", - version: "1", - condition: %{broadcaster_user_id: user_id}, - transport: %{ - method: "webhook", - callback: Application.fetch_env!(:botchini, :host) <> "/api/twitch/webhooks/callback", - secret: Application.fetch_env!(:botchini, :twitch_webhook_secret) + resp = + Req.post!( + api(), + url: "/eventsub/subscriptions", + json: %{ + type: "stream.online", + version: "1", + condition: %{broadcaster_user_id: user_id}, + transport: %{ + method: "webhook", + callback: Application.fetch_env!(:botchini, :host) <> "/api/twitch/webhooks/callback", + secret: Application.fetch_env!(:botchini, :twitch_webhook_secret) + } } - }) + ) - body + resp.body |> Map.get("data") |> List.first() end @spec delete_stream_webhook(String.t()) :: any() def delete_stream_webhook(subscription_id) do - delete("/eventsub/subscriptions", query: [id: subscription_id]) + Req.delete!( + api(), + url: "/eventsub/subscriptions", + params: [id: subscription_id] + ) end - @spec authenticate() :: any() - def authenticate do - [Tesla.Middleware.JSON] - |> Tesla.client() - |> Tesla.post!("https://id.twitch.tv/oauth2/token", "", - query: [ - grant_type: "client_credentials", - client_id: Application.fetch_env!(:botchini, :twitch_client_id), - client_secret: Application.fetch_env!(:botchini, :twitch_client_secret) - ] + defp api do + Req.new( + base_url: "https://api.twitch.tv/helix", + auth: {:bearer, AuthMiddleware.get_token()}, + headers: [{"client-id", Application.fetch_env!(:botchini, :twitch_client_id)}] ) - |> Map.get(:body) end end diff --git a/lib/botchini/services/youtube/youtube.ex b/lib/botchini/services/youtube/youtube.ex index 190380a..355f32e 100644 --- a/lib/botchini/services/youtube/youtube.ex +++ b/lib/botchini/services/youtube/youtube.ex @@ -3,29 +3,20 @@ defmodule Botchini.Services.Youtube do Handles communication with YouTube API """ - use Tesla - alias Tesla.Multipart require Logger alias Botchini.Services.Youtube.Structs.{Channel, Video} - plug(Tesla.Middleware.JSON) - plug(Tesla.Middleware.Logger) - - plug(Tesla.Middleware.Query, - key: Application.fetch_env!(:botchini, :youtube_api_key) - ) - - @youtube_api "https://www.googleapis.com/youtube/v3" - @spec search_channels(String.t()) :: list(Channel.t()) def search_channels(term) do - {:ok, %{body: body}} = - get("#{@youtube_api}/search", - query: [part: "snippet", type: "channel", q: term] + resp = + Req.get!( + api(), + url: "/search", + params: [part: "snippet", type: "channel", q: term] ) - case Map.get(body, "items") do + case Map.get(resp.body, "items") do nil -> [] @@ -38,12 +29,14 @@ defmodule Botchini.Services.Youtube do @spec get_channel(String.t()) :: Channel.t() | nil def get_channel(channel_id) do - {:ok, %{body: body}} = - get("#{@youtube_api}/channels", - query: [part: "snippet", id: channel_id] + resp = + Req.get!( + api(), + url: "/channels", + params: [part: "snippet", id: channel_id] ) - case Map.get(body, "items") do + case Map.get(resp.body, "items") do nil -> nil @@ -55,12 +48,14 @@ defmodule Botchini.Services.Youtube do @spec get_video(String.t()) :: Video.t() | nil def get_video(video_id) do - {:ok, %{body: body}} = - get("https://www.googleapis.com/youtube/v3/videos", - query: [part: "snippet,liveStreamingDetails", id: video_id] + resp = + Req.get!( + api(), + url: "/videos", + params: [part: "snippet,liveStreamingDetails", id: video_id] ) - case Map.get(body, "items") do + case Map.get(resp.body, "items") do nil -> nil @@ -75,18 +70,17 @@ defmodule Botchini.Services.Youtube do callback_url = "#{Application.fetch_env!(:botchini, :host)}/api/youtube/webhooks/callback" topic_url = "https://www.youtube.com/xml/feeds/videos.xml?channel_id=#{channel_id}" - mp = - Multipart.new() - |> Multipart.add_field("hub.callback", callback_url) - |> Multipart.add_field("hub.topic", topic_url) - |> Multipart.add_field("hub.verify", "async") - |> Multipart.add_field("hub.mode", if(subscribe, do: "subscribe", else: "unsubscribe")) - |> Multipart.add_field( - "hub.secret", - Application.fetch_env!(:botchini, :youtube_webhook_secret) - ) + Req.post!( + url: "https://pubsubhubbub.appspot.com/subscribe", + form: [ + "hub.verify": "async", + "hub.mode": if(subscribe, do: "subscribe", else: "unsubscribe"), + "hub.callback": callback_url, + "hub.topic": topic_url, + "hub.secret": Application.fetch_env!(:botchini, :youtube_webhook_secret) + ] + ) - {:ok, _} = post("https://pubsubhubbub.appspot.com/subscribe", mp) {:ok} end @@ -102,4 +96,11 @@ defmodule Botchini.Services.Youtube do List.last(match) end end + + defp api do + Req.new( + base_url: "https://www.googleapis.com/youtube/v3", + params: [key: Application.fetch_env!(:botchini, :youtube_api_key)] + ) + end end diff --git a/lib/botchini_discord/creators/responses/components.ex b/lib/botchini_discord/creators/responses/components.ex index 5577177..5cbfcdd 100644 --- a/lib/botchini_discord/creators/responses/components.ex +++ b/lib/botchini_discord/creators/responses/components.ex @@ -6,7 +6,7 @@ defmodule BotchiniDiscord.Creators.Responses.Components do alias Botchini.Creators.Schema.Creator alias Nostrum.Constants.{ButtonStyle, ComponentType} - @spec follow_creator(Creator.service(), String.t()) :: map() + @spec follow_creator(Creator.services(), String.t()) :: map() def follow_creator(service, service_id) do %{ type: ComponentType.action_row(), @@ -21,7 +21,7 @@ defmodule BotchiniDiscord.Creators.Responses.Components do } end - @spec unfollow_creator(Creator.service(), String.t()) :: map() + @spec unfollow_creator(Creator.services(), String.t()) :: map() def unfollow_creator(service, service_id) do %{ type: ComponentType.action_row(), @@ -36,7 +36,7 @@ defmodule BotchiniDiscord.Creators.Responses.Components do } end - @spec confirm_unfollow_creator(Creator.service(), String.t()) :: map() + @spec confirm_unfollow_creator(Creator.services(), String.t()) :: map() def confirm_unfollow_creator(service, service_id) do %{ type: ComponentType.action_row(), diff --git a/mix.exs b/mix.exs index b60e579..edfd999 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Botchini.MixProject do def project do [ app: :botchini, - version: "8.9.1", + version: "8.9.2", elixir: "~> 1.16.1", build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, @@ -28,7 +28,6 @@ defmodule Botchini.MixProject do [ # Discord {:nostrum, "~> 0.9.1", runtime: Mix.env() != :test}, - {:cowlib, "~> 2.11", hex: :remedy_cowlib, override: true}, # Phoenix {:phoenix, "~> 1.6.16"}, {:phoenix_html, "~> 3.3.1"}, @@ -47,13 +46,11 @@ defmodule Botchini.MixProject do {:elixir_xml_to_map, "~> 2.0"}, # Ecto {:phoenix_ecto, "~> 4.4"}, - {:ecto_sql, "~> 3.9.2"}, - {:postgrex, ">= 0.16.5"}, + {:ecto_sql, "~> 3.11.1"}, + {:postgrex, "~> 0.17.5"}, # HTTP Client - {:tesla, "~> 1.6.0"}, - {:gun, "~> 2.0", override: true}, - {:hackney, "~> 1.17.0"}, - {:exconstructor, "~> 1.1.0"}, + {:req, "~> 0.4.0"}, + {:exconstructor, "~> 1.2.13"}, # Helpers {:ink, "~> 1.0"}, {:quantum, "~> 3.0"}, diff --git a/mix.lock b/mix.lock index 25415d4..7cdfa59 100644 --- a/mix.lock +++ b/mix.lock @@ -4,42 +4,42 @@ "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, "certifi": {:hex, :certifi, "2.13.0", "e52be248590050b2dd33b0bb274b56678f9068e67805dca8aa8b1ccdb016bbf6", [:rebar3], [], "hexpm", "8f3d9533a0f06070afdfd5d596b32e21c6580667a492891851b0e2737bc507a1"}, "chacha20": {:hex, :chacha20, "1.0.4", "0359d8f9a32269271044c1b471d5cf69660c362a7c61a98f73a05ef0b5d9eb9e", [:mix], [], "hexpm", "2027f5d321ae9903f1f0da7f51b0635ad6b8819bc7fe397837930a2011bc2349"}, - "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, - "cowlib": {:hex, :remedy_cowlib, "2.11.1", "7abb4d0779a7d1c655f7642dc0bd0af754951e95005dfa01b500c68fe35a5961", [:rebar3], [], "hexpm", "0b613dc308e080cb6134285f1b1b55c3873e101652e70c70010fc6651c91b130"}, + "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, "credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"}, "crontab": {:hex, :crontab, "1.1.13", "3bad04f050b9f7f1c237809e42223999c150656a6b2afbbfef597d56df2144c5", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "d67441bec989640e3afb94e123f45a2bc42d76e02988c9613885dc3d01cf7085"}, "curve25519": {:hex, :curve25519, "1.0.5", "f801179424e4012049fcfcfcda74ac04f65d0ffceeb80e7ef1d3352deb09f5bb", [:mix], [], "hexpm", "0fba3ad55bf1154d4d5fc3ae5fb91b912b77b13f0def6ccb3a5d58168ff4192d"}, "db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, - "ecto": {:hex, :ecto, "3.9.6", "2f420c173efcb2e22fa4f8fc41e75e02b3c5bd4cffef12085cae5418c12e530d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df17bc06ba6f78a7b764e4a14ef877fe5f4499332c5a105ace11fe7013b72c84"}, - "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, + "ecto": {:hex, :ecto, "3.11.2", "e1d26be989db350a633667c5cda9c3d115ae779b66da567c68c80cfb26a8c9ee", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c38bca2c6f8d8023f2145326cc8a80100c3ffe4dcbd9842ff867f7fc6156c65"}, + "ecto_sql": {:hex, :ecto_sql, "3.11.1", "e9abf28ae27ef3916b43545f9578b4750956ccea444853606472089e7d169470", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ce14063ab3514424276e7e360108ad6c2308f6d88164a076aac8a387e1fea634"}, "ed25519": {:hex, :ed25519, "1.4.1", "479fb83c3e31987c9cad780e6aeb8f2015fb5a482618cdf2a825c9aff809afc4", [:mix], [], "hexpm", "0dacb84f3faa3d8148e81019ca35f9d8dcee13232c32c9db5c2fb8ff48c80ec7"}, "elixir_xml_to_map": {:hex, :elixir_xml_to_map, "2.0.0", "a9b4a3e03ec7b938d463958ce857aa719627efc9af62412f7fa80497f69c1091", [:mix], [{:erlsom, "~> 1.4", [hex: :erlsom, repo: "hexpm", optional: false]}], "hexpm", "6988899f0cd5036a6dabc493ffc110cf3d6bffbf8e1b56410575f66c1bf6eb8c"}, "equivalex": {:hex, :equivalex, "1.0.3", "170d9a82ae066e0020dfe1cf7811381669565922eb3359f6c91d7e9a1124ff74", [:mix], [], "hexpm", "46fa311adb855117d36e461b9c0ad2598f72110ad17ad73d7533c78020e045fc"}, "erlsom": {:hex, :erlsom, "1.5.1", "c8fe2babd33ff0846403f6522328b8ab676f896b793634cfe7ef181c05316c03", [:rebar3], [], "hexpm", "7965485494c5844dd127656ac40f141aadfa174839ec1be1074e7edf5b4239eb"}, "esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"}, - "exconstructor": {:hex, :exconstructor, "1.1.0", "272623a7b203cb2901c20cbb92c5c3ab103cc0087ff7c881979e046043346752", [:mix], [], "hexpm", "0edd55e8352e04dabf71f35453a57650175c7d7e6af707b1d3df610e5052afe0"}, + "exconstructor": {:hex, :exconstructor, "1.2.13", "7021eed1450202dcbcd1ef021d6aacf7351854ff9d7964f166931567f9dfa9fb", [:mix], [], "hexpm", "69d3f0251a07bb7c5ef85bde22a1eee577dfbb49852d77fb7ad7b937035aeef2"}, "expo": {:hex, :expo, "0.4.1", "1c61d18a5df197dfda38861673d392e642649a9cef7694d2f97a587b2cfb319b", [:mix], [], "hexpm", "2ff7ba7a798c8c543c12550fa0e2cbc81b95d4974c65855d8d15ba7b37a1ce47"}, "exsync": {:hex, :exsync, "0.4.1", "0a14fe4bfcb80a509d8a0856be3dd070fffe619b9ba90fec13c58b316c176594", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "cefb22aa805ec97ffc5b75a4e1dc54bcaf781e8b32564bf74abbe5803d1b5178"}, "faker": {:hex, :faker, "0.18.0", "943e479319a22ea4e8e39e8e076b81c02827d9302f3d32726c5bf82f430e6e14", [:mix], [], "hexpm", "bfbdd83958d78e2788e99ec9317c4816e651ad05e24cfd1196ce5db5b3e81797"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, + "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, "floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"}, "forecastle": {:hex, :forecastle, "0.1.2", "f8dab08962c7a33010ebd39182513129f17b8814aa16fa453ddd536040882daf", [:mix], [], "hexpm", "8efaeb2e7d0fa24c605605e42562e2dbb0ffd11dc1dd99ef77d78884536ce501"}, "gen_stage": {:hex, :gen_stage, "1.2.1", "19d8b5e9a5996d813b8245338a28246307fd8b9c99d1237de199d21efc4c76a1", [:mix], [], "hexpm", "83e8be657fa05b992ffa6ac1e3af6d57aa50aace8f691fcf696ff02f8335b001"}, "gettext": {:hex, :gettext, "0.22.3", "c8273e78db4a0bb6fba7e9f0fd881112f349a3117f7f7c598fa18c66c888e524", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "935f23447713954a6866f1bb28c3a878c4c011e802bcd68a726f5e558e4b64bd"}, "gun": {:hex, :gun, "2.1.0", "b4e4cbbf3026d21981c447e9e7ca856766046eff693720ba43114d7f5de36e87", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "52fc7fc246bfc3b00e01aea1c2854c70a366348574ab50c57dfe796d24a0101d"}, - "hackney": {:hex, :hackney, "1.17.1", "08463f93d2cc1a03817bf28d8dae6021543f773bd436c9377047224856c4422c", [:rebar3], [{:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "~> 3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "d2cba9e3c8103ad0320623e9f1c33e8d378a15eaabe2ee8ae441898f3d35a18c"}, - "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"}, "ink": {:hex, :ink, "1.2.1", "d42ea4753a5fe0a2103ac25aecca581196e49497f67f80b8fe0fc674c92afac6", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2038033f35f94f3e12ec2362b9978ab1415f426f8eef2228bfcd4e465e9b05ee"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "kcl": {:hex, :kcl, "1.4.2", "8b73a55a14899dc172fcb05a13a754ac171c8165c14f65043382d567922f44ab", [:mix], [{:curve25519, ">= 1.0.4", [hex: :curve25519, repo: "hexpm", optional: false]}, {:ed25519, "~> 1.3", [hex: :ed25519, repo: "hexpm", optional: false]}, {:poly1305, "~> 1.0", [hex: :poly1305, repo: "hexpm", optional: false]}, {:salsa20, "~> 1.0", [hex: :salsa20, repo: "hexpm", optional: false]}], "hexpm", "9f083dd3844d902df6834b258564a82b21a15eb9f6acdc98e8df0c10feeabf05"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, - "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, + "mint": {:hex, :mint, "1.6.0", "88a4f91cd690508a04ff1c3e28952f322528934be541844d54e0ceb765f01d5e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "3c5ae85d90a5aca0a49c0d8b67360bbe407f3b54f1030a111047ff988e8fefaa"}, + "nimble_options": {:hex, :nimble_options, "1.1.0", "3b31a57ede9cb1502071fade751ab0c7b8dbe75a9a4c2b5bbb0943a690b63172", [:mix], [], "hexpm", "8bbbb3941af3ca9acc7835f5655ea062111c9c27bcac53e004460dfd19008a99"}, + "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, + "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "nostrum": {:hex, :nostrum, "0.9.1", "52832df6adcd09389d83074bbb7f9e634eb110f178566e6df64314d981e0d0ed", [:mix], [{:castle, "~> 0.3.0", [hex: :castle, repo: "hexpm", optional: false]}, {:certifi, "~> 2.13", [hex: :certifi, repo: "hexpm", optional: false]}, {:gun, "~> 2.0", [hex: :gun, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:kcl, "~> 1.4", [hex: :kcl, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "d5697109e07bd1f747b3d2a74b69d003c12210ab12e57ac54d83dcf087de34f5"}, - "parse_trans": {:hex, :parse_trans, "3.4.2", "c352ddc1a0d5e54f9b1654d45f9c432eef76f9cea371c55ddff769ef688fdb74", [:rebar3], [], "hexpm", "4c25347de3b7c35732d32e69ab43d1ceee0beae3f3b3ade1b59cbd3dd224d9ca"}, "patch": {:hex, :patch, "0.12.0", "2da8967d382bade20344a3e89d618bfba563b12d4ac93955468e830777f816b0", [:mix], [], "hexpm", "ffd0e9a7f2ad5054f37af84067ee88b1ad337308a1cb227e181e3967127b0235"}, "petal_components": {:hex, :petal_components, "0.17.7", "09ee08bdf2bf6c1a043fc26b8167849cc2f14690822f783df784bb9196136202", [:mix], [{:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_ecto, "~> 4.4", [hex: :phoenix_ecto, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "8c9bc2ccf11a617bd6d8f0ebe2361716b0a6ab3bb30fd974719b54efc113db75"}, "phoenix": {:hex, :phoenix, "1.6.16", "e5bdd18c7a06da5852a25c7befb72246de4ddc289182285f8685a40b7b5f5451", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e15989ff34f670a96b95ef6d1d25bad0d9c50df5df40b671d8f4a669e050ac39"}, @@ -55,16 +55,14 @@ "plug_cowboy": {:hex, :plug_cowboy, "2.6.2", "753611b23b29231fb916b0cdd96028084b12aff57bfd7b71781bd04b1dbeb5c9", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "951ed2433df22f4c97b85fdb145d4cee561f36b74854d64c06d896d7cd2921a7"}, "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "poly1305": {:hex, :poly1305, "1.0.4", "7cdc8961a0a6e00a764835918cdb8ade868044026df8ef5d718708ea6cc06611", [:mix], [{:chacha20, "~> 1.0", [hex: :chacha20, repo: "hexpm", optional: false]}, {:equivalex, "~> 1.0", [hex: :equivalex, repo: "hexpm", optional: false]}], "hexpm", "e14e684661a5195e149b3139db4a1693579d4659d65bba115a307529c47dbc3b"}, - "postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"}, + "postgrex": {:hex, :postgrex, "0.17.5", "0483d054938a8dc069b21bdd636bf56c487404c241ce6c319c1f43588246b281", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "50b8b11afbb2c4095a3ba675b4f055c416d0f3d7de6633a595fc131a828a67eb"}, "quantum": {:hex, :quantum, "3.5.3", "ee38838a07761663468145f489ad93e16a79440bebd7c0f90dc1ec9850776d99", [:mix], [{:crontab, "~> 1.1", [hex: :crontab, repo: "hexpm", optional: false]}, {:gen_stage, "~> 0.14 or ~> 1.0", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_registry, "~> 0.2", [hex: :telemetry_registry, repo: "hexpm", optional: false]}], "hexpm", "500fd3fa77dcd723ed9f766d4a175b684919ff7b6b8cfd9d7d0564d58eba8734"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, + "req": {:hex, :req, "0.4.14", "103de133a076a31044e5458e0f850d5681eef23dfabf3ea34af63212e3b902e2", [:mix], [{:aws_signature, "~> 0.3.2", [hex: :aws_signature, repo: "hexpm", optional: true]}, {:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:nimble_ownership, "~> 0.2.0 or ~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2ddd3d33f9ab714ced8d3c15fd03db40c14dbf129003c4a3eb80fac2cc0b1b08"}, "salsa20": {:hex, :salsa20, "1.0.4", "404cbea1fa8e68a41bcc834c0a2571ac175580fec01cc38cc70c0fb9ffc87e9b", [:mix], [], "hexpm", "745ddcd8cfa563ddb0fd61e7ce48d5146279a2cf7834e1da8441b369fdc58ac6"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "tailwind": {:hex, :tailwind, "0.2.2", "9e27288b568ede1d88517e8c61259bc214a12d7eed271e102db4c93fcca9b2cd", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "ccfb5025179ea307f7f899d1bb3905cd0ac9f687ed77feebc8f67bdca78565c4"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.2", "2caabe9344ec17eafe5403304771c3539f3b6e2f7fb6a6f602558c825d0d0bfb", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b43db0dc33863930b9ef9d27137e78974756f5f198cae18409970ed6fa5b561"}, "telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"}, "telemetry_registry": {:hex, :telemetry_registry, "0.3.1", "14a3319a7d9027bdbff7ebcacf1a438f5f5c903057b93aee484cca26f05bdcba", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6d0ca77b691cf854ed074b459a93b87f4c7f5512f8f7743c635ca83da81f939e"}, - "tesla": {:hex, :tesla, "1.6.1", "42c9b88a988dcb6f929560890902dd06a81aa320311887aeeab0406581b5e567", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "a17a9aa6c14e44ad9940a143290d44fdcc49eb2ff0bf2e9a0ddf62e6be491f59"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, }