x 0.13.0 → 0.14.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f4970075e9256b31a7f53ca6a3a06df7559631b9104c2069372b3797845cd77
4
- data.tar.gz: a0e25d20e521f8a3408b9e04b8826d7f8959257ecf6748687a0d1b0292719f38
3
+ metadata.gz: e7f8185b86c61142faad23edbd1563f5a10263d7f47114d5f31a83e93af805dd
4
+ data.tar.gz: 8df083a42c16683e27d4face3445e3a835663f11600751024a519c3a658ed0ed
5
5
  SHA512:
6
- metadata.gz: 7be87f0b82af146429afa88288f60d53d07185d2ed47f57d534c729758a3bfc426c4a57e11703665eedd19b9d994ce4e51bd4f08e3de84cdc49ca7a2de28eae6
7
- data.tar.gz: 3e28cfc6ee5d244eff7671e0f724c0a07071d1872792d9fb742ee44bcf2fc2f1a797053dc0d2a415a51a625d85629115f71ad003bb3b9fcaf75049cde6b5d0d1
6
+ metadata.gz: 17dda35c335587d569dc1d41c8fe3ca2221e8e1d3b1742a443559c7d558b149e92229d7d767e64bf4a12982f4a3b4d2afb002d9d34db819216e1934eaf48391f
7
+ data.tar.gz: 990d9afb8e30cb0c998765525b47c4bf44779f96f4fbd006903fc9b3fe655d0f50df8aa197c77d9ad05250ded0fc086bb768d4662d539490ab81804d2e86b5f0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## [0.14.0] - 2023-12-08
2
+ * Allow passing custom objects per-request (768889f)
3
+
1
4
  ## [0.13.0] - 2023-12-04
2
5
  * Introduce X::RateLimit, which is returned with X::TooManyRequests errors (196caec)
