Skip to content

Commit 23edc6c

Browse files
committed
Proof of concept
1 parent 01d12f9 commit 23edc6c

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

lib/parameters/open_api.ex

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
defmodule Parameters.OAS3 do
2+
def type_mapper(:map), do: :object
3+
def type_mapper(:integer), do: :number
4+
def type_mapper(:float), do: :number
5+
def type_mapper(any), do: any
6+
7+
defmacro __using__(opts) do
8+
version = Keyword.fetch!(opts, :version)
9+
title = Keyword.fetch!(opts, :title)
10+
content_types = Keyword.fetch!(opts, :content_types)
11+
accepts = Keyword.fetch!(opts, :accepts)
12+
13+
quote do
14+
def generate do
15+
config = Application.get_env(unquote(opts[:otp_app]), __MODULE__)
16+
router = Keyword.fetch!(config, :router)
17+
routes = router.__routes__()
18+
accepts = unquote(accepts)
19+
content_types = unquote(content_types)
20+
21+
spec = %{
22+
openapi: "3.0.0",
23+
info: %{
24+
title: unquote(title),
25+
version: unquote(version)
26+
}
27+
}
28+
29+
key_fn = fn route -> route.path end
30+
val_fn = fn route ->
31+
parameters = route.plug.__parameters__()
32+
node = Enum.find(parameters, fn node -> node.id == route.plug_opts end)
33+
34+
key = "#{route.verb}"
35+
val = %{
36+
requestBody: %{
37+
required: true,
38+
description: "",
39+
content: for pipeline <- route.pipe_through, into: %{} do
40+
key = Keyword.fetch!(content_types, pipeline)
41+
42+
val = %{
43+
schema: %{
44+
required: for field <- node.fields, field.options[:required] do
45+
field.id
46+
end,
47+
properties: for field <- node.fields, into: %{} do
48+
{field.id, %{
49+
type: Parameters.OpenAPI.type_mapper(field.type)
50+
}}
51+
end,
52+
}
53+
}
54+
55+
{key, val}
56+
end,
57+
},
58+
responses: %{
59+
default: %{
60+
description: "",
61+
content: for pipeline <- route.pipe_through, into: %{} do
62+
key = Keyword.fetch!(content_types, pipeline)
63+
64+
val = %{
65+
schema: %{
66+
type: :object
67+
}
68+
}
69+
70+
{key, val}
71+
end,
72+
}
73+
},
74+
}
75+
76+
{key, val}
77+
end
78+
79+
paths =
80+
routes
81+
|> Enum.group_by(key_fn, val_fn)
82+
|> Enum.map(fn {key, val} -> {key, Enum.into(val, %{})} end)
83+
|> Enum.into(%{})
84+
85+
Map.put(spec, :paths, paths)
86+
end
87+
end
88+
end
89+
end

0 commit comments

Comments
 (0)