apidoco 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +149 -0
- data/Rakefile +34 -0
- data/app/assets/config/apidoco_manifest.js +2 -0
- data/app/assets/javascripts/apidoco/apidoco_app.js +3 -0
- data/app/assets/javascripts/apidoco/application.js +15 -0
- data/app/assets/javascripts/apidoco/bootstrap/bootstrap.min.js +7 -0
- data/app/assets/javascripts/apidoco/controllers/documentations_controller.js +26 -0
- data/app/assets/javascripts/apidoco/directives/angular-scroll.min.js.map +1 -0
- data/app/assets/javascripts/apidoco/directives/angular_scroll.min.js +2 -0
- data/app/assets/javascripts/apidoco/directives/ng_prettyjson.min.js +22 -0
- data/app/assets/javascripts/apidoco/jquery.min.js +5 -0
- data/app/assets/stylesheets/apidoco/application.css +15 -0
- data/app/assets/stylesheets/apidoco/bootstrap/bootstrap.min.css +6 -0
- data/app/assets/stylesheets/apidoco/bootstrap/bootstrap.min.css.map +1 -0
- data/app/assets/stylesheets/apidoco/custom.css +15 -0
- data/app/assets/stylesheets/apidoco/fonts/glyphicons-halflings-regular.eot +0 -0
- data/app/assets/stylesheets/apidoco/fonts/glyphicons-halflings-regular.svg +288 -0
- data/app/assets/stylesheets/apidoco/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/app/assets/stylesheets/apidoco/fonts/glyphicons-halflings-regular.woff +0 -0
- data/app/assets/stylesheets/apidoco/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/app/assets/stylesheets/apidoco/helpers.css +12 -0
- data/app/assets/stylesheets/apidoco/ng-prettyjson.min.css +7 -0
- data/app/assets/stylesheets/apidoco/simple-sidebar.css +127 -0
- data/app/controllers/apidoco/apis_controller.rb +22 -0
- data/app/controllers/apidoco/application_controller.rb +5 -0
- data/app/helpers/apidoco/application_helper.rb +9 -0
- data/app/jobs/apidoco/application_job.rb +4 -0
- data/app/mailers/apidoco/application_mailer.rb +6 -0
- data/app/models/apidoco/application_record.rb +5 -0
- data/app/views/apidoco/apis/_side_bar.html.erb +20 -0
- data/app/views/apidoco/apis/show.html.erb +73 -0
- data/app/views/layouts/apidoco/application.html.erb +14 -0
- data/config/routes.rb +4 -0
- data/lib/apidoco.rb +8 -0
- data/lib/apidoco/engine.rb +5 -0
- data/lib/apidoco/resource_documentation.rb +19 -0
- data/lib/apidoco/version.rb +3 -0
- data/lib/apidoco/version_documentation.rb +32 -0
- data/lib/apidoco/version_parser.rb +24 -0
- data/lib/generators/apidoco_generator.rb +82 -0
- data/lib/tasks/apidoco_tasks.rake +4 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +5 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +34 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +15 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +9 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +54 -0
- data/spec/dummy/config/environments/production.rb +86 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/new_framework_defaults.rb +24 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/puma.rb +47 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/generators/apidoco_generator_spec.rb +34 -0
- data/spec/rails_helper.rb +57 -0
- data/spec/spec_helper.rb +17 -0
- metadata +281 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* @license ng-prettyjson - v0.2.0
|
3
|
+
* (c) 2013 Julien VALERY https://github.com/darul75/ng-prettyjson
|
4
|
+
* License: MIT
|
5
|
+
**/
|
6
|
+
|
7
|
+
pre.pretty-json{outline:1px solid #e9e9e9;padding:5px;margin:5px}pre.pretty-json span.string{color:green}pre.pretty-json span.number{color:#ff8c00}pre.pretty-json span.boolean{color:#00f}pre.pretty-json span.null{color:#ff00ff}pre.pretty-json span.key{color:red}pre.pretty-json span.sep{color:#000}
|
@@ -0,0 +1,127 @@
|
|
1
|
+
/*!
|
2
|
+
* Start Bootstrap - Simple Sidebar (http://startbootstrap.com/)
|
3
|
+
* Copyright 2013-2016 Start Bootstrap
|
4
|
+
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE)
|
5
|
+
*/
|
6
|
+
|
7
|
+
body {
|
8
|
+
overflow-x: hidden;
|
9
|
+
}
|
10
|
+
|
11
|
+
/* Toggle Styles */
|
12
|
+
|
13
|
+
#wrapper {
|
14
|
+
padding-left: 0;
|
15
|
+
-webkit-transition: all 0.5s ease;
|
16
|
+
-moz-transition: all 0.5s ease;
|
17
|
+
-o-transition: all 0.5s ease;
|
18
|
+
transition: all 0.5s ease;
|
19
|
+
}
|
20
|
+
|
21
|
+
#wrapper.toggled {
|
22
|
+
padding-left: 250px;
|
23
|
+
}
|
24
|
+
|
25
|
+
#sidebar-wrapper {
|
26
|
+
z-index: 1000;
|
27
|
+
position: fixed;
|
28
|
+
left: 250px;
|
29
|
+
width: 0;
|
30
|
+
height: 100%;
|
31
|
+
margin-left: -250px;
|
32
|
+
overflow-y: auto;
|
33
|
+
background: #000;
|
34
|
+
-webkit-transition: all 0.5s ease;
|
35
|
+
-moz-transition: all 0.5s ease;
|
36
|
+
-o-transition: all 0.5s ease;
|
37
|
+
transition: all 0.5s ease;
|
38
|
+
}
|
39
|
+
|
40
|
+
#wrapper.toggled #sidebar-wrapper {
|
41
|
+
width: 250px;
|
42
|
+
}
|
43
|
+
|
44
|
+
#page-content-wrapper {
|
45
|
+
width: 100%;
|
46
|
+
position: absolute;
|
47
|
+
padding: 15px;
|
48
|
+
}
|
49
|
+
|
50
|
+
#wrapper.toggled #page-content-wrapper {
|
51
|
+
position: absolute;
|
52
|
+
margin-right: -250px;
|
53
|
+
}
|
54
|
+
|
55
|
+
/* Sidebar Styles */
|
56
|
+
|
57
|
+
.sidebar-nav {
|
58
|
+
position: absolute;
|
59
|
+
top: 0;
|
60
|
+
width: 250px;
|
61
|
+
margin: 0;
|
62
|
+
padding: 0;
|
63
|
+
list-style: none;
|
64
|
+
}
|
65
|
+
|
66
|
+
.sidebar-nav li {
|
67
|
+
text-indent: 20px;
|
68
|
+
line-height: 40px;
|
69
|
+
}
|
70
|
+
|
71
|
+
.sidebar-nav li a {
|
72
|
+
display: block;
|
73
|
+
text-decoration: none;
|
74
|
+
color: #999999;
|
75
|
+
}
|
76
|
+
|
77
|
+
.sidebar-nav li a:hover,
|
78
|
+
.sidebar-nav li a:active,
|
79
|
+
.sidebar-nav li a.active,
|
80
|
+
.sidebar-nav li a:focus {
|
81
|
+
text-decoration: none;
|
82
|
+
color: #fff;
|
83
|
+
background: rgba(255,255,255,0.2);
|
84
|
+
}
|
85
|
+
|
86
|
+
.sidebar-nav > .sidebar-brand {
|
87
|
+
height: 65px;
|
88
|
+
font-size: 18px;
|
89
|
+
line-height: 60px;
|
90
|
+
}
|
91
|
+
|
92
|
+
.sidebar-nav > .sidebar-brand a {
|
93
|
+
color: #999999;
|
94
|
+
}
|
95
|
+
|
96
|
+
.sidebar-nav > .sidebar-brand a:hover {
|
97
|
+
color: #fff;
|
98
|
+
background: none;
|
99
|
+
}
|
100
|
+
|
101
|
+
@media(min-width:768px) {
|
102
|
+
#wrapper {
|
103
|
+
padding-left: 250px;
|
104
|
+
}
|
105
|
+
|
106
|
+
#wrapper.toggled {
|
107
|
+
padding-left: 0;
|
108
|
+
}
|
109
|
+
|
110
|
+
#sidebar-wrapper {
|
111
|
+
width: 250px;
|
112
|
+
}
|
113
|
+
|
114
|
+
#wrapper.toggled #sidebar-wrapper {
|
115
|
+
width: 0;
|
116
|
+
}
|
117
|
+
|
118
|
+
#page-content-wrapper {
|
119
|
+
padding: 20px;
|
120
|
+
position: relative;
|
121
|
+
}
|
122
|
+
|
123
|
+
#wrapper.toggled #page-content-wrapper {
|
124
|
+
position: relative;
|
125
|
+
margin-right: 0;
|
126
|
+
}
|
127
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_dependency "apidoco/application_controller"
|
2
|
+
|
3
|
+
module Apidoco
|
4
|
+
class ApisController < ApplicationController
|
5
|
+
before_action :set_version_parser
|
6
|
+
|
7
|
+
def index
|
8
|
+
redirect_to api_path(id: @vp.documentations.first.name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
@documentation = @vp.documentation(params[:id])
|
13
|
+
@data = @documentation.as_json
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def set_version_parser
|
19
|
+
@vp = VersionParser.new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div id="sidebar-wrapper">
|
2
|
+
<ul class="sidebar-nav">
|
3
|
+
<li class="sidebar-brand">
|
4
|
+
<a href="#">
|
5
|
+
APIDOCO::{{currentVersion}}
|
6
|
+
</a>
|
7
|
+
</li>
|
8
|
+
<li class="padding-10">
|
9
|
+
<select class="form-control" ng-if="documentationVersions.length > 1" ng-model="currentVersion" ng-change="navigateToCurrentVersion(currentVersion);">
|
10
|
+
<option ng-repeat="version in documentationVersions" ng-value="version.name">{{version.name}}</option>
|
11
|
+
</select>
|
12
|
+
</li>
|
13
|
+
<li class="mt-10 padding-10">
|
14
|
+
<input type="text" placeholder="Search.." class="form-control input-sm" ng-model="searchKeyword" />
|
15
|
+
</li>
|
16
|
+
<li ng-repeat="x in jsonItem.apis | filter: searchKeyword">
|
17
|
+
<a href="#api_{{$index}}" du-smooth-scroll du-scrollspy>{{x.name}}</a>
|
18
|
+
</li>
|
19
|
+
</ul>
|
20
|
+
</div>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<div ng-controller="DocumentationController"
|
2
|
+
ng-init="jsonItem = <%= @data.to_json %>;
|
3
|
+
documentationVersions = <%= documentation_versions(@vp).to_json %>;
|
4
|
+
currentVersion = '<%= @documentation.version %>';">
|
5
|
+
<!-- Sidebar -->
|
6
|
+
<%= render partial: "side_bar" %>
|
7
|
+
<!-- Page Content -->
|
8
|
+
<div id="page-content-wrapper">
|
9
|
+
<div class="container-fluid">
|
10
|
+
<div class="row">
|
11
|
+
<div class="col-lg-12">
|
12
|
+
<div class="row">
|
13
|
+
<div class="col-lg-2">
|
14
|
+
<a href="#menu-toggle" class="btn btn-default glyphicon glyphicon-align-justify" id="menu-toggle"></a>
|
15
|
+
</div>
|
16
|
+
</div><br />
|
17
|
+
|
18
|
+
<div class="row">
|
19
|
+
<div class="col-lg-12 text_wheat">
|
20
|
+
<strong>BASE URL</strong>
|
21
|
+
{{ jsonItem.base_url }}
|
22
|
+
</div>
|
23
|
+
</div><br />
|
24
|
+
|
25
|
+
<div class="row api_details" ng-repeat="x in jsonItem.apis | filter: searchKeyword" id="api_{{$index}}">
|
26
|
+
<div class="col-lg-12">
|
27
|
+
<h4>{{x.name}}</h4>
|
28
|
+
<div class="row mt-10">
|
29
|
+
<div class="col-lg-2 text-right">End Point:</div>
|
30
|
+
<div class="col-lg-10">
|
31
|
+
<code>{{x.end_point}}</code>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="row mt-10">
|
36
|
+
<div class="col-lg-2 text-right">HTTP Method:</div>
|
37
|
+
<div class="col-lg-10">{{x.http_method}}</div>
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<div class="row mt-10">
|
41
|
+
<div class="col-lg-2 text-right">Params:</div>
|
42
|
+
<div class="col-lg-10">
|
43
|
+
<p ng-repeat="param in x.params">
|
44
|
+
<code>{{param.key}}
|
45
|
+
<span ng-if="param.required">
|
46
|
+
#{{param.required ? 'required' : 'optional'}}</span>
|
47
|
+
</code>
|
48
|
+
</p>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<div class="row mt-10">
|
53
|
+
<div class="col-lg-2 text-right">Examples:</div>
|
54
|
+
<div class="col-lg-10">
|
55
|
+
<div ng-repeat="example in x.examples">
|
56
|
+
<div>
|
57
|
+
<p class="text-center">Request</p>
|
58
|
+
<pre pretty-json="example.request" />
|
59
|
+
</div>
|
60
|
+
<div>
|
61
|
+
<p class="text-center">Response</p>
|
62
|
+
<pre pretty-json="example.response" />
|
63
|
+
</div>
|
64
|
+
</div>
|
65
|
+
</div>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
</div>
|
73
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html ng-app="apiDocoApp">
|
3
|
+
<head>
|
4
|
+
<title>Apidoco</title>
|
5
|
+
<%= stylesheet_link_tag "apidoco/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "apidoco/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<div id="wrapper">
|
11
|
+
<%= yield %>
|
12
|
+
</div>
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
data/lib/apidoco.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Apidoco
|
2
|
+
class ResourceDocumentation
|
3
|
+
attr_accessor :directory
|
4
|
+
|
5
|
+
def initialize(directory)
|
6
|
+
self.directory = directory
|
7
|
+
end
|
8
|
+
|
9
|
+
def as_json
|
10
|
+
children.map { |c| JSON.parse(File.read(c)) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def children
|
14
|
+
directory.children.select do |child|
|
15
|
+
child.extname.eql?('.json')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Apidoco
|
2
|
+
class VersionDocumentation
|
3
|
+
attr_accessor :directory
|
4
|
+
|
5
|
+
def initialize(directory)
|
6
|
+
self.directory = directory
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
directory.basename.to_s
|
11
|
+
end
|
12
|
+
alias_method :version, :name
|
13
|
+
|
14
|
+
def as_json
|
15
|
+
{
|
16
|
+
name: name,
|
17
|
+
base_url: "",
|
18
|
+
apis: resource_documentations.flat_map(&:as_json)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def resource_documentations
|
23
|
+
resource_directories.map { |dir| ResourceDocumentation.new(dir) }
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def resource_directories
|
29
|
+
directory.children.select(&:directory?)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Apidoco
|
2
|
+
# Parses the documentation versions, keeps track of all the documented api versions
|
3
|
+
class VersionParser
|
4
|
+
attr_accessor :base_path
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
self.base_path = Pathname('docs').join('api')
|
8
|
+
end
|
9
|
+
|
10
|
+
def documentations
|
11
|
+
documentation_directories.map { |dir| VersionDocumentation.new(dir) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def documentation(version)
|
15
|
+
documentations.find { |doc| doc.version.eql?(version) }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def documentation_directories
|
21
|
+
base_path.children.select(&:directory?)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#
|
2
|
+
# ApidocoGenerator
|
3
|
+
#
|
4
|
+
# @author sufinsha
|
5
|
+
#
|
6
|
+
class ApidocoGenerator < Rails::Generators::Base
|
7
|
+
desc 'This generator creates empty folder for api versions'
|
8
|
+
def create_apidoco_folder
|
9
|
+
resource = args[0]
|
10
|
+
|
11
|
+
resource_actions = actions(args[1..-1])
|
12
|
+
|
13
|
+
resource_actions.each do |action|
|
14
|
+
create_file "#{Rails.root}/docs/#{file_name(resource, action)}",
|
15
|
+
file_content(resource, action)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def actions(args)
|
22
|
+
return args if args.present?
|
23
|
+
|
24
|
+
[:show, :index, :create, :update, :destroy]
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_end_points_with_method(action)
|
28
|
+
end_points_with_method = {
|
29
|
+
index: {
|
30
|
+
endpoint: '.json', method: 'GET', collection: true
|
31
|
+
},
|
32
|
+
show: {
|
33
|
+
endpoint: '/:id.json', method: 'GET', collection: false
|
34
|
+
},
|
35
|
+
create: {
|
36
|
+
endpoint: '.json', method: 'POST', collection: true
|
37
|
+
},
|
38
|
+
update: {
|
39
|
+
endpoint: '/:id.json', method: 'PUT|PATCH', collection: false
|
40
|
+
},
|
41
|
+
destroy: {
|
42
|
+
endpoint: '/:id.json', method: 'DELETE', collection: false
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end_points_with_method[action] || {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def api_name(resource, action)
|
49
|
+
endpoint_with_method = default_end_points_with_method(action.intern)
|
50
|
+
resource_title = if endpoint_with_method[:collection]
|
51
|
+
resource.pluralize.titleize
|
52
|
+
else
|
53
|
+
resource.singularize.titleize
|
54
|
+
end
|
55
|
+
"#{action.to_s.titleize} #{resource_title}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def file_name(resource, action)
|
59
|
+
"#{resource}/#{action}.json"
|
60
|
+
end
|
61
|
+
|
62
|
+
def resource_name(resource)
|
63
|
+
resource.split('/').last
|
64
|
+
end
|
65
|
+
|
66
|
+
def file_content(resource, action)
|
67
|
+
endpoint_with_method = default_end_points_with_method(action.intern)
|
68
|
+
name = api_name(resource_name(resource), action)
|
69
|
+
<<-FILE
|
70
|
+
{
|
71
|
+
"name": "#{name}",
|
72
|
+
"end_point": "#{resource}#{endpoint_with_method[:endpoint]}",
|
73
|
+
"http_method": "#{endpoint_with_method[:method]}",
|
74
|
+
"params": [],
|
75
|
+
"examples": [{
|
76
|
+
"request": {},
|
77
|
+
"response": {}
|
78
|
+
}]
|
79
|
+
}
|
80
|
+
FILE
|
81
|
+
end
|
82
|
+
end
|