esi-sdk 1.1.2 → 2.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/cicd.yml +17 -2
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +38 -0
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +21 -40
  7. data/README.md +2 -0
  8. data/Rakefile +75 -37
  9. data/bin/console +1 -1
  10. data/esi-sdk.gemspec +2 -3
  11. data/lib/esi/client/alliance.rb +103 -10
  12. data/lib/esi/client/assets.rb +193 -18
  13. data/lib/esi/client/bookmarks.rb +130 -12
  14. data/lib/esi/client/calendar.rb +144 -16
  15. data/lib/esi/client/character.rb +414 -42
  16. data/lib/esi/client/clones.rb +65 -6
  17. data/lib/esi/client/contacts.rb +294 -30
  18. data/lib/esi/client/contracts.rb +294 -31
  19. data/lib/esi/client/corporation.rb +755 -152
  20. data/lib/esi/client/dogma.rb +118 -12
  21. data/lib/esi/client/faction_warfare.rb +198 -14
  22. data/lib/esi/client/fittings.rb +94 -10
  23. data/lib/esi/client/fleets.rb +469 -49
  24. data/lib/esi/client/incursions.rb +23 -1
  25. data/lib/esi/client/industry.rb +250 -23
  26. data/lib/esi/client/insurance.rb +23 -1
  27. data/lib/esi/client/killmails.rb +95 -10
  28. data/lib/esi/client/location.rb +98 -9
  29. data/lib/esi/client/loyalty.rb +57 -6
  30. data/lib/esi/client/mail.rb +262 -28
  31. data/lib/esi/client/market.rb +322 -34
  32. data/lib/esi/client/opportunities.rb +124 -13
  33. data/lib/esi/client/planetary_interaction.rb +124 -13
  34. data/lib/esi/client/routes.rb +34 -6
  35. data/lib/esi/client/search.rb +64 -7
  36. data/lib/esi/client/skills.rb +95 -9
  37. data/lib/esi/client/sovereignty.rb +69 -3
  38. data/lib/esi/client/status.rb +24 -1
  39. data/lib/esi/client/universe.rb +817 -194
  40. data/lib/esi/client/user_interface.rb +157 -14
  41. data/lib/esi/client/wallet.rb +199 -22
  42. data/lib/esi/client/wars.rb +81 -9
  43. data/lib/esi/client.rb +74 -82
  44. data/lib/esi/errors.rb +12 -1
  45. data/lib/esi/version.rb +1 -1
  46. data/package.json +19 -0
  47. data/release.config.js +2 -2
  48. data/yarn.lock +3695 -0
  49. metadata +10 -22
@@ -12,7 +12,7 @@ module ESI
12
12
  # @esi_version legacy
13
13
  # @esi_version v1
14
14
  #
15
- # @param war_id [Integer,String] ID for a war
15
+ # @param war_id [Integer] ID for a war
16
16
  # @param params [Hash] Additional query string parameters
17
17
  # @param headers [Hash] Additional headers
18
18
  #
@@ -24,11 +24,35 @@ module ESI
24
24
  # @raise [ESI::Errors::GatewayTimeoutError] Gateway timeout
25
25
  #
26
26
  # @see https://esi.evetech.net/ui/#/Wars/get_wars_war_id
27
- def get_war(war_id:, params: {}, headers: {})
28
- get("/wars/#{war_id}/", headers: headers, params: params)
27
+ def get_war(war_id:, headers: {}, params: {})
28
+ get_war_raw(war_id: war_id, headers: headers, params: params).json
29
29
  end
30
30
  alias get_wars_war_id get_war
31
31
 
