@@ -85,48 +85,72 @@ export class SwaggerModule {
85
85
httpAdapter : HttpServer ,
86
86
documentOrFactory : OpenAPIObject | ( ( ) => OpenAPIObject ) ,
87
87
options : {
88
+ swaggerUiEnabled : boolean ;
88
89
jsonDocumentUrl : string ;
89
90
yamlDocumentUrl : string ;
90
91
swaggerOptions : SwaggerCustomOptions ;
91
92
}
92
93
) {
93
94
let document : OpenAPIObject ;
94
95
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 ;
99
104
} ;
100
105
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
+ ) {
101
125
const baseUrlForSwaggerUI = normalizeRelPath ( `./${ urlLastSubdirectory } /` ) ;
102
126
103
- let html : string ;
104
- let swaggerInitJS : string ;
127
+ let swaggerUiHtml : string ;
128
+ let swaggerUiInitJS : string ;
105
129
106
130
httpAdapter . get (
107
131
normalizeRelPath ( `${ finalPath } /swagger-ui-init.js` ) ,
108
132
( req , res ) => {
109
133
res . type ( 'application/javascript' ) ;
134
+ const document = getBuiltDocument ( ) ;
110
135
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
+ ) ;
118
142
const swaggerInitJsPerRequest = buildSwaggerInitJS (
119
143
documentToSerialize ,
120
- options . swaggerOptions
144
+ swaggerOptions
121
145
) ;
122
146
return res . send ( swaggerInitJsPerRequest ) ;
123
147
}
124
148
125
- if ( ! swaggerInitJS ) {
126
- swaggerInitJS = buildSwaggerInitJS ( document , options . swaggerOptions ) ;
149
+ if ( ! swaggerUiInitJS ) {
150
+ swaggerUiInitJS = buildSwaggerInitJS ( document , swaggerOptions ) ;
127
151
}
128
152
129
- res . send ( swaggerInitJS ) ;
153
+ res . send ( swaggerUiInitJS ) ;
130
154
}
131
155
) ;
132
156
@@ -141,29 +165,26 @@ export class SwaggerModule {
141
165
) ,
142
166
( req , res ) => {
143
167
res . type ( 'application/javascript' ) ;
168
+ const document = getBuiltDocument ( ) ;
144
169
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
+ ) ;
152
176
const swaggerInitJsPerRequest = buildSwaggerInitJS (
153
177
documentToSerialize ,
154
- options . swaggerOptions
178
+ swaggerOptions
155
179
) ;
156
180
return res . send ( swaggerInitJsPerRequest ) ;
157
181
}
158
182
159
- if ( ! swaggerInitJS ) {
160
- swaggerInitJS = buildSwaggerInitJS (
161
- document ,
162
- options . swaggerOptions
163
- ) ;
183
+ if ( ! swaggerUiInitJS ) {
184
+ swaggerUiInitJS = buildSwaggerInitJS ( document , swaggerOptions ) ;
164
185
}
165
186
166
- res . send ( swaggerInitJS ) ;
187
+ res . send ( swaggerUiInitJS ) ;
167
188
}
168
189
) ;
169
190
} catch ( err ) {
@@ -173,63 +194,26 @@ export class SwaggerModule {
173
194
*/
174
195
}
175
196
176
- httpAdapter . get ( finalPath , ( req , res ) => {
197
+ httpAdapter . get ( finalPath , ( _ , res ) => {
177
198
res . type ( 'text/html' ) ;
178
199
179
- if ( ! document ) {
180
- document = lazyBuildDocument ( ) ;
200
+ if ( ! swaggerUiHtml ) {
201
+ swaggerUiHtml = buildSwaggerHTML ( baseUrlForSwaggerUI , swaggerOptions ) ;
181
202
}
182
203
183
- if ( options . swaggerOptions . patchDocumentOnRequest ) {
184
- const documentToSerialize =
185
- options . swaggerOptions . patchDocumentOnRequest ( req , res , document ) ;
186
- const htmlPerRequest = buildSwaggerHTML (
187
- baseUrlForSwaggerUI ,
188
- documentToSerialize ,
189
- options . swaggerOptions
190
- ) ;
191
- return res . send ( htmlPerRequest ) ;
192
- }
193
-
194
- if ( ! html ) {
195
- html = buildSwaggerHTML (
196
- baseUrlForSwaggerUI ,
197
- document ,
198
- options . swaggerOptions
199
- ) ;
200
- }
201
-
202
- res . send ( html ) ;
204
+ res . send ( swaggerUiHtml ) ;
203
205
} ) ;
204
206
205
207
// fastify doesn't resolve 'routePath/' -> 'routePath', that's why we handle it manually
206
208
try {
207
- httpAdapter . get ( normalizeRelPath ( `${ finalPath } /` ) , ( req , res ) => {
209
+ httpAdapter . get ( normalizeRelPath ( `${ finalPath } /` ) , ( _ , res ) => {
208
210
res . type ( 'text/html' ) ;
209
211
210
- if ( ! document ) {
211
- document = lazyBuildDocument ( ) ;
212
- }
213
-
214
- if ( options . swaggerOptions . patchDocumentOnRequest ) {
215
- const documentToSerialize =
216
- options . swaggerOptions . patchDocumentOnRequest ( req , res , document ) ;
217
- const htmlPerRequest = buildSwaggerHTML (
218
- baseUrlForSwaggerUI ,
219
- documentToSerialize ,
220
- options . swaggerOptions
221
- ) ;
222
- return res . send ( htmlPerRequest ) ;
212
+ if ( ! swaggerUiHtml ) {
213
+ swaggerUiHtml = buildSwaggerHTML ( baseUrlForSwaggerUI , swaggerOptions ) ;
223
214
}
224
215
225
- if ( ! html ) {
226
- html = buildSwaggerHTML (
227
- baseUrlForSwaggerUI ,
228
- document ,
229
- options . swaggerOptions
230
- ) ;
231
- }
232
- res . send ( html ) ;
216
+ res . send ( swaggerUiHtml ) ;
233
217
} ) ;
234
218
} catch ( err ) {
235
219
/**
@@ -239,13 +223,20 @@ export class SwaggerModule {
239
223
* We can simply ignore that error here.
240
224
*/
241
225
}
226
+ }
242
227
228
+ private static serveDefinitions (
229
+ httpAdapter : HttpServer ,
230
+ getBuiltDocument : ( ) => OpenAPIObject ,
231
+ options : {
232
+ jsonDocumentUrl : string ;
233
+ yamlDocumentUrl : string ;
234
+ swaggerOptions : SwaggerCustomOptions ;
235
+ }
236
+ ) {
243
237
httpAdapter . get ( normalizeRelPath ( options . jsonDocumentUrl ) , ( req , res ) => {
244
238
res . type ( 'application/json' ) ;
245
-
246
- if ( ! document ) {
247
- document = lazyBuildDocument ( ) ;
248
- }
239
+ const document = getBuiltDocument ( ) ;
249
240
250
241
const documentToSerialize = options . swaggerOptions . patchDocumentOnRequest
251
242
? options . swaggerOptions . patchDocumentOnRequest ( req , res , document )
@@ -256,10 +247,7 @@ export class SwaggerModule {
256
247
257
248
httpAdapter . get ( normalizeRelPath ( options . yamlDocumentUrl ) , ( req , res ) => {
258
249
res . type ( 'text/yaml' ) ;
259
-
260
- if ( ! document ) {
261
- document = lazyBuildDocument ( ) ;
262
- }
250
+ const document = getBuiltDocument ( ) ;
263
251
264
252
const documentToSerialize = options . swaggerOptions . patchDocumentOnRequest
265
253
? options . swaggerOptions . patchDocumentOnRequest ( req , res , document )
@@ -299,6 +287,8 @@ export class SwaggerModule {
299
287
? `${ validatedGlobalPrefix } ${ validatePath ( options . yamlDocumentUrl ) } `
300
288
: `${ finalPath } -yaml` ;
301
289
290
+ const swaggerUiEnabled = options ?. swaggerUiEnabled ?? true ;
291
+
302
292
const httpAdapter = app . getHttpAdapter ( ) ;
303
293
304
294
SwaggerModule . serveDocuments (
@@ -307,24 +297,27 @@ export class SwaggerModule {
307
297
httpAdapter ,
308
298
documentOrFactory ,
309
299
{
300
+ swaggerUiEnabled,
310
301
jsonDocumentUrl : finalJSONDocumentPath ,
311
302
yamlDocumentUrl : finalYAMLDocumentPath ,
312
303
swaggerOptions : options || { }
313
304
}
314
305
) ;
315
306
316
- SwaggerModule . serveStatic ( finalPath , app , options ?. customSwaggerUiPath ) ;
317
- /**
318
- * Covers assets fetched through a relative path when Swagger url ends with a slash '/'.
319
- * @see https://github.com/nestjs/swagger/issues/1976
320
- */
321
- const serveStaticSlashEndingPath = `${ finalPath } /${ urlLastSubdirectory } ` ;
322
- /**
323
- * serveStaticSlashEndingPath === finalPath when path === '' || path === '/'
324
- * in that case we don't need to serve swagger assets on extra sub path
325
- */
326
- if ( serveStaticSlashEndingPath !== finalPath ) {
327
- 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
+ }
328
321
}
329
322
}
330
323
}
0 commit comments