x 0.10.0 → 0.12.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -28
  3. data/README.md +12 -2
  4. data/lib/x/authenticator.rb +10 -0
  5. data/lib/x/bearer_token_authenticator.rb +5 -3
  6. data/lib/x/cgi.rb +15 -0
  7. data/lib/x/client.rb +85 -49
  8. data/lib/x/connection.rb +39 -76
  9. data/lib/x/errors/bad_gateway.rb +5 -0
  10. data/lib/x/errors/{not_found_error.rb → bad_request.rb} +1 -1
  11. data/lib/x/errors/client_error.rb +2 -2
  12. data/lib/x/errors/connection_exception.rb +5 -0
  13. data/lib/x/errors/error.rb +1 -11
  14. data/lib/x/errors/{forbidden_error.rb → forbidden.rb} +1 -1
  15. data/lib/x/errors/gateway_timeout.rb +5 -0
  16. data/lib/x/errors/{bad_request_error.rb → gone.rb} +1 -1
  17. data/lib/x/errors/http_error.rb +42 -0
  18. data/lib/x/errors/network_error.rb +1 -1
  19. data/lib/x/errors/not_acceptable.rb +5 -0
  20. data/lib/x/errors/not_found.rb +5 -0
  21. data/lib/x/errors/payload_too_large.rb +5 -0
  22. data/lib/x/errors/server_error.rb +2 -2
  23. data/lib/x/errors/service_unavailable.rb +5 -0
  24. data/lib/x/errors/too_many_redirects.rb +5 -0
  25. data/lib/x/errors/too_many_requests.rb +24 -0
  26. data/lib/x/errors/unauthorized.rb +5 -0
  27. data/lib/x/errors/unprocessable_entity.rb +5 -0
  28. data/lib/x/{media_upload.rb → media_uploader.rb} +34 -35
  29. data/lib/x/oauth_authenticator.rb +10 -15
  30. data/lib/x/redirect_handler.rb +26 -23
  31. data/lib/x/request_builder.rb +22 -35
  32. data/lib/x/response_parser.rb +69 -0
  33. data/lib/x/version.rb +1 -1
  34. data/sig/x.rbs +118 -92
  35. metadata +22 -13
  36. data/lib/x/errors/authentication_error.rb +0 -5
  37. data/lib/x/errors/payload_too_large_error.rb +0 -5
  38. data/lib/x/errors/service_unavailable_error.rb +0 -5
  39. data/lib/x/errors/too_many_redirects_error.rb +0 -5
  40. data/lib/x/errors/too_many_requests_error.rb +0 -29
  41. data/lib/x/response_handler.rb +0 -63
data/sig/x.rbs CHANGED
@@ -1,13 +1,19 @@
1
1
  module X
2
2
  VERSION: Gem::Version
3
3
 
4
- class BearerTokenAuthenticator
4
+ class Authenticator
5
+ AUTHENTICATION_HEADER: String
6
+
7
+ def header: (Net::HTTPRequest? request) -> Hash[String, String]
8
+ end
9
+
10
+ class BearerTokenAuthenticator < Authenticator
5
11
  attr_accessor bearer_token: String
6
- def initialize: (String bearer_token) -> void
7
- def header: (Net::HTTPRequest _request) -> String
12
+ def initialize: (bearer_token: String) -> void
13
+ def header: (Net::HTTPRequest? request) -> Hash[String, String]
8
14
  end
9
15
 
10
- class OauthAuthenticator
16
+ class OAuthAuthenticator < Authenticator
11
17
  OAUTH_VERSION: String
12
18
  OAUTH_SIGNATURE_METHOD: String
13
19
  OAUTH_SIGNATURE_ALGORITHM: String
@@ -16,8 +22,8 @@ module X
16
22
  attr_accessor api_key_secret: String
17
23
  attr_accessor access_token: String
18
24
  attr_accessor access_token_secret: String
19
- def initialize: (String api_key, String api_key_secret, String access_token, String access_token_secret) -> void
20
- def header: (Net::HTTPRequest request) -> String
25
+ def initialize: (api_key: String, api_key_secret: String, access_token: String, access_token_secret: String) -> void
26
+ def header: (Net::HTTPRequest request) -> Hash[String, String]
21
27
 