3
6
 
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Tests](https://github.com/sferik/x-ruby/actions/workflows/test.yml/badge.svg)](https://github.com/sferik/x-ruby/actions/workflows/test.yml)
2
- [![RuboCop](https://github.com/sferik/x-ruby/actions/workflows/rubocop.yml/badge.svg)](https://github.com/sferik/x-ruby/actions/workflows/rubocop.yml)
2
+ [![Linter](https://github.com/sferik/x-ruby/actions/workflows/lint.yml/badge.svg)](https://github.com/sferik/x-ruby/actions/workflows/lint.yml)
3
3
  [![Mutant](https://github.com/sferik/x-ruby/actions/workflows/mutant.yml/badge.svg)](https://github.com/sferik/x-ruby/actions/workflows/mutant.yml)
4
4
  [![Typer Checker](https://github.com/sferik/x-ruby/actions/workflows/steep.yml/badge.svg)](https://github.com/sferik/x-ruby/actions/workflows/steep.yml)
5
5
  [![Gem Version](https://badge.fury.io/rb/x.svg)](https://rubygems.org/gems/x)
@@ -52,8 +52,15 @@ x_client.delete("tweets/#{post["data"]["id"]}")
52
52
  # Initialize an API v1.1 client
53
53
  v1_client = X::Client.new(base_url: "https://api.twitter.com/1.1/", **x_credentials)
54
54
 
55
- # Get your account settings
56
- v1_client.get("account/settings.json")
55
+ # Define a custom response object
56
+ Language = Struct.new(:code, :name, :local_name, :status, :debug)
57
+
58
+ # Parse a response with custom array and object classes
59
+ languages = v1_client.get("help/languages.json", object_class: Language, array_class: Set)
60
+ # #<Set: {#<struct Language code="ur", name="Urdu", local_name="اردو", status="beta", debug=false>, …
61
+
62
+ # Access data with dots instead of brackets
63
+ languages.first.local_name
57
64
 
58
65
  # Initialize an Ads API client
59
66
  ads_client = X::Client.new(base_url: "https://ads-api.twitter.com/12/", **x_credentials)
@@ -149,20 +156,23 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/sferik
149
156
 
150
157
  Pull requests will only be accepted if they meet all the following criteria:
151
158
 
152
- 1. Code must conform to [RuboCop rules](https://github.com/rubocop/rubocop). This can be verified with:
159
+ 1. Code must conform to [Standard Ruby](https://github.com/standardrb/standard#readme). This can be verified with:
160
+
161
+ bundle exec rake standard
162
+
163
+ 2. Code must conform to the [RuboCop rules](https://github.com/rubocop/rubocop#readme). This can be verified with:
153
164
 
154
- bundle exec rubocop
165
+ bundle exec rake rubocop
155
166
 
156
- 2. 100% C0 code coverage. This can be verified with:
167
+ 3. 100% C0 code coverage. This can be verified with:
157
168
 
158
169
  bundle exec rake test
159
170
 
160
- 3. 100% mutation coverage. This can be verified with:
171
+ 4. 100% mutation coverage. This can be verified with:
161
172
 
162
- git remote add upstream https://github.com/sferik/x-ruby
163
173
  bundle exec rake mutant
164
174
 
165
- 4. RBS type signatures (in `sig/x.rbs`). This can be verified with:
175
+ 5. RBS type signatures (in `sig/x.rbs`). This can be verified with:
166
176
 
167
177
  bundle exec rake steep
168
178
 
data/lib/x/client.rb CHANGED
@@ -11,16 +11,16 @@ module X
11
11
  extend Forwardable
12
12
 
13
13
  DEFAULT_BASE_URL = "https://api.twitter.com/2/".freeze
14
+ DEFAULT_ARRAY_CLASS = Array
15
+ DEFAULT_OBJECT_CLASS = Hash
14
16
 
15
- attr_accessor :base_url
17
+ attr_accessor :base_url, :default_array_class, :default_object_class
16
18
  attr_reader :api_key, :api_key_secret, :access_token, :access_token_secret, :bearer_token
17
19
 
18
20
  def_delegators :@connection, :open_timeout, :read_timeout, :write_timeout, :proxy_url, :debug_output
19
21
  def_delegators :@connection, :open_timeout=, :read_timeout=, :write_timeout=, :proxy_url=, :debug_output=
20
22
  def_delegators :@redirect_handler, :max_redirects
21
23
  def_delegators :@redirect_handler, :max_redirects=
22
- def_delegators :@response_parser, :array_class, :object_class
23
- def_delegators :@response_parser, :array_class=, :object_class=
24
24
 
25
25
  def initialize(api_key: nil, api_key_secret: nil, access_token: nil, access_token_secret: nil,
26
26
  bearer_token: nil,
@@ -30,36 +30,38 @@ module X
30
30
  write_timeout: Connection::DEFAULT_WRITE_TIMEOUT,
31
31
  debug_output: Connection::DEFAULT_DEBUG_OUTPUT,
32
32
  proxy_url: nil,
33
- array_class: nil,
34
- object_class: nil,
33
+ default_array_class: DEFAULT_ARRAY_CLASS,
34
+ default_object_class: DEFAULT_OBJECT_CLASS,
35
35
  max_redirects: RedirectHandler::DEFAULT_MAX_REDIRECTS)
36
36
 
37
- initialize_oauth(api_key, api_key_secret, access_token, access_token_secret)
38
- @bearer_token = bearer_token
37
+ initialize_oauth(api_key, api_key_secret, access_token, access_token_secret, bearer_token)
39
38
  initialize_authenticator
40
39
  @base_url = base_url
40
+ initialize_default_classes(default_array_class, default_object_class)
41
41
  @connection = Connection.new(open_timeout: open_timeout, read_timeout: read_timeout,
42
42
  write_timeout: write_timeout, debug_output: debug_output, proxy_url: proxy_url)
43
43
  @request_builder = RequestBuilder.new
44
44
  @redirect_handler = RedirectHandler.new(connection: @connection, request_builder: @request_builder,
45
45
  max_redirects: max_redirects)
46
- @response_parser = ResponseParser.new(array_class: array_class, object_class: object_class)
46
+ @response_parser = ResponseParser.new
47
47
  end
48
48
 
49
- def get(endpoint, headers: {})
50
- execute_request(:get, endpoint, headers: headers)
49
+ def get(endpoint, headers: {}, array_class: default_array_class, object_class: default_object_class)
50
+ execute_request(:get, endpoint, headers: headers, array_class: array_class, object_class: object_class)
51
51
  end
52
52
 
53
- def post(endpoint, body = nil, headers: {})
54
- execute_request(:post, endpoint, body: body, headers: headers)
53
+ def post(endpoint, body = nil, headers: {}, array_class: default_array_class, object_class: default_object_class)
54
+ execute_request(:post, endpoint, body: body, headers: headers, array_class: array_class,
55
+ object_class: object_class)
55
56
  end
56
57
 
57
- def put(endpoint, body = nil, headers: {})
58
- execute_request(:put, endpoint, body: body, headers: headers)
58
+ def put(endpoint, body = nil, headers: {}, array_class: default_array_class, object_class: default_object_class)
59
+ execute_request(:put, endpoint, body: body, headers: headers, array_class: array_class,
60
+ object_class: object_class)
59
61
  end
60
62
 
61
- def delete(endpoint, headers: {})
62
- execute_request(:delete, endpoint, headers: headers)
63
+ def delete(endpoint, headers: {}, array_class: default_array_class, object_class: default_object_class)
64
+ execute_request(:delete, endpoint, headers: headers, array_class: array_class, object_class: object_class)
63
65
  end
64
66
 
65
67
  def api_key=(api_key)
@@ -89,11 +91,17 @@ module X
89
91
 
90
92
  private
91
93
 
92
- def initialize_oauth(api_key, api_key_secret, access_token, access_token_secret)
94
+ def initialize_oauth(api_key, api_key_secret, access_token, access_token_secret, bearer_token)
93
95
  @api_key = api_key
94
96
  @api_key_secret = api_key_secret
95
97
  @access_token = access_token
96
98
  @access_token_secret = access_token_secret
99
+ @bearer_token = bearer_token
100
+ end
101
+
102
+ def initialize_default_classes(default_array_class, default_object_class)
103
+ @default_array_class = default_array_class
104
+ @default_object_class = default_object_class
97
105
  end
98
106
 
99
107
  def initialize_authenticator
@@ -109,14 +117,14 @@ module X
109
117
  end
110
118
  end
111
119
 
112
- def execute_request(http_method, endpoint, headers:, body: nil)
120
+ def execute_request(http_method, endpoint, body: nil, headers: {}, array_class: default_array_class, object_class: default_object_class)
113
121
  uri = URI.join(base_url, endpoint)
114
122
  request = @request_builder.build(http_method: http_method, uri: uri, body: body, headers: headers,
115
123
  authenticator: @authenticator)
116
124
  response = @connection.perform(request: request)
117
125
  response = @redirect_handler.handle(response: response, request: request, base_url: base_url,
118
126
  authenticator: @authenticator)
119
- @response_parser.parse(response: response)
127
+ @response_parser.parse(response: response, array_class: array_class, object_class: object_class)
120
128
  end
121
129
  end
122
130
  end
@@ -36,14 +36,7 @@ module X
36
36
  }.freeze
37
37
  JSON_CONTENT_TYPE_REGEXP = %r{application/json}
38
38
 
39
- attr_accessor :array_class, :object_class
40
-
41
- def initialize(array_class: nil, object_class: nil)
42
- @array_class = array_class
43
- @object_class = object_class
44
- end
45
-
46
- def parse(response:)
39
+ def parse(response:, array_class: nil, object_class: nil)
47
40
  raise error(response) unless response.is_a?(Net::HTTPSuccess)
48
41
 
49
42
  return unless json?(response)
data/lib/x/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "rubygems/version"
2
2
 
3
3
  module X
4
- VERSION = Gem::Version.create("0.13.0")
4
+ VERSION = Gem::Version.create("0.14.0")
5
5
  end
data/sig/x.rbs CHANGED
@@ -193,15 +193,10 @@ module X
193
193
  end
194
194
 
195
195
  class ResponseParser
196
- DEFAULT_ARRAY_CLASS: Class
197
- DEFAULT_OBJECT_CLASS: Class
198
196
  ERROR_MAP: Hash[Integer, singleton(Unauthorized) | singleton(BadRequest) | singleton(Forbidden) | singleton(InternalServerError) | singleton(NotFound) | singleton(PayloadTooLarge) | singleton(ServiceUnavailable) | singleton(TooManyRequests)]
199
197
  JSON_CONTENT_TYPE_REGEXP: Regexp
200
198
 
201
- attr_accessor array_class: Class
202
- attr_accessor object_class: Class
203
- def initialize: (?array_class: Class, ?object_class: Class) -> void
204
- def parse: (response: Net::HTTPResponse) -> untyped
199
+ def parse: (response: Net::HTTPResponse, ?array_class: Class?, ?object_class: Class?) -> untyped
205
200
 
206
201
  private
207
202
  def error: (Net::HTTPResponse response) -> (Unauthorized | BadRequest | Forbidden | InternalServerError | NotFound | PayloadTooLarge | ServiceUnavailable | TooManyRequests)
@@ -211,6 +206,8 @@ module X
211
206
 
212
207
  class Client
213
208
  DEFAULT_BASE_URL: String
209
+ DEFAULT_ARRAY_CLASS: Class
210
+ DEFAULT_OBJECT_CLASS: Class
214
211
 
215
212
  extend Forwardable
216
213
  @authenticator: Authenticator
@@ -230,8 +227,8 @@ module X
230
227
  attr_accessor write_timeout: Float | Integer
231
228
  attr_accessor proxy_url: String
232
229
  attr_accessor debug_output: IO
233
- attr_accessor array_class: Class
234
- attr_accessor object_class: Class
230
+ attr_accessor default_array_class: Class
231
+ attr_accessor default_object_class: Class
235
232
  attr_accessor max_redirects: Integer
236
233
  attr_accessor authenticator: Authenticator
237
234
  attr_accessor connection: Connection
@@ -239,16 +236,17 @@ module X
239
236
  attr_accessor redirect_handler: RedirectHandler
240
237
  attr_accessor response_parser: ResponseParser
241
238
 
242
- 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
243
- def get: (String endpoint, ?headers: Hash[String, String]) -> untyped
244
- def post: (String endpoint, ?String? body, ?headers: Hash[String, String]) -> untyped
245
- def put: (String endpoint, ?String? body, ?headers: Hash[String, String]) -> untyped
246
- def delete: (String endpoint, ?headers: Hash[String, String]) -> untyped
239
+ 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, ?default_array_class: Class, ?default_object_class: Class, ?max_redirects: Integer) -> void
240
+ def get: (String endpoint, ?headers: Hash[String, String], ?array_class: Class, ?object_class: Class) -> untyped
241
+ def post: (String endpoint, ?String? body, ?headers: Hash[String, String], ?array_class: Class, ?object_class: Class) -> untyped
242
+ def put: (String endpoint, ?String? body, ?headers: Hash[String, String], ?array_class: Class, ?object_class: Class) -> untyped
243
+ def delete: (String endpoint, ?headers: Hash[String, String], ?array_class: Class, ?object_class: Class) -> untyped
247
244
 
248
245
  private
249
- def initialize_oauth: (String? api_key, String? api_key_secret, String? access_token, String? access_token_secret) -> void
246
+ def initialize_oauth: (String? api_key, String? api_key_secret, String? access_token, String? access_token_secret, String? bearer_token) -> void
247
+ def initialize_default_classes: (Class? default_array_class, Class? default_object_class) -> void
250
248
  def initialize_authenticator: -> Authenticator
251
- def execute_request: (Symbol http_method, String endpoint, headers: Hash[String, String], ?body: String?) -> untyped
249
+ def execute_request: (Symbol http_method, String endpoint, ?body: String?, ?headers: Hash[String, String], ?array_class: Class?, ?object_class: Class?) -> untyped
252
250
  end
253
251
 
254
252
  module MediaUploader
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.13.0
4
+ version: 0.14.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-12-04 00:00:00.000000000 Z
11
+ date: 2023-12-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: