From 0fce811d55bef38bc496f4fca7e37ef299efc9a4 Mon Sep 17 00:00:00 2001 From: yujonglee Date: Sun, 30 Jun 2024 13:07:12 +0900 Subject: [PATCH] add json api --- core/config/config.exs | 4 ++++ core/lib/canary/sources/source.ex | 18 ++++++++++++++---- core/lib/canary/sources/sources.ex | 2 +- core/lib/canary_web/ash_router.ex | 5 +++++ core/lib/canary_web/router.ex | 15 ++++++--------- core/mix.exs | 2 ++ core/mix.lock | 5 +++++ 7 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 core/lib/canary_web/ash_router.ex diff --git a/core/config/config.exs b/core/config/config.exs index bf12f80f..b49d94f0 100644 --- a/core/config/config.exs +++ b/core/config/config.exs @@ -90,6 +90,10 @@ config :canary, config :hammer, backend: {Hammer.Backend.ETS, [expiry_ms: 60_000 * 60 * 4, cleanup_interval_ms: 60_000 * 10]} +# https://ash-hq.org/docs/guides/ash_json_api/latest/tutorials/getting-started-with-ash-json-api#accept-json_api-content-type +config :mime, :types, %{"application/vnd.api+json" => ["json"]} +config :mime, :extensions, %{"json" => "application/vnd.api+json"} + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{config_env()}.exs" diff --git a/core/lib/canary/sources/source.ex b/core/lib/canary/sources/source.ex index c6813411..23c1420b 100644 --- a/core/lib/canary/sources/source.ex +++ b/core/lib/canary/sources/source.ex @@ -1,17 +1,18 @@ defmodule Canary.Sources.Source do use Ash.Resource, domain: Canary.Sources, - data_layer: AshPostgres.DataLayer + data_layer: AshPostgres.DataLayer, + extensions: [AshJsonApi.Resource] attributes do uuid_primary_key :id create_timestamp :created_at attribute :account_id, :uuid, allow_nil?: false - attribute :name, :string, allow_nil?: false - attribute :type, :atom, constraints: [one_of: [:web]] + attribute :name, :string, allow_nil?: false, public?: true + attribute :type, :atom, constraints: [one_of: [:generic, :web]], public?: true - attribute :web_base_url, :string + attribute :web_base_url, :string, public?: true end identities do @@ -57,6 +58,15 @@ defmodule Canary.Sources.Source do end end + json_api do + type "source" + + routes do + get(:read, route: "sources/:id") + post(:create_web, route: "sources/web") + end + end + postgres do table "sources" repo Canary.Repo diff --git a/core/lib/canary/sources/sources.ex b/core/lib/canary/sources/sources.ex index a8a26715..9e1f861d 100644 --- a/core/lib/canary/sources/sources.ex +++ b/core/lib/canary/sources/sources.ex @@ -1,5 +1,5 @@ defmodule Canary.Sources do - use Ash.Domain + use Ash.Domain, extensions: [AshJsonApi.Domain] resources do resource Canary.Sources.Document diff --git a/core/lib/canary_web/ash_router.ex b/core/lib/canary_web/ash_router.ex new file mode 100644 index 00000000..a093064c --- /dev/null +++ b/core/lib/canary_web/ash_router.ex @@ -0,0 +1,5 @@ +defmodule CanaryWeb.AshRouter do + use AshJsonApi.Router, + domains: [Module.concat(["Canary.Sources"])], + open_api: "/openapi" +end diff --git a/core/lib/canary_web/router.ex b/core/lib/canary_web/router.ex index 66907af9..05cc2cb5 100644 --- a/core/lib/canary_web/router.ex +++ b/core/lib/canary_web/router.ex @@ -12,16 +12,11 @@ defmodule CanaryWeb.Router do plug :load_from_session end - pipeline :public_api do + pipeline :api do plug :accepts, ["json"] plug CORSPlug end - pipeline :private_api do - plug :accepts, ["json"] - plug :load_from_bearer - end - scope "/", CanaryWeb do pipe_through :browser @@ -54,10 +49,12 @@ defmodule CanaryWeb.Router do end end - scope "/", CanaryWeb do - pipe_through :public_api + scope "/api" do + pipe_through :api + + post "/submit", CanaryWeb.PublicApiController, :submit - post "/api/submit", PublicApiController, :submit + forward "/", CanaryWeb.AshRouter end if Application.compile_env(:canary, :dev_routes) do diff --git a/core/mix.exs b/core/mix.exs index 9f3f5ddf..1bfb4965 100644 --- a/core/mix.exs +++ b/core/mix.exs @@ -66,6 +66,8 @@ defmodule Canary.MixProject do {:ash_authentication, "~> 4.0"}, {:ash_authentication_phoenix, "~> 2.0"}, {:ash_postgres, "~> 2.0"}, + {:ash_json_api, "~> 1.0"}, + {:open_api_spex, "~> 3.16"}, {:picosat_elixir, "~> 0.2.3"}, {:req, "~> 0.5.0"}, {:retry, "~> 0.18"}, diff --git a/core/mix.lock b/core/mix.lock index 1146232c..9aff211f 100644 --- a/core/mix.lock +++ b/core/mix.lock @@ -4,6 +4,7 @@ "ash": {:hex, :ash, "3.0.15", "1cea8ca799dc8281d09e316a189fddfb27a2a29a0b0e5af369aa83d6f731ca75", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "97abfed57f2bf29c3889c51f0dfa23b382a1361a9d70e7d82d7e59a2be6bdc73"}, "ash_authentication": {:hex, :ash_authentication, "4.0.1", "27e5fcda1022897a02903441a049ba9e5f655e51a757039d946f5bce1de0447c", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, "~> 2.0", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:assent, ">= 0.2.8 and < 1.0.0-0", [hex: :assent, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:finch, "~> 0.18.0", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.5", [hex: :joken, repo: "hexpm", optional: false]}, {:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}], "hexpm", "e204585c8eed2d46a12e7031da48a169c513d5074ba43da90be0a92f7e1e0413"}, "ash_authentication_phoenix": {:hex, :ash_authentication_phoenix, "2.0.0", "1d2dd0abc9b9e008ea4423e902eb24825dbf4b9d1329bd079d7064ecfc45d319", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_authentication, "~> 4.0", [hex: :ash_authentication, repo: "hexpm", optional: false]}, {:ash_phoenix, "~> 2.0", [hex: :ash_phoenix, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_html_helpers, "~> 1.0", [hex: :phoenix_html_helpers, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:slugify, "~> 1.3", [hex: :slugify, repo: "hexpm", optional: false]}], "hexpm", "6a7c24d57ef6f7a4456d5ba139c8221df6a7ed81f15707a23fc33ad369e43a36"}, + "ash_json_api": {:hex, :ash_json_api, "1.3.0", "01df549036ef1835c090a353c4eea1c153d1c8b3494b5aa788e3f56da9aca8a7", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:json_xema, "~> 0.4", [hex: :json_xema, repo: "hexpm", optional: false]}, {:open_api_spex, "~> 3.16", [hex: :open_api_spex, repo: "hexpm", optional: true]}, {:plug, "~> 1.11", [hex: :plug, repo: "hexpm", optional: false]}, {:spark, ">= 2.2.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}], "hexpm", "440eadceedf8ab7f50955e45702ce7e62bb0c0263face83f47e5df5633aeab78"}, "ash_phoenix": {:hex, :ash_phoenix, "2.0.4", "0d18a3371879b875865180aaabc1697a35a6dcb9ebd2f346456208214bd02c9e", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5.6 or ~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.3 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "f3ea5309b42cdcaafc0ca713757cd4bb4819e02aeacc5195a040a955e861767d"}, "ash_postgres": {:hex, :ash_postgres, "2.0.12", "0cd30b5eab6ef6fc77d1f29c23bd8b9ad62e676f8aa14bf9194d3cf87e10adf2", [:mix], [{:ash, ">= 3.0.15 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_sql, ">= 0.2.6 and < 1.0.0-0", [hex: :ash_sql, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "a6536a641bcb3dc0ff5b351c35b9334e5586170037f88c0035f532dcba872700"}, "ash_sql": {:hex, :ash_sql, "0.2.6", "097a191b138af6bd5104ae0e166db5deb443fe3a4616b349fffe98120382765d", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "076abb07d7762537880a12699b756c7c86c1a4e98fcd0dc8c8059de93f7e9265"}, @@ -17,6 +18,7 @@ "chatterbox": {:hex, :ts_chatterbox, "0.15.1", "5cac4d15dd7ad61fc3c4415ce4826fc563d4643dee897a558ec4ea0b1c835c9c", [:rebar3], [{:hpack, "~> 0.3.0", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "4f75b91451338bc0da5f52f3480fa6ef6e3a2aeecfc33686d6b3d0a0948f31aa"}, "comeonin": {:hex, :comeonin, "5.4.0", "246a56ca3f41d404380fc6465650ddaa532c7f98be4bda1b4656b3a37cc13abe", [:mix], [], "hexpm", "796393a9e50d01999d56b7b8420ab0481a7538d0caf80919da493b4a6e51faf1"}, "comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"}, + "conv_case": {:hex, :conv_case, "0.2.3", "c1455c27d3c1ffcdd5f17f1e91f40b8a0bc0a337805a6e8302f441af17118ed8", [:mix], [], "hexpm", "88f29a3d97d1742f9865f7e394ed3da011abb7c5e8cc104e676fdef6270d4b4a"}, "cors_plug": {:hex, :cors_plug, "3.0.3", "7c3ac52b39624bc616db2e937c282f3f623f25f8d550068b6710e58d04a0e330", [:mix], [{:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3f2d759e8c272ed3835fab2ef11b46bddab8c1ab9528167bd463b6452edf830d"}, "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, "crawler": {:git, "https://github.com/fredwu/crawler.git", "6866bbe287c760b7e4bba1925e80f2a4494d7af3", [ref: "6866bbe287c760b7e4bba1925e80f2a4494d7af3"]}, @@ -55,6 +57,7 @@ "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "joken": {:hex, :joken, "2.6.1", "2ca3d8d7f83bf7196296a3d9b2ecda421a404634bfc618159981a960020480a1", [:mix], [{:jose, "~> 1.11.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "ab26122c400b3d254ce7d86ed066d6afad27e70416df947cdcb01e13a7382e68"}, "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, + "json_xema": {:hex, :json_xema, "0.6.2", "2af74c57f3f8dff8b74502d69d53f1ae7b6b236b477f30871c415ea8377a4c72", [:mix], [{:conv_case, "~> 0.2", [hex: :conv_case, repo: "hexpm", optional: false]}, {:xema, "~> 0.16", [hex: :xema, repo: "hexpm", optional: false]}], "hexpm", "50c84c537c95fcc76677f1f030af4aed188f538820fc488aeaa3f7dfe04d0edf"}, "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"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, @@ -67,6 +70,7 @@ "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"}, "oapi_github": {:hex, :oapi_github, "0.3.3", "16c6ec7415d5da61e34206574392d1be9135656acf3ca6508bd3c76dd8fc8569", [:mix], [{:faker, "~> 0.15", [hex: :faker, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.7 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:jose, "~> 1.0", [hex: :jose, repo: "hexpm", optional: true]}, {:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: true]}, {:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:redix, "~> 1.0", [hex: :redix, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e4033236474c98943097ce714b4d5f9760a08f395ace0e278adb44701093f51a"}, "oban": {:hex, :oban, "2.17.10", "c3e5bd739b5c3fdc38eba1d43ab270a8c6ca4463bb779b7705c69400b0d87678", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4afd027b8e2bc3c399b54318b4f46ee8c40251fb55a285cb4e38b5363f0ee7c4"}, + "open_api_spex": {:hex, :open_api_spex, "3.19.1", "65ccb5d06e3d664d1eec7c5ea2af2289bd2f37897094a74d7219fb03fc2b5994", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "392895827ce2984a3459c91a484e70708132d8c2c6c5363972b4b91d6bbac3dd"}, "opentelemetry": {:hex, :opentelemetry, "1.4.0", "f928923ed80adb5eb7894bac22e9a198478e6a8f04020ae1d6f289fdcad0b498", [:rebar3], [{:opentelemetry_api, "~> 1.3.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: false]}], "hexpm", "50b32ce127413e5d87b092b4d210a3449ea80cd8224090fe68d73d576a3faa15"}, "opentelemetry_api": {:hex, :opentelemetry_api, "1.3.0", "03e2177f28dd8d11aaa88e8522c81c2f6a788170fe52f7a65262340961e663f9", [:mix, :rebar3], [{:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: false]}], "hexpm", "b9e5ff775fd064fa098dba3c398490b77649a352b40b0b730a6b7dc0bdd68858"}, "opentelemetry_exporter": {:hex, :opentelemetry_exporter, "1.7.0", "dec4e90c0667cf11a3642f7fe71982dbc0c6bfbb8725a0b13766830718cf0d98", [:rebar3], [{:grpcbox, ">= 0.0.0", [hex: :grpcbox, repo: "hexpm", optional: false]}, {:opentelemetry, "~> 1.4.0", [hex: :opentelemetry, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.3.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:tls_certificate_check, "~> 1.18", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "d0f25f6439ec43f2561537c3fabbe177b38547cddaa3a692cbb8f4770dbefc1e"}, @@ -116,4 +120,5 @@ "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"}, + "xema": {:hex, :xema, "0.17.2", "ddaa58c4489969bffec6e24f1d8dab645d21d0cde9b7ae5215f2ab0b169a5593", [:mix], [{:conv_case, "~> 0.2.2", [hex: :conv_case, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "965a44cd0846dde36a981889d7a3788c3f932893b688ec941b0ce71c363fa1cf"}, }