32
+ # Return details about a war.
33
+ #
34
+ # This endpoint is cached for up to 3600 seconds.
35
+ #
36
+ # @esi_version dev
37
+ # @esi_version legacy
38
+ # @esi_version v1
39
+ #
40
+ # @param war_id [Integer] ID for a war
41
+ # @param params [Hash] Additional query string parameters
42
+ # @param headers [Hash] Additional headers
43
+ #
44
+ # @raise [ESI::Errors::BadRequestError] Bad request
45
+ # @raise [ESI::Errors::ErrorLimitedError] Error limited
46
+ # @raise [ESI::Errors::UnprocessableEntityError] War not found
47
+ # @raise [ESI::Errors::InternalServerError] Internal server error
48
+ # @raise [ESI::Errors::ServiceUnavailableError] Service unavailable
49
+ # @raise [ESI::Errors::GatewayTimeoutError] Gateway timeout
50
+ #
51
+ # @see https://esi.evetech.net/ui/#/Wars/get_wars_war_id
52
+ def get_war_raw(war_id:, headers: {}, params: {})
53
+ get("/wars/#{war_id}/", headers: headers, params: params)
54
+ end
55
+
32
56
  # Return a list of kills related to a war.
33
57
  #
34
58
  # This endpoint is cached for up to 3600 seconds.
@@ -37,7 +61,7 @@ module ESI
37
61
  # @esi_version legacy
38
62
  # @esi_version v1
39
63
  #
40
- # @param war_id [Integer,String] A valid war ID
64
+ # @param war_id [Integer] A valid war ID
41
65
  # @param params [Hash] Additional query string parameters
42
66
  # @param headers [Hash] Additional headers
43
67
  #
@@ -49,11 +73,59 @@ module ESI
49
73
  # @raise [ESI::Errors::GatewayTimeoutError] Gateway timeout
50
74
  #
51
75
  # @see https://esi.evetech.net/ui/#/Wars/get_wars_war_id_killmails
52
- def get_war_killmails(war_id:, params: {}, headers: {})
53
- get("/wars/#{war_id}/killmails/", headers: headers, params: params)
76
+ def get_war_killmails(war_id:, headers: {}, params: {})
77
+ responses = get_war_killmails_raw(war_id: war_id, headers: headers, params: params)
78
+ responses.map(&:json).reduce([], :concat)
54
79
  end
55
80
  alias get_wars_war_id_killmails get_war_killmails
56
81
 
82
+ # Return a list of kills related to a war.
83
+ #
84
+ # This endpoint is cached for up to 3600 seconds.
85
+ #
86
+ # @esi_version dev
87
+ # @esi_version legacy
88
+ # @esi_version v1
89
+ #
90
+ # @param war_id [Integer] A valid war ID
91
+ # @param params [Hash] Additional query string parameters
92
+ # @param headers [Hash] Additional headers
93
+ #
94
+ # @raise [ESI::Errors::BadRequestError] Bad request
95
+ # @raise [ESI::Errors::ErrorLimitedError] Error limited
96
+ # @raise [ESI::Errors::UnprocessableEntityError] War not found
97
+ # @raise [ESI::Errors::InternalServerError] Internal server error
98
+ # @raise [ESI::Errors::ServiceUnavailableError] Service unavailable
99
+ # @raise [ESI::Errors::GatewayTimeoutError] Gateway timeout
100
+ #
101
+ # @see https://esi.evetech.net/ui/#/Wars/get_wars_war_id_killmails
102
+ def get_war_killmails_raw(war_id:, headers: {}, params: {})
103
+ get("/wars/#{war_id}/killmails/", headers: headers, params: params)
104
+ end
105
+
106
+ # Return a list of wars.
107
+ #
108
+ # This endpoint is cached for up to 3600 seconds.
109
+ #
110
+ # @esi_version dev
111
+ # @esi_version legacy
112
+ # @esi_version v1
113
+ #
114
+ # @param max_war_id [Integer] Only return wars with ID smaller than this
115
+ # @param params [Hash] Additional query string parameters
116
+ # @param headers [Hash] Additional headers
117
+ #
118
+ # @raise [ESI::Errors::BadRequestError] Bad request
119
+ # @raise [ESI::Errors::ErrorLimitedError] Error limited
120
+ # @raise [ESI::Errors::InternalServerError] Internal server error
121
+ # @raise [ESI::Errors::ServiceUnavailableError] Service unavailable
122
+ # @raise [ESI::Errors::GatewayTimeoutError] Gateway timeout
123
+ #
124
+ # @see https://esi.evetech.net/ui/#/Wars/get_wars
125
+ def get_wars(max_war_id: nil, headers: {}, params: {})
126
+ get_wars_raw(max_war_id: max_war_id, headers: headers, params: params).json
127
+ end
128
+
57
129
  # Return a list of wars.
