swagger-ui 2.2.5 → 2.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/workspace.xml +274 -111
- package/.travis.yml +14 -0
- package/Dockerfile +3 -2
- package/README.md +9 -2
- package/composer.json +23 -23
- package/dist/css/print.css +1 -1367
- package/dist/css/reset.css +1 -125
- package/dist/css/screen.css +1 -1494
- package/dist/css/style.css +1 -250
- package/dist/css/typography.css +0 -14
- package/dist/index.html +3 -1
- package/dist/lang/el.js +56 -0
- package/dist/lang/ja.js +6 -3
- package/dist/lang/zh-cn.js +3 -0
- package/dist/lib/backbone-min.js +1 -15
- package/dist/lib/es5-shim.js +1 -2065
- package/dist/lib/handlebars-4.0.5.js +3 -4608
- package/dist/lib/highlight.9.1.0.pack.js +1 -2
- package/dist/lib/highlight.9.1.0.pack_extended.js +1 -34
- package/dist/lib/jquery-1.8.0.min.js +3 -2
- package/dist/lib/jquery.ba-bbq.min.js +1 -18
- package/dist/lib/jquery.slideto.min.js +1 -1
- package/dist/lib/jquery.wiggle.min.js +1 -8
- package/dist/lib/js-yaml.min.js +2 -3
- package/dist/lib/jsoneditor.min.js +5 -11
- package/dist/lib/lodash.min.js +2 -102
- package/dist/lib/marked.js +1 -1272
- package/dist/lib/object-assign-pollyfill.js +1 -23
- package/dist/lib/sanitize-html.min.js +4 -6
- package/dist/lib/swagger-oauth.js +1 -347
- package/dist/o2c.html +3 -3
- package/dist/swagger-ui.js +634 -283
- package/dist/swagger-ui.min.js +15 -14
- package/gulpfile.js +28 -1
- package/lang/el.js +56 -0
- package/lang/ja.js +6 -3
- package/lang/zh-cn.js +3 -0
- package/lib/swagger-oauth.js +25 -13
- package/nginx.conf +27 -2
- package/package.json +5 -2
- package/src/main/html/css/print.css +11 -1
- package/src/main/html/css/screen.css +11 -1
- package/src/main/html/css/style.css +0 -2
- package/src/main/html/css/typography.css +2 -2
- package/src/main/html/index.html +3 -1
- package/src/main/html/o2c.html +3 -3
- package/src/main/javascript/helpers/handlebars.js +4 -1
- package/src/main/javascript/utils/utils.js +2 -2
- package/src/main/javascript/view/AuthView.js +59 -17
- package/src/main/javascript/view/AuthsCollection.js +5 -1
- package/src/main/javascript/view/MainView.js +1 -1
- package/src/main/javascript/view/Oauth2Model.js +33 -1
- package/src/main/javascript/view/Oauth2View.js +62 -1
- package/src/main/javascript/view/OperationView.js +30 -8
- package/src/main/javascript/view/partials/signature.js +62 -19
- package/src/main/less/auth.less +5 -0
- package/src/main/less/specs.less +7 -1
- package/src/main/less/style.less +0 -2
- package/src/main/template/oauth2.handlebars +28 -4
- package/src/main/template/operation.handlebars +5 -0
- package/src/main/template/param_required.handlebars +1 -1
- package/src/main/template/templates.js +38 -11
- package/test.sh +7 -0
- package/test.yaml +36 -0
|
@@ -2,10 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
|
|
4
4
|
defaults: {
|
|
5
|
-
scopes: {}
|
|
5
|
+
scopes: {},
|
|
6
|
+
isPasswordFlow: false,
|
|
7
|
+
clientAuthenticationType: 'none'
|
|
6
8
|
},
|
|
7
9
|
|
|
8
10
|
initialize: function () {
|
|
11
|
+
if(this.attributes && this.attributes.scopes) {
|
|
12
|
+
var attributes = _.cloneDeep(this.attributes);
|
|
13
|
+
var i, scopes = [];
|
|
14
|
+
for(i in attributes.scopes) {
|
|
15
|
+
var scope = attributes.scopes[i];
|
|
16
|
+
if(typeof scope.description === 'string') {
|
|
17
|
+
scopes[scope] = attributes.scopes[i];
|
|
18
|
+
scopes.push(attributes.scopes[i]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
attributes.scopes = scopes;
|
|
22
|
+
this.attributes = attributes;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (this.attributes && this.attributes.flow) {
|
|
26
|
+
var flow = this.attributes.flow;
|
|
27
|
+
this.set('isPasswordFlow', flow === 'password');
|
|
28
|
+
this.set('requireClientAuthentication', flow === 'application');
|
|
29
|
+
this.set('clientAuthentication', flow === 'password' || flow === 'application');
|
|
30
|
+
}
|
|
9
31
|
this.on('change', this.validate);
|
|
10
32
|
},
|
|
11
33
|
|
|
@@ -22,6 +44,16 @@ SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
|
|
|
22
44
|
|
|
23
45
|
validate: function () {
|
|
24
46
|
var valid = false;
|
|
47
|
+
if (this.get('isPasswordFlow') &&
|
|
48
|
+
(!this.get('username'))) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (this.get('clientAuthenticationType') in ['basic', 'request-body'] &&
|
|
53
|
+
(!this.get('clientId'))) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
25
57
|
var scp = this.get('scopes');
|
|
26
58
|
var idx = _.findIndex(scp, function (o) {
|
|
27
59
|
return o.checked === true;
|
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
SwaggerUi.Views.Oauth2View = Backbone.View.extend({
|
|
4
4
|
events: {
|
|
5
|
-
'change .oauth-scope': 'scopeChange'
|
|
5
|
+
'change .oauth-scope': 'scopeChange',
|
|
6
|
+
'change .oauth-username': 'setUsername',
|
|
7
|
+
'change .oauth-password': 'setPassword',
|
|
8
|
+
'change .oauth-client-authentication-type': 'setClientAuthenticationType',
|
|
9
|
+
'change .oauth-client-id': 'setClientId',
|
|
10
|
+
'change .oauth-client-secret': 'setClientSecret'
|
|
6
11
|
},
|
|
7
12
|
|
|
8
13
|
template: Handlebars.templates.oauth2,
|
|
9
14
|
|
|
15
|
+
cls: {
|
|
16
|
+
error: 'error'
|
|
17
|
+
},
|
|
18
|
+
|
|
10
19
|
render: function () {
|
|
11
20
|
this.$el.html(this.template(this.model.toJSON()));
|
|
12
21
|
|
|
@@ -18,5 +27,57 @@ SwaggerUi.Views.Oauth2View = Backbone.View.extend({
|
|
|
18
27
|
var scope = $(e.target).data('scope');
|
|
19
28
|
|
|
20
29
|
this.model.setScopes(scope, val);
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
setUsername: function (e) {
|
|
33
|
+
var val= $(e.target).val();
|
|
34
|
+
this.model.set('username', val);
|
|
35
|
+
if (val) {
|
|
36
|
+
$(e.target).removeClass(this.cls.error);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
setPassword: function (e) {
|
|
41
|
+
this.model.set('password', $(e.target).val());
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
setClientAuthenticationType: function (e) {
|
|
45
|
+
var type = $(e.target).val();
|
|
46
|
+
var $el = this.$el;
|
|
47
|
+
this.model.set('clientAuthenticationType', type);
|
|
48
|
+
|
|
49
|
+
switch(type) {
|
|
50
|
+
case 'none':
|
|
51
|
+
$el.find('.oauth-client-authentication').hide();
|
|
52
|
+
break;
|
|
53
|
+
case 'basic':
|
|
54
|
+
case 'request-body':
|
|
55
|
+
$el.find('.oauth-client-id').removeClass(this.cls.error);
|
|
56
|
+
$el.find('.oauth-client-authentication').show();
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
setClientId: function (e) {
|
|
62
|
+
var val = $(e.target).val();
|
|
63
|
+
this.model.set('clientId', val);
|
|
64
|
+
if (val) {
|
|
65
|
+
$(e.target).removeClass(this.cls.error);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
setClientSecret: function (e) {
|
|
70
|
+
this.model.set('clientSecret', $(e.target).val());
|
|
71
|
+
$(e.target).removeClass('error');
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
highlightInvalid: function () {
|
|
75
|
+
if (!this.model.get('username')) {
|
|
76
|
+
this.$el.find('.oauth-username').addClass(this.cls.error);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!this.model.get('clientId')) {
|
|
80
|
+
this.$el.find('.oauth-client-id').addClass(this.cls.error);
|
|
81
|
+
}
|
|
21
82
|
}
|
|
22
83
|
});
|
|
@@ -27,6 +27,10 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
27
27
|
if (opts.swaggerOptions.showRequestHeaders) {
|
|
28
28
|
this.model.showRequestHeaders = true;
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
if (opts.swaggerOptions.showOperationIds) {
|
|
32
|
+
this.model.showOperationIds = true;
|
|
33
|
+
}
|
|
30
34
|
}
|
|
31
35
|
return this;
|
|
32
36
|
},
|
|
@@ -83,7 +87,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
83
87
|
},
|
|
84
88
|
|
|
85
89
|
// Note: copied from CoffeeScript compiled file
|
|
86
|
-
// TODO:
|
|
90
|
+
// TODO: refactor
|
|
87
91
|
render: function() {
|
|
88
92
|
var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value, produces, isXML, isJSON;
|
|
89
93
|
isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;
|
|
@@ -258,9 +262,9 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
258
262
|
}
|
|
259
263
|
|
|
260
264
|
if (Array.isArray(this.model.security)) {
|
|
261
|
-
var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security);
|
|
265
|
+
var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security, this.model.parent.securityDefinitions);
|
|
262
266
|
|
|
263
|
-
authsModel.isLogout = !_.isEmpty(
|
|
267
|
+
authsModel.isLogout = !_.isEmpty(this.model.clientAuthorizations.authz);
|
|
264
268
|
this.authView = new SwaggerUi.Views.AuthButtonView({
|
|
265
269
|
data: authsModel,
|
|
266
270
|
router: this.router,
|
|
@@ -651,7 +655,6 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
651
655
|
|
|
652
656
|
// puts the response data in UI
|
|
653
657
|
showStatus: function(response) {
|
|
654
|
-
console.log(response.headers);
|
|
655
658
|
var url, content;
|
|
656
659
|
if (response.content === undefined) {
|
|
657
660
|
content = response.data;
|
|
@@ -673,6 +676,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
673
676
|
contentType = contentType.split(';')[0].trim();
|
|
674
677
|
}
|
|
675
678
|
}
|
|
679
|
+
|
|
676
680
|
$('.response_body', $(this.el)).removeClass('json');
|
|
677
681
|
$('.response_body', $(this.el)).removeClass('xml');
|
|
678
682
|
|
|
@@ -683,21 +687,32 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
683
687
|
|
|
684
688
|
var pre;
|
|
685
689
|
var code;
|
|
690
|
+
var skipHighlight = false;
|
|
686
691
|
if (!content) {
|
|
687
692
|
code = $('<code />').text('no content');
|
|
688
693
|
pre = $('<pre class="json" />').append(code);
|
|
689
694
|
|
|
690
695
|
// JSON
|
|
691
|
-
} else if (
|
|
696
|
+
} else if (
|
|
697
|
+
contentType === 'application/octet-stream' ||
|
|
698
|
+
headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) ||
|
|
692
699
|
headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) ||
|
|
693
700
|
headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) ||
|
|
694
701
|
headers['content-description'] && (/File Transfer/).test(headers['content-description'])) {
|
|
695
702
|
|
|
696
703
|
if ('Blob' in window) {
|
|
697
704
|
var type = contentType || 'text/html';
|
|
698
|
-
|
|
699
705
|
var a = document.createElement('a');
|
|
700
|
-
var href
|
|
706
|
+
var href;
|
|
707
|
+
|
|
708
|
+
if({}.toString.apply(content) === '[object Blob]') {
|
|
709
|
+
href = window.URL.createObjectURL(content);
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
var binaryData = [];
|
|
713
|
+
binaryData.push(content);
|
|
714
|
+
href = window.URL.createObjectURL(new Blob(binaryData, {type: type}));
|
|
715
|
+
}
|
|
701
716
|
var fileName = response.url.substr(response.url.lastIndexOf('/') + 1);
|
|
702
717
|
var download = [type, fileName, href].join(':');
|
|
703
718
|
|
|
@@ -707,6 +722,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
707
722
|
var responseFilename = /filename=([^;]*);?/.exec(disposition);
|
|
708
723
|
if(responseFilename !== null && responseFilename.length > 1) {
|
|
709
724
|
download = responseFilename[1];
|
|
725
|
+
fileName = download;
|
|
710
726
|
}
|
|
711
727
|
}
|
|
712
728
|
|
|
@@ -715,6 +731,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
715
731
|
a.innerText = 'Download ' + fileName;
|
|
716
732
|
|
|
717
733
|
pre = $('<div/>').append(a);
|
|
734
|
+
skipHighlight = true;
|
|
718
735
|
} else {
|
|
719
736
|
pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).');
|
|
720
737
|
}
|
|
@@ -788,9 +805,14 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
|
|
|
788
805
|
$('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, ' ')).replace(/\n/g, '<br>') + '</pre>');
|
|
789
806
|
}
|
|
790
807
|
|
|
808
|
+
// Call user-defined hook
|
|
809
|
+
if (opts.responseHooks && opts.responseHooks[this.nickname]) {
|
|
810
|
+
opts.responseHooks[this.nickname](response, this);
|
|
811
|
+
}
|
|
812
|
+
|
|
791
813
|
var response_body_el = $('.response_body', $(this.el))[0];
|
|
792
814
|
// only highlight the response if response is less than threshold, default state is highlight response
|
|
793
|
-
if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold) {
|
|
815
|
+
if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold || skipHighlight) {
|
|
794
816
|
return response_body_el;
|
|
795
817
|
} else {
|
|
796
818
|
return hljs.highlightBlock(response_body_el);
|
|
@@ -553,14 +553,30 @@ SwaggerUi.partials.signature = (function () {
|
|
|
553
553
|
modelsToIgnore[value.name] = value;
|
|
554
554
|
|
|
555
555
|
// Response support
|
|
556
|
-
if (value.examples && _.isPlainObject(value.examples)
|
|
557
|
-
value
|
|
556
|
+
if (value.examples && _.isPlainObject(value.examples)) {
|
|
557
|
+
value = _.cloneDeep(value);
|
|
558
|
+
var keys = Object.keys(value.examples);
|
|
559
|
+
|
|
560
|
+
_.forEach(keys, function(key) {
|
|
561
|
+
if(key.indexOf('application/json') === 0) {
|
|
562
|
+
var example = value.examples[key];
|
|
563
|
+
if (_.isString(example)) {
|
|
564
|
+
example = jsyaml.safeLoad(example);
|
|
565
|
+
}
|
|
566
|
+
value.definition.example = example;
|
|
567
|
+
return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
}
|
|
558
571
|
|
|
559
|
-
|
|
560
|
-
|
|
572
|
+
if (value.examples) {
|
|
573
|
+
value = _.cloneDeep(value);
|
|
574
|
+
var example = value.examples;
|
|
575
|
+
if (_.isString(example)) {
|
|
576
|
+
example = jsyaml.safeLoad(example);
|
|
561
577
|
}
|
|
562
|
-
|
|
563
|
-
value.definition
|
|
578
|
+
value.definition.example = example;
|
|
579
|
+
return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
|
|
564
580
|
}
|
|
565
581
|
|
|
566
582
|
return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro);
|
|
@@ -673,7 +689,8 @@ SwaggerUi.partials.signature = (function () {
|
|
|
673
689
|
return str.join('');
|
|
674
690
|
};
|
|
675
691
|
|
|
676
|
-
|
|
692
|
+
// Commenting this funtion as the names are now determined beforehand and the prefix part is exposed as a separate function | https://github.com/swagger-api/swagger-ui/issues/2577
|
|
693
|
+
/** var getName = function (name, xml) {
|
|
677
694
|
var result = name || '';
|
|
678
695
|
|
|
679
696
|
xml = xml || {};
|
|
@@ -688,6 +705,19 @@ SwaggerUi.partials.signature = (function () {
|
|
|
688
705
|
|
|
689
706
|
return result;
|
|
690
707
|
};
|
|
708
|
+
*/
|
|
709
|
+
|
|
710
|
+
var getPrefix = function (name, xml) {
|
|
711
|
+
var result = name || '';
|
|
712
|
+
|
|
713
|
+
xml = xml || {};
|
|
714
|
+
|
|
715
|
+
if (xml.prefix) {
|
|
716
|
+
result = xml.prefix + ':' + result;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return result;
|
|
720
|
+
};
|
|
691
721
|
|
|
692
722
|
var getNamespace = function (xml) {
|
|
693
723
|
var namespace = '';
|
|
@@ -723,9 +753,12 @@ SwaggerUi.partials.signature = (function () {
|
|
|
723
753
|
var attributes = [];
|
|
724
754
|
|
|
725
755
|
if (!items) { return getErrorMessage(); }
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
756
|
+
var key = name;
|
|
757
|
+
// If there is a name specified for the array elements, use that for the array elements name | https://github.com/swagger-api/swagger-ui/issues/2577
|
|
758
|
+
if(items.xml && items.xml.name) {
|
|
759
|
+
key = items.xml.name;
|
|
760
|
+
}
|
|
761
|
+
value = createSchemaXML(key, items, models, config);
|
|
729
762
|
if (namespace) {
|
|
730
763
|
attributes.push(namespace);
|
|
731
764
|
}
|
|
@@ -811,7 +844,7 @@ SwaggerUi.partials.signature = (function () {
|
|
|
811
844
|
|
|
812
845
|
if (namespace) {
|
|
813
846
|
attrs.push(namespace);
|
|
814
|
-
}
|
|
847
|
+
}
|
|
815
848
|
|
|
816
849
|
if (!properties && !additionalProperties) { return getErrorMessage(); }
|
|
817
850
|
|
|
@@ -856,9 +889,10 @@ SwaggerUi.partials.signature = (function () {
|
|
|
856
889
|
var output, index;
|
|
857
890
|
config = config || {};
|
|
858
891
|
config.modelsToIgnore = config.modelsToIgnore || [];
|
|
892
|
+
|
|
859
893
|
var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config)
|
|
860
894
|
: getDescriptor(name, definition, models, config);
|
|
861
|
-
|
|
895
|
+
|
|
862
896
|
if (!descriptor) {
|
|
863
897
|
return getErrorMessage();
|
|
864
898
|
}
|
|
@@ -888,10 +922,10 @@ SwaggerUi.partials.signature = (function () {
|
|
|
888
922
|
if (arguments.length < 4) {
|
|
889
923
|
throw new Error();
|
|
890
924
|
}
|
|
891
|
-
|
|
892
925
|
this.config = config || {};
|
|
893
926
|
this.config.modelsToIgnore = this.config.modelsToIgnore || [];
|
|
894
|
-
|
|
927
|
+
// name is already set by getDescriptorByRef or getDescriptor function depending on the type. Only prefix, if present is needed to be set here | https://github.com/swagger-api/swagger-ui/issues/2577
|
|
928
|
+
this.name = getPrefix(name, definition.xml);
|
|
895
929
|
this.definition = definition;
|
|
896
930
|
this.models = models;
|
|
897
931
|
this.type = type;
|
|
@@ -901,8 +935,15 @@ SwaggerUi.partials.signature = (function () {
|
|
|
901
935
|
var modelType = simpleRef($ref);
|
|
902
936
|
var model = models[modelType] || {};
|
|
903
937
|
var type = model.definition && model.definition.type ? model.definition.type : 'object';
|
|
904
|
-
|
|
905
|
-
|
|
938
|
+
// If model definition xml name is present, then that will be preferred over model name. This is the case of preferring XmlElement name over XmlRootElement name if XmlElement name is provided | https://github.com/swagger-api/swagger-ui/issues/2577
|
|
939
|
+
if(model.definition && model.definition.xml && model.definition.xml.name) {
|
|
940
|
+
name = name || model.definition.xml.name || model.name;
|
|
941
|
+
}
|
|
942
|
+
// else only model name will be considered for determination | https://github.com/swagger-api/swagger-ui/issues/2577
|
|
943
|
+
else {
|
|
944
|
+
name = name || model.name;
|
|
945
|
+
}
|
|
946
|
+
|
|
906
947
|
if (config.modelsToIgnore.indexOf($ref) > -1) {
|
|
907
948
|
type = 'loop';
|
|
908
949
|
config.loopTo = modelType;
|
|
@@ -913,13 +954,15 @@ SwaggerUi.partials.signature = (function () {
|
|
|
913
954
|
if (!model.definition) {
|
|
914
955
|
return null;
|
|
915
956
|
}
|
|
916
|
-
|
|
917
|
-
return new Descriptor(name, type, model.definition, models, config);
|
|
957
|
+
return new Descriptor(name, type, model.definition, models, config);
|
|
918
958
|
}
|
|
919
959
|
|
|
920
960
|
function getDescriptor (name, definition, models, config){
|
|
921
961
|
var type = definition.type || 'object';
|
|
922
|
-
|
|
962
|
+
// If definition xml name is present, then that will be preferred over name | https://github.com/swagger-api/swagger-ui/issues/2577
|
|
963
|
+
if(definition.xml && definition.xml.name) {
|
|
964
|
+
name = definition.xml.name || name;
|
|
965
|
+
}
|
|
923
966
|
if (!definition) {
|
|
924
967
|
return null;
|
|
925
968
|
}
|
package/src/main/less/auth.less
CHANGED
package/src/main/less/specs.less
CHANGED
|
@@ -250,7 +250,8 @@
|
|
|
250
250
|
font-size: .85em;
|
|
251
251
|
line-height: 1.2em;
|
|
252
252
|
overflow: auto;
|
|
253
|
-
|
|
253
|
+
height: 200px;
|
|
254
|
+
resize: vertical;
|
|
254
255
|
cursor: pointer;
|
|
255
256
|
}
|
|
256
257
|
ul.signature-nav {
|
|
@@ -708,6 +709,11 @@
|
|
|
708
709
|
padding: 0;
|
|
709
710
|
line-height: inherit;
|
|
710
711
|
}
|
|
712
|
+
.nickname {
|
|
713
|
+
color: #aaaaaa;
|
|
714
|
+
padding: 0;
|
|
715
|
+
line-height: inherit;
|
|
716
|
+
}
|
|
711
717
|
}
|
|
712
718
|
}
|
|
713
719
|
}
|
package/src/main/less/style.less
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
font-size: 1.5em;
|
|
5
5
|
font-weight: bold;
|
|
6
6
|
text-decoration: none;
|
|
7
|
-
background: transparent url(../images/logo.png) no-repeat left center;
|
|
8
7
|
padding: 20px 0 20px 40px;
|
|
9
8
|
}
|
|
10
9
|
|
|
@@ -84,7 +83,6 @@
|
|
|
84
83
|
width: 1500px;
|
|
85
84
|
margin: auto;
|
|
86
85
|
margin-top: 0;
|
|
87
|
-
background-image: url('../images/shield.png');
|
|
88
86
|
background-repeat: no-repeat;
|
|
89
87
|
background-position: -40px -20px;
|
|
90
88
|
margin-bottom: 210px;
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
<div>
|
|
2
|
-
<h3 class="auth__title">
|
|
2
|
+
<h3 class="auth__title">OAuth2.0</h3>
|
|
3
3
|
<p>{{{sanitize description}}}</p>
|
|
4
|
+
{{#if authorizationUrl}}<p>Authorization URL: {{{sanitize authorizationUrl}}}</p>{{/if}}
|
|
5
|
+
{{#if tokenUrl}}<p>Token URL: {{{sanitize tokenUrl}}}</p>{{/if}}
|
|
6
|
+
<p>flow: {{{escape flow}}}</p>
|
|
7
|
+
{{#if isPasswordFlow}}
|
|
8
|
+
<p>Please input username and password for password flow authorization</p>
|
|
9
|
+
<fieldset>
|
|
10
|
+
<div><label>Username: <input class="oauth-username" type="text" name="username"></label></div>
|
|
11
|
+
<div><label>Password: <input class="oauth-password" type="password" name="password"></label></div>
|
|
12
|
+
</fieldset>
|
|
13
|
+
{{/if}}
|
|
14
|
+
{{#if clientAuthentication}}
|
|
15
|
+
<p>Setup client authentication.{{#if requireClientAuthenticaiton}}(Required){{/if}}</p>
|
|
16
|
+
<fieldset>
|
|
17
|
+
<div><label>Type:
|
|
18
|
+
<select class="oauth-client-authentication-type" name="client-authentication-type">
|
|
19
|
+
<option value="none" selected>None or other</option>
|
|
20
|
+
<option value="basic">Basic auth</option>
|
|
21
|
+
<option value="request-body">Request body</option>
|
|
22
|
+
</select>
|
|
23
|
+
</label></div>
|
|
24
|
+
<div class="oauth-client-authentication" hidden>
|
|
25
|
+
<div><label>ClientId: <input class="oauth-client-id" type="text" name="client-id"></label></div>
|
|
26
|
+
<div><label>Secret: <input class="oauth-client-secret" type="text" name="client-secret"></label></div>
|
|
27
|
+
</div>
|
|
28
|
+
</fieldset>
|
|
29
|
+
{{/if}}
|
|
30
|
+
<p><strong> {{{escape appName}}} </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>
|
|
4
31
|
<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.
|
|
5
32
|
<a href="#">Learn how to use</a>
|
|
6
33
|
</p>
|
|
7
|
-
<p><strong> {{{escape appName}}} </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>
|
|
8
|
-
<p>Authorization URL: {{{sanitize authorizationUrl}}}</p>
|
|
9
|
-
<p>flow: {{{escape flow}}}</p>
|
|
10
34
|
<ul class="api-popup-scopes">
|
|
11
35
|
{{#each scopes}}
|
|
12
36
|
<li>
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
</span>
|
|
11
11
|
</h3>
|
|
12
12
|
<ul class='options'>
|
|
13
|
+
{{#if showOperationIds}}
|
|
14
|
+
<li>
|
|
15
|
+
<a href='#!/{{sanitize encodedParentId}}/{{sanitize nickname}}' class="toggleOperation"><span class="nickname">{{{escape nickname}}}()</span></a>
|
|
16
|
+
</li>
|
|
17
|
+
{{/if}}
|
|
13
18
|
<li>
|
|
14
19
|
<a href='#!/{{sanitize encodedParentId}}/{{sanitize nickname}}' class="toggleOperation"><span class="markdown">{{{escape summary}}}</span></a>
|
|
15
20
|
</li>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
{{/if}}
|
|
19
19
|
{{else}}
|
|
20
20
|
{{#if isFile}}
|
|
21
|
-
<input class='parameter
|
|
21
|
+
<input class='parameter required' type='file' name='{{{sanitize name}}}' id='{{{escape valueId}}}'/>
|
|
22
22
|
{{else}}
|
|
23
23
|
{{#renderTextParam this}}
|
|
24
24
|
{{/renderTextParam}}
|
|
@@ -212,6 +212,28 @@ templates['main'] = template({"1":function(container,depth0,helpers,partials,dat
|
|
|
212
212
|
+ " </h4>\n </div>\n</div>\n";
|
|
213
213
|
},"useData":true});
|
|
214
214
|
templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,data) {
|
|
215
|
+
var stack1;
|
|
216
|
+
|
|
217
|
+
return "<p>Authorization URL: "
|
|
218
|
+
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
|
|
219
|
+
+ "</p>";
|
|
220
|
+
},"3":function(container,depth0,helpers,partials,data) {
|
|
221
|
+
var stack1;
|
|
222
|
+
|
|
223
|
+
return "<p>Token URL: "
|
|
224
|
+
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.tokenUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
|
|
225
|
+
+ "</p>";
|
|
226
|
+
},"5":function(container,depth0,helpers,partials,data) {
|
|
227
|
+
return " <p>Please input username and password for password flow authorization</p>\n <fieldset>\n <div><label>Username: <input class=\"oauth-username\" type=\"text\" name=\"username\"></label></div>\n <div><label>Password: <input class=\"oauth-password\" type=\"password\" name=\"password\"></label></div>\n </fieldset>\n";
|
|
228
|
+
},"7":function(container,depth0,helpers,partials,data) {
|
|
229
|
+
var stack1;
|
|
230
|
+
|
|
231
|
+
return " <p>Setup client authentication."
|
|
232
|
+
+ ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.requireClientAuthenticaiton : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
233
|
+
+ "</p>\n <fieldset>\n <div><label>Type:\n <select class=\"oauth-client-authentication-type\" name=\"client-authentication-type\">\n <option value=\"none\" selected>None or other</option>\n <option value=\"basic\">Basic auth</option>\n <option value=\"request-body\">Request body</option>\n </select>\n </label></div>\n <div class=\"oauth-client-authentication\" hidden>\n <div><label>ClientId: <input class=\"oauth-client-id\" type=\"text\" name=\"client-id\"></label></div>\n <div><label>Secret: <input class=\"oauth-client-secret\" type=\"text\" name=\"client-secret\"></label></div>\n </div>\n </fieldset>\n";
|
|
234
|
+
},"8":function(container,depth0,helpers,partials,data) {
|
|
235
|
+
return "(Required)";
|
|
236
|
+
},"10":function(container,depth0,helpers,partials,data) {
|
|
215
237
|
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
|
|
216
238
|
|
|
217
239
|
return " <li>\n <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\""
|
|
@@ -223,9 +245,9 @@ templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,d
|
|
|
223
245
|
+ "</label><br/>\n <span class=\"api-scope-desc\">"
|
|
224
246
|
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
|
|
225
247
|
+ "\n"
|
|
226
|
-
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"if","hash":{},"fn":container.program(
|
|
248
|
+
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
227
249
|
+ " </span>\n </li>\n";
|
|
228
|
-
},"
|
|
250
|
+
},"11":function(container,depth0,helpers,partials,data) {
|
|
229
251
|
var stack1;
|
|
230
252
|
|
|
231
253
|
return " ("
|
|
@@ -234,16 +256,21 @@ templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,d
|
|
|
234
256
|
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
|
|
235
257
|
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
|
|
236
258
|
|
|
237
|
-
return "<div>\n <h3 class=\"auth__title\">
|
|
259
|
+
return "<div>\n <h3 class=\"auth__title\">OAuth2.0</h3>\n <p>"
|
|
238
260
|
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
|
|
239
|
-
+ "</p>\n
|
|
240
|
-
+ ((stack1 =
|
|
241
|
-
+ "
|
|
242
|
-
+ ((stack1 =
|
|
243
|
-
+ "
|
|
261
|
+
+ "</p>\n "
|
|
262
|
+
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
263
|
+
+ "\n "
|
|
264
|
+
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.tokenUrl : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
265
|
+
+ "\n <p>flow: "
|
|
244
266
|
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.flow : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
|
|
245
|
-
+ "</p>\n
|
|
246
|
-
+ ((stack1 = helpers.
|
|
267
|
+
+ "</p>\n"
|
|
268
|
+
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordFlow : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
269
|
+
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.clientAuthentication : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
270
|
+
+ " <p><strong> "
|
|
271
|
+
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.appName : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
|
|
272
|
+
+ " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n <a href=\"#\">Learn how to use</a>\n </p>\n <ul class=\"api-popup-scopes\">\n"
|
|
273
|
+
+ ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
|
|
247
274
|
+ " </ul>\n</div>";
|
|
248
275
|
},"useData":true});
|
|
249
276
|
templates['operation'] = template({"1":function(container,depth0,helpers,partials,data) {
|
|
@@ -585,7 +612,7 @@ templates['param_required'] = template({"1":function(container,depth0,helpers,pa
|
|
|
585
612
|
},"10":function(container,depth0,helpers,partials,data) {
|
|
586
613
|
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
|
|
587
614
|
|
|
588
|
-
return " <input class='parameter
|
|
615
|
+
return " <input class='parameter required' type='file' name='"
|
|
589
616
|
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
|
|
590
617
|
+ "' id='"
|
|
591
618
|
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
|
package/test.sh
ADDED
package/test.yaml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
swagger: "2.0"
|
|
2
|
+
info:
|
|
3
|
+
title: "Lorem ipsum."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
host: localhost:10010
|
|
6
|
+
basePath: /
|
|
7
|
+
schemes:
|
|
8
|
+
- "http"
|
|
9
|
+
produces:
|
|
10
|
+
- "application/json"
|
|
11
|
+
paths:
|
|
12
|
+
/authenticate:
|
|
13
|
+
post:
|
|
14
|
+
operationId: login
|
|
15
|
+
consumes:
|
|
16
|
+
- application/x-www-form-urlencoded
|
|
17
|
+
produces:
|
|
18
|
+
- text/plain
|
|
19
|
+
security: []
|
|
20
|
+
parameters:
|
|
21
|
+
- name: login
|
|
22
|
+
in: formData
|
|
23
|
+
description: Login of the user
|
|
24
|
+
type: string
|
|
25
|
+
required: true
|
|
26
|
+
- name: password
|
|
27
|
+
in: formData
|
|
28
|
+
description: Password of the user
|
|
29
|
+
type: string
|
|
30
|
+
format: password
|
|
31
|
+
required: true
|
|
32
|
+
responses:
|
|
33
|
+
'200':
|
|
34
|
+
description: Success
|
|
35
|
+
schema:
|
|
36
|
+
type: string
|