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,313 @@
1
+ module Apipie
2
+
3
+ # method parameter description
4
+ #
5
+ # name - method name (show)
6
+ # desc - description
7
+ # required - boolean if required
8
+ # validator - Validator::BaseValidator subclass
9
+ class ParamDescription
10
+
11
+ attr_reader :method_description, :name, :desc, :allow_nil, :allow_blank, :validator, :options, :metadata, :show, :as, :validations, :response_only, :request_only
12
+ attr_reader :additional_properties, :is_array
13
+ attr_accessor :parent, :required
14
+
15
+ alias response_only? response_only
16
+ alias request_only? request_only
17
+ alias is_array? is_array
18
+
19
+ def self.from_dsl_data(method_description, args)
20
+ param_name, validator, desc_or_options, options, block = args
21
+ Apipie::ParamDescription.new(method_description,
22
+ param_name,
23
+ validator,
24
+ desc_or_options,
25
+ options,
26
+ &block)
27
+ end
28
+
29
+ def to_s
30
+ "ParamDescription: #{method_description.id}##{name}"
31
+ end
32
+
33
+ def ==(other)
34
+ return false unless self.class == other.class
35
+ if method_description == other.method_description && @options == other.options
36
+ true
37
+ else
38
+ false
39
+ end
40
+ end
41
+
42
+ def initialize(method_description, name, validator, desc_or_options = nil, options = {}, &block)
43
+
44
+ if desc_or_options.is_a?(Hash)
45
+ options = options.merge(desc_or_options)
46
+ elsif desc_or_options.is_a?(String)
47
+ options[:desc] = desc_or_options
48
+ elsif !desc_or_options.nil?
49
+ raise ArgumentError.new("param description: expected description or options as 3rd parameter")
50
+ end
51
+
52
+ options.symbolize_keys!
53
+
54
+ # we save options to know what was passed in DSL
55
+ @options = options
56
+ if @options[:param_group]
57
+ @from_concern = @options[:param_group][:from_concern]
58
+ end
59
+
60
+ if validator.is_a?(Hash)
61
+ @options.merge!(validator.select{|k,v| k != :array_of })
62
+ end
63
+
64
+ @method_description = method_description
65
+ @name = concern_subst(name)
66
+ @as = options[:as] || @name
67
+ @desc = preformat_text(@options[:desc])
68
+
69
+ @parent = @options[:parent]
70
+ @metadata = @options[:meta]
71
+
72
+ @required = is_required?
73
+
74
+ @response_only = (@options[:only_in] == :response)
75
+ @request_only = (@options[:only_in] == :request)
76
+ raise ArgumentError.new("'#{@options[:only_in]}' is not a valid value for :only_in") if (!@response_only && !@request_only) && @options[:only_in].present?
77
+
78
+ @show = if @options.key? :show
79
+ @options[:show]
80
+ else
81
+ true
82
+ end
83
+
84
+ @allow_nil = @options[:allow_nil] || false
85
+ @allow_blank = @options[:allow_blank] || false
86
+
87
+ action_awareness
88
+
89
+ if validator
90
+ if (validator != Hash) && (validator.is_a? Hash) && validator[:array_of]
91
+ @is_array = true
92
+ validator = validator[:array_of]
93
+ raise "an ':array_of =>' validator is allowed exclusively on response-only fields" unless @response_only
94
+ end
95
+ @validator = Validator::BaseValidator.find(self, validator, @options, block)
96
+ raise "Validator for #{validator} not found." unless @validator
97
+ end
98
+
99
+ @validations = Array(options[:validations]).map {|v| concern_subst(Apipie.markup_to_html(v)) }
100
+
101
+ @additional_properties = @options[:additional_properties]
102
+ @deprecated = @options[:deprecated] || false
103
+ end
104
+
105
+ def from_concern?
106
+ method_description.from_concern? || @from_concern
107
+ end
108
+
109
+ def normalized_value(value)
110
+ if value.is_a?(ActionController::Parameters) && !value.is_a?(Hash)
111
+ value.to_unsafe_hash
112
+ elsif value.is_a? Array
113
+ value.map { |v| normalized_value (v) }
114
+ else
115
+ value
116
+ end
117
+ end
118
+
119
+ def validate(value)
120
+ return true if allow_nil && value.nil?
121
+ return true if allow_blank && value.blank?
122
+ value = normalized_value(value)
123
+ if (!allow_nil && value.nil?) || (blank_forbidden? && value.blank?) || !validator.valid?(value)
124
+ error = validator.error
125
+ error = ParamError.new(error) unless error.is_a? StandardError
126
+ raise error
127
+ end
128
+ end
129
+
130
+ def blank_forbidden?
131
+ !Apipie.configuration.ignore_allow_blank_false && !allow_blank && !validator.ignore_allow_blank?
132
+ end
133
+
134
+ def process_value(value)
135
+ value = normalized_value(value)
136
+ if @validator.respond_to?(:process_value)
137
+ @validator.process_value(value)
138
+ else
139
+ value
140
+ end
141
+ end
142
+
143
+ def full_name
144
+ name_parts = parents_and_self.map{|p| p.name if p.show}.compact
145
+ return name.to_s if name_parts.blank?
146
+ return ([name_parts.first] + name_parts[1..-1].map { |n| "[#{n}]" }).join("")
147
+ end
148
+
149
+ # returns an array of all the parents: starting with the root parent
150
+ # ending with itself
151
+ def parents_and_self
152
+ ret = []
153
+ if self.parent
154
+ ret.concat(self.parent.parents_and_self)
155
+ end
156
+ ret << self
157
+ ret
158
+ end
159
+
160
+ def to_json(lang = nil)
161
+ hash = {
162
+ name: name.to_s,
163
+ full_name: full_name,
164
+ description: preformat_text(Apipie.app.translate(@options[:desc], lang)),
165
+ required: required,
166
+ allow_nil: allow_nil,
167
+ allow_blank: allow_blank,
168
+ validator: validator.to_s,
169
+ expected_type: validator.expected_type,
170
+ metadata: metadata,
171
+ show: show,
172
+ validations: validations,
173
+ deprecated: deprecated?
174
+ }
175
+
176
+ if deprecation.present?
177
+ hash[:deprecation] = deprecation.to_json
178
+ end
179
+
180
+ if sub_params = validator.params_ordered
181
+ hash[:params] = sub_params.map { |p| p.to_json(lang)}
182
+ end
183
+ hash
184
+ end
185
+
186
+ def merge_with(other_param_desc)
187
+ if self.validator && other_param_desc.validator
188
+ self.validator.merge_with(other_param_desc.validator)
189
+ else
190
+ self.validator ||= other_param_desc.validator
191
+ end
192
+ self
193
+ end
194
+
195
+ # merge param descriptions. Allows defining hash params on more places
196
+ # (e.g. in param_groups). For example:
197
+ #
198
+ # def_param_group :user do
199
+ # param :user, Hash do
200
+ # param :name, String
201
+ # end
202
+ # end
203
+ #
204
+ # param_group :user
205
+ # param :user, Hash do
206
+ # param :password, String
207
+ # end
208
+ def self.unify(params)
209
+ ordering = params.map(&:name)
210
+ params.group_by(&:name).map do |name, param_descs|
211
+ param_descs.reduce(&:merge_with)
212
+ end.sort_by { |param| ordering.index(param.name) }
213
+ end
214
+
215
+ def self.merge(target_params, source_params)
216
+ params_to_merge, params_to_add = source_params.partition do |source_param|
217
+ target_params.any? { |target_param| source_param.name == target_param.name }
218
+ end
219
+ unify(target_params + params_to_merge)
220
+ target_params.concat(params_to_add)
221
+ end
222
+
223
+ # action awareness is being inherited from ancestors (in terms of
224
+ # nested params)
225
+ def action_aware?
226
+ if @options.key?(:action_aware)
227
+ return @options[:action_aware]
228
+ elsif @parent
229
+ @parent.action_aware?
230
+ else
231
+ false
232
+ end
233
+ end
234
+
235
+ def as_action
236
+ if @options[:param_group] && @options[:param_group][:options] &&
237
+ @options[:param_group][:options][:as]
238
+ @options[:param_group][:options][:as].to_s
239
+ elsif @parent
240
+ @parent.as_action
241
+ else
242
+ @method_description.method
243
+ end
244
+ end
245
+
246
+ # makes modification that are based on the action that the param
247
+ # is defined for. Typical for required and allow_nil variations in
248
+ # create/update actions.
249
+ def action_awareness
250
+ if action_aware?
251
+ if !@options.key?(:allow_nil)
252
+ if @required
253
+ @allow_nil = false
254
+ else
255
+ @allow_nil = true
256
+ end
257
+ end
258
+ if as_action != "create"
259
+ @required = false
260
+ end
261
+ end
262
+ end
263
+
264
+ def concern_subst(string)
265
+ return string if string.nil? or !from_concern?
266
+
267
+ original = string
268
+ string = ":#{original}" if original.is_a? Symbol
269
+
270
+ replaced = method_description.resource.controller._apipie_perform_concern_subst(string)
271
+
272
+ return original if replaced == string
273
+ return replaced.to_sym if original.is_a? Symbol
274
+ return replaced
275
+ end
276
+
277
+ def preformat_text(text)
278
+ concern_subst(Apipie.markup_to_html(text || ''))
279
+ end
280
+
281
+ def is_required?
282
+ if @options.key?(:required)
283
+ if (@options[:required] == true) || (@options[:required] == false)
284
+ @options[:required]
285
+ else
286
+ Array(@options[:required]).include?(@method_description.method.to_sym)
287
+ end
288
+ else
289
+ Apipie.configuration.required_by_default?
290
+ end
291
+ end
292
+
293
+ def deprecated?
294
+ @deprecated.present?
295
+ end
296
+
297
+ def deprecation
298
+ return if @deprecated.blank? || @deprecated == true
299
+
300
+ case @deprecated
301
+ when Hash
302
+ Apipie::ParamDescription::Deprecation.new(
303
+ info: @deprecated[:info],
304
+ deprecated_in: @deprecated[:in],
305
+ sunset_at: @deprecated[:sunset]
306
+ )
307
+ when String
308
+ Apipie::ParamDescription::Deprecation.new(info: @deprecated)
309
+ end
310
+ end
311
+ end
312
+
313
+ end
@@ -0,0 +1,9 @@
1
+ module Apipie
2
+ class Railtie < Rails::Railtie
3
+ initializer 'apipie.controller_additions' do
4
+ ActiveSupport.on_load :action_controller do
5
+ extend Apipie::DSL::Controller
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,152 @@
1
+ module Apipie
2
+
3
+ # Resource description
4
+ #
5
+ # version - api version (1)
6
+ # description
7
+ # path - relative path (/api/articles)
8
+ # methods - array of keys to Apipie.method_descriptions (array of Apipie::MethodDescription)
9
+ # name - human readable alias of resource (Articles)
10
+ # id - resource name
11
+ # formats - acceptable request/response format types
12
+ # headers - array of headers
13
+ # deprecated - boolean indicating if resource is deprecated
14
+ class ResourceDescription
15
+
16
+ attr_reader :controller, :_short_description, :_full_description, :_methods, :_id,
17
+ :_path, :_params_args, :_returns_args, :_tag_list_arg, :_errors_args,
18
+ :_formats, :_parent, :_metadata, :_headers, :_deprecated
19
+
20
+ def initialize(controller, id, dsl_data = nil, version = nil)
21
+ @_methods = ActiveSupport::OrderedHash.new
22
+ @_params_args = []
23
+ @_errors_args = []
24
+ @_returns_args = []
25
+
26
+ @controller = controller
27
+ @_id = id
28
+ @_version = version || Apipie.configuration.default_version
29
+ @_parent = Apipie.value_from_parents(controller.superclass, version) do |parent, ver|
30
+ Apipie.get_resource_description(parent, ver)
31
+ end
32
+
33
+ update_from_dsl_data(dsl_data) if dsl_data
34
+ end
35
+
36
+ def update_from_dsl_data(dsl_data)
37
+ @_resource_name = dsl_data[:resource_name] if dsl_data[:resource_name]
38
+ @_full_description = dsl_data[:description]
39
+ @_short_description = dsl_data[:short_description]
40
+ @_path = dsl_data[:path] || ""
41
+ @_formats = dsl_data[:formats]
42
+ @_errors_args = dsl_data[:errors]
43
+ @_params_args = dsl_data[:params]
44
+ @_returns_args = dsl_data[:returns]
45
+ @_tag_list_arg = dsl_data[:tag_list]
46
+ @_metadata = dsl_data[:meta]
47
+ @_api_base_url = dsl_data[:api_base_url]
48
+ @_headers = dsl_data[:headers]
49
+ @_deprecated = dsl_data[:deprecated] || false
50
+
51
+ if dsl_data[:app_info]
52
+ Apipie.configuration.app_info[_version] = dsl_data[:app_info]
53
+ end
54
+ end
55
+
56
+ def _version
57
+ @_version || @_parent.try(:_version) || Apipie.configuration.default_version
58
+ end
59
+
60
+ def _api_base_url
61
+ @_api_base_url || @_parent.try(:_api_base_url) || Apipie.api_base_url(_version)
62
+ end
63
+
64
+ def name
65
+ @name ||= case resource_name
66
+ when Proc
67
+ resource_name.call(controller)
68
+ when Symbol
69
+ controller.public_send(resource_name)
70
+ when String
71
+ resource_name
72
+ else
73
+ default_name
74
+ end
75
+ end
76
+ alias _name name
77
+
78
+ def add_method_description(method_description)
79
+ Apipie.debug "@resource_descriptions[#{self._version}][#{self._id}]._methods[#{method_description.method}] = #{method_description}"
80
+ @_methods[method_description.method.to_sym] = method_description
81
+ end
82
+
83
+ def method_description(method_name)
84
+ @_methods[method_name.to_sym]
85
+ end
86
+
87
+ def remove_method_description(method_name)
88
+ if @_methods.key?(method_name)
89
+ @_methods.delete(method_name)
90
+ end
91
+ end
92
+
93
+ def method_descriptions
94
+ @_methods.values
95
+ end
96
+
97
+ def doc_url
98
+ crumbs = []
99
+ crumbs << _version if Apipie.configuration.version_in_url
100
+ crumbs << @_id
101
+ Apipie.full_url crumbs.join('/')
102
+ end
103
+
104
+ def api_url
105
+ "#{Apipie.api_base_url(_version)}#{@_path}"
106
+ end
107
+
108
+ def valid_method_name?(method_name)
109
+ @_methods.keys.map(&:to_s).include?(method_name.to_s)
110
+ end
111
+
112
+ def to_json(method_name = nil, lang = nil)
113
+ if method_name && !valid_method_name?(method_name)
114
+ raise "Method #{method_name} not found for resource #{_name}"
115
+ end
116
+
117
+ methods = if method_name.blank?
118
+ @_methods.collect { |key, method_description| method_description.to_json(lang) }
119
+ else
120
+ [@_methods[method_name.to_sym].to_json(lang)]
121
+ end
122
+
123
+ {
124
+ :doc_url => doc_url,
125
+ :id => _id,
126
+ :api_url => api_url,
127
+ :name => name,
128
+ :short_description => Apipie.app.translate(@_short_description, lang),
129
+ :full_description => Apipie.markup_to_html(Apipie.app.translate(@_full_description, lang)),
130
+ :version => _version,
131
+ :formats => @_formats,
132
+ :metadata => @_metadata,
133
+ :methods => methods,
134
+ :headers => _headers,
135
+ :deprecated => @_deprecated
136
+ }
137
+ end
138
+
139
+ protected
140
+
141
+ def resource_name
142
+ @_resource_name.presence || @_parent&.resource_name
143
+ end
144
+
145
+ private
146
+
147
+ def default_name
148
+ @_id.split('-').map(&:capitalize).join('::')
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,157 @@
1
+ module Apipie
2
+
3
+ class ResponseDescription
4
+ class ResponseObject
5
+ include Apipie::DSL::Base
6
+ include Apipie::DSL::Param
7
+
8
+ attr_accessor :additional_properties, :typename
9
+ attr_reader :headers
10
+
11
+ def initialize(method_description, scope, block, typename)
12
+ @method_description = method_description
13
+ @scope = scope
14
+ @param_group = {scope: scope}
15
+ @additional_properties = false
16
+ @typename = typename
17
+ @headers = []
18
+
19
+ self.instance_exec(&block) if block
20
+
21
+ prepare_hash_params
22
+ end
23
+
24
+ # this routine overrides Param#_default_param_group_scope and is called if Param#param_group is
25
+ # invoked during the instance_exec call in ResponseObject#initialize
26
+ def _default_param_group_scope
27
+ @scope
28
+ end
29
+
30
+ def name
31
+ "response #{@code} for #{@method_description.method}"
32
+ end
33
+
34
+ def params_ordered
35
+ @params_ordered ||= _apipie_dsl_data[:params].map do |args|
36
+ options = args.find { |arg| arg.is_a? Hash }
37
+ options[:param_group] = @param_group
38
+ Apipie::ParamDescription.from_dsl_data(@method_description, args) unless options[:only_in] == :request
39
+ end.compact
40
+ end
41
+
42
+ def prepare_hash_params
43
+ @hash_params = params_ordered.reduce({}) do |h, param|
44
+ h.update(param.name.to_sym => param)
45
+ end
46
+ end
47
+
48
+ # @param [String] header_name
49
+ # @param [String, symbol, Class] validator
50
+ # @param [String] description
51
+ # @param [Hash] options
52
+ def header(header_name, validator, description, options = {})
53
+ @headers << {
54
+ name: header_name,
55
+ validator: validator.to_s.downcase,
56
+ description: description,
57
+ options: options
58
+ }
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+ class ResponseDescription
65
+ include Apipie::DSL::Base
66
+ include Apipie::DSL::Param
67
+
68
+ attr_reader :code, :description, :scope, :type_ref, :hash_validator, :is_array_of
69
+
70
+ def self.from_dsl_data(method_description, code, args)
71
+ options, scope, block, adapter = args
72
+
73
+ Apipie::ResponseDescription.new(method_description,
74
+ code,
75
+ options,
76
+ scope,
77
+ block,
78
+ adapter)
79
+ end
80
+
81
+ def initialize(method_description, code, options, scope, block, adapter)
82
+
83
+ @type_ref = options[:param_group]
84
+ @is_array_of = options[:array_of] || false
85
+ raise ReturnsMultipleDefinitionError, options if @is_array_of && @type_ref
86
+
87
+ @type_ref ||= @is_array_of
88
+
89
+ @method_description = method_description
90
+
91
+ @code =
92
+ if code.is_a? Symbol
93
+ begin
94
+ Rack::Utils.status_code(code)
95
+ rescue ArgumentError
96
+ nil
97
+ end
98
+ else
99
+ code
100
+ end
101
+
102
+ @description = options[:desc]
103
+ if @description.nil?
104
+ @description = Rack::Utils::HTTP_STATUS_CODES[@code]
105
+ raise "Cannot infer description from status code #{@code}" if @description.nil?
106
+ end
107
+ @scope = scope
108
+
109
+ if adapter
110
+ @response_object = adapter
111
+ else
112
+ @response_object = ResponseObject.new(method_description, scope, block, @type_ref)
113
+ end
114
+
115
+ @response_object.additional_properties ||= options[:additional_properties]
116
+ end
117
+
118
+ def is_array?
119
+ @is_array_of != false
120
+ end
121
+
122
+ delegate :typename, to: :@response_object
123
+
124
+ def param_description
125
+ nil
126
+ end
127
+
128
+ delegate :params_ordered, to: :@response_object
129
+
130
+ def additional_properties
131
+ !!@response_object.additional_properties
132
+ end
133
+ alias allow_additional_properties additional_properties
134
+
135
+ # @return [Array<Hash>]
136
+ def headers
137
+ # TODO: Support headers for Apipie::ResponseDescriptionAdapter
138
+ if @response_object.is_a?(Apipie::ResponseDescriptionAdapter)
139
+ return []
140
+ end
141
+
142
+ @response_object.headers
143
+ end
144
+
145
+ # @return [Hash{Symbol->TrueClass | FalseClass}]
146
+ def to_json(lang = nil)
147
+ {
148
+ :code => code,
149
+ :description => Apipie.app.translate(description, lang),
150
+ :is_array => is_array?,
151
+ :returns_object => params_ordered.map{ |param| param.to_json(lang).tap{|h| h.delete(:validations) }}.flatten,
152
+ :additional_properties => additional_properties,
153
+ :headers => headers
154
+ }
155
+ end
156
+ end
157
+ end