x 0.4.0 → 0.5.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/lib/x/client.rb +16 -48
- data/lib/x/client_defaults.rb +2 -1
- data/lib/x/connection.rb +27 -8
- data/lib/x/errors/error.rb +6 -2
- data/lib/x/errors/errors.rb +1 -0
- data/lib/x/errors/too_many_requests_error.rb +4 -2
- data/lib/x/request_builder.rb +32 -3
- data/lib/x/response_handler.rb +17 -11
- data/lib/x/version.rb +3 -37
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ff49ecaad847aef0d9da4bdfc4f89cc3bc54da5edbadab40be265e9ec2ec1cf6
         | 
| 4 | 
            +
              data.tar.gz: 1ddef9c1479654f53ed7a889cb33b3d1e4d972c005c4f631726bb4270721c2b0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 406e9aaa6f6166f9d267718ac22e94324b243c85475b30cb7569db957683014644542a3b44a6a3d337f0658a1204e8656b1b0c4ed2355b12ffc195c34b0734e4
         | 
| 7 | 
            +
              data.tar.gz: b0754554e6272ef9b9ede3f650c3c407b71ae6ed8ede70d6da314ca408874898e83c2d6c14b31335817b0fb036422adde8ccefe3c13c274794c2e08229196812
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,10 @@ | |
| 1 1 | 
             
            ## [Unreleased]
         | 
| 2 2 |  | 
| 3 | 
            +
            ## [0.5.0] - 2023-08-10
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            - Add configurable write timeout (2a31f84)
         | 
| 6 | 
            +
            - Use built-in Gem::Version class (066e0b6)
         | 
| 7 | 
            +
             | 
| 3 8 | 
             
            ## [0.4.0] - 2023-08-06
         | 
| 4 9 |  | 
| 5 10 | 
             
            - Refactor Client into Authenticator, RequestBuilder, Connection, ResponseHandler (6bee1e9)
         | 
    
        data/README.md
    CHANGED
    
    | @@ -52,7 +52,7 @@ ads_client.get("accounts") | |
| 52 52 |  | 
| 53 53 | 
             
            ## History and Philosophy
         | 
