rails_api_documentation 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f3a28fb24ee63994ecff8cfdef502e2ee6a07b9
4
- data.tar.gz: c7a0dc69133680aa75d09d0fc2a1cbdd5ace98b3
3
+ metadata.gz: a72e86cdcaefec61dd47079acd6df5eb7ad88762
4
+ data.tar.gz: dc2ee37bbed89765494a3b697ab337db746aaefb
5
5
  SHA512:
6
- metadata.gz: 6a313b7d46410b696f00d7f133d64d385f950c1d56d05ed383d39af1a438d0c2af164b1a064cb7932eeb46f0628dedf8acfacd87daf3af6c7edd0361d5efcf26
7
- data.tar.gz: 4eb52929a55fcc97ab0096246dfd17c5315be9c4255ed4fce52549f2db29a10357f019bc6e5788eb861ea51bef382576980d97d2bedea4bd3adeda2dcc369e65
6
+ metadata.gz: 6a1d84265c02e6c7c588078cb27790bb1a231a6451aa35c3c24210b41a2ec62237deb611be3408346f66dbcd8e68fb6a44f8473194eedb77acc0f4e5e528a085
7
+ data.tar.gz: 43e6fb0376be3a10f0da24cf170bc42110b79869308e5d3b7ebaf19e59104b872e2c34365bc2647ba5e50ab6fb803e38115382579e704f56d4d6692153aeb1d7
data/README.md CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
22
22
  + displaying application api if used in one of correct ways
