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.
Files changed (258) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/build.yml +32 -0
  3. data/.github/workflows/rubocop-challenger.yml +26 -0
  4. data/.github/workflows/rubocop.yml +18 -0
  5. data/.gitignore +16 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +132 -0
  8. data/.rubocop_todo.yml +1967 -0
  9. data/.vscode/settings.json +3 -0
  10. data/APACHE-LICENSE-2.0 +202 -0
  11. data/CHANGELOG.md +693 -0
  12. data/Gemfile +19 -0
  13. data/MIT-LICENSE +20 -0
  14. data/NOTICE +4 -0
  15. data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
  16. data/README.md +2088 -0
  17. data/Rakefile +8 -0
  18. data/apipie-rails.gemspec +44 -0
  19. data/app/controllers/apipie/apipies_controller.rb +184 -0
  20. data/app/helpers/apipie_helper.rb +10 -0
  21. data/app/public/apipie/javascripts/apipie.js +6 -0
  22. data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +167 -0
  23. data/app/public/apipie/javascripts/bundled/bootstrap.js +2280 -0
  24. data/app/public/apipie/javascripts/bundled/jquery.js +2 -0
  25. data/app/public/apipie/javascripts/bundled/prettify.js +28 -0
  26. data/app/public/apipie/stylesheets/application.css +7 -0
  27. data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +9 -0
  28. data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +9 -0
  29. data/app/public/apipie/stylesheets/bundled/prettify.css +30 -0
  30. data/app/views/apipie/apipies/_deprecation.html.erb +16 -0
  31. data/app/views/apipie/apipies/_disqus.html.erb +13 -0
  32. data/app/views/apipie/apipies/_errors.html.erb +23 -0
  33. data/app/views/apipie/apipies/_headers.html.erb +26 -0
  34. data/app/views/apipie/apipies/_languages.erb +6 -0
  35. data/app/views/apipie/apipies/_metadata.erb +1 -0
  36. data/app/views/apipie/apipies/_method_detail.erb +63 -0
  37. data/app/views/apipie/apipies/_params.html.erb +49 -0
  38. data/app/views/apipie/apipies/_params_plain.html.erb +21 -0
  39. data/app/views/apipie/apipies/apipie_404.html.erb +17 -0
  40. data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
  41. data/app/views/apipie/apipies/getting_started.html.erb +6 -0
  42. data/app/views/apipie/apipies/index.html.erb +56 -0
  43. data/app/views/apipie/apipies/method.html.erb +41 -0
  44. data/app/views/apipie/apipies/plain.html.erb +77 -0
  45. data/app/views/apipie/apipies/resource.html.erb +80 -0
  46. data/app/views/apipie/apipies/static.html.erb +103 -0
  47. data/app/views/layouts/apipie/apipie.html.erb +27 -0
  48. data/config/locales/de.yml +28 -0
  49. data/config/locales/en.yml +41 -0
  50. data/config/locales/es.yml +28 -0
  51. data/config/locales/fr.yml +31 -0
  52. data/config/locales/it.yml +41 -0
  53. data/config/locales/ja.yml +31 -0
  54. data/config/locales/ko.yml +32 -0
  55. data/config/locales/pl.yml +28 -0
  56. data/config/locales/pt-BR.yml +28 -0
  57. data/config/locales/ru.yml +28 -0
  58. data/config/locales/tr.yml +28 -0
  59. data/config/locales/zh-CN.yml +28 -0
  60. data/config/locales/zh-TW.yml +28 -0
  61. data/gemfiles/Gemfile.tools +9 -0
  62. data/images/screenshot-1.png +0 -0
  63. data/images/screenshot-2.png +0 -0
  64. data/lib/apipie/apipie_module.rb +83 -0
  65. data/lib/apipie/application.rb +499 -0
  66. data/lib/apipie/configuration.rb +196 -0
  67. data/lib/apipie/core_ext/route.rb +9 -0
  68. data/lib/apipie/dsl_definition.rb +630 -0
  69. data/lib/apipie/error_description.rb +46 -0
  70. data/lib/apipie/errors.rb +86 -0
  71. data/lib/apipie/extractor/collector.rb +116 -0
  72. data/lib/apipie/extractor/recorder.rb +193 -0
  73. data/lib/apipie/extractor/writer.rb +454 -0
  74. data/lib/apipie/extractor.rb +181 -0
  75. data/lib/apipie/generator/config.rb +12 -0
  76. data/lib/apipie/generator/generator.rb +2 -0
  77. data/lib/apipie/generator/swagger/computed_interface_id.rb +23 -0
  78. data/lib/apipie/generator/swagger/config.rb +80 -0
  79. data/lib/apipie/generator/swagger/context.rb +38 -0
  80. data/lib/apipie/generator/swagger/method_description/api_decorator.rb +20 -0
  81. data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +89 -0
  82. data/lib/apipie/generator/swagger/method_description/decorator.rb +22 -0
  83. data/lib/apipie/generator/swagger/method_description/parameters_service.rb +139 -0
  84. data/lib/apipie/generator/swagger/method_description/response_schema_service.rb +46 -0
  85. data/lib/apipie/generator/swagger/method_description/response_service.rb +71 -0
  86. data/lib/apipie/generator/swagger/method_description.rb +2 -0
  87. data/lib/apipie/generator/swagger/operation_id.rb +51 -0
  88. data/lib/apipie/generator/swagger/param_description/builder.rb +114 -0
  89. data/lib/apipie/generator/swagger/param_description/composite.rb +119 -0
  90. data/lib/apipie/generator/swagger/param_description/description.rb +15 -0
  91. data/lib/apipie/generator/swagger/param_description/in.rb +37 -0
  92. data/lib/apipie/generator/swagger/param_description/name.rb +18 -0
  93. data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +61 -0
  94. data/lib/apipie/generator/swagger/param_description/referenced_composite.rb +36 -0
  95. data/lib/apipie/generator/swagger/param_description/type.rb +132 -0
  96. data/lib/apipie/generator/swagger/param_description.rb +18 -0
  97. data/lib/apipie/generator/swagger/path_decorator.rb +36 -0
  98. data/lib/apipie/generator/swagger/referenced_definitions.rb +17 -0
  99. data/lib/apipie/generator/swagger/resource_description_collection.rb +30 -0
  100. data/lib/apipie/generator/swagger/resource_description_composite.rb +56 -0
  101. data/lib/apipie/generator/swagger/schema.rb +63 -0
  102. data/lib/apipie/generator/swagger/swagger.rb +2 -0
  103. data/lib/apipie/generator/swagger/type.rb +16 -0
  104. data/lib/apipie/generator/swagger/type_extractor.rb +51 -0
  105. data/lib/apipie/generator/swagger/warning.rb +74 -0
  106. data/lib/apipie/generator/swagger/warning_writer.rb +54 -0
  107. data/lib/apipie/helpers.rb +73 -0
  108. data/lib/apipie/markup.rb +52 -0
  109. data/lib/apipie/method_description/api.rb +12 -0
  110. data/lib/apipie/method_description/apis_service.rb +82 -0
  111. data/lib/apipie/method_description.rb +230 -0
  112. data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
  113. data/lib/apipie/param_description/deprecation.rb +24 -0
  114. data/lib/apipie/param_description.rb +313 -0
  115. data/lib/apipie/railtie.rb +9 -0
  116. data/lib/apipie/resource_description.rb +152 -0
  117. data/lib/apipie/response_description.rb +157 -0
  118. data/lib/apipie/response_description_adapter.rb +202 -0
  119. data/lib/apipie/routes_formatter.rb +33 -0
  120. data/lib/apipie/routing.rb +16 -0
  121. data/lib/apipie/rspec/response_validation_helper.rb +194 -0
  122. data/lib/apipie/see_description.rb +39 -0
  123. data/lib/apipie/static_dispatcher.rb +75 -0
  124. data/lib/apipie/swagger_generator.rb +45 -0
  125. data/lib/apipie/tag_list_description.rb +11 -0
  126. data/lib/apipie/validator.rb +552 -0
  127. data/lib/apipie/version.rb +3 -0
  128. data/lib/apipie-rails.rb +60 -0
  129. data/lib/generators/apipie/install/README +6 -0
  130. data/lib/generators/apipie/install/install_generator.rb +25 -0
  131. data/lib/generators/apipie/install/templates/initializer.rb.erb +7 -0
  132. data/lib/generators/apipie/views_generator.rb +11 -0
  133. data/lib/tasks/apipie.rake +355 -0
  134. data/rel-eng/gem_release.ipynb +398 -0
  135. data/rel-eng/packages/.readme +3 -0
  136. data/rel-eng/packages/rubygem-apipie-rails +1 -0
  137. data/rel-eng/tito.props +5 -0
  138. data/spec/controllers/api/v1/architectures_controller_spec.rb +29 -0
  139. data/spec/controllers/api/v2/architectures_controller_spec.rb +19 -0
  140. data/spec/controllers/api/v2/empty_middle_controller_spec.rb +23 -0
  141. data/spec/controllers/api/v2/nested/resources_controller_spec.rb +27 -0
  142. data/spec/controllers/api/v2/sub/footguns_controller_spec.rb +19 -0
  143. data/spec/controllers/concerns_controller_spec.rb +42 -0
  144. data/spec/controllers/extended_controller_spec.rb +14 -0
  145. data/spec/controllers/included_param_group_controller_spec.rb +13 -0
  146. data/spec/controllers/pets_controller_spec.rb +98 -0
  147. data/spec/controllers/users_controller_spec.rb +794 -0
  148. data/spec/dummy/Rakefile +7 -0
  149. data/spec/dummy/app/controllers/api/base_controller.rb +4 -0
  150. data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +43 -0
  151. data/spec/dummy/app/controllers/api/v1/base_controller.rb +11 -0
  152. data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +31 -0
  153. data/spec/dummy/app/controllers/api/v2/base_controller.rb +17 -0
  154. data/spec/dummy/app/controllers/api/v2/empty_middle_controller.rb +14 -0
  155. data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +32 -0
  156. data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +33 -0
  157. data/spec/dummy/app/controllers/api/v2/sub/footguns_controller.rb +30 -0
  158. data/spec/dummy/app/controllers/application_controller.rb +18 -0
  159. data/spec/dummy/app/controllers/concerns_controller.rb +8 -0
  160. data/spec/dummy/app/controllers/extended_controller.rb +14 -0
  161. data/spec/dummy/app/controllers/extending_concern.rb +10 -0
  162. data/spec/dummy/app/controllers/files_controller.rb +5 -0
  163. data/spec/dummy/app/controllers/included_param_group_controller.rb +19 -0
  164. data/spec/dummy/app/controllers/overridden_concerns_controller.rb +31 -0
  165. data/spec/dummy/app/controllers/pets_controller.rb +408 -0
  166. data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
  167. data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
  168. data/spec/dummy/app/controllers/sample_controller.rb +39 -0
  169. data/spec/dummy/app/controllers/tagged_cats_controller.rb +32 -0
  170. data/spec/dummy/app/controllers/tagged_dogs_controller.rb +15 -0
  171. data/spec/dummy/app/controllers/twitter_example_controller.rb +307 -0
  172. data/spec/dummy/app/controllers/users_controller.rb +310 -0
  173. data/spec/dummy/app/helpers/random_param_group.rb +8 -0
  174. data/spec/dummy/app/views/layouts/application.html.erb +21 -0
  175. data/spec/dummy/components/test_engine/Gemfile +6 -0
  176. data/spec/dummy/components/test_engine/app/controllers/test_engine/application_controller.rb +4 -0
  177. data/spec/dummy/components/test_engine/app/controllers/test_engine/memes_controller.rb +37 -0
  178. data/spec/dummy/components/test_engine/config/routes.rb +3 -0
  179. data/spec/dummy/components/test_engine/db/.gitkeep +0 -0
  180. data/spec/dummy/components/test_engine/lib/test_engine.rb +7 -0
  181. data/spec/dummy/components/test_engine/test_engine.gemspec +11 -0
  182. data/spec/dummy/config/application.rb +47 -0
  183. data/spec/dummy/config/boot.rb +12 -0
  184. data/spec/dummy/config/database.yml +21 -0
  185. data/spec/dummy/config/environment.rb +8 -0
  186. data/spec/dummy/config/environments/development.rb +25 -0
  187. data/spec/dummy/config/environments/production.rb +49 -0
  188. data/spec/dummy/config/environments/test.rb +33 -0
  189. data/spec/dummy/config/initializers/apipie.rb +110 -0
  190. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  191. data/spec/dummy/config/initializers/inflections.rb +10 -0
  192. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  193. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  194. data/spec/dummy/config/initializers/session_store.rb +8 -0
  195. data/spec/dummy/config/locales/en.yml +5 -0
  196. data/spec/dummy/config/routes.rb +61 -0
  197. data/spec/dummy/config.ru +4 -0
  198. data/spec/dummy/db/.gitkeep +0 -0
  199. data/spec/dummy/doc/apipie_examples.json +1 -0
  200. data/spec/dummy/doc/users/desc_from_file.md +1 -0
  201. data/spec/dummy/public/404.html +26 -0
  202. data/spec/dummy/public/422.html +26 -0
  203. data/spec/dummy/public/500.html +26 -0
  204. data/spec/dummy/public/favicon.ico +0 -0
  205. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  206. data/spec/dummy/script/rails +6 -0
  207. data/spec/lib/apipie/apipies_controller_spec.rb +345 -0
  208. data/spec/lib/apipie/application_spec.rb +62 -0
  209. data/spec/lib/apipie/configuration_spec.rb +38 -0
  210. data/spec/lib/apipie/extractor/collector_spec.rb +57 -0
  211. data/spec/lib/apipie/extractor/recorder/middleware_spec.rb +44 -0
  212. data/spec/lib/apipie/extractor/recorder_spec.rb +77 -0
  213. data/spec/lib/apipie/extractor/writer_spec.rb +112 -0
  214. data/spec/lib/apipie/extractor_spec.rb +9 -0
  215. data/spec/lib/apipie/file_handler_spec.rb +25 -0
  216. data/spec/lib/apipie/generator/swagger/config_spec.rb +19 -0
  217. data/spec/lib/apipie/generator/swagger/context_spec.rb +56 -0
  218. data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +119 -0
  219. data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +105 -0
  220. data/spec/lib/apipie/generator/swagger/method_description/response_service_spec.rb +62 -0
  221. data/spec/lib/apipie/generator/swagger/operation_id_spec.rb +63 -0
  222. data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +245 -0
  223. data/spec/lib/apipie/generator/swagger/param_description/composite_spec.rb +95 -0
  224. data/spec/lib/apipie/generator/swagger/param_description/description_spec.rb +79 -0
  225. data/spec/lib/apipie/generator/swagger/param_description/in_spec.rb +86 -0
  226. data/spec/lib/apipie/generator/swagger/param_description/name_spec.rb +81 -0
  227. data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +210 -0
  228. data/spec/lib/apipie/generator/swagger/param_description_spec.rb +28 -0
  229. data/spec/lib/apipie/generator/swagger/path_decorator_spec.rb +57 -0
  230. data/spec/lib/apipie/generator/swagger/referenced_definitions_spec.rb +35 -0
  231. data/spec/lib/apipie/generator/swagger/resource_description_composite_spec.rb +37 -0
  232. data/spec/lib/apipie/generator/swagger/resource_descriptions_collection_spec.rb +57 -0
  233. data/spec/lib/apipie/generator/swagger/schema_spec.rb +89 -0
  234. data/spec/lib/apipie/generator/swagger/type_extractor_spec.rb +38 -0
  235. data/spec/lib/apipie/generator/swagger/warning_spec.rb +51 -0
  236. data/spec/lib/apipie/generator/swagger/warning_writer_spec.rb +71 -0
  237. data/spec/lib/apipie/method_description/apis_service_spec.rb +60 -0
  238. data/spec/lib/apipie/method_description_spec.rb +133 -0
  239. data/spec/lib/apipie/no_documented_method_spec.rb +17 -0
  240. data/spec/lib/apipie/param_description/deprecation_spec.rb +31 -0
  241. data/spec/lib/apipie/param_description_spec.rb +671 -0
  242. data/spec/lib/apipie/param_group_spec.rb +61 -0
  243. data/spec/lib/apipie/resource_description_spec.rb +91 -0
  244. data/spec/lib/apipie/response_description/response_object_spec.rb +22 -0
  245. data/spec/lib/apipie/response_description_spec.rb +56 -0
  246. data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
  247. data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
  248. data/spec/lib/apipie/validator_spec.rb +149 -0
  249. data/spec/lib/rake_spec.rb +69 -0
  250. data/spec/lib/swagger/openapi_2_0_schema.json +1614 -0
  251. data/spec/lib/swagger/rake_swagger_spec.rb +159 -0
  252. data/spec/lib/swagger/swagger_dsl_spec.rb +664 -0
  253. data/spec/lib/validators/array_validator_spec.rb +85 -0
  254. data/spec/spec_helper.rb +92 -0
  255. data/spec/support/custom_bool_validator.rb +17 -0
  256. data/spec/support/rake.rb +21 -0
  257. data/spec/test_engine/memes_controller_spec.rb +10 -0
  258. 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