| 54 54 |  | 
| 55 | 
            -
            This library is a rewrite of the [Twitter Ruby library](https://github.com/sferik/twitter). Over 16 years, that library ballooned to over 3,000 lines of code (plus 7,500 lines of tests). At the time of writing, this library is about  | 
| 55 | 
            +
            This library is a rewrite of the [Twitter Ruby library](https://github.com/sferik/twitter). Over 16 years, that library ballooned to over 3,000 lines of code (plus 7,500 lines of tests). At the time of writing, this library is about 300 lines of code (plus 200 test lines) and I’d like to keep it that way. That doesn’t mean new features won’t be added over time, but the benefits of potential new features must be weighed against the benefits of simplicity:
         | 
| 56 56 |  | 
| 57 57 | 
             
            * Less code is easier to maintain.
         | 
| 58 58 | 
             
            * Less code means fewer bugs.
         | 
    
        data/lib/x/client.rb
    CHANGED
    
    | @@ -11,26 +11,25 @@ module X | |
| 11 11 | 
             
                extend Forwardable
         | 
| 12 12 | 
             
                include ClientDefaults
         | 
| 13 13 |  | 
| 14 | 
            -
                attr_reader :base_url
         | 
| 15 | 
            -
                attr_accessor :content_type, :open_timeout, :read_timeout, :user_agent, :array_class, :object_class
         | 
| 16 | 
            -
             | 
| 17 14 | 
             
                def_delegators :@authenticator, :bearer_token, :api_key, :api_key_secret, :access_token, :access_token_secret
         | 
| 18 15 | 
             
                def_delegators :@authenticator, :bearer_token=, :api_key=, :api_key_secret=, :access_token=, :access_token_secret=
         | 
| 16 | 
            +
                def_delegators :@connection, :base_url, :open_timeout, :read_timeout, :write_timeout
         | 
| 17 | 
            +
                def_delegators :@connection, :base_url=, :open_timeout=, :read_timeout=, :write_timeout=
         | 
| 18 | 
            +
                def_delegators :@request_builder, :content_type, :user_agent
         | 
| 19 | 
            +
                def_delegators :@request_builder, :content_type=, :user_agent=
         | 
| 20 | 
            +
                def_delegators :@response_handler, :array_class, :object_class
         | 
| 21 | 
            +
                def_delegators :@response_handler, :array_class=, :object_class=
         | 
| 19 22 |  | 
| 20 23 | 
             
                def initialize(bearer_token: nil, api_key: nil, api_key_secret: nil, access_token: nil, access_token_secret: nil,
         | 
| 21 | 
            -
                  base_url: DEFAULT_BASE_URL, content_type: DEFAULT_CONTENT_TYPE,
         | 
| 22 | 
            -
                  open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT,  | 
| 24 | 
            +
                  base_url: DEFAULT_BASE_URL, content_type: DEFAULT_CONTENT_TYPE, user_agent: DEFAULT_USER_AGENT,
         | 
| 25 | 
            +
                  open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT, write_timeout: DEFAULT_WRITE_TIMEOUT,
         | 
| 23 26 | 
             
                  array_class: DEFAULT_ARRAY_CLASS, object_class: DEFAULT_OBJECT_CLASS)
         | 
| 24 | 
            -
             | 
| 25 27 | 
             
                  @authenticator = Authenticator.new(bearer_token: bearer_token, api_key: api_key, api_key_secret: api_key_secret,
         | 
| 26 28 | 
             
                    access_token: access_token, access_token_secret: access_token_secret)
         | 
| 27 | 
            -
                   | 
| 28 | 
            -
             | 
| 29 | 
            -
                  @ | 
| 30 | 
            -
                  @ | 
| 31 | 
            -
                  @user_agent = user_agent
         | 
| 32 | 
            -
                  @array_class = array_class
         | 
| 33 | 
            -
                  @object_class = object_class
         | 
| 29 | 
            +
                  @connection = Connection.new(base_url: base_url, open_timeout: open_timeout, read_timeout: read_timeout,
         | 
| 30 | 
            +
                    write_timeout: write_timeout)
         | 
| 31 | 
            +
                  @request_builder = RequestBuilder.new(content_type: content_type, user_agent: user_agent)
         | 
| 32 | 
            +
                  @response_handler = ResponseHandler.new(array_class: array_class, object_class: object_class)
         | 
| 34 33 | 
             
                end
         | 
| 35 34 |  | 
| 36 35 | 
             
                def get(endpoint)
         | 
| @@ -49,44 +48,13 @@ module X | |
| 49 48 | 
             
                  send_request(:delete, endpoint)
         | 
| 50 49 | 
             
                end
         | 
| 51 50 |  | 
| 52 | 
            -
                def base_url=(new_base_url)
         | 
| 53 | 
            -
                  uri = URI(new_base_url)
         | 
| 54 | 
            -
                  raise ArgumentError, "Invalid base URL" unless uri.is_a?(URI::HTTPS) || uri.is_a?(URI::HTTP)
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                  @base_url = uri
         | 
| 57 | 
            -
                end
         | 
| 58 | 
            -
             | 
| 59 51 | 
             
                private
         | 
| 60 52 |  | 
| 61 53 | 
             
                def send_request(http_method, endpoint, body = nil)
         | 
| 62 | 
            -
                  request =  | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
                   | 
| 66 | 
            -
             | 
| 67 | 
            -
                  ResponseHandler.new(response, @array_class, @object_class).handle
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                def add_headers(request)
         | 
| 71 | 
            -
                  add_authorization(request)
         | 
| 72 | 
            -
                  add_content_type(request)
         | 
| 73 | 
            -
                  add_user_agent(request)
         | 
| 74 | 
            -
                end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                def add_authorization(request)
         | 
| 77 | 
            -
                  if @authenticator.bearer_token
         | 
| 78 | 
            -
                    request["Authorization"] = "Bearer #{@bearer_token}"
         | 
| 79 | 
            -
                  else
         | 
| 80 | 
            -
                    @authenticator.sign!(request)
         | 
| 81 | 
            -
                  end
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                def add_content_type(request)
         | 
| 85 | 
            -
                  request["Content-Type"] = @content_type if @content_type
         | 
| 86 | 
            -
                end
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                def add_user_agent(request)
         | 
| 89 | 
            -
                  request["User-Agent"] = @user_agent if @user_agent
         | 
| 54 | 
            +
                  request = @request_builder.build(authenticator: @authenticator, http_method: http_method, base_url: base_url,
         | 
| 55 | 
            +
                    endpoint: endpoint, body: body)
         | 
| 56 | 
            +
                  response = @connection.send_request(request: request)
         | 
| 57 | 
            +
                  @response_handler.handle(response: response)
         | 
| 90 58 | 
             
                end
         | 
| 91 59 | 
             
              end
         | 
| 92 60 | 
             
            end
         | 
    
        data/lib/x/client_defaults.rb
    CHANGED
    
    | @@ -8,6 +8,7 @@ module X | |
| 8 8 | 
             
                DEFAULT_OBJECT_CLASS = Hash
         | 
| 9 9 | 
             
                DEFAULT_OPEN_TIMEOUT = 60 # seconds
         | 
| 10 10 | 
             
                DEFAULT_READ_TIMEOUT = 60 # seconds
         | 
| 11 | 
            -
                 | 
| 11 | 
            +
                DEFAULT_WRITE_TIMEOUT = 60 # seconds
         | 
| 12 | 
            +
                DEFAULT_USER_AGENT = "X-Client/#{VERSION} Ruby/#{RUBY_VERSION}".freeze
         | 
| 12 13 | 
             
              end
         | 
| 13 14 | 
             
            end
         | 
    
        data/lib/x/connection.rb
    CHANGED
    
    | @@ -1,21 +1,40 @@ | |
| 1 | 
            +
            require "forwardable"
         | 
| 1 2 | 
             
            require "net/http"
         | 
| 2 | 
            -
             | 
| 3 | 
            +
            require "uri"
         | 
| 3 4 | 
             
            require_relative "errors/errors"
         | 
| 5 | 
            +
            require_relative "errors/network_error"
         | 
| 4 6 |  | 
| 5 7 | 
             
            module X
         | 
| 6 8 | 
             
              # Sends HTTP requests
         | 
| 7 9 | 
             
              class Connection
         | 
| 10 | 
            +
                extend Forwardable
         | 
| 8 11 | 
             
                include Errors
         | 
| 9 12 |  | 
| 10 | 
            -
                 | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                   | 
| 13 | 
            +
                attr_reader :base_url
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def_delegators :@http_client, :open_timeout, :read_timeout, :write_timeout
         | 
| 16 | 
            +
                def_delegators :@http_client, :open_timeout=, :read_timeout=, :write_timeout=
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def initialize(base_url:, open_timeout:, read_timeout:, write_timeout:)
         | 
| 19 | 
            +
                  self.base_url = URI(base_url)
         | 
| 20 | 
            +
                  @http_client = Net::HTTP.new(@base_url.host, @base_url.port)
         | 
| 21 | 
            +
                  @http_client.use_ssl = @base_url.scheme == "https"
         | 
| 22 | 
            +
                  @http_client.open_timeout = open_timeout
         | 
| 23 | 
            +
                  @http_client.read_timeout = read_timeout
         | 
| 24 | 
            +
                  @http_client.write_timeout = write_timeout
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def send_request(request:)
         | 
| 28 | 
            +
                  @http_client.request(request)
         | 
| 17 29 | 
             
                rescue *NETWORK_ERRORS => e
         | 
| 18 30 | 
             
                  raise NetworkError, "Network error: #{e.message}"
         | 
| 19 31 | 
             
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def base_url=(new_base_url)
         | 
| 34 | 
            +
                  uri = URI(new_base_url)
         | 
| 35 | 
            +
                  raise ArgumentError, "Invalid base URL" unless uri.is_a?(URI::HTTPS) || uri.is_a?(URI::HTTP)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  @base_url = uri
         | 
| 38 | 
            +
                end
         | 
| 20 39 | 
             
              end
         | 
| 21 40 | 
             
            end
         | 
    
        data/lib/x/errors/error.rb
    CHANGED
    
    | @@ -1,4 +1,6 @@ | |
| 1 1 | 
             
            require "json"
         | 
| 2 | 
            +
            require "net/http"
         | 
| 3 | 
            +
            require_relative "../client_defaults"
         | 
| 2 4 |  | 
| 3 5 | 
             
            module X
         | 
| 4 6 | 
             
              # Base error class
         | 
| @@ -6,8 +8,10 @@ module X | |
| 6 8 | 
             
                include ClientDefaults
         | 
| 7 9 | 
             
                attr_reader :object
         | 
| 8 10 |  | 
| 9 | 
            -
                def initialize(msg = nil, response  | 
| 10 | 
            -
                   | 
| 11 | 
            +
                def initialize(msg = nil, response: nil, array_class: DEFAULT_ARRAY_CLASS, object_class: DEFAULT_OBJECT_CLASS)
         | 
| 12 | 
            +
                  if json_response?(response)
         | 
| 13 | 
            +
                    @object = JSON.parse(response.body, array_class: array_class, object_class: object_class)
         | 
| 14 | 
            +
                  end
         | 
| 11 15 | 
             
                  super(msg)
         | 
| 12 16 | 
             
                end
         | 
| 13 17 |  | 
    
        data/lib/x/errors/errors.rb
    CHANGED
    
    
| @@ -1,10 +1,12 @@ | |
| 1 | 
            -
            require "net/http"
         | 
| 2 1 | 
             
            require_relative "client_error"
         | 
| 2 | 
            +
            require_relative "../client_defaults"
         | 
| 3 3 |  | 
| 4 4 | 
             
            module X
         | 
| 5 5 | 
             
              # Rate limit error
         | 
| 6 6 | 
             
              class TooManyRequestsError < ClientError
         | 
| 7 | 
            -
                 | 
| 7 | 
            +
                include ClientDefaults
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(msg = nil, response: nil, array_class: DEFAULT_ARRAY_CLASS, object_class: DEFAULT_OBJECT_CLASS)
         | 
| 8 10 | 
             
                  @response = response
         | 
| 9 11 | 
             
                  super
         | 
| 10 12 | 
             
                end
         | 
    
        data/lib/x/request_builder.rb
    CHANGED
    
    | @@ -11,12 +11,25 @@ module X | |
| 11 11 | 
             
                  delete: Net::HTTP::Delete
         | 
| 12 12 | 
             
                }.freeze
         | 
| 13 13 |  | 
| 14 | 
            -
                 | 
| 14 | 
            +
                attr_accessor :content_type, :user_agent
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def initialize(content_type:, user_agent:)
         | 
| 17 | 
            +
                  @content_type = content_type
         | 
| 18 | 
            +
                  @user_agent = user_agent
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def build(authenticator:, http_method:, base_url:, endpoint:, body: nil)
         | 
| 15 22 | 
             
                  url = URI.join(base_url, endpoint)
         | 
| 16 | 
            -
                  create_request(http_method, url, body)
         | 
| 23 | 
            +
                  request = create_request(http_method, url, body)
         | 
| 24 | 
            +
                  add_authorization(authenticator, request)
         | 
| 25 | 
            +
                  add_content_type(request)
         | 
| 26 | 
            +
                  add_user_agent(request)
         | 
| 27 | 
            +
                  request
         | 
| 17 28 | 
             
                end
         | 
| 18 29 |  | 
| 19 | 
            -
                 | 
| 30 | 
            +
                private
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def create_request(http_method, url, body)
         | 
| 20 33 | 
             
                  http_method_class = HTTP_METHODS[http_method]
         | 
| 21 34 |  | 
| 22 35 | 
             
                  raise ArgumentError, "Unsupported HTTP method: #{http_method}" unless http_method_class
         | 
| @@ -25,5 +38,21 @@ module X | |
| 25 38 | 
             
                  request.body = body if body && http_method != :get
         | 
| 26 39 | 
             
                  request
         | 
| 27 40 | 
             
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def add_authorization(authenticator, request)
         | 
| 43 | 
            +
                  if authenticator.bearer_token
         | 
| 44 | 
            +
                    request["Authorization"] = "Bearer #{@bearer_token}"
         | 
| 45 | 
            +
                  else
         | 
| 46 | 
            +
                    authenticator.sign!(request)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def add_content_type(request)
         | 
| 51 | 
            +
                  request["Content-Type"] = content_type if content_type
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def add_user_agent(request)
         | 
| 55 | 
            +
                  request["User-Agent"] = user_agent if user_agent
         | 
| 56 | 
            +
                end
         | 
| 28 57 | 
             
              end
         | 
| 29 58 | 
             
            end
         | 
    
        data/lib/x/response_handler.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            require "json"
         | 
| 2 | 
            +
            require "net/http"
         | 
| 2 3 | 
             
            require_relative "errors/errors"
         | 
| 3 4 |  | 
| 4 5 | 
             
            module X
         | 
| @@ -7,28 +8,33 @@ module X | |
| 7 8 | 
             
                include ClientDefaults
         | 
| 8 9 | 
             
                include Errors
         | 
| 9 10 |  | 
| 10 | 
            -
                 | 
| 11 | 
            -
             | 
| 11 | 
            +
                attr_accessor :array_class, :object_class
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def initialize(array_class:, object_class:)
         | 
| 12 14 | 
             
                  @array_class = array_class
         | 
| 13 15 | 
             
                  @object_class = object_class
         | 
| 14 16 | 
             
                end
         | 
| 15 17 |  | 
| 16 | 
            -
                def handle
         | 
| 17 | 
            -
                  if successful_json_response?
         | 
| 18 | 
            -
                    return JSON.parse( | 
| 18 | 
            +
                def handle(response:)
         | 
| 19 | 
            +
                  if successful_json_response?(response)
         | 
| 20 | 
            +
                    return JSON.parse(response.body, array_class: array_class, object_class: object_class)
         | 
| 19 21 | 
             
                  end
         | 
| 20 22 |  | 
| 21 | 
            -
                  error_class = ERROR_CLASSES[ | 
| 22 | 
            -
                  error_message = "#{ | 
| 23 | 
            -
                  raise error_class, error_message if  | 
| 23 | 
            +
                  error_class = ERROR_CLASSES[response.code.to_i] || Error
         | 
| 24 | 
            +
                  error_message = "#{response.code} #{response.message}"
         | 
| 25 | 
            +
                  raise error_class, error_message if empty_response_body?(response)
         | 
| 24 26 |  | 
| 25 | 
            -
                  raise error_class.new(error_message,  | 
| 27 | 
            +
                  raise error_class.new(error_message, response: response, array_class: array_class, object_class: object_class)
         | 
| 26 28 | 
             
                end
         | 
| 27 29 |  | 
| 28 30 | 
             
                private
         | 
| 29 31 |  | 
| 30 | 
            -
                def successful_json_response?
         | 
| 31 | 
            -
                   | 
| 32 | 
            +
                def successful_json_response?(response)
         | 
| 33 | 
            +
                  response.is_a?(Net::HTTPSuccess) && response.body && response["content-type"] == DEFAULT_CONTENT_TYPE
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def empty_response_body?(response)
         | 
| 37 | 
            +
                  response.body.nil? || response.body.empty?
         | 
| 32 38 | 
             
                end
         | 
| 33 39 | 
             
              end
         | 
| 34 40 | 
             
            end
         | 
    
        data/lib/x/version.rb
    CHANGED
    
    | @@ -1,39 +1,5 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
              # The version of this library
         | 
| 3 | 
            -
              module Version
         | 
| 4 | 
            -
                module_function
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                def major
         | 
| 7 | 
            -
                  0
         | 
| 8 | 
            -
                end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                def minor
         | 
| 11 | 
            -
                  4
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                def patch
         | 
| 15 | 
            -
                  0
         | 
| 16 | 
            -
                end
         | 
| 1 | 
            +
            require "rubygems/version"
         | 
| 17 2 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                def to_h
         | 
| 23 | 
            -
                  {
         | 
| 24 | 
            -
                    major: major,
         | 
| 25 | 
            -
                    minor: minor,
         | 
| 26 | 
            -
                    patch: patch,
         | 
| 27 | 
            -
                    pre: pre
         | 
| 28 | 
            -
                  }
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                def to_a
         | 
| 32 | 
            -
                  [major, minor, patch, pre].compact
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def to_s
         | 
| 36 | 
            -
                  to_a.join(".")
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 3 | 
            +
            module X
         | 
| 4 | 
            +
              VERSION = Gem::Version.create("0.5.0")
         | 
| 39 5 | 
             
            end
         | 
    
        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. | 
| 4 | 
            +
              version: 0.5.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-08- | 
| 11 | 
            +
            date: 2023-08-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: oauth
         |