praxis 2.0.pre.17 → 2.0.pre.21

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 (235) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +54 -0
  3. data/.simplecov +3 -1
  4. data/.travis.yml +2 -1
  5. data/CHANGELOG.md +19 -0
  6. data/CONTRIBUTING.md +2 -79
  7. data/Gemfile +5 -1
  8. data/Guardfile +6 -4
  9. data/LICENSE +0 -2
  10. data/MAINTAINERS.md +1 -0
  11. data/README.md +15 -22
  12. data/Rakefile +4 -2
  13. data/bin/praxis +55 -58
  14. data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -6
  15. data/lib/praxis/action_definition.rb +65 -95
  16. data/lib/praxis/api_definition.rb +21 -29
  17. data/lib/praxis/api_general_info.rb +55 -66
  18. data/lib/praxis/application.rb +15 -32
  19. data/lib/praxis/blueprint.rb +80 -73
  20. data/lib/praxis/bootloader.rb +24 -33
  21. data/lib/praxis/bootloader_stages/environment.rb +5 -10
  22. data/lib/praxis/bootloader_stages/file_loader.rb +3 -6
  23. data/lib/praxis/bootloader_stages/plugin_config_load.rb +4 -6
  24. data/lib/praxis/bootloader_stages/plugin_config_prepare.rb +2 -2
  25. data/lib/praxis/bootloader_stages/plugin_loader.rb +3 -7
  26. data/lib/praxis/bootloader_stages/plugin_setup.rb +3 -3
  27. data/lib/praxis/bootloader_stages/routing.rb +5 -8
  28. data/lib/praxis/bootloader_stages/subgroup_loader.rb +2 -10
  29. data/lib/praxis/bootloader_stages/warn_unloaded_files.rb +15 -19
  30. data/lib/praxis/callbacks.rb +12 -11
  31. data/lib/praxis/collection.rb +11 -14
  32. data/lib/praxis/config.rb +17 -28
  33. data/lib/praxis/config_hash.rb +2 -1
  34. data/lib/praxis/controller.rb +7 -6
  35. data/lib/praxis/dispatcher.rb +34 -42
  36. data/lib/praxis/docs/open_api/info_object.rb +11 -8
  37. data/lib/praxis/docs/open_api/media_type_object.rb +18 -17
  38. data/lib/praxis/docs/open_api/operation_object.rb +7 -4
  39. data/lib/praxis/docs/open_api/parameter_object.rb +17 -14
  40. data/lib/praxis/docs/open_api/paths_object.rb +11 -9
  41. data/lib/praxis/docs/open_api/request_body_object.rb +14 -13
  42. data/lib/praxis/docs/open_api/response_object.rb +24 -18
  43. data/lib/praxis/docs/open_api/responses_object.rb +3 -1
  44. data/lib/praxis/docs/open_api/schema_object.rb +61 -29
  45. data/lib/praxis/docs/open_api/server_object.rb +5 -2
  46. data/lib/praxis/docs/open_api/tag_object.rb +9 -6
  47. data/lib/praxis/docs/open_api_generator.rb +114 -150
  48. data/lib/praxis/endpoint_definition.rb +60 -77
  49. data/lib/praxis/error_handler.rb +2 -2
  50. data/lib/praxis/exception.rb +2 -0
  51. data/lib/praxis/exceptions/config.rb +3 -1
  52. data/lib/praxis/exceptions/config_load.rb +2 -0
  53. data/lib/praxis/exceptions/config_validation.rb +3 -1
  54. data/lib/praxis/exceptions/invalid_configuration.rb +3 -1
  55. data/lib/praxis/exceptions/invalid_response.rb +3 -1
  56. data/lib/praxis/exceptions/invalid_trait.rb +3 -1
  57. data/lib/praxis/exceptions/stage_not_found.rb +3 -1
  58. data/lib/praxis/exceptions/validation.rb +4 -3
  59. data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +163 -149
  60. data/lib/praxis/extensions/attribute_filtering/active_record_patches/5x.rb +18 -13
  61. data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_0.rb +13 -9
  62. data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_1_plus.rb +14 -11
  63. data/lib/praxis/extensions/attribute_filtering/active_record_patches.rb +12 -9
  64. data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +8 -5
  65. data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +89 -65
  66. data/lib/praxis/extensions/attribute_filtering/filters_parser.rb +68 -62
  67. data/lib/praxis/extensions/attribute_filtering.rb +3 -1
  68. data/lib/praxis/extensions/field_expansion.rb +6 -4
  69. data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +10 -8
  70. data/lib/praxis/extensions/field_selection/field_selector.rb +91 -92
  71. data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +12 -12
  72. data/lib/praxis/extensions/field_selection.rb +3 -1
  73. data/lib/praxis/extensions/pagination/active_record_pagination_handler.rb +6 -4
  74. data/lib/praxis/extensions/pagination/header_generator.rb +16 -11
  75. data/lib/praxis/extensions/pagination/ordering_params.rb +29 -28
  76. data/lib/praxis/extensions/pagination/pagination_handler.rb +44 -42
  77. data/lib/praxis/extensions/pagination/pagination_params.rb +29 -48
  78. data/lib/praxis/extensions/pagination/sequel_pagination_handler.rb +8 -7
  79. data/lib/praxis/extensions/pagination.rb +10 -15
  80. data/lib/praxis/extensions/rails_compat/request_methods.rb +3 -4
  81. data/lib/praxis/extensions/rails_compat.rb +2 -0
  82. data/lib/praxis/extensions/rendering.rb +12 -12
  83. data/lib/praxis/field_expander.rb +8 -9
  84. data/lib/praxis/file_group.rb +8 -12
  85. data/lib/praxis/finalizable.rb +1 -0
  86. data/lib/praxis/handlers/json.rb +5 -2
  87. data/lib/praxis/handlers/plain.rb +2 -1
  88. data/lib/praxis/handlers/www_form.rb +6 -3
  89. data/lib/praxis/handlers/{xml-sample.rb → xml_sample.rb} +26 -22
  90. data/lib/praxis/mapper/active_model_compat.rb +13 -10
  91. data/lib/praxis/mapper/resource.rb +196 -181
  92. data/lib/praxis/mapper/selector_generator.rb +106 -112
  93. data/lib/praxis/mapper/sequel_compat.rb +70 -67
  94. data/lib/praxis/media_type.rb +2 -2
  95. data/lib/praxis/media_type_identifier.rb +26 -22
  96. data/lib/praxis/middleware_app.rb +18 -15
  97. data/lib/praxis/multipart/parser.rb +46 -51
  98. data/lib/praxis/multipart/part.rb +78 -110
  99. data/lib/praxis/notifications.rb +2 -4
  100. data/lib/praxis/plugin.rb +11 -18
  101. data/lib/praxis/plugin_concern.rb +12 -15
  102. data/lib/praxis/plugins/mapper_plugin.rb +15 -13
  103. data/lib/praxis/plugins/pagination_plugin.rb +8 -6
  104. data/lib/praxis/plugins/rails_plugin.rb +33 -28
  105. data/lib/praxis/renderer.rb +11 -15
  106. data/lib/praxis/request.rb +48 -44
  107. data/lib/praxis/request_stages/action.rb +4 -6
  108. data/lib/praxis/request_stages/load_request.rb +2 -4
  109. data/lib/praxis/request_stages/request_stage.rb +19 -23
  110. data/lib/praxis/request_stages/response.rb +4 -6
  111. data/lib/praxis/request_stages/validate.rb +3 -5
  112. data/lib/praxis/request_stages/validate_params_and_headers.rb +15 -22
  113. data/lib/praxis/request_stages/validate_payload.rb +25 -28
  114. data/lib/praxis/request_superclassing.rb +3 -3
  115. data/lib/praxis/resource_definition.rb +1 -0
  116. data/lib/praxis/response.rb +24 -26
  117. data/lib/praxis/response_definition.rb +77 -122
  118. data/lib/praxis/response_template.rb +11 -15
  119. data/lib/praxis/responses/http.rb +23 -44
  120. data/lib/praxis/responses/internal_server_error.rb +18 -21
  121. data/lib/praxis/responses/multipart_ok.rb +4 -9
  122. data/lib/praxis/responses/validation_error.rb +8 -15
  123. data/lib/praxis/route.rb +8 -10
  124. data/lib/praxis/router/rack.rb +13 -7
  125. data/lib/praxis/router/simple.rb +10 -5
  126. data/lib/praxis/router.rb +27 -34
  127. data/lib/praxis/routing_config.rb +52 -29
  128. data/lib/praxis/simple_media_type.rb +5 -8
  129. data/lib/praxis/stage.rb +17 -25
  130. data/lib/praxis/tasks/api_docs.rb +17 -16
  131. data/lib/praxis/tasks/console.rb +3 -1
  132. data/lib/praxis/tasks/environment.rb +2 -0
  133. data/lib/praxis/tasks/routes.rb +26 -24
  134. data/lib/praxis/tasks.rb +3 -1
  135. data/lib/praxis/trait.rb +37 -46
  136. data/lib/praxis/types/fuzzy_hash.rb +13 -14
  137. data/lib/praxis/types/media_type_common.rb +11 -10
  138. data/lib/praxis/types/multipart_array/part_definition.rb +14 -17
  139. data/lib/praxis/types/multipart_array.rb +100 -115
  140. data/lib/praxis/validation_handler.rb +5 -3
  141. data/lib/praxis/version.rb +3 -1
  142. data/lib/praxis.rb +4 -5
  143. data/praxis.gemspec +22 -21
  144. data/spec/functional_spec.rb +44 -56
  145. data/spec/praxis/action_definition_spec.rb +39 -48
  146. data/spec/praxis/api_definition_spec.rb +45 -47
  147. data/spec/praxis/api_general_info_spec.rb +28 -29
  148. data/spec/praxis/application_spec.rb +18 -14
  149. data/spec/praxis/blueprint_spec.rb +33 -34
  150. data/spec/praxis/bootloader_spec.rb +32 -30
  151. data/spec/praxis/callbacks_spec.rb +37 -37
  152. data/spec/praxis/collection_spec.rb +18 -25
  153. data/spec/praxis/config_hash_spec.rb +5 -4
  154. data/spec/praxis/config_spec.rb +27 -26
  155. data/spec/praxis/controller_spec.rb +8 -9
  156. data/spec/praxis/endpoint_definition_spec.rb +25 -32
  157. data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +171 -114
  158. data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +22 -21
  159. data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +112 -60
  160. data/spec/praxis/extensions/attribute_filtering/filters_parser_spec.rb +37 -38
  161. data/spec/praxis/extensions/field_expansion_spec.rb +8 -10
  162. data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +14 -13
  163. data/spec/praxis/extensions/field_selection/field_selector_spec.rb +9 -16
  164. data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +50 -49
  165. data/spec/praxis/extensions/pagination/active_record_pagination_handler_spec.rb +32 -31
  166. data/spec/praxis/extensions/rendering_spec.rb +9 -9
  167. data/spec/praxis/extensions/support/spec_resources_active_model.rb +32 -49
  168. data/spec/praxis/extensions/support/spec_resources_sequel.rb +48 -48
  169. data/spec/praxis/field_expander_spec.rb +6 -5
  170. data/spec/praxis/file_group_spec.rb +3 -1
  171. data/spec/praxis/handlers/json_spec.rb +6 -5
  172. data/spec/praxis/mapper/resource_spec.rb +39 -29
  173. data/spec/praxis/mapper/selector_generator_spec.rb +80 -46
  174. data/spec/praxis/media_type_identifier_spec.rb +13 -10
  175. data/spec/praxis/media_type_spec.rb +12 -12
  176. data/spec/praxis/middleware_app_spec.rb +23 -22
  177. data/spec/praxis/multipart/parser_spec.rb +7 -9
  178. data/spec/praxis/notifications_spec.rb +4 -4
  179. data/spec/praxis/plugin_concern_spec.rb +5 -6
  180. data/spec/praxis/renderer_spec.rb +10 -9
  181. data/spec/praxis/request_spec.rb +38 -41
  182. data/spec/praxis/request_stages/action_spec.rb +14 -15
  183. data/spec/praxis/request_stages/request_stage_spec.rb +30 -41
  184. data/spec/praxis/request_stages/validate_spec.rb +3 -1
  185. data/spec/praxis/response_definition_spec.rb +79 -92
  186. data/spec/praxis/response_spec.rb +35 -40
  187. data/spec/praxis/responses/internal_server_error_spec.rb +6 -9
  188. data/spec/praxis/responses/validation_error_spec.rb +17 -18
  189. data/spec/praxis/route_spec.rb +4 -7
  190. data/spec/praxis/router_spec.rb +69 -79
  191. data/spec/praxis/routing_config_spec.rb +15 -14
  192. data/spec/praxis/stage_spec.rb +56 -53
  193. data/spec/praxis/trait_spec.rb +17 -17
  194. data/spec/praxis/types/fuzzy_hash_spec.rb +11 -9
  195. data/spec/praxis/types/multipart_array/part_definition_spec.rb +3 -2
  196. data/spec/praxis/types/multipart_array_spec.rb +33 -48
  197. data/spec/spec_app/app/concerns/authenticated.rb +5 -5
  198. data/spec/spec_app/app/concerns/basic_api.rb +3 -1
  199. data/spec/spec_app/app/concerns/log_wrapper.rb +5 -3
  200. data/spec/spec_app/app/controllers/base_class.rb +6 -5
  201. data/spec/spec_app/app/controllers/instances.rb +31 -34
  202. data/spec/spec_app/app/controllers/volumes.rb +6 -6
  203. data/spec/spec_app/app/responses/multipart.rb +1 -2
  204. data/spec/spec_app/app/responses/other_response.rb +2 -2
  205. data/spec/spec_app/config/environment.rb +19 -6
  206. data/spec/spec_app/config.ru +4 -3
  207. data/spec/spec_app/design/api.rb +13 -15
  208. data/spec/spec_app/design/media_types/instance.rb +6 -6
  209. data/spec/spec_app/design/media_types/volume.rb +2 -1
  210. data/spec/spec_app/design/media_types/volume_snapshot.rb +2 -1
  211. data/spec/spec_app/design/resources/instances.rb +11 -17
  212. data/spec/spec_app/design/resources/volume_snapshots.rb +4 -5
  213. data/spec/spec_app/design/resources/volumes.rb +4 -5
  214. data/spec/spec_helper.rb +11 -13
  215. data/spec/support/be_deep_equal_matcher.rb +5 -0
  216. data/spec/support/spec_authorization_plugin.rb +7 -12
  217. data/spec/support/spec_blueprints.rb +5 -4
  218. data/spec/support/spec_complex_authentication_plugin.rb +17 -34
  219. data/spec/support/spec_endpoint_definitions.rb +2 -3
  220. data/spec/support/spec_media_types.rb +28 -35
  221. data/spec/support/spec_resources.rb +22 -16
  222. data/spec/support/spec_simple_authentication_plugin.rb +5 -9
  223. data/tasks/loader.thor +4 -2
  224. data/tasks/thor/app.rb +7 -5
  225. data/tasks/thor/example.rb +23 -22
  226. data/tasks/thor/model.rb +7 -7
  227. data/tasks/thor/scaffold.rb +23 -23
  228. data/tasks/thor/templates/generator/example_app/app/v1/resources/user.rb +0 -8
  229. data/tasks/thor/templates/generator/scaffold/implementation/resources/item.rb +1 -2
  230. metadata +72 -84
  231. data/MAINTAINERS +0 -2
  232. data/TODO.md +0 -25
  233. data/spec/praxis/api_resource_spec.rb +0 -0
  234. data/spec/praxis/dispatcher_spec.rb +0 -0
  235. data/spec/spec_app/app/responses/bulk_response.rb +0 -0
