swagger_yard 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +113 -0
  4. data/Rakefile +40 -0
  5. data/app/controllers/swagger_yard/application_controller.rb +4 -0
  6. data/app/controllers/swagger_yard/swagger_controller.rb +21 -0
  7. data/app/views/swagger_yard/swagger/doc.html.erb +80 -0
  8. data/config/routes.rb +6 -0
  9. data/lib/generators/swagger_yard/doc_generator.rb +11 -0
  10. data/lib/generators/swagger_yard/js_generator.rb +13 -0
  11. data/lib/swagger_yard.rb +113 -0
  12. data/lib/swagger_yard/api.rb +132 -0
  13. data/lib/swagger_yard/api_declaration.rb +42 -0
  14. data/lib/swagger_yard/cache.rb +50 -0
  15. data/lib/swagger_yard/engine.rb +18 -0
  16. data/lib/swagger_yard/local_dispatcher.rb +51 -0
  17. data/lib/swagger_yard/parameter.rb +9 -0
  18. data/lib/swagger_yard/parser.rb +35 -0
  19. data/lib/swagger_yard/resource_listing.rb +32 -0
  20. data/lib/swagger_yard/version.rb +3 -0
  21. data/public/swagger-ui/css/hightlight.default.css +135 -0
  22. data/public/swagger-ui/css/screen.css +1759 -0
  23. data/public/swagger-ui/images/logo_small.png +0 -0
  24. data/public/swagger-ui/images/pet_store_api.png +0 -0
  25. data/public/swagger-ui/images/throbber.gif +0 -0
  26. data/public/swagger-ui/images/wordnik_api.png +0 -0
  27. data/public/swagger-ui/lib/MD5.js +319 -0
  28. data/public/swagger-ui/lib/backbone-min.js +38 -0
  29. data/public/swagger-ui/lib/handlebars-1.0.rc.1.js +1920 -0
  30. data/public/swagger-ui/lib/highlight.7.3.pack.js +1 -0
  31. data/public/swagger-ui/lib/jquery-1.8.0.min.js +2 -0
  32. data/public/swagger-ui/lib/jquery.ba-bbq.min.js +18 -0
  33. data/public/swagger-ui/lib/jquery.slideto.min.js +1 -0
  34. data/public/swagger-ui/lib/jquery.wiggle.min.js +8 -0
  35. data/public/swagger-ui/lib/swagger.js +794 -0
  36. data/public/swagger-ui/lib/underscore-min.js +32 -0
  37. data/public/swagger-ui/swagger-ui.js +2090 -0
  38. data/public/swagger-ui/swagger-ui_org.js +2005 -0
  39. metadata +125 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b7bdd63ad3c131a6f6d1a72c1c773a6b083dc13b
