freight_kit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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