x 0.10.0 → 0.12.0

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