@@ -1,28 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Praxis
2
4
  class RoutingConfig
5
+ attr_reader :route, :version, :base
3
6
 
4
- attr_reader :route
5
- attr_reader :version
6
- attr_reader :base
7
-
8
- def initialize(version:'n/a'.freeze, base: '', prefix:[], &block)
7
+ def initialize(version: 'n/a', base: '', prefix: [], &block)
9
8
  @version = version
10
9
  @base = base
11
10
  @prefix_segments = Array(prefix)
12
11
 
13
12
  @route = nil
14
13
 
15
- if block_given?
16
- instance_eval(&block)
17
- end
14
+ instance_eval(&block) if block_given?
18
15
  end
19
16
 
20
17
  def clear!
21
18
  @prefix_segments = []
22
19
  end
23
20
 
24
- def prefix(prefix=nil)
25
- return @prefix_segments.join.gsub('//','/') if prefix.nil?
21
+ def prefix(prefix = nil)
22
+ return @prefix_segments.join.gsub('//', '/') if prefix.nil?
26
23
 
27
24
  case prefix
28
25
  when ''
@@ -34,28 +31,54 @@ module Praxis
34
31
  end
35
32
  end
36
33
 
37
- def options(path, opts={}) add_route 'OPTIONS', path, opts end
38
- def get(path, opts={}) add_route 'GET', path, opts end
39
- def head(path, opts={}) add_route 'HEAD', path, opts end
40
- def post(path, opts={}) add_route 'POST', path, opts end
41
- def put(path, opts={}) add_route 'PUT', path, opts end
42
- def delete(path, opts={}) add_route 'DELETE', path, opts end
43
- def trace(path, opts={}) add_route 'TRACE', path, opts end
44
- def connect(path, opts={}) add_route 'CONNECT', path, opts end
45
- def patch(path, opts={}) add_route 'PATCH', path, opts end
46
- def any(path, opts={}) add_route 'ANY', path, opts end
34
+ def options(path, opts = {})
35
+ add_route 'OPTIONS', path, opts
36
+ end
47
37
 
