diff --git a/.formatter.exs b/.formatter.exs index 4a7f4bb..033c137 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,3 +1,4 @@ +# Used by "mix format" [ inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], line_length: 80 diff --git a/.gitignore b/.gitignore index ccb231b..62ba6a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,17 @@ # The directory Mix will write compiled artifacts to. -/_build +/_build/ # If you run "mix test --cover", coverage assets end up here. -/cover +/cover/ # The directory Mix downloads your dependencies sources to. -/deps +/deps/ -# Where 3rd-party dependencies like ExDoc output generated docs. -/doc +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch # If the VM crashes, it generates a dump, let's ignore it too. erl_crash.dump @@ -16,8 +19,15 @@ erl_crash.dump # Also ignore archive artifacts (built via "mix archive.build"). *.ez +# Ignore package tarball (built via "mix hex.build"). +kadabra-*.tar + +# Temporary files for e.g. tests. +/tmp/ + # Ignore dialyzer files /priv/plts/*.plt /priv/plts/*.plt.hash +# Misc. .iex.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 10299f3..0320e81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,13 @@ # Changelog -## v0.6.0 +## v0.6.0 - 2021-03-05 **Security** - Verify CA certificates with `:certifi` (~> 2.5) by default. This is considered a breaking change for anyone using Kadabra for anything other than [Pigeon](https://github.com/codedge-llc/pigeon). -## v0.5.0 +## v0.5.0 - 2021-01-10 **Changed** @@ -17,29 +17,29 @@ - Removed Elixir 1.11 compile warnings. -## v0.4.5 +## v0.4.5 - 2020-04-08 - Removed some compile warnings. -## v0.4.4 +## v0.4.4 - 2018-10-13 - Fixed ArithmeticError when calculating how many streams to request on infinite stream sets. -## v0.4.3 +## v0.4.3 - 2018-07-28 - Fixed supervisor crash report during normal connection shutdown. - Removed `GenStage` dependency. - GOAWAY error logger messages now disabled by default. Re-enable with `config :kadabra, debug_log?: true`. -## v0.4.2 +## v0.4.2 - 2018-05-25 - Fixed `{:closed, pid}` task race condition during connection cleanup. - Everything is supervised under `Kadabra.Application` again, instead of handling supervision yourself. -## v0.4.1 +## v0.4.1 - 2018-05-10 - Send exactly number of allowed bytes on initial connection WINDOW_UPDATE. - Default settings use maximum values for MAX_FRAME_SIZE and INITIAL_WINDOW_SIZE. @@ -49,7 +49,7 @@ - Fixed: don't send WINDOW_UPDATE frames larger than remote server's available connection flow window. -## v0.4.0 +## v0.4.0 - 2018-04-04 - Support for `http` URIs. - Requests are now buffered with GenStage. @@ -60,42 +60,42 @@ - Socket options passed as `:tcp`/`:ssl`, respectively. - Removed `:reconnect` functionality. -## v0.3.8 +## v0.3.8 - 2018-02-25 - Fixed: Streams properly killed if hpack table crashes. - Removed unused `Scribe` dependency. -## v0.3.7 +## v0.3.7 - 2018-01-07 - Fixed: `noproc` crash caused by race condition on recv GOAWAY. -## v0.3.6 +## v0.3.6 - 2017-12-18 - Fixed: ES flag properly set on certain HEADERS frames. -## v0.3.5 +## v0.3.5 - 2017-12-04 - Fixed: Memory leak on connection crashes. - New supervision structure. `Kadabra.open/2` now returns a supervisor pid, but the API for making requests remains unchanged. -## v0.3.4 +## v0.3.4 - 2017-10-31 - Fixed: Connections properly respect settings updates. -## v0.3.3 +## v0.3.3 - 2017-10-23 - Fixed: Hpack memory leak on connection close. -## v0.3.2 +## v0.3.2 - 2017-09-16 - Fixed: Connection settings defaults are now actually default. -## v0.3.1 +## v0.3.1 - 2017-08-26 - Fixed: Sending payloads larger than the stream window. -## v0.3.0 +## v0.3.0 - 2017-08-11 - Minimum requirements are now Elixir 1.4/OTP 19. - Performance improvements for individual streams. @@ -104,12 +104,12 @@ - Push promises can be intercepted with `{:push_promise, %Stream.Response{}}` messages. -## v0.2.2 +## v0.2.2 - 2017-08-03 - `Connection` now respects `max_concurrent_streams`. - Fixed: proper WINDOW_UPDATE responses on received DATA frames. -## v0.2.1 +## v0.2.1 - 2017-08-01 - Fixed: calling `Kadabra.open/3` with `reconnect: false` to disable automatic reconnect on socket close. diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/README.md b/README.md index 8638622..a3c130b 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,24 @@ +# Kadabra + [![Build Status](https://travis-ci.org/codedge-llc/kadabra.svg?branch=master)](https://travis-ci.org/codedge-llc/kadabra) [![Coverage Status](https://coveralls.io/repos/github/codedge-llc/kadabra/badge.svg?branch=master)](https://coveralls.io/github/codedge-llc/kadabra?branch=master) -[![Hex.pm](http://img.shields.io/hexpm/v/kadabra.svg)](https://hex.pm/packages/kadabra) -[![Hex.pm](http://img.shields.io/hexpm/dt/kadabra.svg)](https://hex.pm/packages/kadabra) +[![Module Version](https://img.shields.io/hexpm/v/kadabra.svg)](https://hex.pm/packages/kadabra) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/kadabra/) +[![Total Download](https://img.shields.io/hexpm/dt/kadabra.svg)](https://hex.pm/packages/kadabra) +[![License](https://img.shields.io/hexpm/l/kadabra.svg)](https://github.com/codedge-llc/kadabra/blob/master/LICENSE) +[![Last Updated](https://img.shields.io/github/last-commit/codedge-llc/kadabra.svg)](https://github.com/codedge-llc/kadabra/commits/master) -# Kadabra + -HTTP/2 client for Elixir +HTTP/2 client for Elixir. -Written to manage HTTP/2 connections for [pigeon](https://github.com/codedge-llc/pigeon). Very much a work in progress. +Written to manage HTTP/2 connections for [Pigeon](https://github.com/codedge-llc/pigeon). Very much a work in progress. ## Installation _Requires Elixir 1.6/OTP 19.2 or later._ -Add kadabra to your `mix.exs`: +Add `:kadabra` to your `mix.exs`: ```elixir def deps do @@ -25,6 +30,8 @@ end ## Usage +### Simple Requests + ```elixir {:ok, pid} = Kadabra.open("https://http2.golang.org") Kadabra.get(pid, "/") @@ -43,7 +50,7 @@ end } ``` -## Making Requests Manually +### Making Requests Manually ```elixir {:ok, pid} = Kadabra.open("https://http2.golang.org") @@ -71,3 +78,11 @@ end status: 200 } ``` + + + +## Copyright and License + +Copyright (c) 2016-2021 Codedge LLC (https://www.codedge.io/) + +Released under the MIT License, which can be found in [LICENSE.md](./LICENSE.md). diff --git a/lib/kadabra.ex b/lib/kadabra.ex index 10b4558..c806207 100644 --- a/lib/kadabra.ex +++ b/lib/kadabra.ex @@ -1,66 +1,9 @@ defmodule Kadabra do - @moduledoc ~S""" - HTTP/2 client for Elixir. - - Written to manage HTTP/2 connections for - [pigeon](https://github.com/codedge-llc/pigeon). - - *Requires Elixir 1.4/OTP 19.2 or later.* - - ## Usage - - {:ok, pid} = Kadabra.open("https://http2.golang.org") - Kadabra.get(pid, "/") - receive do - {:end_stream, %Kadabra.Stream.Response{} = stream} -> - IO.inspect stream - after 5_000 -> - IO.puts "Connection timed out." - end - - %Kadabra.Stream.Response{ - body: "\\n\\n

