salestation 0.13.0 → 1.0.0

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 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