58
130
  #
59
131
  # This endpoint is cached for up to 3600 seconds.
@@ -73,9 +145,9 @@ module ESI
73
145
  # @raise [ESI::Errors::GatewayTimeoutError] Gateway timeout
74
146
  #
75
147
  # @see https://esi.evetech.net/ui/#/Wars/get_wars
76
- def get_wars(max_war_id:, params: {}, headers: {})
77
- query_string = URI.encode_www_form([["max_war_id", max_war_id]])
78
- get("/wars/?#{query_string}", headers: headers, params: params)
148
+ def get_wars_raw(max_war_id: nil, headers: {}, params: {})
149
+ params.merge!("max_war_id" => max_war_id)
150
+ get("/wars/", headers: headers, params: params)
79
151
  end
80
152
  end
81
153
  end
data/lib/esi/client.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "faraday"
4
- require "faraday-http-cache"
5
- require "faraday_middleware"
3
+ require "httpx"
6
4
  require "timeout"
7
5
 
8
6
  require_relative "./errors"
@@ -91,135 +89,129 @@ module ESI
91
89
  520 => ESI::Errors::EveServerError
92
90
  }.freeze
93
91
 
94
- attr_reader :base_url, :cache, :user_agent, :version
92
+ attr_reader :base_url, :cache, :instrumentation, :logger, :user_agent, :version
95
93
 
96
94
  # Returns a new {ESI::Client}.
97
95
  #
96
+ # See the [faraday-http-cache](https://github.com/sourcelevel/faraday-http-cache) documentation for information on
97
+ # how to set up caching via the `cache` parameter.
98
+ #
98
99
  # @param user_agent [String] Value of the `User-Agent` header for HTTP calls
99
100
  # @param base_url [String] The base URL of the ESI API
100
101
  # @param version [String] The version of the ESI API
102
+ # @param logger [Object] The logger to use
101
103
  # @param cache [Hash] The cache configuration to use
102
104
  # @option cache [Object] :store The cache store (e.g. `Rails.cache`)
103
105
  # @option cache [Object] :logger The logger (e.g. `Rails.logger`)
104
106
  # @option cache [Object] :instrumenter The instrumenter (e.g. `ActiveSupport::Notifications`)
105
- def initialize(user_agent:, base_url: DEFAULT_BASE_URL, version: DEFAULT_VERSION, cache: {})
107
+ # @param instrumentation [Hash] The instrumentation configuration to use
108
+ # @option instrumentation [String] :name The name to use for instrumentation
109
+ # @option instrumentation [Object] :instrumenter The instrumenter to use (e.g. `ActiveSupport::Notifications`)
110
+ def initialize(user_agent:, base_url: DEFAULT_BASE_URL, version: DEFAULT_VERSION, cache: {}, instrumentation: {}, logger: nil) # rubocop:disable Layout/LineLength, Metrics/ParameterLists
106
111
  @base_url = base_url
107
112
  @cache = cache
113
+ @instrumentation = instrumentation
108
114
  @user_agent = user_agent
109
115
  @version = version
116
+ @logger = logger
110
117
  end
111
118
 
112
119
  # Set the `Authorization` header for subsequent requests.
113
120
  #
114
121
  # @param token [String] The [EVE SSO JWT token](https://docs.esi.evetech.net/docs/sso/) to use
115
122
  def authorize(token)
116
- url_encoded_connection.authorization :Bearer, token
117
- json_encoded_connection.authorization :Bearer, token
123
+ session.authentication token
118
124
  end
119
125
 
120
- private
121
-
122
- ESI_RETRY_EXCEPTIONS = [Errno::ETIMEDOUT, Timeout::Error, Faraday::TimeoutError, Faraday::ConnectionFailed,
123
- Faraday::ParsingError, SocketError].freeze
124
-
125
126
  def delete(path, params: {}, headers: {})
126
- response = make_delete_request(path, params: params, headers: headers)
127
- response.body
127
+ params.delete_if { |_, v| v.nil? }
128
+ response = session.delete("/#{version}#{path}", params: params, headers: headers)
129
+ response.raise_for_status
130
+ response
131
+ rescue HTTPX::Error
132
+ raise_error(response)
128
133
  end