48
- ABSOLUTE_PATH_REGEX = %r|^//|
38
+ def get(path, opts = {})
39
+ add_route 'GET', path, opts
40
+ end
49
41
 
50
- def add_route(verb, path, options={})
51
- unless path =~ ABSOLUTE_PATH_REGEX
52
- path = prefix + path
53
- end
54
- prefixed_path = path.gsub('//','/')
55
- path = (base + path).gsub('//','/')
56
- pattern = Mustermann.new(path, **{ignore_unknown_options: true}.merge( options ))
57
- @route = Route.new(verb, pattern, version, prefixed_path: prefixed_path, **options)
42
+ def head(path, opts = {})
43
+ add_route 'HEAD', path, opts
44
+ end
45
+
46
+ def post(path, opts = {})
47
+ add_route 'POST', path, opts
48
+ end
49
+
50
+ def put(path, opts = {})
51
+ add_route 'PUT', path, opts
52
+ end
53
+
54
+ def delete(path, opts = {})
55
+ add_route 'DELETE', path, opts
56
+ end
57
+
58
+ def trace(path, opts = {})
59
+ add_route 'TRACE', path, opts
60
+ end
61
+
62
+ def connect(path, opts = {})
63
+ add_route 'CONNECT', path, opts
64
+ end
65
+
66
+ def patch(path, opts = {})
67
+ add_route 'PATCH', path, opts
68
+ end
69
+
70
+ def any(path, opts = {})
71
+ add_route 'ANY', path, opts
58
72
  end