23
23
  ![alt tag](https://raw.githubusercontent.com/vshaveyko/rails_api_doc/master/preview.png)
24
24
  + Integration with Rabl if it is bundled
25
- + ```resource_params``` method that will filter incoming params for you
25
+ + ```strong_params``` method that will filter incoming params for you
26
26
 
27
27
  ## Usage
28
28
 
@@ -56,7 +56,16 @@ To display api documentation on route '/api_doc' you need to:
56
56
  parameter :comment, type: :string
57
57
  end
58
58
  end
59
- parameter :test, type: String, required: true
59
+ parameter :test, type: :string, required: true
60
+
61
+ parameter({
62
+ articles_attributes: { model: 'Article', type: :ary_object },
63
+ data_attributes: { model: 'Datum' },
64
+ comments_attributes: { model: 'Comment', type: :ary_object }
65
+ }, type: :object) do
66
+ parameter :id
67
+ parameter :name
68
+ end
60
69
 
61
70
  end
62
71
  ```
@@ -75,7 +84,7 @@ To display api documentation on route '/api_doc' you need to:
75
84
 
76
85
  # controller action
77
86
  def create
78
- Comment.create!(resource_params)
87
+ Comment.create!(strong_params)
79
88
  end
80
89
 
81
90
  ```
@@ -84,6 +93,52 @@ To display api documentation on route '/api_doc' you need to:
84
93
 
85
94
  Comment will be created with: `Comment(body='Comment body', title='Comment title', age=nil)`
86
95
 
96
+ ## Value
97
+
98
+ You can pass optional value argument to every parameter:
99
+
100
+ ```ruby
101
+ parameter :val, type: :integer, value: -> (request_value) { 5 }
102
+ ```
103
+
104
+ on every matching request value in this field will be overriden by value returned by proc.
105
+
106
+ value field expecting anything that will respond to `:call` and can accept one argument(param value from request)
107
+
108
+ you should expect that value passed can be `nil`
109
+
110
+ This can be used to force values on some fields, or modify values passed to request in some ways.
111
+
112
+ E.g. you want to force current_user_id on model creation instead of passing it from frontend.
113
+
114
+ ## Enum
115
+
116
+ When you defined parameter type as `:enum` you can pass `enum:` option. This will filter parameter by values provided.
117
+
118
+ ## Group common blocks
119
+
120
+ You can define parameters that have common fields this way:
121
+
122
+ ```ruby
123
+ parameter({
124
+ articles_attributes: { model: 'Article', type: :ary_object },
125
+ data_attributes: { model: 'Datum' },
126
+ comments_attributes: { model: 'Comment', type: :ary_object }
127
+ }, type: :object) do
128
+ parameter :id
129
+ parameter :name
130
+ end
131
+ ```
132
+
133
+ Pass common values as last optional arguments and uniq definitions as hash value.
134
+ All nesting parameters are applied to elements in blocks.
135
+
136
+ Something with same type can be defined like this:
137
+
138
+ ```ruby
139
+ parameter :name, :desc, type: :string
140
+ ```
141
+
87
142
  ## Types
88
143
 
89
144
  Parameter type may be one of these:
@@ -2,4 +2,4 @@
2
2
 
3
3
  div[id="#{ctrl}.request" style="--row-count: #{request_headers.length}"]
4
4
 
5
- = render 'shared/table', model: ctrl, rows: repo[ctrl], headers: request_headers, nesting: [], params: { api_type: :request }
5
+ = render 'shared/table', model: ctrl, rows: repo[ctrl.name], headers: request_headers, nesting: [], params: { api_type: :request }
@@ -11,6 +11,6 @@ div.response-table[id="#{ctrl}.response" style="--row-count: #{response_headers
11
11
  div.request-action-title
12
12
  = render 'shared/title', locals: { blue_title: route[:method], yellow_title: route[:url]}
13
13
 
14
- - if rows = repo.load_template(ctrl, action)
14
+ - if rows = repo.load_attrs(ctrl, action)
15
15
 
16
16
  = render 'shared/table', model: ctrl, rows: rows, headers: response_headers, nesting: [], params: { api_action: action, api_type: :response }
@@ -29,7 +29,7 @@ div.flex-table
29
29
  - if index.zero?
30
30
  span.ico ✏
31
31
  / = submit_tag ,name: 'destroy', class: 'ico destroy'
32
- = link_to '❌' , api_doc_url(construct_destroy_param(row_values, params, nesting)), method: :delete, class: 'destroy ico'
32
+ = link_to '❌' , api_doc_url(construct_destroy_param(row_values, params, nesting)), method: :delete,data: { confirm: 'Are you sure?' }, class: 'destroy ico'
33
33
  span.exit.ico ❌
34
34
  = submit_tag '✔'
35
35
 
@@ -5,19 +5,48 @@ module RailsApiDoc
5
5
  module Request
6
6
  module DSL
7
7
 
8
+ #
8
9
  # Use parameter in controller to define REQUEST parameter.
9
10
  # Adds it to repository: RailsApiDoc::Controller::Request::Repository
10
- def parameter(name, options = {}, &block)
11
+ # Params can be defined in several ways:
12
+ # 1. parameter :name, type: :string
13
+ #
14
+ # 2. parameter {
15
+ # dose_form_attributes: { model: 'Rxnorm::RxDoseForm' },
16
+ # input_method_attributes: { model: 'TreatmentInfo::InputMethod' },
17
+ # input_condition_attributes: { model: 'Drugs::InputCondition' },
18
+ # input_duration_attributes: { model: 'Drugs::InputDuration' }
19
+ # }, type: :object do
20
+ # parameter :id
21
+ # parameter :name
22
+ # end
23
+ #
24
+ # 3. parameter :name, :code, type: :string
25
+ #
26
+ def parameter(*arguments, &block)
27
+ options = arguments.extract_options!
28
+
11
29
  raise ArgumentError, 'Parameter already defined.' if repo.key?(name)
12
30
 
13
31
  validate_options(options, block_given?)
14
32
 
15
- define_parameter(name, options, &block)
33
+ arguments.each do |param|
34
+ # 2)
35
+ if param.is_a?(Hash)
36
+ param.each do |param_name, additional_options|
37
+ _options = options.merge(additional_options)
38
+
39
+ define_parameter(param_name, _options, &block)
40
+ end
41
+ else # 1), 3)
42
+ define_parameter(param, options, &block)
43
+ end
44
+ end
16
45
  end
17
46
 
18
47
  private
19
48
 
20
- def validate_options(options, block_given)
49
+ def validate_options(options, _block_given)
21
50
  options.assert_valid_keys(RailsApiDoc::Controller::Param::VALID_KEYS)
22
51
 
23
52
  RailsApiDoc::Controller::Request::Param.valid_type?(options[:type])
@@ -4,11 +4,11 @@ class RailsApiDoc::Controller::Request::Factory
4
4
  class << self
5
5
 
6
6
  def repo
7
- attributes = RailsApiDoc::Controller::Request::Repository.new
7
+ repo = RailsApiDoc::Controller::Request::Repository.new
8
8
 
9
- attributes = merge_attributes_from_model attributes
9
+ repo.repo = merge_attributes_from_model repo.repo
10
10
 
11
- attributes
11
+ repo
12
12
  end
13
13
 
14
14
  def registered_controllers
@@ -21,7 +21,7 @@ class RailsApiDoc::Controller::Request::Factory
21
21
  # do not mutate attributes
22
22
  #
23
23
  def merge_attributes_from_model(attributes)
24
- RailsApiDoc::Model::AttributeMerger.new(attributes).call(api_type: 'request')
24
+ RailsApiDoc::Model::AttributeMerger.new(attributes, 'request').call
25
25
  end
26
26
 
27
27
  end
@@ -50,9 +50,9 @@ module RailsApiDoc
50
50
 
51
51
  def display_special
52
52
  spec = if enum?
53
- enum
54
- elsif nested?
55
- model
53
+ enum
54
+ elsif nested? || model?
55
+ model
56
56
  end
57
57
 
58
58
  spec = spec.to_s + "(#{param.special})" if param&.special
@@ -8,11 +8,7 @@ class RailsApiDoc::Controller::Response::Factory
8
8
  # TODO: add more options later depending on app settings
9
9
  # TODO: rename to :load_repo
10
10
  def repo
11
- attributes = RailsApiDoc::Controller::Response::Repository.new(repository.repo)
12
-
13
- attributes = merge_attributes_from_model attributes
14
-
15
- attributes
11
+ RailsApiDoc::Controller::Response::Repository.new(repository.repo)
16
12
  end
17
13
 
18
14
  def controllers
@@ -25,13 +21,6 @@ class RailsApiDoc::Controller::Response::Factory
25
21
  @repo ||= ::RailsApiDoc::Controller::Response::Rabl.new(controllers)
26
22
  end
27
23
 
28
- #
29
- # do not mutate attributes
30
- #
31
- def merge_attributes_from_model(attributes)
32
- RailsApiDoc::Model::AttributeMerger.new(attributes).call(api_type: 'response')
33
- end
34
-
35
24
  end
36
25
 
37
26
  end
@@ -7,7 +7,6 @@ module RailsApiDoc::Controller::Response::Headers
7
7
 
8
8
  RESPONSE_HEADERS = [
9
9
  NAME_HEADER,
10
- TYPE_HEADER,
11
10
  VALUE_HEADER,
12
11
  DESC_HEADER
13
12
  ].reduce(&:merge).freeze
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # author: Vadim Shaveiko <@vshaveyko>
1
3
  # :nodoc:
2
4
  class RailsApiDoc::Controller::Response::Repository
3
5
 
@@ -5,7 +7,15 @@ class RailsApiDoc::Controller::Response::Repository
5
7
  include RailsApiDoc::Controller::Response::Headers
6
8
 
7
9
  def initialize(repo)
8
- @repo = repo.clone.transform_values { |v| v.deep_dup }
10
+ @repo = repo.clone.transform_values(&:deep_dup)
11
+ end
12
+
13
+ def load_attrs(ctrl, action)
14
+ at = load_template(ctrl, action)&.nodes || {}
15
+
16
+ at = RailsApiDoc::Model::AttributeMerger.new(at, 'response').merge_action(action: action, ctrl: ctrl)
17
+
18
+ at
9
19
  end
10
20
 
11
21
  def load_template(ctrl, action)
@@ -1,14 +1,19 @@
1
- # :nodoc:
1
+ # frozen_string_literal: true
2
+ # author: Vadim Shaveiko <@vshaveyko>
2
3
  module RailsApiDoc
3
4
  module Controller
4
5
  module ResourceParams
5
- module DSL
6
+ module DSL # :nodoc:
6
7
 
7
8
  include RailsApiDoc::Controller::ResourceParams::PermittedParams # implements params_to_permit
8
9
 
9
- def resource_params
10
+ def strong_params(pars = params)
11
+ #
10
12
  # accepted_params for permit
11
- params.permit(params_to_permit)
13
+ #
14
+ permitted = params_to_permit(pars)
15
+
16
+ pars.permit(permitted)
12
17
  end
13
18
 
14
19
  end
@@ -7,8 +7,8 @@ module RailsApiDoc
7
7
 
8
8
  private
9
9
 
10
- def params_to_permit
11
- _next_nesting_level(params, param_data: _permitted_params)
10
+ def params_to_permit(pars = params)
11
+ _next_nesting_level(pars, param_data: _permitted_params)
12
12
  end
13
13
 
14
14
  def _permitted_params
@@ -32,7 +32,6 @@ module RailsApiDoc
32
32
  level_accepted_params
33
33
  end
34
34
 
35
-
36
35
  #
37
36
  # loop through current level of params and add to permit level if all requirements are met
38
37
  #
@@ -47,6 +46,10 @@ module RailsApiDoc
47
46
  #
48
47
  def loop_params(params, level_permitted_params, accepted_params)
49
48
  level_permitted_params.each do |param_name, api_param_data|
49
+ if api_param_data.value&.respond_to?(:call)
50
+ params[param_name] = api_param_data.value.call(params[param_name])
51
+ end
52
+
50
53
  controller_param = params[param_name]
51
54
 
52
55
  _check_required(param_name, controller_param, api_param_data) # raise if required and no value
@@ -63,7 +66,6 @@ module RailsApiDoc
63
66
  param_data: api_param_data.nested,
64
67
  current_accepted_params: accepted_params,
65
68
  param_name: param_name)
66
-
67
69
  end
68
70
  elsif api_param_data.nested? # value should be nested object
69
71
  _next_nesting_level(controller_param,
@@ -6,53 +6,58 @@ class RailsApiDoc::Model::AttributeMerger
6
6
  MODEL = RailsApiDoc::ApiDatum
7
7
  MERGABLE_FIELDS = [:type, :desc, :action_type].freeze
8
8
 
9
+ @@data = MODEL.all
10
+
9
11
  #
10
12
  # do not mutate attributes
11
13
  #
12
14
  # please - impossible
13
15
  #
14
- def initialize(attributes)
15
- @attrs = attributes
16
+ def initialize(attributes, api_type)
17
+ @attrs = attributes.stringify_keys
18
+ @api_type = api_type
16
19
  end
17
20
 
18
- def call(api_type:)
19
- @api_type = api_type
21
+ def merge_action(action:, ctrl:)
22
+ merge_data = @@data.select { |d| d.api_type == @api_type && d.api_action == action.to_s && d.nesting.first == ctrl.name }
20
23
 
21
- api_params = MODEL.where(api_type: api_type).all.each do |param|
22
- _add_nested_param(param)
24
+ merge_data.each do |param|
25
+ _add_nested_param(param, param.nesting[1..-1], @attrs)
23
26
  end
24
27
 
25
28
  @attrs
26
29
  end
27
30
 
28
- private
31
+ def call
32
+ api_params = @@data.select { |d| d.api_type == @api_type }.each do |param|
33
+ #
34
+ # nesting should be present for parameter to appear
35
+ #
36
+ next unless param.name && param.nesting.present?
29
37
 
30
- def _add_nested_param(param)
31
- # nesting should be present for parameter to appear
32
- return if param.nesting.blank?
38
+ attrs, nesting, name = _parse_settings(param)
33
39
 
34
- attrs, nesting, name = _parse_settings(param)
40
+ _add_nested_param(param, nesting, attrs)
41
+ end
35
42
 
36
- return unless name
43
+ @attrs
44
+ end
45
+
46
+ private
37
47
 
38
- ctrl_param = _find_param(nesting, name, attrs)
48
+ def _add_nested_param(param, nesting, attrs)
49
+ ctrl_param = _find_param(nesting, param.name, attrs)
39
50
 
40
51
  ctrl_param.param = param
41
52
  # _merge_data_to_param(ctrl_param, param)
42
53
  end
43
54
 
44
55
  def _parse_settings(param)
45
- ctrl = param.nesting[0].constantize
56
+ ctrl = param.nesting[0]
46
57
  nesting = param.nesting[1..-1]
47
58
  name = param.name&.to_sym
48
59
  attrs = @attrs[ctrl]
49
60
 
50
- #
51
- # making exception
52
- # until request parameters are not split by actions
53
- #
54
- attrs = attrs[param.api_action] if @api_type == 'response'
55
-
56
61
  [attrs, nesting, name]
57
62
  end
58
63
 
@@ -82,18 +87,18 @@ class RailsApiDoc::Model::AttributeMerger
82
87
  end
83
88
  end
84
89
 
85
- def _find_param(nesting, name, attrs)
86
- nesting.each do |model|
87
- nested_attrs = attrs.each_value.detect { |v| v.nested? && v.model == model }
90
+ def _find_param(nest, name, attrs)
91
+ nest.each do |model|
92
+ #
93
+ # model on different fields because of wrong nesting sturcture for request
94
+ # TODO: fix this later
95
+ #
96
+ nested_attrs = attrs.detect { |k, v| v.nested? && (v.model == model || k.to_s == model) }
88
97
 
89
98
  attrs = nested_attrs ? nested_attrs : _define_nesting_level(attrs, name, model)
90
99
  end
91
100
 
92
- if attrs[name]
93
- attrs[name]
94
- else
95
- attrs[name] = _init_param_for_api_type(name)
96
- end
101
+ attrs[name] ||= _init_param_for_api_type(name, {})
97
102
  end
98
103
 
99
104
  def _define_nesting_level(attrs, name, model)
@@ -123,7 +128,7 @@ class RailsApiDoc::Model::AttributeMerger
123
128
  if @api_type == 'request'
124
129
  RailsApiDoc::Controller::Request::Param.new(name, options, is_new: true)
125
130
  elsif @api_type == 'response'
126
- RailsApiDoc::Controller::Response::Param.new(name, name, options[:nested], options[:model], '', options[:type], is_new: true)
131
+ RailsApiDoc::Controller::Response::Param.new(name, name, options[:nested], options[:model], nil, options[:type], is_new: true)
127
132
  end
128
133
  end
129
134
 
@@ -18,6 +18,7 @@ class RailsApiDoc::Model::AttributeParser
18
18
  action_type: params[:action],
19
19
  nesting: params[:nesting],
20
20
  api_type: params[:api_type],
21
+ api_action: params[:api_action],
21
22
  id: params[:id]
22
23
  }.compact
23
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # author: Vadim Shaveiko <@vshaveyko>
3
3
  module RailsApiDoc
4
- VERSION = '0.3.1'
4
+ VERSION = '0.3.2'
5
5
  end
data/lib/rails_api_doc.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  # author: Vadim Shaveiko <@vshaveyko>
2
2
  # frozen_string_literal: true
3
3
  module RailsApiDoc
4
- NESTED_TYPES = [:ary_object, :object, :model].freeze
4
+
5
+ NESTED_TYPES = [:ary_object, :object, :json].freeze
5
6
 
6
- STRAIGHT_TYPES = [:bool, :string, :integer, :array, :datetime, :enum].freeze
7
+ STRAIGHT_TYPES = [:bool, :string, :integer, :array, :datetime, :enum, :model].freeze
7
8
 
8
9
  ACCEPTED_TYPES = (NESTED_TYPES + STRAIGHT_TYPES).freeze
9
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_api_documentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - vs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-12 00:00:00.000000000 Z
11
+ date: 2016-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler