@@ -22,189 +22,211 @@ angular
2222 }
2323 } ;
2424 } )
25- . controller ( 'swaggerUiController' , [ '$scope' , '$http' , '$sce' , 'swaggerModel' , 'swaggerClient' , function ( $scope , $http , $sce , swaggerModel , swaggerClient ) {
25+ . controller ( 'swaggerUiController' , [ '$scope' , '$http' , '$sce' , '$location' , 'swaggerModel' , 'swaggerClient' ,
26+ function ( $scope , $http , $sce , $location , swaggerModel , swaggerClient ) {
2627
27- var swagger ;
28+ var swagger ;
2829
29- // WARNING only Swagger 2.0 is supported (@see https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md)
30- // WARNING XML is not supported
31- // WARNING authentication is not implemented, please use 'api-explorer-transform' directive's param to customize API calls
30+ // WARNING only Swagger 2.0 is supported (@see https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md)
31+ // WARNING application/xml is not supported
32+ // WARNING authentication is not implemented, please use 'api-explorer-transform' directive's param to customize API calls
3233
33- //TODO find a way to implement permalinks !!
34-
35- $scope . $watch ( 'url' , function ( url ) {
36- //reset
37- $scope . infos = { } ;
38- $scope . resources = [ ] ;
39- $scope . form = { } ;
40- if ( url && url !== '' ) {
41- // load Swagger description
34+ function get ( url , callback ) {
35+ $scope . loading = true ;
4236 var notifyError = typeof $scope . errorHandler === 'function' ;
4337 $http . get ( url )
4438 . success ( function ( data /*, status, headers, config*/ ) {
45- swagger = data ;
46- if ( data . swagger === '2.0' ) {
47- parseV2 ( swagger ) ;
48- } else if ( notifyError ) {
49- $scope . errorHandler ( 'unsupported swagger version' , '415' ) ;
50- }
39+ $scope . loading = false ;
40+ callback ( data ) ;
5141 } )
5242 . error ( function ( data , status /*, headers, config*/ ) {
43+ $scope . loading = false ;
5344 if ( notifyError ) {
5445 $scope . errorHandler ( data , status ) ;
5546 }
5647 } ) ;
5748 }
58- } ) ;
5949
60- /**
61- * parses swagger description to ease HTML generation
62- */
63- function parseV2 ( ) {
64- $scope . infos = swagger . info ;
65- $scope . infos . description = $sce . trustAsHtml ( $scope . infos . description ) ;
50+ $scope . $watch ( 'url' , function ( url ) {
51+ //reset
52+ $scope . infos = { } ;
53+ $scope . resources = [ ] ;
54+ $scope . form = { } ;
55+ if ( url && url !== '' ) {
56+ // load Swagger description
57+ var notifyError = typeof $scope . errorHandler === 'function' ;
58+ get ( url , function ( data ) {
59+ swagger = data ;
60+ if ( data . swagger === '2.0' ) {
61+ parseV2 ( swagger ) ;
62+ } else if ( notifyError ) {
63+ $scope . errorHandler ( 'unsupported swagger version' , '415' ) ;
64+ }
65+ } ) ;
66+ }
67+ } ) ;
68+
69+ /**
70+ * parses swagger description to ease HTML generation
71+ */
72+ function parseV2 ( ) {
73+ $scope . infos = swagger . info ;
74+ $scope . infos . description = $sce . trustAsHtml ( $scope . infos . description ) ;
6675
67- var operationId = 0 ,
68- paramId = 0 ,
69- map = { } ,
70- form = { } ,
71- resources = [ ] ;
76+ var operationId = 0 ,
77+ paramId = 0 ,
78+ map = { } ,
79+ form = { } ,
80+ resources = [ ] ,
81+ openPath = $location . search ( ) . open ;
7282
73- // parse resources
74- if ( ! swagger . tags ) {
75- resources . push ( {
76- name : 'default' ,
77- open : true
78- } ) ;
79- map [ 'default' ] = 0 ;
80- } else {
81- for ( var i = 0 , l = swagger . tags . length ; i < l ; i ++ ) {
82- var tag = swagger . tags [ i ] ;
83- resources . push ( tag ) ;
84- map [ tag . name ] = i ;
83+ // parse resources
84+ if ( ! swagger . tags ) {
85+ resources . push ( {
86+ name : 'default' ,
87+ open : true
88+ } ) ;
89+ map [ 'default' ] = 0 ;
90+ } else {
91+ for ( var i = 0 , l = swagger . tags . length ; i < l ; i ++ ) {
92+ var tag = swagger . tags [ i ] ;
93+ resources . push ( tag ) ;
94+ map [ tag . name ] = i ;
95+ }
8596 }
86- }
87- // parse operations
88- for ( var path in swagger . paths ) {
89- for ( var httpMethod in swagger . paths [ path ] ) {
90- var operation = swagger . paths [ path ] [ httpMethod ] ;
91- //TODO manage 'deprecated' operations ?
92- operation . id = operationId ;
93- form [ operationId ] = {
94- contentType : operation . consumes && operation . consumes . length === 1 ? operation . consumes [ 0 ] : 'application/json' ,
95- responseType : 'application/json'
96- } ;
97- operation . httpMethod = httpMethod ;
98- operation . path = path ;
99- // parse operation's parameters
100- for ( var j = 0 , params = operation . parameters || [ ] , k = params . length ; j < k ; j ++ ) {
101- //TODO manage 'collectionFormat' (csv, multi etc.) ?
102- //TODO manage constraints (pattern, min, max etc.) ?
103- var param = params [ j ] ;
104- param . id = paramId ;
105- param . type = swaggerModel . getType ( param ) ;
106- param . subtype = param . type === 'array' && param . enum ? 'enum' : param . type ;
107- // put param into form scope
108- form [ operationId ] [ param . name ] = param . default || '' ;
109- if ( param . schema ) {
110- param . schema . display = 1 ; // display schema
111- param . schema . json = swaggerModel . generateSampleJson ( swagger , param . schema ) ;
112- param . schema . model = $sce . trustAsHtml ( swaggerModel . generateModel ( swagger , param . schema ) ) ;
113- }
114- if ( param . in === 'body' ) {
115- operation . consumes = operation . consumes || [ 'application/json' ] ;
97+ // parse operations
98+ for ( var path in swagger . paths ) {
99+ for ( var httpMethod in swagger . paths [ path ] ) {
100+ var operation = swagger . paths [ path ] [ httpMethod ] ;
101+ //TODO manage 'deprecated' operations ?
102+ operation . id = operationId ;
103+ form [ operationId ] = {
104+ contentType : operation . consumes && operation . consumes . length === 1 ? operation . consumes [ 0 ] : 'application/json' ,
105+ responseType : 'application/json'
106+ } ;
107+ operation . httpMethod = httpMethod ;
108+ operation . path = path ;
109+ // parse operation's parameters
110+ for ( var j = 0 , params = operation . parameters || [ ] , k = params . length ; j < k ; j ++ ) {
111+ //TODO manage 'collectionFormat' (csv, multi etc.) ?
112+ //TODO manage constraints (pattern, min, max etc.) ?
113+ var param = params [ j ] ;
114+ param . id = paramId ;
115+ param . type = swaggerModel . getType ( param ) ;
116+ param . subtype = param . type === 'array' && param . enum ? 'enum' : param . type ;
117+ // put param into form scope
118+ form [ operationId ] [ param . name ] = param . default || '' ;
119+ if ( param . schema ) {
120+ param . schema . display = 1 ; // display schema
121+ param . schema . json = swaggerModel . generateSampleJson ( swagger , param . schema ) ;
122+ param . schema . model = $sce . trustAsHtml ( swaggerModel . generateModel ( swagger , param . schema ) ) ;
123+ }
124+ if ( param . in === 'body' ) {
125+ operation . consumes = operation . consumes || [ 'application/json' ] ;
126+ }
127+ paramId ++ ;
116128 }
117- paramId ++ ;
118- }
119- // parse operation's responses
120- if ( operation . responses ) {
121- for ( var code in operation . responses ) {
122- //TODO manage headers, examples ?
123- var resp = operation . responses [ code ] ;
124- resp . description = $sce . trustAsHtml ( resp . description ) ;
125- if ( resp . schema ) {
126- resp . schema . json = swaggerModel . generateSampleJson ( swagger , resp . schema ) ;
127- if ( resp . schema . type === 'object' || resp . schema . type === 'array' || resp . schema . $ref ) {
128- resp . display = 1 ; // display schema
129- resp . schema . model = $sce . trustAsHtml ( swaggerModel . generateModel ( swagger , resp . schema ) ) ;
130- } else if ( resp . schema . type === 'string' ) {
131- delete resp . schema ;
132- }
133- if ( code === '200' || code === '201' ) {
134- operation . responseClass = resp ;
135- operation . responseClass . display = 1 ;
136- operation . responseClass . status = code ;
137- delete operation . responses [ code ] ;
129+ // parse operation's responses
130+ if ( operation . responses ) {
131+ for ( var code in operation . responses ) {
132+ //TODO manage headers, examples ?
133+ var resp = operation . responses [ code ] ;
134+ resp . description = $sce . trustAsHtml ( resp . description ) ;
135+ if ( resp . schema ) {
136+ resp . schema . json = swaggerModel . generateSampleJson ( swagger , resp . schema ) ;
137+ if ( resp . schema . type === 'object' || resp . schema . type === 'array' || resp . schema . $ref ) {
138+ resp . display = 1 ; // display schema
139+ resp . schema . model = $sce . trustAsHtml ( swaggerModel . generateModel ( swagger , resp . schema ) ) ;
140+ } else if ( resp . schema . type === 'string' ) {
141+ delete resp . schema ;
142+ }
143+ if ( code === '200' || code === '201' ) {
144+ operation . responseClass = resp ;
145+ operation . responseClass . display = 1 ;
146+ operation . responseClass . status = code ;
147+ delete operation . responses [ code ] ;
148+ } else {
149+ operation . hasResponses = true ;
150+ }
138151 } else {
139152 operation . hasResponses = true ;
140153 }
141- } else {
142- operation . hasResponses = true ;
143154 }
144155 }
156+ operation . tags = operation . tags || [ 'default' ] ;
157+ // map operation to resource
158+ var tag = operation . tags [ 0 ] ;
159+ if ( typeof map [ tag ] === 'undefined' ) {
160+ map [ tag ] = resources . length ;
161+ resources . push ( {
162+ name : tag
163+ } ) ;
164+ }
165+ var res = resources [ map [ operation . tags [ 0 ] ] ] ;
166+ operation . open = openPath === operation . operationId || openPath === res . name + '*' ;
167+ res . operations = res . operations || [ ] ;
168+ res . operations . push ( operation ) ;
169+ if ( operation . open ) {
170+ res . open = true ;
171+ }
172+ operationId ++ ;
145173 }
146- operation . tags = operation . tags || [ 'default' ] ;
147- // map operation to resource
148- var tag = operation . tags [ 0 ] ;
149- if ( typeof map [ tag ] === 'undefined' ) {
150- map [ tag ] = resources . length ;
151- resources . push ( {
152- name : tag
153- } ) ;
154- }
155- var res = resources [ map [ operation . tags [ 0 ] ] ] ; //TODO make sure there is only one defined !
156- res . operations = res . operations || [ ] ;
157- res . operations . push ( operation ) ;
158- operationId ++ ;
159174 }
160- }
161- // cleanup resources
162- for ( var i = 0 ; i < resources . length ; i ++ ) {
163- var operations = resources [ i ] . operations ;
164- if ( ! operations || ( operations && operations . length === 0 ) ) {
165- resources . splice ( i , 1 ) ;
175+ // cleanup resources
176+ for ( var i = 0 ; i < resources . length ; i ++ ) {
177+ var res = resources [ i ] ,
178+ operations = resources [ i ] . operations ;
179+
180+ res . open = res . open || openPath === res . name || openPath === res . name + '*' ;
181+ if ( ! operations || ( operations && operations . length === 0 ) ) {
182+ resources . splice ( i , 1 ) ;
183+ }
166184 }
185+ // sort resources alphabeticaly
186+ resources . sort ( function ( a , b ) {
187+ if ( a . name > b . name ) {
188+ return 1 ;
189+ } else if ( a . name < b . name ) {
190+ return - 1 ;
191+ }
192+ return 0 ;
193+ } ) ;
194+ // clear cache
195+ swaggerModel . clearCache ( ) ;
196+ // display swagger
197+ $scope . form = form ;
198+ $scope . resources = resources ;
167199 }
168- // sort resources alphabeticaly
169- resources . sort ( function ( a , b ) {
170- if ( a . name > b . name ) {
171- return 1 ;
172- } else if ( a . name < b . name ) {
173- return - 1 ;
200+
201+ /**
202+ * show all resource's operations as list or as expanded list
203+ */
204+ $scope . expand = function ( resource , expandOperations ) {
205+ resource . open = true ;
206+ for ( var i = 0 , op = resource . operations , l = op . length ; i < l ; i ++ ) {
207+ op [ i ] . open = expandOperations ;
174208 }
175- return 0 ;
176- } ) ;
177- // clear cache
178- swaggerModel . clearCache ( ) ;
179- // display swagger
180- $scope . form = form ;
181- $scope . resources = resources ;
182- }
209+ } ;
183210
184- /**
185- * show all resource's operations as list or as expanded list
186- */
187- $scope . expand = function ( resource , expandOperations ) {
188- resource . open = true ;
189- for ( var i = 0 , op = resource . operations , l = op . length ; i < l ; i ++ ) {
190- op [ i ] . open = expandOperations ;
191- }
192- } ;
211+ $scope . permalink = function ( name ) {
212+ $location . search ( 'open' , name ) ;
213+ } ;
193214
194- /**
195- * sends a sample API request
196- */
197- $scope . submitExplorer = function ( operation ) {
198- operation . loading = true ;
199- swaggerClient
200- . send ( swagger , operation , $scope . form [ operation . id ] , $scope . apiExplorerTransform )
201- . then ( function ( result ) {
202- operation . loading = false ;
203- operation . explorerResult = result ;
204- } ) ;
205- } ;
215+ /**
216+ * sends a sample API request
217+ */
218+ $scope . submitExplorer = function ( operation ) {
219+ operation . loading = true ;
220+ swaggerClient
221+ . send ( swagger , operation , $scope . form [ operation . id ] , $scope . apiExplorerTransform )
222+ . then ( function ( result ) {
223+ operation . loading = false ;
224+ operation . explorerResult = result ;
225+ } ) ;
226+ } ;
206227
207- } ] )
228+ }
229+ ] )
208230 . directive ( 'fileInput' , function ( ) {
209231 // helper to be able to retrieve HTML5 File in ngModel from input
210232 return {
0 commit comments