129
134
 
130
135
  def get(path, params: {}, headers: {})
131
- response = make_get_request(path, params: params, headers: headers)
136
+ params.delete_if { |_, v| v.nil? }
137
+ response = session.get("/#{version}#{path}", params: params, headers: headers)
138
+ response.raise_for_status
132
139
 
133
- return paginate(response, params, headers) if paginated?(response)
140
+ return paginate(response, "/#{version}#{path}", params, headers) if paginated?(response)
134
141
 
135
- response.body
142
+ response
143
+ rescue HTTPX::Error
144
+ raise_error(response)
136
145
  end
137
146
 
138
- def post(path, payload: {}, headers: {})
139
- response = make_post_request(path, payload: payload, headers: headers)
140
- response.body
147
+ def post(path, payload: {}, params: {}, headers: {})
148
+ params.delete_if { |_, v| v.nil? }
149
+ response = session.post("/#{version}#{path}",
150
+ params: params,
151
+ headers: headers,
152
+ json: payload)
153
+ response.raise_for_status
154
+ response
155
+ rescue HTTPX::Error
156
+ raise_error(response)
141
157
  end
142
158
 
143
- def put(path, payload: {}, headers: {})
144
- response = make_put_request(path, payload: payload, headers: headers)
145
- response.body
159
+ def put(path, payload: {}, params: {}, headers: {})
160
+ params.delete_if { |_, v| v.nil? }
161
+ response = session.put("/#{version}#{path}",
162
+ params: params,
163
+ headers: headers,
164
+ json: payload)
165
+ response.raise_for_status
166
+ response
167
+ rescue HTTPX::Error
168
+ raise_error(response)
146
169
  end
147
170
 
148
- def paginate(response, params, headers)
149
- all_items = response.body
150
- page_count = response.headers["X-Pages"].to_i - 1
151
- page_count.times do |n|
152
- page_number = n + 1
153
- params = params.merge(page: page_number)
154
- page = make_get_request(path, params: params, headers: headers)
155
- all_items += page.body
156
- end
157
-
158
- all_items
159
- end
160
-
161
- def make_delete_request(path, params: {}, headers: {})
162
- res = url_encoded_connection.delete("/#{version}#{path}", params, headers)
163
-
164
- raise_error(res) unless res.success?
165
-
166
- res
167
- end
168
-
169
- def make_get_request(path, params: {}, headers: {})
170
- res = url_encoded_connection.get("/#{version}#{path}", params, headers)
171
-
172
- raise_error(res) unless res.success?
173
-
174
- res
175
- end
176
-
177
- def make_post_request(path, payload: {}, headers: {})
178
- res = json_encoded_connection.post("/#{version}#{path}", payload, headers)
179
-
180
- raise_error(res) unless res.success?
171
+ private
181
172
 
182
- res
183
- end
173
+ def paginate(response, path, params, headers) # rubocop:disable Metrics/MethodLength
174
+ response_headers = normalize_headers(response.headers)
175
+ page_count = response_headers["x-pages"].to_i
184
176
 
185
- def make_put_request(path, payload: {}, headers: {})
186
- res = json_encoded_connection.put("/#{version}#{path}", payload, headers)
177
+ requests = (2..page_count).map do |n|
178
+ session.build_request(:get, path, params: params.merge(page: n), headers: headers)
179
+ end
180
+ responses = requests.any? ? session.request(*requests) : []
181
+ responses.unshift(response)
187
182
 
188
- raise_error(res) unless res.success?
183
+ if responses.any?(&:error)
184
+ raise ESI::Errors::PaginationError.new("Error paginating request", responses: responses)
185
+ end
189
186
 
190
- res
187
+ responses
191
188
  end
192
189
 
193
190
  def paginated?(response)
194
- response.headers["X-Pages"] && response.headers["X-Pages"].to_i <= 1
191
+ headers = normalize_headers(response.headers)
192
+ headers.key?("x-pages")
195
193
  end
196
194
 
197
- def raise_error(res)
198
- raise (ERROR_MAPPING[res.status] || Error).new("(#{res.status}) #{res["error"]}", response: res)
195
+ def normalize_headers(headers)
196
+ headers.to_h.transform_keys(&:downcase)
199
197
  end
