freight_kit 0.1.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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile.lock +201 -0
  4. data/MIT-LICENSE +31 -0
  5. data/README.md +153 -0
  6. data/VERSION +1 -0
  7. data/accessorial_symbols.txt +95 -0
  8. data/freight_kit.gemspec +58 -0
  9. data/lib/freight_kit/carrier.rb +473 -0
  10. data/lib/freight_kit/carriers.rb +24 -0
  11. data/lib/freight_kit/contact.rb +17 -0
  12. data/lib/freight_kit/error.rb +5 -0
  13. data/lib/freight_kit/errors/document_not_found_error.rb +5 -0
  14. data/lib/freight_kit/errors/expired_credentials_error.rb +5 -0
  15. data/lib/freight_kit/errors/http_error.rb +25 -0
  16. data/lib/freight_kit/errors/invalid_credentials_error.rb +5 -0
  17. data/lib/freight_kit/errors/response_error.rb +16 -0
  18. data/lib/freight_kit/errors/shipment_not_found_error.rb +5 -0
  19. data/lib/freight_kit/errors/unserviceable_accessorials_error.rb +17 -0
  20. data/lib/freight_kit/errors/unserviceable_error.rb +5 -0
  21. data/lib/freight_kit/errors.rb +10 -0
  22. data/lib/freight_kit/model.rb +17 -0
  23. data/lib/freight_kit/models/credential.rb +117 -0
  24. data/lib/freight_kit/models/date_time.rb +37 -0
  25. data/lib/freight_kit/models/document_response.rb +17 -0
  26. data/lib/freight_kit/models/label.rb +13 -0
  27. data/lib/freight_kit/models/location.rb +108 -0
  28. data/lib/freight_kit/models/pickup_response.rb +19 -0
  29. data/lib/freight_kit/models/price.rb +38 -0
  30. data/lib/freight_kit/models/rate.rb +81 -0
  31. data/lib/freight_kit/models/rate_response.rb +15 -0
  32. data/lib/freight_kit/models/response.rb +21 -0
  33. data/lib/freight_kit/models/shipment.rb +66 -0
  34. data/lib/freight_kit/models/shipment_event.rb +38 -0
  35. data/lib/freight_kit/models/tracking_response.rb +75 -0
  36. data/lib/freight_kit/models.rb +17 -0
  37. data/lib/freight_kit/package.rb +313 -0
  38. data/lib/freight_kit/package_item.rb +65 -0
  39. data/lib/freight_kit/packaging.rb +52 -0
  40. data/lib/freight_kit/platform.rb +36 -0
  41. data/lib/freight_kit/shipment_packer.rb +116 -0
  42. data/lib/freight_kit/tariff.rb +29 -0
  43. data/lib/freight_kit/version.rb +5 -0
  44. data/lib/freight_kit.rb +34 -0
  45. data/service_type_symbols.txt +4 -0
  46. data/shipment_event_symbols.txt +17 -0
  47. metadata +453 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 832f852aa2321263f0360b108b76090bff3d5555da249ce75852c1b31a616fdc