4
+ data.tar.gz: e1e5bba9bf16d673fc157c20204b42d0f36c016b
5
+ SHA512:
6
+ metadata.gz: c2dfb163d06f32d74f097f87aebfffe1f4b6b905ee3475f88d825b05b05d6512127694723ffe273bf8d093ace6e0c5a04146b54e99e07f5f066176e4cd168e5e
7
+ data.tar.gz: b8e6e42710336cd98347c547959b2380d42e3b55d85d2abee6f4fb3a6bd08391bc2855a75eafc0d265bbdd82a68eeaeaee3f7e5aaa27d0a21dcb934720a1ef84
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Chris Trinh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ SwaggerYard
2
+ ==================
3
+
4
+ The SwaggerYard gem is a Rails Engine designed to parse your Yardocs API controller.
5
+ It'll create a Swagger-UI complaint JSON to be served out through where you mount SwaggerYard.
6
+ You can mount this to the Rails app serving the REST API or you could mount it as a separate Rails app.
7
+ Parsing of the Yardocs happens during the server startup and the data will be subsequently cached to the Rails cache you have defined.
8
+ If your API is large expect a slow server start up time.
9
+
10
+ Installation
11
+ -----------------
12
+
13
+ Put SwaggerYard in your Gemfile:
14
+
15
+ gem 'swagger_yard'
16
+
17
+ Install the gem with Bunder:
18
+
19
+ bundle install
20
+
21
+
22
+ Getting Started
23
+ -----------------
24
+
25
+ Place your configuration in a your rails initializers
26
+
27
+ # config/initializers/swagger_yard.rb
28
+ SwaggerYard.configure do |config|
29
+ config.swagger_version = "1.1"
30
+ config.api_version = "0.1"
31
+ config.doc_base_path = "http://swagger.example.com/doc"
32
+ config.api_base_path = "http://swagger.example.com/api"
33
+ end
34
+
35
+ Mount your engine
36
+
37
+ # config/routes.rb
38
+ mount SwaggerYard::Engine, at: "/swagger"
39
+
40
+
41
+ Example
42
+ ----------------
43
+
44
+ Here is a example of how to use SwaggerYard
45
+
46
+
47
+ # @resource Account ownership
48
+ #
49
+ # @resource_path /accounts/ownerships
50
+ #
51
+ # This document describes the API for creating, reading, and deleting account ownerships.
52
+ #
53
+ class Accounts::OwnershipsController < ActionController::Base
54
+ ##
55
+ # Returns a list of ownerships associated with the account.
56
+ #
57
+ # @notes Status can be -1(Deleted), 0(Inactive), 1(Active), 2(Expired) and 3(Cancelled).
58
+ #
59
+ # @path [GET] /accounts/ownerships.{format_type}
60
+ #
61
+ # @parameter [Integer] offset Used for pagination of response data (default: 25 items per response). Specifies the offset of the next block of data to receive.
62
+ # @parameter [Array] status Filter by status. (e.g. status[]=1&status[]=2&status[]=3).
63
+ # @parameter_list [String] sort_order Orders response by fields. (e.g. sort_order=created_at).
64
+ # [List] id
65
+ # [List] begin_at
66
+ # [List] end_at
67
+ # [List] created_at
68
+ # @parameter [Boolean] sort_descending Reverse order of sort_order sorting, make it descending.
69
+ # @parameter [Date] begin_at_greater Filters response to include only items with begin_at >= specified timestamp (e.g. begin_at_greater=2012-02-15T02:06:56Z).
70
+ # @parameter [Date] begin_at_less Filters response to include only items with begin_at <= specified timestamp (e.g. begin_at_less=2012-02-15T02:06:56Z).
71
+ # @parameter [Date] end_at_greater Filters response to include only items with end_at >= specified timestamp (e.g. end_at_greater=2012-02-15T02:06:56Z).
72
+ # @parameter [Date] end_at_less Filters response to include only items with end_at <= specified timestamp (e.g. end_at_less=2012-02-15T02:06:56Z).
73
+ #
74
+ def index
75
+ ...
76
+ end
77
+ end
78
+
79
+
80
+ ![Web UI](https://raw.github.com/synctv/swagger_yard/master/example/web-ui.png)
81
+
82
+
83
+ Generators
84
+ ----------------
85
+
86
+ There are two generators that you can use
87
+
88
+ rails g swagger_yard:ui
89
+ rails g swagger_yard:js
90
+
91
+ They both copy over their respective files over to your Rails app to be customized.
92
+ See [rails engines overriding views](http://guides.rubyonrails.org/engines.html#overriding-views) for more info
93
+
94
+ Copying over JS requires that ActionDispatch::Static middleware be used (by default it should in use).
95
+
96
+
97
+ Notes
98
+ -----------------
99
+
100
+ By default SwaggerYard will use a slightly modify version of the swagger-ui. Changes to the JS code are indicated with "SwaggerYard changes" comments. The changes are mainly to support Rails way of supporting an array of parameters.
101
+
102
+
103
+ More Information
104
+ -----------------
105
+
106
+ [Swagger-ui](https://github.com/wordnik/swagger-ui)
107
+ [Yard](https://github.com/lsegal/yard)
108
+
109
+
110
+ Author
111
+ -----------------
112
+
113
+ Chris Trinh
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'SwaggerYard'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,4 @@
1
+ module SwaggerYard
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,21 @@
1
+ module SwaggerYard
2
+ class SwaggerController < ApplicationController
3
+ layout false
4
+
5
+ def index
6
+ swagger_listing = SwaggerYard.get_listing
7
+ swagger_listing.merge!("basePath" => request.url) if swagger_listing["basePath"].blank?
8
+ render :json => swagger_listing
9
+ end
10
+
11
+ def show
12
+ swagger_api = SwaggerYard.get_api("/#{params[:resource]}")
13
+ swagger_api.merge!("basePath" => request.base_url + SwaggerYard.api_path) if swagger_api["basePath"].blank?
14
+ render :json => swagger_api
15
+ end
16
+
17
+ def doc
18
+ render :doc
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,80 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Swagger UI</title>
5
+ <link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
6
+ <link href='../swagger-ui/css/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
7
+ <link href='../swagger-ui/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
8
+ <script src='../swagger-ui/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
9
+ <script src='../swagger-ui/lib/jquery.slideto.min.js' type='text/javascript'></script>
10
+ <script src='../swagger-ui/lib/jquery.wiggle.min.js' type='text/javascript'></script>
11
+ <script src='../swagger-ui/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
12
+ <script src='../swagger-ui/lib/handlebars-1.0.rc.1.js' type='text/javascript'></script>
13
+ <script src='../swagger-ui/lib/underscore-min.js' type='text/javascript'></script>
14
+ <script src='../swagger-ui/lib/backbone-min.js' type='text/javascript'></script>
15
+ <script src='../swagger-ui/lib/swagger.js' type='text/javascript'></script>
16
+ <script src='../swagger-ui/lib/MD5.js' type='text/javascript'></script>
17
+ <script src='../swagger-ui/lib/highlight.7.3.pack.js' type='text/javascript'></script>
18
+ <script src='../swagger-ui/swagger-ui.js' type='text/javascript'></script>
19
+
20
+ <script type="text/javascript">
21
+ $(function () {
22
+ window.swaggerUi = new SwaggerUi({
23
+ discoveryUrl: location.protocol + "//" + location.host + "/swagger/api",
24
+ dom_id:"swagger-ui-container",
25
+ supportHeaderParams: true,
26
+ supportedSubmitMethods: ['get', 'post', 'put'],
27
+ onComplete: function(swaggerApi, swaggerUi){
28
+ if(console) {
29
+ console.log("Loaded SwaggerUI")
30
+ console.log(swaggerApi);
31
+ console.log(swaggerUi);
32
+ }
33
+ $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
34
+ },
35
+ onFailure: function(data) {
36
+ if(console) {
37
+ console.log("Unable to Load SwaggerUI");
38
+ console.log(data);
39
+ }
40
+ },
41
+ docExpansion: "none"
42
+ });
43
+
44
+ window.swaggerUi.load();
45
+ });
46
+
47
+ </script>
48
+ </head>
49
+
50
+ <body>
51
+ <div id='header'>
52
+ <div class="swagger-ui-wrap">
53
+ <a id="logo" href="http://swagger.wordnik.com">swagger</a>
54
+
55
+ <form id='api_selector'>
56
+ <div class='input icon-btn'>
57
+ <img id="show-pet-store-icon" src="../swagger-ui/images/pet_store_api.png" title="Show Swagger Petstore Example Apis">
58
+ </div>
59
+ <div class='input icon-btn'>
60
+ <img id="show-wordnik-dev-icon" src="../swagger-ui/images/wordnik_api.png" title="Show Wordnik Developer Apis">
61
+ </div>
62
+ <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl"
63
+ type="text"/></div>
64
+ <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
65
+ <div class='input'><a id="explore" href="#">Explore</a></div>
66
+ </form>
67
+ </div>
68
+ </div>
69
+
70
+ <div id="message-bar" class="swagger-ui-wrap">
71
+ &nbsp;
72
+ </div>
73
+
74
+ <div id="swagger-ui-container" class="swagger-ui-wrap">
75
+
76
+ </div>
77
+
78
+ </body>
79
+
80
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ SwaggerYard::Engine.routes.draw do
2
+ get '/doc', to: 'swagger#doc'
3
+
4
+ get '/api', to: 'swagger#index'
5
+ get '/api/*resource', to: 'swagger#show'
6
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails/generators'
2
+ module SwaggerYard
3
+ class DocGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../../../../app/views/swagger_yard/swagger", __FILE__)
5
+ desc "Add swagger-ui doc ERB file to app/views for customization"
6
+
7
+ def generate_layout
8
+ copy_file "doc.html.erb", "app/views/swagger_yard/swagger/doc.html.erb"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/generators'
2
+
3
+ module SwaggerYard
4
+ class JsGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("../../../../public/swagger-ui", __FILE__)
6
+ desc "Add swagger-ui js to /public for customization"
7
+
8
+ def generate_layout
9
+ copy_file "swagger-ui_org.js", "public/swagger-ui/swagger-ui.js"
10
+ directory "lib", "public/swagger-ui/lib"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,113 @@
1
+ require "yard"
2
+ require "swagger_yard/engine"
3
+ require "swagger_yard/cache"
4
+ require "swagger_yard/parser"
5
+
6
+ module SwaggerYard
7
+ class << self
8
+ ##
9
+ # Configuration for Swagger Yard, use like:
10
+ #
11
+ # SwaggerYard.configure do |config|
12
+ # config.swagger_version = "1.1"
13
+ # config.api_version = "0.1"
14
+ # config.doc_base_path = "http://swagger.example.com/doc"
15
+ # config.api_base_path = "http://swagger.example.com/api"
16
+ # end
17
+ def configure
18
+ yield self
19
+ end
20
+
21
+ attr_accessor :doc_base_path, :api_base_path, :api_path
22
+ attr_writer :swagger_version, :api_version, :cache_store, :cache_prefix, :enable, :reload
23
+
24
+ def cache_store
25
+ @cache_store ||= Rails.cache
26
+ end
27
+
28
+ def cache_prefix
29
+ @cache_prefix ||= "swagger_yard/"
30
+ end
31
+
32
+ def swagger_version
33
+ @swagger_version ||= "1.1"
34
+ end
35
+
36
+ def api_version
37
+ @api_version ||= "0.1"
38
+ end
39
+
40
+ def enable
41
+ @enable ||= false
42
+ end
43
+
44
+ def reload
45
+ @reload ||= false
46
+ end
47
+
48
+ def resource_to_file_path
49
+ @resource_to_file_path ||= {}
50
+ end
51
+
52
+ def parse_file(file_path)
53
+ ::YARD.parse(file_path)
54
+ yard_objects = ::YARD::Registry.all
55
+ ::YARD::Registry.clear
56
+ @parser.run(yard_objects)
57
+ end
58
+
59
+ def generate!(controller_path)
60
+ register_custom_yard_tags!
61
+ @controller_path = controller_path
62
+ cache.fetch("listing_index") { parse_controllers }
63
+ end
64
+
65
+ def get_api(resource_name)
66
+ if reload
67
+ parse_file(resource_to_file_path[resource_name]).to_h
68
+ else
69
+ cache.fetch(resource_name) { parse_file(resource_to_file_path[resource_name]).to_h }
70
+ end
71
+ end
72
+
73
+ def get_listing
74
+ if reload
75
+ parse_controllers
76
+ else
77
+ cache.fetch("listing_index") { parse_controllers }
78
+ end
79
+ end
80
+
81
+ private
82
+ ##
83
+ # Register some custom yard tags used by swagger-ui
84
+ def register_custom_yard_tags!
85
+ ::YARD::Tags::Library.define_tag("Api resource", :resource)
86
+ ::YARD::Tags::Library.define_tag("Resource path", :resource_path)
87
+ ::YARD::Tags::Library.define_tag("Api path", :path)
88
+ ::YARD::Tags::Library.define_tag("Parameter", :parameter)
89
+ ::YARD::Tags::Library.define_tag("Parameter list", :parameter_list)
90
+ ::YARD::Tags::Library.define_tag("Status code", :status_code)
91
+ ::YARD::Tags::Library.define_tag("Implementation notes", :notes)
92
+ ::YARD::Tags::Library.define_tag("Response class", :response_class)
93
+ ::YARD::Tags::Library.define_tag("Api Summary", :summary)
94
+ end
95
+
96
+ def cache
97
+ @cache ||= Cache.new(cache_store, cache_prefix)
98
+ end
99
+
100
+ def parse_controllers
101
+ @parser = Parser.new
102
+
103
+ Dir[@controller_path].each do |file|
104
+ if api_declaration = parse_file(file)
105
+ resource_to_file_path[api_declaration.resource_name] = file
106
+ cache[api_declaration.resource_name] = api_declaration.to_h
107
+ end
108
+ end
109
+
110
+ @parser.listing.to_h
111
+ end
112
+ end
113
+ end