11/**
22 * swagger-client - swagger.js is a javascript client for use with swaggering APIs.
3- * @version v2.1.8 -M1
3+ * @version v2.1.9 -M1
44 * @link http://swagger.io
55 * @license apache 2.0
66 */
@@ -301,6 +301,206 @@ PrimitiveModel.prototype.getMockSignature = function(modelsToIgnore) {
301301 }
302302 return returnVal ;
303303} ;
304+ /**
305+ * Resolves a spec's remote references
306+ */
307+ var Resolver = function ( ) { } ;
308+
309+ Resolver . prototype . resolve = function ( spec , callback , scope ) {
310+ this . scope = ( scope || this ) ;
311+ var host , name , path , property , propertyName , type ;
312+ var processedCalls = 0 , resolvedRefs = { } , unresolvedRefs = { } ;
313+
314+ // store objects for dereferencing
315+ var resolutionTable = { } ;
316+
317+ // models
318+ for ( name in spec . definitions ) {
319+ var model = spec . definitions [ name ] ;
320+ for ( propertyName in model . properties ) {
321+ property = model . properties [ propertyName ] ;
322+ this . resolveTo ( property , resolutionTable ) ;
323+ }
324+ }
325+ // operations
326+ for ( name in spec . paths ) {
327+ var method , operation , responseCode ;
328+ path = spec . paths [ name ] ;
329+ for ( method in path ) {
330+ operation = path [ method ] ;
331+ var i , parameters = operation . parameters ;
332+ for ( i in parameters ) {
333+ var parameter = parameters [ i ] ;
334+ if ( parameter . in === 'body' && parameter . schema ) {
335+ this . resolveTo ( parameter . schema , resolutionTable ) ;
336+ }
337+ if ( parameter . $ref ) {
338+ this . resolveInline ( spec , parameter , resolutionTable , unresolvedRefs ) ;
339+ }
340+ }
341+ for ( responseCode in operation . responses ) {
342+ var response = operation . responses [ responseCode ] ;
343+ if ( response . schema ) {
344+ this . resolveTo ( response . schema , resolutionTable ) ;
345+ }
346+ }
347+ }
348+ }
349+ // get hosts
350+ var opts = { } , expectedCalls = 0 ;
351+ for ( name in resolutionTable ) {
352+ var parts = name . split ( '#' ) ;
353+ if ( parts . length == 2 ) {
354+ host = parts [ 0 ] ; path = parts [ 1 ] ;
355+ if ( ! Array . isArray ( opts [ host ] ) ) {
356+ opts [ host ] = [ ] ;
357+ expectedCalls += 1 ;
358+ }
359+ opts [ host ] . push ( path ) ;
360+ }
361+ }
362+
363+ for ( name in opts ) {
364+ var self = this , opt = opts [ name ] ;
365+ host = name ;
366+
367+ var obj = {
368+ useJQuery : false , // TODO
369+ url : host ,
370+ method : "get" ,
371+ headers : {
372+ accept : this . scope . swaggerRequestHeaders || 'application/json'
373+ } ,
374+ on : {
375+ error : function ( response ) {
376+ processedCalls += 1 ;
377+ var i ;
378+ for ( i = 0 ; i < opt . length ; i ++ ) {
379+ // fail all of these
380+ var resolved = host + '#' + opt [ i ] ;
381+ unresolvedRefs [ resolved ] = null ;
382+ }
383+ if ( processedCalls === expectedCalls )
384+ self . finish ( spec , resolutionTable , resolvedRefs , unresolvedRefs , callback ) ;
385+ } ,
386+ response : function ( response ) {
387+ var i , j , swagger = response . obj ;
388+ processedCalls += 1 ;
389+ for ( i = 0 ; i < opt . length ; i ++ ) {
390+ var location = swagger , path = opt [ i ] , parts = path . split ( '/' ) ;
391+ for ( j = 0 ; j < parts . length ; j ++ ) {
392+ var segment = parts [ j ] ;
393+ if ( typeof location === 'undefined' )
394+ break ;
395+ if ( segment . length > 0 )
396+ location = location [ segment ] ;
397+ }
398+ var resolved = host + '#' + path , resolvedName = parts [ j - 1 ] ;
399+ if ( typeof location !== 'undefined' ) {
400+ resolvedRefs [ resolved ] = {
401+ name : resolvedName ,
402+ obj : location
403+ } ;
404+ }
405+ else unresolvedRefs [ resolved ] = null ;
406+ }
407+ if ( processedCalls === expectedCalls )
408+ self . finish ( spec , resolutionTable , resolvedRefs , unresolvedRefs , callback ) ;
409+ }
410+ }
411+ } ;
412+ authorizations . apply ( obj ) ;
413+ new SwaggerHttp ( ) . execute ( obj ) ;
414+ }
415+ if ( Object . keys ( opts ) . length === 0 )
416+ callback . call ( this . scope , spec , unresolvedRefs ) ;
417+ } ;
418+
419+ Resolver . prototype . finish = function ( spec , resolutionTable , resolvedRefs , unresolvedRefs , callback ) {
420+ // walk resolution table and replace with resolved refs
421+ var ref ;
422+ for ( ref in resolutionTable ) {
423+ var i , locations = resolutionTable [ ref ] ;
424+ for ( i = 0 ; i < locations . length ; i ++ ) {
425+ var resolvedTo = resolvedRefs [ locations [ i ] . obj . $ref ] ;
426+ if ( resolvedTo ) {
427+ if ( ! spec . definitions )
428+ spec . definitions = { } ;
429+ if ( locations [ i ] . resolveAs === '$ref' ) {
430+ spec . definitions [ resolvedTo . name ] = resolvedTo . obj ;
431+ locations [ i ] . obj . $ref = '#/definitions/' + resolvedTo . name ;
432+ }
433+ else if ( locations [ i ] . resolveAs === 'inline' ) {
434+ var key ;
435+ var targetObj = locations [ i ] . obj ;
436+ delete targetObj . $ref ;
437+ for ( key in resolvedTo . obj ) {
438+ targetObj [ key ] = resolvedTo . obj [ key ] ;
439+ }
440+ }
441+ }
442+ }
443+ }
444+ callback . call ( this . scope , spec , unresolvedRefs ) ;
445+ } ;
446+
447+ /**
448+ * immediately in-lines local refs, queues remote refs
449+ * for inline resolution
450+ */
451+ Resolver . prototype . resolveInline = function ( spec , property , objs , unresolvedRefs ) {
452+ var ref = property . $ref ;
453+ if ( ref ) {
454+ if ( ref . indexOf ( 'http' ) === 0 ) {
455+ if ( Array . isArray ( objs [ ref ] ) ) {
456+ objs [ ref ] . push ( { obj : property , resolveAs : 'inline' } ) ;
457+ }
458+ else {
459+ objs [ ref ] = [ { obj : property , resolveAs : 'inline' } ] ;
460+ }
461+ }
462+ else if ( ref . indexOf ( '#' ) === 0 ) {
463+ // local resolve
464+ var shortenedRef = ref . substring ( 1 ) ;
465+ var i , parts = shortenedRef . split ( '/' ) , location = spec ;
466+ for ( i = 0 ; i < parts . length ; i ++ ) {
467+ var part = parts [ i ] ;
468+ if ( part . length > 0 ) {
469+ location = location [ part ] ;
470+ }
471+ }
472+ if ( location ) {
473+ delete property . $ref ;
474+ var key ;
475+ for ( key in location ) {
476+ property [ key ] = location [ key ] ;
477+ }
478+ }
479+ else unresolvedRefs [ ref ] = null ;
480+ }
481+ }
482+ else if ( property . type === 'array' ) {
483+ this . resolveTo ( property . items , objs ) ;
484+ }
485+ } ;
486+
487+ Resolver . prototype . resolveTo = function ( property , objs ) {
488+ var ref = property . $ref ;
489+ if ( ref ) {
490+ if ( ref . indexOf ( 'http' ) === 0 ) {
491+ if ( Array . isArray ( objs [ ref ] ) ) {
492+ objs [ ref ] . push ( { obj : property , resolveAs : '$ref' } ) ;
493+ }
494+ else {
495+ objs [ ref ] = [ { obj : property , resolveAs : '$ref' } ] ;
496+ }
497+ }
498+ }
499+ else if ( property . type === 'array' ) {
500+ var items = property . items ;
501+ this . resolveTo ( items , objs ) ;
502+ }
503+ } ;
304504var addModel = function ( name , model ) {
305505 models [ name ] = model ;
306506} ;
@@ -389,7 +589,7 @@ SwaggerClient.prototype.build = function(mock) {
389589
390590 if ( responseObj . swagger && parseInt ( responseObj . swagger ) === 2 ) {
391591 self . swaggerVersion = responseObj . swagger ;
392- self . buildFromSpec ( responseObj ) ;
592+ new Resolver ( ) . resolve ( responseObj , self . buildFromSpec , self ) ;
393593 self . isValid = true ;
394594 }
395595 else {
@@ -403,7 +603,9 @@ SwaggerClient.prototype.build = function(mock) {
403603 }
404604 } ;
405605 if ( this . spec ) {
406- setTimeout ( function ( ) { self . buildFromSpec ( self . spec ) ; } , 10 ) ;
606+ setTimeout ( function ( ) {
607+ new Resolver ( ) . resolve ( self . spec , self . buildFromSpec , self ) ;
608+ } , 10 ) ;
407609 }
408610 else {
409611 authorizations . apply ( obj ) ;
@@ -3088,5 +3290,5 @@ e.SwaggerApi = SwaggerClient;
30883290e . Operation = Operation ;
30893291e . Model = Model ;
30903292e . addModel = addModel ;
3091-
3293+ e . Resolver = Resolver ;
30923294} ) ( ) ;
0 commit comments