1- import { merge } from 'lutils' ;
1+ import { dereference } from '@jdw/jst' ;
2+ import { clone , merge } from 'lutils' ;
3+ import uuid from 'uuid' ;
24
35type ServiceDescriptionType = {
6+ title : string ,
47 description : string ,
58 version : string ,
6- summary : string ,
79 termsOfService ?: string ,
810 contact ?: {
911 name ?: string ,
@@ -14,68 +16,178 @@ type ServiceDescriptionType = {
1416 name : string ,
1517 url : string ,
1618 } ,
19+ models ?: any [ ] ,
1720} ;
1821
1922export default class DocumentGenerator {
20- private config : ServiceDescriptionType = {
23+ private config = {
2124 description : '' ,
2225 version : '0.0.0' ,
23- summary : '' ,
26+ title : '' ,
27+ paths : { } ,
28+ components : {
29+ schemas : { } ,
30+ } ,
2431 } ;
2532
2633 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);
2837 }
2938
3039 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 ;
5141 }
5242
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));
5569 }
5670
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+ }
60113
61- private getServers ( ) {
62- return [ { url : 'nothing' } ] ;
114+ return parameters ;
63115 }
64116
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 ;
67132 }
68133
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 ;
71148 }
72149
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 ;
75161 }
76162
77- private getVersion ( ) {
78- return this . config . version ;
163+ private getHttpEvents ( funcConfig ) {
164+ return funcConfig . filter ( ( event ) => event . http ? true : false ) ;
79165 }
80166
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+ }
81193}
0 commit comments