Go + HTTP/2

\\n\\n

Welcome to..." - headers: [ - {":status", "200"}, - {"content-type", "text/html; charset=utf-8"}, - {"content-length", "1708"}, - {"date", "Sun, 16 Oct 2016 21:20:47 GMT"} - ], - id: 1, - status: 200 - } - - ## Making Requests Manually - - {:ok, pid} = Kadabra.open("https://http2.golang.org") - - path = "/ECHO" # Route echoes PUT body in uppercase - body = "sample echo request" - headers = [ - {":method", "PUT"}, - {":path", path}, - ] - - Kadabra.request(pid, headers, body) - - receive do - {:end_stream, %Kadabra.Stream.Response{} = stream} -> - IO.inspect stream - after 5_000 -> - IO.puts "Connection timed out." - end - - %Kadabra.Stream.Response{ - body: "SAMPLE ECHO REQUEST", - headers: [ - {":status", "200"}, - {"content-type", "text/plain; charset=utf-8"}, - {"date", "Sun, 16 Oct 2016 21:28:15 GMT"} - ], - id: 1, - status: 200 - } - """ + @external_resource "README.md" + @moduledoc "README.md" + |> File.read!() + |> String.split("") + |> Enum.fetch!(1) alias Kadabra.{ConnectionPool, Request, Stream} diff --git a/lib/stream/response.ex b/lib/stream/response.ex index 682887a..e037f22 100644 --- a/lib/stream/response.ex +++ b/lib/stream/response.ex @@ -5,7 +5,9 @@ defmodule Kadabra.Stream.Response do If received as a push promise, `:status` and `:body` will most likely be empty. - *Sample response for a `PUT` request* + ## Examples + + Sample response for a `PUT` request: %Kadabra.Stream.Response{ body: "SAMPLE ECHO REQUEST", @@ -17,6 +19,7 @@ defmodule Kadabra.Stream.Response do id: 1, status: 200 } + """ defstruct [:id, :headers, :body, :status] diff --git a/mix.exs b/mix.exs index dbf7cb8..b7c39d7 100644 --- a/mix.exs +++ b/mix.exs @@ -1,31 +1,25 @@ defmodule Kadabra.Mixfile do use Mix.Project + @source_url "https://github.com/codedge-llc/kadabra" @version "0.6.0" def project do [ app: :kadabra, build_embedded: Mix.env() == :prod, + start_permanent: Mix.env() == :prod, consolidate_protocols: Mix.env() != :test, - deps: deps(), - description: description(), - dialyzer: dialyzer(), - docs: docs(), + version: @version, elixir: "~> 1.6", - elixirc_options: [warnings_as_errors: true], name: "Kadabra", package: package(), - preferred_cli_env: [ - coveralls: :test, - "coveralls.detail": :test, - "coveralls.post": :test, - "coveralls.html": :test - ], - source_url: "https://github.com/codedge-llc/kadabra", - start_permanent: Mix.env() == :prod, + deps: deps(), + docs: docs(), + dialyzer: dialyzer(), test_coverage: [tool: ExCoveralls], - version: @version + preferred_cli_env: preferred_cli_env(), + elixirc_options: [warnings_as_errors: true] ] end @@ -36,12 +30,6 @@ defmodule Kadabra.Mixfile do ] end - defp description do - """ - HTTP2 client for Elixir - """ - end - defp deps do [ {:certifi, "~> 2.5"}, @@ -53,15 +41,6 @@ defmodule Kadabra.Mixfile do ] end - defp docs do - [ - main: "Kadabra", - extras: [ - "CHANGELOG.md" - ] - ] - end - defp dialyzer do [ ignore_warnings: "config/dialyzer.ignore-warnings", @@ -73,10 +52,46 @@ defmodule Kadabra.Mixfile do defp package do [ - files: ["lib", "mix.exs", "README*", "LICENSE*"], + description: "HTTP2 client for Elixir.", + files: [ + "lib", + "mix.exs", + "README.md", + "CHANGELOG.md", + "CONTRIBUTING.md", + "LICENSE.md" + ], licenses: ["MIT"], - links: %{"GitHub" => "https://github.com/codedge-llc/kadabra"}, + links: %{ + "Changelog" => "https://hexdocs.pm/kadabra/changelog.html", + "GitHub" => @source_url + }, maintainers: ["Henry Popp"] ] end + + defp docs do + [ + extras: [ + "CHANGELOG.md", + "CONTRIBUTING.md": [title: "Contributing"], + "LICENSE.md": [title: "License"], + "README.md": [title: "Overview"] + ], + main: "readme", + source_url: @source_url, + source_ref: "v#{@version}", + formatters: ["html"], + skip_undefined_reference_warnings_on: ["CHANGELOG.md"] + ] + end + + defp preferred_cli_env do + [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test + ] + end end diff --git a/mix.lock b/mix.lock index 6cc4e03..bff5a10 100644 --- a/mix.lock +++ b/mix.lock @@ -1,34 +1,24 @@ %{ - "benchee": {:hex, :benchee, "0.11.0", "cf96e328ff5d69838dd89c21a9db22716bfcc6ef772e9d9dddf7ba622102722d", [], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"}, "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, - "certifi": {:hex, :certifi, "2.5.3", "70bdd7e7188c804f3a30ee0e7c99655bc35d8ac41c23e12325f36ab449b70651", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "ed516acb3929b101208a9d700062d520f3953da3b6b918d866106ffa980e1c10"}, + "certifi": {:hex, :certifi, "2.6.1", "dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493", [:rebar3], [], "hexpm", "524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"}, "credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"}, - "deep_merge": {:hex, :deep_merge, "0.1.1", "c27866a7524a337b6a039eeb8dd4f17d458fd40fbbcb8c54661b71a22fffe846", [], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"}, - "dogma": {:hex, :dogma, "0.1.16", "3c1532e2f63ece4813fe900a16704b8e33264da35fdb0d8a1d05090a3022eef9", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"}, "earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"}, + "ex_doc": {:hex, :ex_doc, "0.24.1", "15673de99154f93ca7f05900e4e4155ced1ee0cd34e0caeee567900a616871a4", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "07972f17bdf7dc7b5bd76ec97b556b26178ed3f056e7ec9288eb7cea7f91cce2"}, "excoveralls": {:hex, :excoveralls, "0.14.0", "4b562d2acd87def01a3d1621e40037fdbf99f495ed3a8570dfcf1ab24e15f76d", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "94f17478b0cca020bcd85ce7eafea82d2856f7ed022be777734a2f864d36091a"}, - "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "gen_stage": {:hex, :gen_stage, "0.13.1", "edff5bca9cab22c5d03a834062515e6a1aeeb7665fb44eddae086252e39c4378", [:mix], [], "hexpm"}, - "hackney": {:hex, :hackney, "1.17.0", "717ea195fd2f898d9fe9f1ce0afcc2621a41ecfe137fae57e7fe6e9484b9aa99", [: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", "64c22225f1ea8855f584720c0e5b3cd14095703af1c9fbc845ba042811dc671c"}, + "hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [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.1", [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", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"}, "hpack": {:hex, :hpack_erl, "0.2.3", "17670f83ff984ae6cd74b1c456edde906d27ff013740ee4d9efaa4f1bf999633", [:rebar3], [], "hexpm", "06f580167c4b8b8a6429040df36cc93bba6d571faeaec1b28816523379cbb23a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, - "inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, - "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, - "pane": {:hex, :pane, "0.1.1", "4a9b46957a02991acbce012169ab7e8ecff74ad24886f94b142680062b10f167", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, - "scribe": {:hex, :scribe, "0.4.1", "4bf5395fb882995f705172b817b9a4ccae6ac83f9918fdedb6a2b9dafb57ec5f", [:mix], [{:pane, "~> 0.1", [hex: :pane, repo: "hexpm", optional: false]}], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, }