salestation 0.13.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bceb665efc56da15d2a5ef0523bb99b6d54ee68abf99530262f4c6c90bbd345f
4
- data.tar.gz: 2c8257fe1fb5c5f851c4c11d832517b3eafe4223ea225cd2aad30bf030de8557
3
+ metadata.gz: c129ac9a73dc7d09bf7fdc7b4511b6eeb34283887d83e950233cd44f13248792
4
+ data.tar.gz: 86cad63b60207ce1f73a4752af80f9d55cb01ee3c535ac4990ab1a0250470cf1
5
5
  SHA512:
6
- metadata.gz: 67853444ea1fa18ea9c0e57d4088435de7a5b36319cd2a0cf865207450d997af66065765fa2b500845400b5def00a4a485fd2a2d73dd45391f60cd459d0fb4da
7
- data.tar.gz: 7d6f38b300d2edcb25f23cabeecc3f5c9ac63f69da7174e6119bf37c3407d4bf62d2a67c01e974c6d542c9d5ab62981639556e3bc5a7142f2aca3c107178fabc
6
+ metadata.gz: 38ccd7f281a2a86ba758ad9b306986ce93b08b55fda317670b06cf33e4dfce6cadb97a57962ca638f071d9bcc86f995da8519586b4541ff0ad14264f09edb6a7
7
+ data.tar.gz: e7d668a2e2f4ef5d245a46d8b70a89798b98fdd1ff969fe4a1a925c3e0c8bdebd6fd72a9964fddf01a3b77f76fe7fa44c468e3ab0f139d3e1a96a8af4f75199b
data/README.md CHANGED
@@ -96,11 +96,10 @@ def create_app_request
96
96
  end
97
97
 
98
98
  post '/hello/:name' do |name|
99
- coercions = {age: ->(age) { age.to_s }}
100
-
101
- extractor = BodyParamExtractor[:age, coercions: coercions]
99
+ extractor = BodyParamExtractor[:age]
102
100
  .merge(ConstantInput[name: name])
103
101
  .merge(HeadersExtractor[{'authorization' => :auth}])
102
+ .coerce(age: ->(age) { age.to_s })
104
103
 
105
104
  response = extractor.call(request)
106
105
  .map(create_app_request)
@@ -15,6 +15,10 @@ module Salestation
15
15
  def merge(other)
16
16
  CombinedInputExtractor.new([self, other])
17
17
  end
18
+
19
+ def coerce(rules)
20
+ InputCoercer.new(self, rules)
21
+ end
18
22
  end
19
23
 
20
24
  class CombinedInputExtractor
@@ -41,6 +45,41 @@ module Salestation
41
45
  def merge(other_extractor)
42
46
  CombinedInputExtractor.new(@extractors + [other_extractor])
43
47
  end
48
+
49
+ def coerce(rules)
50
+ InputCoercer.new(self, rules)
51
+ end
52
+ end
53
+
54
+ # Handles coercing input values
55
+ #
56
+ # @example
57
+ # extractor = BodyParamExtractor[:x, :y]
58
+ # .coerce(x: ->(value) { "x_#{value}"})
59
+ # input = {
60
+ # 'x' => 'a',
61
+ # 'y' => 'b',
62
+ # }
63
+ # # rack_request is Rack::Request with 'rack.request.form_hash' set to input
64
+ # extractor.call(rack_request).value #=> {x: 'x_a', y: 'b'}
65
+ class InputCoercer
66
+ def initialize(extractor, rules)
67
+ @extractor = extractor
68
+ @rules = rules
69
+ end
70
+
71
+ def call(rack_request)
72
+ @extractor
73
+ .call(rack_request)
74
+ .map(&method(:coerce))
75
+ end
76
+
77
+ def coerce(input)
78
+ @rules.each do |field, coercer|
79
+ input[field] = coercer.call(@rules[field]) if input.key?(field)
80
+ end
81
+ Deterministic::Result::Success(input)
82
+ end
44
83
  end
45
84
 
46
85
  class HeadersExtractor
@@ -64,30 +103,53 @@ module Salestation
64
103
  class ParamExtractor
65
104
  include Deterministic
66
105
 
67
- def self.[](*keys, coercions: {}, rack_key:)
106
+ def self.[](filters:, rack_key:)
68
107
  InputExtractor.new do |rack_request|
69
108
  request_hash = rack_request.env[rack_key] || {}
70
-
71
- input = keys
72
- .select { |key| request_hash.key?(key.to_s) }
73
- .map { |key| [key, request_hash[key.to_s]] }
74
- .map { |key, value| coercions.key?(key) ? [key, coercions[key].call(value)] : [key, value] }
75
- .to_h
76
-
109
+ input = extract(filters, request_hash)
77
110
  Result::Success(input)
78
111
  end
79
112
  end
113
+
114
+ def self.extract(filters, request_hash)
115
+ filters.each_with_object({}) do |filter, extracted_data|
116
+ case filter
117
+ when Symbol
118
+ stringified_key = filter.to_s
119
+ extracted_data[filter] = request_hash[stringified_key] if request_hash.key?(stringified_key)
120
+ when Hash
121
+ filter.each do |key, nested_filters|
122
+ extracted_data[key] = extract(nested_filters, request_hash[key.to_s])
123
+ end
124
+ end
125
+ end
126
+ end
80
127
  end
81
128
 
82
129
  class QueryParamExtractor
83
- def self.[](*keys, coercions: {})
84
- ParamExtractor[*keys, coercions: coercions, rack_key: 'rack.request.query_hash']
130
+ def self.[](*filters)
131
+ ParamExtractor[filters: filters, rack_key: 'rack.request.query_hash']
85
132
  end
86
133
  end
87
134
 
135
+ # Extracts and symbolizes params from request body
136
+ #
137
+ # @example
138
+ # extractor = BodyParamExtractor[:x, :y, {foo: [:bar, :baz]}]
139
+ # input = {
140
+ # 'x' => '1',
141
+ # 'y' => '2',
142
+ # 'z' => '3',
143
+ # 'foo' => {
144
+ # 'bar' => 'qq'
145
+ # }
146
+ # }
147
+ # # rack_request is Rack::Request with 'rack.request.form_hash' set to input
148
+ # extractor.call(rack_request).value #=> {x: 1, y: 2, foo: {bar: 'qq}}
149
+ #
88
150
  class BodyParamExtractor
89
- def self.[](*keys, coercions: {})
90
- ParamExtractor[*keys, coercions: coercions, rack_key: 'rack.request.form_hash']
151
+ def self.[](*filters)
152
+ ParamExtractor[filters: filters, rack_key: 'rack.request.form_hash']
91
153
  end
92
154
  end
93
155
 
data/salestation.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "salestation"
7
- spec.version = "0.13.0"
7
+ spec.version = "1.0.0"
8
8
  spec.authors = ["SaleMove TechMovers"]
9
9
  spec.email = ["techmovers@salemove.com"]
10
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: salestation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SaleMove TechMovers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-22 00:00:00.000000000 Z
11
+ date: 2018-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler