@@ -15,38 +15,23 @@ import type { ElysiaSwaggerConfig } from './types'
15
15
*
16
16
* @see https://github.com/elysiajs/elysia-swagger
17
17
*/
18
- export const swagger = async < Path extends string = '/swagger' > (
19
- {
20
- provider = 'scalar' ,
21
- scalarVersion = 'latest' ,
22
- scalarCDN = '' ,
23
- scalarConfig = { } ,
24
- documentation = { } ,
25
- version = '5.9.0' ,
26
- excludeStaticFile = true ,
27
- path = '/swagger' as Path ,
28
- exclude = [ ] ,
29
- swaggerOptions = { } ,
30
- theme = `https://unpkg.com/swagger-ui-dist@${ version } /swagger-ui.css` ,
31
- autoDarkMode = true ,
32
- excludeMethods = [ 'OPTIONS' ] ,
33
- excludeTags = [ ]
34
- } : ElysiaSwaggerConfig < Path > = {
35
- provider : 'scalar' ,
36
- scalarVersion : 'latest' ,
37
- scalarCDN : '' ,
38
- scalarConfig : { } ,
39
- documentation : { } ,
40
- version : '5.9.0' ,
41
- excludeStaticFile : true ,
42
- path : '/swagger' as Path ,
43
- exclude : [ ] ,
44
- swaggerOptions : { } ,
45
- autoDarkMode : true ,
46
- excludeMethods : [ 'OPTIONS' ] ,
47
- excludeTags : [ ]
48
- }
49
- ) => {
18
+ export const swagger = < Path extends string = '/swagger' > ( {
19
+ provider = 'scalar' ,
20
+ scalarVersion = 'latest' ,
21
+ scalarCDN = '' ,
22
+ scalarConfig = { } ,
23
+ documentation = { } ,
24
+ version = '5.9.0' ,
25
+ excludeStaticFile = true ,
26
+ path = '/swagger' as Path ,
27
+ specPath = `${ path } /json` ,
28
+ exclude = [ ] ,
29
+ swaggerOptions = { } ,
30
+ theme = `https://unpkg.com/swagger-ui-dist@${ version } /swagger-ui.css` ,
31
+ autoDarkMode = true ,
32
+ excludeMethods = [ 'OPTIONS' ] ,
33
+ excludeTags = [ ]
34
+ } : ElysiaSwaggerConfig < Path > = { } ) => {
50
35
const schema = { }
51
36
let totalRoutes = 0
52
37
@@ -62,126 +47,142 @@ export const swagger = async <Path extends string = '/swagger'>(
62
47
63
48
const relativePath = path . startsWith ( '/' ) ? path . slice ( 1 ) : path
64
49
65
- const openAPISpecUrl = relativePath === '' ? `/json` : `/${ relativePath } /json`
66
-
67
50
const app = new Elysia ( { name : '@elysiajs/swagger' } )
68
51
69
- app . get ( path , function documentation ( { request} ) {
70
- const combinedSwaggerOptions = {
71
- url : openAPISpecUrl ,
72
- dom_id : '#swagger-ui' ,
73
- ...swaggerOptions
74
- }
75
-
76
- const stringifiedSwaggerOptions = JSON . stringify (
77
- combinedSwaggerOptions ,
78
- ( key , value ) => {
79
- if ( typeof value == 'function' ) return undefined
80
-
81
- return value
52
+ const page = new Response (
53
+ provider === 'swagger-ui'
54
+ ? SwaggerUIRender (
55
+ info ,
56
+ version ,
57
+ theme ,
58
+ JSON . stringify (
59
+ {
60
+ url : specPath ,
61
+ dom_id : '#swagger-ui' ,
62
+ ...swaggerOptions
63
+ } ,
64
+ ( _ , value ) =>
65
+ typeof value === 'function' ? undefined : value
66
+ ) ,
67
+ autoDarkMode
68
+ )
69
+ : ScalarRender (
70
+ info ,
71
+ scalarVersion ,
72
+ {
73
+ spec : {
74
+ ...scalarConfig . spec ,
75
+ url : specPath
76
+ } ,
77
+ ...scalarConfig ,
78
+ // so we can showcase the elysia theme
79
+ // @ts -expect-error
80
+ _integration : 'elysiajs'
81
+ } satisfies ReferenceConfiguration ,
82
+ scalarCDN
83
+ ) ,
84
+ {
85
+ headers : {
86
+ 'content-type' : 'text/html; charset=utf8'
82
87
}
83
- )
84
-
85
- const scalarConfiguration : ReferenceConfiguration = {
86
- spec : {
87
- ...scalarConfig . spec ,
88
- url : `${ new URL ( request . url ) . pathname . replace ( / \/ $ / , "" ) } /json`
89
- } ,
90
- ...scalarConfig ,
91
- // so we can showcase the elysia theme
92
- // @ts -expect-error
93
- _integration : 'elysiajs'
94
88
}
89
+ )
95
90
96
- return new Response (
97
- provider === 'swagger-ui'
98
- ? SwaggerUIRender (
99
- info ,
100
- version ,
101
- theme ,
102
- stringifiedSwaggerOptions ,
103
- autoDarkMode
91
+ app . get ( path , page , {
92
+ detail : {
93
+ hide : true
94
+ }
95
+ } ) . get (
96
+ specPath ,
97
+ function openAPISchema ( ) {
98
+ // @ts -expect-error Private property
99
+ const routes = app . getGlobalRoutes ( ) as InternalRoute [ ]
100
+
101
+ if ( routes . length !== totalRoutes ) {
102
+ const ALLOWED_METHODS = [
103
+ 'GET' ,
104
+ 'PUT' ,
105
+ 'POST' ,
106
+ 'DELETE' ,
107
+ 'OPTIONS' ,
108
+ 'HEAD' ,
109
+ 'PATCH' ,
110
+ 'TRACE'
111
+ ]
112
+ totalRoutes = routes . length
113
+
114
+ // forEach create a clone of a route (can't use for-of)
115
+ routes . forEach ( ( route : InternalRoute ) => {
116
+ if ( route . hooks ?. detail ?. hide === true ) return
117
+ if ( excludeMethods . includes ( route . method ) ) return
118
+ if (
119
+ ALLOWED_METHODS . includes ( route . method ) === false &&
120
+ route . method !== 'ALL'
104
121
)
105
- : ScalarRender ( info , scalarVersion , scalarConfiguration , scalarCDN ) ,
106
- {
107
- headers : {
108
- 'content-type' : 'text/html; charset=utf8'
109
- }
110
- }
111
- )
112
- } ) . get ( path === '/' ? '/json' : `${ path } /json` , function openAPISchema ( ) {
113
- // @ts -expect-error Private property
114
- const routes = app . getGlobalRoutes ( ) as InternalRoute [ ]
115
-
116
- if ( routes . length !== totalRoutes ) {
117
- const ALLOWED_METHODS = [ 'GET' , 'PUT' , 'POST' , 'DELETE' , 'OPTIONS' , 'HEAD' , 'PATCH' , 'TRACE' ]
118
- totalRoutes = routes . length
119
-
120
- // forEach create a clone of a route (can't use for-of)
121
- routes . forEach ( ( route : InternalRoute ) => {
122
- if ( route . hooks ?. detail ?. hide === true ) return
123
- // TODO: route.hooks?.detail?.hide !== false add ability to hide: false to prevent excluding
124
- if ( excludeMethods . includes ( route . method ) ) return
125
- if ( ALLOWED_METHODS . includes ( route . method ) === false && route . method !== 'ALL' ) return
126
-
127
- if ( route . method === 'ALL' ) {
128
- ALLOWED_METHODS . forEach ( ( method ) => {
122
+ return
123
+
124
+ if ( route . method === 'ALL' )
125
+ ALLOWED_METHODS . forEach ( ( method ) => {
126
+ registerSchemaPath ( {
127
+ schema,
128
+ hook : route . hooks ,
129
+ method,
130
+ path : route . path ,
131
+ // @ts -ignore
132
+ models : app . getGlobalDefinitions ?.( ) . type ,
133
+ contentType : route . hooks . type
134
+ } )
135
+ } )
136
+ else
129
137
registerSchemaPath ( {
130
138
schema,
131
139
hook : route . hooks ,
132
- method,
140
+ method : route . method ,
133
141
path : route . path ,
134
142
// @ts -ignore
135
- models : app . definitions ? .type ,
143
+ models : app . getGlobalDefinitions ?. ( ) . type ,
136
144
contentType : route . hooks . type
137
145
} )
138
- } )
139
- return
140
- }
141
-
142
- registerSchemaPath ( {
143
- schema,
144
- hook : route . hooks ,
145
- method : route . method ,
146
- path : route . path ,
147
- // @ts -ignore
148
- models : app . definitions ?. type ,
149
- contentType : route . hooks . type
150
146
} )
151
- } )
152
- }
147
+ }
153
148
154
- return {
155
- openapi : '3.0.3' ,
156
- ...{
157
- ...documentation ,
158
- tags : documentation . tags ?. filter (
159
- ( tag ) => ! excludeTags ?. includes ( tag ?. name )
160
- ) ,
161
- info : {
162
- title : 'Elysia Documentation' ,
163
- description : 'Development documentation' ,
164
- version : '0.0.0' ,
165
- ...documentation . info
166
- }
167
- } ,
168
- paths : {
169
- ...filterPaths ( schema , relativePath , {
170
- excludeStaticFile,
171
- exclude : Array . isArray ( exclude ) ? exclude : [ exclude ]
172
- } ) ,
173
- ...documentation . paths
174
- } ,
175
- components : {
176
- ...documentation . components ,
177
- schemas : {
178
- // @ts -ignore
179
- ...app . definitions ?. type ,
180
- ...documentation . components ?. schemas
149
+ return {
150
+ openapi : '3.0.3' ,
151
+ ...{
152
+ ...documentation ,
153
+ tags : documentation . tags ?. filter (
154
+ ( tag ) => ! excludeTags ?. includes ( tag ?. name )
155
+ ) ,
156
+ info : {
157
+ title : 'Elysia Documentation' ,
158
+ description : 'Development documentation' ,
159
+ version : '0.0.0' ,
160
+ ...documentation . info
161
+ }
162
+ } ,
163
+ paths : {
164
+ ...filterPaths ( schema , {
165
+ excludeStaticFile,
166
+ exclude : Array . isArray ( exclude ) ? exclude : [ exclude ]
167
+ } ) ,
168
+ ...documentation . paths
169
+ } ,
170
+ components : {
171
+ ...documentation . components ,
172
+ schemas : {
173
+ // @ts -ignore
174
+ ...app . getGlobalDefinitions ?.( ) . type ,
175
+ ...documentation . components ?. schemas
176
+ }
181
177
}
178
+ } satisfies OpenAPIV3 . Document
179
+ } ,
180
+ {
181
+ detail : {
182
+ hide : true
182
183
}
183
- } satisfies OpenAPIV3 . Document
184
- } )
184
+ }
185
+ )
185
186
186
187
return app
187
188
}
0 commit comments