59
73
 
74
+ ABSOLUTE_PATH_REGEX = %r{^//}.freeze
75
+
76
+ def add_route(verb, path, options = {})
77
+ path = prefix + path unless path =~ ABSOLUTE_PATH_REGEX
78
+ prefixed_path = path.gsub('//', '/')
79
+ path = (base + path).gsub('//', '/')
80
+ pattern = Mustermann.new(path, **{ ignore_unknown_options: true }.merge(options))
81
+ @route = Route.new(verb, pattern, version, prefixed_path: prefixed_path, **options)
82
+ end
60
83
  end
61
84
  end
@@ -1,29 +1,26 @@
1
- module Praxis
1
+ # frozen_string_literal: true
2
2
 
3
+ module Praxis
3
4
  # Stripped-down representation of an Internet Media Type where the structure and content of the
4
5
  # type are unknown, or are defined externally to the Praxis application.
5
6
  #
6
7
  # @see Praxis::MediaType
7
8
  # @see Praxis::Types::MediaTypeCommon
8
9
  SimpleMediaType = Struct.new(:identifier) do
9
-
10
10
  def name
11
11
  self.class.name
12
12
  end
13
13
 
14
14
  def self.id
15
- "Praxis-SimpleMediaType".freeze
15
+ 'Praxis-SimpleMediaType'
16
16
  end
17
17
 
18
18
  def id
19
19
  self.class.id
20
20
  end
21
21
 
22
-
23
- def describe(shallow=true)
24
- {name: name, family: "string", id: id, identifier: identifier}
22
+ def describe(*)
23
+ { name: name, family: 'string', id: id, identifier: identifier }
25
24
  end
26
-
27
25
  end
28
-
29
26
  end
data/lib/praxis/stage.rb CHANGED
@@ -1,32 +1,28 @@
1
- module Praxis
1
+ # frozen_string_literal: true
2
2
 
3
+ module Praxis
3
4
  class Stage
4
-
5
- attr_reader :name
6
- attr_reader :context
7
- attr_reader :stages
8
- attr_reader :before_callbacks
9
- attr_reader :after_callbacks
5
+ attr_reader :name, :context, :stages, :before_callbacks, :after_callbacks
10
6
 
11
7
  def application
12
8
  context
13
9
  end
14
10
 
15
- def initialize(name, context, **opts)
11
+ def initialize(name, context, **_opts)
16
12
  @name = name
17
13
  @context = context
18
- @before_callbacks = Array.new
19
- @after_callbacks = Array.new
20
- @deferred_callbacks = Hash.new do |hash,stage|
21
- hash[stage] = {before: [], after:[]}
14
+ @before_callbacks = []
15
+ @after_callbacks = []
16
+ @deferred_callbacks = Hash.new do |hash, stage|
17
+ hash[stage] = { before: [], after: [] }
22
18
  end
23
- @stages = Array.new
19
+ @stages = []
24
20
  end
25
21
 
26
22
  def run
27
- execute_callbacks(self.before_callbacks)
23
+ execute_callbacks(before_callbacks)
28
24
  execute
29
- execute_callbacks(self.after_callbacks)
25
+ execute_callbacks(after_callbacks)
30
26
  end
31
27
 
32
28
  def setup!
@@ -34,22 +30,20 @@ module Praxis
34
30
  end
35
31
 
36
32
  def setup_deferred_callbacks!
37
- @deferred_callbacks.keys.each do |stage_name|
33
+ @deferred_callbacks.each_key do |stage_name|
38
34
  callbacks = @deferred_callbacks.delete stage_name
39
35
  callbacks[:before].each do |(*stage_path, block)|
40
- self.before(stage_name, *stage_path, &block)
36
+ before(stage_name, *stage_path, &block)
41
37
  end
42
38
 
43
39
  callbacks[:after].each do |(*stage_path, block)|
44
- self.after(stage_name, *stage_path, &block)
40
+ after(stage_name, *stage_path, &block)
45
41
  end
46
42
  end
47
43
  end
48
44
 
49
45
  def execute
50
- @stages.each do |stage|
51
- stage.run
52
- end
46
+ @stages.each(&:run)
53
47
  end
54
48
 
55
49
  def execute_callbacks(callbacks)
@@ -65,7 +59,7 @@ module Praxis
65
59
  def before(*stage_path, &block)
66
60
  if stage_path.any?
67
61
  stage_name = stage_path.shift
68
- stage = stages.find { |stage| stage.name == stage_name }
62
+ stage = stages.find { |s| s.name == stage_name }
69
63
  if stage
70
64
  stage.before(*stage_path, &block)
71
65
  else
@@ -79,7 +73,7 @@ module Praxis
79
73
  def after(*stage_path, &block)
80
74
  if stage_path.any?
81
75
  stage_name = stage_path.shift
82
- stage = stages.find { |stage| stage.name == stage_name }
76
+ stage = stages.find { |s| s.name == stage_name }
83
77
  if stage
84
78
  stage.after(*stage_path, &block)
85
79
  else
@@ -89,7 +83,5 @@ module Praxis
89
83
  @after_callbacks << block
90
84
  end
91
85
  end
92
-
93
-
94
86
  end
95
87
  end
@@ -1,42 +1,43 @@
1
- namespace :praxis do
1
+ # frozen_string_literal: true
2
2
 
3
+ namespace :praxis do
3
4
  namespace :docs do
4
-
5
- desc "Generate OpenAPI 3 docs for a Praxis App"
6
- task :generate => [:environment] do |t, args|
5
+ desc 'Generate OpenAPI 3 docs for a Praxis App'
6
+ task generate: [:environment] do |_t, _args|
7
7
  require 'fileutils'
8
8
 
9
9
  Praxis::Blueprint.caching_enabled = false
10
- generator = Praxis::Docs::OpenApiGenerator.new(Dir.pwd)
10
+ generator = Praxis::Docs::OpenApiGenerator.instance
11
+ generator.configure_root(Dir.pwd)
11
12
  generator.save!
12
13
  end
13
14
 
14
- desc "Preview (and Generate) OpenAPI 3 docs for a Praxis App"
15
- task :preview => [:generate] do |t, args|
16
- require 'webrick'
15
+ desc 'Preview (and Generate) OpenAPI 3 docs for a Praxis App'
16
+ task preview: [:generate] do |_t, _args|
17
+ require 'webrick'
17
18
  docs_port = 9090
18
- root = Dir.pwd + '/docs/openapi/'
19
+ root = "#{Dir.pwd}/docs/openapi/"
19
20
  wb = Thread.new do
20
- s = WEBrick::HTTPServer.new(:Port => docs_port, :DocumentRoot => root)
21
+ s = WEBrick::HTTPServer.new(Port: docs_port, DocumentRoot: root)
21
22
  trap('INT') { s.shutdown }
22
23
  s.start
23
24
  end
24
25
  # If there is only 1 version we'll feature it and open the browser onto it
25
26
  versions = Dir.children(root)
26
- featured_version = (versions.size < 2) ? "#{versions.first}/" : ''
27
+ featured_version = versions.size < 2 ? "#{versions.first}/" : ''
27
28
  `open http://localhost:#{docs_port}/#{featured_version}`
28
29
  wb.join
29
30
  end
30
- desc "Generate and package all OpenApi Docs into a zip, ready for a Web server (like S3...) to present it"
31
- task :package => [:generate] do |t, args|
32
- docs_root = Dir.pwd + '/docs/openapi/'
33
- zip_file = Dir.pwd + '/docs/openapi.zip'
31
+ desc 'Generate and package all OpenApi Docs into a zip, ready for a Web server (like S3...) to present it'
32
+ task package: [:generate] do |_t, _args|
33
+ docs_root = "#{Dir.pwd}/docs/openapi/"
34
+ zip_file = "#{Dir.pwd}/docs/openapi.zip"
34
35
  `rm -f #{zip_file}`
35
36
  # NOTE: This assumes the "zip" utility is installed, supporting the recursive flag.
36
37
  `zip -r #{zip_file} #{docs_root}`
37
38
  puts
38
39
  puts "Left packaged API docs in #{zip_file}"
39
- puts " --> To view the docs, unzip the file under a web server (or S3...) and access the index.hml files from a browser"
40
+ puts ' --> To view the docs, unzip the file under a web server (or S3...) and access the index.hml files from a browser'
40
41
  end
41
42
  end
42
43
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  namespace :praxis do
2
- desc "Run interactive pry/irb console"
4
+ desc 'Run interactive pry/irb console'
3
5
  task :console do
4
6
  have_pry = false
5
7
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  namespace :praxis do
2
4
  task :environment do
3
5
  Praxis::Application.instance.setup
@@ -1,21 +1,22 @@
1
- namespace :praxis do
1
+ # frozen_string_literal: true
2
2
 
3
+ namespace :praxis do
3
4
  desc 'List routes, format=json or table, default table'
4
- task :routes, [:format] => [:environment] do |t, args|
5
+ task :routes, [:format] => [:environment] do |_t, args|
5
6
  require 'terminal-table'
6
7
 
7
- table = Terminal::Table.new title: "Routes",
8
- headings: [
9
- "Version", "Path", "Verb",
10
- "Endpoint", "Action", "Implementation", "Options"
11
- ]
8
+ table = Terminal::Table.new title: 'Routes',
9
+ headings: %w[
10
+ Version Path Verb
11
+ Endpoint Action Implementation Options
12
+ ]
12
13
 
13
14
  rows = []
14
15
  Praxis::Application.instance.endpoint_definitions.each do |endpoint_definition|
15
16
  endpoint_definition.actions.each do |name, action|
16
17
  method = begin
17
- m = endpoint_definition.controller.instance_method(name)
18
- rescue
18
+ endpoint_definition.controller.instance_method(name)
19
+ rescue StandardError
19
20
  nil
20
21
  end
21
22
 
@@ -24,31 +25,32 @@ namespace :praxis do
24
25
  row = {
25
26
  resource: endpoint_definition.name,
26
27
  action: name,
27
- implementation: method_name,
28
+ implementation: method_name
28
29
  }
29
30
 
30
- unless action.route
31
- warn "Warning: No routes defined for #{endpoint_definition.name}##{name}."
32
- rows << row
33
- else
31
+ if action.route
34
32
  route = action.route
35
33
  rows << row.merge({
36
- version: route.version,
37
- verb: route.verb,
38
- path: route.path,
39
- options: route.options
40
- })
34
+ version: route.version,
35
+ verb: route.verb,
36
+ path: route.path,
37
+ options: route.options
38
+ })
39
+ else
40
+ warn "Warning: No routes defined for #{endpoint_definition.name}##{name}."
41
+ rows << row
41
42
  end
