praxis 2.0.pre.5 → 2.0.pre.6
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 +5 -5
- data/.rspec +0 -1
- data/.ruby-version +1 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile +1 -1
- data/Guardfile +2 -1
- data/Rakefile +1 -7
- data/TODO.md +28 -0
- data/lib/api_browser/package-lock.json +7110 -0
- data/lib/praxis.rb +6 -4
- data/lib/praxis/action_definition.rb +9 -16
- data/lib/praxis/application.rb +1 -2
- data/lib/praxis/bootloader_stages/routing.rb +2 -4
- data/lib/praxis/extensions/attribute_filtering.rb +2 -0
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +148 -157
- data/lib/praxis/extensions/attribute_filtering/active_record_patches.rb +15 -0
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/5x.rb +90 -0
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_0.rb +68 -0
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_1_plus.rb +58 -0
- data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +35 -0
- data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +9 -12
- data/lib/praxis/extensions/attribute_filtering/sequel_filter_query_builder.rb +3 -2
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +7 -9
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +6 -9
- data/lib/praxis/extensions/pagination.rb +130 -0
- data/lib/praxis/extensions/pagination/active_record_pagination_handler.rb +42 -0
- data/lib/praxis/extensions/pagination/header_generator.rb +70 -0
- data/lib/praxis/extensions/pagination/ordering_params.rb +234 -0
- data/lib/praxis/extensions/pagination/pagination_handler.rb +68 -0
- data/lib/praxis/extensions/pagination/pagination_params.rb +374 -0
- data/lib/praxis/extensions/pagination/sequel_pagination_handler.rb +45 -0
- data/lib/praxis/handlers/json.rb +2 -0
- data/lib/praxis/handlers/www_form.rb +5 -0
- data/lib/praxis/handlers/{xml.rb → xml-sample.rb} +6 -0
- data/lib/praxis/mapper/active_model_compat.rb +23 -5
- data/lib/praxis/mapper/resource.rb +16 -9
- data/lib/praxis/mapper/sequel_compat.rb +1 -0
- data/lib/praxis/media_type.rb +1 -56
- data/lib/praxis/plugins/mapper_plugin.rb +1 -1
- data/lib/praxis/plugins/pagination_plugin.rb +71 -0
- data/lib/praxis/resource_definition.rb +4 -12
- data/lib/praxis/route.rb +2 -4
- data/lib/praxis/routing_config.rb +4 -8
- data/lib/praxis/tasks/routes.rb +9 -14
- data/lib/praxis/validation_handler.rb +1 -2
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +2 -3
- data/spec/functional_spec.rb +9 -6
- data/spec/praxis/action_definition_spec.rb +4 -16
- data/spec/praxis/api_general_info_spec.rb +6 -6
- data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +304 -0
- data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +39 -0
- data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +34 -0
- data/spec/praxis/extensions/field_expansion_spec.rb +6 -24
- data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +15 -11
- data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +4 -3
- data/spec/praxis/extensions/pagination/active_record_pagination_handler_spec.rb +130 -0
- data/spec/praxis/extensions/{field_selection/support → support}/spec_resources_active_model.rb +45 -2
- data/spec/praxis/extensions/{field_selection/support → support}/spec_resources_sequel.rb +0 -0
- data/spec/praxis/media_type_spec.rb +5 -129
- data/spec/praxis/request_spec.rb +3 -22
- data/spec/praxis/resource_definition_spec.rb +1 -1
- data/spec/praxis/response_definition_spec.rb +1 -5
- data/spec/praxis/route_spec.rb +2 -9
- data/spec/praxis/routing_config_spec.rb +4 -13
- data/spec/praxis/types/multipart_array_spec.rb +4 -21
- data/spec/spec_app/config/environment.rb +0 -2
- data/spec/spec_app/design/api.rb +1 -1
- data/spec/spec_app/design/media_types/instance.rb +0 -8
- data/spec/spec_app/design/media_types/volume.rb +0 -12
- data/spec/spec_app/design/resources/instances.rb +1 -2
- data/spec/spec_helper.rb +6 -0
- data/spec/support/spec_media_types.rb +0 -73
- metadata +35 -45
- data/spec/praxis/handlers/xml_spec.rb +0 -177
- data/spec/praxis/links_spec.rb +0 -68
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative 'pagination_handler'
|
2
|
+
|
3
|
+
module Praxis
|
4
|
+
module Extensions
|
5
|
+
module Pagination
|
6
|
+
class SequelPaginationHandler < PaginationHandler
|
7
|
+
|
8
|
+
def self.where_lt(query, attr, value)
|
9
|
+
query.where("#{attr} < ?", value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.where_gt(query, attr, value)
|
13
|
+
query.where("#{attr} > ?", value)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.order(query, order)
|
17
|
+
return query unless order
|
18
|
+
order_clause = order.map do |spec_hash|
|
19
|
+
direction, name = spec_hash.first
|
20
|
+
case direction.to_sym
|
21
|
+
when :desc
|
22
|
+
Sequel.desc(name.to_sym)
|
23
|
+
else
|
24
|
+
Sequel.asc(name.to_sym)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
query = query.order(*order_clause)
|
28
|
+
query
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.count(query)
|
32
|
+
query.count
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.offset(query, offset)
|
36
|
+
query.offset(offset)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.limit(query, limit)
|
40
|
+
query.limit(limit)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/praxis/handlers/json.rb
CHANGED
@@ -17,6 +17,8 @@ module Praxis
|
|
17
17
|
# @param [String] document
|
18
18
|
# @return [Hash,Array] the structured-data representation of the document
|
19
19
|
def parse(document)
|
20
|
+
# Try to be nice and accept an empty string as an empty payload (seems nice to do for dumb http clients)
|
21
|
+
return nil if (document.nil? || document == '')
|
20
22
|
::JSON.parse(document)
|
21
23
|
end
|
22
24
|
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# This is an example of a handler that can load and generate www-url-encoded payloads.
|
2
|
+
# Note that if you use your API to pass nil values for attributes as a way to unset their
|
3
|
+
# values, this handler will not work (as there isn't necessarily a defined "null" value in
|
4
|
+
# this encoding (although you can probably define how to encode/decode it and use it as such)
|
5
|
+
# Use at your own risk.
|
1
6
|
module Praxis
|
2
7
|
module Handlers
|
3
8
|
class WWWForm
|
@@ -1,3 +1,9 @@
|
|
1
|
+
# This is an example of a handler that can load and generate 'activesupport-style' xml payloads.
|
2
|
+
# Note that if you use your API to pass nil values for attributes as a way to unset their values,
|
3
|
+
# this handler will not work (as there isn't necessarily a defined "null" value in this encoding
|
4
|
+
# (although you can probably define how to encode/decode it and use it as such)
|
5
|
+
# Use at your own risk
|
6
|
+
|
1
7
|
module Praxis
|
2
8
|
module Handlers
|
3
9
|
class XML
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'active_support/concern'
|
4
4
|
|
5
5
|
require 'praxis/extensions/field_selection/active_record_query_selector'
|
6
|
+
require 'praxis/extensions/attribute_filtering/active_record_filter_query_builder'
|
6
7
|
|
7
8
|
module Praxis
|
8
9
|
module Mapper
|
@@ -15,7 +16,7 @@ module Praxis
|
|
15
16
|
|
16
17
|
module ClassMethods
|
17
18
|
def _filter_query_builder_class
|
18
|
-
Praxis::Extensions::ActiveRecordFilterQueryBuilder
|
19
|
+
Praxis::Extensions::AttributeFiltering::ActiveRecordFilterQueryBuilder
|
19
20
|
end
|
20
21
|
|
21
22
|
def _field_selector_query_builder_class
|
@@ -57,19 +58,36 @@ module Praxis
|
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
61
|
+
def _join_foreign_key_for(assoc_reflection)
|
62
|
+
maj, min, _ = ActiveRecord.gem_version.segments
|
63
|
+
if maj >= 6 && min >=1
|
64
|
+
assoc_reflection.join_foreign_key.to_sym
|
65
|
+
else
|
66
|
+
assoc_reflection.join_keys.foreign_key.to_sym
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def _join_primary_key_for(assoc_reflection)
|
71
|
+
maj, min, _ = ActiveRecord.gem_version.segments
|
72
|
+
if maj >= 6 && min >=1
|
73
|
+
assoc_reflection.join_primary_key.to_sym
|
74
|
+
else
|
75
|
+
assoc_reflection.join_keys.key.to_sym
|
76
|
+
end
|
77
|
+
end
|
60
78
|
private
|
61
79
|
def local_columns_used_for_the_association(type, assoc_reflection)
|
62
80
|
case type
|
63
81
|
when :one_to_many
|
64
82
|
# The associated table will point to us by key (usually the PK, but not always)
|
65
|
-
[assoc_reflection
|
83
|
+
[_join_foreign_key_for(assoc_reflection)]
|
66
84
|
when :many_to_one
|
67
85
|
# We have the FKs to the associated model
|
68
|
-
[assoc_reflection
|
86
|
+
[_join_foreign_key_for(assoc_reflection)]
|
69
87
|
when :many_to_many
|
70
88
|
ref = resolve_closest_through_reflection(assoc_reflection)
|
71
89
|
# The associated middle table will point to us by key (usually the PK, but not always)
|
72
|
-
[ref
|
90
|
+
[_join_foreign_key_for(ref)] # The foreign key that the last through table points to
|
73
91
|
else
|
74
92
|
raise "association type #{type} not supported"
|
75
93
|
end
|
@@ -80,7 +98,7 @@ module Praxis
|
|
80
98
|
# will always get us the right column
|
81
99
|
case type
|
82
100
|
when :one_to_many, :many_to_one, :many_to_many
|
83
|
-
[assoc_reflection
|
101
|
+
[_join_primary_key_for(assoc_reflection)]
|
84
102
|
else
|
85
103
|
raise "association type #{type} not supported"
|
86
104
|
end
|
@@ -196,17 +196,24 @@ module Praxis::Mapper
|
|
196
196
|
end
|
197
197
|
|
198
198
|
# TODO: this shouldn't be needed if we incorporate it with the properties of the mapper...
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
199
|
+
# ...maybe what this means is that we can change it for a better DSL in the resource?
|
200
|
+
def self.filters_mapping(definition)
|
201
|
+
@_filters_map = \
|
202
|
+
case definition
|
203
|
+
when Hash
|
204
|
+
definition
|
205
|
+
when Array
|
206
|
+
definition.each_with_object({}) { |item, hash| hash[item.to_sym] = item }
|
207
|
+
else
|
208
|
+
raise "Resource.filters_mapping only allows a hash or an array"
|
209
|
+
end
|
205
210
|
end
|
206
211
|
|
207
212
|
def self.craft_filter_query(base_query, filters:) # rubocop:disable Metrics/AbcSize
|
208
|
-
if filters
|
209
|
-
|
213
|
+
if filters
|
214
|
+
raise "Must define the mapping of filters if want to use Filtering for resource: #{self}" unless @_filters_map
|
215
|
+
debug = Praxis::Application.instance.config.mapper.debug_queries
|
216
|
+
base_query = model._filter_query_builder_class.new(query: base_query, model: model, filters_map: @_filters_map, debug: debug).generate(filters)
|
210
217
|
end
|
211
218
|
|
212
219
|
base_query
|
@@ -215,7 +222,7 @@ module Praxis::Mapper
|
|
215
222
|
def self.craft_field_selection_query(base_query, selectors:) # rubocop:disable Metrics/AbcSize
|
216
223
|
if selectors && model._field_selector_query_builder_class
|
217
224
|
debug = Praxis::Application.instance.config.mapper.debug_queries
|
218
|
-
base_query = model._field_selector_query_builder_class.new(query: base_query, selectors: selectors
|
225
|
+
base_query = model._field_selector_query_builder_class.new(query: base_query, selectors: selectors, debug: debug).generate
|
219
226
|
end
|
220
227
|
|
221
228
|
base_query
|
data/lib/praxis/media_type.rb
CHANGED
@@ -7,15 +7,12 @@ module Praxis
|
|
7
7
|
# encodings; for example, a controller might respond with an actual Widget object, but a
|
8
8
|
# Content-Type header specifying 'application/vnd.acme.widget+json'; Praxis uses the information
|
9
9
|
# contained in the media-type definition of Widget to transform the object into an equivalent
|
10
|
-
# JSON representation.
|
11
|
-
# registered with the framework, Praxis will respond with an XML representation of the
|
12
|
-
# widget. The use of media types allows your application's models to be decoupled from its
|
10
|
+
# JSON representation. The use of media types allows your application's models to be decoupled from its
|
13
11
|
# HTTP interface specification.
|
14
12
|
#
|
15
13
|
# A media type definition consists of:
|
16
14
|
# - a MIME type identifier
|
17
15
|
# - attributes, each of which has a name and a data type
|
18
|
-
# - named links to other resources
|
19
16
|
# - named views, which expose interesting subsets of attributes
|
20
17
|
#
|
21
18
|
# @example Declare a widget type that's used by my supply-chain management app
|
@@ -37,16 +34,6 @@ module Praxis
|
|
37
34
|
# description: 'The factory in which this widget was produced'
|
38
35
|
# end
|
39
36
|
#
|
40
|
-
# links do
|
41
|
-
# link :factory,
|
42
|
-
# description: 'Link to the factory in which this widget was produced'
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# # If widgets can be linked-to by other resources, they should have a link view
|
46
|
-
# view :link do
|
47
|
-
# attribute :href
|
48
|
-
# end
|
49
|
-
#
|
50
37
|
# # All resources should have a default view
|
51
38
|
# view :default do
|
52
39
|
# attribute :id
|
@@ -58,32 +45,6 @@ module Praxis
|
|
58
45
|
|
59
46
|
include Types::MediaTypeCommon
|
60
47
|
|
61
|
-
class DSLCompiler < Attributor::HashDSLCompiler
|
62
|
-
def links(&block)
|
63
|
-
attribute :links, Praxis::Links.for(options[:reference]), dsl_compiler: Links::DSLCompiler, &block
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.attributes(opts={}, &block)
|
68
|
-
super(opts.merge(dsl_compiler: MediaType::DSLCompiler), &block)
|
69
|
-
end
|
70
|
-
|
71
|
-
def self._finalize!
|
72
|
-
super
|
73
|
-
|
74
|
-
# Only define our special links accessor if it was setup using the special DSL
|
75
|
-
# (we might have an app defining an attribute called `links` on its own, in which
|
76
|
-
# case we leave it be)
|
77
|
-
if @attribute && self.attributes.key?(:links) && self.attributes[:links].type < Praxis::Links
|
78
|
-
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
79
|
-
def links
|
80
|
-
self.class::Links.new(@object)
|
81
|
-
end
|
82
|
-
RUBY
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
48
|
class FieldResolver
|
88
49
|
def self.resolve(type,fields)
|
89
50
|
self.new.resolve(type,fields)
|
@@ -118,30 +79,14 @@ module Praxis
|
|
118
79
|
|
119
80
|
|
120
81
|
fields.each do |name, sub_fields|
|
121
|
-
# skip links and do them below
|
122
|
-
next if name == :links && defined?(type::Links)
|
123
82
|
|
124
83
|
new_type = type.attributes[name].type
|
125
84
|
result[name] = resolve(new_type, sub_fields)
|
126
85
|
end
|
127
86
|
|
128
|
-
# now to tackle whatever links there may be
|
129
|
-
if defined?(type::Links) &&(links_fields = fields[:links])
|
130
|
-
resolved_links = resolve_links(type::Links, links_fields)
|
131
|
-
self.deep_merge(result, resolved_links)
|
132
|
-
end
|
133
|
-
|
134
87
|
result
|
135
88
|
end
|
136
89
|
|
137
|
-
def resolve_links(links_type, links)
|
138
|
-
links.each_with_object({}) do |(name, link_fields), hash|
|
139
|
-
using = links_type.links[name]
|
140
|
-
new_type = links_type.attributes[name].type
|
141
|
-
hash[using] = resolve(new_type, link_fields)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
90
|
# perform a deep recursive *in place* merge
|
146
91
|
# form all values in +source+ onto +target+
|
147
92
|
#
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'praxis/extensions/pagination'
|
3
|
+
|
4
|
+
# Simple plugin concept
|
5
|
+
# Example configuration for this plugin
|
6
|
+
# Praxis::Application.configure do |application|
|
7
|
+
# application.bootloader.use Praxis::Plugins::PaginationPlugin, {
|
8
|
+
# max_items: 500, # Unlimited by default,
|
9
|
+
# default_page_size: 100,
|
10
|
+
# disallow_paging_by_default: false,
|
11
|
+
# # See all available options below
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# This would be applied to all controllers etc...so if one does not that
|
16
|
+
# It can easily add the `include Praxis::Extensions::Pagination` for every controller
|
17
|
+
# and use the class `Praxis::Types::PaginationParams.xxx yyy` stanzas to configure defaults
|
18
|
+
|
19
|
+
module Praxis
|
20
|
+
module Plugins
|
21
|
+
module PaginationPlugin
|
22
|
+
include Praxis::PluginConcern
|
23
|
+
|
24
|
+
class Plugin < Praxis::Plugin
|
25
|
+
include Singleton
|
26
|
+
|
27
|
+
def config_key
|
28
|
+
:pagination
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_config!
|
32
|
+
@options || {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def prepare_config!(node)
|
36
|
+
node.attributes do
|
37
|
+
attribute :max_items, Integer # Defaults to unlimited
|
38
|
+
attribute :default_page_size, Integer, default: Praxis::Types::PaginationParams.default_page_size
|
39
|
+
attribute :paging_default_mode, Hash, default: Praxis::Types::PaginationParams.paging_default_mode
|
40
|
+
attribute :disallow_paging_by_default, Attributor::Boolean, default: Praxis::Types::PaginationParams.disallow_paging_by_default
|
41
|
+
attribute :disallow_cursor_by_default, Attributor::Boolean, default: Praxis::Types::PaginationParams.disallow_cursor_by_default
|
42
|
+
attribute :disallow_cursor_by_default, Attributor::Boolean, default: Praxis::Types::PaginationParams.disallow_cursor_by_default
|
43
|
+
attribute :sorting do
|
44
|
+
attribute :enforce_all_fields, Attributor::Boolean, default: Praxis::Types::OrderingParams.enforce_all_fields
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup!
|
50
|
+
self.config.each do |name, val|
|
51
|
+
if name == :sorting
|
52
|
+
val.each do |ordername, orderval|
|
53
|
+
Praxis::Types::OrderingParams.send(ordername, orderval)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
Praxis::Types::PaginationParams.send(name, val)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module Controller
|
63
|
+
extend ActiveSupport::Concern
|
64
|
+
|
65
|
+
included do
|
66
|
+
include Praxis::Extensions::Pagination
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -95,14 +95,6 @@ module Praxis
|
|
95
95
|
@on_finalize
|
96
96
|
end
|
97
97
|
|
98
|
-
# FIXME: this is inconsistent with the rest of the magic DSL convention.
|
99
|
-
def routing(&block)
|
100
|
-
warn "DEPRECATED: ResourceDefinition.routing is deprecated use prefix directly instead."
|
101
|
-
|
102
|
-
# eval this assuming it will only call #prefix
|
103
|
-
self.instance_eval(&block)
|
104
|
-
end
|
105
|
-
|
106
98
|
def prefix(prefix=nil)
|
107
99
|
return @prefix if prefix.nil?
|
108
100
|
@routing_prefix = nil # reset routing_prefix
|
@@ -125,7 +117,7 @@ module Praxis
|
|
125
117
|
@routing_prefix = nil # reset routing_prefix
|
126
118
|
|
127
119
|
parent_action = parent.canonical_path
|
128
|
-
parent_route = parent_action.
|
120
|
+
parent_route = parent_action.route.path
|
129
121
|
|
130
122
|
# if a mapping is passed, it *must* resolve any param name conflicts
|
131
123
|
unless mapping.any?
|
@@ -146,7 +138,7 @@ module Praxis
|
|
146
138
|
if mapping.key?(name)
|
147
139
|
param = mapping[name]
|
148
140
|
# FIXME: this won't handle URI Template type paths, ie '/{parent_id}'
|
149
|
-
prefixed_path = parent_action.
|
141
|
+
prefixed_path = parent_action.route.prefixed_path
|
150
142
|
@parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param.to_s}\\3")
|
151
143
|
else
|
152
144
|
mapping[name] = name
|
@@ -221,14 +213,14 @@ module Praxis
|
|
221
213
|
end
|
222
214
|
|
223
215
|
def to_href( params )
|
224
|
-
canonical_path.
|
216
|
+
canonical_path.route.path.expand(params)
|
225
217
|
end
|
226
218
|
|
227
219
|
def parse_href(path)
|
228
220
|
if path.kind_of?(::URI::Generic)
|
229
221
|
path = path.path
|
230
222
|
end
|
231
|
-
param_values = canonical_path.
|
223
|
+
param_values = canonical_path.route.path.params(path)
|
232
224
|
attrs = canonical_path.params.attributes
|
233
225
|
param_values.each_with_object({}) do |(key,value),hash|
|
234
226
|
hash[key.to_sym] = attrs[key.to_sym].load(value,[key])
|
data/lib/praxis/route.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Praxis
|
2
2
|
|
3
3
|
class Route
|
4
|
-
attr_accessor :verb, :path, :version, :
|
4
|
+
attr_accessor :verb, :path, :version, :prefixed_path, :options
|
5
5
|
|
6
|
-
def initialize(verb, path, version='n/a',
|
6
|
+
def initialize(verb, path, version='n/a', prefixed_path:nil, **options)
|
7
7
|
@verb = verb
|
8
8
|
@path = path
|
9
9
|
@version = version
|
10
|
-
@name = name
|
11
10
|
@options = options
|
12
11
|
@prefixed_path = prefixed_path
|
13
12
|
end
|
@@ -34,7 +33,6 @@ module Praxis
|
|
34
33
|
path: path.to_s,
|
35
34
|
version: version
|
36
35
|
}
|
37
|
-
result[:name] = name unless name.nil?
|
38
36
|
result[:options] = options if options.any?
|
39
37
|
result
|
40
38
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Praxis
|
2
2
|
class RoutingConfig
|
3
3
|
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :route
|
5
5
|
attr_reader :version
|
6
6
|
attr_reader :base
|
7
7
|
|
@@ -10,7 +10,7 @@ module Praxis
|
|
10
10
|
@base = base
|
11
11
|
@prefix_segments = Array(prefix)
|
12
12
|
|
13
|
-
@
|
13
|
+
@route = nil
|
14
14
|
|
15
15
|
if block_given?
|
16
16
|
instance_eval(&block)
|
@@ -53,12 +53,8 @@ module Praxis
|
|
53
53
|
end
|
54
54
|
prefixed_path = path.gsub('//','/')
|
55
55
|
path = (base + path).gsub('//','/')
|
56
|
-
|
57
|
-
|
58
|
-
pattern = Mustermann.new(path, **{ignore_unknown_options: true}.merge( options ))
|
59
|
-
route = Route.new(verb, pattern, version, name: route_name, prefixed_path: prefixed_path, **options)
|
60
|
-
@routes << route
|
61
|
-
route
|
56
|
+
pattern = Mustermann.new(path, {ignore_unknown_options: true}.merge( options ))
|
57
|
+
@route = Route.new(verb, pattern, version, prefixed_path: prefixed_path, **options)
|
62
58
|
end
|
63
59
|
|
64
60
|
end
|