swaggard 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -0
  3. data/app/assets/fonts/swaggard/droid-sans-v6-latin-700.eot +0 -0
  4. data/app/assets/fonts/swaggard/droid-sans-v6-latin-700.svg +0 -0
  5. data/app/assets/fonts/swaggard/droid-sans-v6-latin-700.ttf +0 -0
  6. data/app/assets/fonts/swaggard/droid-sans-v6-latin-700.woff +0 -0
  7. data/app/assets/fonts/swaggard/droid-sans-v6-latin-700.woff2 +0 -0
  8. data/app/assets/fonts/swaggard/droid-sans-v6-latin-regular.eot +0 -0
  9. data/app/assets/fonts/swaggard/droid-sans-v6-latin-regular.svg +0 -0
  10. data/app/assets/fonts/swaggard/droid-sans-v6-latin-regular.ttf +0 -0
  11. data/app/assets/fonts/swaggard/droid-sans-v6-latin-regular.woff +0 -0
  12. data/app/assets/fonts/swaggard/droid-sans-v6-latin-regular.woff2 +0 -0
  13. data/app/assets/images/swaggard/explorer_icons.png +0 -0
  14. data/app/assets/images/swaggard/favicon-16x16.png +0 -0
  15. data/app/assets/images/swaggard/favicon-32x32.png +0 -0
  16. data/app/assets/images/swaggard/favicon.ico +0 -0
  17. data/app/assets/images/swaggard/logo_small.png +0 -0
  18. data/app/assets/images/swaggard/pet_store_api.png +0 -0
  19. data/app/assets/images/swaggard/throbber.gif +0 -0
  20. data/app/assets/images/swaggard/wordnik_api.png +0 -0
  21. data/app/assets/javascripts/swaggard/application.js +12 -12
  22. data/app/assets/javascripts/swaggard/lib/backbone-min.js +0 -0
  23. data/app/assets/javascripts/swaggard/lib/handlebars-2.0.0.js +0 -0
  24. data/app/assets/javascripts/swaggard/lib/highlight.7.3.pack.js +0 -0
  25. data/app/assets/javascripts/swaggard/lib/jquery-1.8.0.min.js +1 -1
  26. data/app/assets/javascripts/swaggard/lib/jquery.ba-bbq.min.js +0 -0
  27. data/app/assets/javascripts/swaggard/lib/jquery.slideto.min.js +0 -0
  28. data/app/assets/javascripts/swaggard/lib/jquery.wiggle.min.js +0 -0
  29. data/app/assets/javascripts/swaggard/lib/marked.js +0 -0
  30. data/app/assets/javascripts/swaggard/lib/swagger-oauth.js +290 -0
  31. data/app/assets/javascripts/swaggard/lib/underscore-min.js +6 -32
  32. data/app/assets/javascripts/swaggard/lib/underscore-min.map +1 -0
  33. data/app/assets/javascripts/swaggard/swaggard.js +59 -0
  34. data/app/assets/javascripts/swaggard/swagger-ui.js +31404 -1363
  35. data/app/assets/stylesheets/swaggard/application.css +1 -1
  36. data/app/assets/stylesheets/swaggard/application_print.css +15 -0
  37. data/app/assets/stylesheets/swaggard/print.css.scss +1175 -0
  38. data/app/assets/stylesheets/swaggard/reset.css +0 -0
  39. data/app/assets/stylesheets/swaggard/screen.css.scss +41 -15
  40. data/app/assets/stylesheets/swaggard/typography.css.scss +2 -1
  41. data/app/controllers/swaggard/swagger_controller.rb +3 -1
  42. data/app/views/swaggard/swagger/index.html.erb +30 -71
  43. data/config/initializers/assets.rb +1 -0
  44. data/lib/swaggard.rb +13 -7
  45. data/lib/swaggard/api_definition.rb +3 -1
  46. data/lib/swaggard/configuration.rb +18 -6
  47. data/lib/swaggard/engine.rb +8 -2
  48. data/lib/swaggard/parsers/controllers.rb +0 -2
  49. data/lib/swaggard/parsers/models.rb +1 -1
  50. data/lib/swaggard/swagger/default_response.rb +17 -0
  51. data/lib/swaggard/swagger/definition.rb +3 -1
  52. data/lib/swaggard/swagger/operation.rb +3 -0
  53. data/lib/swaggard/swagger/parameters/body.rb +4 -2
  54. data/lib/swaggard/swagger/parameters/query.rb +13 -1
  55. data/lib/swaggard/swagger/response.rb +14 -6
  56. data/lib/swaggard/swagger/type.rb +27 -42
  57. data/lib/swaggard/version.rb +1 -1
  58. data/spec/fixtures/api.json +1 -1
  59. data/spec/fixtures/dummy/app/controllers/admin/pets_controller.rb +11 -0
  60. data/spec/fixtures/dummy/config/routes.rb +4 -1
  61. data/spec/fixtures/swagger_schema.json +1495 -0
  62. data/spec/integration/swaggard_spec.rb +8 -4
  63. data/spec/spec_helper.rb +0 -1
  64. metadata +17 -8
  65. data/app/assets/javascripts/swaggard/lib/MD5.js +0 -319
  66. data/app/assets/javascripts/swaggard/lib/handlebars-1.0.rc.1.js +0 -1920
  67. data/app/assets/javascripts/swaggard/lib/shred.bundle.js +0 -2765
  68. data/app/assets/javascripts/swaggard/lib/swagger-client.js +0 -3294
  69. data/app/assets/javascripts/swaggard/lib/swagger.js +0 -794
  70. data/app/assets/javascripts/swaggard/swagger-ui_org.js +0 -2005
