Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85710689
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
25 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/open_api_spex/info.ex b/lib/open_api_spex/info.ex
index 134c22b..47b46ce 100644
--- a/lib/open_api_spex/info.ex
+++ b/lib/open_api_spex/info.ex
@@ -1,30 +1,30 @@
defmodule OpenApiSpex.Info do
@moduledoc """
Defines the `OpenApiSpex.Info.t` type.
"""
alias OpenApiSpex.{Contact, License}
@enforce_keys [:title, :version]
defstruct [
:title,
:description,
:termsOfService,
:contact,
:license,
:version
]
@typedoc """
[Info Object](https://swagger.io/specification/#infoObject)
The object provides metadata about the API. The metadata MAY be used by the clients if needed,
and MAY be presented in editing or documentation generation tools for convenience.
"""
@type t :: %__MODULE__{
title: String.t,
- description: String.t,
- termsOfService: String.t,
- contact: Contact.t,
- license: License.t,
+ description: String.t | nil,
+ termsOfService: String.t | nil,
+ contact: Contact.t | nil,
+ license: License.t | nil,
version: String.t
}
-end
\ No newline at end of file
+end
diff --git a/lib/open_api_spex/open_api.ex b/lib/open_api_spex/open_api.ex
index 6886d50..f4fb87b 100644
--- a/lib/open_api_spex/open_api.ex
+++ b/lib/open_api_spex/open_api.ex
@@ -1,65 +1,66 @@
defmodule OpenApiSpex.OpenApi do
@moduledoc """
Defines the `OpenApiSpex.OpenApi.t` type.
"""
alias OpenApiSpex.{
Info, Server, Paths, Components,
SecurityRequirement, Tag, ExternalDocumentation,
OpenApi
}
+ @enforce_keys [:info, :paths]
defstruct [
- :info,
- :servers,
- :paths,
- :components,
- :security,
- :tags,
- :externalDocs,
openapi: "3.0.0",
+ info: nil,
+ servers: [],
+ paths: nil,
+ components: nil,
+ security: [],
+ tags: [],
+ externalDocs: nil
]
@typedoc """
[OpenAPI Object](https://swagger.io/specification/#oasObject)
This is the root document object of the OpenAPI document.
"""
@type t :: %OpenApi{
openapi: String.t,
info: Info.t,
servers: [Server.t],
paths: Paths.t,
- components: Components.t,
+ components: Components.t | nil,
security: [SecurityRequirement.t],
tags: [Tag.t],
- externalDocs: ExternalDocumentation.t
+ externalDocs: ExternalDocumentation.t | nil
}
defimpl Poison.Encoder do
def encode(api_spec = %OpenApi{}, options) do
api_spec
|> to_json()
|> Poison.Encoder.encode(options)
end
defp to_json(%Regex{source: source}), do: source
defp to_json(value = %{__struct__: _}) do
value
|> Map.from_struct()
|> to_json()
end
defp to_json(value) when is_map(value) do
value
|> Stream.map(fn {k,v} -> {to_string(k), to_json(v)} end)
|> Stream.filter(fn {_, nil} -> false; _ -> true end)
|> Enum.into(%{})
end
defp to_json(value) when is_list(value) do
Enum.map(value, &to_json/1)
end
defp to_json(nil), do: nil
defp to_json(true), do: true
defp to_json(false), do: false
defp to_json(value) when is_atom(value), do: to_string(value)
defp to_json(value), do: value
end
end
\ No newline at end of file
diff --git a/lib/open_api_spex/schema.ex b/lib/open_api_spex/schema.ex
index a0a7413..370cef1 100644
--- a/lib/open_api_spex/schema.ex
+++ b/lib/open_api_spex/schema.ex
@@ -1,402 +1,402 @@
defmodule OpenApiSpex.Schema do
@moduledoc """
Defines the `OpenApiSpex.Schema.t` type and operations for casting and validating against a schema.
"""
alias OpenApiSpex.{
Schema, Reference, Discriminator, Xml, ExternalDocumentation
}
@doc """
A module implementing the `OpenApiSpex.Schema` behaviour should export a `schema/0` function
that produces an `OpenApiSpex.Schema` struct.
"""
@callback schema() :: t
defstruct [
:title,
:multipleOf,
:maximum,
:exclusiveMaximum,
:minimum,
:exclusiveMinimum,
:maxLength,
:minLength,
:pattern,
:maxItems,
:minItems,
:uniqueItems,
:maxProperties,
:minProperties,
:required,
:enum,
:type,
:allOf,
:oneOf,
:anyOf,
:not,
:items,
:properties,
{:additionalProperties, nil},
:description,
:format,
:default,
:nullable,
:discriminator,
:readOnly,
:writeOnly,
:xml,
:externalDocs,
:example,
:deprecated,
:"x-struct"
]
@typedoc """
[Schema Object](https://swagger.io/specification/#schemaObject)
The Schema Object allows the definition of input and output data types.
These types can be objects, but also primitives and arrays.
This object is an extended subset of the JSON Schema Specification Wright Draft 00.
## Example
alias OpenApiSpex.Schema
%Schema{
title: "User",
type: :object,
properties: %{
id: %Schema{type: :integer, minimum: 1},
name: %Schema{type: :string, pattern: "[a-zA-Z][a-zA-Z0-9_]+"},
email: %Scheam{type: :string, format: :email},
last_login: %Schema{type: :string, format: :"date-time"}
},
required: [:name, :email],
example: %{
"name" => "joe",
"email" => "joe@gmail.com"
}
}
"""
@type t :: %__MODULE__{
title: String.t,
multipleOf: number | nil,
maximum: number | nil,
exclusiveMaximum: boolean | nil,
minimum: number | nil,
exclusiveMinimum: boolean | nil,
maxLength: integer | nil,
minLength: integer | nil,
pattern: String.t | Regex.t | nil,
maxItems: integer | nil,
minItems: integer | nil,
uniqueItems: boolean | nil,
maxProperties: integer | nil,
minProperties: integer | nil,
- required: [String.t] | nil,
+ required: [atom] | nil,
enum: [String.t] | nil,
type: atom,
- allOf: [Schema.t | Reference.t] | nil,
- oneOf: [Schema.t | Reference.t] | nil,
- anyOf: [Schema.t | Reference.t] | nil,
- not: Schema.t | Reference.t | nil,
- items: Schema.t | Reference.t | nil,
- properties: %{atom => Schema.t | Reference.t} | nil,
- additionalProperties: boolean | Schema.t | Reference.t | nil,
+ allOf: [Schema.t | Reference.t | module] | nil,
+ oneOf: [Schema.t | Reference.t | module] | nil,
+ anyOf: [Schema.t | Reference.t | module] | nil,
+ not: Schema.t | Reference.t | module | nil,
+ items: Schema.t | Reference.t | module | nil,
+ properties: %{atom => Schema.t | Reference.t | module} | nil,
+ additionalProperties: boolean | Schema.t | Reference.t | module | nil,
description: String.t,
format: String.t | nil,
default: any | nil,
nullable: boolean | nil,
discriminator: Discriminator.t | nil,
readOnly: boolean | nil,
writeOnly: boolean | nil,
xml: Xml.t | nil,
externalDocs: ExternalDocumentation.t | nil,
example: any,
deprecated: boolean | nil,
"x-struct": module | nil
}
@doc """
Cast a simple value to the elixir type defined by a schema.
By default, object types are cast to maps, however if the "x-struct" attribute is set in the schema,
the result will be constructed as an instance of the given struct type.
## Examples
iex> OpenApiSpex.Schema.cast(%Schema{type: :integer}, "123", %{})
{:ok, 123}
iex> {:ok, dt = %DateTime{}} = OpenApiSpex.Schema.cast(%Schema{type: :string, format: :"date-time"}, "2018-04-02T13:44:55Z", %{})
...> dt |> DateTime.to_iso8601()
"2018-04-02T13:44:55Z"
"""
@spec cast(Schema.t | Reference.t, any, %{String.t => Schema.t | Reference.t}) :: {:ok, any} | {:error, String.t}
def cast(schema = %Schema{"x-struct": mod}, value, schemas) when not is_nil(mod) do
with {:ok, data} <- cast(%{schema | "x-struct": nil}, value, schemas) do
{:ok, struct(mod, data)}
end
end
def cast(%Schema{type: :boolean}, value, _schemas) when is_boolean(value), do: {:ok, value}
def cast(%Schema{type: :boolean}, value, _schemas) when is_binary(value) do
case value do
"true" -> {:ok, true}
"false" -> {:ok, false}
_ -> {:error, "Invalid boolean: #{inspect(value)}"}
end
end
def cast(%Schema{type: :integer}, value, _schemas) when is_integer(value), do: {:ok, value}
def cast(%Schema{type: :integer}, value, _schemas) when is_binary(value) do
case Integer.parse(value) do
{i, ""} -> {:ok, i}
_ -> {:error, :bad_integer}
end
end
def cast(%Schema{type: :number}, value, _schemas) when is_number(value), do: {:ok, value}
def cast(%Schema{type: :number}, value, _schemas) when is_binary(value) do
case Float.parse(value) do
{x, ""} -> {:ok, x}
_ -> {:error, :bad_float}
end
end
def cast(%Schema{type: :string, format: :"date-time"}, value, _schemas) when is_binary(value) do
case DateTime.from_iso8601(value) do
{:ok, datetime = %DateTime{}, _offset} -> {:ok, datetime}
error = {:error, _reason} -> error
end
end
def cast(%Schema{type: :string, format: :date}, value, _schemas) when is_binary(value) do
case Date.from_iso8601(value) do
{:ok, date = %Date{}} -> {:ok, date}
error = {:error, _reason} -> error
end
end
def cast(%Schema{type: :string}, value, _schemas) when is_binary(value), do: {:ok, value}
def cast(%Schema{type: :array, items: nil}, value, _schemas) when is_list(value), do: {:ok, value}
def cast(%Schema{type: :array}, [], _schemas), do: {:ok, []}
def cast(schema = %Schema{type: :array, items: items_schema}, [x | rest], schemas) do
with {:ok, x_cast} <- cast(items_schema, x, schemas),
{:ok, rest_cast} <- cast(schema, rest, schemas) do
{:ok, [x_cast | rest_cast]}
end
end
def cast(schema = %Schema{type: :array}, value, _schemas) when not is_list(value) do
{:error, "Invalid array: #{inspect(value)}"}
end
def cast(schema = %Schema{type: :object}, value, schemas) when is_map(value) do
with {:ok, props} <- cast_properties(schema, Enum.to_list(value), schemas) do
{:ok, Map.new(props)}
end
end
def cast(ref = %Reference{}, val, schemas), do: cast(Reference.resolve_schema(ref, schemas), val, schemas)
def cast(additionalProperties, val, _schemas) when additionalProperties in [true, false, nil], do: {:ok, val}
@spec cast_properties(Schema.t, list, %{String.t => Schema.t}) :: {:ok, list} | {:error, String.t}
defp cast_properties(%Schema{}, [], _schemas), do: {:ok, []}
defp cast_properties(object_schema = %Schema{}, [{key, value} | rest], schemas) do
{name, schema} = Enum.find(
object_schema.properties,
{key, object_schema.additionalProperties},
fn {name, _schema} -> to_string(name) == to_string(key) end)
with {:ok, new_value} <- cast(schema, value, schemas),
{:ok, cast_tail} <- cast_properties(object_schema, rest, schemas) do
{:ok, [{name, new_value} | cast_tail]}
end
end
@doc """
Validate a value against a Schema.
This expects that the value has already been `cast` to the appropriate data type.
## Examples
iex> OpenApiSpex.Schema.validate(%OpenApiSpex.Schema{type: :integer, minimum: 5}, 3, %{})
{:error, "#: 3 is smaller than minimum 5"}
iex> OpenApiSpex.Schema.validate(%OpenApiSpex.Schema{type: :string, pattern: "(.*)@(.*)"}, "joe@gmail.com", %{})
:ok
iex> OpenApiSpex.Schema.validate(%OpenApiSpex.Schema{type: :string, pattern: "(.*)@(.*)"}, "joegmail.com", %{})
{:error, "#: Value does not match pattern: (.*)@(.*)"}
"""
@spec validate(Schema.t | Reference.t, any, %{String.t => Schema.t | Reference.t}) :: :ok | {:error, String.t}
def validate(schema, val, schemas), do: validate(schema, val, "#", schemas)
@spec validate(Schema.t | Reference.t, any, String.t, %{String.t => Schema.t | Reference.t}) :: :ok | {:error, String.t}
def validate(ref = %Reference{}, val, path, schemas), do: validate(Reference.resolve_schema(ref, schemas), val, path, schemas)
def validate(%Schema{nullable: true}, nil, _path, _schemas), do: :ok
def validate(%Schema{type: type}, nil, path, _schemas) do
{:error, "#{path}: null value where #{type} expected"}
end
def validate(schema = %Schema{type: type}, value, path, _schemas) when type in [:integer, :number] do
with :ok <- validate_multiple(schema, value, path),
:ok <- validate_maximum(schema, value, path),
:ok <- validate_minimum(schema, value, path) do
:ok
end
end
def validate(schema = %Schema{type: :string}, value, path, _schemas) do
with :ok <- validate_max_length(schema, value, path),
:ok <- validate_min_length(schema, value, path),
:ok <- validate_pattern(schema, value, path) do
:ok
end
end
def validate(%Schema{type: :boolean}, value, path, _schemas) do
case is_boolean(value) do
true -> :ok
_ -> {:error, "#{path}: Invalid boolean: #{inspect(value)}"}
end
end
def validate(schema = %Schema{type: :array}, value, path, schemas) do
with :ok <- validate_max_items(schema, value, path),
:ok <- validate_min_items(schema, value, path),
:ok <- validate_unique_items(schema, value, path),
:ok <- validate_array_items(schema, value, {path, 0}, schemas) do
:ok
end
end
def validate(schema = %Schema{type: :object, properties: properties, required: required}, value = %{}, path, schemas) do
with :ok <- validate_required_properties(schema, value, path),
:ok <- validate_max_properties(schema, value, path),
:ok <- validate_min_properties(schema, value, path),
:ok <- validate_object_properties(properties, MapSet.new(required || []), value, path, schemas) do
:ok
end
end
@spec validate_multiple(Schema.t, number, String.t) :: :ok | {:error, String.t}
defp validate_multiple(%{multipleOf: nil}, _, _), do: :ok
defp validate_multiple(%{multipleOf: n}, value, _) when (round(value / n) * n == value), do: :ok
defp validate_multiple(%{multipleOf: n}, value, path), do: {:error, "#{path}: #{value} is not a multiple of #{n}"}
@spec validate_maximum(Schema.t, number, String.t) :: :ok | {:error, String.t}
defp validate_maximum(%{maximum: nil}, _val, _path), do: :ok
defp validate_maximum(%{maximum: n, exclusiveMaximum: true}, value, _path) when value < n, do: :ok
defp validate_maximum(%{maximum: n}, value, _path) when value <= n, do: :ok
defp validate_maximum(%{maximum: n}, value, path), do: {:error, "#{path}: #{value} is larger than maximum #{n}"}
@spec validate_minimum(Schema.t, number, String.t) :: :ok | {:error, String.t}
defp validate_minimum(%{minimum: nil}, _val, _path), do: :ok
defp validate_minimum(%{minimum: n, exclusiveMinimum: true}, value, _path) when value > n, do: :ok
defp validate_minimum(%{minimum: n}, value, _path) when value >= n, do: :ok
defp validate_minimum(%{minimum: n}, value, path), do: {:error, "#{path}: #{value} is smaller than minimum #{n}"}
@spec validate_max_length(Schema.t, String.t, String.t) :: :ok | {:error, String.t}
defp validate_max_length(%{maxLength: nil}, _val, _path), do: :ok
defp validate_max_length(%{maxLength: n}, value, path) do
case String.length(value) <= n do
true -> :ok
_ -> {:error, "#{path}: String length is larger than maxLength: #{n}"}
end
end
@spec validate_min_length(Schema.t, String.t, String.t) :: :ok | {:error, String.t}
defp validate_min_length(%{minLength: nil}, _val, _path), do: :ok
defp validate_min_length(%{minLength: n}, value, path) do
case String.length(value) >= n do
true -> :ok
_ -> {:error, "#{path}: String length is smaller than minLength: #{n}"}
end
end
@spec validate_pattern(Schema.t, String.t, String.t) :: :ok | {:error, String.t}
defp validate_pattern(%{pattern: nil}, _val, _path), do: :ok
defp validate_pattern(schema = %{pattern: regex}, val, path) when is_binary(regex) do
with {:ok, regex} <- Regex.compile(regex) do
validate_pattern(%{schema | pattern: regex}, val, path)
end
end
defp validate_pattern(%{pattern: regex = %Regex{}}, val, path) do
case Regex.match?(regex, val) do
true -> :ok
_ -> {:error, "#{path}: Value does not match pattern: #{regex.source}"}
end
end
@spec validate_max_items(Schema.t, list, String.t) :: :ok | {:error, String.t}
defp validate_max_items(%Schema{maxItems: nil}, _val, _path), do: :ok
defp validate_max_items(%Schema{maxItems: n}, value, _path) when length(value) <= n, do: :ok
defp validate_max_items(%Schema{maxItems: n}, value, path) do
{:error, "#{path}: Array length #{length(value)} is larger than maxItems: #{n}"}
end
@spec validate_min_items(Schema.t, list, String.t) :: :ok | {:error, String.t}
defp validate_min_items(%Schema{minItems: nil}, _val, _path), do: :ok
defp validate_min_items(%Schema{minItems: n}, value, _path) when length(value) >= n, do: :ok
defp validate_min_items(%Schema{minItems: n}, value, path) do
{:error, "#{path}: Array length #{length(value)} is smaller than minItems: #{n}"}
end
@spec validate_unique_items(Schema.t, list, String.t) :: :ok | {:error, String.t}
defp validate_unique_items(%Schema{uniqueItems: true}, value, path) do
unique_size =
value
|> MapSet.new()
|> MapSet.size()
case unique_size == length(value) do
true -> :ok
_ -> {:error, "#{path}: Array items must be unique"}
end
end
defp validate_unique_items(_schema, _value, _path), do: :ok
@spec validate_array_items(Schema.t, list, {String.t, integer}, %{String.t => Schema.t}) :: :ok | {:error, String.t}
defp validate_array_items(%Schema{type: :array, items: nil}, value, _path, _schemas) when is_list(value), do: :ok
defp validate_array_items(%Schema{type: :array}, [], _path, _schemas), do: :ok
defp validate_array_items(schema = %Schema{type: :array, items: item_schema}, [x | rest], {path, index}, schemas) do
with :ok <- validate(item_schema, x, "#{path}/#{index}", schemas) do
validate_array_items(schema, rest, {path, index + 1}, schemas)
end
end
@spec validate_required_properties(Schema.t, %{}, String.t) :: :ok | {:error, String.t}
defp validate_required_properties(%Schema{type: :object, required: nil}, _val, _path), do: :ok
defp validate_required_properties(%Schema{type: :object, required: required}, value = %{}, path) do
missing = required -- Map.keys(value)
case missing do
[] -> :ok
_ -> {:error, "#{path}: Missing required properties: #{inspect(missing)}"}
end
end
@spec validate_max_properties(Schema.t, %{}, String.t) :: :ok | {:error, String.t}
defp validate_max_properties(%Schema{type: :object, maxProperties: nil}, _val, _path), do: :ok
defp validate_max_properties(%Schema{type: :object, maxProperties: n}, val, _path) when map_size(val) <= n, do: :ok
defp validate_max_properties(%Schema{type: :object, maxProperties: n}, val, path) do
{:error, "#{path}: Object property count #{map_size(val)} is greater than maxProperties: #{n}"}
end
@spec validate_min_properties(Schema.t, %{}, String.t) :: :ok | {:error, String.t}
defp validate_min_properties(%Schema{type: :object, minProperties: nil}, _val, _path), do: :ok
defp validate_min_properties(%Schema{type: :object, minProperties: n}, val, _path) when map_size(val) >= n, do: :ok
defp validate_min_properties(%Schema{type: :object, minProperties: n}, val, path) do
{:error, "#{path}: Object property count #{map_size(val)} is less than minProperties: #{n}"}
end
@spec validate_object_properties(Enumerable.t, MapSet.t, %{}, String.t, %{String.t => Schema.t | Reference.t}) :: :ok | {:error, String.t}
defp validate_object_properties(properties = %{}, required, value = %{}, path, schemas = %{}) do
properties
|> Enum.filter(fn {name, _schema} -> Map.has_key?(value, name) end)
|> validate_object_properties(required, value, path, schemas)
end
defp validate_object_properties([], _required, _val, _path, _schemas), do: :ok
defp validate_object_properties([{name, schema} | rest], required, value = %{}, path, schemas = %{}) do
property_required = MapSet.member?(required, name)
property_value = Map.get(value, name)
property_path = "#{path}/#{name}"
with :ok <- validate_object_property(schema, property_required, property_value, property_path, schemas),
:ok <- validate_object_properties(rest, required, value, path, schemas) do
:ok
end
end
defp validate_object_property(_schema, false, nil, _path, _schemas), do: :ok
defp validate_object_property(schema, _required, value, path, schemas) do
validate(schema, value, path, schemas)
end
end
diff --git a/mix.exs b/mix.exs
index 5da6d90..fe87dbd 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,58 +1,58 @@
defmodule OpenApiSpex.Mixfile do
use Mix.Project
@version "1.1.4"
def project do
[
app: :open_api_spex,
version: @version,
elixir: "~> 1.5",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
description: description(),
package: package(),
deps: deps(),
source_url: "https://github.com/mbuhot/open_api_spex",
homepage_url: "https://github.com/mbuhot/open_api_spex",
docs: [extras: ["README.md"], main: "readme", source_ref: "v#{@version}"],
dialyzer: [
plt_add_apps: [:mix],
plt_add_deps: :apps_direct,
flags: ["-Werror_handling", "-Wno_unused", "-Wunmatched_returns", "-Wunderspecs"],
remove_defaults: [:unknown]
]
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Run "mix help compile.app" to learn about applications.
def application, do: [extra_applications: []]
defp description() do
"Leverage Open Api Specification 3 (swagger) to document, test, validate and explore your Plug and Phoenix APIs."
end
defp package() do
[
name: "open_api_spex",
files: ["lib", "mix.exs", "README.md", "LICENSE", "CHANGELOG.md"],
maintainers: ["Mike Buhot (m.buhot@gmail.com)"],
licenses: ["Mozilla Public License, version 2.0"],
links: %{"GitHub" => "https://github.com/mbuhot/open_api_spex"}
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:poison, "~> 3.1"},
{:plug, "~> 1.4"},
{:phoenix, "~> 1.3", only: :test},
{:ex_doc, "~> 0.16", only: :dev, runtime: false},
- {:dialyxir, "~> 0.5", only: :dev, runtime: false}
+ {:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false}
]
end
-end
\ No newline at end of file
+end
diff --git a/mix.lock b/mix.lock
index d2aa36b..4272b1c 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,10 +1,10 @@
%{
- "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [], [], "hexpm"},
- "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [], [], "hexpm"},
- "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
- "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [], [], "hexpm"},
- "phoenix": {:hex, :phoenix, "1.3.0", "1c01124caa1b4a7af46f2050ff11b267baa3edb441b45dbf243e979cd4c5891b", [], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
- "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.2", "bfa7fd52788b5eaa09cb51ff9fcad1d9edfeb68251add458523f839392f034c1", [], [], "hexpm"},
- "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
- "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"},
+ "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"},
+ "earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"},
+ "ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
+ "mime": {:hex, :mime, "1.2.0", "78adaa84832b3680de06f88f0997e3ead3b451a440d183d688085be2d709b534", [:mix], [], "hexpm"},
+ "phoenix": {:hex, :phoenix, "1.3.2", "2a00d751f51670ea6bc3f2ba4e6eb27ecb8a2c71e7978d9cd3e5de5ccf7378bd", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
+ "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.2", "bfa7fd52788b5eaa09cb51ff9fcad1d9edfeb68251add458523f839392f034c1", [:mix], [], "hexpm"},
+ "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
+ "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Sep 19, 1:59 AM (7 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1765241
Default Alt Text
(25 KB)
Attached To
Mode
R22 open_api_spex
Attached
Detach File
Event Timeline
Log In to Comment