Current section
Files
Jump to
Current section
Files
lib/openapi_validator.ex
defmodule OpenapiValidator do
def find_schema({nil, nil}, _) do
%{}
end
def find_schema({method, schema_url}, %{paths: paths, specs: specs}) do
spec_name = Map.get(paths, {method, schema_url}, "")
Map.get(specs, spec_name, %{})
end
defp compile_spec(item) when is_binary(item) do
item
|> Jason.decode!()
|> ExJsonSchema.Schema.resolve()
end
defp compile_spec(item) when is_map(item) do
item
|> ExJsonSchema.Schema.resolve()
end
def compile_specs(specs, results \\ %{})
def compile_specs([], results) do
results
end
def compile_specs([head | tail] = items, results) when is_list(items) do
new_specs = compile_spec(head)
merged_results = add_schema(new_specs, results)
compile_specs(tail, merged_results)
end
def add_schema(new_specs, results) do
case ExJsonSchema.Schema.get_fragment(new_specs, [
:root,
"paths",
]) do
{:error, _} ->
results
{:ok, paths} ->
ref = get_name(new_specs)
old_paths = Map.get(results, :paths, %{})
old_specs = Map.get(results, :specs, %{})
new_paths =
Enum.map(List.flatten(build_routes(paths)), fn item -> {item, ref} end)
|> Map.new()
results
|> Map.put(:paths, Map.merge(old_paths, new_paths))
|> Map.put(:specs, Map.put(old_specs, ref, new_specs))
end
end
defp build_route(route_name, methods) do
Enum.map(
methods,
fn method ->
method = String.upcase(method)
{method, route_name}
end
)
end
defp build_routes(api_routes) do
# router = Module.concat(app, Router)
Enum.map(
api_routes,
fn {route_name, route} ->
build_route(route_name, Map.keys(route))
end
)
end
defp get_name(schema) do
case ExJsonSchema.Schema.get_fragment(schema, [
:root,
"info",
]) do
{:error, _} ->
false
{:ok, result} ->
Map.get(result, "title")
end
end
end