@@ -43,14 +43,16 @@ const convertV21Auth = (array) => {
43
43
} ;
44
44
45
45
const constructUrlFromParts = ( url ) => {
46
+ if ( ! url ) return '' ;
47
+
46
48
const { protocol = 'http' , host, path, port, query, hash } = url || { } ;
47
49
const hostStr = Array . isArray ( host ) ? host . filter ( Boolean ) . join ( '.' ) : host || '' ;
48
50
const pathStr = Array . isArray ( path ) ? path . filter ( Boolean ) . join ( '/' ) : path || '' ;
49
51
const portStr = port ? `:${ port } ` : '' ;
50
52
const queryStr =
51
53
query && Array . isArray ( query ) && query . length > 0
52
54
? `?${ query
53
- . filter ( ( q ) => q . key )
55
+ . filter ( ( q ) => q && q . key )
54
56
. map ( ( q ) => `${ q . key } =${ q . value || '' } ` )
55
57
. join ( '&' ) } `
56
58
: '' ;
@@ -140,6 +142,110 @@ const importCollectionLevelVariables = (variables, requestObject) => {
140
142
requestObject . vars . req = vars ;
141
143
} ;
142
144
145
+ const processAuth = ( auth , requestObject ) => {
146
+ if ( ! auth || ! auth . type || auth . type === 'noauth' ) {
147
+ return ;
148
+ }
149
+
150
+ let authValues = auth [ auth . type ] ;
151
+ if ( Array . isArray ( authValues ) ) {
152
+ authValues = convertV21Auth ( authValues ) ;
153
+ }
154
+
155
+ if ( auth . type === 'basic' ) {
156
+ requestObject . auth . mode = 'basic' ;
157
+ requestObject . auth . basic = {
158
+ username : authValues . username || '' ,
159
+ password : authValues . password || ''
160
+ } ;
161
+ } else if ( auth . type === 'bearer' ) {
162
+ requestObject . auth . mode = 'bearer' ;
163
+ requestObject . auth . bearer = {
164
+ token : authValues . token || ''
165
+ } ;
166
+ } else if ( auth . type === 'awsv4' ) {
167
+ requestObject . auth . mode = 'awsv4' ;
168
+ requestObject . auth . awsv4 = {
169
+ accessKeyId : authValues . accessKey || '' ,
170
+ secretAccessKey : authValues . secretKey || '' ,
171
+ sessionToken : authValues . sessionToken || '' ,
172
+ service : authValues . service || '' ,
173
+ region : authValues . region || '' ,
174
+ profileName : ''
175
+ } ;
176
+ } else if ( auth . type === 'apikey' ) {
177
+ requestObject . auth . mode = 'apikey' ;
178
+ requestObject . auth . apikey = {
179
+ key : authValues . key || '' ,
180
+ value : authValues . value ?. toString ( ) || '' , // Convert the value to a string as Postman's schema does not rigidly define the type of it,
181
+ placement : 'header' //By default we are placing the apikey values in headers!
182
+ } ;
183
+ } else if ( auth . type === 'digest' ) {
184
+ requestObject . auth . mode = 'digest' ;
185
+ requestObject . auth . digest = {
186
+ username : authValues . username || '' ,
187
+ password : authValues . password || ''
188
+ } ;
189
+ } else if ( auth . type === 'oauth2' ) {
190
+ const findValueUsingKey = ( key ) => {
191
+ return authValues [ key ] || '' ;
192
+ } ;
193
+ const oauth2GrantTypeMaps = {
194
+ authorization_code_with_pkce : 'authorization_code' ,
195
+ authorization_code : 'authorization_code' ,
196
+ client_credentials : 'client_credentials' ,
197
+ password_credentials : 'password_credentials'
198
+ } ;
199
+ const grantType = oauth2GrantTypeMaps [ findValueUsingKey ( 'grant_type' ) ] || 'authorization_code' ;
200
+
201
+ requestObject . auth . mode = 'oauth2' ;
202
+ if ( grantType === 'authorization_code' ) {
203
+ requestObject . auth . oauth2 = {
204
+ grantType : 'authorization_code' ,
205
+ authorizationUrl : findValueUsingKey ( 'authUrl' ) ,
206
+ callbackUrl : findValueUsingKey ( 'redirect_uri' ) ,
207
+ accessTokenUrl : findValueUsingKey ( 'accessTokenUrl' ) ,
208
+ refreshTokenUrl : findValueUsingKey ( 'refreshTokenUrl' ) ,
209
+ clientId : findValueUsingKey ( 'clientId' ) ,
210
+ clientSecret : findValueUsingKey ( 'clientSecret' ) ,
211
+ scope : findValueUsingKey ( 'scope' ) ,
212
+ state : findValueUsingKey ( 'state' ) ,
213
+ pkce : Boolean ( findValueUsingKey ( 'grant_type' ) == 'authorization_code_with_pkce' ) ,
214
+ tokenPlacement : findValueUsingKey ( 'addTokenTo' ) == 'header' ? 'header' : 'url' ,
215
+ credentialsPlacement : findValueUsingKey ( 'client_authentication' ) == 'body' ? 'body' : 'basic_auth_header'
216
+ } ;
217
+ } else if ( grantType === 'password_credentials' ) {
218
+ requestObject . auth . oauth2 = {
219
+ grantType : 'password' ,
220
+ accessTokenUrl : findValueUsingKey ( 'accessTokenUrl' ) ,
221
+ refreshTokenUrl : findValueUsingKey ( 'refreshTokenUrl' ) ,
222
+ username : findValueUsingKey ( 'username' ) ,
223
+ password : findValueUsingKey ( 'password' ) ,
224
+ clientId : findValueUsingKey ( 'clientId' ) ,
225
+ clientSecret : findValueUsingKey ( 'clientSecret' ) ,
226
+ scope : findValueUsingKey ( 'scope' ) ,
227
+ state : findValueUsingKey ( 'state' ) ,
228
+ tokenPlacement : findValueUsingKey ( 'addTokenTo' ) == 'header' ? 'header' : 'url' ,
229
+ credentialsPlacement : findValueUsingKey ( 'client_authentication' ) == 'body' ? 'body' : 'basic_auth_header'
230
+ } ;
231
+ } else if ( grantType === 'client_credentials' ) {
232
+ requestObject . auth . oauth2 = {
233
+ grantType : 'client_credentials' ,
234
+ accessTokenUrl : findValueUsingKey ( 'accessTokenUrl' ) ,
235
+ refreshTokenUrl : findValueUsingKey ( 'refreshTokenUrl' ) ,
236
+ clientId : findValueUsingKey ( 'clientId' ) ,
237
+ clientSecret : findValueUsingKey ( 'clientSecret' ) ,
238
+ scope : findValueUsingKey ( 'scope' ) ,
239
+ state : findValueUsingKey ( 'state' ) ,
240
+ tokenPlacement : findValueUsingKey ( 'addTokenTo' ) == 'header' ? 'header' : 'url' ,
241
+ credentialsPlacement : findValueUsingKey ( 'client_authentication' ) == 'body' ? 'body' : 'basic_auth_header'
242
+ } ;
243
+ }
244
+ } else {
245
+ console . warn ( 'Unexpected auth.type' , auth . type ) ;
246
+ }
247
+ } ;
248
+
143
249
const importPostmanV2CollectionItem = ( brunoParent , item , parentAuth ) => {
144
250
brunoParent . items = brunoParent . items || [ ] ;
145
251
const folderMap = { } ;
@@ -172,7 +278,10 @@ const importPostmanV2CollectionItem = (brunoParent, item, parentAuth) => {
172
278
mode : 'none' ,
173
279
basic : null ,
174
280
bearer : null ,
175
- awsv4 : null
281
+ awsv4 : null ,
282
+ apikey : null ,
283
+ oauth2 : null ,
284
+ digest : null
176
285
} ,
177
286
headers : [ ] ,
178
287
script : { } ,
@@ -181,6 +290,15 @@ const importPostmanV2CollectionItem = (brunoParent, item, parentAuth) => {
181
290
}
182
291
}
183
292
} ;
293
+
294
+ // Folder level auth
295
+ if ( i . auth ) {
296
+ processAuth ( i . auth , brunoFolderItem . root . request ) ;
297
+ } else if ( parentAuth ) {
298
+ // Inherit parent auth if folder doesn't define its own
299
+ processAuth ( parentAuth , brunoFolderItem . root . request ) ;
300
+ }
301
+
184
302
if ( i . item && i . item . length ) {
185
303
importPostmanV2CollectionItem ( brunoFolderItem , i . item , i . auth ?? parentAuth ) ;
186
304
}
@@ -194,8 +312,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, parentAuth) => {
194
312
195
313
} else {
196
314
if ( i . request ) {
197
- if ( ! requestMethods . includes ( i ?. request ?. method . toUpperCase ( ) ) ) {
198
- console . warn ( " Unexpected request.method" )
315
+ if ( ! requestMethods . includes ( i ?. request ?. method . toUpperCase ( ) ) ) {
316
+ console . warn ( ' Unexpected request.method' , i ?. request ?. method ) ;
199
317
return ;
200
318
}
201
319
@@ -221,7 +339,10 @@ const importPostmanV2CollectionItem = (brunoParent, item, parentAuth) => {
221
339
mode : 'none' ,
222
340
basic : null ,
223
341
bearer : null ,
224
- awsv4 : null
342
+ awsv4 : null ,
343
+ apikey : null ,
344
+ oauth2 : null ,
345
+ digest : null
225
346
} ,
226
347
headers : [ ] ,
227
348
params : [ ] ,
@@ -356,102 +477,9 @@ const importPostmanV2CollectionItem = (brunoParent, item, parentAuth) => {
356
477
} ) ;
357
478
} ) ;
358
479
480
+ // Handle request-level auth or inherit from parent
359
481
const auth = i . request . auth ?? parentAuth ;
360
- if ( auth ?. [ auth . type ] && auth . type !== 'noauth' ) {
361
- let authValues = auth [ auth . type ] ;
362
- if ( Array . isArray ( authValues ) ) {
363
- authValues = convertV21Auth ( authValues ) ;
364
- }
365
- if ( auth . type === 'basic' ) {
366
- brunoRequestItem . request . auth . mode = 'basic' ;
367
- brunoRequestItem . request . auth . basic = {
368
- username : authValues . username ,
369
- password : authValues . password
370
- } ;
371
- } else if ( auth . type === 'bearer' ) {
372
- brunoRequestItem . request . auth . mode = 'bearer' ;
373
- brunoRequestItem . request . auth . bearer = {
374
- token : authValues . token
375
- } ;
376
- } else if ( auth . type === 'awsv4' ) {
377
- brunoRequestItem . request . auth . mode = 'awsv4' ;
378
- brunoRequestItem . request . auth . awsv4 = {
379
- accessKeyId : authValues . accessKey ,
380
- secretAccessKey : authValues . secretKey ,
381
- sessionToken : authValues . sessionToken ,
382
- service : authValues . service ,
383
- region : authValues . region ,
384
- profileName : ''
385
- } ;
386
- } else if ( auth . type === 'apikey' ) {
387
- brunoRequestItem . request . auth . mode = 'apikey' ;
388
- brunoRequestItem . request . auth . apikey = {
389
- key : authValues . key ,
390
- value : authValues . value ?. toString ( ) , // Convert the value to a string as Postman's schema does not rigidly define the type of it,
391
- placement : "header" //By default we are placing the apikey values in headers!
392
- }
393
- } else if ( auth . type === 'oauth2' ) {
394
- const findValueUsingKey = ( key ) => {
395
- return auth ?. oauth2 ?. find ( v => v ?. key == key ) ?. value || ''
396
- }
397
- const oauth2GrantTypeMaps = {
398
- 'authorization_code_with_pkce' : 'authorization_code' ,
399
- 'authorization_code' : 'authorization_code' ,
400
- 'client_credentials' : 'client_credentials' ,
401
- 'password_credentials' : 'password_credentials'
402
- }
403
- const grantType = oauth2GrantTypeMaps [ findValueUsingKey ( 'grant_type' ) ] || 'authorization_code' ;
404
- if ( grantType ) {
405
- brunoRequestItem . request . auth . mode = 'oauth2' ;
406
- switch ( grantType ) {
407
- case 'authorization_code' :
408
- brunoRequestItem . request . auth . oauth2 = {
409
- grantType : 'authorization_code' ,
410
- authorizationUrl : findValueUsingKey ( 'authUrl' ) ,
411
- callbackUrl : findValueUsingKey ( 'redirect_uri' ) ,
412
- accessTokenUrl : findValueUsingKey ( 'accessTokenUrl' ) ,
413
- refreshTokenUrl : findValueUsingKey ( 'refreshTokenUrl' ) ,
414
- clientId : findValueUsingKey ( 'clientId' ) ,
415
- clientSecret : findValueUsingKey ( 'clientSecret' ) ,
416
- scope : findValueUsingKey ( 'scope' ) ,
417
- state : findValueUsingKey ( 'state' ) ,
418
- pkce : Boolean ( findValueUsingKey ( 'grant_type' ) == 'authorization_code_with_pkce' ) ,
419
- tokenPlacement : findValueUsingKey ( 'addTokenTo' ) == 'header' ? 'header' : 'url' ,
420
- credentialsPlacement : findValueUsingKey ( 'client_authentication' ) == 'body' ? 'body' : 'basic_auth_header'
421
- } ;
422
- break ;
423
- case 'password_credentials' :
424
- brunoRequestItem . request . auth . oauth2 = {
425
- grantType : 'password' ,
426
- accessTokenUrl : findValueUsingKey ( 'accessTokenUrl' ) ,
427
- refreshTokenUrl : findValueUsingKey ( 'refreshTokenUrl' ) ,
428
- username : findValueUsingKey ( 'username' ) ,
429
- password : findValueUsingKey ( 'password' ) ,
430
- clientId : findValueUsingKey ( 'clientId' ) ,
431
- clientSecret : findValueUsingKey ( 'clientSecret' ) ,
432
- scope : findValueUsingKey ( 'scope' ) ,
433
- state : findValueUsingKey ( 'state' ) ,
434
- tokenPlacement : findValueUsingKey ( 'addTokenTo' ) == 'header' ? 'header' : 'url' ,
435
- credentialsPlacement : findValueUsingKey ( 'client_authentication' ) == 'body' ? 'body' : 'basic_auth_header'
436
- } ;
437
- break ;
438
- case 'client_credentials' :
439
- brunoRequestItem . request . auth . oauth2 = {
440
- grantType : 'client_credentials' ,
441
- accessTokenUrl : findValueUsingKey ( 'accessTokenUrl' ) ,
442
- refreshTokenUrl : findValueUsingKey ( 'refreshTokenUrl' ) ,
443
- clientId : findValueUsingKey ( 'clientId' ) ,
444
- clientSecret : findValueUsingKey ( 'clientSecret' ) ,
445
- scope : findValueUsingKey ( 'scope' ) ,
446
- state : findValueUsingKey ( 'state' ) ,
447
- tokenPlacement : findValueUsingKey ( 'addTokenTo' ) == 'header' ? 'header' : 'url' ,
448
- credentialsPlacement : findValueUsingKey ( 'client_authentication' ) == 'body' ? 'body' : 'basic_auth_header'
449
- } ;
450
- break ;
451
- }
452
- }
453
- }
454
- }
482
+ processAuth ( auth , brunoRequestItem . request ) ;
455
483
456
484
each ( get ( i , 'request.url.query' ) , ( param ) => {
457
485
brunoRequestItem . request . params . push ( {
@@ -519,7 +547,10 @@ const importPostmanV2Collection = (collection) => {
519
547
mode : 'none' ,
520
548
basic : null ,
521
549
bearer : null ,
522
- awsv4 : null
550
+ awsv4 : null ,
551
+ apikey : null ,
552
+ oauth2 : null ,
553
+ digest : null
523
554
} ,
524
555
headers : [ ] ,
525
556
script : { } ,
@@ -533,10 +564,13 @@ const importPostmanV2Collection = (collection) => {
533
564
importScriptsFromEvents ( collection . event , brunoCollection . root . request ) ;
534
565
}
535
566
536
- if ( collection ?. variable ) {
567
+ if ( collection ?. variable ) {
537
568
importCollectionLevelVariables ( collection . variable , brunoCollection . root . request ) ;
538
569
}
539
570
571
+ // Collection level auth
572
+ processAuth ( collection . auth , brunoCollection . root . request ) ;
573
+
540
574
importPostmanV2CollectionItem ( brunoCollection , collection . item , collection . auth ) ;
541
575
542
576
return brunoCollection ;
@@ -557,28 +591,28 @@ const parsePostmanCollection = (collection) => {
557
591
return importPostmanV2Collection ( collection ) ;
558
592
}
559
593
560
- throw new Error ( 'Unknown postman schema' ) ;
594
+ throw new Error ( 'Unsupported Postman schema version. Only Postman Collection v2.0 and v2.1 are supported. ' ) ;
561
595
} catch ( err ) {
562
596
console . log ( err ) ;
563
597
if ( err instanceof Error ) {
564
598
throw err ;
565
599
}
566
600
567
- throw new Error ( 'Unable to parse the postman collection json file' ) ;
601
+ throw new Error ( 'Invalid Postman collection format. Please check your JSON file. ' ) ;
568
602
}
569
603
} ;
570
604
571
605
const postmanToBruno = ( postmanCollection ) => {
572
- try {
573
- const parsedPostmanCollection = parsePostmanCollection ( postmanCollection ) ;
574
- const transformedCollection = transformItemsInCollection ( parsedPostmanCollection ) ;
575
- const hydratedCollection = hydrateSeqInCollection ( transformedCollection ) ;
576
- const validatedCollection = validateSchema ( hydratedCollection ) ;
577
- return validatedCollection ;
578
- } catch ( err ) {
579
- console . log ( err ) ;
580
- throw new Error ( ' Import collection failed' ) ;
581
- }
606
+ try {
607
+ const parsedPostmanCollection = parsePostmanCollection ( postmanCollection ) ;
608
+ const transformedCollection = transformItemsInCollection ( parsedPostmanCollection ) ;
609
+ const hydratedCollection = hydrateSeqInCollection ( transformedCollection ) ;
610
+ const validatedCollection = validateSchema ( hydratedCollection ) ;
611
+ return validatedCollection ;
612
+ } catch ( err ) {
613
+ console . log ( err ) ;
614
+ throw new Error ( ` Import collection failed: ${ err . message } ` ) ;
615
+ }
582
616
} ;
583
617
584
618
export default postmanToBruno ;
0 commit comments