22
28
  private
23
29
  def parse_request: (Net::HTTPRequest request) -> [String, String, Hash[String, String]]
@@ -34,188 +40,203 @@ module X
34
40
  end
35
41
 
36
42
  class Error < StandardError
43
+ end
44
+
45
+ class ClientError < HTTPError
46
+ end
47
+
48
+ class BadGateway < ClientError
49
+ end
50
+
51
+ class BadRequest < ClientError
52
+ end
53
+
54
+ class ConnectionException < ClientError
55
+ end
56
+
57
+ class HTTPError < Error
37
58
  JSON_CONTENT_TYPE_REGEXP: Regexp
38
59
 
39
- attr_reader object: untyped
40
- def initialize: (String msg, response: Net::HTTPResponse?) -> void
60
+ attr_reader response : Net::HTTPResponse
61
+ attr_reader code : String
62
+
63
+ def initialize: (response: Net::HTTPResponse) -> void
41
64
 
42
65
  private
43
- def json_response?: (Net::HTTPResponse response) -> bool
66
+ def error_message: (Net::HTTPResponse response) -> String
67
+ def message_from_json_response: (Net::HTTPResponse response) -> String
68
+ def json?: (Net::HTTPResponse response) -> bool
44
69
  end
45
70
 
46
- class ClientError < Error
71
+ class Forbidden < ClientError
47
72
  end
48
73
 
49
- class BadRequestError < ClientError
74
+ class GatewayTimeout < ClientError
50
75
  end
51
76
 
52
- class AuthenticationError < ClientError
77
+ class Gone < ClientError
53
78
  end
54
79
 
55
- class ForbiddenError < ClientError
80
+ class InternalServerError < ServerError
56
81
  end
57
82
 
58
- class InternalServerError < ServerError
83
+ class NetworkError < Error
59
84
  end
60
85
 
61
- class NotFoundError < ClientError
86
+ class NotAcceptable < ClientError
62
87
  end
63
88
 
64
- class PayloadTooLargeError < ClientError
89
+ class NotFound < ClientError
65
90
  end
66
91
 
67
- class TooManyRedirectsError < ClientError
92
+ class PayloadTooLarge < ClientError
68
93
  end
69
94
 
70
- class TooManyRequestsError < ClientError
95
+ class ServerError < HTTPError
96
+ end
97
+
98
+ class ServiceUnavailable < ServerError
99
+ end
100
+
101
+ class TooManyRedirects < Error
102
+ end
103
+
104
+ class TooManyRequests < ClientError
71
105
  @response: Net::HTTPResponse
72
106
 
73
- def initialize: (String msg, response: Net::HTTPResponse) -> void
74
107
  def limit: -> Integer
75
108
  def remaining: -> Integer
76
109
  def reset_at: -> Time
77
110
  def reset_in: -> Integer?
78
111
  end
79
112
 
80
- class ServerError < Error
81
- end
82
-
83
- class ServiceUnavailableError < ServerError
113
+ class Unauthorized < ClientError
84
114
  end
85
115
 
86
- class NetworkError < Error
116
+ class UnprocessableEntity < ClientError
87
117
  end
88
118
 
89
119
  class Connection
90
- DEFAULT_BASE_URL: String
91
120
  DEFAULT_HOST: String
92
121
  DEFAULT_PORT: Integer
93
122
  DEFAULT_OPEN_TIMEOUT: Integer
94
123
  DEFAULT_READ_TIMEOUT: Integer
95
124
  DEFAULT_WRITE_TIMEOUT: Integer
125
+ DEFAULT_DEBUG_OUTPUT: IO
96
126
  NETWORK_ERRORS: Array[(singleton(Errno::ECONNREFUSED) | singleton(Errno::ECONNRESET) | singleton(Net::OpenTimeout) | singleton(Net::ReadTimeout) | singleton(OpenSSL::SSL::SSLError))]
97
127
 
98
128
  extend Forwardable
99
- @http_client: Net::HTTP
100
129
 
