apipie-rails-jq 1.4.3.pre.beta.pre.jq.1
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 +7 -0
- data/.github/workflows/build.yml +32 -0
- data/.github/workflows/rubocop-challenger.yml +26 -0
- data/.github/workflows/rubocop.yml +18 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.rubocop.yml +132 -0
- data/.rubocop_todo.yml +1967 -0
- data/.vscode/settings.json +3 -0
- data/APACHE-LICENSE-2.0 +202 -0
- data/CHANGELOG.md +693 -0
- data/Gemfile +19 -0
- data/MIT-LICENSE +20 -0
- data/NOTICE +4 -0
- data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
- data/README.md +2088 -0
- data/Rakefile +8 -0
- data/apipie-rails.gemspec +44 -0
- data/app/controllers/apipie/apipies_controller.rb +184 -0
- data/app/helpers/apipie_helper.rb +10 -0
- data/app/public/apipie/javascripts/apipie.js +6 -0
- data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +167 -0
- data/app/public/apipie/javascripts/bundled/bootstrap.js +2280 -0
- data/app/public/apipie/javascripts/bundled/jquery.js +2 -0
- data/app/public/apipie/javascripts/bundled/prettify.js +28 -0
- data/app/public/apipie/stylesheets/application.css +7 -0
- data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +9 -0
- data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +9 -0
- data/app/public/apipie/stylesheets/bundled/prettify.css +30 -0
- data/app/views/apipie/apipies/_deprecation.html.erb +16 -0
- data/app/views/apipie/apipies/_disqus.html.erb +13 -0
- data/app/views/apipie/apipies/_errors.html.erb +23 -0
- data/app/views/apipie/apipies/_headers.html.erb +26 -0
- data/app/views/apipie/apipies/_languages.erb +6 -0
- data/app/views/apipie/apipies/_metadata.erb +1 -0
- data/app/views/apipie/apipies/_method_detail.erb +63 -0
- data/app/views/apipie/apipies/_params.html.erb +49 -0
- data/app/views/apipie/apipies/_params_plain.html.erb +21 -0
- data/app/views/apipie/apipies/apipie_404.html.erb +17 -0
- data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
- data/app/views/apipie/apipies/getting_started.html.erb +6 -0
- data/app/views/apipie/apipies/index.html.erb +56 -0
- data/app/views/apipie/apipies/method.html.erb +41 -0
- data/app/views/apipie/apipies/plain.html.erb +77 -0
- data/app/views/apipie/apipies/resource.html.erb +80 -0
- data/app/views/apipie/apipies/static.html.erb +103 -0
- data/app/views/layouts/apipie/apipie.html.erb +27 -0
- data/config/locales/de.yml +28 -0
- data/config/locales/en.yml +41 -0
- data/config/locales/es.yml +28 -0
- data/config/locales/fr.yml +31 -0
- data/config/locales/it.yml +41 -0
- data/config/locales/ja.yml +31 -0
- data/config/locales/ko.yml +32 -0
- data/config/locales/pl.yml +28 -0
- data/config/locales/pt-BR.yml +28 -0
- data/config/locales/ru.yml +28 -0
- data/config/locales/tr.yml +28 -0
- data/config/locales/zh-CN.yml +28 -0
- data/config/locales/zh-TW.yml +28 -0
- data/gemfiles/Gemfile.tools +9 -0
- data/images/screenshot-1.png +0 -0
- data/images/screenshot-2.png +0 -0
- data/lib/apipie/apipie_module.rb +83 -0
- data/lib/apipie/application.rb +499 -0
- data/lib/apipie/configuration.rb +196 -0
- data/lib/apipie/core_ext/route.rb +9 -0
- data/lib/apipie/dsl_definition.rb +630 -0
- data/lib/apipie/error_description.rb +46 -0
- data/lib/apipie/errors.rb +86 -0
- data/lib/apipie/extractor/collector.rb +116 -0
- data/lib/apipie/extractor/recorder.rb +193 -0
- data/lib/apipie/extractor/writer.rb +454 -0
- data/lib/apipie/extractor.rb +181 -0
- data/lib/apipie/generator/config.rb +12 -0
- data/lib/apipie/generator/generator.rb +2 -0
- data/lib/apipie/generator/swagger/computed_interface_id.rb +23 -0
- data/lib/apipie/generator/swagger/config.rb +80 -0
- data/lib/apipie/generator/swagger/context.rb +38 -0
- data/lib/apipie/generator/swagger/method_description/api_decorator.rb +20 -0
- data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +89 -0
- data/lib/apipie/generator/swagger/method_description/decorator.rb +22 -0
- data/lib/apipie/generator/swagger/method_description/parameters_service.rb +139 -0
- data/lib/apipie/generator/swagger/method_description/response_schema_service.rb +46 -0
- data/lib/apipie/generator/swagger/method_description/response_service.rb +71 -0
- data/lib/apipie/generator/swagger/method_description.rb +2 -0
- data/lib/apipie/generator/swagger/operation_id.rb +51 -0
- data/lib/apipie/generator/swagger/param_description/builder.rb +114 -0
- data/lib/apipie/generator/swagger/param_description/composite.rb +119 -0
- data/lib/apipie/generator/swagger/param_description/description.rb +15 -0
- data/lib/apipie/generator/swagger/param_description/in.rb +37 -0
- data/lib/apipie/generator/swagger/param_description/name.rb +18 -0
- data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +61 -0
- data/lib/apipie/generator/swagger/param_description/referenced_composite.rb +36 -0
- data/lib/apipie/generator/swagger/param_description/type.rb +132 -0
- data/lib/apipie/generator/swagger/param_description.rb +18 -0
- data/lib/apipie/generator/swagger/path_decorator.rb +36 -0
- data/lib/apipie/generator/swagger/referenced_definitions.rb +17 -0
- data/lib/apipie/generator/swagger/resource_description_collection.rb +30 -0
- data/lib/apipie/generator/swagger/resource_description_composite.rb +56 -0
- data/lib/apipie/generator/swagger/schema.rb +63 -0
- data/lib/apipie/generator/swagger/swagger.rb +2 -0
- data/lib/apipie/generator/swagger/type.rb +16 -0
- data/lib/apipie/generator/swagger/type_extractor.rb +51 -0
- data/lib/apipie/generator/swagger/warning.rb +74 -0
- data/lib/apipie/generator/swagger/warning_writer.rb +54 -0
- data/lib/apipie/helpers.rb +73 -0
- data/lib/apipie/markup.rb +52 -0
- data/lib/apipie/method_description/api.rb +12 -0
- data/lib/apipie/method_description/apis_service.rb +82 -0
- data/lib/apipie/method_description.rb +230 -0
- data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
- data/lib/apipie/param_description/deprecation.rb +24 -0
- data/lib/apipie/param_description.rb +313 -0
- data/lib/apipie/railtie.rb +9 -0
- data/lib/apipie/resource_description.rb +152 -0
- data/lib/apipie/response_description.rb +157 -0
- data/lib/apipie/response_description_adapter.rb +202 -0
- data/lib/apipie/routes_formatter.rb +33 -0
- data/lib/apipie/routing.rb +16 -0
- data/lib/apipie/rspec/response_validation_helper.rb +194 -0
- data/lib/apipie/see_description.rb +39 -0
- data/lib/apipie/static_dispatcher.rb +75 -0
- data/lib/apipie/swagger_generator.rb +45 -0
- data/lib/apipie/tag_list_description.rb +11 -0
- data/lib/apipie/validator.rb +552 -0
- data/lib/apipie/version.rb +3 -0
- data/lib/apipie-rails.rb +60 -0
- data/lib/generators/apipie/install/README +6 -0
- data/lib/generators/apipie/install/install_generator.rb +25 -0
- data/lib/generators/apipie/install/templates/initializer.rb.erb +7 -0
- data/lib/generators/apipie/views_generator.rb +11 -0
- data/lib/tasks/apipie.rake +355 -0
- data/rel-eng/gem_release.ipynb +398 -0
- data/rel-eng/packages/.readme +3 -0
- data/rel-eng/packages/rubygem-apipie-rails +1 -0
- data/rel-eng/tito.props +5 -0
- data/spec/controllers/api/v1/architectures_controller_spec.rb +29 -0
- data/spec/controllers/api/v2/architectures_controller_spec.rb +19 -0
- data/spec/controllers/api/v2/empty_middle_controller_spec.rb +23 -0
- data/spec/controllers/api/v2/nested/resources_controller_spec.rb +27 -0
- data/spec/controllers/api/v2/sub/footguns_controller_spec.rb +19 -0
- data/spec/controllers/concerns_controller_spec.rb +42 -0
- data/spec/controllers/extended_controller_spec.rb +14 -0
- data/spec/controllers/included_param_group_controller_spec.rb +13 -0
- data/spec/controllers/pets_controller_spec.rb +98 -0
- data/spec/controllers/users_controller_spec.rb +794 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/api/base_controller.rb +4 -0
- data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +43 -0
- data/spec/dummy/app/controllers/api/v1/base_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +31 -0
- data/spec/dummy/app/controllers/api/v2/base_controller.rb +17 -0
- data/spec/dummy/app/controllers/api/v2/empty_middle_controller.rb +14 -0
- data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +32 -0
- data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +33 -0
- data/spec/dummy/app/controllers/api/v2/sub/footguns_controller.rb +30 -0
- data/spec/dummy/app/controllers/application_controller.rb +18 -0
- data/spec/dummy/app/controllers/concerns_controller.rb +8 -0
- data/spec/dummy/app/controllers/extended_controller.rb +14 -0
- data/spec/dummy/app/controllers/extending_concern.rb +10 -0
- data/spec/dummy/app/controllers/files_controller.rb +5 -0
- data/spec/dummy/app/controllers/included_param_group_controller.rb +19 -0
- data/spec/dummy/app/controllers/overridden_concerns_controller.rb +31 -0
- data/spec/dummy/app/controllers/pets_controller.rb +408 -0
- data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
- data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
- data/spec/dummy/app/controllers/sample_controller.rb +39 -0
- data/spec/dummy/app/controllers/tagged_cats_controller.rb +32 -0
- data/spec/dummy/app/controllers/tagged_dogs_controller.rb +15 -0
- data/spec/dummy/app/controllers/twitter_example_controller.rb +307 -0
- data/spec/dummy/app/controllers/users_controller.rb +310 -0
- data/spec/dummy/app/helpers/random_param_group.rb +8 -0
- data/spec/dummy/app/views/layouts/application.html.erb +21 -0
- data/spec/dummy/components/test_engine/Gemfile +6 -0
- data/spec/dummy/components/test_engine/app/controllers/test_engine/application_controller.rb +4 -0
- data/spec/dummy/components/test_engine/app/controllers/test_engine/memes_controller.rb +37 -0
- data/spec/dummy/components/test_engine/config/routes.rb +3 -0
- data/spec/dummy/components/test_engine/db/.gitkeep +0 -0
- data/spec/dummy/components/test_engine/lib/test_engine.rb +7 -0
- data/spec/dummy/components/test_engine/test_engine.gemspec +11 -0
- data/spec/dummy/config/application.rb +47 -0
- data/spec/dummy/config/boot.rb +12 -0
- data/spec/dummy/config/database.yml +21 -0
- data/spec/dummy/config/environment.rb +8 -0
- data/spec/dummy/config/environments/development.rb +25 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +33 -0
- data/spec/dummy/config/initializers/apipie.rb +110 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +8 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +61 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/.gitkeep +0 -0
- data/spec/dummy/doc/apipie_examples.json +1 -0
- data/spec/dummy/doc/users/desc_from_file.md +1 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/lib/apipie/apipies_controller_spec.rb +345 -0
- data/spec/lib/apipie/application_spec.rb +62 -0
- data/spec/lib/apipie/configuration_spec.rb +38 -0
- data/spec/lib/apipie/extractor/collector_spec.rb +57 -0
- data/spec/lib/apipie/extractor/recorder/middleware_spec.rb +44 -0
- data/spec/lib/apipie/extractor/recorder_spec.rb +77 -0
- data/spec/lib/apipie/extractor/writer_spec.rb +112 -0
- data/spec/lib/apipie/extractor_spec.rb +9 -0
- data/spec/lib/apipie/file_handler_spec.rb +25 -0
- data/spec/lib/apipie/generator/swagger/config_spec.rb +19 -0
- data/spec/lib/apipie/generator/swagger/context_spec.rb +56 -0
- data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +119 -0
- data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +105 -0
- data/spec/lib/apipie/generator/swagger/method_description/response_service_spec.rb +62 -0
- data/spec/lib/apipie/generator/swagger/operation_id_spec.rb +63 -0
- data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +245 -0
- data/spec/lib/apipie/generator/swagger/param_description/composite_spec.rb +95 -0
- data/spec/lib/apipie/generator/swagger/param_description/description_spec.rb +79 -0
- data/spec/lib/apipie/generator/swagger/param_description/in_spec.rb +86 -0
- data/spec/lib/apipie/generator/swagger/param_description/name_spec.rb +81 -0
- data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +210 -0
- data/spec/lib/apipie/generator/swagger/param_description_spec.rb +28 -0
- data/spec/lib/apipie/generator/swagger/path_decorator_spec.rb +57 -0
- data/spec/lib/apipie/generator/swagger/referenced_definitions_spec.rb +35 -0
- data/spec/lib/apipie/generator/swagger/resource_description_composite_spec.rb +37 -0
- data/spec/lib/apipie/generator/swagger/resource_descriptions_collection_spec.rb +57 -0
- data/spec/lib/apipie/generator/swagger/schema_spec.rb +89 -0
- data/spec/lib/apipie/generator/swagger/type_extractor_spec.rb +38 -0
- data/spec/lib/apipie/generator/swagger/warning_spec.rb +51 -0
- data/spec/lib/apipie/generator/swagger/warning_writer_spec.rb +71 -0
- data/spec/lib/apipie/method_description/apis_service_spec.rb +60 -0
- data/spec/lib/apipie/method_description_spec.rb +133 -0
- 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/apipie/param_description_spec.rb +671 -0
- data/spec/lib/apipie/param_group_spec.rb +61 -0
- data/spec/lib/apipie/resource_description_spec.rb +91 -0
- data/spec/lib/apipie/response_description/response_object_spec.rb +22 -0
- data/spec/lib/apipie/response_description_spec.rb +56 -0
- data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
- data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
- data/spec/lib/apipie/validator_spec.rb +149 -0
- data/spec/lib/rake_spec.rb +69 -0
- data/spec/lib/swagger/openapi_2_0_schema.json +1614 -0
- data/spec/lib/swagger/rake_swagger_spec.rb +159 -0
- data/spec/lib/swagger/swagger_dsl_spec.rb +664 -0
- data/spec/lib/validators/array_validator_spec.rb +85 -0
- data/spec/spec_helper.rb +92 -0
- data/spec/support/custom_bool_validator.rb +17 -0
- data/spec/support/rake.rb +21 -0
- data/spec/test_engine/memes_controller_spec.rb +10 -0
- metadata +499 -0
@@ -0,0 +1,630 @@
|
|
1
|
+
# Apipie DSL functions.
|
2
|
+
|
3
|
+
module Apipie
|
4
|
+
|
5
|
+
# DSL is a module that provides #api, #error, #param, #returns.
|
6
|
+
module DSL
|
7
|
+
|
8
|
+
module Base
|
9
|
+
attr_reader :apipie_resource_descriptions, :api_params
|
10
|
+
|
11
|
+
def _apipie_eval_dsl(*args, &block)
|
12
|
+
raise 'The Apipie DLS data need to be cleared before evaluating new block' if @_apipie_dsl_data
|
13
|
+
instance_exec(*args, &block)
|
14
|
+
return _apipie_dsl_data
|
15
|
+
ensure
|
16
|
+
_apipie_dsl_data_clear
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def _apipie_dsl_data
|
22
|
+
@_apipie_dsl_data ||= _apipie_dsl_data_init
|
23
|
+
end
|
24
|
+
|
25
|
+
def _apipie_dsl_data_clear
|
26
|
+
@_apipie_dsl_data = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def _apipie_dsl_data_init
|
30
|
+
@_apipie_dsl_data = {
|
31
|
+
:api => false,
|
32
|
+
:api_args => [],
|
33
|
+
:api_from_routes => nil,
|
34
|
+
:errors => [],
|
35
|
+
:tag_list => [],
|
36
|
+
:returns => {},
|
37
|
+
:params => [],
|
38
|
+
:headers => [],
|
39
|
+
:resource_id => nil,
|
40
|
+
:short_description => nil,
|
41
|
+
:description => nil,
|
42
|
+
:examples => [],
|
43
|
+
:see => [],
|
44
|
+
:formats => nil,
|
45
|
+
:api_versions => [],
|
46
|
+
:meta => nil,
|
47
|
+
:show => true,
|
48
|
+
:deprecated => false
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Resource
|
54
|
+
# resource_id "my_own_resource_id"
|
55
|
+
def resource_id(resource_id)
|
56
|
+
Apipie.set_resource_id(@controller, resource_id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def name(name)
|
60
|
+
_apipie_dsl_data[:resource_name] = name
|
61
|
+
end
|
62
|
+
|
63
|
+
def api_base_url(url)
|
64
|
+
_apipie_dsl_data[:api_base_url] = url
|
65
|
+
end
|
66
|
+
|
67
|
+
def short(short)
|
68
|
+
_apipie_dsl_data[:short_description] = short
|
69
|
+
end
|
70
|
+
alias short_description short
|
71
|
+
|
72
|
+
def path(path)
|
73
|
+
_apipie_dsl_data[:path] = path
|
74
|
+
end
|
75
|
+
|
76
|
+
def app_info(app_info)
|
77
|
+
_apipie_dsl_data[:app_info] = app_info
|
78
|
+
end
|
79
|
+
|
80
|
+
def deprecated(value)
|
81
|
+
_apipie_dsl_data[:deprecated] = value
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
module Action
|
87
|
+
|
88
|
+
def def_param_group(name, &block)
|
89
|
+
Apipie.add_param_group(self, name, &block)
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# # load paths from routes and don't provide description
|
94
|
+
# api
|
95
|
+
#
|
96
|
+
def api(method, path, desc = nil, options = {}) #:doc:
|
97
|
+
return unless Apipie.active_dsl?
|
98
|
+
_apipie_dsl_data[:api] = true
|
99
|
+
_apipie_dsl_data[:api_args] << [method, path, desc, options]
|
100
|
+
end
|
101
|
+
|
102
|
+
# # load paths from routes
|
103
|
+
# api! "short description",
|
104
|
+
#
|
105
|
+
def api!(desc = nil, options = {}) #:doc:
|
106
|
+
return unless Apipie.active_dsl?
|
107
|
+
_apipie_dsl_data[:api] = true
|
108
|
+
_apipie_dsl_data[:api_from_routes] = { :desc => desc, :options =>options }
|
109
|
+
end
|
110
|
+
|
111
|
+
# Reference other similar method
|
112
|
+
#
|
113
|
+
# api :PUT, '/articles/:id'
|
114
|
+
# see "articles#create"
|
115
|
+
# def update; end
|
116
|
+
def see(*args)
|
117
|
+
return unless Apipie.active_dsl?
|
118
|
+
_apipie_dsl_data[:see] << args
|
119
|
+
end
|
120
|
+
|
121
|
+
# Show some example of what does the described
|
122
|
+
# method return.
|
123
|
+
def example(example) #:doc:
|
124
|
+
return unless Apipie.active_dsl?
|
125
|
+
_apipie_dsl_data[:examples] << example.strip_heredoc
|
126
|
+
end
|
127
|
+
|
128
|
+
# Determine if the method should be included
|
129
|
+
# in the documentation
|
130
|
+
def show(show)
|
131
|
+
return unless Apipie.active_dsl?
|
132
|
+
_apipie_dsl_data[:show] = show
|
133
|
+
end
|
134
|
+
|
135
|
+
# Describe whole resource
|
136
|
+
#
|
137
|
+
# Example:
|
138
|
+
# api :desc => "Show user profile", :path => "/users/", :version => '1.0 - 3.4.2012'
|
139
|
+
# param :id, Integer, :desc => "User ID", :required => true
|
140
|
+
# desc <<-EOS
|
141
|
+
# Long description...
|
142
|
+
# EOS
|
143
|
+
def resource_description(options = {}, &block) #:doc:
|
144
|
+
return unless Apipie.active_dsl?
|
145
|
+
raise ArgumentError, "Block expected" unless block
|
146
|
+
|
147
|
+
dsl_data = ResourceDescriptionDsl.eval_dsl(self, &block)
|
148
|
+
versions = dsl_data[:api_versions]
|
149
|
+
Apipie.set_controller_versions(self, versions)
|
150
|
+
@apipie_resource_descriptions = versions.map do |version|
|
151
|
+
Apipie.define_resource_description(self, version, dsl_data)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
module Common
|
157
|
+
def api_versions(*versions)
|
158
|
+
_apipie_dsl_data[:api_versions].concat(versions)
|
159
|
+
end
|
160
|
+
alias api_version api_versions
|
161
|
+
|
162
|
+
# Describe the next method.
|
163
|
+
#
|
164
|
+
# Example:
|
165
|
+
# desc "print hello world"
|
166
|
+
# def hello_world
|
167
|
+
# puts "hello world"
|
168
|
+
# end
|
169
|
+
#
|
170
|
+
def desc(description) #:doc:
|
171
|
+
return unless Apipie.active_dsl?
|
172
|
+
if _apipie_dsl_data[:description]
|
173
|
+
raise "Double method description."
|
174
|
+
end
|
175
|
+
_apipie_dsl_data[:description] = description
|
176
|
+
end
|
177
|
+
alias description desc
|
178
|
+
alias full_description desc
|
179
|
+
|
180
|
+
# describe next method with document in given path
|
181
|
+
# in convention, these doc located under "#{Rails.root}/doc"
|
182
|
+
# Example:
|
183
|
+
# document "hello_world.md"
|
184
|
+
# def hello_world
|
185
|
+
# puts "hello world"
|
186
|
+
# end
|
187
|
+
def document path
|
188
|
+
content = File.open(File.join(Rails.root, Apipie.configuration.doc_path, path)).read
|
189
|
+
desc content
|
190
|
+
end
|
191
|
+
|
192
|
+
# Describe available request/response formats
|
193
|
+
#
|
194
|
+
# formats ['json', 'jsonp', 'xml']
|
195
|
+
def formats(formats) #:doc:
|
196
|
+
return unless Apipie.active_dsl?
|
197
|
+
_apipie_dsl_data[:formats] = formats
|
198
|
+
end
|
199
|
+
|
200
|
+
# Describe additional metadata
|
201
|
+
#
|
202
|
+
# meta :author => { :name => 'John', :surname => 'Doe' }
|
203
|
+
def meta(meta) #:doc:
|
204
|
+
_apipie_dsl_data[:meta] = meta
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
# Describe possible errors
|
209
|
+
#
|
210
|
+
# Example:
|
211
|
+
# error :desc => "speaker is sleeping", :code => 500, :meta => [:some, :more, :data]
|
212
|
+
# error 500, "speaker is sleeping"
|
213
|
+
# def hello_world
|
214
|
+
# return 500 if self.speaker.sleeping?
|
215
|
+
# puts "hello world"
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
def error(code_or_options, desc = nil, options = {}) #:doc:
|
219
|
+
return unless Apipie.active_dsl?
|
220
|
+
_apipie_dsl_data[:errors] << [code_or_options, desc, options]
|
221
|
+
end
|
222
|
+
|
223
|
+
# Add tags to resources and actions group operations together.
|
224
|
+
def tags(*args)
|
225
|
+
return unless Apipie.active_dsl?
|
226
|
+
tags = args.length == 1 ? args.first : args
|
227
|
+
_apipie_dsl_data[:tag_list] += tags
|
228
|
+
end
|
229
|
+
|
230
|
+
def _apipie_define_validators(description)
|
231
|
+
|
232
|
+
# [re]define method only if validation is turned on
|
233
|
+
return unless description && [true, :implicitly, :explicitly].include?(Apipie.configuration.validate)
|
234
|
+
|
235
|
+
_apipie_save_method_params(description.method, description.params)
|
236
|
+
|
237
|
+
unless instance_methods.include?(:apipie_validations)
|
238
|
+
define_method(:apipie_validations) do
|
239
|
+
method_params = self.class._apipie_get_method_params(action_name)
|
240
|
+
|
241
|
+
if Apipie.configuration.validate_presence?
|
242
|
+
Validator::BaseValidator.raise_if_missing_params do |missing|
|
243
|
+
method_params.each_value do |param|
|
244
|
+
# check if required parameters are present
|
245
|
+
missing << param if param.required && !params.key?(param.name)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
if Apipie.configuration.validate_value?
|
251
|
+
method_params.each_value do |param|
|
252
|
+
# params validations
|
253
|
+
param.validate(params[:"#{param.name}"]) if params.key?(param.name)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Only allow params passed in that are defined keys in the api
|
258
|
+
# Auto skip the default params (format, controller, action)
|
259
|
+
if Apipie.configuration.validate_key?
|
260
|
+
params.reject{|k,_| %w[format controller action].include?(k.to_s) }.each_pair do |param, _|
|
261
|
+
# params allowed
|
262
|
+
if method_params.none? {|_,p| p.name.to_s == param.to_s}
|
263
|
+
self.class._apipie_handle_validate_key_error params, param
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
return unless Apipie.configuration.process_value?
|
269
|
+
@api_params ||= {}
|
270
|
+
method_params.each_value do |param|
|
271
|
+
# params processing
|
272
|
+
@api_params[param.as] = param.process_value(params[:"#{param.name}"]) if params.key?(param.name)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
return unless [:implicitly, true].include?(Apipie.configuration.validate)
|
278
|
+
old_method = instance_method(description.method)
|
279
|
+
|
280
|
+
define_method(description.method) do |*args|
|
281
|
+
apipie_validations
|
282
|
+
|
283
|
+
# run the original method code
|
284
|
+
old_method.bind(self).call(*args)
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
def _apipie_handle_validate_key_error params, param
|
291
|
+
case Apipie.configuration.action_on_non_validated_keys
|
292
|
+
when :raise
|
293
|
+
raise UnknownParam, param
|
294
|
+
when :skip
|
295
|
+
params.delete(param)
|
296
|
+
Rails.logger.warn(UnknownParam.new(param).to_s)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def _apipie_save_method_params(method, params)
|
301
|
+
@method_params ||= {}
|
302
|
+
@method_params[method] = params
|
303
|
+
end
|
304
|
+
|
305
|
+
def _apipie_get_method_params(method)
|
306
|
+
@method_params[method]
|
307
|
+
end
|
308
|
+
|
309
|
+
# Describe request header.
|
310
|
+
# Headers can't be validated with config.validate_presence = true
|
311
|
+
#
|
312
|
+
# Example:
|
313
|
+
# header 'ClientId', "client-id"
|
314
|
+
# def show
|
315
|
+
# render :text => headers['HTTP_CLIENT_ID']
|
316
|
+
# end
|
317
|
+
#
|
318
|
+
def header(header_name, description, options = {}) #:doc
|
319
|
+
return unless Apipie.active_dsl?
|
320
|
+
_apipie_dsl_data[:headers] << {
|
321
|
+
name: header_name,
|
322
|
+
description: description,
|
323
|
+
options: options
|
324
|
+
}
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
|
329
|
+
# this describes the params, it's in separate module because it's
|
330
|
+
# used in Validators as well
|
331
|
+
module Param
|
332
|
+
# Describe method's parameter
|
333
|
+
#
|
334
|
+
# Example:
|
335
|
+
# param :greeting, String, :desc => "arbitrary text", :required => true
|
336
|
+
# def hello_world(greeting)
|
337
|
+
# puts greeting
|
338
|
+
# end
|
339
|
+
#
|
340
|
+
def param(param_name, validator, desc_or_options = nil, options = {}, &block) #:doc:
|
341
|
+
return unless Apipie.active_dsl?
|
342
|
+
_apipie_dsl_data[:params] << [param_name,
|
343
|
+
validator,
|
344
|
+
desc_or_options,
|
345
|
+
options.merge(:param_group => @_current_param_group),
|
346
|
+
block]
|
347
|
+
end
|
348
|
+
|
349
|
+
def property(param_name, validator, desc_or_options = nil, options = {}, &block) #:doc:
|
350
|
+
return unless Apipie.active_dsl?
|
351
|
+
options[:only_in] ||= :response
|
352
|
+
options[:required] = true if options[:required].nil?
|
353
|
+
param(param_name, validator, desc_or_options, options, &block)
|
354
|
+
end
|
355
|
+
|
356
|
+
# Reuses param group for this method. The definition is looked up
|
357
|
+
# in scope of this controller. If the group was defined in
|
358
|
+
# different controller, the second param can be used to specify it.
|
359
|
+
# when using action_aware params, you can specify :as =>
|
360
|
+
# :create or :update to explicitly say how it should behave
|
361
|
+
def param_group(name, scope_or_options = nil, options = {})
|
362
|
+
if scope_or_options.is_a? Hash
|
363
|
+
options.merge!(scope_or_options)
|
364
|
+
scope = options[:scope]
|
365
|
+
else
|
366
|
+
scope = scope_or_options
|
367
|
+
end
|
368
|
+
scope ||= _default_param_group_scope
|
369
|
+
|
370
|
+
@_current_param_group = {
|
371
|
+
:scope => scope,
|
372
|
+
:name => name,
|
373
|
+
:options => options,
|
374
|
+
:from_concern => scope.apipie_concern?
|
375
|
+
}
|
376
|
+
self.instance_exec(&Apipie.get_param_group(scope, name))
|
377
|
+
ensure
|
378
|
+
@_current_param_group = nil
|
379
|
+
end
|
380
|
+
|
381
|
+
# Describe possible responses
|
382
|
+
#
|
383
|
+
# Example:
|
384
|
+
# def_param_group :user do
|
385
|
+
# param :user, Hash do
|
386
|
+
# param :name, String
|
387
|
+
# end
|
388
|
+
# end
|
389
|
+
#
|
390
|
+
# returns :user, "the speaker"
|
391
|
+
# returns "the speaker" do
|
392
|
+
# param_group: :user
|
393
|
+
# end
|
394
|
+
# returns :param_group => :user, "the speaker"
|
395
|
+
# returns :user, :code => 201, :desc => "the created speaker record"
|
396
|
+
# returns :array_of => :user, "many speakers"
|
397
|
+
# def hello_world
|
398
|
+
# render json: {user: {name: "Alfred"}}
|
399
|
+
# end
|
400
|
+
#
|
401
|
+
def returns(pgroup_or_options, desc_or_options = nil, options = {}, &block) #:doc:
|
402
|
+
return unless Apipie.active_dsl?
|
403
|
+
|
404
|
+
|
405
|
+
if desc_or_options.is_a? Hash
|
406
|
+
options.merge!(desc_or_options)
|
407
|
+
elsif !desc_or_options.nil?
|
408
|
+
options[:desc] = desc_or_options
|
409
|
+
end
|
410
|
+
|
411
|
+
if pgroup_or_options.is_a? Hash
|
412
|
+
options.merge!(pgroup_or_options)
|
413
|
+
else
|
414
|
+
options[:param_group] = pgroup_or_options
|
415
|
+
end
|
416
|
+
|
417
|
+
code = options[:code] || 200
|
418
|
+
scope = options[:scope] || _default_param_group_scope
|
419
|
+
descriptor = options[:param_group] || options[:array_of]
|
420
|
+
|
421
|
+
if block.nil?
|
422
|
+
if descriptor.is_a? ResponseDescriptionAdapter
|
423
|
+
adapter = descriptor
|
424
|
+
elsif descriptor.respond_to? :describe_own_properties
|
425
|
+
adapter = ResponseDescriptionAdapter.from_self_describing_class(descriptor)
|
426
|
+
else
|
427
|
+
begin
|
428
|
+
block = Apipie.get_param_group(scope, descriptor) if descriptor
|
429
|
+
rescue
|
430
|
+
raise "No param_group or self-describing class named #{descriptor}"
|
431
|
+
end
|
432
|
+
end
|
433
|
+
elsif descriptor
|
434
|
+
raise "cannot specify both block and param_group"
|
435
|
+
end
|
436
|
+
|
437
|
+
_apipie_dsl_data[:returns][code] = [options, scope, block, adapter]
|
438
|
+
end
|
439
|
+
|
440
|
+
# where the group definition should be looked up when no scope
|
441
|
+
# given. This is expected to return a controller.
|
442
|
+
def _default_param_group_scope
|
443
|
+
self
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
module Controller
|
448
|
+
include Apipie::DSL::Base
|
449
|
+
include Apipie::DSL::Common
|
450
|
+
include Apipie::DSL::Action
|
451
|
+
include Apipie::DSL::Param
|
452
|
+
|
453
|
+
# defines the substitutions to be made in the API paths defined
|
454
|
+
# in concerns included. For example:
|
455
|
+
#
|
456
|
+
# There is this method defined in concern:
|
457
|
+
#
|
458
|
+
# api GET ':controller_path/:id'
|
459
|
+
# def show
|
460
|
+
# # ...
|
461
|
+
# end
|
462
|
+
#
|
463
|
+
# If you include the concern into some controller, you can
|
464
|
+
# specify the value for :controller_path like this:
|
465
|
+
#
|
466
|
+
# apipie_concern_subst(:controller_path => '/users')
|
467
|
+
# include ::Concerns::SampleController
|
468
|
+
#
|
469
|
+
# The resulting path will be '/users/:id'.
|
470
|
+
#
|
471
|
+
# It has to be specified before the concern is included.
|
472
|
+
#
|
473
|
+
# If not specified, the default predefined substitutions are
|
474
|
+
#
|
475
|
+
# {:conroller_path => controller.controller_path,
|
476
|
+
# :resource_id => `resource_id_from_apipie` }
|
477
|
+
def apipie_concern_subst(subst_hash)
|
478
|
+
_apipie_concern_subst.merge!(subst_hash)
|
479
|
+
end
|
480
|
+
|
481
|
+
# Allows to update existing params after definition was made (usually needed
|
482
|
+
# when extending the API form plugins).
|
483
|
+
#
|
484
|
+
# UsersController.apipie_update_params([:create, :update]) do
|
485
|
+
# param :user, Hash do
|
486
|
+
# param :oauth, String
|
487
|
+
# end
|
488
|
+
# end
|
489
|
+
#
|
490
|
+
# The block is evaluated in scope of the controller. Ohe can pass some additional
|
491
|
+
# objects via additional arguments like this:
|
492
|
+
#
|
493
|
+
# UsersController.apipie_update_params([:create, :update], [:name, :secret]) do |param_names|
|
494
|
+
# param :user, Hash do
|
495
|
+
# param_names.each { |p| param p, String }
|
496
|
+
# end
|
497
|
+
# end
|
498
|
+
def _apipie_update_params(method_desc, dsl_data)
|
499
|
+
params_ordered = dsl_data[:params].map do |args|
|
500
|
+
Apipie::ParamDescription.from_dsl_data(method_desc, args)
|
501
|
+
end
|
502
|
+
ParamDescription.merge(method_desc.params_ordered_self, params_ordered)
|
503
|
+
end
|
504
|
+
|
505
|
+
def _apipie_update_meta(method_desc, dsl_data)
|
506
|
+
return unless dsl_data[:meta].is_a?(Hash)
|
507
|
+
|
508
|
+
method_desc.metadata ||= {}
|
509
|
+
method_desc.metadata.merge!(dsl_data[:meta])
|
510
|
+
end
|
511
|
+
|
512
|
+
def apipie_update_methods(methods, *args, &block)
|
513
|
+
methods.each do |method|
|
514
|
+
method_desc = Apipie.get_method_description(self, method)
|
515
|
+
unless method_desc
|
516
|
+
raise "Could not find method description for #{self}##{method}. Was the method defined?"
|
517
|
+
end
|
518
|
+
dsl_data = _apipie_eval_dsl(*args, &block)
|
519
|
+
_apipie_update_params(method_desc, dsl_data)
|
520
|
+
_apipie_update_meta(method_desc, dsl_data)
|
521
|
+
end
|
522
|
+
end
|
523
|
+
# backwards compatibility
|
524
|
+
alias apipie_update_params apipie_update_methods
|
525
|
+
|
526
|
+
def _apipie_concern_subst
|
527
|
+
@_apipie_concern_subst ||= {
|
528
|
+
controller_path: self.controller_path,
|
529
|
+
resource_id: Apipie.get_resource_id(self)
|
530
|
+
}
|
531
|
+
end
|
532
|
+
|
533
|
+
def _apipie_perform_concern_subst(string)
|
534
|
+
_apipie_concern_subst.reduce(string) do |ret, (key, val)|
|
535
|
+
ret.gsub(":#{key}", val)
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
def apipie_concern?
|
540
|
+
false
|
541
|
+
end
|
542
|
+
|
543
|
+
# create method api and redefine newly added method
|
544
|
+
def method_added(method_name) #:doc:
|
545
|
+
super
|
546
|
+
return if !Apipie.active_dsl? || !_apipie_dsl_data[:api]
|
547
|
+
|
548
|
+
return if _apipie_dsl_data[:api_args].blank? && _apipie_dsl_data[:api_from_routes].blank?
|
549
|
+
|
550
|
+
# remove method description if exists and create new one
|
551
|
+
Apipie.remove_method_description(self, _apipie_dsl_data[:api_versions], method_name)
|
552
|
+
description = Apipie.define_method_description(self, method_name, _apipie_dsl_data)
|
553
|
+
|
554
|
+
_apipie_dsl_data_clear
|
555
|
+
_apipie_define_validators(description)
|
556
|
+
ensure
|
557
|
+
_apipie_dsl_data_clear
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
module Concern
|
562
|
+
include Apipie::DSL::Base
|
563
|
+
include Apipie::DSL::Common
|
564
|
+
include Apipie::DSL::Action
|
565
|
+
include Apipie::DSL::Param
|
566
|
+
|
567
|
+
# the concern was included into a controller
|
568
|
+
def included(controller)
|
569
|
+
super
|
570
|
+
_apipie_concern_data.each do |method_name, _apipie_dsl_data|
|
571
|
+
# remove method description if exists and create new one
|
572
|
+
description = Apipie.define_method_description(controller, method_name, _apipie_dsl_data)
|
573
|
+
controller._apipie_define_validators(description)
|
574
|
+
end
|
575
|
+
_apipie_concern_update_api_blocks.each do |(methods, block)|
|
576
|
+
controller.apipie_update_methods(methods, &block)
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
def _apipie_concern_data
|
581
|
+
@_apipie_concern_data ||= []
|
582
|
+
end
|
583
|
+
|
584
|
+
def _apipie_concern_update_api_blocks
|
585
|
+
@_apipie_concern_update_api_blocks ||= []
|
586
|
+
end
|
587
|
+
|
588
|
+
def apipie_concern?
|
589
|
+
true
|
590
|
+
end
|
591
|
+
|
592
|
+
# create method api and redefine newly added method
|
593
|
+
def method_added(method_name) #:doc:
|
594
|
+
super
|
595
|
+
|
596
|
+
return if ! Apipie.active_dsl? || !_apipie_dsl_data[:api]
|
597
|
+
|
598
|
+
_apipie_concern_data << [method_name, _apipie_dsl_data.merge(:from_concern => true)]
|
599
|
+
ensure
|
600
|
+
_apipie_dsl_data_clear
|
601
|
+
end
|
602
|
+
|
603
|
+
def update_api(*methods, &block)
|
604
|
+
_apipie_concern_update_api_blocks << [methods, block]
|
605
|
+
end
|
606
|
+
|
607
|
+
end
|
608
|
+
|
609
|
+
class ResourceDescriptionDsl
|
610
|
+
include Apipie::DSL::Base
|
611
|
+
include Apipie::DSL::Common
|
612
|
+
include Apipie::DSL::Resource
|
613
|
+
include Apipie::DSL::Param
|
614
|
+
|
615
|
+
def initialize(controller)
|
616
|
+
@controller = controller
|
617
|
+
end
|
618
|
+
|
619
|
+
# evaluates resource description DSL and returns results
|
620
|
+
def self.eval_dsl(controller, &block)
|
621
|
+
dsl_data = self.new(controller)._apipie_eval_dsl(&block)
|
622
|
+
if dsl_data[:api_versions].empty?
|
623
|
+
dsl_data[:api_versions] = Apipie.controller_versions(controller)
|
624
|
+
end
|
625
|
+
dsl_data
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
end # module DSL
|
630
|
+
end # module Apipie
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Apipie
|
2
|
+
|
3
|
+
class ErrorDescription
|
4
|
+
attr_reader :code, :description, :metadata
|
5
|
+
|
6
|
+
def self.from_dsl_data(args)
|
7
|
+
code_or_options, desc, options = args
|
8
|
+
Apipie::ErrorDescription.new(code_or_options, desc, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(code_or_options, desc = nil, options = {})
|
12
|
+
if code_or_options.is_a? Hash
|
13
|
+
code_or_options.symbolize_keys!
|
14
|
+
@code = code_or_options[:code]
|
15
|
+
@metadata = code_or_options[:meta]
|
16
|
+
@description = code_or_options[:desc] || code_or_options[:description]
|
17
|
+
else
|
18
|
+
@code =
|
19
|
+
if code_or_options.is_a? Symbol
|
20
|
+
begin
|
21
|
+
Rack::Utils.status_code(code_or_options)
|
22
|
+
rescue ArgumentError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
else
|
26
|
+
code_or_options
|
27
|
+
end
|
28
|
+
|
29
|
+
raise UnknownCode, code_or_options unless @code
|
30
|
+
|
31
|
+
@metadata = options[:meta]
|
32
|
+
@description = desc
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_json(lang)
|
37
|
+
{
|
38
|
+
:code => code,
|
39
|
+
:description => Apipie.app.translate(description, lang),
|
40
|
+
:metadata => metadata
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|