42
43
  end
43
44
  end
44
- case args[:format] || "table"
45
- when "json"
45
+ format_type = args[:format] || 'table'
46
+ case format_type
47
+ when 'json'
46
48
  puts JSON.pretty_generate(rows)
47
- when "table"
49
+ when 'table'
48
50
  rows.each do |row|
49
- formatted_options = row[:options].map{|(k,v)| "#{k}:#{v.to_s}"}.join("\n")
51
+ formatted_options = row[:options].map { |(k, v)| "#{k}:#{v}" }.join("\n")
50
52
  row_data = row.values_at(:version, :path, :verb, :resource,
51
- :action, :implementation)
53
+ :action, :implementation)
52
54
  row_data << formatted_options
53
55
  table.add_row(row_data)
54
56
  end
data/lib/praxis/tasks.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'praxis/tasks/environment'
2
4
  require 'praxis/tasks/console'
3
5
  require 'praxis/tasks/routes'
4
- require 'praxis/tasks/api_docs'
6
+ require 'praxis/tasks/api_docs'
data/lib/praxis/trait.rb CHANGED
@@ -1,8 +1,8 @@
1
- module Praxis
1
+ # frozen_string_literal: true
2
2
 
3
+ module Praxis
3
4
  class Trait
4
- attr_reader :name
5
- attr_reader :attribute_groups
5
+ attr_reader :name, :attribute_groups
6
6
 