101
- attr_reader base_uri: URI::Generic
130
+ attr_accessor open_timeout : Float | Integer
131
+ attr_accessor read_timeout : Float | Integer
132
+ attr_accessor write_timeout : Float | Integer
133
+ attr_accessor debug_output : IO
134
+
102
135
  attr_reader proxy_uri: URI::Generic?
103
- attr_reader open_timeout : Float | Integer
104
- attr_reader read_timeout : Float | Integer
105
- attr_reader write_timeout : Float | Integer
106
- def initialize: (?base_url: URI::Generic | String, ?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO?) -> void
107
- def send_request: (Net::HTTPRequest request) -> Net::HTTPResponse
108
- def base_uri=: (URI::Generic | String base_url) -> void
109
- def debug_output: -> IO?
110
- def configuration: -> Hash[Symbol, untyped]
136
+ attr_reader proxy_host : String?
137
+ attr_reader proxy_port : Integer?
138
+ attr_reader proxy_user : String?
139
+ attr_reader proxy_pass : String?
140
+
141
+ def initialize: (?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO) -> void
142
+ def proxy_url=: (URI::Generic | String proxy_url) -> void
143
+ def perform: (request: Net::HTTPRequest) -> Net::HTTPResponse
111
144
 
112
145
  private
113
- def apply_http_client_settings: (open_timeout: Float | Integer, read_timeout: Float | Integer, write_timeout: Float | Integer, debug_output: IO?) -> untyped
114
- def current_http_client_settings: -> {open_timeout: Float | Integer, read_timeout: Float | Integer, write_timeout: Float | Integer, debug_output: IO?}
115
- def update_http_client_settings: -> untyped
116
- def build_http_client: (host: String, port: Integer) -> (Net::HTTP)
117
- def conditionally_apply_http_client_settings: { -> untyped } -> untyped
146
+ def build_http_client: (?String host, ?Integer port) -> Net::HTTP
147
+ def configure_http_client: (Net::HTTP http_client) -> Net::HTTP
118
148
  end
119
149
 
120
150
  class RequestBuilder
121
- HTTP_METHODS: Hash[::Symbol, (singleton(::Net::HTTP::Get) | singleton(::Net::HTTP::Post) | singleton(::Net::HTTP::Put) | singleton(::Net::HTTP::Delete))]
122
- DEFAULT_CONTENT_TYPE: String
123
- DEFAULT_USER_AGENT: String
124
- AUTHORIZATION_HEADER: String
125
- CONTENT_TYPE_HEADER: String
126
- USER_AGENT_HEADER: String
127
-
128
- attr_accessor content_type: String
129
- attr_accessor user_agent: String
151
+ HTTP_METHODS: Hash[Symbol, (singleton(Net::HTTP::Get) | singleton(Net::HTTP::Post) | singleton(Net::HTTP::Put) | singleton(Net::HTTP::Delete))]
152
+ DEFAULT_HEADERS: Hash[String, String]
153
+
130
154
  def initialize: (?content_type: String, ?user_agent: String) -> void
131
- def build: (BearerTokenAuthenticator | OauthAuthenticator authenticator, Symbol http_method, URI::Generic uri, ?body: String?) -> (Net::HTTPRequest)
132
- def configuration: -> Hash[Symbol, untyped]
155
+ def build: (authenticator: Authenticator, http_method: Symbol, uri: URI::Generic, ?body: String?, ?headers: Hash[String, String]) -> (Net::HTTPRequest)
133
156
 
134
157
  private
135
- def create_request: (Symbol http_method, URI::Generic uri, String? body) -> (Net::HTTPRequest)
136
- def add_authorization: (Net::HTTPRequest request, BearerTokenAuthenticator | OauthAuthenticator authenticator) -> void
137
- def add_content_type: (Net::HTTPRequest request) -> void
138
- def add_user_agent: (Net::HTTPRequest request) -> void
158
+ def create_request: (http_method: Symbol, uri: URI::Generic, body: String?) -> (Net::HTTPRequest)
159
+ def add_authentication: (request: Net::HTTPRequest, authenticator: Authenticator) -> void
160
+ def add_headers: (request: Net::HTTPRequest, headers: Hash[String, String]) -> void
139
161
  def escape_query_params: (URI::Generic uri) -> URI::Generic
