Page MenuHomePhorge

No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/open_api_spex/cast_parameters.ex b/lib/open_api_spex/cast_parameters.ex
index 0242981..fe9f682 100644
--- a/lib/open_api_spex/cast_parameters.ex
+++ b/lib/open_api_spex/cast_parameters.ex
@@ -1,97 +1,82 @@
defmodule OpenApiSpex.CastParameters do
@moduledoc false
alias OpenApiSpex.{Cast, Operation, Parameter, Schema, Reference, Components}
alias OpenApiSpex.Cast.{Error, Object}
alias Plug.Conn
@spec cast(Plug.Conn.t(), Operation.t(), Components.t()) ::
{:error, [Error.t()]} | {:ok, Conn.t()}
def cast(conn, operation, components) do
- # Convert parameters to an object schema for the set location
- casted_params =
- operation.parameters
- |> Enum.reduce(%{}, fn param, acc ->
- # Operation's parameters list may include references - resolving here
- parameter =
- case param do
- %Reference{} -> Reference.resolve_parameter(param, components.parameters)
- %Parameter{} -> param
- end
-
- location_schema =
- acc
- |> Map.get(parameter.in)
- |> add_to_location_schema(parameter)
-
- Map.put(acc, parameter.in, location_schema)
- end)
- # then delegate to `Cast.Object.cast/1`
- |> Enum.map(fn {location, location_schema} ->
- params = get_params_by_location(conn, location, Map.keys(location_schema.properties))
-
- ctx = %Cast{
- value: params,
- schema: location_schema,
- schemas: components.schemas
- }
-
- Object.cast(ctx)
- end)
-
full_cast_result =
- Enum.reduce_while(casted_params, {:ok, %{}}, fn
- {:ok, entry}, {:ok, acc} -> {:cont, {:ok, Map.merge(acc, entry)}}
- cast_error, _ -> {:halt, cast_error}
- end)
+ schemas_by_location(operation, components)
+ |> Enum.map(fn {location, schema} -> cast_location(location, schema, components, conn) end)
+ |> reduce_cast_results()
case full_cast_result do
- {:ok, result} -> {:ok, %{conn | params: result}}
+ {:ok, params} -> {:ok, %{conn | params: params}}
err -> err
end
end
defp get_params_by_location(conn, :query, _) do
Plug.Conn.fetch_query_params(conn).query_params
end
defp get_params_by_location(conn, :path, _) do
conn.path_params
end
defp get_params_by_location(conn, :cookie, _) do
Plug.Conn.fetch_cookies(conn).req_cookies
end
defp get_params_by_location(conn, :header, expected_names) do
conn.req_headers
|> Enum.filter(fn {key, _value} ->
Enum.member?(expected_names, String.downcase(key))
end)
|> Map.new()
end
- defp add_to_location_schema(nil, parameter) do
- # Since there is no Schema on the "parameter" level, we create one here
- template_schema = %Schema{
+ defp create_location_schema(parameters) do
+ %Schema{
type: :object,
additionalProperties: false,
- properties: %{},
- required: []
+ properties: Map.new(parameters, fn p -> {p.name, Parameter.schema(p)} end),
+ required: parameters |> Enum.filter(& &1.required) |> Enum.map(& &1.name)
}
+ end
- add_to_location_schema(template_schema, parameter)
+ defp schemas_by_location(operation, components) do
+ param_specs_by_location =
+ operation.parameters
+ |> Enum.map(fn
+ %Reference{} = ref -> Reference.resolve_parameter(ref, components.parameters)
+ %Parameter{} = param -> param
+ end)
+ |> Enum.group_by(& &1.in)
+
+ Map.new(param_specs_by_location, fn {location, parameters} ->
+ {location, create_location_schema(parameters)}
+ end)
end
- defp add_to_location_schema(location_schema, parameter) do
- # Put the operation parameter to the proper location schema for validation
- required =
- case parameter.required do
- true -> [parameter.name | location_schema.required]
- _ -> location_schema.required
- end
+ defp cast_location(location, schema, components, conn) do
+ params = get_params_by_location(conn, location, Map.keys(schema.properties))
- properties = Map.put(location_schema.properties, parameter.name, Parameter.schema(parameter))
+ ctx = %Cast{
+ value: params,
+ schema: schema,
+ schemas: components.schemas
+ }
+
+ Object.cast(ctx)
+ end
- %{location_schema | properties: properties, required: required}
+ defp reduce_cast_results(results) do
+ Enum.reduce_while(results, {:ok, %{}}, fn
+ {:ok, params}, {:ok, all_params} -> {:cont, {:ok, Map.merge(all_params, params)}}
+ cast_error, _ -> {:halt, cast_error}
+ end)
end
end

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 26, 6:58 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40463
Default Alt Text
(4 KB)

Event Timeline