...
1 package middleware
2
3 import (
4 "bytes"
5 "fmt"
6 "html/template"
7 "net/http"
8 "path"
9 )
10
11
12 type SwaggerUIOpts struct {
13
14 BasePath string
15
16
17 Path string
18
19
20
21
22 SpecURL string
23
24
25 Title string
26
27
28 Template string
29
30
31 OAuthCallbackURL string
32
33
34
35
36
37
38 SwaggerURL string
39
40 SwaggerPresetURL string
41 SwaggerStylesURL string
42
43 Favicon32 string
44 Favicon16 string
45 }
46
47
48 func (r *SwaggerUIOpts) EnsureDefaults() {
49 r.ensureDefaults()
50
51 if r.Template == "" {
52 r.Template = swaggeruiTemplate
53 }
54 }
55
56 func (r *SwaggerUIOpts) EnsureDefaultsOauth2() {
57 r.ensureDefaults()
58
59 if r.Template == "" {
60 r.Template = swaggerOAuthTemplate
61 }
62 }
63
64 func (r *SwaggerUIOpts) ensureDefaults() {
65 common := toCommonUIOptions(r)
66 common.EnsureDefaults()
67 fromCommonToAnyOptions(common, r)
68
69
70 if r.OAuthCallbackURL == "" {
71 r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback")
72 }
73 if r.SwaggerURL == "" {
74 r.SwaggerURL = swaggerLatest
75 }
76 if r.SwaggerPresetURL == "" {
77 r.SwaggerPresetURL = swaggerPresetLatest
78 }
79 if r.SwaggerStylesURL == "" {
80 r.SwaggerStylesURL = swaggerStylesLatest
81 }
82 if r.Favicon16 == "" {
83 r.Favicon16 = swaggerFavicon16Latest
84 }
85 if r.Favicon32 == "" {
86 r.Favicon32 = swaggerFavicon32Latest
87 }
88 }
89
90
91
92
93 func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler {
94 opts.EnsureDefaults()
95
96 pth := path.Join(opts.BasePath, opts.Path)
97 tmpl := template.Must(template.New("swaggerui").Parse(opts.Template))
98 assets := bytes.NewBuffer(nil)
99 if err := tmpl.Execute(assets, opts); err != nil {
100 panic(fmt.Errorf("cannot execute template: %w", err))
101 }
102
103 return serveUI(pth, assets.Bytes(), next)
104 }
105
106 const (
107 swaggerLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"
108 swaggerPresetLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"
109 swaggerStylesLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui.css"
110 swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png"
111 swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png"
112 swaggeruiTemplate = `
113 <!DOCTYPE html>
114 <html lang="en">
115 <head>
116 <meta charset="UTF-8">
117 <title>{{ .Title }}</title>
118
119 <link rel="stylesheet" type="text/css" href="{{ .SwaggerStylesURL }}" >
120 <link rel="icon" type="image/png" href="{{ .Favicon32 }}" sizes="32x32" />
121 <link rel="icon" type="image/png" href="{{ .Favicon16 }}" sizes="16x16" />
122 <style>
123 html
124 {
125 box-sizing: border-box;
126 overflow: -moz-scrollbars-vertical;
127 overflow-y: scroll;
128 }
129
130 *,
131 *:before,
132 *:after
133 {
134 box-sizing: inherit;
135 }
136
137 body
138 {
139 margin:0;
140 background: #fafafa;
141 }
142 </style>
143 </head>
144
145 <body>
146 <div id="swagger-ui"></div>
147
148 <script src="{{ .SwaggerURL }}"> </script>
149 <script src="{{ .SwaggerPresetURL }}"> </script>
150 <script>
151 window.onload = function() {
152 // Begin Swagger UI call region
153 const ui = SwaggerUIBundle({
154 url: '{{ .SpecURL }}',
155 dom_id: '#swagger-ui',
156 deepLinking: true,
157 presets: [
158 SwaggerUIBundle.presets.apis,
159 SwaggerUIStandalonePreset
160 ],
161 plugins: [
162 SwaggerUIBundle.plugins.DownloadUrl
163 ],
164 layout: "StandaloneLayout",
165 oauth2RedirectUrl: '{{ .OAuthCallbackURL }}'
166 })
167 // End Swagger UI call region
168
169 window.ui = ui
170 }
171 </script>
172 </body>
173 </html>
174 `
175 )
176
View as plain text