7
7
  def initialize(&block)
8
8
  @name = nil
@@ -11,21 +11,24 @@ module Praxis
11
11
  @routing = nil
12
12
  @other = []
13
13
 
14
- @attribute_groups = Hash.new do |h,k|
14
+ @attribute_groups = Hash.new do |h, k|
15
15
  h[k] = []
16
16
  end
17
17
 
18
- if block_given?
19
- self.instance_eval(&block)
20
- end
18
+ instance_eval(&block) if block_given?
21
19
  end
22
20
 
23
21
  def method_missing(name, *args, &block)
24
22
  @other << [name, args, block]
25
23
  end
26
24
 
27
- def description(desc=nil)
25
+ def respond_to_missing?(*)
26
+ true
27
+ end
28
+
29
+ def description(desc = nil)
28
30
  return @description if desc.nil?
31
+
29
32
  @description = desc
30
33
  end
31
34
 
@@ -37,22 +40,20 @@ module Praxis
37
40
  @attribute_groups[name] << block
38
41
  end
39
42
 
40
- def headers(*args, &block)
41
- create_group(:headers,&block)
43
+ def headers(*_args, &block)
44
+ create_group(:headers, &block)
42
45
  end
43
46
 
44
- def params(*args, &block)
45
- create_group(:params,&block)
47
+ def params(*_args, &block)
48
+ create_group(:params, &block)
46
49
  end
