rails_api_documentation 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -8
- data/app/assets/javascripts/table.js.coffee +10 -1
- data/app/assets/stylesheets/rails_api_doc/default.sass +39 -16
- data/app/assets/stylesheets/rails_api_doc/table.sass +21 -4
- data/app/controllers/rails_api_doc/api_docs_controller.rb +17 -20
- data/app/helpers/rails_api_doc/application_helper.rb +11 -0
- data/app/models/rails_api_doc/api_datum.rb +17 -0
- data/app/views/layouts/rails_api_doc/application.slim +2 -5
- data/app/views/rails_api_doc/api_docs/_request_api_table.slim +1 -1
- data/app/views/rails_api_doc/api_docs/_response_api_table.slim +4 -3
- data/app/views/rails_api_doc/api_docs/{index.slim → show.slim} +0 -0
- data/app/views/shared/_param_inputs.slim +2 -3
- data/app/views/shared/_table.slim +8 -6
- data/app/views/shared/_title.slim +8 -0
- data/config/routes.rb +1 -1
- data/lib/generators/rails_api_doc/templates/api_datum_migration.rb +4 -1
- data/lib/rails_api_doc.rb +16 -1
- data/lib/rails_api_doc/controller/headers.rb +59 -0
- data/lib/rails_api_doc/controller/param.rb +113 -0
- data/lib/rails_api_doc/controller/repo.rb +35 -0
- data/lib/rails_api_doc/controller/request/dsl.rb +1 -3
- data/lib/rails_api_doc/controller/request/factory.rb +29 -0
- data/lib/rails_api_doc/controller/request/headers.rb +11 -42
- data/lib/rails_api_doc/controller/request/param.rb +26 -33
- data/lib/rails_api_doc/controller/request/repository.rb +5 -26
- data/lib/rails_api_doc/controller/response/factory.rb +20 -2
- data/lib/rails_api_doc/controller/response/headers.rb +10 -21
- data/lib/rails_api_doc/controller/response/param.rb +38 -1
- data/lib/rails_api_doc/controller/response/rabl.rb +8 -19
- data/lib/rails_api_doc/controller/response/rabl_compiler.rb +7 -9
- data/lib/rails_api_doc/controller/response/repository.rb +38 -0
- data/lib/rails_api_doc/model/attribute_merger.rb +130 -0
- data/lib/rails_api_doc/model/attribute_parser.rb +23 -5
- data/lib/rails_api_doc/version.rb +1 -1
- metadata +10 -3
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# author: Vadim Shaveiko <@vshaveyko>
|
3
|
+
# :nodoc:
|
4
|
+
module RailsApiDoc
|
5
|
+
module Controller
|
6
|
+
module Headers
|
7
|
+
|
8
|
+
DESC_HEADER = {
|
9
|
+
'Desc' => {
|
10
|
+
value: lambda do |_row_name, row_values|
|
11
|
+
row_values[:desc] || row_values.param&.desc || 'TODO: add description'
|
12
|
+
end,
|
13
|
+
fill_type: :input,
|
14
|
+
param: :desc
|
15
|
+
}
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
TYPE_HEADER = {
|
19
|
+
'Type' => {
|
20
|
+
value: lambda do |_row_name, row_values|
|
21
|
+
row_values.display_type
|
22
|
+
end,
|
23
|
+
fill_type: :select,
|
24
|
+
param: :type,
|
25
|
+
values: RailsApiDoc::ACCEPTED_TYPES
|
26
|
+
}
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
SPECIAL_HEADER = {
|
30
|
+
'Special' => {
|
31
|
+
value: lambda do |_row_name, row_values|
|
32
|
+
row_values.display_special
|
33
|
+
end,
|
34
|
+
fill_type: :input,
|
35
|
+
param: :special
|
36
|
+
}
|
37
|
+
}.freeze
|
38
|
+
|
39
|
+
NAME_HEADER = {
|
40
|
+
'Parameter' => {
|
41
|
+
value: lambda do |row_name, row_values|
|
42
|
+
row_values.display_name
|
43
|
+
end,
|
44
|
+
fill_type: :input,
|
45
|
+
param: :name
|
46
|
+
}
|
47
|
+
}.freeze
|
48
|
+
|
49
|
+
VALUE_HEADER = {
|
50
|
+
'Value' => {
|
51
|
+
value: lambda do |_row_name, row_values|
|
52
|
+
row_values.display_value
|
53
|
+
end
|
54
|
+
}
|
55
|
+
}.freeze
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# author: Vadim Shaveiko <@vshaveyko>
|
3
|
+
module RailsApiDoc
|
4
|
+
module Controller
|
5
|
+
class Param
|
6
|
+
|
7
|
+
COMMON_VALID_KEYS = [:type, :model, :desc, :id, :nested, :action_type].freeze #:nodoc:
|
8
|
+
VALID_REQUEST_KEYS = [:required, :enum, :value].freeze
|
9
|
+
VALID_RESPONSE_KEYS = [:attr].freeze
|
10
|
+
VALID_KEYS = (COMMON_VALID_KEYS + VALID_REQUEST_KEYS + VALID_RESPONSE_KEYS).freeze
|
11
|
+
|
12
|
+
HELPER_KEYS = [:new, :is_new, :param, :name, :store].freeze
|
13
|
+
attr_accessor *HELPER_KEYS
|
14
|
+
|
15
|
+
#
|
16
|
+
# define methods responding to each type with '?'
|
17
|
+
# ex: ary_object? array? string?
|
18
|
+
#
|
19
|
+
RailsApiDoc::ACCEPTED_TYPES.each do |type|
|
20
|
+
define_method "#{type}?" do
|
21
|
+
@store[:type] == type.to_sym
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# redirect all keys accssors to store
|
27
|
+
# .type= is @store[:type]=
|
28
|
+
# .type is @store[:type]
|
29
|
+
#
|
30
|
+
def self.define_accessors(*accessors)
|
31
|
+
accessors.each do |acc|
|
32
|
+
define_method acc do
|
33
|
+
@store[acc]
|
34
|
+
end
|
35
|
+
|
36
|
+
define_method "#{acc}?" do
|
37
|
+
@store[acc].present?
|
38
|
+
end
|
39
|
+
|
40
|
+
define_method "#{acc}=" do |val|
|
41
|
+
@store[acc] = val
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# define methods for each store key
|
48
|
+
# type, name, etc
|
49
|
+
#
|
50
|
+
define_accessors *COMMON_VALID_KEYS
|
51
|
+
|
52
|
+
#
|
53
|
+
# try sending other methods to @store
|
54
|
+
# if possible
|
55
|
+
#
|
56
|
+
delegate :[], :[]=, :each_value, to: :@store
|
57
|
+
|
58
|
+
#
|
59
|
+
# these are actions applied to the params by gem user from frontend
|
60
|
+
#
|
61
|
+
def destroyed?
|
62
|
+
param&.action_type == 'destroy'
|
63
|
+
end
|
64
|
+
|
65
|
+
def created?
|
66
|
+
param&.action_type == 'create'
|
67
|
+
end
|
68
|
+
|
69
|
+
def updated?
|
70
|
+
param&.action_type == 'update'
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_updated_field(field)
|
74
|
+
@new.push(field) unless field.in?(@new)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# redefine to get desired behaviour
|
79
|
+
#
|
80
|
+
def display_type
|
81
|
+
t = if nested?
|
82
|
+
(model || type).to_s + '(Nested)'
|
83
|
+
else
|
84
|
+
type.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
t += "(#{param.type})" if param && param.type != type
|
88
|
+
|
89
|
+
t
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# redefined in descendants
|
94
|
+
#
|
95
|
+
def display_special
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# redefined in descendants
|
100
|
+
#
|
101
|
+
def display_name
|
102
|
+
@name
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# redefined in descendants
|
107
|
+
#
|
108
|
+
def display_value
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# author: Vadim Shaveiko <@vshaveyko>
|
3
|
+
# :nodoc:
|
4
|
+
module RailsApiDoc::Controller::Repo
|
5
|
+
|
6
|
+
attr_accessor :repo
|
7
|
+
|
8
|
+
def self.extended(base)
|
9
|
+
base.instance_eval do
|
10
|
+
@repo = Hash.new do |hsh, key|
|
11
|
+
hsh[key] = Hash.new do |hsh, key|
|
12
|
+
hsh[key] = RailsApiDoc::Controller::Request::Param.new(key, {})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args, &block)
|
19
|
+
return @repo.send(name, *args, &block) if respond_to_missing?(name)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(method, *)
|
24
|
+
@repo.respond_to?(method)
|
25
|
+
end
|
26
|
+
|
27
|
+
def []=(key, value)
|
28
|
+
unless key < ActionController::Base
|
29
|
+
raise ArgumentError, 'Repository keys are controllers only'
|
30
|
+
end
|
31
|
+
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -5,8 +5,6 @@ module RailsApiDoc
|
|
5
5
|
module Request
|
6
6
|
module DSL
|
7
7
|
|
8
|
-
VALID_KEYS = [:type, :required, :enum, :model, :desc, :value].freeze #:nodoc:
|
9
|
-
|
10
8
|
# Use parameter in controller to define REQUEST parameter.
|
11
9
|
# Adds it to repository: RailsApiDoc::Controller::Request::Repository
|
12
10
|
def parameter(name, options = {}, &block)
|
@@ -20,7 +18,7 @@ module RailsApiDoc
|
|
20
18
|
private
|
21
19
|
|
22
20
|
def validate_options(options, block_given)
|
23
|
-
options.assert_valid_keys(VALID_KEYS)
|
21
|
+
options.assert_valid_keys(RailsApiDoc::Controller::Param::VALID_KEYS)
|
24
22
|
|
25
23
|
RailsApiDoc::Controller::Request::Param.valid_type?(options[:type])
|
26
24
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# :nodoc:
|
2
|
+
class RailsApiDoc::Controller::Request::Factory
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def repo
|
7
|
+
attributes = RailsApiDoc::Controller::Request::Repository.new
|
8
|
+
|
9
|
+
attributes = merge_attributes_from_model attributes
|
10
|
+
|
11
|
+
attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
def registered_controllers
|
15
|
+
RailsApiDoc::Controller::Request::Repository.repo.keys
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
#
|
21
|
+
# do not mutate attributes
|
22
|
+
#
|
23
|
+
def merge_attributes_from_model(attributes)
|
24
|
+
RailsApiDoc::Model::AttributeMerger.new(attributes).call(api_type: 'request')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -1,55 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# author: Vadim Shaveiko <@vshaveyko>
|
1
3
|
# :nodoc:
|
2
4
|
module RailsApiDoc
|
3
5
|
module Controller
|
4
6
|
module Request
|
5
7
|
module Headers
|
6
8
|
|
9
|
+
include RailsApiDoc::Controller::Headers
|
10
|
+
|
7
11
|
def headers
|
8
12
|
REQUEST_HEADERS
|
9
13
|
end
|
10
14
|
|
11
|
-
REQUEST_HEADERS =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
fill_type: :input,
|
19
|
-
param: :name
|
20
|
-
},
|
21
|
-
'Type' => {
|
22
|
-
value: -> (row_name, row_values) {
|
23
|
-
if row_values.nested?
|
24
|
-
(row_values.model || row_values.type).to_s + "(Nested)"
|
25
|
-
else
|
26
|
-
row_values.type
|
27
|
-
end
|
28
|
-
},
|
29
|
-
fill_type: :select,
|
30
|
-
param: :type,
|
31
|
-
values: RailsApiDoc::Controller::Request::Param::ACCEPTED_TYPES
|
32
|
-
},
|
33
|
-
'Special' => {
|
34
|
-
value: -> (row_name, row_values) {
|
35
|
-
case
|
36
|
-
when row_values.enum?
|
37
|
-
row_values[:enum]
|
38
|
-
when row_values.model?
|
39
|
-
row_values[:model]
|
40
|
-
end
|
41
|
-
},
|
42
|
-
fill_type: :input,
|
43
|
-
param: :special
|
44
|
-
},
|
45
|
-
'Desc' => {
|
46
|
-
value: -> (row_name, row_values) {
|
47
|
-
'TODO: description' # if row_values[:desc]
|
48
|
-
},
|
49
|
-
fill_type: :input,
|
50
|
-
param: :desc
|
51
|
-
}
|
52
|
-
}
|
15
|
+
REQUEST_HEADERS = [
|
16
|
+
NAME_HEADER,
|
17
|
+
TYPE_HEADER,
|
18
|
+
SPECIAL_HEADER,
|
19
|
+
DESC_HEADER
|
20
|
+
].reduce(&:merge).freeze
|
21
|
+
|
53
22
|
end
|
54
23
|
end
|
55
24
|
end
|
@@ -3,25 +3,25 @@
|
|
3
3
|
module RailsApiDoc
|
4
4
|
module Controller
|
5
5
|
module Request
|
6
|
-
class Param
|
6
|
+
class Param < RailsApiDoc::Controller::Param
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
#
|
9
|
+
# define methods for each store key
|
10
|
+
# type, name, etc
|
11
|
+
#
|
12
|
+
define_accessors *VALID_REQUEST_KEYS
|
13
13
|
|
14
14
|
#
|
15
15
|
# @type - type to check
|
16
16
|
#
|
17
17
|
def self.accepted_nested_type?(type)
|
18
|
-
type.in?(NESTED_TYPES)
|
18
|
+
type.in?(RailsApiDoc::NESTED_TYPES)
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.valid_type?(type)
|
22
|
-
return if type.nil? || type.in?(ACCEPTED_TYPES)
|
22
|
+
return if type.nil? || type.in?(RailsApiDoc::ACCEPTED_TYPES)
|
23
23
|
raise ArgumentError, "Wrong type: #{type}. " \
|
24
|
-
|
24
|
+
"Correct types are: #{RailsApiDoc::ACCEPTED_TYPES}."
|
25
25
|
end
|
26
26
|
|
27
27
|
def self.valid_enum?(type, enum)
|
@@ -36,43 +36,36 @@ module RailsApiDoc
|
|
36
36
|
raise ArgumentError, 'Empty object passed.'
|
37
37
|
end
|
38
38
|
|
39
|
-
def initialize(name, store)
|
39
|
+
def initialize(name, store, is_new: false)
|
40
40
|
@name = name
|
41
41
|
@store = store
|
42
|
+
|
43
|
+
@new = []
|
44
|
+
@is_new = is_new
|
42
45
|
end
|
43
46
|
|
44
47
|
def nested?
|
45
48
|
self.class.accepted_nested_type?(@store[:type])
|
46
49
|
end
|
47
50
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
# define methods responding to each type with '?'
|
55
|
-
# ex: ary_object? array? string?
|
56
|
-
#
|
57
|
-
if name[-1] == '?'
|
58
|
-
type_name = name[0...-1]
|
51
|
+
def display_special
|
52
|
+
spec = if enum?
|
53
|
+
enum
|
54
|
+
elsif nested?
|
55
|
+
model
|
56
|
+
end
|
59
57
|
|
60
|
-
|
61
|
-
end
|
58
|
+
spec = spec.to_s + "(#{param.special})" if param&.special
|
62
59
|
|
63
|
-
|
64
|
-
|
65
|
-
end
|
60
|
+
spec
|
61
|
+
end
|
66
62
|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
63
|
+
def display_name
|
64
|
+
title = @name.to_s
|
70
65
|
|
71
|
-
|
72
|
-
end
|
66
|
+
title += '*' if required?
|
73
67
|
|
74
|
-
|
75
|
-
@store.respond_to?(name) || @store.key?(name)
|
68
|
+
title
|
76
69
|
end
|
77
70
|
|
78
71
|
end
|
@@ -3,33 +3,12 @@
|
|
3
3
|
# :nodoc:
|
4
4
|
class RailsApiDoc::Controller::Request::Repository
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
class << self
|
11
|
-
|
12
|
-
def method_missing(name, *args, &block)
|
13
|
-
return @repo.send(name, *args, &block) if respond_to_missing?(name)
|
14
|
-
super
|
15
|
-
end
|
16
|
-
|
17
|
-
def registered_controllers
|
18
|
-
@repo.keys
|
19
|
-
end
|
20
|
-
|
21
|
-
def respond_to_missing?(method, *)
|
22
|
-
@repo.respond_to?(method)
|
23
|
-
end
|
24
|
-
|
25
|
-
def []=(key, value)
|
26
|
-
unless key < ActionController::Base
|
27
|
-
raise ArgumentError, 'Repository keys are controllers only'
|
28
|
-
end
|
29
|
-
|
30
|
-
super
|
31
|
-
end
|
6
|
+
include RailsApiDoc::Controller::Request::Headers
|
7
|
+
extend RailsApiDoc::Controller::Repo
|
8
|
+
include RailsApiDoc::Controller::Repo
|
32
9
|
|
10
|
+
def initialize
|
11
|
+
@repo = self.class.repo.clone.transform_values { |v| v.deep_dup }
|
33
12
|
end
|
34
13
|
|
35
14
|
end
|