apidoco_dsl 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/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +166 -0
- data/LICENSE.txt +21 -0
- data/README.md +268 -0
- data/Rakefile +6 -0
- data/apidoco_dsl.gemspec +33 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/apidoco_dsl.rb +42 -0
- data/lib/apidoco_dsl/api.rb +10 -0
- data/lib/apidoco_dsl/api_doc.rb +180 -0
- data/lib/apidoco_dsl/documentable.rb +65 -0
- data/lib/apidoco_dsl/param.rb +85 -0
- data/lib/apidoco_dsl/param_group.rb +53 -0
- data/lib/apidoco_dsl/railtie.rb +14 -0
- data/lib/apidoco_dsl/version.rb +3 -0
- data/lib/generators/apidoco_dsl/documentation_generator.rb +18 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b2ac5c3c67fb00766a4f2b0e950d5a78fcb3856ca7aa326bda1190178ed4782b
|
4
|
+
data.tar.gz: c31cbdb3a36888731cfc8de10ff1126e745ba2fec09184f021655a81cd0dd7c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63e799515b3cf792abed9424abee6afca94165a84851290ef7dafa7feb9dadb8915e765bb06e143453e26965a3aa87f89c80335f91be8f949bad94ff97193493
|
7
|
+
data.tar.gz: c668eb909680132161998c93c0d47e4e1bf0c98a402690af54f3a109ed88cbf7b16f11cd77209be3c3a6201c023abce1e45ba0409b58d68ba2eff0575b946e65
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
apidoco_dsl (0.1.0)
|
5
|
+
apidoco (~> 1.5)
|
6
|
+
kramdown
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actioncable (6.0.3.1)
|
12
|
+
actionpack (= 6.0.3.1)
|
13
|
+
nio4r (~> 2.0)
|
14
|
+
websocket-driver (>= 0.6.1)
|
15
|
+
actionmailbox (6.0.3.1)
|
16
|
+
actionpack (= 6.0.3.1)
|
17
|
+
activejob (= 6.0.3.1)
|
18
|
+
activerecord (= 6.0.3.1)
|
19
|
+
activestorage (= 6.0.3.1)
|
20
|
+
activesupport (= 6.0.3.1)
|
21
|
+
mail (>= 2.7.1)
|
22
|
+
actionmailer (6.0.3.1)
|
23
|
+
actionpack (= 6.0.3.1)
|
24
|
+
actionview (= 6.0.3.1)
|
25
|
+
activejob (= 6.0.3.1)
|
26
|
+
mail (~> 2.5, >= 2.5.4)
|
27
|
+
rails-dom-testing (~> 2.0)
|
28
|
+
actionpack (6.0.3.1)
|
29
|
+
actionview (= 6.0.3.1)
|
30
|
+
activesupport (= 6.0.3.1)
|
31
|
+
rack (~> 2.0, >= 2.0.8)
|
32
|
+
rack-test (>= 0.6.3)
|
33
|
+
rails-dom-testing (~> 2.0)
|
34
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
35
|
+
actiontext (6.0.3.1)
|
36
|
+
actionpack (= 6.0.3.1)
|
37
|
+
activerecord (= 6.0.3.1)
|
38
|
+
activestorage (= 6.0.3.1)
|
39
|
+
activesupport (= 6.0.3.1)
|
40
|
+
nokogiri (>= 1.8.5)
|
41
|
+
actionview (6.0.3.1)
|
42
|
+
activesupport (= 6.0.3.1)
|
43
|
+
builder (~> 3.1)
|
44
|
+
erubi (~> 1.4)
|
45
|
+
rails-dom-testing (~> 2.0)
|
46
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
47
|
+
activejob (6.0.3.1)
|
48
|
+
activesupport (= 6.0.3.1)
|
49
|
+
globalid (>= 0.3.6)
|
50
|
+
activemodel (6.0.3.1)
|
51
|
+
activesupport (= 6.0.3.1)
|
52
|
+
activerecord (6.0.3.1)
|
53
|
+
activemodel (= 6.0.3.1)
|
54
|
+
activesupport (= 6.0.3.1)
|
55
|
+
activestorage (6.0.3.1)
|
56
|
+
actionpack (= 6.0.3.1)
|
57
|
+
activejob (= 6.0.3.1)
|
58
|
+
activerecord (= 6.0.3.1)
|
59
|
+
marcel (~> 0.3.1)
|
60
|
+
activesupport (6.0.3.1)
|
61
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
62
|
+
i18n (>= 0.7, < 2)
|
63
|
+
minitest (~> 5.1)
|
64
|
+
tzinfo (~> 1.1)
|
65
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
66
|
+
angularjs-rails (1.6.8)
|
67
|
+
apidoco (1.5.4)
|
68
|
+
angularjs-rails
|
69
|
+
rails (>= 4.0.0)
|
70
|
+
builder (3.2.4)
|
71
|
+
concurrent-ruby (1.1.6)
|
72
|
+
crass (1.0.6)
|
73
|
+
diff-lcs (1.3)
|
74
|
+
erubi (1.9.0)
|
75
|
+
globalid (0.4.2)
|
76
|
+
activesupport (>= 4.2.0)
|
77
|
+
i18n (1.8.2)
|
78
|
+
concurrent-ruby (~> 1.0)
|
79
|
+
kramdown (2.2.1)
|
80
|
+
rexml
|
81
|
+
loofah (2.5.0)
|
82
|
+
crass (~> 1.0.2)
|
83
|
+
nokogiri (>= 1.5.9)
|
84
|
+
mail (2.7.1)
|
85
|
+
mini_mime (>= 0.1.1)
|
86
|
+
marcel (0.3.3)
|
87
|
+
mimemagic (~> 0.3.2)
|
88
|
+
method_source (1.0.0)
|
89
|
+
mimemagic (0.3.5)
|
90
|
+
mini_mime (1.0.2)
|
91
|
+
mini_portile2 (2.4.0)
|
92
|
+
minitest (5.14.1)
|
93
|
+
nio4r (2.5.2)
|
94
|
+
nokogiri (1.10.9)
|
95
|
+
mini_portile2 (~> 2.4.0)
|
96
|
+
rack (2.2.2)
|
97
|
+
rack-test (1.1.0)
|
98
|
+
rack (>= 1.0, < 3)
|
99
|
+
rails (6.0.3.1)
|
100
|
+
actioncable (= 6.0.3.1)
|
101
|
+
actionmailbox (= 6.0.3.1)
|
102
|
+
actionmailer (= 6.0.3.1)
|
103
|
+
actionpack (= 6.0.3.1)
|
104
|
+
actiontext (= 6.0.3.1)
|
105
|
+
actionview (= 6.0.3.1)
|
106
|
+
activejob (= 6.0.3.1)
|
107
|
+
activemodel (= 6.0.3.1)
|
108
|
+
activerecord (= 6.0.3.1)
|
109
|
+
activestorage (= 6.0.3.1)
|
110
|
+
activesupport (= 6.0.3.1)
|
111
|
+
bundler (>= 1.3.0)
|
112
|
+
railties (= 6.0.3.1)
|
113
|
+
sprockets-rails (>= 2.0.0)
|
114
|
+
rails-dom-testing (2.0.3)
|
115
|
+
activesupport (>= 4.2.0)
|
116
|
+
nokogiri (>= 1.6)
|
117
|
+
rails-html-sanitizer (1.3.0)
|
118
|
+
loofah (~> 2.3)
|
119
|
+
railties (6.0.3.1)
|
120
|
+
actionpack (= 6.0.3.1)
|
121
|
+
activesupport (= 6.0.3.1)
|
122
|
+
method_source
|
123
|
+
rake (>= 0.8.7)
|
124
|
+
thor (>= 0.20.3, < 2.0)
|
125
|
+
rake (10.5.0)
|
126
|
+
rexml (3.2.4)
|
127
|
+
rspec (3.9.0)
|
128
|
+
rspec-core (~> 3.9.0)
|
129
|
+
rspec-expectations (~> 3.9.0)
|
130
|
+
rspec-mocks (~> 3.9.0)
|
131
|
+
rspec-core (3.9.2)
|
132
|
+
rspec-support (~> 3.9.3)
|
133
|
+
rspec-expectations (3.9.2)
|
134
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
135
|
+
rspec-support (~> 3.9.0)
|
136
|
+
rspec-mocks (3.9.1)
|
137
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
138
|
+
rspec-support (~> 3.9.0)
|
139
|
+
rspec-support (3.9.3)
|
140
|
+
sprockets (4.0.0)
|
141
|
+
concurrent-ruby (~> 1.0)
|
142
|
+
rack (> 1, < 3)
|
143
|
+
sprockets-rails (3.2.1)
|
144
|
+
actionpack (>= 4.0)
|
145
|
+
activesupport (>= 4.0)
|
146
|
+
sprockets (>= 3.0.0)
|
147
|
+
thor (1.0.1)
|
148
|
+
thread_safe (0.3.6)
|
149
|
+
tzinfo (1.2.7)
|
150
|
+
thread_safe (~> 0.1)
|
151
|
+
websocket-driver (0.7.2)
|
152
|
+
websocket-extensions (>= 0.1.0)
|
153
|
+
websocket-extensions (0.1.5)
|
154
|
+
zeitwerk (2.3.0)
|
155
|
+
|
156
|
+
PLATFORMS
|
157
|
+
ruby
|
158
|
+
|
159
|
+
DEPENDENCIES
|
160
|
+
apidoco_dsl!
|
161
|
+
bundler (~> 2.0)
|
162
|
+
rake (~> 10.0)
|
163
|
+
rspec (~> 3.0)
|
164
|
+
|
165
|
+
BUNDLED WITH
|
166
|
+
2.0.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Steve Lewis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,268 @@
|
|
1
|
+
# ApidocoDsl
|
2
|
+
|
3
|
+
This gem provides a DSL wrapper around the excellent [Apidoco Gem](https://github.com/72pulses/apidoco) for Ruby on Rails projects. The DSL is heavily inspired by the one provided by [Apipie](https://github.com/Apipie/apipie-rails), but it was developed from scratch. In our opinion, the Apidoco system is more flexible, and it's output is prettier than Apipie. The one thing it was lacking was a good DSL to produce the JSON files that make up its documentation output. That's where this gem comes in. Instead of writing JSON files by hand, using this gem you can write your documentation directly in to your code _as code_, which is later parsed and converted into the JSON files that feed the Apidoco engine.
|
4
|
+
|
5
|
+
## Compatibility with Apidoco
|
6
|
+
|
7
|
+
This DSL gem was written against the 1.5.4 version of the Apidoco gem. Later versions of Apidoco may introduce breaking changes with this gem, but we'll do our best to keep it up to date. One important point with regards to compatibility is that this gem renders Apidoco's resource generator, (`rails g apidoco resource`), unnecessary, unless there really is certain documentation you'd rather write the raw JSON file for. Using this gem, documentation that you write into your code will automatically be placed in the right locations for the Apidoco engine.
|
8
|
+
|
9
|
+
## Generating documentation
|
10
|
+
|
11
|
+
Once you've written your documentation into your code, it has to be parsed and written out to the appropriate Apidoco directory in JSON format. This gem provides a generator for this purpose that is invoked this way:
|
12
|
+
|
13
|
+
```bash
|
14
|
+
rails g apidoco_dsl:documentation
|
15
|
+
```
|
16
|
+
|
17
|
+
## Writing Documentation
|
18
|
+
|
19
|
+
### Where to write it
|
20
|
+
|
21
|
+
As mentioned before, this gem allows you to write documentation for your code using code. There are a couple ways you can do this, depending upon the needs of your project and how much you want to intermingle your functional code with your documentation.
|
22
|
+
|
23
|
+
#### Inline with the methods they document
|
24
|
+
|
25
|
+
By including the ApidocoDsl module in to the classes you want to document, you can write your documentation in the same file with the code it documents:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
class MyApiController < ApplicationController
|
29
|
+
require 'apidoco_dsl'
|
30
|
+
extend ApidocoDsl
|
31
|
+
|
32
|
+
namespace "V1"
|
33
|
+
resource :widgets
|
34
|
+
|
35
|
+
api_doc do
|
36
|
+
...
|
37
|
+
end
|
38
|
+
def show
|
39
|
+
...
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
#### In a separate class
|
45
|
+
|
46
|
+
Unlike systems like Apipie, with Apidoco and this gem, there is no inherent programmatic link between documentation and the classes/methods being documented. Because of this, it is possible, (and perhaps even preferable), to define all of your documentation in locations and classes that are entirely separate from the code they document. You are free to organize your documentation files however it makes sense to you.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
module ApiDocs
|
50
|
+
class MyResource
|
51
|
+
extend ApidocoDsl
|
52
|
+
extend ActiveSupport::Concern
|
53
|
+
|
54
|
+
api_doc do
|
55
|
+
...
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
### The DSL
|
62
|
+
|
63
|
+
At the most basic level, ApidocoDsl is used for writing documentation about the individual endpoints of your API. Doing so starts with defining an `api_doc` block. Below is a "full" doc block:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
api_doc do
|
67
|
+
published true
|
68
|
+
name "Do Something"
|
69
|
+
description "Does Something"
|
70
|
+
endpoint "/v1/do_something/"
|
71
|
+
http_method 'POST'
|
72
|
+
header({ 'Content-Type' => 'application/json', 'Authentication' => "Bearer <token>" })
|
73
|
+
|
74
|
+
param :thing1, type: 'String', desc: 'The first thing', notes: "Introduced by the Cat In The Hat", required: true
|
75
|
+
param :thing2, type: 'Integer', desc: 'The second thing', notes: "Comes with Thing 1"
|
76
|
+
|
77
|
+
example_request do
|
78
|
+
{
|
79
|
+
thing1: "This is the first thing",
|
80
|
+
thing2: 42
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
example_response path: example_root + '/create_response.json'
|
85
|
+
|
86
|
+
returns code: :created do
|
87
|
+
property :thing_id, type: 'Integer', desc: "The thing's ID", notes: "Will be a number"
|
88
|
+
param_group :carrier_connection_response
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
Note in the example above that `example_root` is a variable defined above this definition, and not actually part of the ApidocoDsl.
|
94
|
+
|
95
|
+
Everything inside the block is considered documentation for the endpoint. It may be helpful to read the [Apidoco documentation](https://github.com/72pulses/apidoco), for context on some of these, but each method is described below.
|
96
|
+
|
97
|
+
#### published
|
98
|
+
|
99
|
+
Whether or not this documentation should be 'published', that is, visible on the documentation site. By default, documentation is _not_ published. Calling this method with an argument of `true`, will make it visible.
|
100
|
+
|
101
|
+
#### name
|
102
|
+
|
103
|
+
This is the name that will be displayed on the documentation page to identify this endpoint, both as a header and in the navigation. It can be anything you want, but obviously should actually identify the endpoint being documented. It takes a string.
|
104
|
+
|
105
|
+
#### description
|
106
|
+
|
107
|
+
A longer-form description of the endpoint. This method takes either a string _or_ a path argument. Given a string, it will simply display that string. Given a path, it will parse the provided file, (as Markdown), and use the result as the description for the endpoint.
|
108
|
+
|
109
|
+
#### endpoint
|
110
|
+
|
111
|
+
The URL for the endpoint being documented. It will be copied as is into the final documentation for the endpoint. By convention, any parameters provided in the endpoint url are preceded by colons, like this:
|
112
|
+
|
113
|
+
`endpoint: "v1/customers/:id"`
|
114
|
+
|
115
|
+
#### http_method
|
116
|
+
|
117
|
+
Which HTTP method(s) to use when calling this endpoint. This is a string that will be passed, as-is to the final documentation. For endpoints that accept more than one method, (`PUT` or `PATCH`, for instance), separate them with pipes: `PUT|PATCH`.
|
118
|
+
|
119
|
+
#### header
|
120
|
+
|
121
|
+
What, if any sort of headers to include in the request to this endpoint. Common choices might be a `Content-Type` header or an `Authentication` header.
|
122
|
+
|
123
|
+
#### param
|
124
|
+
|
125
|
+
This method defines a param for this endpoint. It is discussed in more detail below.
|
126
|
+
|
127
|
+
#### property
|
128
|
+
|
129
|
+
Like a `param`, but generally used to define _responses_ rather than requests. Discussed in more detail below.
|
130
|
+
|
131
|
+
#### param_group
|
132
|
+
|
133
|
+
A param_group is used to, literally, group a set of params or properties together. This may be done for simple organizatonal reasons, but it is most useful for creating sets of parameters that can be reused in multiple endpoint definitions. Param groups are discussed in more detail below.
|
134
|
+
|
135
|
+
#### example_request / example_response
|
136
|
+
|
137
|
+
There are two ways to provide an example request or an example response for an endpoint. The first is to provide a block to the method itself, adding your example inside:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
example_request do
|
141
|
+
{ "param1": "foo", "param2": "bar" }
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
The hash will be automatically converted to JSON for presentation purposes.
|
146
|
+
|
147
|
+
|
148
|
+
Alternatively, you can provide a `path` argument that points to a `json` file:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
example_request path: "/examples/endpoint_request.json"
|
152
|
+
```
|
153
|
+
|
154
|
+
#### returns
|
155
|
+
|
156
|
+
If your API endpoint returns any properties, the `returns` method allows you to specify what they are by identifying them as properties:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
returns do
|
160
|
+
property :response_1, type: "String", desc: "The first part of the response"
|
161
|
+
property :response_2, type: "Integer", desc:
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
You can also specify a response `code`, whether or not the endpoint returns any other properties. If not specified, the `code` is 200.
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
returns code: 203 do
|
169
|
+
...
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
### Params and Properties
|
174
|
+
|
175
|
+
Describing which parameters your endpoints take and what properties they return is handled by the `param` and `property` methods respectively. These methods work the same way and are technically interchangeable. The only difference is that any defined properties
|
176
|
+
are considered `required` by default.
|
177
|
+
|
178
|
+
Here's an example param:
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
param :age, type: 'Integer', desc: "How old this person is.", notes: "Used for setting various interface options", validations: "Must be a positive integer.", required: true
|
182
|
+
```
|
183
|
+
|
184
|
+
A param/property takes the following attributes:
|
185
|
+
|
186
|
+
#### name
|
187
|
+
|
188
|
+
The name of the param/property is the first argument to the method and is always required. Note that it is a positional argument, not a kwarg.
|
189
|
+
|
190
|
+
#### type
|
191
|
+
|
192
|
+
A kwarg that describes the "type" of the parameter. If you provide a string, this value can be anything you want. It's also possible to pass any valid Ruby type, (String, Array, Hash, etc.), without enclosing it in a string. The `type` argument is required.
|
193
|
+
|
194
|
+
#### desc
|
195
|
+
|
196
|
+
An optional kwarg that takes a string describing the parameter. For the sake of formatting, it's best if the description is kept relatively short.
|
197
|
+
|
198
|
+
#### notes
|
199
|
+
|
200
|
+
An optional kwarg for providing additional context or information about a parameter. For the sake of formatting, it's best if the description is kept relatively short. Notes are an optional means of highlighting specific information about a parameter, (such as acceptable values), etc.
|
201
|
+
|
202
|
+
#### validations
|
203
|
+
|
204
|
+
An optional kwarg for adding a note about any validations present on the given parameter. For the sake of formatting, it's best if the validations argument is kept relatively short.
|
205
|
+
|
206
|
+
#### required
|
207
|
+
|
208
|
+
Whether or not this parameter is required. Take a boolean and defaults to `false` for a param and `true` for a property.
|
209
|
+
|
210
|
+
### Param Groups
|
211
|
+
|
212
|
+
Param groups allow you to define a set of parameters that can be shared between individual documentation blocks, reducing duplication. You define them by calling `def_param_group`:
|
213
|
+
|
214
|
+
```ruby
|
215
|
+
def_param_group :my_group do
|
216
|
+
param :param1, type: "Integer", desc: "The first param"
|
217
|
+
param :param2, type: "Integer", desc: "The second param"
|
218
|
+
end
|
219
|
+
```
|
220
|
+
You can define params or properties inside of a param group just like you would inside of an `api_doc` block. To add a param group to a doc block, use the `param_group` method:
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
api_doc do
|
224
|
+
...
|
225
|
+
|
226
|
+
param_group :my_group
|
227
|
+
|
228
|
+
...
|
229
|
+
|
230
|
+
returns do
|
231
|
+
param_group :my_response_group
|
232
|
+
end
|
233
|
+
end
|
234
|
+
```
|
235
|
+
|
236
|
+
The `param_group` method takes a single argument, the name of the param group you want to invoke.
|
237
|
+
|
238
|
+
Once a param group is defined, it can be used in _any_ documentation block, even those that are in a different source file. For that reason, it may be convenient to define your param groups in files separate from your api documentation itself.
|
239
|
+
|
240
|
+
## Installation
|
241
|
+
|
242
|
+
Add this line to your application's Gemfile:
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
gem 'apidoco_dsl'
|
246
|
+
```
|
247
|
+
|
248
|
+
And then execute:
|
249
|
+
|
250
|
+
$ bundle
|
251
|
+
|
252
|
+
Or install it yourself as:
|
253
|
+
|
254
|
+
$ gem install apidoco_dsl
|
255
|
+
|
256
|
+
## Development
|
257
|
+
|
258
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
259
|
+
|
260
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
261
|
+
|
262
|
+
## Contributing
|
263
|
+
|
264
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/apidoco_dsl.
|
265
|
+
|
266
|
+
## License
|
267
|
+
|
268
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/apidoco_dsl.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "apidoco_dsl/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "apidoco_dsl"
|
7
|
+
spec.version = ApidocoDsl::VERSION
|
8
|
+
spec.authors = ["Steve Lewis"]
|
9
|
+
spec.email = ["steve.l@lojistic.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{ Provides a block-based DSL for apidoco similar to ApiPie }
|
12
|
+
spec.homepage = "https://github.com/lojistic/apidoco_dsl"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
16
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
17
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
18
|
+
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
spec.bindir = "exe"
|
25
|
+
spec.add_dependency "apidoco", "~> 1.5"
|
26
|
+
spec.add_dependency "kramdown"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
31
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
32
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "apidoco_dsl"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/apidoco_dsl.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "apidoco_dsl/version"
|
2
|
+
require "apidoco_dsl/documentable"
|
3
|
+
require 'apidoco_dsl/param'
|
4
|
+
require "apidoco_dsl/api"
|
5
|
+
require 'apidoco_dsl/api_doc'
|
6
|
+
require 'apidoco_dsl/param_group'
|
7
|
+
require 'apidoco_dsl/railtie'
|
8
|
+
|
9
|
+
module ApidocoDsl
|
10
|
+
class Error < StandardError; end
|
11
|
+
|
12
|
+
@@api = Api.new
|
13
|
+
|
14
|
+
def self.fetch_docs
|
15
|
+
return @@api.api_docs
|
16
|
+
end
|
17
|
+
|
18
|
+
def namespace(namespace)
|
19
|
+
@@api.namespace = namespace
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def resource(resource)
|
24
|
+
@@api.resource = resource
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_doc(&block)
|
28
|
+
api_doc = ApiDoc.new(@@api)
|
29
|
+
api_doc.instance_exec(&block)
|
30
|
+
|
31
|
+
@@api.api_docs << api_doc
|
32
|
+
end
|
33
|
+
|
34
|
+
def def_param_group(group_name, &block)
|
35
|
+
param_group = ParamGroup.new(group_name, @@api)
|
36
|
+
param_group.instance_exec(&block)
|
37
|
+
|
38
|
+
@@api.param_groups[group_name] = param_group
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'kramdown'
|
2
|
+
|
3
|
+
module ApidocoDsl
|
4
|
+
class ApiDoc
|
5
|
+
include Documentable
|
6
|
+
attr_accessor :doc_request_params, :doc_response_params, :doc_published, :doc_name,
|
7
|
+
:doc_endpoint, :doc_http_method, :doc_header, :doc_examples,
|
8
|
+
:doc_sort_order, :doc_description, :doc_request_example, :doc_response_example,
|
9
|
+
:doc_return_code, :doc_namespace, :doc_resource, :doc_markdown
|
10
|
+
|
11
|
+
#attr_reader :api
|
12
|
+
|
13
|
+
SETTABLE = ['published', 'name', 'endpoint',
|
14
|
+
'http_method', 'header', 'markdown', 'sort_order']
|
15
|
+
|
16
|
+
def initialize(api)
|
17
|
+
@api = api
|
18
|
+
@doc_request_params = []
|
19
|
+
@doc_response_params = []
|
20
|
+
@doc_examples = []
|
21
|
+
@doc_namespace = @api.namespace
|
22
|
+
@doc_resource = @api.resource
|
23
|
+
@param_destination = 'request'
|
24
|
+
end
|
25
|
+
|
26
|
+
def param_key
|
27
|
+
"Document"
|
28
|
+
end
|
29
|
+
|
30
|
+
def returns(code: 200, &block)
|
31
|
+
@doc_return_code = translate_return_code(code)
|
32
|
+
@param_destination = 'response'
|
33
|
+
self.instance_exec(&block) if block_given?
|
34
|
+
@param_destination = 'request'
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(name, *args)
|
38
|
+
return set_attribute(name, *args) if SETTABLE.include?(name.to_s)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_attribute(name, value)
|
43
|
+
self.send(:"doc_#{name}=", value)
|
44
|
+
end
|
45
|
+
|
46
|
+
def example_request(path: nil)
|
47
|
+
ex = {}
|
48
|
+
ex['request'] = yield if block_given?
|
49
|
+
ex['request'] = JSON.parse(File.read(path)) if path
|
50
|
+
@doc_examples << ex
|
51
|
+
end
|
52
|
+
|
53
|
+
def example_response(path: nil)
|
54
|
+
ex = {}
|
55
|
+
ex['response'] = yield if block_given?
|
56
|
+
ex['response'] = JSON.parse(File.read(path)) if path
|
57
|
+
@doc_examples << ex
|
58
|
+
end
|
59
|
+
|
60
|
+
def description(txt = nil, path: nil)
|
61
|
+
if path
|
62
|
+
txt = File.read(path)
|
63
|
+
erb = ERB.new(txt).result
|
64
|
+
html = Kramdown::Document.new(erb).to_html
|
65
|
+
@doc_description = ERB.new(html).result
|
66
|
+
else
|
67
|
+
@doc_description = txt
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def doc_folder
|
72
|
+
doc_namespace.split('::').map(&:underscore).map(&:downcase).join('/') + "/#{doc_resource.to_s.underscore}/"
|
73
|
+
end
|
74
|
+
|
75
|
+
def doc_file
|
76
|
+
doc_name.gsub(/\s/, '').underscore
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_json
|
80
|
+
doc = {}
|
81
|
+
doc['published'] = doc_published unless doc_published.nil?
|
82
|
+
doc['name'] = doc_name unless doc_name.nil?
|
83
|
+
doc['end_point'] = doc_endpoint unless doc_endpoint.nil?
|
84
|
+
doc['http_method'] = doc_http_method unless doc_http_method.nil?
|
85
|
+
doc['params'] = unroll_parameters(doc_request_params, []) unless doc_request_params.empty?
|
86
|
+
doc['response_params'] = unroll_parameters(doc_response_params, []) unless doc_response_params.empty?
|
87
|
+
doc['header'] = doc_header unless doc_header.nil?
|
88
|
+
doc['description'] = doc_description unless doc_description.nil?
|
89
|
+
doc['examples'] = doc_examples unless doc_examples.empty?
|
90
|
+
doc['sort_order'] = doc_sort_order unless doc_sort_order.nil?
|
91
|
+
doc['return_code'] = doc_return_code
|
92
|
+
doc['markdown'] = doc_markdown
|
93
|
+
|
94
|
+
return JSON.pretty_generate(doc)
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def translate_return_code(code)
|
100
|
+
trans = {
|
101
|
+
100 => :continue,
|
102
|
+
101 => :switching_protocols,
|
103
|
+
102 => :processing,
|
104
|
+
200 => :ok,
|
105
|
+
201 => :created,
|
106
|
+
202 => :accepted,
|
107
|
+
203 => :non_authoritative_information,
|
108
|
+
204 => :no_content,
|
109
|
+
205 => :reset_content,
|
110
|
+
206 => :partial_content,
|
111
|
+
207 => :multi_status,
|
112
|
+
226 => :im_used,
|
113
|
+
300 => :multiple_choices,
|
114
|
+
301 => :moved_permanently,
|
115
|
+
302 => :found,
|
116
|
+
303 => :see_other,
|
117
|
+
304 => :not_modified,
|
118
|
+
305 => :use_proxy,
|
119
|
+
307 => :temporary_redirect,
|
120
|
+
400 => :bad_request,
|
121
|
+
401 => :unauthorized,
|
122
|
+
402 => :payment_required,
|
123
|
+
403 => :forbidden,
|
124
|
+
404 => :not_found,
|
125
|
+
405 => :method_not_allowed,
|
126
|
+
406 => :not_acceptable,
|
127
|
+
407 => :proxy_authentication_required,
|
128
|
+
408 => :request_timeout,
|
129
|
+
409 => :conflict,
|
130
|
+
410 => :gone,
|
131
|
+
411 => :length_required,
|
132
|
+
412 => :precondition_failed,
|
133
|
+
413 => :request_entity_too_large,
|
134
|
+
414 => :request_uri_too_long,
|
135
|
+
415 => :unsupported_media_type,
|
136
|
+
416 => :requested_range_not_satisfiable,
|
137
|
+
417 => :expectation_failed,
|
138
|
+
422 => :unprocessable_entity,
|
139
|
+
423 => :locked,
|
140
|
+
424 => :failed_dependency,
|
141
|
+
426 => :upgrade_required,
|
142
|
+
500 => :internal_server_error,
|
143
|
+
501 => :not_implemented,
|
144
|
+
502 => :bad_gateway,
|
145
|
+
503 => :service_unavailable,
|
146
|
+
504 => :gateway_timeout,
|
147
|
+
505 => :http_version_not_supported,
|
148
|
+
507 => :insufficient_storage,
|
149
|
+
510 => :not_extended
|
150
|
+
}.invert
|
151
|
+
|
152
|
+
trans[code] || code
|
153
|
+
end
|
154
|
+
|
155
|
+
def unroll_parameters(params, unrolled = [])
|
156
|
+
# Unrolling parameters is a matter of recursively seeking down through each base set of params for
|
157
|
+
# each of _their_ params, and assigning/setting keys appropriately.
|
158
|
+
|
159
|
+
params.each do |pr|
|
160
|
+
if pr.params.any?
|
161
|
+
|
162
|
+
unrolled << pr.to_h
|
163
|
+
duped = pr.params.dup
|
164
|
+
duped.each{|d| d.parent = pr; }
|
165
|
+
unroll_parameters(duped, unrolled)
|
166
|
+
else
|
167
|
+
unrolled << pr.to_h
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
return unrolled
|
173
|
+
end
|
174
|
+
|
175
|
+
def push_to
|
176
|
+
self.send(:"doc_#{@param_destination}_params")
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ApidocoDsl
|
2
|
+
module Documentable
|
3
|
+
attr_accessor :api
|
4
|
+
|
5
|
+
def param(key, type:, desc: nil, notes: nil, validations: nil, required: false, &block)
|
6
|
+
this_param = Param.new(
|
7
|
+
param_key: key,
|
8
|
+
param_type: type,
|
9
|
+
param_description: desc,
|
10
|
+
param_notes: notes,
|
11
|
+
param_required: required,
|
12
|
+
param_validations: validations,
|
13
|
+
parent: self
|
14
|
+
)
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
this_param.instance_exec(this_param, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
push_to << this_param
|
21
|
+
end
|
22
|
+
|
23
|
+
# There may be a clever way to do this, preserving key ancestry without duplication...I haven't found it.
|
24
|
+
def property(key, type:, desc: nil, notes: nil, validations: nil, required: true, &block)
|
25
|
+
this_param = Param.new(
|
26
|
+
param_key: key,
|
27
|
+
param_type: type,
|
28
|
+
param_description: desc,
|
29
|
+
param_notes: notes,
|
30
|
+
param_required: required,
|
31
|
+
param_validations: validations,
|
32
|
+
parent: self
|
33
|
+
)
|
34
|
+
|
35
|
+
if block_given?
|
36
|
+
this_param.instance_exec(this_param, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
push_to << this_param
|
40
|
+
end
|
41
|
+
|
42
|
+
def param_group(group_name)
|
43
|
+
# Param groups seem to have trouble inheriting parentage correctly.
|
44
|
+
# This appears to be because the params are "parented" when they are
|
45
|
+
# initally defined and when grabbing them here, we need to "re-parent"
|
46
|
+
# them...or more accurately, a copy of them.
|
47
|
+
#
|
48
|
+
# Again, problem, because a single param may itself have multiple layers
|
49
|
+
# of child params and groups...
|
50
|
+
#
|
51
|
+
# An interesting note here is that defining a nested grouping _manually_
|
52
|
+
# appears to have the desired effect.
|
53
|
+
|
54
|
+
pg = @api.param_groups[group_name].deep_dup
|
55
|
+
#pg.reparent(self) # Make the calling object the top-level parent for every param in this group
|
56
|
+
|
57
|
+
pg.params.each do |param|
|
58
|
+
push_to << param
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module ApidocoDsl
|
2
|
+
class Param
|
3
|
+
include Documentable
|
4
|
+
|
5
|
+
attr_accessor :param_key, :param_type, :param_description,
|
6
|
+
:param_notes, :param_validations, :param_required, :params, :parent
|
7
|
+
|
8
|
+
SETTABLE = ['key', 'type', 'description', 'notes', 'validations', 'required']
|
9
|
+
|
10
|
+
def initialize(param_key:,
|
11
|
+
param_type:,
|
12
|
+
param_description: nil,
|
13
|
+
param_notes: nil,
|
14
|
+
param_validations: nil,
|
15
|
+
param_required: false,
|
16
|
+
parent: nil)
|
17
|
+
|
18
|
+
@param_key = param_key
|
19
|
+
@param_type = param_type
|
20
|
+
@param_description = param_description
|
21
|
+
@param_notes = param_notes
|
22
|
+
@param_validations = param_validations
|
23
|
+
@param_required = param_required
|
24
|
+
@parent = parent
|
25
|
+
@params = []
|
26
|
+
@api = parent.api
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(name, *args)
|
30
|
+
return set_attribute(name, *args) if SETTABLE.include?(name.to_s)
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_attribute(name, value)
|
35
|
+
self.send(:"param_#{name}=", value)
|
36
|
+
end
|
37
|
+
|
38
|
+
def doc_request_params
|
39
|
+
@params
|
40
|
+
end
|
41
|
+
alias doc_response_params doc_request_params
|
42
|
+
|
43
|
+
def to_h
|
44
|
+
param = {}
|
45
|
+
param['key'] = compound_key
|
46
|
+
param['type'] = param_type unless param_type.nil?
|
47
|
+
param['description'] = param_description unless param_description.nil?
|
48
|
+
param['notes'] = param_notes unless param_notes.nil?
|
49
|
+
param['required'] = param_required
|
50
|
+
param['validations'] = param_validations unless param_validations.nil?
|
51
|
+
|
52
|
+
return param
|
53
|
+
end
|
54
|
+
|
55
|
+
def display_key
|
56
|
+
return param_key.to_s unless @parent && @parent.is_a?(Param)
|
57
|
+
return "[#{param_key.to_s}]"
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def compound_key
|
63
|
+
return param_key.to_s unless @parent && @parent.is_a?(Param)
|
64
|
+
|
65
|
+
ancestors = []
|
66
|
+
this_parent = @parent
|
67
|
+
ancestor = this_parent
|
68
|
+
|
69
|
+
while ancestor
|
70
|
+
ancestors << ancestor
|
71
|
+
ancestor = ancestor.try(:parent)
|
72
|
+
end
|
73
|
+
|
74
|
+
keys = ancestors.map{|a| a.try(:display_key) }.reverse
|
75
|
+
|
76
|
+
compounded = keys.map(&:to_s).join('')
|
77
|
+
return compounded + display_key
|
78
|
+
end
|
79
|
+
|
80
|
+
def push_to
|
81
|
+
@params
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ApidocoDsl
|
2
|
+
class ParamGroup
|
3
|
+
include Documentable
|
4
|
+
|
5
|
+
attr_accessor :name, :params
|
6
|
+
|
7
|
+
def initialize(group_name, api)
|
8
|
+
@name = group_name
|
9
|
+
@api = api
|
10
|
+
@params = []
|
11
|
+
@doc_request_params = @params
|
12
|
+
end
|
13
|
+
|
14
|
+
def doc_request_params
|
15
|
+
@params
|
16
|
+
end
|
17
|
+
alias doc_response_params doc_request_params
|
18
|
+
|
19
|
+
|
20
|
+
def reparent(new_parent)
|
21
|
+
original_params = @params.deep_dup
|
22
|
+
@params = []
|
23
|
+
|
24
|
+
p '&&&&&&&&&&'
|
25
|
+
p '&&&&&&&&&&'
|
26
|
+
p '&&&&&&&&&&'
|
27
|
+
#original_params.each do |param|
|
28
|
+
#p param.parent.class
|
29
|
+
#p param.display_key #unless param.parent
|
30
|
+
#end
|
31
|
+
|
32
|
+
#original_params.each do |param|
|
33
|
+
#param = param.dup
|
34
|
+
#param.parent = new_parent
|
35
|
+
|
36
|
+
#@params << param
|
37
|
+
#end
|
38
|
+
|
39
|
+
@params.each do |param|
|
40
|
+
p param.parent.parent.class
|
41
|
+
p param.parent.display_key
|
42
|
+
p param.display_key #unless param.parent
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def push_to
|
49
|
+
@params
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'apidoco_dsl'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module ApidocoDsl
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
railtie_name :apidoco_dsl
|
7
|
+
|
8
|
+
rake_tasks do
|
9
|
+
path = File.expand_path(__dir__ + '/../')
|
10
|
+
Dir.glob("#{path}/tasks/**/*.rake").each{|t| load t }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ApidocoDsl
|
2
|
+
module Generators
|
3
|
+
class DocumentationGenerator < Rails::Generators::Base
|
4
|
+
desc "Generate static JSON documentation for your API endpoints"
|
5
|
+
|
6
|
+
def generate_docs
|
7
|
+
docs = ApidocoDsl.fetch_docs
|
8
|
+
base_path = Apidoco.base_path
|
9
|
+
|
10
|
+
docs.each do |doc|
|
11
|
+
doc_path = "#{base_path}/#{doc.doc_folder}/#{doc.doc_file}.json"
|
12
|
+
create_file(doc_path, doc.to_json, force: true)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apidoco_dsl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steve Lewis
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: apidoco
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: kramdown
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- steve.l@lojistic.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".travis.yml"
|
93
|
+
- Gemfile
|
94
|
+
- Gemfile.lock
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- apidoco_dsl.gemspec
|
99
|
+
- bin/console
|
100
|
+
- bin/setup
|
101
|
+
- lib/apidoco_dsl.rb
|
102
|
+
- lib/apidoco_dsl/api.rb
|
103
|
+
- lib/apidoco_dsl/api_doc.rb
|
104
|
+
- lib/apidoco_dsl/documentable.rb
|
105
|
+
- lib/apidoco_dsl/param.rb
|
106
|
+
- lib/apidoco_dsl/param_group.rb
|
107
|
+
- lib/apidoco_dsl/railtie.rb
|
108
|
+
- lib/apidoco_dsl/version.rb
|
109
|
+
- lib/generators/apidoco_dsl/documentation_generator.rb
|
110
|
+
homepage: https://github.com/lojistic/apidoco_dsl
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata:
|
114
|
+
homepage_uri: https://github.com/lojistic/apidoco_dsl
|
115
|
+
source_code_uri: https://github.com/lojistic/apidoco_dsl
|
116
|
+
changelog_uri: https://github.com/lojistic/apidoco_dsl
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.7.6
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: Provides a block-based DSL for apidoco similar to ApiPie
|
137
|
+
test_files: []
|