140
162
  end
141
163
 
142
164
  class RedirectHandler
143
165
  DEFAULT_MAX_REDIRECTS: Integer
144
166
 
145
- attr_reader authenticator: BearerTokenAuthenticator | OauthAuthenticator
167
+ attr_reader authenticator: Authenticator
146
168
  attr_reader connection: Connection
147
169
  attr_reader request_builder: RequestBuilder
148
170
  attr_reader max_redirects: Integer
149
- def initialize: (BearerTokenAuthenticator | OauthAuthenticator authenticator, Connection connection, RequestBuilder request_builder, ?max_redirects: Integer) -> void
150
- def handle_redirects: (Net::HTTPResponse response, Net::HTTPRequest original_request, URI::Generic | String original_base_url, ?Integer redirect_count) -> Net::HTTPResponse
171
+ def initialize: (connection: Connection, request_builder: RequestBuilder, ?max_redirects: Integer) -> void
172
+ def handle: (response: Net::HTTPResponse, request: Net::HTTPRequest, base_url: String, ?authenticator: Authenticator, ?redirect_count: Integer) -> Net::HTTPResponse
151
173
 
152
174
  private
153
- def build_new_uri: (Net::HTTPResponse response, URI::Generic | String original_base_url) -> URI::Generic
154
- def build_request: (Net::HTTPRequest original_request, URI::Generic new_uri) -> Net::HTTPRequest
175
+ def build_new_uri: (Net::HTTPResponse response, String base_url) -> URI::Generic
176
+ def build_request: (Net::HTTPRequest request, URI::Generic new_uri, Integer response_code, Authenticator authenticator) -> Net::HTTPRequest
155
177
  def send_new_request: (URI::Generic new_uri, Net::HTTPRequest new_request) -> Net::HTTPResponse
156
178
  end
157
179
 
158
- class ResponseHandler
180
+ class ResponseParser
159
181
  DEFAULT_ARRAY_CLASS: Class
160
182
  DEFAULT_OBJECT_CLASS: Class
161
- ERROR_CLASSES: Hash[Integer, singleton(AuthenticationError) | singleton(BadRequestError) | singleton(ForbiddenError) | singleton(InternalServerError) | singleton(NotFoundError) | singleton(PayloadTooLargeError) | singleton(ServiceUnavailableError) | singleton(TooManyRequestsError)]
183
+ ERROR_MAP: Hash[Integer, singleton(Unauthorized) | singleton(BadRequest) | singleton(Forbidden) | singleton(InternalServerError) | singleton(NotFound) | singleton(PayloadTooLarge) | singleton(ServiceUnavailable) | singleton(TooManyRequests)]
162
184
  JSON_CONTENT_TYPE_REGEXP: Regexp
163
185
 
164
186
  attr_accessor array_class: Class
165
187
  attr_accessor object_class: Class
166
188
  def initialize: (?array_class: Class, ?object_class: Class) -> void
167
- def handle: (Net::HTTPResponse response) -> untyped
168
- def configuration: -> Hash[Symbol, Class]
189
+ def parse: (response: Net::HTTPResponse) -> untyped
169
190
 
170
191
  private
171
- def success?: (Net::HTTPResponse response) -> bool
192
+ def error: (Net::HTTPResponse response) -> (Unauthorized | BadRequest | Forbidden | InternalServerError | NotFound | PayloadTooLarge | ServiceUnavailable | TooManyRequests)
193
+ def error_class: (Net::HTTPResponse response) -> (singleton(Unauthorized) | singleton(BadRequest) | singleton(Forbidden) | singleton(InternalServerError) | singleton(NotFound) | singleton(PayloadTooLarge) | singleton(ServiceUnavailable) | singleton(TooManyRequests))
172
194
  def json?: (Net::HTTPResponse response) -> bool
173
195
  end
174
196
 
175
197
  class Client
198
+ DEFAULT_BASE_URL: String
199
+
176
200
  extend Forwardable
177
- @authenticator: BearerTokenAuthenticator | OauthAuthenticator
201
+ @authenticator: Authenticator
178
202
  @connection: Connection
179
203
  @request_builder: RequestBuilder
