peddler 4.1.1 → 4.3.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +116 -296
  3. data/lib/peddler/api.rb +3 -2
  4. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09.rb +119 -2
  5. data/lib/peddler/apis/aplus_content_2020_11_01.rb +59 -49
  6. data/lib/peddler/apis/catalog_items_2022_04_01.rb +34 -33
  7. data/lib/peddler/apis/catalog_items_v0.rb +0 -62
  8. data/lib/peddler/apis/easy_ship_2022_03_23.rb +19 -18
  9. data/lib/peddler/apis/feeds_2021_06_30.rb +1 -1
  10. data/lib/peddler/apis/finances_2024_06_01.rb +53 -0
  11. data/lib/peddler/apis/finances_2024_06_19.rb +14 -17
  12. data/lib/peddler/apis/fulfillment_inbound_2024_03_20.rb +10 -5
  13. data/lib/peddler/apis/fulfillment_inbound_v0.rb +2 -170
  14. data/lib/peddler/apis/listings_items_2021_08_01.rb +77 -5
  15. data/lib/peddler/apis/messaging_v1.rb +50 -49
  16. data/lib/peddler/apis/orders_v0.rb +1 -1
  17. data/lib/peddler/apis/product_pricing_v0.rb +3 -2
  18. data/lib/peddler/apis/reports_2021_06_30.rb +1 -1
  19. data/lib/peddler/apis/seller_wallet_2024_03_01.rb +195 -0
  20. data/lib/peddler/apis/sellers_v1.rb +1 -1
  21. data/lib/peddler/apis/shipping_v1.rb +12 -12
  22. data/lib/peddler/apis/shipping_v2.rb +46 -20
  23. data/lib/peddler/apis/uploads_2020_11_01.rb +9 -8
  24. data/lib/peddler/apis/vehicles_2024_11_01.rb +40 -0
  25. data/lib/peddler/apis/vendor_direct_fulfillment_shipping_2021_12_28.rb +40 -27
  26. data/lib/peddler/apis/vendor_invoices_v1.rb +1 -1
  27. data/lib/peddler/apis/vendor_shipments_v1.rb +40 -1
  28. data/lib/peddler/error.rb +11 -1
  29. data/lib/peddler/parsers/openapi_parser_generator.rb +550 -0
  30. data/lib/peddler/parsers/smart_parser.rb +199 -0
  31. data/lib/peddler/token.rb +12 -12
  32. data/lib/peddler/version.rb +1 -1
  33. data/lib/peddler.rb +3 -0
  34. metadata +8 -8
  35. data/lib/peddler/json_feed_document.rb +0 -31
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "json"
5
+ require "bigdecimal"
6
+
7
+ begin
8
+ require "money"
9
+ MONEY_GEM_AVAILABLE = true
10
+
11
+ # Configure Money to avoid issues
12
+ Money.rounding_mode = BigDecimal::ROUND_HALF_UP
13
+
14
+ # Avoid locale issues by using currency backend
15
+ if Money.respond_to?(:locale_backend=)
16
+ Money.locale_backend = :currency
17
+ end
18
+ rescue LoadError
19
+ MONEY_GEM_AVAILABLE = false
20
+ end
21
+
22
+ module Peddler
23
+ module Parsers
24
+ # Smartly parses common Amazon data types in API responses
25
+ class SmartParser
26
+ # Initialize the parser with options
27
+ #
28
+ # @param [Hash] options Parser configuration options
29
+ # @option options [Boolean] :parse_money Whether to parse money objects (default: true)
30
+ # @option options [Boolean] :parse_dates Whether to parse date/time strings (default: true)
31
+ # @option options [Boolean] :parse_dimensions Whether to parse dimension objects (default: true)
32
+ # @option options [Boolean] :symbolize_keys Whether to symbolize hash keys (default: false)
33
+ def initialize(options = {})
34
+ @parse_money = options.fetch(:parse_money, true)
35
+ @parse_dates = options.fetch(:parse_dates, true)
36
+ @parse_dimensions = options.fetch(:parse_dimensions, true)
37
+ @symbolize_keys = options.fetch(:symbolize_keys, false)
38
+ end
39
+
40
+ # Parse the HTTP response
41
+ #
42
+ # @param [HTTP::Response] response The HTTP response
43
+ # @return [Hash] The parsed response with transformed values
44
+ def call(response)
45
+ parsed = JSON.parse(response.body.to_s)
46
+ transform_values(parsed)
47
+ end
48
+
49
+ # Convert the response to a hash
50
+ #
51
+ # @return [Hash] The parsed response hash
52
+ def to_h
53
+ @parsed_response
54
+ end
55
+
56
+ private
57
+
58
+ # Transform values in the parsed response recursively
59
+ #
60
+ # @param [Hash, Array, Object] obj The object to transform
61
+ # @return [Hash, Array, Object] The transformed object
62
+ def transform_values(obj)
63
+ case obj
64
+ when Hash
65
+ transform_hash(obj)
66
+ when Array
67
+ obj.map { |item| transform_values(item) }
68
+ else
69
+ obj
70
+ end
71
+ end
72
+
73
+ # Transform a hash's values and possibly its keys
74
+ #
75
+ # @param [Hash] hash The hash to transform
76
+ # @return [Hash] The transformed hash
77
+ def transform_hash(hash)
78
+ result = @symbolize_keys ? {} : hash.class.new
79
+
80
+ hash.each do |k, v|
81
+ key = @symbolize_keys ? k.to_sym : k
82
+
83
+ # Apply transformations based on key patterns and value structure
84
+ transformed_value = apply_transformations(k, v)
85
+
86
+ result[key] = transformed_value
87
+ end
88
+
89
+ @parsed_response = result
90
+ end
91
+
92
+ # Apply type-specific transformations based on key and value
93
+ #
94
+ # @param [String] key The hash key
95
+ # @param [Object] value The value to transform
96
+ # @return [Object] The transformed value
97
+ def apply_transformations(key, value)
98
+ if value.is_a?(String) && @parse_dates && date_object?(key, value)
99
+ transform_date(value)
100
+ elsif value.is_a?(Hash)
101
+ if @parse_money && money_object?(value)
102
+ transform_money(value)
103
+ elsif @parse_dimensions && dimension_object?(value)
104
+ transform_dimension(value)
105
+ else
106
+ transform_values(value)
107
+ end
108
+ else
109
+ transform_values(value)
110
+ end
111
+ end
112
+
113
+ # Check if a hash represents a money object
114
+ #
115
+ # @param [Hash] hash The hash to check
116
+ # @return [Boolean] True if the hash represents a money object
117
+ def money_object?(hash)
118
+ hash.size == 2 &&
119
+ hash.key?("CurrencyCode") &&
120
+ hash.key?("Amount")
121
+ end
122
+
123
+ # Transform a money object into a Money object or hash
124
+ #
125
+ # @param [Hash] money_hash The money hash to transform
126
+ # @return [Money, Hash] A Money object if gem is available, otherwise a transformed hash
127
+ def transform_money(money_hash)
128
+ currency_code = money_hash["CurrencyCode"]
129
+ amount_str = money_hash["Amount"]
130
+
131
+ if defined?(Money) && MONEY_GEM_AVAILABLE
132
+ # Convert to cents (Money uses cents as its base unit)
133
+ amount_cents = (BigDecimal(amount_str) * 100).to_i
134
+
135
+ # Create Money object with the specified currency
136
+ Money.new(amount_cents, currency_code)
137
+ else
138
+ # Fallback when Money gem not available
139
+ amount = BigDecimal(amount_str)
140
+ if @symbolize_keys
141
+ { currency: currency_code, amount: amount }
142
+ else
143
+ { "currency" => currency_code, "amount" => amount }
144
+ end
145
+ end
146
+ end
147
+
148
+ # Check if a key or value suggests a date/time object
149
+ #
150
+ # @param [String] key The hash key
151
+ # @param [Object] value The value to check
152
+ # @return [Boolean] True if the value represents a date/time
153
+ def date_object?(key, value)
154
+ return false unless value.is_a?(String)
155
+
156
+ key.end_with?("Date", "Time", "At") &&
157
+ value.match?(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/)
158
+ end
159
+
160
+ # Transform a date string into a DateTime object
161
+ #
162
+ # @param [String] date_string The date string to transform
163
+ # @return [DateTime] A DateTime object
164
+ def transform_date(date_string)
165
+ # We intentionally use DateTime here for consistent API and testing
166
+ # even though RuboCop recommends Time
167
+ DateTime.parse(date_string)
168
+ end
169
+
170
+ # Check if a hash represents a dimension object
171
+ #
172
+ # @param [Hash] hash The hash to check
173
+ # @return [Boolean] True if the hash represents a dimension object
174
+ def dimension_object?(hash)
175
+ hash.size == 2 &&
176
+ hash.key?("Value") &&
177
+ hash.key?("Unit")
178
+ end
179
+
180
+ # Transform a dimension object into a more usable format
181
+ #
182
+ # @param [Hash] dimension_hash The dimension hash to transform
183
+ # @return [Hash] A transformed dimension object
184
+ def transform_dimension(dimension_hash)
185
+ if @symbolize_keys
186
+ {
187
+ value: dimension_hash["Value"].to_f,
188
+ unit: dimension_hash["Unit"],
189
+ }
190
+ else
191
+ {
192
+ "value" => dimension_hash["Value"].to_f,
193
+ "unit" => dimension_hash["Unit"],
194
+ }
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
data/lib/peddler/token.rb CHANGED
@@ -45,6 +45,18 @@ module Peddler
45
45
  response
