1
- import _ = require( ' lodash' ) ;
1
+ import _ = require( " lodash" ) ;
2
2
// tslint:disable-next-line no-submodule-imports
3
- import { validateSync as openApiValidatorSync } from 'swagger2openapi/validate' ;
4
- import * as uuid from 'uuid' ;
5
-
6
- import { parseModels } from './parse' ;
7
- import { IDefinition , IDefinitionConfig , IOperation , IParameterConfig , IServerlessFunctionConfig } from './types' ;
8
- import { cleanSchema } from './utils' ;
3
+ import { validateSync as openApiValidatorSync } from "swagger2openapi/validate" ;
4
+ import * as uuid from "uuid" ;
5
+
6
+ import { parseModels } from "./parse" ;
7
+ import {
8
+ Definition ,
9
+ DefinitionConfig ,
10
+ Operation ,
11
+ ParameterConfig ,
12
+ ServerlessFunctionConfig
13
+ } from "./types" ;
14
+ import { cleanSchema } from "./utils" ;
9
15
10
16
export class DefinitionGenerator {
11
17
// The OpenAPI version we currently validate against
12
- public version = ' 3.0.0' ;
18
+ public version = " 3.0.0" ;
13
19
14
20
// Base configuration object
15
- public definition = < IDefinition > {
21
+ public definition : Definition = {
16
22
openapi : this . version ,
17
- components : { } ,
23
+ components : { }
18
24
} ;
19
25
20
- public config : IDefinitionConfig ;
26
+ public config : DefinitionConfig ;
21
27
22
28
private root : string ;
23
29
24
30
/**
25
31
* Constructor
26
32
*/
27
- constructor ( config : IDefinitionConfig , root : string ) {
33
+ public constructor ( config : DefinitionConfig , root : string ) {
28
34
this . config = _ . cloneDeep ( config ) ;
29
35
this . root = root ;
30
36
}
31
37
32
- public async parse ( ) {
38
+ public async parse ( ) {
33
39
const {
34
- title = '' ,
35
- description = '' ,
40
+ title = "" ,
41
+ description = "" ,
36
42
version = uuid . v4 ( ) ,
37
- models,
43
+ models
38
44
} = this . config ;
39
45
40
46
_ . merge ( this . definition , {
@@ -43,16 +49,21 @@ export class DefinitionGenerator {
43
49
paths : { } ,
44
50
components : {
45
51
schemas : { } ,
46
- securitySchemes : { } ,
47
- } ,
52
+ securitySchemes : { }
53
+ }
48
54
} ) ;
49
55
50
56
this . definition . components . schemas = await parseModels ( models , this . root ) ;
51
57
52
58
return this ;
53
59
}
54
60
55
- public validate ( ) : { valid : boolean , context : string [ ] , warnings : any [ ] , error ?: any [ ] } {
61
+ public validate ( ) : {
62
+ valid : boolean ;
63
+ context : Array < string > ;
64
+ warnings : Array < any > ;
65
+ error ?: Array < any > ;
66
+ } {
56
67
const payload : any = { } ;
57
68
58
69
try {
@@ -68,7 +79,7 @@ export class DefinitionGenerator {
68
79
* Add Paths to OpenAPI Configuration from Serverless function documentation
69
80
* @param config Add
70
81
*/
71
- public readFunctions ( config : IServerlessFunctionConfig [ ] ) : void {
82
+ public readFunctions ( config : Array < ServerlessFunctionConfig > ) : void {
72
83
// loop through function configurations
73
84
for ( const funcConfig of config ) {
74
85
// loop through http events
@@ -81,9 +92,9 @@ export class DefinitionGenerator {
81
92
[ `/${ httpEventConfig . path } ` ] : {
82
93
[ httpEventConfig . method . toLowerCase ( ) ] : this . getOperationFromConfig (
83
94
funcConfig . _functionName ,
84
- httpEventConfig . documentation ,
85
- ) ,
86
- } ,
95
+ httpEventConfig . documentation
96
+ )
97
+ }
87
98
} ;
88
99
89
100
// merge path configuration into main configuration
@@ -100,9 +111,12 @@ export class DefinitionGenerator {
100
111
* @param funcName
101
112
* @param documentationConfig
102
113
*/
103
- private getOperationFromConfig ( funcName : string , documentationConfig ) : IOperation {
104
- const operationObj : IOperation = {
105
- operationId : funcName ,
114
+ private getOperationFromConfig (
115
+ funcName : string ,
116
+ documentationConfig
117
+ ) : Operation {
118
+ const operationObj : Operation = {
119
+ operationId : funcName
106
120
} ;
107
121
108
122
if ( documentationConfig . summary ) {
@@ -122,7 +136,9 @@ export class DefinitionGenerator {
122
136
}
123
137
124
138
if ( documentationConfig . requestBody ) {
125
- operationObj . requestBody = this . getRequestBodiesFromConfig ( documentationConfig ) ;
139
+ operationObj . requestBody = this . getRequestBodiesFromConfig (
140
+ documentationConfig
141
+ ) ;
126
142
}
127
143
128
144
operationObj . parameters = this . getParametersFromConfig ( documentationConfig ) ;
@@ -136,54 +152,54 @@ export class DefinitionGenerator {
136
152
* Derives Path, Query and Request header parameters from Serverless documentation
137
153
* @param documentationConfig
138
154
*/
139
- private getParametersFromConfig ( documentationConfig ) : IParameterConfig [ ] {
140
- const parameters : IParameterConfig [ ] = [ ] ;
155
+ private getParametersFromConfig ( documentationConfig ) : Array < ParameterConfig > {
156
+ const parameters : Array < ParameterConfig > = [ ] ;
141
157
142
158
// Build up parameters from configuration for each parameter type
143
- for ( const type of [ ' path' , ' query' , ' header' , ' cookie' ] ) {
159
+ for ( const type of [ " path" , " query" , " header" , " cookie" ] ) {
144
160
let paramBlock ;
145
- if ( type === ' path' && documentationConfig . pathParams ) {
161
+ if ( type === " path" && documentationConfig . pathParams ) {
146
162
paramBlock = documentationConfig . pathParams ;
147
- } else if ( type === ' query' && documentationConfig . queryParams ) {
163
+ } else if ( type === " query" && documentationConfig . queryParams ) {
148
164
paramBlock = documentationConfig . queryParams ;
149
- } else if ( type === ' header' && documentationConfig . requestHeaders ) {
165
+ } else if ( type === " header" && documentationConfig . requestHeaders ) {
150
166
paramBlock = documentationConfig . requestHeaders ;
151
- } else if ( type === ' cookie' && documentationConfig . cookieParams ) {
167
+ } else if ( type === " cookie" && documentationConfig . cookieParams ) {
152
168
paramBlock = documentationConfig . cookieParams ;
153
169
} else {
154
170
continue ;
155
171
}
156
172
157
173
// Loop through each parameter in a parameter block and add parameters to array
158
174
for ( const parameter of paramBlock ) {
159
- const parameterConfig : IParameterConfig = {
175
+ const parameterConfig : ParameterConfig = {
160
176
name : parameter . name ,
161
177
in : type ,
162
- description : parameter . description || '' ,
163
- required : parameter . required || false , // Note: all path parameters must be required
178
+ description : parameter . description || "" ,
179
+ required : parameter . required || false // Note: all path parameters must be required
164
180
} ;
165
181
166
182
// if type is path, then required must be true (@see OpenAPI 3.0-RC1)
167
- if ( type === ' path' ) {
183
+ if ( type === " path" ) {
168
184
parameterConfig . required = true ;
169
- } else if ( type === ' query' ) {
170
- parameterConfig . allowEmptyValue = parameter . allowEmptyValue || false ; // OpenAPI default is false
185
+ } else if ( type === " query" ) {
186
+ parameterConfig . allowEmptyValue = parameter . allowEmptyValue || false ; // OpenAPI default is false
171
187
172
- if ( ' allowReserved' in parameter ) {
188
+ if ( " allowReserved" in parameter ) {
173
189
parameterConfig . allowReserved = parameter . allowReserved || false ;
174
190
}
175
191
}
176
192
177
- if ( ' deprecated' in parameter ) {
193
+ if ( " deprecated" in parameter ) {
178
194
parameterConfig . deprecated = parameter . deprecated ;
179
195
}
180
196
181
- if ( ' style' in parameter ) {
197
+ if ( " style" in parameter ) {
182
198
parameterConfig . style = parameter . style ;
183
199
184
200
parameterConfig . explode = parameter . explode
185
201
? parameter . explode
186
- : parameter . style === ' form' ;
202
+ : parameter . style === " form" ;
187
203
}
188
204
189
205
if ( parameter . schema ) {
@@ -211,39 +227,56 @@ export class DefinitionGenerator {
211
227
* Derives request body schemas from event documentation configuration
212
228
* @param documentationConfig
213
229
*/
214
- private getRequestBodiesFromConfig ( documentationConfig ) {
230
+ private getRequestBodiesFromConfig ( documentationConfig ) {
215
231
const requestBodies = { } ;
216
232
217
233
if ( ! documentationConfig . requestModels ) {
218
- throw new Error ( `Required requestModels in: ${ JSON . stringify ( documentationConfig , null , 2 ) } ` ) ;
234
+ throw new Error (
235
+ `Required requestModels in: ${ JSON . stringify (
236
+ documentationConfig ,
237
+ null ,
238
+ 2
239
+ ) } `
240
+ ) ;
219
241
}
220
242
221
243
// Does this event have a request model?
222
244
if ( documentationConfig . requestModels ) {
223
245
// For each request model type (Sorted by "Content-Type")
224
- for ( const requestModelType of Object . keys ( documentationConfig . requestModels ) ) {
246
+ for ( const requestModelType of Object . keys (
247
+ documentationConfig . requestModels
248
+ ) ) {
225
249
// get schema reference information
226
- const requestModel = this . config . models . filter (
227
- ( model ) => model . name === documentationConfig . requestModels [ requestModelType ] ,
228
- ) . pop ( ) ;
250
+ const requestModel = this . config . models
251
+ . filter (
252
+ model =>
253
+ model . name === documentationConfig . requestModels [ requestModelType ]
254
+ )
255
+ . pop ( ) ;
229
256
230
257
if ( requestModel ) {
231
258
const reqModelConfig = {
232
259
schema : {
233
- $ref : `#/components/schemas/${ documentationConfig . requestModels [ requestModelType ] } ` ,
234
- } ,
260
+ $ref : `#/components/schemas/${
261
+ documentationConfig . requestModels [ requestModelType ]
262
+ } `
263
+ }
235
264
} ;
236
265
237
266
this . attachExamples ( requestModel , reqModelConfig ) ;
238
267
239
- const reqBodyConfig : { content : object , description ?: string } = {
268
+ const reqBodyConfig : { content : object ; description ?: string } = {
240
269
content : {
241
- [ requestModelType ] : reqModelConfig ,
242
- } ,
270
+ [ requestModelType ] : reqModelConfig
271
+ }
243
272
} ;
244
273
245
- if ( documentationConfig . requestBody && 'description' in documentationConfig . requestBody ) {
246
- reqBodyConfig . description = documentationConfig . requestBody . description ;
274
+ if (
275
+ documentationConfig . requestBody &&
276
+ "description" in documentationConfig . requestBody
277
+ ) {
278
+ reqBodyConfig . description =
279
+ documentationConfig . requestBody . description ;
247
280
}
248
281
249
282
_ . merge ( requestBodies , reqBodyConfig ) ;
@@ -254,7 +287,7 @@ export class DefinitionGenerator {
254
287
return requestBodies ;
255
288
}
256
289
257
- private attachExamples ( target , config ) {
290
+ private attachExamples ( target , config ) {
258
291
if ( target . examples && Array . isArray ( target . examples ) ) {
259
292
_ . merge ( config , { examples : _ . cloneDeep ( target . examples ) } ) ;
260
293
} else if ( target . example ) {
@@ -266,65 +299,70 @@ export class DefinitionGenerator {
266
299
* Gets response bodies from documentation config
267
300
* @param documentationConfig
268
301
*/
269
- private getResponsesFromConfig ( documentationConfig ) {
302
+ private getResponsesFromConfig ( documentationConfig ) {
270
303
const responses = { } ;
271
304
if ( documentationConfig . methodResponses ) {
272
305
for ( const response of documentationConfig . methodResponses ) {
273
- const methodResponseConfig : { description : any , content : object , headers ?: object } = {
274
- description : (
275
- ( response . responseBody && 'description' in response . responseBody )
306
+ const methodResponseConfig : {
307
+ description : any ;
308
+ content : object ;
309
+ headers ?: object ;
310
+ } = {
311
+ description :
312
+ response . responseBody && "description" in response . responseBody
276
313
? response . responseBody . description
277
- : `Status ${ response . statusCode } Response`
278
- ) ,
279
- content : this . getResponseContent ( response . responseModels ) ,
314
+ : `Status ${ response . statusCode } Response` ,
315
+ content : this . getResponseContent ( response . responseModels )
280
316
} ;
281
317
282
318
if ( response . responseHeaders ) {
283
319
methodResponseConfig . headers = { } ;
284
320
for ( const header of response . responseHeaders ) {
285
321
methodResponseConfig . headers [ header . name ] = {
286
- description : header . description || `${ header . name } header` ,
322
+ description : header . description || `${ header . name } header`
287
323
} ;
288
324
if ( header . schema ) {
289
- methodResponseConfig . headers [ header . name ] . schema = cleanSchema ( header . schema ) ;
325
+ methodResponseConfig . headers [ header . name ] . schema = cleanSchema (
326
+ header . schema
327
+ ) ;
290
328
}
291
329
}
292
330
}
293
331
294
332
_ . merge ( responses , {
295
- [ response . statusCode ] : methodResponseConfig ,
333
+ [ response . statusCode ] : methodResponseConfig
296
334
} ) ;
297
335
}
298
336
}
299
337
300
338
return responses ;
301
339
}
302
340
303
- private getResponseContent ( response ) {
341
+ private getResponseContent ( response ) {
304
342
const content = { } ;
305
343
306
344
for ( const responseKey of Object . keys ( response ) ) {
307
- const responseModel = this . config . models . find ( ( model ) =>
308
- model . name === response [ responseKey ] ,
345
+ const responseModel = this . config . models . find (
346
+ model => model . name === response [ responseKey ]
309
347
) ;
310
348
311
349
if ( responseModel ) {
312
350
const resModelConfig = {
313
351
schema : {
314
- $ref : `#/components/schemas/${ response [ responseKey ] } ` ,
315
- } ,
352
+ $ref : `#/components/schemas/${ response [ responseKey ] } `
353
+ }
316
354
} ;
317
355
318
356
this . attachExamples ( responseModel , resModelConfig ) ;
319
357
320
- _ . merge ( content , { [ responseKey ] : resModelConfig } ) ;
358
+ _ . merge ( content , { [ responseKey ] : resModelConfig } ) ;
321
359
}
322
360
}
323
361
324
362
return content ;
325
363
}
326
364
327
- private getHttpEvents ( funcConfig ) {
328
- return funcConfig . filter ( ( event ) => event . http ? true : false ) ;
365
+ private getHttpEvents ( funcConfig ) {
366
+ return funcConfig . filter ( event => ( event . http ? true : false ) ) ;
329
367
}
330
368
}
0 commit comments