# frozen_string_literal: truerequire"faraday"require"faraday/retry"moduleAttio# HTTP client for making API requests to Attio# Handles authentication, retries, and error responsesclassClientdefinitialize(api_key: nil)@api_key=api_key||Attio.configuration.api_keyraiseAuthenticationError,"No API key provided"unless@api_keyend# Perform a GET request# @param path [String] The API endpoint path# @param params [Hash] Query parameters# @return [Hash] Parsed JSON response# @raise [Error] On API errorsdefget(path,params={})request(:get,path,params)end# Perform a POST request# @param path [String] The API endpoint path# @param body [Hash] Request body to be sent as JSON# @return [Hash] Parsed JSON response# @raise [Error] On API errorsdefpost(path,body={})request(:post,path,body)end# Perform a PUT request# @param path [String] The API endpoint path# @param body [Hash] Request body to be sent as JSON# @return [Hash] Parsed JSON response# @raise [Error] On API errorsdefput(path,body={})request(:put,path,body)end# Perform a PATCH request# @param path [String] The API endpoint path# @param body [Hash] Request body to be sent as JSON# @return [Hash] Parsed JSON response# @raise [Error] On API errorsdefpatch(path,body={})request(:patch,path,body)end# Perform a DELETE request# @param path [String] The API endpoint path# @return [Hash] Parsed JSON response# @raise [Error] On API errorsdefdelete(path)request(:delete,path)endprivatedefrequest(method,path,params_or_body={})response=connection.send(method)do|req|req.urlpathcasemethodwhen:get,:deletereq.params=params_or_bodyifparams_or_body.any?elsereq.body=params_or_body.to_jsonendendhandle_response(response)rescueFaraday::Error=>ehandle_error(e)enddefconnection@connection||=Faraday.new(url: base_url,headers: default_headers)do|faraday|faraday.request:jsonfaraday.response:json,content_type: /\bjson$/faraday.request:retry,max: Attio.configuration.max_retries,interval: 0.5,backoff_factor: 2,exceptions: [Faraday::TimeoutError,Faraday::ConnectionFailed]faraday.response:logger,Attio.configuration.loggerifAttio.configuration.debugfaraday.options.timeout=Attio.configuration.timeoutfaraday.options.open_timeout=Attio.configuration.open_timeoutfaraday.ssl.verify=Attio.configuration.verify_ssl_certsfaraday.ssl.ca_file=Attio.configuration.ca_bundle_pathifAttio.configuration.ca_bundle_pathendenddefbase_url"#{Attio.configuration.api_base}/#{Attio.configuration.api_version}"enddefdefault_headers{"Authorization"=>"Bearer #{@api_key}","User-Agent"=>"Attio Ruby/#{Attio::VERSION}","Accept"=>"application/json","Content-Type"=>"application/json"}enddefhandle_response(response)caseresponse.statuswhen200..299response.bodywhen400error_message=response.body["error"]||response.body["message"]||"Bad request"raiseBadRequestError.new("Bad request: #{error_message}",response_to_hash(response))when401raiseAuthenticationError.new("Authentication failed",response_to_hash(response))when403raiseForbiddenError.new("Access forbidden",response_to_hash(response))when404raiseNotFoundError.new("Resource not found",response_to_hash(response))when409raiseConflictError.new("Resource conflict",response_to_hash(response))when422raiseUnprocessableEntityError.new("Unprocessable entity",response_to_hash(response))when429raiseRateLimitError.new("Rate limit exceeded",response_to_hash(response))when500..599raiseServerError.new("Server error",response_to_hash(response))elseraiseError.new("Unexpected response status: #{response.status}",response_to_hash(response))endenddefhandle_error(error)caseerrorwhenFaraday::TimeoutErrorraiseTimeoutError,"Request timed out"whenFaraday::ConnectionFailedraiseConnectionError,"Connection failed: #{error.message}"elseraiseConnectionError,"Request failed: #{error.message}"endenddefresponse_to_hash(response){status: response.status,headers: response.headers,body: response.body}endendend