46
46
  end
47
47
 
48
+ def grant_type
49
+ if options.key?(:grant_type)
50
+ options[:grant_type]
51
+ elsif options.key?(:refresh_token)
52
+ "refresh_token"
53
+ elsif options.key?(:scope)
54
+ "client_credentials"
55
+ elsif options.key?(:code)
56
+ "authorization_code"
57
+ end
58
+ end
59
+
48
60
  private
49
61
 
50
62
  def params
@@ -54,17 +66,5 @@ module Peddler
54
66
  client_secret: client_secret,
55
67
  }.compact.merge(options)
56
68
  end
57
-
58
- def grant_type
59
- return if options.key?(:grant_type)
60
-
61
- if options.key?(:refresh_token)
62
- "refresh_token"
63
- elsif options.key?(:scope)
64
- "client_credentials"
65
- elsif options.key?(:code)
66
- "authorization_code"
67
- end
68
- end
69
69
  end
70
70
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Peddler
4
- VERSION = "4.1.1"
4
+ VERSION = "4.3.0"
5
5
  end
data/lib/peddler.rb CHANGED
@@ -12,6 +12,7 @@ require "peddler/apis/easy_ship_2022_03_23"
12
12
  require "peddler/apis/fba_inbound_eligibility_v1"
13
13
  require "peddler/apis/fba_inventory_v1"
