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