@@ -85,48 +85,72 @@ export class SwaggerModule {
8585 httpAdapter : HttpServer ,
8686 documentOrFactory : OpenAPIObject | ( ( ) => OpenAPIObject ) ,
8787 options : {
88+ swaggerUiEnabled : boolean ;
8889 jsonDocumentUrl : string ;
8990 yamlDocumentUrl : string ;
9091 swaggerOptions : SwaggerCustomOptions ;
9192 }
9293 ) {
9394 let document : OpenAPIObject ;
9495
95- const lazyBuildDocument = ( ) => {
96- return typeof documentOrFactory === 'function'
97- ? documentOrFactory ( )
98- : documentOrFactory ;
96+ const getBuiltDocument = ( ) => {
97+ if ( ! document ) {
98+ document =
99+ typeof documentOrFactory === 'function'
100+ ? documentOrFactory ( )
101+ : documentOrFactory ;
102+ }
103+ return document ;
99104 } ;
100105
106+ if ( options . swaggerUiEnabled ) {
107+ this . serveSwaggerUi (
108+ finalPath ,
109+ urlLastSubdirectory ,
110+ httpAdapter ,
111+ getBuiltDocument ,
112+ options . swaggerOptions
113+ ) ;
114+ }
115+ this . serveDefinitions ( httpAdapter , getBuiltDocument , options ) ;
116+ }
117+
118+ private static serveSwaggerUi (
119+ finalPath : string ,
120+ urlLastSubdirectory : string ,
121+ httpAdapter : HttpServer ,
122+ getBuiltDocument : ( ) => OpenAPIObject ,
123+ swaggerOptions : SwaggerCustomOptions
124+ ) {
101125 const baseUrlForSwaggerUI = normalizeRelPath ( `./${ urlLastSubdirectory } /` ) ;
102126
103- let html : string ;
104- let swaggerInitJS : string ;
127+ let swaggerUiHtml : string ;
128+ let swaggerUiInitJS : string ;
105129
106130 httpAdapter . get (
107131 normalizeRelPath ( `${ finalPath } /swagger-ui-init.js` ) ,
108132 ( req , res ) => {
109133 res . type ( 'application/javascript' ) ;
134+ const document = getBuiltDocument ( ) ;
110135
111- if ( ! document ) {
112- document = lazyBuildDocument ( ) ;
113- }
114-
115- if ( options . swaggerOptions . patchDocumentOnRequest ) {
116- const documentToSerialize =
117- options . swaggerOptions . patchDocumentOnRequest ( req , res , document ) ;
136+ if ( swaggerOptions . patchDocumentOnRequest ) {
137+ const documentToSerialize = swaggerOptions . patchDocumentOnRequest (
138+ req ,
139+ res ,
140+ document
141+ ) ;
118142 const swaggerInitJsPerRequest = buildSwaggerInitJS (
119143 documentToSerialize ,
120- options . swaggerOptions
144+ swaggerOptions
121145 ) ;
122146 return res . send ( swaggerInitJsPerRequest ) ;
123147 }
124148
125- if ( ! swaggerInitJS ) {
126- swaggerInitJS = buildSwaggerInitJS ( document , options . swaggerOptions ) ;
149+ if ( ! swaggerUiInitJS ) {
150+ swaggerUiInitJS = buildSwaggerInitJS ( document , swaggerOptions ) ;
127151 }
128152
129- res . send ( swaggerInitJS ) ;
153+ res . send ( swaggerUiInitJS ) ;
130154 }
131155 ) ;
132156
@@ -141,29 +165,26 @@ export class SwaggerModule {
141165 ) ,
142166 ( req , res ) => {
143167 res . type ( 'application/javascript' ) ;
168+ const document = getBuiltDocument ( ) ;
144169
145- if ( ! document ) {
146- document = lazyBuildDocument ( ) ;
147- }
148-
149- if ( options . swaggerOptions . patchDocumentOnRequest ) {
150- const documentToSerialize =
151- options . swaggerOptions . patchDocumentOnRequest ( req , res , document ) ;
170+ if ( swaggerOptions . patchDocumentOnRequest ) {
171+ const documentToSerialize = swaggerOptions . patchDocumentOnRequest (
172+ req ,
173+ res ,
174+ document
175+ ) ;
152176 const swaggerInitJsPerRequest = buildSwaggerInitJS (
153177 documentToSerialize ,
154- options . swaggerOptions
178+ swaggerOptions
155179 ) ;
156180 return res . send ( swaggerInitJsPerRequest ) ;
157181 }
158182
159- if ( ! swaggerInitJS ) {
160- swaggerInitJS = buildSwaggerInitJS (
161- document ,
162- options . swaggerOptions
163- ) ;
183+ if ( ! swaggerUiInitJS ) {
184+ swaggerUiInitJS = buildSwaggerInitJS ( document , swaggerOptions ) ;
164185 }
165186
166- res . send ( swaggerInitJS ) ;
187+ res . send ( swaggerUiInitJS ) ;
167188 }
168189 ) ;
169190 } catch ( err ) {
@@ -173,40 +194,26 @@ export class SwaggerModule {
173194 */
174195 }
175196
176- httpAdapter . get ( finalPath , ( req , res ) => {
197+ httpAdapter . get ( finalPath , ( _ , res ) => {
177198 res . type ( 'text/html' ) ;
178199
179- if ( ! document ) {
180- document = lazyBuildDocument ( ) ;
181- }
182-
183- if ( ! html ) {
184- html = buildSwaggerHTML (
185- baseUrlForSwaggerUI ,
186- options . swaggerOptions
187- ) ;
200+ if ( ! swaggerUiHtml ) {
201+ swaggerUiHtml = buildSwaggerHTML ( baseUrlForSwaggerUI , swaggerOptions ) ;
188202 }
189203
190- res . send ( html ) ;
204+ res . send ( swaggerUiHtml ) ;
191205 } ) ;
192206
193207 // fastify doesn't resolve 'routePath/' -> 'routePath', that's why we handle it manually
194208 try {
195- httpAdapter . get ( normalizeRelPath ( `${ finalPath } /` ) , ( req , res ) => {
209+ httpAdapter . get ( normalizeRelPath ( `${ finalPath } /` ) , ( _ , res ) => {
196210 res . type ( 'text/html' ) ;
197211
198- if ( ! document ) {
199- document = lazyBuildDocument ( ) ;
200- }
201-
202- if ( ! html ) {
203- html = buildSwaggerHTML (
204- baseUrlForSwaggerUI ,
205- options . swaggerOptions
206- ) ;
212+ if ( ! swaggerUiHtml ) {
213+ swaggerUiHtml = buildSwaggerHTML ( baseUrlForSwaggerUI , swaggerOptions ) ;
207214 }
208215
209- res . send ( html ) ;
216+ res . send ( swaggerUiHtml ) ;
210217 } ) ;
211218 } catch ( err ) {
212219 /**
@@ -216,13 +223,20 @@ export class SwaggerModule {
216223 * We can simply ignore that error here.
217224 */
218225 }
226+ }
219227
228+ private static serveDefinitions (
229+ httpAdapter : HttpServer ,
230+ getBuiltDocument : ( ) => OpenAPIObject ,
231+ options : {
232+ jsonDocumentUrl : string ;
233+ yamlDocumentUrl : string ;
234+ swaggerOptions : SwaggerCustomOptions ;
235+ }
236+ ) {
220237 httpAdapter . get ( normalizeRelPath ( options . jsonDocumentUrl ) , ( req , res ) => {
221238 res . type ( 'application/json' ) ;
222-
223- if ( ! document ) {
224- document = lazyBuildDocument ( ) ;
225- }
239+ const document = getBuiltDocument ( ) ;
226240
227241 const documentToSerialize = options . swaggerOptions . patchDocumentOnRequest
228242 ? options . swaggerOptions . patchDocumentOnRequest ( req , res , document )
@@ -233,10 +247,7 @@ export class SwaggerModule {
233247
234248 httpAdapter . get ( normalizeRelPath ( options . yamlDocumentUrl ) , ( req , res ) => {
235249 res . type ( 'text/yaml' ) ;
236-
237- if ( ! document ) {
238- document = lazyBuildDocument ( ) ;
239- }
250+ const document = getBuiltDocument ( ) ;
240251
241252 const documentToSerialize = options . swaggerOptions . patchDocumentOnRequest
242253 ? options . swaggerOptions . patchDocumentOnRequest ( req , res , document )
@@ -276,6 +287,8 @@ export class SwaggerModule {
276287 ? `${ validatedGlobalPrefix } ${ validatePath ( options . yamlDocumentUrl ) } `
277288 : `${ finalPath } -yaml` ;
278289
290+ const swaggerUiEnabled = options ?. swaggerUiEnabled ?? true ;
291+
279292 const httpAdapter = app . getHttpAdapter ( ) ;
280293
281294 SwaggerModule . serveDocuments (
@@ -284,24 +297,27 @@ export class SwaggerModule {
284297 httpAdapter ,
285298 documentOrFactory ,
286299 {
300+ swaggerUiEnabled,
287301 jsonDocumentUrl : finalJSONDocumentPath ,
288302 yamlDocumentUrl : finalYAMLDocumentPath ,
289303 swaggerOptions : options || { }
290304 }
291305 ) ;
292306
293- SwaggerModule . serveStatic ( finalPath , app , options ?. customSwaggerUiPath ) ;
294- /**
295- * Covers assets fetched through a relative path when Swagger url ends with a slash '/'.
296- * @see https://github.com/nestjs/swagger/issues/1976
297- */
298- const serveStaticSlashEndingPath = `${ finalPath } /${ urlLastSubdirectory } ` ;
299- /**
300- * serveStaticSlashEndingPath === finalPath when path === '' || path === '/'
301- * in that case we don't need to serve swagger assets on extra sub path
302- */
303- if ( serveStaticSlashEndingPath !== finalPath ) {
304- SwaggerModule . serveStatic ( serveStaticSlashEndingPath , app ) ;
307+ if ( swaggerUiEnabled ) {
308+ SwaggerModule . serveStatic ( finalPath , app , options ?. customSwaggerUiPath ) ;
309+ /**
310+ * Covers assets fetched through a relative path when Swagger url ends with a slash '/'.
311+ * @see https://github.com/nestjs/swagger/issues/1976
312+ */
313+ const serveStaticSlashEndingPath = `${ finalPath } /${ urlLastSubdirectory } ` ;
314+ /**
315+ * serveStaticSlashEndingPath === finalPath when path === '' || path === '/'
316+ * in that case we don't need to serve swagger assets on extra sub path
317+ */
318+ if ( serveStaticSlashEndingPath !== finalPath ) {
319+ SwaggerModule . serveStatic ( serveStaticSlashEndingPath , app ) ;
320+ }
305321 }
306322 }
307323}
0 commit comments