14
14
  require "peddler/apis/feeds_2021_06_30"
15
+ require "peddler/apis/finances_2024_06_01"
15
16
  require "peddler/apis/finances_2024_06_19"
16
17
  require "peddler/apis/finances_v0"
17
18
  require "peddler/apis/fulfillment_inbound_2024_03_20"
@@ -32,6 +33,7 @@ require "peddler/apis/product_type_definitions_2020_09_01"
32
33
  require "peddler/apis/replenishment_2022_11_07"
33
34
  require "peddler/apis/reports_2021_06_30"
34
35
  require "peddler/apis/sales_v1"
36
+ require "peddler/apis/seller_wallet_2024_03_01"
35
37
  require "peddler/apis/sellers_v1"
36
38
  require "peddler/apis/services_v1"
37
39
  require "peddler/apis/shipment_invoicing_v0"
@@ -41,6 +43,7 @@ require "peddler/apis/solicitations_v1"
41
43
  require "peddler/apis/supply_sources_2020_07_01"
42
44
  require "peddler/apis/tokens_2021_03_01"
43
45
  require "peddler/apis/uploads_2020_11_01"
46
+ require "peddler/apis/vehicles_2024_11_01"
44
47
  require "peddler/apis/vendor_direct_fulfillment_inventory_v1"
45
48
  require "peddler/apis/vendor_direct_fulfillment_orders_2021_12_28"
46
49
  require "peddler/apis/vendor_direct_fulfillment_orders_v1"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peddler
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 4.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hakan Ensari
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: http
@@ -30,7 +29,6 @@ dependencies:
30
29
  - - "<"
