apipie-rails 0.9.2 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rubocop-challenger.yml +1 -1
- data/.github/workflows/rubocop.yml +20 -0
- data/.rubocop.yml +21 -0
- data/.rubocop_todo.yml +222 -610
- data/CHANGELOG.md +16 -1
- data/README.rst +20 -0
- data/apipie-rails.gemspec +4 -0
- data/app/controllers/apipie/apipies_controller.rb +2 -2
- data/app/helpers/apipie_helper.rb +1 -1
- data/app/views/apipie/apipies/_deprecation.html.erb +16 -0
- data/app/views/apipie/apipies/_params.html.erb +7 -1
- data/config/locales/en.yml +7 -0
- data/lib/apipie/apipie_module.rb +2 -2
- data/lib/apipie/application.rb +16 -8
- data/lib/apipie/configuration.rb +13 -2
- data/lib/apipie/dsl_definition.rb +6 -6
- data/lib/apipie/error_description.rb +1 -1
- data/lib/apipie/errors.rb +2 -16
- data/lib/apipie/extractor/collector.rb +1 -1
- data/lib/apipie/extractor/recorder.rb +2 -2
- data/lib/apipie/extractor.rb +2 -2
- data/lib/apipie/generator/swagger/operation_id.rb +1 -1
- data/lib/apipie/helpers.rb +3 -3
- data/lib/apipie/markup.rb +9 -8
- data/lib/apipie/method_description.rb +1 -1
- data/lib/apipie/param_description/deprecation.rb +24 -0
- data/lib/apipie/param_description.rb +38 -11
- data/lib/apipie/resource_description.rb +10 -7
- data/lib/apipie/response_description.rb +1 -1
- data/lib/apipie/response_description_adapter.rb +3 -3
- data/lib/apipie/routing.rb +1 -1
- data/lib/apipie/rspec/response_validation_helper.rb +1 -1
- data/lib/apipie/swagger_generator.rb +6 -6
- data/lib/apipie/validator.rb +9 -10
- data/lib/apipie/version.rb +1 -1
- data/lib/apipie-rails.rb +1 -0
- data/lib/tasks/apipie.rake +11 -10
- data/spec/controllers/users_controller_spec.rb +8 -1
- data/spec/dummy/config.ru +1 -1
- data/spec/{controllers → lib/apipie}/apipies_controller_spec.rb +6 -2
- data/spec/lib/apipie/application_spec.rb +53 -0
- data/spec/lib/apipie/configuration_spec.rb +23 -0
- data/spec/lib/apipie/extractor/recorder_spec.rb +40 -0
- data/spec/lib/{generator → apipie/generator}/swagger/context_spec.rb +1 -0
- data/spec/lib/{method_description_spec.rb → apipie/method_description_spec.rb} +4 -4
- data/spec/lib/apipie/no_documented_method_spec.rb +17 -0
- data/spec/lib/apipie/param_description/deprecation_spec.rb +31 -0
- data/spec/lib/{param_description_spec.rb → apipie/param_description_spec.rb} +81 -1
- data/spec/lib/apipie/resource_description_spec.rb +91 -0
- data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
- data/spec/lib/rake_spec.rb +1 -1
- data/spec/lib/swagger/rake_swagger_spec.rb +2 -2
- data/spec/lib/swagger/swagger_dsl_spec.rb +11 -5
- data/spec/spec_helper.rb +3 -3
- metadata +79 -29
- data/spec/lib/application_spec.rb +0 -49
- data/spec/lib/resource_description_spec.rb +0 -48
- /data/spec/{lib/swagger/response_validation_spec.rb → controllers/pets_controller_spec.rb} +0 -0
- /data/spec/lib/{extractor → apipie/extractor/recorder}/middleware_spec.rb +0 -0
- /data/spec/lib/{extractor → apipie/extractor}/writer_spec.rb +0 -0
- /data/spec/lib/{extractor → apipie}/extractor_spec.rb +0 -0
- /data/spec/lib/{file_handler_spec.rb → apipie/file_handler_spec.rb} +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/operation_id_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description/builder_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description/composite_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description/description_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description/in_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description/name_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description/type_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/param_description_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/type_extractor_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/warning_spec.rb +0 -0
- /data/spec/lib/{generator → apipie/generator}/swagger/warning_writer_spec.rb +0 -0
- /data/spec/lib/{method_description → apipie/method_description}/apis_service_spec.rb +0 -0
- /data/spec/lib/{param_group_spec.rb → apipie/param_group_spec.rb} +0 -0
- /data/spec/lib/{validator_spec.rb → apipie/validator_spec.rb} +0 -0
- /data/spec/{controllers → test_engine}/memes_controller_spec.rb +0 -0
data/CHANGELOG.md
CHANGED
@@ -4,10 +4,25 @@
|
|
4
4
|
Also deleted the `Gemfile` that was now a broken symlink.
|
5
5
|
please use `export BUNDLE_GEMFILE='gemfiles/Gemfile.rails61'; bundle exec rspec` to run the test suite
|
6
6
|
|
7
|
+
## [v0.9.4](https://github.com/Apipie/apipie-rails/tree/v0.9.4) (2023-04-11)
|
8
|
+
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.9.3...v0.9.4)
|
9
|
+
* [Fix] Separate nested resource name [#855](https://github.com/Apipie/apipie-rails/pull/855)[#455](https://github.com/Apipie/apipie-rails/issues/455) (Panos Dalitsouris)
|
10
|
+
* [Rubocop] Disable a few Rubocop Rules, run Rubocop with ruby 3.2 [#851](https://github.com/Apipie/apipie-rails/pull/851)[#853](https://github.com/Apipie/apipie-rails/pull/853)[#840](https://github.com/Apipie/apipie-rails/pull/840)[#841](https://github.com/Apipie/apipie-rails/pull/841) (Panos Dalitsouris)
|
11
|
+
* [Rubocop] More Rubocop Auto corrections [#858](https://github.com/Apipie/apipie-rails/pull/858)[#849](https://github.com/Apipie/apipie-rails/pull/849)[#850](https://github.com/Apipie/apipie-rails/pull/850)[#844](https://github.com/Apipie/apipie-rails/pull/844)[#846](https://github.com/Apipie/apipie-rails/pull/846)[#834](https://github.com/Apipie/apipie-rails/pull/834)[#847](https://github.com/Apipie/apipie-rails/pull/847) (Rubocop Challenger)
|
12
|
+
|
13
|
+
## [v0.9.3](https://github.com/Apipie/apipie-rails/tree/v0.9.3) (2023-03-08)
|
14
|
+
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.9.2...v0.9.3)
|
15
|
+
* [Feature] Allow Apipie::ParamDescription to be marked as deprecated [#819](https://github.com/Apipie/apipie-rails/pull/819)[#811](https://github.com/Apipie/apipie-rails/pull/811) (Panos Dalitsouris)
|
16
|
+
* [Fix] Make html markup thread safe ([#822](https://github.com/Apipie/apipie-rails/issues/822)) (Adam Růžička)
|
17
|
+
* [Feature] Allow action matcher strategy to be configured [#821](https://github.com/Apipie/apipie-rails/pull/821) (Panos Dalitsouris)
|
18
|
+
* [CI] Run Rubocop when opening PR [#826](https://github.com/Apipie/apipie-rails/pull/826) (Panos Dalitsouris)
|
19
|
+
* [CI] Green rubocop - Fix after rubocop challenger upgrade [#829](https://github.com/Apipie/apipie-rails/pull/829) (Mathieu Jobin)
|
20
|
+
* [Rubocop] More Rubocop Auto corrections [#818](https://github.com/Apipie/apipie-rails/pull/818)[#825](https://github.com/Apipie/apipie-rails/pull/825)[#827](https://github.com/Apipie/apipie-rails/pull/827)[#837](https://github.com/Apipie/apipie-rails/pull/837)[#839](https://github.com/Apipie/apipie-rails/pull/839) (Rubocop Challenger)
|
21
|
+
|
7
22
|
## [v0.9.2](https://github.com/Apipie/apipie-rails/tree/v0.9.2) (2023-02-07)
|
8
23
|
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.9.1...v0.9.2)
|
9
24
|
* [Rubocop] More Rubocop Auto corrections [#795](https://github.com/Apipie/apipie-rails/pull/795)[#781](https://github.com/Apipie/apipie-rails/pull/781)[#791](https://github.com/Apipie/apipie-rails/pull/791)[#788](https://github.com/Apipie/apipie-rails/pull/788) (Rubocop Challenger)
|
10
|
-
* [Fix] Can't include translation in full description ([#446](https://github.com/Apipie/apipie-rails/issues/446)) [#808](https://github.com/Apipie/apipie-rails/pull/808)(
|
25
|
+
* [Fix] Can't include translation in full description ([#446](https://github.com/Apipie/apipie-rails/issues/446)) [#808](https://github.com/Apipie/apipie-rails/pull/808) (Peter Nagy)
|
11
26
|
* [Refactor] Move swagger param description creation [#810](https://github.com/Apipie/apipie-rails/pull/810) (Panos Dalitsouris)
|
12
27
|
* [Rubocop] Redo rubocop TODOs, set HashSyntax config to most used style [#814](https://github.com/Apipie/apipie-rails/pull/814) (Mathieu Jobin)
|
13
28
|
* [Fix] Swagger missing i18n [#815](https://github.com/Apipie/apipie-rails/pull/815) (@jirubio)
|
data/README.rst
CHANGED
@@ -355,6 +355,22 @@ Example:
|
|
355
355
|
#...
|
356
356
|
end
|
357
357
|
|
358
|
+
deprecated
|
359
|
+
Indicates if the parameter is marked as deprecated.
|
360
|
+
|
361
|
+
Example
|
362
|
+
~~~~~~~~
|
363
|
+
|
364
|
+
.. code:: ruby
|
365
|
+
|
366
|
+
param :pet_name, String, desc: "Name of pet", deprecated: true
|
367
|
+
param :pet_name, String, desc: "Name of pet", deprecated: 'Some deprecation info'
|
368
|
+
param :pet_name, String, desc: "Name of pet", deprecated: { in: "2.3", info: "Something", sunset: "3.0" }
|
369
|
+
def create
|
370
|
+
#...
|
371
|
+
end
|
372
|
+
|
373
|
+
|
358
374
|
DRY with param_group
|
359
375
|
--------------------
|
360
376
|
|
@@ -982,6 +998,9 @@ reload_controllers
|
|
982
998
|
api_controllers_matcher
|
983
999
|
For reloading to work properly you need to specify where your API controllers are. Can be an array if multiple paths are needed
|
984
1000
|
|
1001
|
+
api_action_matcher
|
1002
|
+
Determines the strategy to identity the correct controller action. Needs to be a class that implements a `.call(controller)` method
|
1003
|
+
|
985
1004
|
api_routes
|
986
1005
|
Set if your application uses a custom API router, different from the Rails
|
987
1006
|
default
|
@@ -1063,6 +1082,7 @@ Example:
|
|
1063
1082
|
config.markup = Apipie::Markup::Markdown.new
|
1064
1083
|
config.reload_controllers = Rails.env.development?
|
1065
1084
|
config.api_controllers_matcher = File.join(Rails.root, "app", "controllers", "**","*.rb")
|
1085
|
+
config.api_action_matcher = proc { |controller| controller.params[:action] }
|
1066
1086
|
config.api_routes = Rails.application.routes
|
1067
1087
|
config.app_info["1.0"] = "
|
1068
1088
|
This is where you can inform user about your application and API
|
data/apipie-rails.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
|
2
3
|
$:.push File.expand_path('lib', __dir__)
|
3
4
|
require "apipie/version"
|
4
5
|
|
@@ -28,6 +29,9 @@ Gem::Specification.new do |s|
|
|
28
29
|
s.add_development_dependency "rspec-rails", "~> 3.0"
|
29
30
|
s.add_development_dependency "rake"
|
30
31
|
s.add_development_dependency 'rubocop_challenger'
|
32
|
+
s.add_development_dependency 'rubocop-rails'
|
33
|
+
s.add_development_dependency 'rubocop-rspec'
|
34
|
+
s.add_development_dependency 'rubocop-performance'
|
31
35
|
s.add_development_dependency "simplecov"
|
32
36
|
s.add_development_dependency "sqlite3"
|
33
37
|
end
|
@@ -155,7 +155,7 @@ module Apipie
|
|
155
155
|
def render_from_cache
|
156
156
|
path = Apipie.configuration.doc_base_url.dup
|
157
157
|
# some params can contain dot, but only one in row
|
158
|
-
if [:resource, :method, :format, :version].any? { |p| params[p].to_s.gsub(".", "") =~ /\W/ || params[p].to_s
|
158
|
+
if [:resource, :method, :format, :version].any? { |p| params[p].to_s.gsub(".", "") =~ /\W/ || params[p].to_s.include?('..') }
|
159
159
|
head :bad_request and return
|
160
160
|
end
|
161
161
|
|
@@ -171,7 +171,7 @@ module Apipie
|
|
171
171
|
# we sanitize the params before so in ideal case, this condition
|
172
172
|
# will be never satisfied. It's here for cases somebody adds new
|
173
173
|
# param into the path later and forgets about sanitation.
|
174
|
-
if path
|
174
|
+
if path.include?('..')
|
175
175
|
head :bad_request and return
|
176
176
|
end
|
177
177
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% if deprecation.present? %>
|
2
|
+
<strong><%= t('apipie.deprecation_details') %></strong>
|
3
|
+
<ul>
|
4
|
+
<% if deprecation[:deprecated_in].present? %>
|
5
|
+
<li><%= t('apipie.deprecation.attributes.deprecated_in') %>: <%= deprecation[:deprecated_in] %></li>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<% if deprecation[:sunset_at].present? %>
|
9
|
+
<li><%= t('apipie.deprecation.attributes.sunset_at') %>: <%= deprecation[:sunset_at] %></li>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<% if deprecation[:info].present? %>
|
13
|
+
<li><%= t('apipie.deprecation.attributes.info') %>: <%= deprecation[:info] %></li>
|
14
|
+
<% end %>
|
15
|
+
</ul>
|
16
|
+
<% end %>
|
@@ -7,7 +7,11 @@
|
|
7
7
|
<% end %>
|
8
8
|
<tr style='background-color:rgb(<%= "#{col},#{col},#{col}" %>);'>
|
9
9
|
<td>
|
10
|
-
<strong><%= param[:full_name]
|
10
|
+
<strong><%= param[:full_name] %></strong>
|
11
|
+
<% if param[:deprecated].present? %>
|
12
|
+
<code><%= t('apipie.deprecated').upcase %></code>
|
13
|
+
<% end %>
|
14
|
+
<br>
|
11
15
|
<small>
|
12
16
|
<%= param[:required] ? t('apipie.required') : t('apipie.optional') %>
|
13
17
|
<%= param[:allow_nil] ? ', '+t('apipie.nil_allowed') : '' %>
|
@@ -29,6 +33,8 @@
|
|
29
33
|
</ul>
|
30
34
|
<%- end %>
|
31
35
|
|
36
|
+
<%= render partial: 'deprecation', locals: { deprecation: param[:deprecation] } %>
|
37
|
+
|
32
38
|
<% unless param[:metadata].blank? %>
|
33
39
|
<br>
|
34
40
|
Metadata:
|
data/config/locales/en.yml
CHANGED
data/lib/apipie/apipie_module.rb
CHANGED
@@ -13,7 +13,7 @@ module Apipie
|
|
13
13
|
app.to_json(version, resource_name, method_name, lang)
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.to_swagger_json(version = nil, resource_name = nil, method_name = nil, lang = nil, clear_warnings=true)
|
16
|
+
def self.to_swagger_json(version = nil, resource_name = nil, method_name = nil, lang = nil, clear_warnings = true)
|
17
17
|
version ||= Apipie.configuration.default_version
|
18
18
|
app.to_swagger_json(version, resource_name, method_name, lang, clear_warnings)
|
19
19
|
end
|
@@ -24,7 +24,7 @@ module Apipie
|
|
24
24
|
app.json_schema_for_method_response(version, controller_name, method_name, return_code, allow_nulls)
|
25
25
|
end
|
26
26
|
|
27
|
-
def self.json_schema_for_self_describing_class(cls, allow_nulls=true)
|
27
|
+
def self.json_schema_for_self_describing_class(cls, allow_nulls = true)
|
28
28
|
app.json_schema_for_self_describing_class(cls, allow_nulls)
|
29
29
|
end
|
30
30
|
|
data/lib/apipie/application.rb
CHANGED
@@ -181,9 +181,7 @@ module Apipie
|
|
181
181
|
else
|
182
182
|
raise ArgumentError.new("Resource #{resource_name} does not exists.")
|
183
183
|
end
|
184
|
-
|
185
|
-
resource_description.method_description(method_name.to_sym)
|
186
|
-
end
|
184
|
+
resource_description&.method_description(method_name.to_sym)
|
187
185
|
end
|
188
186
|
alias [] get_method_description
|
189
187
|
|
@@ -242,7 +240,7 @@ module Apipie
|
|
242
240
|
|
243
241
|
# initialize variables for gathering dsl data
|
244
242
|
def init_env
|
245
|
-
@resource_descriptions = HashWithIndifferentAccess.new { |h, version| h[version] = {} }
|
243
|
+
@resource_descriptions = ActiveSupport::HashWithIndifferentAccess.new { |h, version| h[version] = {} }
|
246
244
|
@controller_to_resource_id = {}
|
247
245
|
@param_groups = {}
|
248
246
|
@swagger_generator = Apipie::SwaggerGenerator.new(self)
|
@@ -270,7 +268,7 @@ module Apipie
|
|
270
268
|
@swagger_generator.json_schema_for_self_describing_class(cls, allow_nulls)
|
271
269
|
end
|
272
270
|
|
273
|
-
def to_swagger_json(version, resource_name, method_name, lang, clear_warnings=false)
|
271
|
+
def to_swagger_json(version, resource_name, method_name, lang, clear_warnings = false)
|
274
272
|
return unless valid_search_args?(version, resource_name, method_name)
|
275
273
|
|
276
274
|
# if resource_name is blank, take just resources which have some methods because
|
@@ -377,8 +375,18 @@ module Apipie
|
|
377
375
|
@controller_to_resource_id[klass]
|
378
376
|
elsif Apipie.configuration.namespaced_resources? && klass.respond_to?(:controller_path)
|
379
377
|
return nil if klass == ActionController::Base
|
378
|
+
|
379
|
+
version_prefix = version_prefix(klass)
|
380
380
|
path = klass.controller_path
|
381
|
-
|
381
|
+
|
382
|
+
path =
|
383
|
+
if version_prefix == '/'
|
384
|
+
path
|
385
|
+
else
|
386
|
+
path.gsub(version_prefix, '')
|
387
|
+
end
|
388
|
+
|
389
|
+
path.gsub('/', '-')
|
382
390
|
elsif klass.respond_to?(:controller_name)
|
383
391
|
return nil if klass == ActionController::Base
|
384
392
|
klass.controller_name
|
@@ -388,11 +396,11 @@ module Apipie
|
|
388
396
|
end
|
389
397
|
|
390
398
|
def locale
|
391
|
-
Apipie.configuration.locale
|
399
|
+
Apipie.configuration.locale&.call(nil)
|
392
400
|
end
|
393
401
|
|
394
402
|
def locale=(locale)
|
395
|
-
Apipie.configuration.locale
|
403
|
+
Apipie.configuration.locale&.call(locale)
|
396
404
|
end
|
397
405
|
|
398
406
|
def translate(str, locale)
|
data/lib/apipie/configuration.rb
CHANGED
@@ -27,6 +27,16 @@ module Apipie
|
|
27
27
|
# "#{Rails.root}/app/controllers/api/*.rb"
|
28
28
|
attr_accessor :api_controllers_matcher
|
29
29
|
|
30
|
+
# An object that responds to a `.call(controller)` method responsible for
|
31
|
+
# matching the correct controller action
|
32
|
+
attr_reader :api_action_matcher
|
33
|
+
|
34
|
+
def api_action_matcher=(callable)
|
35
|
+
raise 'Must implement .call method' unless callable.respond_to?(:call)
|
36
|
+
|
37
|
+
@api_action_matcher = callable
|
38
|
+
end
|
39
|
+
|
30
40
|
# set to true if you want to reload the controllers at each refresh of the
|
31
41
|
# documentation. It requires +:api_controllers_matcher+ to be set to work
|
32
42
|
# properly.
|
@@ -147,7 +157,7 @@ module Apipie
|
|
147
157
|
def initialize
|
148
158
|
@markup = Apipie::Markup::RDoc.new
|
149
159
|
@app_name = "Another API"
|
150
|
-
@app_info = HashWithIndifferentAccess.new
|
160
|
+
@app_info = ActiveSupport::HashWithIndifferentAccess.new
|
151
161
|
@copyright = nil
|
152
162
|
@validate = :implicitly
|
153
163
|
@validate_value = true
|
@@ -155,7 +165,8 @@ module Apipie
|
|
155
165
|
@validate_key = false
|
156
166
|
@action_on_non_validated_keys = :raise
|
157
167
|
@required_by_default = false
|
158
|
-
@api_base_url = HashWithIndifferentAccess.new
|
168
|
+
@api_base_url = ActiveSupport::HashWithIndifferentAccess.new
|
169
|
+
@api_action_matcher = proc { |controller| controller.params[:action] }
|
159
170
|
@doc_base_url = "/apipie"
|
160
171
|
@layout = "apipie/apipie"
|
161
172
|
@disqus_shortname = nil
|
@@ -96,7 +96,7 @@ module Apipie
|
|
96
96
|
# # load paths from routes and don't provide description
|
97
97
|
# api
|
98
98
|
#
|
99
|
-
def api(method, path, desc = nil, options={}) #:doc:
|
99
|
+
def api(method, path, desc = nil, options = {}) #:doc:
|
100
100
|
return unless Apipie.active_dsl?
|
101
101
|
_apipie_dsl_data[:api] = true
|
102
102
|
_apipie_dsl_data[:api_args] << [method, path, desc, options]
|
@@ -105,7 +105,7 @@ module Apipie
|
|
105
105
|
# # load paths from routes
|
106
106
|
# api! "short description",
|
107
107
|
#
|
108
|
-
def api!(desc = nil, options={}) #:doc:
|
108
|
+
def api!(desc = nil, options = {}) #:doc:
|
109
109
|
return unless Apipie.active_dsl?
|
110
110
|
_apipie_dsl_data[:api] = true
|
111
111
|
_apipie_dsl_data[:api_from_routes] = { :desc => desc, :options =>options }
|
@@ -145,7 +145,7 @@ module Apipie
|
|
145
145
|
# EOS
|
146
146
|
def resource_description(options = {}, &block) #:doc:
|
147
147
|
return unless Apipie.active_dsl?
|
148
|
-
raise ArgumentError, "Block expected" unless
|
148
|
+
raise ArgumentError, "Block expected" unless block
|
149
149
|
|
150
150
|
dsl_data = ResourceDescriptionDsl.eval_dsl(self, &block)
|
151
151
|
versions = dsl_data[:api_versions]
|
@@ -218,7 +218,7 @@ module Apipie
|
|
218
218
|
# puts "hello world"
|
219
219
|
# end
|
220
220
|
#
|
221
|
-
def error(code_or_options, desc=nil, options={}) #:doc:
|
221
|
+
def error(code_or_options, desc = nil, options = {}) #:doc:
|
222
222
|
return unless Apipie.active_dsl?
|
223
223
|
_apipie_dsl_data[:errors] << [code_or_options, desc, options]
|
224
224
|
end
|
@@ -403,7 +403,7 @@ module Apipie
|
|
403
403
|
# render json: {user: {name: "Alfred"}}
|
404
404
|
# end
|
405
405
|
#
|
406
|
-
def returns(pgroup_or_options, desc_or_options=nil, options={}, &block) #:doc:
|
406
|
+
def returns(pgroup_or_options, desc_or_options = nil, options = {}, &block) #:doc:
|
407
407
|
return unless Apipie.active_dsl?
|
408
408
|
|
409
409
|
|
@@ -508,7 +508,7 @@ module Apipie
|
|
508
508
|
end
|
509
509
|
|
510
510
|
def _apipie_update_meta(method_desc, dsl_data)
|
511
|
-
return unless dsl_data[:meta]
|
511
|
+
return unless dsl_data[:meta].is_a?(Hash)
|
512
512
|
|
513
513
|
method_desc.metadata ||= {}
|
514
514
|
method_desc.metadata.merge!(dsl_data[:meta])
|
data/lib/apipie/errors.rb
CHANGED
@@ -60,27 +60,13 @@ module Apipie
|
|
60
60
|
|
61
61
|
class ResponseDoesNotMatchSwaggerSchema < Error
|
62
62
|
def initialize(controller_name, method_name, response_code, error_messages, schema, returned_object)
|
63
|
-
|
64
|
-
@method_name = method_name
|
65
|
-
@response_code = response_code
|
66
|
-
@error_messages = error_messages
|
67
|
-
@schema = schema
|
68
|
-
@returned_object = returned_object
|
69
|
-
end
|
70
|
-
|
71
|
-
def to_s
|
72
|
-
"Response does not match swagger schema (#{@controller_name}##{@method_name} #{@response_code}): #{@error_messages}\nSchema: #{JSON(@schema)}\nReturned object: #{@returned_object}"
|
63
|
+
super("Response does not match swagger schema (#{controller_name}##{method_name} #{response_code}): #{error_messages}\nSchema: #{JSON(schema)}\nReturned object: #{returned_object}")
|
73
64
|
end
|
74
65
|
end
|
75
66
|
|
76
67
|
class NoDocumentedMethod < Error
|
77
68
|
def initialize(controller_name, method_name)
|
78
|
-
|
79
|
-
@controller_name = controller_name
|
80
|
-
end
|
81
|
-
|
82
|
-
def to_s
|
83
|
-
"There is no documented method #{@controller_name}##{@method_name}"
|
69
|
+
super("There is no documented method #{controller_name}##{method_name}")
|
84
70
|
end
|
85
71
|
end
|
86
72
|
end
|
@@ -96,7 +96,7 @@ module Apipie
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def add_routes_info(desc)
|
99
|
-
api_prefix = Apipie.api_base_url.sub(
|
99
|
+
api_prefix = Apipie.api_base_url.sub(%r{/$},"")
|
100
100
|
desc[:api] = Apipie::Extractor.apis_from_routes[[desc[:controller].name, desc[:action]]]
|
101
101
|
if desc[:api]
|
102
102
|
desc[:params].each do |name, param|
|
@@ -9,7 +9,7 @@ module Apipie
|
|
9
9
|
|
10
10
|
def analyse_env(env)
|
11
11
|
@verb = env["REQUEST_METHOD"].to_sym
|
12
|
-
@path = env["PATH_INFO"].sub(
|
12
|
+
@path = env["PATH_INFO"].sub(%r{^/*},"/")
|
13
13
|
@query = env["QUERY_STRING"] unless env["QUERY_STRING"].blank?
|
14
14
|
@params = Rack::Utils.parse_nested_query(@query)
|
15
15
|
@params.merge!(env["action_dispatch.request.request_parameters"] || {})
|
@@ -24,7 +24,7 @@ module Apipie
|
|
24
24
|
|
25
25
|
def analyse_controller(controller)
|
26
26
|
@controller = controller.class
|
27
|
-
@action = controller
|
27
|
+
@action = Apipie.configuration.api_action_matcher.call(controller)
|
28
28
|
end
|
29
29
|
|
30
30
|
def analyse_response(response)
|
data/lib/apipie/extractor.rb
CHANGED
@@ -81,7 +81,7 @@ module Apipie
|
|
81
81
|
def apis_from_routes
|
82
82
|
return @apis_from_routes if @apis_from_routes
|
83
83
|
|
84
|
-
@api_prefix = Apipie.api_base_url.sub(
|
84
|
+
@api_prefix = Apipie.api_base_url.sub(%r{/$},"")
|
85
85
|
populate_api_routes
|
86
86
|
update_api_descriptions
|
87
87
|
|
@@ -157,7 +157,7 @@ module Apipie
|
|
157
157
|
method_key = "#{Apipie.get_resource_name(controller.safe_constantize || next)}##{action}"
|
158
158
|
old_apis = apis_from_docs[method_key] || []
|
159
159
|
new_apis.each do |new_api|
|
160
|
-
new_api[:path]
|
160
|
+
new_api[:path]&.sub!(/\(\.:format\)$/,"")
|
161
161
|
old_api = old_apis.find do |api|
|
162
162
|
api[:path] == "#{@api_prefix}#{new_api[:path]}"
|
163
163
|
end
|
@@ -37,7 +37,7 @@ class Apipie::Generator::Swagger::OperationId
|
|
37
37
|
#
|
38
38
|
# @return [String]
|
39
39
|
def path
|
40
|
-
@path.gsub(
|
40
|
+
@path.gsub(%r{/}, '_').gsub(/:(\w+)/, '\1').gsub(/_$/, '')
|
41
41
|
end
|
42
42
|
|
43
43
|
# Converts an http method like `GET` to `get` Using lowercase http method,
|
data/lib/apipie/helpers.rb
CHANGED
@@ -25,10 +25,10 @@ module Apipie
|
|
25
25
|
@url_prefix << request_script_name
|
26
26
|
@url_prefix << Apipie.configuration.doc_base_url
|
27
27
|
end
|
28
|
-
path = path.sub(
|
28
|
+
path = path.sub(%r{^/},"")
|
29
29
|
ret = "#{@url_prefix}/#{path}"
|
30
|
-
ret.insert(0,"/") unless ret =~
|
31
|
-
ret.sub!(
|
30
|
+
ret.insert(0,"/") unless ret =~ %r{\A[./]}
|
31
|
+
ret.sub!(%r{/*\Z},"")
|
32
32
|
ret
|
33
33
|
end
|
34
34
|
|
data/lib/apipie/markup.rb
CHANGED
@@ -4,6 +4,11 @@ module Apipie
|
|
4
4
|
|
5
5
|
class RDoc
|
6
6
|
|
7
|
+
def initialize
|
8
|
+
require 'rdoc'
|
9
|
+
require 'rdoc/markup/to_html'
|
10
|
+
end
|
11
|
+
|
7
12
|
def to_html(text)
|
8
13
|
rdoc.convert(text)
|
9
14
|
end
|
@@ -11,14 +16,10 @@ module Apipie
|
|
11
16
|
private
|
12
17
|
|
13
18
|
def rdoc
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
::RDoc::Markup::ToHtml.new()
|
19
|
-
else
|
20
|
-
::RDoc::Markup::ToHtml.new(::RDoc::Options.new)
|
21
|
-
end
|
19
|
+
if Gem::Version.new(::RDoc::VERSION) < Gem::Version.new('4.0.0')
|
20
|
+
::RDoc::Markup::ToHtml.new()
|
21
|
+
else
|
22
|
+
::RDoc::Markup::ToHtml.new(::RDoc::Options.new)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Apipie
|
4
|
+
class ParamDescription
|
5
|
+
# Data transfer object, used when param description is deprecated
|
6
|
+
class Deprecation
|
7
|
+
attr_reader :info, :deprecated_in, :sunset_at
|
8
|
+
|
9
|
+
def initialize(info: nil, deprecated_in: nil, sunset_at: nil)
|
10
|
+
@info = info
|
11
|
+
@deprecated_in = deprecated_in
|
12
|
+
@sunset_at = sunset_at
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_json(*_args)
|
16
|
+
{
|
17
|
+
info: @info,
|
18
|
+
deprecated_in: @deprecated_in,
|
19
|
+
sunset_at: @sunset_at
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -97,6 +97,7 @@ module Apipie
|
|
97
97
|
@validations = Array(options[:validations]).map {|v| concern_subst(Apipie.markup_to_html(v)) }
|
98
98
|
|
99
99
|
@additional_properties = @options[:additional_properties]
|
100
|
+
@deprecated = @options[:deprecated] || false
|
100
101
|
end
|
101
102
|
|
102
103
|
def from_concern?
|
@@ -155,17 +156,25 @@ module Apipie
|
|
155
156
|
end
|
156
157
|
|
157
158
|
def to_json(lang = nil)
|
158
|
-
hash = {
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
159
|
+
hash = {
|
160
|
+
name: name.to_s,
|
161
|
+
full_name: full_name,
|
162
|
+
description: preformat_text(Apipie.app.translate(@options[:desc], lang)),
|
163
|
+
required: required,
|
164
|
+
allow_nil: allow_nil,
|
165
|
+
allow_blank: allow_blank,
|
166
|
+
validator: validator.to_s,
|
167
|
+
expected_type: validator.expected_type,
|
168
|
+
metadata: metadata,
|
169
|
+
show: show,
|
170
|
+
validations: validations,
|
171
|
+
deprecated: deprecated?
|
172
|
+
}
|
173
|
+
|
174
|
+
if deprecation.present?
|
175
|
+
hash[:deprecation] = deprecation.to_json
|
176
|
+
end
|
177
|
+
|
169
178
|
if sub_params = validator.params_ordered
|
170
179
|
hash[:params] = sub_params.map { |p| p.to_json(lang)}
|
171
180
|
end
|
@@ -279,6 +288,24 @@ module Apipie
|
|
279
288
|
end
|
280
289
|
end
|
281
290
|
|
291
|
+
def deprecated?
|
292
|
+
@deprecated.present?
|
293
|
+
end
|
294
|
+
|
295
|
+
def deprecation
|
296
|
+
return if @deprecated.blank? || @deprecated == true
|
297
|
+
|
298
|
+
case @deprecated
|
299
|
+
when Hash
|
300
|
+
Apipie::ParamDescription::Deprecation.new(
|
301
|
+
info: @deprecated[:info],
|
302
|
+
deprecated_in: @deprecated[:in],
|
303
|
+
sunset_at: @deprecated[:sunset]
|
304
|
+
)
|
305
|
+
when String
|
306
|
+
Apipie::ParamDescription::Deprecation.new(info: @deprecated)
|
307
|
+
end
|
308
|
+
end
|
282
309
|
end
|
283
310
|
|
284
311
|
end
|
@@ -14,27 +14,25 @@ module Apipie
|
|
14
14
|
class ResourceDescription
|
15
15
|
|
16
16
|
attr_reader :controller, :_short_description, :_full_description, :_methods, :_id,
|
17
|
-
:_path, :
|
17
|
+
:_path, :_params_args, :_returns_args, :_tag_list_arg, :_errors_args,
|
18
18
|
:_formats, :_parent, :_metadata, :_headers, :_deprecated
|
19
19
|
|
20
|
-
def initialize(controller,
|
21
|
-
|
20
|
+
def initialize(controller, id, dsl_data = nil, version = nil)
|
22
21
|
@_methods = ActiveSupport::OrderedHash.new
|
23
22
|
@_params_args = []
|
24
23
|
@_errors_args = []
|
25
24
|
@_returns_args = []
|
26
25
|
|
27
26
|
@controller = controller
|
28
|
-
@_id =
|
27
|
+
@_id = id
|
29
28
|
@_version = version || Apipie.configuration.default_version
|
30
|
-
@_name = @_id.humanize
|
31
29
|
@_parent = Apipie.get_resource_description(controller.superclass, version)
|
32
30
|
|
33
31
|
update_from_dsl_data(dsl_data) if dsl_data
|
34
32
|
end
|
35
33
|
|
36
34
|
def update_from_dsl_data(dsl_data)
|
37
|
-
@
|
35
|
+
@_resource_name = dsl_data[:resource_name] if dsl_data[:resource_name]
|
38
36
|
@_full_description = dsl_data[:description]
|
39
37
|
@_short_description = dsl_data[:short_description]
|
40
38
|
@_path = dsl_data[:path] || ""
|
@@ -61,6 +59,11 @@ module Apipie
|
|
61
59
|
@_api_base_url || @_parent.try(:_api_base_url) || Apipie.api_base_url(_version)
|
62
60
|
end
|
63
61
|
|
62
|
+
def name
|
63
|
+
@name ||= @_resource_name.presence || @_id.split('-').map(&:capitalize).join('::')
|
64
|
+
end
|
65
|
+
alias _name name
|
66
|
+
|
64
67
|
def add_method_description(method_description)
|
65
68
|
Apipie.debug "@resource_descriptions[#{self._version}][#{self._name}]._methods[#{method_description.method}] = #{method_description}"
|
66
69
|
@_methods[method_description.method.to_sym] = method_description
|
@@ -108,7 +111,7 @@ module Apipie
|
|
108
111
|
:doc_url => doc_url,
|
109
112
|
:id => _id,
|
110
113
|
:api_url => api_url,
|
111
|
-
:name =>
|
114
|
+
:name => name,
|
112
115
|
:short_description => Apipie.app.translate(@_short_description, lang),
|
113
116
|
:full_description => Apipie.markup_to_html(Apipie.app.translate(@_full_description, lang)),
|
114
117
|
:version => _version,
|