180
204
  @redirect_handler: RedirectHandler
181
- @response_handler: ResponseHandler
205
+ @response_parser: ResponseParser
182
206
 
183
207
  attr_accessor access_token: String
184
208
  attr_accessor access_token_secret: String
185
209
  attr_accessor api_key: String
186
210
  attr_accessor api_key_secret: String
187
211
  attr_accessor bearer_token: String
188
- attr_accessor base_uri: URI::Generic | String
212
+ attr_accessor base_url: String
189
213
  attr_accessor open_timeout: Float | Integer
190
214
  attr_accessor read_timeout: Float | Integer
191
215
  attr_accessor write_timeout: Float | Integer
192
216
  attr_accessor proxy_url: String
193
- attr_accessor content_type: String
194
- attr_accessor user_agent: String
195
- attr_accessor debug_output: IO?
217
+ attr_accessor debug_output: IO
196
218
  attr_accessor array_class: Class
197
219
  attr_accessor object_class: Class
198
220
  attr_accessor max_redirects: Integer
199
- attr_accessor authenticator: BearerTokenAuthenticator | OauthAuthenticator
221
+ attr_accessor authenticator: Authenticator
200
222
  attr_accessor connection: Connection
201
223
  attr_accessor request_builder: RequestBuilder
202
224
  attr_accessor redirect_handler: RedirectHandler
203
- attr_accessor response_handler: ResponseHandler
204
- alias base_url base_uri
205
-
225
+ attr_accessor response_parser: ResponseParser
206
226
 
207
- def initialize: (?bearer_token: String?, ?api_key: String?, ?api_key_secret: String?, ?access_token: String?, ?access_token_secret: String?, ?base_url: URI::Generic | String, ?content_type: String, ?user_agent: String, ?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO?, ?array_class: Class, ?object_class: Class, ?max_redirects: Integer) -> void
208
- def get: (String endpoint) -> untyped
209
- def post: (String endpoint, ?String? body) -> untyped
210
- def put: (String endpoint, ?String? body) -> untyped
211
- def delete: (String endpoint) -> untyped
227
+ def initialize: (?api_key: String?, ?api_key_secret: String?, ?access_token: String?, ?access_token_secret: String?, ?bearer_token: String?, ?base_url: String, ?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO, ?array_class: Class, ?object_class: Class, ?max_redirects: Integer) -> void
228
+ def get: (String endpoint, ?headers: Hash[String, String]) -> untyped
229
+ def post: (String endpoint, ?String? body, ?headers: Hash[String, String]) -> untyped
230
+ def put: (String endpoint, ?String? body, ?headers: Hash[String, String]) -> untyped
231
+ def delete: (String endpoint, ?headers: Hash[String, String]) -> untyped
212
232
 
213
233
  private
214
- def initialize_authenticator: (String? bearer_token, String? api_key, String? api_key_secret, String? access_token, String? access_token_secret) -> (BearerTokenAuthenticator | OauthAuthenticator)
215
- def send_request: (Symbol http_method, String endpoint, ?String? body) -> untyped
234
+ def initialize_oauth: (String? api_key, String? api_key_secret, String? access_token, String? access_token_secret) -> void
235
+ def initialize_authenticator: -> Authenticator
236
+ def execute_request: (Symbol http_method, String endpoint, headers: Hash[String, String], ?body: String?) -> untyped
216
237
  end
217
238
 
218
- module MediaUpload
239
+ module MediaUploader
219
240
  MAX_RETRIES: Integer
220
241
  BYTES_PER_MB: Integer
221
242
  MEDIA_CATEGORIES: Array[String]
@@ -235,22 +256,27 @@ module X
235
256
  SUBRIP_MIME_TYPE: String
236
257
  WEBP_MIME_TYPE: String
237
258
  MIME_TYPE_MAP: Hash[String, String]
238
- extend MediaUpload
259
+ extend MediaUploader
239
260
 
240
- def media_upload: (client: Client, file_path: String, media_category: String, ?media_type: String, ?boundary: String) -> untyped
241
- def chunked_media_upload: (client: Client, file_path: String, media_category: String, ?media_type: String, ?boundary: String, ?chunk_size_mb: Integer) -> untyped
261
+ def upload: (client: Client, file_path: String, media_category: String, ?media_type: String, ?boundary: String) -> untyped
262
+ def chunked_upload: (client: Client, file_path: String, media_category: String, ?media_type: String, ?boundary: String, ?chunk_size_mb: Integer) -> untyped
242
263
  def await_processing: (client: Client, media: untyped) -> untyped
243
264
 
244
265
  private
245
266
  def validate!: (file_path: String, media_category: String) -> nil
246
267
  def infer_media_type: (String file_path, String media_category) -> String
247
- def init: (Client upload_client, String file_path, String media_type, String media_category) -> untyped
248
268
  def split: (String file_path, Integer chunk_size) -> Array[String]
249
- def append: (Client upload_client, Array[String] chunk_paths, untyped media, String media_type, ?String boundary) -> Array[String]
250
- def upload_chunk: (Client upload_client, String query, String chunk_path, String media_type, String boundary) -> Integer?
251
- def cleanup_chunk: (String chunk_path) -> Integer?
252
- def finalize: (Client upload_client, untyped media) -> untyped
253
- def construct_upload_body: (String file_path, String media_type, ?String boundary) -> String
269
+ def init: (upload_client: Client, file_path: String, media_type: String, media_category: String) -> untyped
270
+ def append: (upload_client: Client, file_paths: Array[String], media: untyped, media_type: String, ?boundary: String) -> Array[String]
271
+ def upload_chunk: (upload_client: Client, query: String, upload_body: String, file_path: String, ?headers: Hash[String, String]) -> Integer?
272
+ def cleanup_file: (String file_path) -> Integer?
273
+ def finalize: (upload_client: Client, media: untyped) -> untyped
274
+ def construct_upload_body: (file_path: String, media_type: String, ?boundary: String) -> String
275
+ end
276
+
277
+ class CGI
278
+ def self.escape: (String value) -> String
279
+ def self.escape_params: (Hash[String, String] | Array[[String, String]] params) -> String
254
280
  end
255
281
  end
256
282
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: x
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Berlin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-08 00:00:00.000000000 Z
11
+ date: 2023-11-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -23,27 +23,36 @@ files:
23
23
  - bin/console
24
24
  - bin/setup
25
25
  - lib/x.rb
26
+ - lib/x/authenticator.rb
26
27
  - lib/x/bearer_token_authenticator.rb
28
+ - lib/x/cgi.rb
27
29
  - lib/x/client.rb
28
30
  - lib/x/connection.rb
29
- - lib/x/errors/authentication_error.rb
30
- - lib/x/errors/bad_request_error.rb
31
+ - lib/x/errors/bad_gateway.rb
32
+ - lib/x/errors/bad_request.rb
31
33
  - lib/x/errors/client_error.rb
34
+ - lib/x/errors/connection_exception.rb
32
35
  - lib/x/errors/error.rb
33
- - lib/x/errors/forbidden_error.rb
36
+ - lib/x/errors/forbidden.rb
37
+ - lib/x/errors/gateway_timeout.rb
38
+ - lib/x/errors/gone.rb
39
+ - lib/x/errors/http_error.rb
34
40
  - lib/x/errors/internal_server_error.rb
35
41
  - lib/x/errors/network_error.rb
36
- - lib/x/errors/not_found_error.rb
37
- - lib/x/errors/payload_too_large_error.rb
42
+ - lib/x/errors/not_acceptable.rb
43
+ - lib/x/errors/not_found.rb
44
+ - lib/x/errors/payload_too_large.rb
38
45
  - lib/x/errors/server_error.rb
39
- - lib/x/errors/service_unavailable_error.rb
40
- - lib/x/errors/too_many_redirects_error.rb
41
- - lib/x/errors/too_many_requests_error.rb
42
- - lib/x/media_upload.rb
46
+ - lib/x/errors/service_unavailable.rb
47
+ - lib/x/errors/too_many_redirects.rb
48
+ - lib/x/errors/too_many_requests.rb
49
+ - lib/x/errors/unauthorized.rb
50
+ - lib/x/errors/unprocessable_entity.rb
51
+ - lib/x/media_uploader.rb
43
52
  - lib/x/oauth_authenticator.rb