31
30
  - !ruby/object:Gem::Version
32
31
  version: '7.0'
33
- description:
34
32
  email:
35
33
  - hakanensari@gmail.com
36
34
  executables: []
@@ -53,6 +51,7 @@ files:
53
51
  - lib/peddler/apis/fba_inbound_eligibility_v1.rb
54
52
  - lib/peddler/apis/fba_inventory_v1.rb
55
53
  - lib/peddler/apis/feeds_2021_06_30.rb
54
+ - lib/peddler/apis/finances_2024_06_01.rb
56
55
  - lib/peddler/apis/finances_2024_06_19.rb
57
56
  - lib/peddler/apis/finances_v0.rb
58
57
  - lib/peddler/apis/fulfillment_inbound_2024_03_20.rb
@@ -73,6 +72,7 @@ files:
73
72
  - lib/peddler/apis/replenishment_2022_11_07.rb
74
73
  - lib/peddler/apis/reports_2021_06_30.rb
75
74
  - lib/peddler/apis/sales_v1.rb
75
+ - lib/peddler/apis/seller_wallet_2024_03_01.rb
76
76
  - lib/peddler/apis/sellers_v1.rb
77
77
  - lib/peddler/apis/services_v1.rb
78
78
  - lib/peddler/apis/shipment_invoicing_v0.rb
@@ -82,6 +82,7 @@ files:
82
82
  - lib/peddler/apis/supply_sources_2020_07_01.rb
83
83
  - lib/peddler/apis/tokens_2021_03_01.rb
84
84
  - lib/peddler/apis/uploads_2020_11_01.rb
85
+ - lib/peddler/apis/vehicles_2024_11_01.rb
85
86
  - lib/peddler/apis/vendor_direct_fulfillment_inventory_v1.rb
86
87
  - lib/peddler/apis/vendor_direct_fulfillment_orders_2021_12_28.rb
87
88
  - lib/peddler/apis/vendor_direct_fulfillment_orders_v1.rb
@@ -98,8 +99,9 @@ files:
98
99
  - lib/peddler/endpoint.rb
99
100
  - lib/peddler/error.rb
100
101
  - lib/peddler/helpers/feeds_2021_06_30.rb
101
- - lib/peddler/json_feed_document.rb
102
102
  - lib/peddler/marketplace.rb
103
+ - lib/peddler/parsers/openapi_parser_generator.rb
104
+ - lib/peddler/parsers/smart_parser.rb
103
105
  - lib/peddler/response.rb
104
106
  - lib/peddler/token.rb
105
107
  - lib/peddler/version.rb
@@ -108,7 +110,6 @@ licenses:
108
110
  - MIT
109
111
  metadata:
110
112
  rubygems_mfa_required: 'true'
111
- post_install_message:
112
113
  rdoc_options: []
113
114
  require_paths:
114
115
  - lib
@@ -123,8 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
124
  - !ruby/object:Gem::Version
124
125
  version: '0'
125
126
  requirements: []
126
- rubygems_version: 3.5.16
127
- signing_key:
127
+ rubygems_version: 3.6.7
128
128
  specification_version: 4
129
129
  summary: Amazon Selling Partner API (SP-API) in Ruby
130
130
  test_files: []
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Peddler
4
- class JSONFeedDocument
5
- CONTENT_TYPE = "application/json; charset=UTF-8"
6
-
7
- def upload(content)
8
- # While HTTPrb already sets the content-type, Amazon server seems to fail if we don't explicitly set it again
9
- # here. A bit of a mystery; maybe it's the order of the headers that's screwing things up on their end?
10
- HTTP.headers("Content-Type" => CONTENT_TYPE).put(url, json: content)
11
- end
12
-
13
- def initialize(api)
14
- @api = api
15
- end
16
-
17
- def id
18
- metadata.fetch("id")
19
- end
20
-
21
- def url
22
- metadata.fetch("url")
23
- end
24
-
25
- private
26
-
27
- def metadata
28
- @metadata ||= @api.create_feed_document({ "contentType" => CONTENT_TYPE }).parse
29
- end
30
- end
31
- end