@@ -14,7 +14,8 @@ let _ = require('lodash'),
14
14
trace : true
15
15
} ,
16
16
17
- _generateTreeFromPaths = function ( openapi , { includeDeprecated } ) {
17
+
18
+ _generateTreeFromPathsV2 = function ( openapi , { includeDeprecated } ) {
18
19
/**
19
20
* We will create a unidirectional graph
20
21
*/
@@ -26,13 +27,32 @@ let _ = require('lodash'),
26
27
meta : { }
27
28
} ) ;
28
29
29
- _ . forEach ( openapi . paths , function ( methods , path ) {
30
- let pathSplit = path === '/' ? [ path ] : _ . compact ( path . split ( '/' ) ) ;
30
+ /**
31
+ * Get all the paths sorted in desc order.
32
+ */
33
+ const paths = Object . keys ( openapi . paths ) . sort ( ( a , b ) => {
34
+ return ( a > b ? - 1 : 1 ) ;
35
+ } ) ;
31
36
32
- // if after path split we just have one entry
33
- // that means no folders need to be generated.
34
- // check for all the methods inside it and expand.
37
+ if ( _ . isEmpty ( paths ) ) {
38
+ return tree ;
39
+ }
40
+
41
+ _ . forEach ( paths , function ( completePath ) {
42
+ let pathSplit = completePath === '/' ? [ completePath ] : _ . compact ( completePath . split ( '/' ) ) ;
43
+
44
+ /**
45
+ * /user
46
+ * /team
47
+ * /hi
48
+ * /bye
49
+ *
50
+ * In this scenario, always create a base folder for the path
51
+ * and then add and link the request inside the created folder.
52
+ */
35
53
if ( pathSplit . length === 1 ) {
54
+ let methods = openapi . paths [ completePath ] ;
55
+
36
56
_ . forEach ( methods , function ( data , method ) {
37
57
if ( ! ALLOWED_HTTP_METHODS [ method ] ) {
38
58
return ;
@@ -46,94 +66,254 @@ let _ = require('lodash'),
46
66
return ;
47
67
}
48
68
49
- tree . setNode ( `path:${ pathSplit [ 0 ] } :${ method } ` , {
69
+ if ( ! tree . hasNode ( `path:folder:${ pathSplit [ 0 ] } ` ) ) {
70
+ tree . setNode ( `path:folder:${ pathSplit [ 0 ] } ` , {
71
+ type : 'folder' ,
72
+ meta : {
73
+ name : pathSplit [ 0 ] ,
74
+ path : pathSplit [ 0 ] ,
75
+ pathIdentifier : pathSplit [ 0 ]
76
+ } ,
77
+ data : { }
78
+ } ) ;
79
+
80
+ tree . setEdge ( 'root:collection' , `path:folder:${ pathSplit [ 0 ] } ` ) ;
81
+ }
82
+
83
+ tree . setNode ( `path:request:${ pathSplit [ 0 ] } :${ method } ` , {
50
84
type : 'request' ,
85
+ data : { } ,
51
86
meta : {
52
- path : path ,
87
+ path : completePath ,
53
88
method : method ,
54
89
pathIdentifier : pathSplit [ 0 ]
55
- } ,
56
- data : { }
90
+ }
57
91
} ) ;
58
92
59
- tree . setEdge ( 'root:collection' , `path:${ pathSplit [ 0 ] } :${ method } ` ) ;
93
+ tree . setEdge ( `path:folder: ${ pathSplit [ 0 ] } ` , `path:request :${ pathSplit [ 0 ] } :${ method } ` ) ;
60
94
} ) ;
61
95
}
62
96
63
97
else {
64
- _ . forEach ( pathSplit , function ( p , index ) {
98
+ _ . forEach ( pathSplit , function ( path , index ) {
65
99
let previousPathIdentified = pathSplit . slice ( 0 , index ) . join ( '/' ) ,
66
100
pathIdentifier = pathSplit . slice ( 0 , index + 1 ) . join ( '/' ) ;
67
101
68
- /**
69
- * Always first try to find the node if it already exists.
70
- * if yes, bail out nothing is needed to be done.
71
- */
72
- if ( tree . hasNode ( `path:${ pathIdentifier } ` ) ) {
73
- return ;
102
+ if ( ( index + 1 ) === pathSplit . length ) {
103
+ let methods = openapi . paths [ completePath ] ;
104
+
105
+ _ . forEach ( methods , function ( data , method ) {
106
+ if ( ! ALLOWED_HTTP_METHODS [ method ] ) {
107
+ return ;
108
+ }
109
+
110
+ /**
111
+ * include deprecated handling.
112
+ * If true, add in the postman collection. If false ignore the request.
113
+ */
114
+ if ( ! includeDeprecated && data . deprecated ) {
115
+ return ;
116
+ }
117
+
118
+ /**
119
+ * If it is the last node,
120
+ * it might happen that this exists as a folder.
121
+ *
122
+ * If yes add a request inside that folder else
123
+ * add as a request on the previous path idendified which will be a folder.
124
+ */
125
+ if ( ! tree . hasNode ( `path:folder:${ pathIdentifier } ` ) ) {
126
+ tree . setNode ( `path:folder:${ pathIdentifier } ` , {
127
+ type : 'folder' ,
128
+ meta : {
129
+ name : path ,
130
+ path : path ,
131
+ pathIdentifier : pathIdentifier
132
+ } ,
133
+ data : { }
134
+ } ) ;
135
+
136
+ tree . setEdge ( index === 0 ? 'root:collection' : `path:folder:${ previousPathIdentified } ` ,
137
+ `path:folder:${ pathIdentifier } ` ) ;
138
+ }
139
+
140
+ tree . setNode ( `path:request:${ pathIdentifier } :${ method } ` , {
141
+ type : 'request' ,
142
+ data : { } ,
143
+ meta : {
144
+ path : completePath ,
145
+ method : method ,
146
+ pathIdentifier : pathIdentifier
147
+ }
148
+ } ) ;
149
+
150
+ tree . setEdge ( `path:folder:${ pathIdentifier } ` , `path:request:${ pathIdentifier } :${ method } ` ) ;
151
+ } ) ;
74
152
}
75
153
76
154
else {
77
- tree . setNode ( `path:${ pathIdentifier } ` , {
155
+ tree . setNode ( `path:folder: ${ pathIdentifier } ` , {
78
156
type : 'folder' ,
79
157
meta : {
80
- name : p ,
81
- path : p ,
158
+ name : path ,
159
+ path : path ,
82
160
pathIdentifier : pathIdentifier
83
161
} ,
84
162
data : { }
85
163
} ) ;
86
164
87
- /**
88
- * If index is 0, this means that we are on the first level.
89
- * Hence it is folder/request to be added on the first level
90
- *
91
- * If after the split we have more than one paths, then we need
92
- * to add to the previous node.
93
- */
94
- tree . setEdge ( index === 0 ? 'root:collection' : `path:${ previousPathIdentified } ` , `path:${ pathIdentifier } ` ) ;
95
- }
96
- } ) ;
97
-
98
- /**
99
- * Now for all the methods present in the path, add the request nodes.
100
- */
101
-
102
- _ . forEach ( methods , function ( data , method ) {
103
- if ( ! ALLOWED_HTTP_METHODS [ method ] ) {
104
- return ;
105
- }
106
-
107
- /**
108
- * include deprecated handling.
109
- * If true, add in the postman collection. If false ignore the request.
110
- */
111
- if ( ! includeDeprecated && data . deprecated ) {
112
- return ;
165
+ tree . setEdge ( index === 0 ? 'root:collection' : `path:folder:${ previousPathIdentified } ` ,
166
+ `path:folder:${ pathIdentifier } ` ) ;
113
167
}
114
-
115
- // join till the last path i.e. the folder.
116
- let previousPathIdentified = pathSplit . slice ( 0 , ( pathSplit . length ) ) . join ( '/' ) ,
117
- pathIdentifier = `${ pathSplit . join ( '/' ) } :${ method } ` ;
118
-
119
- tree . setNode ( `path:${ pathIdentifier } ` , {
120
- type : 'request' ,
121
- data : { } ,
122
- meta : {
123
- path : path ,
124
- method : method ,
125
- pathIdentifier : pathIdentifier
126
- }
127
- } ) ;
128
-
129
- tree . setEdge ( `path:${ previousPathIdentified } ` , `path:${ pathIdentifier } ` ) ;
130
168
} ) ;
131
169
}
132
170
} ) ;
133
171
134
172
return tree ;
135
173
} ,
136
174
175
+ // _generateTreeFromPaths = function (openapi, { includeDeprecated }) {
176
+ // /**
177
+ // * We will create a unidirectional graph
178
+ // */
179
+ // let tree = new Graph();
180
+
181
+ // tree.setNode('root:collection', {
182
+ // type: 'collection',
183
+ // data: {},
184
+ // meta: {}
185
+ // });
186
+
187
+ // _.forEach(openapi.paths, function (methods, path) {
188
+ // let pathSplit = path === '/' ? [path] : _.compact(path.split('/'));
189
+
190
+ // // if after path split we just have one entry
191
+ // // that means no folders need to be generated.
192
+ // // check for all the methods inside it and expand.
193
+ // if (pathSplit.length === 1) {
194
+ // /**
195
+ // * Always first try to find the node if it already exists.
196
+ // * if yes, bail out nothing is needed to be done.
197
+ // *
198
+ // * if the path length is 1, then also generate
199
+ // * the folder otherwise /pet and /pet/:id will never be in same folder.
200
+ // */
201
+ // // if (!tree.hasNode(`path:${pathSplit[0]}`)) {
202
+ // // tree.setNode(`path:${pathSplit[0]}`, {
203
+ // // type: 'folder',
204
+ // // meta: {
205
+ // // name: pathSplit[0],
206
+ // // path: pathSplit[0],
207
+ // // pathIdentifier: pathIdentifier
208
+ // // },
209
+ // // data: {}
210
+ // // });
211
+
212
+ // // tree.setEdge('root:collection', `path:${pathSplit[0]}`);
213
+ // // }
214
+
215
+
216
+ // _.forEach(methods, function (data, method) {
217
+ // if (!ALLOWED_HTTP_METHODS[method]) {
218
+ // return;
219
+ // }
220
+
221
+ // /**
222
+ // * include deprecated handling.
223
+ // * If true, add in the postman collection. If false ignore the request.
224
+ // */
225
+ // if (!includeDeprecated && data.deprecated) {
226
+ // return;
227
+ // }
228
+
229
+ // tree.setNode(`path:${pathSplit[0]}:${method}`, {
230
+ // type: 'request',
231
+ // meta: {
232
+ // path: path,
233
+ // method: method,
234
+ // pathIdentifier: pathSplit[0]
235
+ // },
236
+ // data: {}
237
+ // });
238
+
239
+ // tree.setEdge(`path:${pathSplit[0]}`, `path:${pathSplit[0]}:${method}`);
240
+ // });
241
+ // }
242
+
243
+ // else {
244
+ // _.forEach(pathSplit, function (p, index) {
245
+ // let previousPathIdentified = pathSplit.slice(0, index).join('/'),
246
+ // pathIdentifier = pathSplit.slice(0, index + 1).join('/');
247
+
248
+ // /**
249
+ // * Always first try to find the node if it already exists.
250
+ // * if yes, bail out nothing is needed to be done.
251
+ // */
252
+ // if (tree.hasNode(`path:${pathIdentifier}`)) {
253
+ // return;
254
+ // }
255
+
256
+ // else {
257
+ // tree.setNode(`path:${pathIdentifier}`, {
258
+ // type: 'folder',
259
+ // meta: {
260
+ // name: p,
261
+ // path: p,
262
+ // pathIdentifier: pathIdentifier
263
+ // },
264
+ // data: {}
265
+ // });
266
+
267
+ // /**
268
+ // * If index is 0, this means that we are on the first level.
269
+ // * Hence it is folder/request to be added on the first level
270
+ // *
271
+ // * If after the split we have more than one paths, then we need
272
+ // * to add to the previous node.
273
+ // */
274
+ // tree.setEdge(index === 0 ? 'root:collection' : `path:${previousPathIdentified}`, `path:${pathIdentifier}`);
275
+ // }
276
+ // });
277
+
278
+ // /**
279
+ // * Now for all the methods present in the path, add the request nodes.
280
+ // */
281
+
282
+ // _.forEach(methods, function (data, method) {
283
+ // if (!ALLOWED_HTTP_METHODS[method]) {
284
+ // return;
285
+ // }
286
+
287
+ // /**
288
+ // * include deprecated handling.
289
+ // * If true, add in the postman collection. If false ignore the request.
290
+ // */
291
+ // if (!includeDeprecated && data.deprecated) {
292
+ // return;
293
+ // }
294
+
295
+ // // join till the last path i.e. the folder.
296
+ // let previousPathIdentified = pathSplit.slice(0, (pathSplit.length)).join('/'),
297
+ // pathIdentifier = `${pathSplit.join('/')}:${method}`;
298
+
299
+ // tree.setNode(`path:${pathIdentifier}`, {
300
+ // type: 'request',
301
+ // data: {},
302
+ // meta: {
303
+ // path: path,
304
+ // method: method,
305
+ // pathIdentifier: pathIdentifier
306
+ // }
307
+ // });
308
+
309
+ // tree.setEdge(`path:${previousPathIdentified}`, `path:${pathIdentifier}`);
310
+ // });
311
+ // }
312
+ // });
313
+
314
+ // return tree;
315
+ // },
316
+
137
317
_generateTreeFromTags = function ( openapi , { includeDeprecated } ) {
138
318
let tree = new Graph ( ) ,
139
319
@@ -295,7 +475,7 @@ module.exports = function (openapi, { folderStrategy, includeWebhooks, includeDe
295
475
break ;
296
476
297
477
case 'paths' :
298
- skeletonTree = _generateTreeFromPaths ( openapi , { includeDeprecated } ) ;
478
+ skeletonTree = _generateTreeFromPathsV2 ( openapi , { includeDeprecated } ) ;
299
479
break ;
300
480
301
481
default :
0 commit comments