1- import { JSONSchema7 } from 'json-schema' ;
21// tslint:disable-next-line no-submodule-imports
32import { validateSync as openApiValidatorSync } from 'swagger2openapi/validate' ;
43import * as uuid from 'uuid' ;
54
65import { 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' ) ;
89
910export class DefinitionGenerator {
1011 // The OpenAPI version we currently validate against
@@ -18,23 +19,25 @@ export class DefinitionGenerator {
1819
1920 public config : IDefinitionConfig ;
2021
22+ private root : string ;
23+
2124 /**
2225 * Constructor
23- * @param serviceDescriptor IServiceDescription
2426 */
25- constructor ( config : IDefinitionConfig ) {
26- this . config = clone ( config ) ;
27+ constructor ( config : IDefinitionConfig , root : string ) {
28+ this . config = _ . cloneDeep ( config ) ;
29+ this . root = root ;
2730 }
2831
29- public parse ( ) {
32+ public async parse ( ) {
3033 const {
3134 title = '' ,
3235 description = '' ,
3336 version = uuid . v4 ( ) ,
3437 models,
3538 } = this . config ;
3639
37- merge ( this . definition , {
40+ _ . merge ( this . definition , {
3841 openapi : this . version ,
3942 info : { title, description, version } ,
4043 paths : { } ,
@@ -44,24 +47,7 @@ export class DefinitionGenerator {
4447 } ,
4548 } ) ;
4649
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 ) ;
6551
6652 return this ;
6753 }
@@ -101,49 +87,10 @@ export class DefinitionGenerator {
10187 } ;
10288
10389 // 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 ) ;
14291 }
14392 }
14493 }
145-
146- return cloned ;
14794 }
14895
14996 /**
@@ -240,7 +187,7 @@ export class DefinitionGenerator {
240187 }
241188
242189 if ( parameter . schema ) {
243- parameterConfig . schema = this . cleanSchema ( parameter . schema ) ;
190+ parameterConfig . schema = cleanSchema ( parameter . schema ) ;
244191 }
245192
246193 if ( parameter . example ) {
@@ -299,7 +246,7 @@ export class DefinitionGenerator {
299246 reqBodyConfig . description = documentationConfig . requestBody . description ;
300247 }
301248
302- merge ( requestBodies , reqBodyConfig ) ;
249+ _ . merge ( requestBodies , reqBodyConfig ) ;
303250 }
304251 }
305252 }
@@ -309,9 +256,9 @@ export class DefinitionGenerator {
309256
310257 private attachExamples ( target , config ) {
311258 if ( target . examples && Array . isArray ( target . examples ) ) {
312- merge ( config , { examples : clone ( target . examples ) } ) ;
259+ _ . merge ( config , { examples : _ . cloneDeep ( target . examples ) } ) ;
313260 } else if ( target . example ) {
314- merge ( config , { example : clone ( target . example ) } ) ;
261+ _ . merge ( config , { example : _ . cloneDeep ( target . example ) } ) ;
315262 }
316263 }
317264
@@ -339,12 +286,12 @@ export class DefinitionGenerator {
339286 description : header . description || `${ header . name } header` ,
340287 } ;
341288 if ( header . schema ) {
342- methodResponseConfig . headers [ header . name ] . schema = this . cleanSchema ( header . schema ) ;
289+ methodResponseConfig . headers [ header . name ] . schema = cleanSchema ( header . schema ) ;
343290 }
344291 }
345292 }
346293
347- merge ( responses , {
294+ _ . merge ( responses , {
348295 [ response . statusCode ] : methodResponseConfig ,
349296 } ) ;
350297 }
@@ -370,7 +317,7 @@ export class DefinitionGenerator {
370317
371318 this . attachExamples ( responseModel , resModelConfig ) ;
372319
373- merge ( content , { [ responseKey ] : resModelConfig } ) ;
320+ _ . merge ( content , { [ responseKey ] : resModelConfig } ) ;
374321 }
375322 }
376323
0 commit comments