File without changes
@@ -274,6 +274,9 @@
274
274
  font-weight: bold;
275
275
  font-size: 25px;
276
276
  }
277
+ .swagger-section .swagger-ui-wrap .footer {
278
+ margin-top: 20px;
279
+ }
277
280
  .swagger-section .swagger-ui-wrap p.big,
278
281
  .swagger-section .swagger-ui-wrap div.big p {
279
282
  font-size: 1em;
@@ -423,6 +426,17 @@
423
426
  .swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
424
427
  font-weight: bold;
425
428
  }
429
+ .swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
430
+ .swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
431
+ display: inline;
432
+ }
433
+ .swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
434
+ display: block;
435
+ content: '';
436
+ }
437
+ .swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
438
+ margin-right: -3px;
439
+ }
426
440
  .swagger-section .swagger-ui-wrap .model-signature .propName {
427
441
  font-weight: bold;
428
442
  }
@@ -782,7 +796,7 @@
782
796
  padding: 6px 8px;
783
797
  }
784
798
  .swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
785
- background-image: image-url("swaggard/throbber.gif");
799
+ background-image: image-url('swaggard/throbber.gif');
786
800
  width: 128px;
787
801
  height: 16px;
788
802
  display: block;
@@ -793,6 +807,9 @@
793
807
  outline: 2px solid black;
794
808
  outline-color: #cc0000;
795
809
  }
810
+ .swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
811
+ max-width: 300px;
812
+ }
796
813
  .swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
797
814
  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
798
815
  padding: 10px;
@@ -1066,6 +1083,9 @@
1066
1083
  .swagger-section .swagger-ui-wrap form.form_box p strong {
1067
1084
  color: black;
1068
1085
  }
1086
+ .swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
1087
+ padding-bottom: 0;
1088
+ }
1069
1089
  .swagger-section .title {
1070
1090
  font-style: bold;
1071
1091
  }
@@ -1138,8 +1158,16 @@
1138
1158
  .swagger-section .auth {
1139
1159
  float: right;
1140
1160
  }
1141
- .swagger-section #api_information_panel {
1142
- position: absolute;
1161
+ .swagger-section .api-ic {
1162
+ height: 18px;
1163
+ vertical-align: middle;
1164
+ display: inline-block;
1165
+ background: image-url('swaggard/explorer_icons.png') no-repeat;
1166
+ }
1167
+ .swagger-section .api-ic .api_information_panel {
1168
+ position: relative;
1169
+ margin-top: 20px;
1170
+ margin-left: -5px;
1143
1171
  background: #FFF;
1144
1172
  border: 1px solid #ccc;
1145
1173
  border-radius: 5px;
@@ -1150,34 +1178,32 @@
1150
1178
  color: black;
1151
1179
  padding: 5px;
1152
1180
  }
1153
- .swagger-section #api_information_panel p .api-msg-enabled {
1181
+ .swagger-section .api-ic .api_information_panel p .api-msg-enabled {
1154
1182
  color: green;
1155
1183
  }
1156
- .swagger-section #api_information_panel p .api-msg-disabled {
1184
+ .swagger-section .api-ic .api_information_panel p .api-msg-disabled {
1157
1185
  color: red;
1158
1186
  }
1159
- .swagger-section .api-ic {
1160
- height: 18px;
1161
- vertical-align: middle;
1162
- display: inline-block;
1163
- background: image-url("swaggard/explorer_icons.png") no-repeat;
1187
+ .swagger-section .api-ic:hover .api_information_panel {
1188
+ position: absolute;
1189
+ display: block;
1164
1190
  }
1165
1191
  .swagger-section .ic-info {
1166
1192
  background-position: 0 0;
1167
1193
  width: 18px;
1168
- margin-top: -7px;
1194
+ margin-top: -6px;
1169
1195
  margin-left: 4px;
1170
1196
  }
1171
1197
  .swagger-section .ic-warning {
1172
1198
  background-position: -60px 0;
1173
1199
  width: 18px;
1174
- margin-top: -7px;
1200
+ margin-top: -6px;
1175
1201
  margin-left: 4px;
1176
1202
  }
1177
1203
  .swagger-section .ic-error {
1178
1204
  background-position: -30px 0;
1179
1205
  width: 18px;
1180
- margin-top: -7px;
1206
+ margin-top: -6px;
1181
1207
  margin-left: 4px;
1182
1208
  }
1183
1209
  .swagger-section .ic-off {
@@ -1200,7 +1226,7 @@
1200
1226
  font-size: 1.5em;
1201
1227
  font-weight: bold;
1202
1228
  text-decoration: none;
1203
- background: transparent image-url("swaggard/logo_small.png") no-repeat left center;
1229
+ background: transparent image-url('swaggard/logo_small.png') no-repeat left center;
1204
1230
  padding: 20px 0 20px 40px;
1205
1231
  color: white;
1206
1232
  }
@@ -1253,4 +1279,4 @@
1253
1279
  min-height: 30px;
1254
1280
  text-align: center;
1255
1281
  padding-top: 10px;
1256
- }
1282
+ }
@@ -3,7 +3,7 @@
3
3
  font-family: 'Droid Sans';
4
4
  font-style: normal;
5
5
  font-weight: 400;
6
- src: url('../fonts/droid-sans-v6-latin-regular.eot'); /* IE9 Compat Modes */
6
+ src: font-url('swaggard/droid-sans-v6-latin-regular.eot'); /* IE9 Compat Modes */
7
7
  src: local('Droid Sans'), local('DroidSans'),