47
50
 
48
51
  def payload(*args, &block)
49
- type, opts = args
52
+ type, _opts = args
50
53
 
51
- if type && !(type < Attributor::Hash)
52
- raise 'payload in a trait with non-hash (or model or struct) is not supported'
53
- end
54
+ raise 'payload in a trait with non-hash (or model or struct) is not supported' if type && !(type < Attributor::Hash)
54
55
 
55
- create_group(:payload,&block)
56
+ create_group(:payload, &block)
56
57
  end
57
58
 
58
59
  def routing(&block)
@@ -60,26 +61,24 @@ module Praxis
60
61
  end
61
62
 
62
63
  def describe
63
- desc = {description: @description}
64
+ desc = { description: @description }
64
65
  desc[:name] = @name if @name
65
66
  desc[:responses] = @responses if @responses.any?
66
67
 
67
- if @routing
68
- desc[:routing] = ConfigHash.new(&@routing).to_hash
69
- end
68
+ desc[:routing] = ConfigHash.new(&@routing).to_hash if @routing
70
69
 
71
70
  @attribute_groups.each_with_object(desc) do |(name, blocks), hash|
72
71
  type_class = if name == :headers
73
- # Headers are special:
74
- # Keys are strings, they have a special DSL, and are case insensitive
75
- hash_opts = {
76
- dsl_compiler: ActionDefinition::HeadersDSLCompiler,
77
- case_insensitive_load: true
78
- }
79
- Attributor::Hash.of(key: String).construct(Proc.new {}, **hash_opts)
80
- else
81
- Attributor::Hash.construct(Proc.new {})
82
- end
72
+ # Headers are special:
73
+ # Keys are strings, they have a special DSL, and are case insensitive
74
+ hash_opts = {
75
+ dsl_compiler: ActionDefinition::HeadersDSLCompiler,
76
+ case_insensitive_load: true
77
+ }
78
+ Attributor::Hash.of(key: String).construct(proc {}, **hash_opts)
79
+ else
80
+ Attributor::Hash.construct(proc {})
81
+ end
83
82
  blocks.each do |block|