200
198
 
201
- def url_encoded_connection
202
- @url_encoded_connection ||= Faraday.new(base_url, headers: default_headers) do |f|
203
- f.use :http_cache, cache unless cache.empty?
204
- f.request :url_encoded
205
- f.request :retry, { exceptions: ESI_RETRY_EXCEPTIONS }
206
- f.response :follow_redirects
207
- f.response :json
208
- end
199
+ def raise_error(res)
200
+ raise (ERROR_MAPPING[res.status] || ESI::Errors::ClientError).new("(#{res.status}) #{res.json["error"]}",
201
+ response: res)
209
202
  end
210
203
 
211
- def json_encoded_connection
212
- @json_encoded_connection ||= Faraday.new(base_url, headers: default_headers) do |f|
213
- f.use :http_cache, cache unless cache.empty?
214
- f.request :json
215
- f.request :retry, { exceptions: ESI_RETRY_EXCEPTIONS }
216
- f.response :follow_redirects
217
- f.response :json
218
- end
204
+ def session
205
+ @session ||= HTTPX.with(origin: base_url)
206
+ .with_headers(default_headers)
207
+ .plugin(:authentication)
208
+ .plugin(:persistent)
209
+ .plugin(:response_cache)
210
+ .plugin(:retries)
219
211
  end
220
212
 
221
213
  def default_headers
222
- { "User-Agent": user_agent }
214
+ { "User-Agent": user_agent, Accept: "application/json" }
223
215
  end
224
216
  end
225
217
  end
data/lib/esi/errors.rb CHANGED
@@ -9,7 +9,7 @@ module ESI
9
9
 
10
10
  # Base class for ESI client errors.
11
11
  class ClientError < Error
12
- attr_reader :response
12
+ attr_reader :response, :responses
13
13
 
14
14
  def initialize(msg, response:)
15
15
  super(msg)
@@ -18,6 +18,17 @@ module ESI
18
18
  end
19
19
  end
20
20
 
21
+ # ESI pagination error.
22
+ class PaginationError < ClientError
23
+ attr_reader :responses
24
+
25
+ def initialize(msg, responses:)
26
+ super(msg, response: nil)
27
+
28
+ @responses = responses
29
+ end
30
+ end
31
+
21
32
  # ESI unauthorized error.
22
33
  class UnauthorizedError < ClientError; end
23
34
 
data/lib/esi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ESI
4
- VERSION = "1.1.2"
4
+ VERSION = "2.1.0"
5
5
  end
data/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "esi-sdk",
3
+ "private": true,
4
+ "dependencies": {},
5
+ "version": "1.2.0",
6
+ "description": "API client for the EVE Swagger Interface (ESI)",
7
+ "repository": "https://github.com/bokoboshahni/esi-sdk-ruby.git",
8
+ "author": "Bokobo Shahni <shahni@bokobo.space>",
9
+ "license": "MIT",
10
+ "devDependencies": {
11
+ "@semantic-release/changelog": "^5.0.1",
12
+ "@semantic-release/exec": "^6.0.1",
13
+ "@semantic-release/git": "^9.0.1",
14
+ "semantic-release": "^17.4.7"
15
+ },
16
+ "scripts": {
17
+ "release": "semantic-release"
18
+ }
19
+ }
data/release.config.js CHANGED
@@ -21,10 +21,10 @@ module.exports = {
21
21
  changelogTitle: '# ESI SDK Changelog'
22
22
  }],
23
23
  ['@semantic-release/exec', {
24
- prepareCmd: "VERSION=${nextRelease.version} bundle exec rake set_version"
24
+ prepareCmd: "VERSION=${nextRelease.version} bundle exec rake set_version && bundle install"
25
25
  }],
26
26
  ['@semantic-release/git', {
27
- assets: ['CHANGELOG.md', 'lib/esi/version.rb']
27
+ assets: ['CHANGELOG.md', 'Gemfile.lock', 'lib/esi/version.rb']
28
28
  }],
29
29
  ['@semantic-release/exec', {
30
30
  publishCmd: "bundle exec rake build release:rubygem_push"