@@ -15,38 +15,23 @@ import type { ElysiaSwaggerConfig } from './types'
1515 *
1616 * @see https://github.com/elysiajs/elysia-swagger
1717 */
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 > = { } ) => {
5035 const schema = { }
5136 let totalRoutes = 0
5237
@@ -62,126 +47,142 @@ export const swagger = async <Path extends string = '/swagger'>(
6247
6348 const relativePath = path . startsWith ( '/' ) ? path . slice ( 1 ) : path
6449
65- const openAPISpecUrl = relativePath === '' ? `/json` : `/${ relativePath } /json`
66-
6750 const app = new Elysia ( { name : '@elysiajs/swagger' } )
6851
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'
8287 }
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'
9488 }
89+ )
9590
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'
104121 )
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
129137 registerSchemaPath ( {
130138 schema,
131139 hook : route . hooks ,
132- method,
140+ method : route . method ,
133141 path : route . path ,
134142 // @ts -ignore
135- models : app . definitions ? .type ,
143+ models : app . getGlobalDefinitions ?. ( ) . type ,
136144 contentType : route . hooks . type
137145 } )
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
150146 } )
151- } )
152- }
147+ }
153148
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+ }
181177 }
178+ } satisfies OpenAPIV3 . Document
179+ } ,
180+ {
181+ detail : {
182+ hide : true
182183 }
183- } satisfies OpenAPIV3 . Document
184- } )
184+ }
185+ )
185186
186187 return app
187188}
0 commit comments