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.
- checksums.yaml +4 -4
- data/.rubocop.yml +54 -0
- data/.simplecov +3 -1
- data/.travis.yml +2 -1
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTING.md +2 -79
- data/Gemfile +5 -1
- data/Guardfile +6 -4
- data/LICENSE +0 -2
- data/MAINTAINERS.md +1 -0
- data/README.md +15 -22
- data/Rakefile +4 -2
- data/bin/praxis +55 -58
- data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -6
- data/lib/praxis/action_definition.rb +65 -95
- data/lib/praxis/api_definition.rb +21 -29
- data/lib/praxis/api_general_info.rb +55 -66
- data/lib/praxis/application.rb +15 -32
- data/lib/praxis/blueprint.rb +80 -73
- data/lib/praxis/bootloader.rb +24 -33
- data/lib/praxis/bootloader_stages/environment.rb +5 -10
- data/lib/praxis/bootloader_stages/file_loader.rb +3 -6
- data/lib/praxis/bootloader_stages/plugin_config_load.rb +4 -6
- data/lib/praxis/bootloader_stages/plugin_config_prepare.rb +2 -2
- data/lib/praxis/bootloader_stages/plugin_loader.rb +3 -7
- data/lib/praxis/bootloader_stages/plugin_setup.rb +3 -3
- data/lib/praxis/bootloader_stages/routing.rb +5 -8
- data/lib/praxis/bootloader_stages/subgroup_loader.rb +2 -10
- data/lib/praxis/bootloader_stages/warn_unloaded_files.rb +15 -19
- data/lib/praxis/callbacks.rb +12 -11
- data/lib/praxis/collection.rb +11 -14
- data/lib/praxis/config.rb +17 -28
- data/lib/praxis/config_hash.rb +2 -1
- data/lib/praxis/controller.rb +7 -6
- data/lib/praxis/dispatcher.rb +34 -42
- data/lib/praxis/docs/open_api/info_object.rb +11 -8
- data/lib/praxis/docs/open_api/media_type_object.rb +18 -17
- data/lib/praxis/docs/open_api/operation_object.rb +7 -4
- data/lib/praxis/docs/open_api/parameter_object.rb +17 -14
- data/lib/praxis/docs/open_api/paths_object.rb +11 -9
- data/lib/praxis/docs/open_api/request_body_object.rb +14 -13
- data/lib/praxis/docs/open_api/response_object.rb +24 -18
- data/lib/praxis/docs/open_api/responses_object.rb +3 -1
- data/lib/praxis/docs/open_api/schema_object.rb +61 -29
- data/lib/praxis/docs/open_api/server_object.rb +5 -2
- data/lib/praxis/docs/open_api/tag_object.rb +9 -6
- data/lib/praxis/docs/open_api_generator.rb +114 -150
- data/lib/praxis/endpoint_definition.rb +60 -77
- data/lib/praxis/error_handler.rb +2 -2
- data/lib/praxis/exception.rb +2 -0
- data/lib/praxis/exceptions/config.rb +3 -1
- data/lib/praxis/exceptions/config_load.rb +2 -0
- data/lib/praxis/exceptions/config_validation.rb +3 -1
- data/lib/praxis/exceptions/invalid_configuration.rb +3 -1
- data/lib/praxis/exceptions/invalid_response.rb +3 -1
- data/lib/praxis/exceptions/invalid_trait.rb +3 -1
- data/lib/praxis/exceptions/stage_not_found.rb +3 -1
- data/lib/praxis/exceptions/validation.rb +4 -3
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +163 -149
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/5x.rb +18 -13
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_0.rb +13 -9
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_1_plus.rb +14 -11
- data/lib/praxis/extensions/attribute_filtering/active_record_patches.rb +12 -9
- data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +8 -5
- data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +89 -65
- data/lib/praxis/extensions/attribute_filtering/filters_parser.rb +68 -62
- data/lib/praxis/extensions/attribute_filtering.rb +3 -1
- data/lib/praxis/extensions/field_expansion.rb +6 -4
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +10 -8
- data/lib/praxis/extensions/field_selection/field_selector.rb +91 -92
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +12 -12
- data/lib/praxis/extensions/field_selection.rb +3 -1
- data/lib/praxis/extensions/pagination/active_record_pagination_handler.rb +6 -4
- data/lib/praxis/extensions/pagination/header_generator.rb +16 -11
- data/lib/praxis/extensions/pagination/ordering_params.rb +29 -28
- data/lib/praxis/extensions/pagination/pagination_handler.rb +44 -42
- data/lib/praxis/extensions/pagination/pagination_params.rb +29 -48
- data/lib/praxis/extensions/pagination/sequel_pagination_handler.rb +8 -7
- data/lib/praxis/extensions/pagination.rb +10 -15
- data/lib/praxis/extensions/rails_compat/request_methods.rb +3 -4
- data/lib/praxis/extensions/rails_compat.rb +2 -0
- data/lib/praxis/extensions/rendering.rb +12 -12
- data/lib/praxis/field_expander.rb +8 -9
- data/lib/praxis/file_group.rb +8 -12
- data/lib/praxis/finalizable.rb +1 -0
- data/lib/praxis/handlers/json.rb +5 -2
- data/lib/praxis/handlers/plain.rb +2 -1
- data/lib/praxis/handlers/www_form.rb +6 -3
- data/lib/praxis/handlers/{xml-sample.rb → xml_sample.rb} +26 -22
- data/lib/praxis/mapper/active_model_compat.rb +13 -10
- data/lib/praxis/mapper/resource.rb +196 -181
- data/lib/praxis/mapper/selector_generator.rb +106 -112
- data/lib/praxis/mapper/sequel_compat.rb +70 -67
- data/lib/praxis/media_type.rb +2 -2
- data/lib/praxis/media_type_identifier.rb +26 -22
- data/lib/praxis/middleware_app.rb +18 -15
- data/lib/praxis/multipart/parser.rb +46 -51
- data/lib/praxis/multipart/part.rb +78 -110
- data/lib/praxis/notifications.rb +2 -4
- data/lib/praxis/plugin.rb +11 -18
- data/lib/praxis/plugin_concern.rb +12 -15
- data/lib/praxis/plugins/mapper_plugin.rb +15 -13
- data/lib/praxis/plugins/pagination_plugin.rb +8 -6
- data/lib/praxis/plugins/rails_plugin.rb +33 -28
- data/lib/praxis/renderer.rb +11 -15
- data/lib/praxis/request.rb +48 -44
- data/lib/praxis/request_stages/action.rb +4 -6
- data/lib/praxis/request_stages/load_request.rb +2 -4
- data/lib/praxis/request_stages/request_stage.rb +19 -23
- data/lib/praxis/request_stages/response.rb +4 -6
- data/lib/praxis/request_stages/validate.rb +3 -5
- data/lib/praxis/request_stages/validate_params_and_headers.rb +15 -22
- data/lib/praxis/request_stages/validate_payload.rb +25 -28
- data/lib/praxis/request_superclassing.rb +3 -3
- data/lib/praxis/resource_definition.rb +1 -0
- data/lib/praxis/response.rb +24 -26
- data/lib/praxis/response_definition.rb +77 -122
- data/lib/praxis/response_template.rb +11 -15
- data/lib/praxis/responses/http.rb +23 -44
- data/lib/praxis/responses/internal_server_error.rb +18 -21
- data/lib/praxis/responses/multipart_ok.rb +4 -9
- data/lib/praxis/responses/validation_error.rb +8 -15
- data/lib/praxis/route.rb +8 -10
- data/lib/praxis/router/rack.rb +13 -7
- data/lib/praxis/router/simple.rb +10 -5
- data/lib/praxis/router.rb +27 -34
- data/lib/praxis/routing_config.rb +52 -29
- data/lib/praxis/simple_media_type.rb +5 -8
- data/lib/praxis/stage.rb +17 -25
- data/lib/praxis/tasks/api_docs.rb +17 -16
- data/lib/praxis/tasks/console.rb +3 -1
- data/lib/praxis/tasks/environment.rb +2 -0
- data/lib/praxis/tasks/routes.rb +26 -24
- data/lib/praxis/tasks.rb +3 -1
- data/lib/praxis/trait.rb +37 -46
- data/lib/praxis/types/fuzzy_hash.rb +13 -14
- data/lib/praxis/types/media_type_common.rb +11 -10
- data/lib/praxis/types/multipart_array/part_definition.rb +14 -17
- data/lib/praxis/types/multipart_array.rb +100 -115
- data/lib/praxis/validation_handler.rb +5 -3
- data/lib/praxis/version.rb +3 -1
- data/lib/praxis.rb +4 -5
- data/praxis.gemspec +22 -21
- data/spec/functional_spec.rb +44 -56
- data/spec/praxis/action_definition_spec.rb +39 -48
- data/spec/praxis/api_definition_spec.rb +45 -47
- data/spec/praxis/api_general_info_spec.rb +28 -29
- data/spec/praxis/application_spec.rb +18 -14
- data/spec/praxis/blueprint_spec.rb +33 -34
- data/spec/praxis/bootloader_spec.rb +32 -30
- data/spec/praxis/callbacks_spec.rb +37 -37
- data/spec/praxis/collection_spec.rb +18 -25
- data/spec/praxis/config_hash_spec.rb +5 -4
- data/spec/praxis/config_spec.rb +27 -26
- data/spec/praxis/controller_spec.rb +8 -9
- data/spec/praxis/endpoint_definition_spec.rb +25 -32
- data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +171 -114
- data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +22 -21
- data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +112 -60
- data/spec/praxis/extensions/attribute_filtering/filters_parser_spec.rb +37 -38
- data/spec/praxis/extensions/field_expansion_spec.rb +8 -10
- data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +14 -13
- data/spec/praxis/extensions/field_selection/field_selector_spec.rb +9 -16
- data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +50 -49
- data/spec/praxis/extensions/pagination/active_record_pagination_handler_spec.rb +32 -31
- data/spec/praxis/extensions/rendering_spec.rb +9 -9
- data/spec/praxis/extensions/support/spec_resources_active_model.rb +32 -49
- data/spec/praxis/extensions/support/spec_resources_sequel.rb +48 -48
- data/spec/praxis/field_expander_spec.rb +6 -5
- data/spec/praxis/file_group_spec.rb +3 -1
- data/spec/praxis/handlers/json_spec.rb +6 -5
- data/spec/praxis/mapper/resource_spec.rb +39 -29
- data/spec/praxis/mapper/selector_generator_spec.rb +80 -46
- data/spec/praxis/media_type_identifier_spec.rb +13 -10
- data/spec/praxis/media_type_spec.rb +12 -12
- data/spec/praxis/middleware_app_spec.rb +23 -22
- data/spec/praxis/multipart/parser_spec.rb +7 -9
- data/spec/praxis/notifications_spec.rb +4 -4
- data/spec/praxis/plugin_concern_spec.rb +5 -6
- data/spec/praxis/renderer_spec.rb +10 -9
- data/spec/praxis/request_spec.rb +38 -41
- data/spec/praxis/request_stages/action_spec.rb +14 -15
- data/spec/praxis/request_stages/request_stage_spec.rb +30 -41
- data/spec/praxis/request_stages/validate_spec.rb +3 -1
- data/spec/praxis/response_definition_spec.rb +79 -92
- data/spec/praxis/response_spec.rb +35 -40
- data/spec/praxis/responses/internal_server_error_spec.rb +6 -9
- data/spec/praxis/responses/validation_error_spec.rb +17 -18
- data/spec/praxis/route_spec.rb +4 -7
- data/spec/praxis/router_spec.rb +69 -79
- data/spec/praxis/routing_config_spec.rb +15 -14
- data/spec/praxis/stage_spec.rb +56 -53
- data/spec/praxis/trait_spec.rb +17 -17
- data/spec/praxis/types/fuzzy_hash_spec.rb +11 -9
- data/spec/praxis/types/multipart_array/part_definition_spec.rb +3 -2
- data/spec/praxis/types/multipart_array_spec.rb +33 -48
- data/spec/spec_app/app/concerns/authenticated.rb +5 -5
- data/spec/spec_app/app/concerns/basic_api.rb +3 -1
- data/spec/spec_app/app/concerns/log_wrapper.rb +5 -3
- data/spec/spec_app/app/controllers/base_class.rb +6 -5
- data/spec/spec_app/app/controllers/instances.rb +31 -34
- data/spec/spec_app/app/controllers/volumes.rb +6 -6
- data/spec/spec_app/app/responses/multipart.rb +1 -2
- data/spec/spec_app/app/responses/other_response.rb +2 -2
- data/spec/spec_app/config/environment.rb +19 -6
- data/spec/spec_app/config.ru +4 -3
- data/spec/spec_app/design/api.rb +13 -15
- data/spec/spec_app/design/media_types/instance.rb +6 -6
- data/spec/spec_app/design/media_types/volume.rb +2 -1
- data/spec/spec_app/design/media_types/volume_snapshot.rb +2 -1
- data/spec/spec_app/design/resources/instances.rb +11 -17
- data/spec/spec_app/design/resources/volume_snapshots.rb +4 -5
- data/spec/spec_app/design/resources/volumes.rb +4 -5
- data/spec/spec_helper.rb +11 -13
- data/spec/support/be_deep_equal_matcher.rb +5 -0
- data/spec/support/spec_authorization_plugin.rb +7 -12
- data/spec/support/spec_blueprints.rb +5 -4
- data/spec/support/spec_complex_authentication_plugin.rb +17 -34
- data/spec/support/spec_endpoint_definitions.rb +2 -3
- data/spec/support/spec_media_types.rb +28 -35
- data/spec/support/spec_resources.rb +22 -16
- data/spec/support/spec_simple_authentication_plugin.rb +5 -9
- data/tasks/loader.thor +4 -2
- data/tasks/thor/app.rb +7 -5
- data/tasks/thor/example.rb +23 -22
- data/tasks/thor/model.rb +7 -7
- data/tasks/thor/scaffold.rb +23 -23
- data/tasks/thor/templates/generator/example_app/app/v1/resources/user.rb +0 -8
- data/tasks/thor/templates/generator/scaffold/implementation/resources/item.rb +1 -2
- metadata +72 -84
- data/MAINTAINERS +0 -2
- data/TODO.md +0 -25
- data/spec/praxis/api_resource_spec.rb +0 -0
- data/spec/praxis/dispatcher_spec.rb +0 -0
- data/spec/spec_app/app/responses/bulk_response.rb +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_support/concern'
|
|
2
4
|
require 'active_support/inflector'
|
|
3
5
|
|
|
@@ -8,21 +10,21 @@ module Praxis
|
|
|
8
10
|
DEFAULT_RESOURCE_HREF_ACTION = :show
|
|
9
11
|
|
|
10
12
|
included do
|
|
11
|
-
@version = 'n/a'
|
|
12
|
-
@actions =
|
|
13
|
-
@responses =
|
|
13
|
+
@version = 'n/a'
|
|
14
|
+
@actions = {}
|
|
15
|
+
@responses = {}
|
|
14
16
|
|
|
15
|
-
@action_defaults = Trait.new
|
|
17
|
+
@action_defaults = Trait.new(&EndpointDefinition.generate_defaults_block)
|
|
16
18
|
|
|
17
19
|
@version_options = {}
|
|
18
20
|
@metadata = {}
|
|
19
21
|
@traits = []
|
|
20
22
|
|
|
21
|
-
if
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
@prefix = if name
|
|
24
|
+
"/#{name.split('::').last.underscore}"
|
|
25
|
+
else
|
|
26
|
+
'/'
|
|
27
|
+
end
|
|
26
28
|
|
|
27
29
|
@version_prefix = ''
|
|
28
30
|
|
|
@@ -31,21 +33,20 @@ module Praxis
|
|
|
31
33
|
|
|
32
34
|
@routing_prefix = nil
|
|
33
35
|
|
|
34
|
-
@on_finalize =
|
|
36
|
+
@on_finalize = []
|
|
35
37
|
|
|
36
38
|
Application.instance.endpoint_definitions << self
|
|
37
39
|
end
|
|
38
40
|
|
|
39
|
-
def self.generate_defaults_block(
|
|
40
|
-
|
|
41
|
+
def self.generate_defaults_block(version: nil)
|
|
41
42
|
# Ensure we inherit any base params defined in the API definition for the passed in version
|
|
42
43
|
base_attributes = if (base_params = ApiDefinition.instance.info(version).base_params)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
base_params.attributes
|
|
45
|
+
else
|
|
46
|
+
{}
|
|
47
|
+
end
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
proc do
|
|
49
50
|
unless base_attributes.empty?
|
|
50
51
|
params do
|
|
51
52
|
base_attributes.each do |base_name, base_attribute|
|
|
@@ -64,15 +65,8 @@ module Praxis
|
|
|
64
65
|
end
|
|
65
66
|
end
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
68
|
module ClassMethods
|
|
70
|
-
attr_reader :actions
|
|
71
|
-
attr_reader :responses
|
|
72
|
-
attr_reader :version_options
|
|
73
|
-
attr_reader :traits
|
|
74
|
-
attr_reader :version_prefix
|
|
75
|
-
attr_reader :parent_prefix
|
|
69
|
+
attr_reader :actions, :responses, :version_options, :traits, :version_prefix, :parent_prefix
|
|
76
70
|
|
|
77
71
|
# opaque hash of user-defined medata, used to decorate the definition,
|
|
78
72
|
# and also available in the generated JSON documents
|
|
@@ -80,38 +74,35 @@ module Praxis
|
|
|
80
74
|
|
|
81
75
|
attr_accessor :controller
|
|
82
76
|
|
|
83
|
-
def display_name(
|
|
77
|
+
def display_name(string = nil)
|
|
84
78
|
unless string
|
|
85
|
-
return
|
|
79
|
+
return @display_name ||= name.split('::').last # Best guess at a display name?
|
|
86
80
|
end
|
|
81
|
+
|
|
87
82
|
@display_name = string
|
|
88
83
|
end
|
|
89
84
|
|
|
90
85
|
def on_finalize(&block)
|
|
91
|
-
if block_given?
|
|
92
|
-
@on_finalize << proc(&block)
|
|
93
|
-
end
|
|
86
|
+
@on_finalize << proc(&block) if block_given?
|
|
94
87
|
|
|
95
88
|
@on_finalize
|
|
96
89
|
end
|
|
97
90
|
|
|
98
|
-
def prefix(prefix=nil)
|
|
91
|
+
def prefix(prefix = nil)
|
|
99
92
|
return @prefix if prefix.nil?
|
|
93
|
+
|
|
100
94
|
@routing_prefix = nil # reset routing_prefix
|
|
101
95
|
@prefix = prefix
|
|
102
96
|
end
|
|
103
97
|
|
|
104
|
-
def media_type(media_type=nil)
|
|
98
|
+
def media_type(media_type = nil)
|
|
105
99
|
return @media_type if media_type.nil?
|
|
106
100
|
|
|
107
|
-
if media_type.
|
|
108
|
-
media_type = SimpleMediaType.new(media_type)
|
|
109
|
-
end
|
|
101
|
+
media_type = SimpleMediaType.new(media_type) if media_type.is_a?(String)
|
|
110
102
|
@media_type = media_type
|
|
111
103
|
end
|
|
112
104
|
|
|
113
|
-
|
|
114
|
-
def parent(parent=nil, **mapping)
|
|
105
|
+
def parent(parent = nil, **mapping)
|
|
115
106
|
return @parent if parent.nil?
|
|
116
107
|
|
|
117
108
|
@routing_prefix = nil # reset routing_prefix
|
|
@@ -139,24 +130,24 @@ module Praxis
|
|
|
139
130
|
param = mapping[name]
|
|
140
131
|
# FIXME: this won't handle URI Template type paths, ie '/{parent_id}'
|
|
141
132
|
prefixed_path = parent_action.route.prefixed_path
|
|
142
|
-
@parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param
|
|
133
|
+
@parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param}\\3")
|
|
143
134
|
else
|
|
144
135
|
mapping[name] = name
|
|
145
136
|
end
|
|
146
137
|
end
|
|
147
138
|
|
|
148
|
-
|
|
149
|
-
|
|
139
|
+
on_finalize do
|
|
140
|
+
inherit_params_from_parent(parent_action, **mapping)
|
|
150
141
|
end
|
|
151
142
|
|
|
152
143
|
@parent = parent
|
|
153
144
|
end
|
|
154
145
|
|
|
155
146
|
def inherit_params_from_parent(parent_action, **mapping)
|
|
156
|
-
actions.each do |
|
|
147
|
+
actions.each do |_name, action|
|
|
157
148
|
action.params do
|
|
158
149
|
mapping.each do |parent_name, name|
|
|
159
|
-
next if action.params
|
|
150
|
+
next if action.params&.attributes&.key?(name)
|
|
160
151
|
|
|
161
152
|
parent_attribute = parent_action.params.attributes[parent_name]
|
|
162
153
|
|
|
@@ -164,7 +155,6 @@ module Praxis
|
|
|
164
155
|
end
|
|
165
156
|
end
|
|
166
157
|
end
|
|
167
|
-
|
|
168
158
|
end
|
|
169
159
|
|
|
170
160
|
attr_writer :routing_prefix
|
|
@@ -175,18 +165,17 @@ module Praxis
|
|
|
175
165
|
@routing_prefix = parent_prefix + prefix
|
|
176
166
|
end
|
|
177
167
|
|
|
178
|
-
|
|
179
|
-
def version(version=nil)
|
|
168
|
+
def version(version = nil)
|
|
180
169
|
return @version unless version
|
|
181
170
|
|
|
182
171
|
@version = version
|
|
183
|
-
@action_defaults.instance_eval
|
|
172
|
+
@action_defaults.instance_eval(&EndpointDefinition.generate_defaults_block(version: version))
|
|
184
173
|
end
|
|
185
174
|
|
|
186
|
-
|
|
187
|
-
def canonical_path(action_name=nil)
|
|
175
|
+
def canonical_path(action_name = nil)
|
|
188
176
|
if action_name
|
|
189
|
-
raise "Canonical path for #{
|
|
177
|
+
raise "Canonical path for #{name} is already defined as: '#{@canonical_action_name}'. 'canonical_path' can only be defined once." if @canonical_action_name
|
|
178
|
+
|
|
190
179
|
@canonical_action_name = action_name
|
|
191
180
|
else
|
|
192
181
|
# Resolution of the actual action definition needs to be done lazily, since we can use the `canonical_path` stanza
|
|
@@ -194,80 +183,74 @@ module Praxis
|
|
|
194
183
|
unless @canonical_action
|
|
195
184
|
href_action = @canonical_action_name || DEFAULT_RESOURCE_HREF_ACTION
|
|
196
185
|
@canonical_action = actions.fetch(href_action) do
|
|
197
|
-
raise "Error: trying to set canonical_href of #{
|
|
186
|
+
raise "Error: trying to set canonical_href of #{name}. Action '#{href_action}' does not exist"
|
|
198
187
|
end
|
|
199
188
|
end
|
|
200
|
-
|
|
189
|
+
@canonical_action
|
|
201
190
|
end
|
|
202
191
|
end
|
|
203
192
|
|
|
204
|
-
def to_href(
|
|
193
|
+
def to_href(params)
|
|
205
194
|
canonical_path.route.path.expand(params.transform_values(&:to_s))
|
|
206
195
|
end
|
|
207
196
|
|
|
208
197
|
def parse_href(path)
|
|
209
|
-
if path.
|
|
210
|
-
path = path.path
|
|
211
|
-
end
|
|
198
|
+
path = path.path if path.is_a?(::URI::Generic)
|
|
212
199
|
param_values = canonical_path.route.path.params(path)
|
|
213
200
|
attrs = canonical_path.params.attributes
|
|
214
|
-
param_values.each_with_object({}) do |(key,value),hash|
|
|
215
|
-
hash[key.to_sym] = attrs[key.to_sym].load(value,[key])
|
|
201
|
+
param_values.each_with_object({}) do |(key, value), hash|
|
|
202
|
+
hash[key.to_sym] = attrs[key.to_sym].load(value, [key])
|
|
216
203
|
end
|
|
217
|
-
rescue => e
|
|
218
|
-
raise Praxis::Exception
|
|
204
|
+
rescue StandardError => e
|
|
205
|
+
raise Praxis::Exception, "Error parsing or coercing parameters from href: #{path}\n" + e.message
|
|
219
206
|
end
|
|
220
207
|
|
|
221
208
|
def trait(trait_name)
|
|
222
|
-
unless ApiDefinition.instance.traits.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
trait = ApiDefinition.instance.traits.fetch(trait_name)
|
|
209
|
+
raise Exceptions::InvalidTrait, "Trait #{trait_name} not found in the system" unless ApiDefinition.instance.traits.key? trait_name
|
|
210
|
+
|
|
211
|
+
# TODO: We're only storing the names here, should we store the actual traits in a hash?
|
|
226
212
|
@traits << trait_name
|
|
227
213
|
end
|
|
228
|
-
|
|
214
|
+
alias use trait
|
|
229
215
|
|
|
230
216
|
def action_defaults(&block)
|
|
231
|
-
if block_given?
|
|
232
|
-
@action_defaults.instance_eval(&block)
|
|
233
|
-
end
|
|
217
|
+
@action_defaults.instance_eval(&block) if block_given?
|
|
234
218
|
|
|
235
219
|
@action_defaults
|
|
236
220
|
end
|
|
237
221
|
|
|
238
222
|
def action(name, &block)
|
|
239
|
-
raise ArgumentError,
|
|
223
|
+
raise ArgumentError, 'can not create ActionDefinition without block' unless block_given?
|
|
240
224
|
raise ArgumentError, "Action names must be defined using symbols (Got: #{name} (of type #{name.class}))" unless name.is_a? Symbol
|
|
225
|
+
|
|
241
226
|
@actions[name] = ActionDefinition.new(name, self, &block)
|
|
242
227
|
end
|
|
243
228
|
|
|
244
|
-
def description(text=nil)
|
|
229
|
+
def description(text = nil)
|
|
245
230
|
@description = text if text
|
|
246
231
|
@description
|
|
247
232
|
end
|
|
248
233
|
|
|
249
234
|
def id
|
|
250
|
-
|
|
235
|
+
name.gsub('::', '-')
|
|
251
236
|
end
|
|
252
237
|
|
|
253
238
|
def describe(context: nil)
|
|
254
239
|
{}.tap do |hash|
|
|
255
240
|
hash[:description] = description
|
|
256
241
|
hash[:media_type] = media_type.describe(true) if media_type
|
|
257
|
-
hash[:actions] = actions.values.collect{|action| action.describe(context: context)}
|
|
258
|
-
hash[:name] =
|
|
259
|
-
hash[:parent] =
|
|
260
|
-
hash[:display_name] =
|
|
242
|
+
hash[:actions] = actions.values.collect { |action| action.describe(context: context) }
|
|
243
|
+
hash[:name] = name
|
|
244
|
+
hash[:parent] = parent.id if parent
|
|
245
|
+
hash[:display_name] = display_name
|
|
261
246
|
hash[:metadata] = metadata
|
|
262
|
-
hash[:traits] =
|
|
247
|
+
hash[:traits] = traits
|
|
263
248
|
end
|
|
264
249
|
end
|
|
265
250
|
|
|
266
251
|
def nodoc!
|
|
267
252
|
metadata[:doc_visibility] = :none
|
|
268
253
|
end
|
|
269
|
-
|
|
270
254
|
end
|
|
271
|
-
|
|
272
255
|
end
|
|
273
256
|
end
|
data/lib/praxis/error_handler.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Praxis
|
|
2
4
|
class ErrorHandler
|
|
3
|
-
|
|
4
5
|
def handle!(request, error)
|
|
5
6
|
Application.instance.logger.error error.inspect
|
|
6
7
|
error.backtrace.each do |line|
|
|
@@ -11,6 +12,5 @@ module Praxis
|
|
|
11
12
|
response.request = request
|
|
12
13
|
response.finish
|
|
13
14
|
end
|
|
14
|
-
|
|
15
15
|
end
|
|
16
16
|
end
|
data/lib/praxis/exception.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Praxis
|
|
2
4
|
module Exceptions
|
|
3
|
-
class Validation <
|
|
4
|
-
|
|
5
|
+
class Validation < RuntimeError
|
|
5
6
|
attr_accessor :errors
|
|
7
|
+
|
|
6
8
|
def initialize(message, errors: nil)
|
|
7
9
|
super(message)
|
|
8
10
|
@errors = errors
|
|
9
11
|
end
|
|
10
|
-
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
end
|