1
- import { merge } from 'lutils' ;
1
+ import { dereference } from '@jdw/jst' ;
2
+ import { clone , merge } from 'lutils' ;
3
+ import uuid from 'uuid' ;
2
4
3
5
type ServiceDescriptionType = {
6
+ title : string ,
4
7
description : string ,
5
8
version : string ,
6
- summary : string ,
7
9
termsOfService ?: string ,
8
10
contact ?: {
9
11
name ?: string ,
@@ -14,68 +16,178 @@ type ServiceDescriptionType = {
14
16
name : string ,
15
17
url : string ,
16
18
} ,
19
+ models ?: any [ ] ,
17
20
} ;
18
21
19
22
export default class DocumentGenerator {
20
- private config : ServiceDescriptionType = {
23
+ private config = {
21
24
description : '' ,
22
25
version : '0.0.0' ,
23
- summary : '' ,
26
+ title : '' ,
27
+ paths : { } ,
28
+ components : {
29
+ schemas : { } ,
30
+ } ,
24
31
} ;
25
32
26
33
constructor ( serviceDescriptor : ServiceDescriptionType ) {
27
- merge ( [ this . config , serviceDescriptor ] , { depth : 32 } ) ;
34
+ this . config = this . process ( clone ( serviceDescriptor , { depth : 100 } ) ) ;
35
+ // merge([this.config, serviceDescriptor], { depth: 32 });
36
+ // console.log(this.config);
28
37
}
29
38
30
39
public generate ( ) {
31
- return {
32
- openapi : '3.0.0-RC0' ,
33
- servers : this . getServers ( ) ,
34
- info : {
35
- description : this . getDescription ( ) ,
36
- version : this . getVersion ( ) ,
37
- title : this . getTitle ( ) ,
38
- termsOfService : this . getTermsOfService ( ) ,
39
- } ,
40
- tags : this . getTags ( ) ,
41
- paths : { } ,
42
- components : {
43
- schemas : this . getSchemas ( ) ,
44
- requestBodies : { } ,
45
- responses : { } ,
46
- parameters : { } ,
47
- examples : { } ,
48
- securitySchemes : { } ,
49
- } ,
50
- } ;
40
+ return this . config ;
51
41
}
52
42
53
- private getDescription ( ) {
54
- return this . config . description ;
43
+ public addPathsFromFunctionConfig ( config ) {
44
+ // loop through function configurations
45
+ for ( const funcConfig of config ) {
46
+ // loop through http events
47
+ for ( const httpEvent of this . getHttpEvents ( funcConfig . events ) ) {
48
+ const httpEventConfig = httpEvent . http ;
49
+ if ( httpEventConfig . documentation ) {
50
+ const documentationConfig = httpEventConfig . documentation ;
51
+ // console.log(documentationConfig);
52
+ const pathConfig = {
53
+ [ `/${ httpEventConfig . path } ` ] : {
54
+ [ httpEventConfig . method ] : {
55
+ operationId : funcConfig . _functionName ,
56
+ summary : documentationConfig . summary || '' ,
57
+ description : documentationConfig . description || '' ,
58
+ responses : this . getResponsesFromConfig ( documentationConfig ) ,
59
+ parameters : this . getParametersFromConfig ( documentationConfig ) ,
60
+ requestBody : this . getRequestBodiesFromConfig ( documentationConfig ) ,
61
+ } ,
62
+ } ,
63
+ } ;
64
+ merge ( [ this . config . paths , pathConfig ] , { depth : 100 } ) ;
65
+ }
66
+ }
67
+ }
68
+ // console.log(JSON.stringify(this.config.paths, null, 2));
55
69
}
56
70
57
- private getSchemas ( ) {
58
- return { } ;
59
- }
71
+ private getParametersFromConfig ( documentationConfig ) {
72
+ const parameters = [ ] ;
73
+ // Path Parameters
74
+ if ( documentationConfig . pathParams ) {
75
+ for ( const parameter of documentationConfig . pathParams ) {
76
+ parameters . push ( {
77
+ name : parameter . name ,
78
+ in : 'path' ,
79
+ description : parameter . description ,
80
+ required : true , // Note: all path parameters must be required
81
+ schema : parameter . schema || { } ,
82
+ example : parameter . example || null ,
83
+ } ) ;
84
+ }
85
+ }
86
+ // Query Parameters
87
+ if ( documentationConfig . queryParams ) {
88
+ for ( const parameter of documentationConfig . queryParams ) {
89
+ parameters . push ( {
90
+ name : parameter . name ,
91
+ in : 'query' ,
92
+ description : parameter . description ,
93
+ required : parameter . required || false , // Note: all path parameters must be required
94
+ schema : parameter . schema || { } ,
95
+ example : parameter . example || null ,
96
+ } ) ;
97
+ }
98
+ }
99
+
100
+ // Request Header Parameters
101
+ if ( documentationConfig . requestHeaders ) {
102
+ for ( const parameter of documentationConfig . requestHeaders ) {
103
+ parameters . push ( {
104
+ name : parameter . name ,
105
+ in : 'header' ,
106
+ description : parameter . description ,
107
+ required : parameter . required || false , // Note: all path parameters must be required
108
+ schema : parameter . schema || { } ,
109
+ example : parameter . example || null ,
110
+ } ) ;
111
+ }
112
+ }
60
113
61
- private getServers ( ) {
62
- return [ { url : 'nothing' } ] ;
114
+ return parameters ;
63
115
}
64
116
65
- private getTermsOfService ( ) {
66
- return this . config . termsOfService ;
117
+ private getRequestBodiesFromConfig ( documentationConfig ) {
118
+ const requestBodies = { } ;
119
+ if ( documentationConfig . requestModels ) {
120
+ for ( const requestModelType of Object . keys ( documentationConfig . requestModels ) ) {
121
+ merge ( [ requestBodies , {
122
+ [ requestModelType ] : {
123
+ schema : {
124
+ $ref : `#/components/schemas/${ documentationConfig . requestModels [ requestModelType ] } ` ,
125
+ } ,
126
+ } ,
127
+ } ] , { depth : 100 } ) ;
128
+ }
129
+ }
130
+
131
+ return requestBodies ;
67
132
}
68
133
69
- private getTags ( ) {
70
- return [ ] ;
134
+ private getResponsesFromConfig ( documentationConfig ) {
135
+ const responses = { } ;
136
+ if ( documentationConfig . methodResponses ) {
137
+ for ( const response of documentationConfig . methodResponses ) {
138
+ merge ( [ responses , {
139
+ [ response . statusCode ] : {
140
+ description : response . description || `Status ${ response . statusCode } Response` ,
141
+ content : this . getResponseContent ( response . responseModels ) ,
142
+ } ,
143
+ } ] , { depth : 100 } ) ;
144
+ }
145
+ }
146
+
147
+ return responses ;
71
148
}
72
149
73
- private getTitle ( ) {
74
- return this . config . summary ;
150
+ private getResponseContent ( response ) {
151
+ const content = { } ;
152
+ for ( const responseKey of Object . keys ( response ) ) {
153
+ merge ( content , { [ responseKey ] : {
154
+ schema : {
155
+ $ref : `#/components/schemas/${ response [ responseKey ] } ` ,
156
+ } ,
157
+ } } ) ;
158
+ }
159
+ // console.log(content);
160
+ return content ;
75
161
}
76
162
77
- private getVersion ( ) {
78
- return this . config . version ;
163
+ private getHttpEvents ( funcConfig ) {
164
+ return funcConfig . filter ( ( event ) => event . http ? true : false ) ;
79
165
}
80
166
167
+ private process ( serviceDescriptor ) : any {
168
+ const configObject = {
169
+ openapi : '3.0.0-RC0' ,
170
+ servers : [ ] ,
171
+ info : {
172
+ title : serviceDescriptor . summary || '' ,
173
+ description : serviceDescriptor . description || '' ,
174
+ version : serviceDescriptor . version || uuid . v4 ( ) ,
175
+ } ,
176
+ paths : { } ,
177
+ components : {
178
+ schemas : { } ,
179
+ requestBodies : { } ,
180
+ responses : { } ,
181
+ parameters : { } ,
182
+ examples : { } ,
183
+ securitySchemes : { } ,
184
+ } ,
185
+ } ;
186
+
187
+ for ( const model of serviceDescriptor . models ) {
188
+ configObject . components . schemas [ model . name ] = dereference ( model . schema ) ;
189
+ }
190
+
191
+ return configObject ;
192
+ }
81
193
}
0 commit comments