8
8
  font-url('swaggard/droid-sans-v6-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
9
9
  font-url('swaggard/droid-sans-v6-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
@@ -11,6 +11,7 @@
11
11
  font-url('swaggard/droid-sans-v6-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
12
12
  font-url('swaggard/droid-sans-v6-latin-regular.svg#DroidSans') format('svg'); /* Legacy iOS */
13
13
  }
14
+
14
15
  /* droid-sans-700 - latin */
15
16
  @font-face {
16
17
  font-family: 'Droid Sans';
@@ -12,7 +12,9 @@ module Swaggard
12
12
  end
13
13
 
14
14
  format.json do
15
- render :json => Swaggard.get_doc
15
+ doc = Swaggard.get_doc(request.host_with_port)
16
+
17
+ render json: doc
16
18
  end
17
19
  end
18
20
  end
@@ -1,74 +1,33 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <title>Swagger UI</title>
5
-
6
- <%= stylesheet_link_tag 'swaggard/application', media: 'all' %>
7
- <%= javascript_include_tag 'swaggard/application' %>
8
-
9
- <script type="text/javascript">
10
- $(function () {
11
- var url = window.location.search.match(/url=([^&]+)/);
12
- if (url && url.length > 1) {
13
- url = decodeURIComponent(url[1]);
14
- } else {
15
- url = location.protocol + "//" + location.host + "/swagger.json";
16
- }
17
- window.swaggerUi = new SwaggerUi({
18
- url: url,
19
- dom_id: "swagger-ui-container",
20
- supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
21
- onComplete: function(swaggerApi, swaggerUi){
22
- $('pre code').each(function(i, e) {
23
- hljs.highlightBlock(e)
24
- });
25
- },
26
- onFailure: function(data) {
27
- log("Unable to Load SwaggerUI");
28
- },
29
- docExpansion: "none",
30
- apisSorter : "alpha"
31
- });
32
-
33
- function addApiKeyAuthorization() {
34
- var key = $('#input_apiKey')[0].value;
35
- log("key: " + key);
36
- if(key && key.trim() != "") {
37
- log("added key " + key);
38
- window.authorizations.add('key', new ApiKeyAuthorization("<%= @authentication_key %>",
39
- key,
40
- "<%= @authentication_type %>"));
41
- }
42
- }
43
-
44
- var $apiKeyInput = $('#input_apiKey');
45
-
46
- $apiKeyInput.change(function() {
47
- addApiKeyAuthorization();
48
- });
49
-
50
- var apiKey = "<%= @authentication_value %>";
51
- $apiKeyInput.val(apiKey);
52
- addApiKeyAuthorization();
53
-
54
- window.swaggerUi.load();
55
- });
56
- </script>
57
- </head>
58
-
59
- <body class="swagger-section">
60
- <div id='header'>
61
- <div class="swagger-ui-wrap">
62
- <a id="logo" href="http://swagger.io">swagger</a>
63
- <form id='api_selector'>
64
- <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
65
- <div class='input'><input placeholder="<%= @authentication_key %>" id="input_apiKey" name="apiKey" type="text"/></div>
66
- <div class='input'><a id="explore" href="#">Explore</a></div>
67
- </form>
68
- </div>
69
- </div>
70
-
71
- <div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>
72
- <div id="swagger-ui-container" class="swagger-ui-wrap"></div>
73
- </body>
3
+ <head>
4
+ <title>Swagger UI</title>
5
+
6
+ <%= favicon_link_tag 'swaggard/favicon-32x32.png', sizes: '32x32' %>
7
+ <%= favicon_link_tag 'swaggard/favicon-16x16.png', sizes: '16x16' %>
8
+
9
+ <%= stylesheet_link_tag 'swaggard/application', media: :screen %>
10
+ <%= stylesheet_link_tag 'swaggard/application_print', media: :print %>
11
+ <%= javascript_include_tag 'swaggard/application' %>
12
+
13
+ </head>
14
+
15
+ <body class='swagger-section'>
16
+ <div id='header'>
17
+ <div class='swagger-ui-wrap'>
18
+ <a id='logo' href='http://swagger.io'>swagger</a>
19
+ <%= form_tag '', id: :api_selector, data: { authentication_key: @authentication_key,
20
+ authentication_type: @authentication_type,
21
+ authentication_value: @authentication_value} do %>
22
+ <div class='input'><input placeholder='http://example.com/api' id='input_baseUrl' name='baseUrl' type='text'/></div>
23
+ <div class='input'><input placeholder='<%= @authentication_key %>' id='input_apiKey' name='apiKey' type='text'/></div>
24
+ <div class='input'><a id='explore' href='#'>Explore</a></div>
25
+ <% end %>
26
+
27
+ </div>
28
+ </div>
29
+
30
+ <div id='message-bar' class='swagger-ui-wrap'>&nbsp;</div>
31
+ <div id='swagger-ui-container' class='swagger-ui-wrap'></div>
32
+ </body>
74
33
  </html>
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.precompile += %w[swaggard/application_print.css]
@@ -30,10 +30,14 @@ module Swaggard
30
30
  ::YARD::Tags::Library.define_tag('Response class', :response_class)
31
31
  end
32
32
 
33
- def get_doc
33
+ def get_doc(host)
34
34
  load!
35
35
 
36
- @api.to_doc
36
+ doc = @api.to_doc
37
+
38
+ doc['host'] = host if doc['host'].blank?
39
+
40
+ doc
37
41
  end
38
42
 
39
43
  private
@@ -71,13 +75,15 @@ module Swaggard
71
75
  parser = Parsers::Models.new
72
76
 
73
77
  definitions =[]
74
- Dir[configuration.models_path].each do |file|
75
- yard_objects = get_yard_objects(file)
78
+ configuration.models_paths.each do |path|
79
+ Dir[path].each do |file|
80
+ yard_objects = get_yard_objects(file)
76
81
 
77
- definitions.concat(parser.run(yard_objects))
78
- end
82
+ definitions.concat(parser.run(yard_objects))
83
+ end
79
84
 
80
- @api.definitions = definitions
85
+ @api.definitions = definitions
86
+ end
81
87
  end
82
88
 
83
89
  def get_yard_objects(file)
@@ -32,7 +32,9 @@ module Swaggard
32
32
  'title' => Swaggard.configuration.title,
33
33
  'termsOfService' => Swaggard.configuration.tos,
34
34
  'contact' => {
35
- 'email' => Swaggard.configuration.contact
35
+ 'name' => Swaggard.configuration.contact_name,
36
+ 'email' => Swaggard.configuration.contact_email,
37
+ 'url' => Swaggard.configuration.contact_url
36
38
  },
37
39
  'license' => {
38
40
  'name' => Swaggard.configuration.license_name,
@@ -12,11 +12,11 @@ module Swaggard
12
12
  # end
13
13
  class Configuration
14
14
 
15
- attr_accessor :doc_base_path, :api_base_path, :controllers_path, :models_path, :routes
15
+ attr_accessor :doc_base_path, :controllers_path, :models_paths, :routes
16
16
 
17
- attr_writer :swagger_version, :api_version, :api_path, :api_formats, :title, :description,
18
- :tos, :contact, :host, :authentication_type, :authentication_key,
19
- :authentication_value
17
+ attr_writer :swagger_version, :api_base_path, :api_version, :api_path, :api_formats, :title,
18
+ :description, :tos, :contact_email, :contact_name, :contact_url, :host,
19
+ :authentication_type, :authentication_key, :authentication_value
20
20
 
21
21
  def swagger_version
22
22
  @swagger_version ||= '2.0'
@@ -30,6 +30,10 @@ module Swaggard
30
30
  @api_path ||= ''
31
31
  end
32
32
 
33
+ def api_base_path
34
+ @api_base_path ||= '/'
35
+ end
36
+
33
37
  def api_formats
34
38
  @api_formats ||= [:xml, :json]
35
39
  end
@@ -54,8 +58,16 @@ module Swaggard
54
58
  @tos ||= ''
55
59
  end
56
60
 
57
- def contact
58
- @contact ||= ''
61
+ def contact_name
62
+ @contact_name ||= ''
63
+ end
64
+
65
+ def contact_email
66
+ @contact_email ||= ''
67
+ end
68
+
69
+ def contact_url
70
+ @contact_email ||= ''
59
71
  end
60
72
 
61
73
  def license_name
@@ -6,8 +6,14 @@ module Swaggard
6
6
  app.reload_routes!
7
7
 
8
8
  Swaggard.configure do |config|
9
- config.controllers_path = "#{app.root}/app/controllers/**/*.rb"
10
- config.models_path = "#{app.root}/app/serializers/**/*.rb"
9
+ unless config.controllers_path
10
+ config.controllers_path = "#{app.root}/app/controllers/**/*.rb"
11
+ end
12
+
13
+ unless config.models_paths
14
+ config.models_paths = ["#{app.root}/app/serializers/**/*.rb"]
15
+ end
16
+
11
17
  config.routes = app.routes.routes
12
18
  end
13
19
 
@@ -15,8 +15,6 @@ module Swaggard
15
15
  elsif tag && yard_object.type == :method
16
16
  operation = Swagger::Operation.new(yard_object, tag, routes)
17
17
  operations << operation if operation.valid?
18
- else
19
- break
20
18
  end
21
19
  end
22
20
 
@@ -11,7 +11,7 @@ module Swaggard
11
11
  yard_objects.each do |yard_object|
12
12
  next unless yard_object.type == :class
13
13
 
14
- definition = Swagger::Definition.new(yard_object.name)
14
+ definition = Swagger::Definition.new(yard_object.path)
15
15
 
16
16
  yard_object.tags.each do |tag|
17
17
  property = Swagger::Property.new(tag)
@@ -0,0 +1,17 @@
1
+ module Swaggard
2
+ module Swagger
3
+ class DefaultResponse
4
+
5
+ def status_code
6
+ 'default'
7
+ end
8
+
9
+ def to_doc
10
+ {
11
+ 'description' => 'successful operation'
12
+ }
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -15,7 +15,9 @@ module Swaggard
15
15
 
16
16
  def to_doc
17
17
  {
18
- 'properties' => Hash[@properties.map { |property| [property.id, property.to_doc] }]
18
+ 'type' => 'object',
19
+ 'required' => [],
20
+ 'properties' => Hash[@properties.map { |property| [property.id, property.to_doc] }]
19
21
  }
20
22
  end
21
23
 
@@ -5,6 +5,7 @@ require_relative 'parameters/path'
5
5
  require_relative 'parameters/query'
6
6
 
7
7
  require_relative 'response'
8
+ require_relative 'default_response'
8
9
 
9
10
  module Swaggard
10
11
  module Swagger
@@ -43,6 +44,8 @@ module Swaggard
43
44
  build_path_parameters(routes)
44
45
 
45
46
  @parameters.sort_by { |parameter| parameter.name }
47
+
48
+ @responses << DefaultResponse.new unless @responses.any?
46
49
  end
47
50
 
48
51
  def valid?