1 | 1 | const ParserInterface = require('../ParserInterface'), |
|
2 | _ = require('lodash'), |
||
3 | ParametersParser = require('./ParametersParser'), |
||
4 | ResponseParser = require('./ResponseParser') |
||
5 | |||
6 | /** |
||
7 | * @ignore _ |
||
8 | */ |
||
9 | |||
10 | /** |
||
11 | * Methods parser for swagger 2.0 |
||
12 | * @class MethodsParser |
||
13 | * |
||
14 | * @property {Object} methods Original methods data |
||
15 | * @property {ResponseParser|undefined} respParser Response parser object |
||
16 | * @property {ParametersParser|undefined} paramParser Parameters parser object |
||
17 | * @property {SecuritySchemesParser} securityParser Security parser |
||
18 | * @property {ParameterParserOptionsObject} parameterParserConfig Parameters parser config object |
||
19 | * @property {Array.<MethodConfigObject>} parseMethods Parsed methods |
||
20 | * @property {Array.<String>.<MethodConfigObject>} methodsGroup Grouping parsed methods |
||
21 | * @property {String} packageName Package name |
||
22 | * @property {String} className Class name |
||
23 | * @property {String} moduleName Module name |
||
24 | */ |
||
25 | class MethodsParser extends ParserInterface { |
||
26 | constructor (methods, securityParser, definitions, options) { |
||
27 | 2 | super() |
|
28 | |||
29 | 2 | options = options || {} |
|
30 | |||
31 | 2 | this.parameterParserConfig = options.parameterParserConfig |
|
32 | // this.respParserConfig = options.respParserConfig |
||
33 | |||
34 | 2 | this.moduleName = options.moduleName |
|
35 | 2 | this.className = options.className |
|
36 | 2 | this.packageName = options.packageName |
|
37 | |||
38 | 2 | this.securityParser = securityParser |
|
39 | 2 | this.parseMethods = [] |
|
40 | 2 | this.definitions = definitions |
|
41 | 2 | this.methods = methods |
|
42 | 2 | this.modelPath = options.modelPath |
|
43 | 2 | this.docsPath = options.docsPath |
|
44 | 2 | this.methodsGroup = {} |
|
45 | } |
||
46 | |||
47 | _iterateMethod (config, uri, definitions) { |
||
48 | 2 | let _self = this |
|
49 | 2 | _.each(config, (methodConfig, method) => { |
|
50 | 2 | method = _.upperCase(method) |
|
51 | 2 | let nextMethod = { |
|
52 | path : uri, |
||
53 | method : method, |
||
54 | methodName : methodConfig.operationId ? MethodsParser._normalizeMethodName(methodConfig.operationId) : MethodsParser._getPathToMethodName(config, method, uri), |
||
55 | tags : methodConfig.tags, |
||
56 | summary : methodConfig.summary, |
||
57 | description : methodConfig.description, |
||
58 | externalDocs : methodConfig.externalDocs, |
||
59 | operationId : methodConfig.operationId, |
||
60 | produces : methodConfig.produces, |
||
61 | consumes : methodConfig.consumes, |
||
62 | schemes : methodConfig.schemes, |
||
63 | isDeprecated : methodConfig.deprecated || false, |
||
64 | security : methodConfig.security, |
||
65 | isSecure : typeof methodConfig.security !== 'undefined', |
||
66 | isGET : method === 'GET', |
||
67 | isPUT : method === 'PUT', |
||
68 | isOPTIONS : method === 'OPTIONS', |
||
69 | isDELETE : method === 'DELETE', |
||
70 | isHEAD : method === 'HEAD', |
||
71 | isPOST : method === 'POST', |
||
72 | isTRACE : method === 'TRACE', |
||
73 | isCONNECT : method === 'CONNECT', |
||
74 | isPATCH : method === 'PATCH', |
||
75 | definitions : this.definitions || {}, |
||
76 | headers : [], |
||
77 | parameters : [], |
||
78 | bodyParams : [], |
||
79 | queryParams : [], |
||
80 | formDataParams: [], |
||
81 | enums : [], |
||
82 | pathParams : [], |
||
83 | modelPath : _self.modelPath, |
||
84 | docsPath : _self.docsPath |
||
85 | } |
||
86 | |||
87 | 2 | if (_.size(methodConfig.parameters)) { |
|
88 | 1 | _self.paramParser = new ParametersParser(methodConfig.parameters, _self.parameterParserConfig) |
|
89 | 1 | nextMethod.parameters = _self.paramParser.parse() |
|
90 | 1 | nextMethod.headers = _self.paramParser.headers |
|
91 | 1 | nextMethod.enums = _self.paramParser.enums |
|
92 | 1 | nextMethod.bodyParams = _self.paramParser.bodys |
|
93 | 1 | nextMethod.queryParams = _self.paramParser.querys |
|
94 | 1 | nextMethod.formDataParams = _self.paramParser.formDatas |
|
95 | 1 | nextMethod.pathParams = _self.paramParser.paths |
|
96 | } |
||
97 | |||
98 | 2 | if (_.size(methodConfig.responses)) { |
|
99 | _self.respParser = new ResponseParser(methodConfig.responses, this.modelPath) |
||
100 | nextMethod.responses = _self.respParser.parse() |
||
101 | } |
||
102 | |||
103 | 2 | nextMethod = _self._addSecurityParameters(nextMethod) |
|
104 | 2 | nextMethod.packageName = _self.packageName |
|
105 | 2 | nextMethod.className = _self.className |
|
106 | 2 | nextMethod.moduleName = _self.moduleName |
|
107 | 2 | nextMethod.docsPath = _self.docsPath |
|
108 | 2 | nextMethod.modelPath = _self.modelPath |
|
109 | 2 | nextMethod.definitions = _self.definitions |
|
110 | |||
111 | 2 | if (nextMethod.tags) { |
|
112 | 2 | let tags = nextMethod.tags |
|
113 | 2 | for (let i = 0; i < tags.length; i++) { |
|
114 | 2 | if (typeof this.methodsGroup[tags[i]] === 'undefined') { |
|
115 | 2 | this.methodsGroup[tags[i]] = [] |
|
116 | } |
||
117 | |||
118 | 2 | this.methodsGroup[tags[i]].push(nextMethod) |
|
119 | } |
||
120 | } |
||
121 | |||
122 | 2 | _self.parseMethods.push(nextMethod) |
|
123 | |||
124 | }) |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Normalize method name |
||
129 | * |
||
130 | * @return {string} |
||
131 | * |
||
132 | * @private |
||
133 | */ |
||
134 | static _normalizeMethodName (id) { |
||
135 | /* eslint-disable */ |
||
136 | return id.replace(/\.|\-|\{|\}/g, '_').split(' ').join('_') |
||
137 | /* eslint-enable */ |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * |
||
142 | * @param {Object} opts |
||
143 | * @param m |
||
144 | * @param path |
||
145 | * @return {*} |
||
146 | * @private |
||
147 | */ |
||
148 | static _getPathToMethodName (opts, m, path) { |
||
149 | 4 | if (path === '/' || path === '') { |
|
150 | return m |
||
151 | } |
||
152 | |||
153 | // clean url path for requests ending with '/' |
||
154 | 2 | let cleanPath = path.replace(/\/$/, '') |
|
155 | |||
156 | 2 | let segments = cleanPath.split('/').slice(1) |
|
157 | 2 | segments = _.transform(segments, function (result, segment) { |
|
158 | 6 | if (segment[0] === '{' && segment[segment.length - 1] === '}') { |
|
159 | segment = 'by' + segment[1].toUpperCase() + segment.substring(2, segment.length - 1) |
||
160 | } |
||
161 | 6 | result.push(segment) |
|
162 | }) |
||
163 | 2 | let result = _.camelCase(segments.join('-')) |
|
164 | 2 | return m.toLowerCase() + result[0].toUpperCase() + result.substring(1) |
|
165 | } |
||
166 | |||
167 | /** |
||
168 | * Add security headers & params |
||
169 | * |
||
170 | * @param {MethodConfigObject} methodConfig |
||
171 | * |
||
172 | * @return {MethodConfigObject} |
||
173 | * @private |
||
174 | */ |
||
175 | _addSecurityParameters (methodConfig) { |
||
176 | 2 | let headers = this.securityParser.getHeadersForRequest(methodConfig.security), |
|
177 | parameters = this.securityParser.getParametersForRequest(methodConfig.security) |
||
178 | |||
179 | 2 | if (_.size(headers)) { |
|
180 | _.each(headers, (headConfig) => { |
||
181 | 2 | if (typeof headConfig === 'undefined') { |
|
182 | return |
||
183 | } |
||
184 | methodConfig.headers.push(headConfig) |
||
185 | }) |
||
186 | } |
||
187 | |||
188 | 2 | if (_.size(parameters)) { |
|
189 | _.each(parameters, (paramConfig, index) => { |
||
0 ignored issues
–
show
|
|||
190 | 2 | if (typeof paramConfig === 'undefined') { |
|
191 | return |
||
192 | } |
||
193 | methodConfig.parameters.push(paramConfig) |
||
194 | 2 | if (paramConfig.in) { |
|
195 | 2 | if (typeof methodConfig.parameters[paramConfig.in + 'Params'] === 'undefined') { |
|
196 | throw new Error('Unsupported operand. Send issue please about error') |
||
197 | } |
||
198 | methodConfig.parameters[paramConfig.in + 'Params'].push(paramConfig) |
||
199 | } |
||
200 | }) |
||
201 | } |
||
202 | |||
203 | 2 | return methodConfig |
|
204 | } |
||
205 | |||
206 | /** |
||
207 | * Parse methods data |
||
208 | * |
||
209 | * @property {Array.<Swagger20OperationDefinition>} definitions |
||
210 | * |
||
211 | * @return {Array.<MethodConfigObject>} |
||
212 | */ |
||
213 | parse (definitions) { |
||
214 | 2 | let _self = this |
|
215 | |||
216 | 2 | _.each(this.methods, (config, uri) => { |
|
217 | 2 | _self._iterateMethod(config, uri, definitions) |
|
218 | }) |
||
219 | |||
220 | 2 | return this.parseMethods |
|
221 | } |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * @ignore module.exports |
||
226 | * @ignore exports |
||
227 | */ |
||
228 | module.exports = MethodsParser |
This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.