84
83
  type_class.construct(block)
85
84
  end
@@ -89,7 +88,6 @@ module Praxis
89
88
  desc
90
89
  end
91
90
 
92
-
93
91
  def apply!(target)
94
92
  @attribute_groups.each do |name, blocks|
95
93
  blocks.each do |block|
@@ -97,27 +95,20 @@ module Praxis
97
95
  end
98
96
  end
99
97
 
100
- if @routing
101
- target.routing(&@routing)
102
- end
98
+ target.routing(&@routing) if @routing
103
99
 
104
100
  @responses.each do |name, args|
105
101
  target.response(name, **args)
106
102
  end
103
+ return unless @other.any?
107
104
 
108
- if @other.any?
109
- @other.each do |name, args, block|
110
- if block
111
- target.send(name, *args, &block)
112
- else
113
- target.send(name,*args)
114
- end
105
+ @other.each do |name, args, block|
106
+ if block
107
+ target.send(name, *args, &block)
108
+ else
109
+ target.send(name, *args)
115
110
  end
116
111
  end
117
112
  end
118
-
119
-
120
-
121
113
  end
122
-
123
114
  end
@@ -1,35 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Praxis
2
4
  module Types
3
-
4
5
  class FuzzyHash
5
- def initialize(value={})
6
+ def initialize(value = {})
6
7
  @hash = {}
7
8
  @regexes = []
8
9
  update(value)
9
10
  end
10
11
 
11
12
  def update(value)
12
- value.each do |k,v|
13
- self[k] = v
13
+ value.each do |key, val|
14
+ self[key] = val
14
15
  end
15
16
 
16
17
  self
17
18
  end
18
19
 
19
- def []=(k,v)
20
- case k
20
+ def []=(key, val)
21
+ case key
21
22
  when Regexp
22
- @regexes << k
23
+ @regexes << key
23
24
  end
24
- @hash[k] = v
25
+ @hash[key] = val
25
26
  end
26
27
 
27
- def [](k)
28
- return @hash[k] if @hash.key?(k)
28
+ def [](key)
29
+ return @hash[key] if @hash.key?(key)
29
30
 
30
- k = k.to_s
31
+ key = key.to_s
31
32
  @regexes.each do |regex|
32
- return @hash[regex] if regex.match(k)
33
+ return @hash[regex] if regex.match(key)
33
34
  end
34
35
 
35
36
  nil
@@ -42,8 +43,6 @@ module Praxis
42
43
  def respond_to_missing?(*args)
43
44
  @hash.respond_to?(*args)
44
45
  end
45
-
46
46
  end
47
-
48
47
  end
49
48
  end
@@ -1,43 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Praxis
2
4
  module Types
3
-
4
5
  # Traits that are shared by MediaType and SimpleMediaType.
5
6
  module MediaTypeCommon
6
7
  extend ::ActiveSupport::Concern
7
8
 
8
9
  module ClassMethods
9
10
  def as_json_schema(**args)
10
- the_type = @attribute && @attribute.type || member_type
11
+ the_type = @attribute&.type || member_type
11
12
  the_type.as_json_schema(args)
12
13
  end
13
14
 
14
15
  def json_schema_type
15
- the_type = @attribute && @attribute.type || member_type
16
+ the_type = @attribute&.type || member_type
16
17
  the_type.json_schema_type
17
18
  end
18
-
19
- def description(text=nil)
19
+
20
+ def description(text = nil)
20
21
  @description = text if text
21
22
  @description
22
23
  end
23
24
 
24
- def display_name( string=nil )
25
+ def display_name(string = nil)
25
26
  unless string
26
- return @display_name ||= self.name.split("::").last # Best guess at a display name?
27
+ return @display_name ||= name.split('::').last # Best guess at a display name?
27
28
  end
29
+
28
30
  @display_name = string
29
31
  end
30
32
 
31
33
  # Get or set the identifier of this media type.
32
34
  #
33
35
  # @return [MediaTypeIdentifier] the string-representation of this type's identifier
34
- def identifier(identifier=nil)
36
+ def identifier(identifier = nil)
35
37
  return @identifier unless identifier
38
+
36
39
  @identifier = MediaTypeIdentifier.load(identifier)
37
40
  end
38
41
  end
39
-
40
42
  end
41
-
42
43
  end
43
44
  end