4
+ data.tar.gz: f8c416a68c5ae57c52bad4618da2962a4d59e0b8df8f0c6aa74d2396a7b9a29e
5
+ SHA512:
6
+ metadata.gz: da55cd2f0f21e3741ed674e075d88e1693d62dfc45fb0a32a79f2e58f6defb15928ee686ff13207d266c8ece846ff643c5e7d0d731430c8b5685173911806ea4
7
+ data.tar.gz: eb616c1fd02a6c104153b4fd0fd0d191c0144c86815e299866c0b255c9d050b50454c27a62589e2cc9f4f1b456e9a409d7a04e5ca08301f82707bf517be0c775
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,201 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ freight_kit (0.1.0)
5
+ active_utils (~> 3.3.1)
6
+ activemodel (>= 4.2, < 7.0.8)
7
+ activesupport (>= 4.2, < 7.0.8)
8
+ httparty (~> 0.10)
9
+ measured (>= 2.0, < 2.8.3)
10
+ mimemagic (~> 0.4.3)
11
+ nokogiri (>= 1.6, < 1.14)
12
+ place_kit (~> 0.0.1)
13
+ savon (>= 2.0, < 2.13)
14
+ watir (>= 7.0, < 7.2)
15
+
16
+ GEM
17
+ remote: https://rubygems.org/
18
+ specs:
19
+ active_utils (3.3.19)
20
+ activesupport (>= 4.2)
21
+ i18n
22
+ activemodel (7.0.7)
23
+ activesupport (= 7.0.7)
24
+ activesupport (7.0.7)
25
+ concurrent-ruby (~> 1.0, >= 1.0.2)
26
+ i18n (>= 1.6, < 2)
27
+ minitest (>= 5.1)
28
+ tzinfo (~> 2.0)
29
+ addressable (2.8.5)
30
+ public_suffix (>= 2.0.2, < 6.0)
31
+ akami (1.3.1)
32
+ gyoku (>= 0.4.0)
33
+ nokogiri
34
+ ansi (1.5.0)
35
+ ast (2.4.2)
36
+ base64 (0.1.1)
37
+ builder (3.2.4)
38
+ business_time (0.11.0)
39
+ activesupport (>= 3.2.0)
40
+ sorted_set
41
+ tzinfo
42
+ byebug (11.1.3)
43
+ coderay (1.1.3)
44
+ concurrent-ruby (1.2.2)
45
+ crack (0.4.5)
46
+ rexml
47
+ fastcsv (0.0.7)
48
+ gyoku (1.4.0)
49
+ builder (>= 2.1.2)
50
+ rexml (~> 3.0)
51
+ hashdiff (1.0.1)
52
+ httparty (0.21.0)
53
+ mini_mime (>= 1.0.0)
54
+ multi_xml (>= 0.5.2)
55
+ httpi (2.5.0)
56
+ rack
57
+ socksify
58
+ i18n (1.14.1)
59
+ concurrent-ruby (~> 1.0)
60
+ json (2.6.3)
61
+ language_server-protocol (3.17.0.3)
62
+ measured (2.8.2)
63
+ activesupport (>= 5.2)
64
+ method_source (1.0.0)
65
+ mimemagic (0.4.3)
66
+ nokogiri (~> 1)
67
+ rake
68
+ mini_mime (1.1.5)
69
+ mini_portile2 (2.8.4)
70
+ minitest (5.15.0)
71
+ minitest-reporters (1.5.0)
72
+ ansi
73
+ builder
74
+ minitest (>= 5.0)
75
+ ruby-progressbar
76
+ mocha (1.13.0)
77
+ multi_xml (0.6.0)
78
+ nokogiri (1.13.10)
79
+ mini_portile2 (~> 2.8.0)
80
+ racc (~> 1.4)
81
+ nori (2.6.0)
82
+ parallel (1.23.0)
83
+ parser (3.2.2.3)
84
+ ast (~> 2.4.1)
85
+ racc
86
+ place_kit (0.0.1)
87
+ activesupport (>= 6.0.0, < 7.1)
88
+ fastcsv (~> 0.0.6)
89
+ pry (0.13.1)
90
+ coderay (~> 1.1)
91
+ method_source (~> 1.0)
92
+ pry-byebug (3.9.0)
93
+ byebug (~> 11.0)
94
+ pry (~> 0.13.0)
95
+ public_suffix (5.0.3)
96
+ racc (1.7.1)
97
+ rack (3.0.8)
98
+ rainbow (3.1.1)
99
+ rake (13.0.6)
100
+ rbtree (0.4.6)
101
+ redcarpet (3.5.1)
102
+ regexp_parser (2.8.1)
103
+ rexml (3.2.6)
104
+ rubocop (1.56.0)
105
+ base64 (~> 0.1.1)
106
+ json (~> 2.3)
107
+ language_server-protocol (>= 3.17.0)
108
+ parallel (~> 1.10)
109
+ parser (>= 3.2.2.3)
110
+ rainbow (>= 2.2.2, < 4.0)
111
+ regexp_parser (>= 1.8, < 3.0)
112
+ rexml (>= 3.2.5, < 4.0)
113
+ rubocop-ast (>= 1.28.1, < 2.0)
114
+ ruby-progressbar (~> 1.7)
115
+ unicode-display_width (>= 2.4.0, < 3.0)
116
+ rubocop-ast (1.29.0)
117
+ parser (>= 3.2.1.0)
118
+ rubocop-capybara (2.18.0)
119
+ rubocop (~> 1.41)
120
+ rubocop-factory_bot (2.23.1)
121
+ rubocop (~> 1.33)
122
+ rubocop-graphql (1.4.0)
123
+ rubocop (>= 0.90, < 2)
124
+ rubocop-next (1.0.3)
125
+ rubocop (~> 1.56.0)
126
+ rubocop-graphql (~> 1.4.0)
127
+ rubocop-rails (~> 2.20.2)
128
+ rubocop-rake (~> 0.6.0)
129
+ rubocop-rspec (~> 2.23.2)
130
+ rubocop-shopify (~> 2.14.0)
131
+ rubocop-rails (2.20.2)
132
+ activesupport (>= 4.2.0)
133
+ rack (>= 1.1)
134
+ rubocop (>= 1.33.0, < 2.0)
135
+ rubocop-rake (0.6.0)
136
+ rubocop (~> 1.0)
137
+ rubocop-rspec (2.23.2)
138
+ rubocop (~> 1.33)
139
+ rubocop-capybara (~> 2.17)
140
+ rubocop-factory_bot (~> 2.22)
141
+ rubocop-shopify (2.14.0)
142
+ rubocop (~> 1.51)
143
+ ruby-progressbar (1.13.0)
144
+ rubyzip (2.3.2)
145
+ savon (2.12.1)
146
+ akami (~> 1.2)
147
+ builder (>= 2.1.2)
148
+ gyoku (~> 1.2)
149
+ httpi (~> 2.3)
150
+ nokogiri (>= 1.8.1)
151
+ nori (~> 2.4)
152
+ wasabi (~> 3.4)
153
+ selenium-webdriver (4.11.0)
154
+ rexml (~> 3.2, >= 3.2.5)
155
+ rubyzip (>= 1.2.2, < 3.0)
156
+ websocket (~> 1.0)
157
+ set (1.0.3)
158
+ socksify (1.7.1)
159
+ sorted_set (1.0.3)
160
+ rbtree
161
+ set (~> 1.0)
162
+ timecop (0.9.8)
163
+ tzinfo (2.0.6)
164
+ concurrent-ruby (~> 1.0)
165
+ unicode-display_width (2.4.2)
166
+ vcr (6.1.0)
167
+ wasabi (3.7.0)
168
+ addressable
169
+ httpi (~> 2.0)
170
+ nokogiri (>= 1.4.2)
171
+ watir (7.1.0)
172
+ regexp_parser (>= 1.2, < 3)
173
+ selenium-webdriver (~> 4.0)
174
+ webmock (3.14.0)
175
+ addressable (>= 2.8.0)
176
+ crack (>= 0.3.2)
177
+ hashdiff (>= 0.4.0, < 2.0.0)
178
+ websocket (1.2.9)
179
+ yard (0.9.34)
180
+
181
+ PLATFORMS
182
+ arm64-darwin-22
183
+
184
+ DEPENDENCIES
185
+ business_time (~> 0.11.0)
186
+ freight_kit!
187
+ minitest (~> 5.15.0)
188
+ minitest-reporters (~> 1.5.0)
189
+ mocha (~> 1.13.0)
190
+ pry (~> 0.13.1)
191
+ pry-byebug (~> 3.9.0)
192
+ rake (~> 13.0.3)
193
+ redcarpet (~> 3.5.1)
194
+ rubocop-next (~> 1.0.3)
195
+ timecop (~> 0.9.4)
196
+ vcr (~> 6.1.0)
197
+ webmock (~> 3.14.0)
198
+ yard (~> 0.9.28)
199
+
200
+ BUNDLED WITH
201
+ 2.4.19
data/MIT-LICENSE ADDED
@@ -0,0 +1,31 @@
1
+ Portions of this project are © 2016 Shopify from project
2
+ ActiveShipping.
3
+
4
+ Portions of this project are © 2018 Sub Pop Records from project
5
+ RectiveShipping.
6
+
7
+ Portions of this project are © 2020 Brody Hoskins from project ReactiveFreight.
8
+
9
+ Portions of this project are © 2021 Brody Hoskins from project HyperCarrier.
10
+
11
+ Copyright for all later portions this project are held by Third Party Logistics
12
+ Management Systems LLC.
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining
15
+ a copy of this software and associated documentation files (the
16
+ "Software"), to deal in the Software without restriction, including
17
+ without limitation the rights to use, copy, modify, merge, publish,
18
+ distribute, sublicense, and/or sell copies of the Software, and to
19
+ permit persons to whom the Software is furnished to do so, subject to
20
+ the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be
23
+ included in all copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # FreightKit
2
+
3
+ This library interfaces with the web services of various shipping carriers. The goal is to abstract the features that are most frequently used into a pleasant and consistent Ruby API.
4
+
5
+ FreightKit supports:
6
+
7
+ - Downloading scanned documents
8
+ - Finding shipping rates
9
+ - Tracking shipments
10
+
11
+ On a technical level it supports:
12
+
13
+ - Abstracted accessorials
14
+ - Abstracted tracking events
15
+ - Cubic feet and density calculations
16
+ - Freight class calculations (and manual overriding)
17
+
18
+ ## Definitions
19
+
20
+ Carrier: Has unique web services pertaining to whatever real-world services they provide.
21
+
22
+ Platform: Provides web-accessible services for many carriers at once.
23
+
24
+ __Note:__ `Carrier`s may extend `Platform`s and override them when their behavior differs from the `Platform`.
25
+
26
+ ## Plug-in System
27
+
28
+ FreightKit relies on plug-ins (gems) to define how it connects to individual `Carrier`s and `Platform`s.
29
+
30
+ ## Installation
31
+
32
+ Using bundler, add to the `Gemfile`:
33
+
34
+ ```ruby
35
+ gem 'freight_kit'
36
+ ```
37
+
38
+ Or standalone:
39
+
40
+ ```
41
+ $ gem install freight_kit
42
+ ```
43
+
44
+ __Note__: Plug-ins are required to connect to `Carrier`s and `Platforms` (see above).
45
+
46
+ ## Standard Usage
47
+
48
+ Start off by initializing the `Carrier` provided by a `Carrier` plug-in:
49
+
50
+ ```ruby
51
+ require 'freight_kit'
52
+
53
+ # Typically just one `Credential` is required
54
+ credentials = [
55
+ FreightKit::Credential.new(
56
+ type: :api,
57
+ account: 'account_number',
58
+ username: 'username',
59
+ password: 'password',
60
+ tariff: FreightKit::Tariff.new # optional
61
+ ),
62
+ FreightKit::Credential.new(
63
+ type: :oauth2,
64
+ access_token: 'token',
65
+ expires_at: DateTime.current + 1.day, # DateTime
66
+ scope: 'scope'
67
+ ),
68
+ FreightKit::Credential.new(
69
+ type: :website,
70
+ username: 'username',
71
+ password: 'password'
72
+ ),
73
+ FreightKit::Credential.new(
74
+ type: :selenoid,
75
+ base_url: URI.parse('http://domain:4444'),
76
+ browser: :chrome
77
+ )
78
+ ]
79
+
80
+ carrier = FreightKit::SCAC.new(credentials)
81
+ ```
82
+
83
+ ### Documents
84
+
85
+ ```ruby
86
+ carrier.bol(tracking_number) # BOL generated by carrier
87
+ carrier.scanned_bol(tracking_number) # BOL scanned by carrier
88
+
89
+ carrier.pod(tracking_number)
90
+ ```
91
+
92
+ ### Tracking
93
+
94
+ ```ruby
95
+ tracking = carrier.find_tracking_info(tracking_number)
96
+
97
+ tracking.delivered?
98
+ tracking.status
99
+
100
+ tracking.shipment_events.each do |event|
101
+ puts "#{event.name} at #{event.location.city}, #{event.location.state} on #{event.time}. #{event.message}"
102
+ end
103
+ ```
104
+
105
+ ### Quoting
106
+
107
+ ```ruby
108
+ packages = [
109
+ FreightKit::Package.new(
110
+ 371 * 16, # 371 lbs
111
+ {
112
+ length: 40, # inches
113
+ width: 48,
114
+ height: 47
115
+ },
116
+ units: :imperial
117
+ ),
118
+ FreightKit::Package.new(
119
+ 371 * 16, # 371 lbs
120
+ {
121
+ length: 40, # inches
122
+ width: 48,
123
+ height: 47
124
+ },
125
+ freight_class: 125, # override calculated freight class
126
+ units: :imperial
127
+ )
128
+ ]
129
+
130
+ origin = FreightKit::Location.new(
131
+ country: 'US',
132
+ state: 'CA',
133
+ city: 'Los Angeles',
134
+ zip: '90001'
135
+ )
136
+
137
+ destination = FreightKit::Location.new(
138
+ country: 'US',
139
+ state: 'IL',
140
+ city: 'Chicago',
141
+ zip: '60007'
142
+ )
143
+
144
+ accessorials = %i[
145
+ appointment_delivery
146
+ liftgate_delivery
147
+ residential_delivery
148
+ ]
149
+
150
+ response = carrier.find_rates(origin, destination, packages, accessorials: accessorials)
151
+ rates = response.rates
152
+ rates = response.rates.sort_by(&:price).collect { |rate| [rate.service_name, rate.price] }
153
+ ```
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,95 @@
1
+ :afterhours_delivery
2
+ :afterhours_pickup
3
+ :airport_delivery
4
+ :airport_pickup
5
+ :amusement_park_delivery
6
+ :amusement_park_pickup
7
+ :appointment_delivery
8
+ :appointment_pickup
9
+ :athletic_facility_delivery
10
+ :athletic_facility_pickup
11
+ :brewery_delivery
12
+ :brewery_pickup
13
+ :cemetery_delivery
14
+ :cemetery_pickup
15
+ :church_delivery
16
+ :church_pickup
17
+ :construction_delivery
18
+ :construction_pickup
19
+ :convention_delivery
20
+ :convention_pickup
21
+ :customs_brokerage
22
+ :dock_dropoff
23
+ :dock_pickup
24
+ :driver_assist
25
+ :early_morning_delivery
26
+ :early_morning_pickup
27
+ :fair_delivery
28
+ :fair_pickup
29
+ :farm_delivery
30
+ :farm_pickup
31
+ :fitness_center_delivery
32
+ :fitness_center_pickup
33
+ :flatbed_delivery
34
+ :flatbed_pickup
35
+ :golf_course_delivery
36
+ :golf_course_pickup
37
+ :government_delivery
38
+ :government_pickup
39
+ :grocery_store_delivery
40
+ :grocery_store_pickup
41
+ :grocery_warehouse_delivery
42
+ :grocery_warehouse_pickup
43
+ :guaranteed_delivery
44
+ :guaranteed_delivery_am
45
+ :guaranteed_delivery_pm
46
+ :hospital_delivery
47
+ :hospital_pickup
48
+ :hotel_delivery
49
+ :hotel_pickup
50
+ :inside_delivery
51
+ :inside_pickup
52
+ :inspection_site_delivery
53
+ :inspection_site_pickup
54
+ :jobsite_delivery
55
+ :jobsite_pickup
56
+ :liftgate_delivery
57
+ :liftgate_pickup
58
+ :mall_delivery
59
+ :mall_pickup
60
+ :marina_delivery
61
+ :marina_pickup
62
+ :military_site_delivery
63
+ :military_site_pickup
64
+ :mine_site_delivery
65
+ :mine_site_pickup
66
+ :motel_delivery
67
+ :motel_pickup
68
+ :nursing_home_delivery
69
+ :nursing_home_pickup
70
+ :park_delivery
71
+ :park_pickup
72
+ :prison_delivery
73
+ :prison_pickup
74
+ :ranch_delivery
75
+ :ranch_pickup
76
+ :reservation_delivery
77
+ :reservation_pickup
78
+ :residential_delivery
79
+ :residential_pickup
80
+ :resort_delivery
81
+ :resort_pickup
82
+ :restaurant_delivery
83
+ :restaurant_pickup
84
+ :school_delivery
85
+ :school_pickup
86
+ :steel_mill_delivery
87
+ :steel_mill_pickup
88
+ :storage_facility_delivery
89
+ :storage_facility_pickup
90
+ :university_delivery
91
+ :university_pickup
92
+ :utility_site_delivery
93
+ :utility_site_pickup
94
+ :winery_delivery
95
+ :winery_pickup
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ version = File.read(File.expand_path('VERSION', __dir__)).strip.freeze
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'freight_kit'
7
+ spec.version = version
8
+
9
+ spec.authors = [
10
+ 'Third Party Transportation Systems LLC',
11
+ 'Brody Hoskins',
12
+ 'Sub Pop Records',
13
+ 'Shopify',
14
+ ]
15
+ spec.email = [
16
+ 'hello@next-tms.com',
17
+ 'brody@brody.digital',
18
+ 'webmaster@subpop.com',
19
+ 'integrations-team@shopify.com',
20
+ ]
21
+
22
+ spec.description = 'Freight carrier API and website abstraction library for transportation management systems (TMS)'
23
+ spec.homepage = 'https://github.com/next-tms/freight_kit'
24
+ spec.summary = spec.description
25
+
26
+ spec.files = Dir['lib/**/*'] +
27
+ Dir['[A-Z]*'] +
28
+ Dir['test/**/*']
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_development_dependency('business_time', '~> 0.11.0')
32
+ spec.add_development_dependency('minitest', '~> 5.15.0')
33
+ spec.add_development_dependency('minitest-reporters', '~> 1.5.0')
34
+ spec.add_development_dependency('mocha', '~> 1.13.0')
35
+ spec.add_development_dependency('pry', '~> 0.13.1')
36
+ spec.add_development_dependency('pry-byebug', '~> 3.9.0')
37
+ spec.add_development_dependency('rake', '~> 13.0.3')
38
+ spec.add_development_dependency('rubocop-next', '~> 1.0.3')
39
+ spec.add_development_dependency('timecop', '~> 0.9.4')
40
+ spec.add_development_dependency('vcr', '~> 6.1.0')
41
+ spec.add_development_dependency('webmock', '~> 3.14.0')
42
+
43
+ spec.add_development_dependency('redcarpet', '~> 3.5.1') # for yard
44
+ spec.add_development_dependency('yard', '~> 0.9.28')
45
+
46
+ spec.add_dependency('activemodel', '>= 4.2', '< 7.0.8')
47
+ spec.add_dependency('activesupport', '>= 4.2', '< 7.0.8')
48
+ spec.add_dependency('active_utils', '~> 3.3.1')
49
+ spec.add_dependency('httparty', '~> 0.10')
50
+ spec.add_dependency('measured', '>= 2.0', '< 2.8.3')
51
+ spec.add_dependency('mimemagic', '~> 0.4.3')
52
+ spec.add_dependency('nokogiri', '>= 1.6', '< 1.14')
53
+ spec.add_dependency('place_kit', '~> 0.0.1')
54
+ spec.add_dependency('savon', '>= 2.0', '< 2.13')
55
+ spec.add_dependency('watir', '>= 7.0', '< 7.2')
56
+
57
+ spec.required_ruby_version = '>= 3.2.0'
58
+ end