Current section
Files
Jump to
Current section
Files
lib/stripe/open_api/phases/build_operations.ex
defmodule Stripe.OpenApi.Phases.BuildOperations do
@moduledoc false
def run(blueprint, options \\ []) do
operations =
for {path, map} <- blueprint.source["paths"],
!options[:only_paths] or path in options[:only_paths],
!options[:path_prefixes] or String.starts_with?(path, options[:path_prefixes]),
{method, map} <- map,
into: %{} do
name =
map["operationId"]
|> String.replace(["/", "-"], "_")
|> Macro.underscore()
|> String.to_atom()
method = String.to_atom(method)
parameters = parameters(map["parameters"])
{path_params, query_params} =
parameters
|> Enum.split_with(&(&1.in == "path"))
body_params =
map["requestBody"]["content"]["application/x-www-form-urlencoded"]["schema"][
"properties"
] || %{}
body_params =
body_params
|> Enum.map(fn {key, value} ->
%OpenApiGen.Blueprint.Parameter{
in: "body",
name: key,
required: false,
schema: build_schema(value)
}
end)
operation = %OpenApiGen.Blueprint.Operation{
id: map["operationId"],
description: map["description"],
deprecated: map["deprecated"] || false,
method: method,
name: name,
parameters: parameters,
path_parameters: path_params,
query_parameters: query_params,
body_parameters: body_params,
path: path,
success_response:
response_type(map["responses"]["200"]["content"]["application/json"]["schema"])
}
{{operation.path, operation.method}, operation}
end
blueprint = Map.put(blueprint, :operations, operations)
{:ok, blueprint}
end
defp response_type(%{"$ref" => ref}), do: %OpenApiGen.Blueprint.Reference{name: ref}
defp response_type(%{"anyOf" => any_of}),
do: %OpenApiGen.Blueprint.AnyOf{any_of: Enum.map(any_of, &response_type/1)}
defp response_type(%{
"properties" => %{
"object" => %{
"enum" => [
"search_result"
]
},
"data" => %{"items" => items}
}
}) do
%OpenApiGen.Blueprint.SearchResult{type_of: response_type(items)}
end
defp response_type(%{
"properties" => %{
"data" => %{"items" => items}
}
}),
do: %OpenApiGen.Blueprint.ListOf{type_of: response_type(items)}
defp response_type(val), do: val
defp parameters(nil) do
[]
end
defp parameters(params) do
Enum.map(
params,
&%OpenApiGen.Blueprint.Parameter{
in: &1["in"],
name: &1["name"],
required: &1["required"],
schema: build_schema(&1["schema"])
}
)
end
defp build_schema(schema, name \\ nil)
defp build_schema(%{"type" => type} = schema, name)
when type in ["string", "integer", "boolean", "number"] do
%OpenApiGen.Blueprint.Parameter.Schema{
type: schema["type"],
name: name
}
end
defp build_schema(%{"type" => "array"} = schema, name) do
%OpenApiGen.Blueprint.Parameter.Schema{
type: schema["type"],
items: build_schema(schema["items"]),
name: name
}
end
defp build_schema(%{"type" => "object"} = schema, name) do
%OpenApiGen.Blueprint.Parameter.Schema{
type: schema["type"],
name: name,
properties:
(schema["properties"] || []) |> Enum.map(&build_schema(elem(&1, 1), elem(&1, 0)))
}
end
defp build_schema(%{"anyOf" => any_of} = _schema, name) do
%OpenApiGen.Blueprint.Parameter.Schema{
type: :any_of,
any_of: any_of |> Enum.map(&build_schema(&1)),
name: name
}
end
end