44
53
  - lib/x/redirect_handler.rb
45
54
  - lib/x/request_builder.rb
46
- - lib/x/response_handler.rb
55
+ - lib/x/response_parser.rb
47
56
  - lib/x/version.rb
48
57
  - sig/x.rbs
49
58
  homepage: https://sferik.github.io/x-ruby
@@ -72,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
81
  - !ruby/object:Gem::Version
73
82
  version: '0'
74
83
  requirements: []
75
- rubygems_version: 3.4.20
84
+ rubygems_version: 3.4.21
76
85
  signing_key:
77
86
  specification_version: 4
78
87
  summary: A Ruby interface to the X API.
@@ -1,5 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- class AuthenticationError < ClientError; end
5
- end
@@ -1,5 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- class PayloadTooLargeError < ClientError; end
5
- end
@@ -1,5 +0,0 @@
1
- require_relative "server_error"
2
-
3
- module X
4
- class ServiceUnavailableError < ServerError; end
5
- end
@@ -1,5 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- class TooManyRedirectsError < ClientError; end
5
- end
@@ -1,29 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- # Rate limit error
5
- class TooManyRequestsError < ClientError
6
- def initialize(msg, response:)
7
- @response = response
8
- super
9
- end
10
-
11
- def limit
12
- @response.fetch("x-rate-limit-limit", 0).to_i
13
- end
14
-
15
- def remaining
16
- @response.fetch("x-rate-limit-remaining", 0).to_i
17
- end
18
-
19
- def reset_at
20
- Time.at(@response.fetch("x-rate-limit-reset", 0).to_i).utc
21
- end
22
-
23
- def reset_in
24
- [(reset_at - Time.now).ceil, 0].max if reset_at
25
- end
26
-
27
- alias_method :retry_after, :reset_in
28
- end
29
- end
@@ -1,63 +0,0 @@
1
- require "json"
2
- require "net/http"
3
- require_relative "errors/authentication_error"
4
- require_relative "errors/bad_request_error"
5
- require_relative "errors/forbidden_error"
6
- require_relative "errors/not_found_error"
7
- require_relative "errors/payload_too_large_error"
8
- require_relative "errors/internal_server_error"
9
- require_relative "errors/service_unavailable_error"
10
- require_relative "errors/too_many_requests_error"
11
-
12
- module X
13
- # Process HTTP responses
14
- class ResponseHandler
15
- DEFAULT_ARRAY_CLASS = Array
16
- DEFAULT_OBJECT_CLASS = Hash
17
- ERROR_CLASSES = {
18
- 400 => BadRequestError,
19
- 401 => AuthenticationError,
20
- 403 => ForbiddenError,
21
- 404 => NotFoundError,
22
- 413 => PayloadTooLargeError,
23
- 429 => TooManyRequestsError,
24
- 500 => InternalServerError,
25
- 503 => ServiceUnavailableError
26
- }.freeze
27
- JSON_CONTENT_TYPE_REGEXP = %r{application/(problem\+|)json}
28
-
29
- attr_accessor :array_class, :object_class
30
-
31
- def initialize(array_class: DEFAULT_ARRAY_CLASS, object_class: DEFAULT_OBJECT_CLASS)
32
- @array_class = array_class
33
- @object_class = object_class
34
- end
35
-
36
- def handle(response)
37
- if success?(response)
38
- JSON.parse(response.body, array_class: array_class, object_class: object_class) if json?(response)
39
- else
40
- error_class = ERROR_CLASSES[response.code.to_i] || Error
41
- error_message = "#{response.code} #{response.message}"
42
- raise error_class.new(error_message, response: response)
43
- end
44
- end
45
-
46
- def configuration
47
- {
48
- array_class: array_class,
49
- object_class: object_class
50
- }
51
- end
52
-
53
- private
54
-
55
- def success?(response)
56
- response.is_a?(Net::HTTPSuccess)
57
- end
58
-
59
- def json?(response)
60
- response.body && JSON_CONTENT_TYPE_REGEXP.match?(response["content-type"])
61
- end
62
- end
63
- end