11import { dereference } from '@jdw/jst' ;
2- import * as c from 'chalk' ;
3- import * as openApiValidator from 'swagger2openapi/validate.js' ;
2+ import * as openApiValidator from 'swagger2openapi/validate' ;
43
54import * as uuid from 'uuid' ;
6- import { IParameterConfig , IServerlessFunctionConfig , IServiceDescription } from './types' ;
5+ import { IDefinition , IDefinitionConfig , IParameterConfig , IServerlessFunctionConfig } from './types' ;
76import { clone , merge } from './utils' ;
87
9- export class DocumentGenerator {
8+ export class DefinitionGenerator {
109 // The OpenAPI version we currently validate against
11- private openapiVersion = '3.0.0-RC1' ;
10+ public version = '3.0.0-RC1' ;
1211
1312 // Base configuration object
14- private config = {
15- openapi : this . openapiVersion ,
16- description : '' ,
17- version : '0.0.0' ,
18- title : '' ,
19- paths : { } ,
20- components : {
21- schemas : { } ,
22- } ,
13+ public definition = < IDefinition > {
14+ openapi : this . version ,
15+ components : { } ,
2316 } ;
2417
25- private serviceDescriptor : IServiceDescription ;
18+ public config : IDefinitionConfig ;
2619
2720 /**
2821 * Constructor
2922 * @param serviceDescriptor IServiceDescription
3023 */
31- constructor ( serviceDescriptor : IServiceDescription ) {
32- this . serviceDescriptor = clone ( serviceDescriptor ) ;
33-
34- merge ( this . config , {
35- openapi : this . openapiVersion ,
36- servers : [ ] ,
37- info : {
38- title : serviceDescriptor . summary || '' ,
39- description : serviceDescriptor . description || '' ,
40- version : serviceDescriptor . version || uuid . v4 ( ) ,
41- } ,
24+ constructor ( config : IDefinitionConfig ) {
25+ this . config = clone ( config ) ;
26+ }
27+
28+ public parse ( ) {
29+ const {
30+ title = '' ,
31+ description = '' ,
32+ version = uuid . v4 ( ) ,
33+ models,
34+ } = this . config ;
35+
36+ merge ( this . definition , {
37+ openapi : this . version ,
38+ info : { title, description, version } ,
4239 paths : { } ,
4340 components : {
4441 schemas : { } ,
4542 securitySchemes : { } ,
4643 } ,
4744 } ) ;
4845
49- for ( const model of serviceDescriptor . models ) {
50- this . config . components . schemas [ model . name ] = this . cleanSchema ( dereference ( model . schema ) ) ;
46+ if ( models ) {
47+ for ( const model of models ) {
48+ this . definition . components . schemas [ model . name ] = this . cleanSchema (
49+ dereference ( model . schema ) ,
50+ ) ;
51+ }
5152 }
53+
54+ return this ;
5255 }
5356
54- public generate ( ) {
55- const result : any = { } ;
56- process . stdout . write ( ` ${ c . bold . yellow ( '[VALIDATION]' ) } Validating OpenAPI generated output\n` ) ;
57+ public validate ( ) : { valid : boolean , context : string [ ] , warnings : any [ ] , error ?: any [ ] } {
58+ const payload : any = { } ;
59+
5760 try {
58- openApiValidator . validateSync ( this . config , result ) ;
59- process . stdout . write ( `${ c . bold . green ( '[VALIDATION]' ) } OpenAPI valid: ${ c . bold . green ( 'true' ) } \n\n` ) ;
60- return this . config ;
61- } catch ( e ) {
62- process . stdout . write (
63- `${ c . bold . red ( '[VALIDATION]' ) } Failed to validate OpenAPI document: \n\n${ c . yellow ( e . message ) } \n\n` +
64- `${ c . bold . green ( 'Path:' ) } ${ result . context . pop ( ) } \n` ,
65- ) ;
66- throw new Error ( 'Failed to validate OpenAPI document' ) ;
61+ openApiValidator . validateSync ( this . definition , payload ) ;
62+ } catch ( error ) {
63+ payload . error = JSON . parse ( error . message . replace ( / ^ F a i l e d O p e n A P I 3 s c h e m a v a l i d a t i o n : / , '' ) ) ;
6764 }
65+
66+ return payload ;
6867 }
6968
7069 /**
7170 * Add Paths to OpenAPI Configuration from Serverless function documentation
7271 * @param config Add
7372 */
74- public addPathsFromFunctionConfig ( config : IServerlessFunctionConfig [ ] ) : void {
73+ public readFunctions ( config : IServerlessFunctionConfig [ ] ) : void {
7574 // loop through function configurations
7675 for ( const funcConfig of config ) {
7776 // loop through http events
@@ -93,7 +92,7 @@ export class DocumentGenerator {
9392 } ,
9493 } ;
9594 // merge path configuration into main configuration
96- merge ( this . config . paths , pathConfig ) ;
95+ merge ( this . definition . paths , pathConfig ) ;
9796 }
9897 }
9998 }
@@ -170,7 +169,6 @@ export class DocumentGenerator {
170169 : parameter . style === 'form' ;
171170 }
172171
173- // console.log(parameter);
174172 if ( parameter . schema ) {
175173 parameterConfig . schema = this . cleanSchema ( parameter . schema ) ;
176174 }
@@ -181,7 +179,6 @@ export class DocumentGenerator {
181179 parameterConfig . examples = parameter . examples ;
182180 }
183181
184- // Add parameter config to parameters array
185182 parameters . push ( parameterConfig ) ;
186183 }
187184 }
@@ -201,7 +198,7 @@ export class DocumentGenerator {
201198 // For each request model type (Sorted by "Content-Type")
202199 for ( const requestModelType of Object . keys ( documentationConfig . requestModels ) ) {
203200 // get schema reference information
204- const requestModel = this . serviceDescriptor . models . filter (
201+ const requestModel = this . config . models . filter (
205202 ( model ) => model . name === documentationConfig . requestModels [ requestModelType ] ,
206203 ) . pop ( ) ;
207204
@@ -278,7 +275,7 @@ export class DocumentGenerator {
278275 private getResponseContent ( response ) {
279276 const content = { } ;
280277 for ( const responseKey of Object . keys ( response ) ) {
281- const responseModel = this . serviceDescriptor . models . filter (
278+ const responseModel = this . config . models . filter (
282279 ( model ) => model . name === response [ responseKey ] ,
283280 ) . pop ( ) ;
284281 if ( responseModel ) {
@@ -295,7 +292,7 @@ export class DocumentGenerator {
295292 merge ( content , { [ responseKey ] : resModelConfig } ) ;
296293 }
297294 }
298- // console.log(content);
295+
299296 return content ;
300297 }
301298
0 commit comments