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.
- checksums.yaml +4 -4
- data/README.md +116 -296
- data/lib/peddler/api.rb +3 -2
- data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09.rb +119 -2
- data/lib/peddler/apis/aplus_content_2020_11_01.rb +59 -49
- data/lib/peddler/apis/catalog_items_2022_04_01.rb +34 -33
- data/lib/peddler/apis/catalog_items_v0.rb +0 -62
- data/lib/peddler/apis/easy_ship_2022_03_23.rb +19 -18
- data/lib/peddler/apis/feeds_2021_06_30.rb +1 -1
- data/lib/peddler/apis/finances_2024_06_01.rb +53 -0
- data/lib/peddler/apis/finances_2024_06_19.rb +14 -17
- data/lib/peddler/apis/fulfillment_inbound_2024_03_20.rb +10 -5
- data/lib/peddler/apis/fulfillment_inbound_v0.rb +2 -170
- data/lib/peddler/apis/listings_items_2021_08_01.rb +77 -5
- data/lib/peddler/apis/messaging_v1.rb +50 -49
- data/lib/peddler/apis/orders_v0.rb +1 -1
- data/lib/peddler/apis/product_pricing_v0.rb +3 -2
- data/lib/peddler/apis/reports_2021_06_30.rb +1 -1
- data/lib/peddler/apis/seller_wallet_2024_03_01.rb +195 -0
- data/lib/peddler/apis/sellers_v1.rb +1 -1
- data/lib/peddler/apis/shipping_v1.rb +12 -12
- data/lib/peddler/apis/shipping_v2.rb +46 -20
- data/lib/peddler/apis/uploads_2020_11_01.rb +9 -8
- data/lib/peddler/apis/vehicles_2024_11_01.rb +40 -0
- data/lib/peddler/apis/vendor_direct_fulfillment_shipping_2021_12_28.rb +40 -27
- data/lib/peddler/apis/vendor_invoices_v1.rb +1 -1
- data/lib/peddler/apis/vendor_shipments_v1.rb +40 -1
- data/lib/peddler/error.rb +11 -1
- data/lib/peddler/parsers/openapi_parser_generator.rb +550 -0
- data/lib/peddler/parsers/smart_parser.rb +199 -0
- data/lib/peddler/token.rb +12 -12
- data/lib/peddler/version.rb +1 -1
- data/lib/peddler.rb +3 -0
- metadata +8 -8
- 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
|
data/lib/peddler/version.rb
CHANGED
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.
|
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:
|
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.
|
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
|