1
- import { JSONSchema7 } from 'json-schema' ;
2
1
// tslint:disable-next-line no-submodule-imports
3
2
import { validateSync as openApiValidatorSync } from 'swagger2openapi/validate' ;
4
3
import * as uuid from 'uuid' ;
5
4
6
5
import { IDefinition , IDefinitionConfig , IOperation , IParameterConfig , IServerlessFunctionConfig } from './types' ;
7
- import { clone , isIterable , merge , omit } from './utils' ;
6
+ import { cleanSchema } from './utils' ;
7
+ import { parseModels } from './SchemaBuilder' ;
8
+ import _ = require( 'lodash' ) ;
8
9
9
10
export class DefinitionGenerator {
10
11
// The OpenAPI version we currently validate against
@@ -18,23 +19,25 @@ export class DefinitionGenerator {
18
19
19
20
public config : IDefinitionConfig ;
20
21
22
+ private root : string ;
23
+
21
24
/**
22
25
* Constructor
23
- * @param serviceDescriptor IServiceDescription
24
26
*/
25
- constructor ( config : IDefinitionConfig ) {
26
- this . config = clone ( config ) ;
27
+ constructor ( config : IDefinitionConfig , root : string ) {
28
+ this . config = _ . cloneDeep ( config ) ;
29
+ this . root = root ;
27
30
}
28
31
29
- public parse ( ) {
32
+ public async parse ( ) {
30
33
const {
31
34
title = '' ,
32
35
description = '' ,
33
36
version = uuid . v4 ( ) ,
34
37
models,
35
38
} = this . config ;
36
39
37
- merge ( this . definition , {
40
+ _ . merge ( this . definition , {
38
41
openapi : this . version ,
39
42
info : { title, description, version } ,
40
43
paths : { } ,
@@ -44,24 +47,7 @@ export class DefinitionGenerator {
44
47
} ,
45
48
} ) ;
46
49
47
- if ( isIterable ( models ) ) {
48
- for ( const model of models ) {
49
- if ( ! model . schema ) {
50
- continue ;
51
- }
52
-
53
- for ( const definitionName of Object . keys ( model . schema . definitions || { } ) ) {
54
- const definition = model . schema . definitions [ definitionName ] ;
55
- if ( typeof definition !== 'boolean' ) {
56
- this . definition . components . schemas [ definitionName ] = this . cleanSchema ( this . updateReferences ( definition ) ) ;
57
- }
58
- }
59
-
60
- const schemaWithoutDefinitions = omit ( model . schema , [ 'definitions' ] ) ;
61
-
62
- this . definition . components . schemas [ model . name ] = this . cleanSchema ( this . updateReferences ( schemaWithoutDefinitions ) ) ;
63
- }
64
- }
50
+ this . definition . components . schemas = await parseModels ( models , this . root ) ;
65
51
66
52
return this ;
67
53
}
@@ -101,49 +87,10 @@ export class DefinitionGenerator {
101
87
} ;
102
88
103
89
// merge path configuration into main configuration
104
- merge ( this . definition . paths , pathConfig ) ;
105
- }
106
- }
107
- }
108
- }
109
-
110
- /**
111
- * Cleans schema objects to make them OpenAPI compatible
112
- * @param schema JSON Schema Object
113
- */
114
- private cleanSchema ( schema ) {
115
- // Clone the schema for manipulation
116
- const cleanedSchema = clone ( schema ) ;
117
-
118
- // Strip $schema from schemas
119
- if ( cleanedSchema . $schema ) {
120
- delete cleanedSchema . $schema ;
121
- }
122
-
123
- // Return the cleaned schema
124
- return cleanedSchema ;
125
- }
126
-
127
- /**
128
- * Walks through the schema object recursively and updates references to point to openapi's components
129
- * @param schema JSON Schema Object
130
- */
131
- private updateReferences ( schema : JSONSchema7 ) : JSONSchema7 {
132
- const cloned = clone ( schema ) ;
133
-
134
- if ( cloned . $ref ) {
135
- cloned . $ref = cloned . $ref . replace ( '#/definitions' , '#/components/schemas' ) ;
136
- } else {
137
- for ( const key of Object . getOwnPropertyNames ( cloned ) ) {
138
- const value = cloned [ key ] ;
139
-
140
- if ( typeof value === 'object' ) {
141
- cloned [ key ] = this . updateReferences ( value ) ;
90
+ _ . merge ( this . definition . paths , pathConfig ) ;
142
91
}
143
92
}
144
93
}
145
-
146
- return cloned ;
147
94
}
148
95
149
96
/**
@@ -240,7 +187,7 @@ export class DefinitionGenerator {
240
187
}
241
188
242
189
if ( parameter . schema ) {
243
- parameterConfig . schema = this . cleanSchema ( parameter . schema ) ;
190
+ parameterConfig . schema = cleanSchema ( parameter . schema ) ;
244
191
}
245
192
246
193
if ( parameter . example ) {
@@ -299,7 +246,7 @@ export class DefinitionGenerator {
299
246
reqBodyConfig . description = documentationConfig . requestBody . description ;
300
247
}
301
248
302
- merge ( requestBodies , reqBodyConfig ) ;
249
+ _ . merge ( requestBodies , reqBodyConfig ) ;
303
250
}
304
251
}
305
252
}
@@ -309,9 +256,9 @@ export class DefinitionGenerator {
309
256
310
257
private attachExamples ( target , config ) {
311
258
if ( target . examples && Array . isArray ( target . examples ) ) {
312
- merge ( config , { examples : clone ( target . examples ) } ) ;
259
+ _ . merge ( config , { examples : _ . cloneDeep ( target . examples ) } ) ;
313
260
} else if ( target . example ) {
314
- merge ( config , { example : clone ( target . example ) } ) ;
261
+ _ . merge ( config , { example : _ . cloneDeep ( target . example ) } ) ;
315
262
}
316
263
}
317
264
@@ -339,12 +286,12 @@ export class DefinitionGenerator {
339
286
description : header . description || `${ header . name } header` ,
340
287
} ;
341
288
if ( header . schema ) {
342
- methodResponseConfig . headers [ header . name ] . schema = this . cleanSchema ( header . schema ) ;
289
+ methodResponseConfig . headers [ header . name ] . schema = cleanSchema ( header . schema ) ;
343
290
}
344
291
}
345
292
}
346
293
347
- merge ( responses , {
294
+ _ . merge ( responses , {
348
295
[ response . statusCode ] : methodResponseConfig ,
349
296
} ) ;
350
297
}
@@ -370,7 +317,7 @@ export class DefinitionGenerator {
370
317
371
318
this . attachExamples ( responseModel , resModelConfig ) ;
372
319
373
- merge ( content , { [ responseKey ] : resModelConfig } ) ;
320
+ _ . merge ( content , { [ responseKey ] : resModelConfig } ) ;
374
321
}
375
322
}
376
323
0 commit comments