From 9dc9569385307fa31597a0da5ca0f5819925b3f7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 16:55:16 +0000 Subject: [PATCH 1/5] chore(internal): version bump (#80) --- sig/finch-api/version.rbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sig/finch-api/version.rbs b/sig/finch-api/version.rbs index 09587fe7..d9d5fcd3 100644 --- a/sig/finch-api/version.rbs +++ b/sig/finch-api/version.rbs @@ -1,3 +1,3 @@ module FinchAPI - VERSION: "0.1.0-alpha.3" + VERSION: "0.1.0-alpha.4" end From 899a7c0fdf4968dcc552fb5dedfb0c5809562b06 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 17:17:33 +0000 Subject: [PATCH 2/5] chore: relocate internal modules (#82) --- lib/finch-api.rb | 17 +- lib/finch-api/base_client.rb | 457 ------- lib/finch-api/base_model.rb | 1174 ----------------- lib/finch-api/base_page.rb | 59 - lib/finch-api/client.rb | 2 +- lib/finch-api/individuals_page.rb | 8 +- .../models/access_token_create_params.rb | 2 +- .../models/account_disconnect_params.rb | 2 +- .../models/account_introspect_params.rb | 2 +- .../models/connect/session_new_params.rb | 2 +- .../connect/session_reauthenticate_params.rb | 2 +- .../models/hris/benefit_create_params.rb | 2 +- .../models/hris/benefit_list_params.rb | 2 +- .../benefit_list_supported_benefits_params.rb | 2 +- .../models/hris/benefit_retrieve_params.rb | 2 +- .../models/hris/benefit_update_params.rb | 2 +- .../benefits/individual_enroll_many_params.rb | 2 +- .../individual_enrolled_ids_params.rb | 2 +- ...ndividual_retrieve_many_benefits_params.rb | 2 +- .../individual_unenroll_many_params.rb | 2 +- .../models/hris/company_retrieve_params.rb | 2 +- .../hris/directory_list_individuals_params.rb | 2 +- .../models/hris/directory_list_params.rb | 2 +- .../models/hris/document_list_params.rb | 2 +- .../models/hris/document_retreive_params.rb | 2 +- .../hris/employment_retrieve_many_params.rb | 2 +- .../hris/individual_retrieve_many_params.rb | 2 +- .../pay_statement_retrieve_many_params.rb | 2 +- .../models/hris/payment_list_params.rb | 2 +- .../models/jobs/automated_create_params.rb | 2 +- .../models/jobs/automated_list_params.rb | 2 +- .../models/jobs/automated_retrieve_params.rb | 2 +- .../models/jobs/manual_retrieve_params.rb | 2 +- .../models/payroll/pay_group_list_params.rb | 2 +- .../payroll/pay_group_retrieve_params.rb | 2 +- lib/finch-api/models/provider_list_params.rb | 2 +- .../request_forwarding_forward_params.rb | 2 +- .../models/sandbox/company_update_params.rb | 2 +- .../sandbox/connection_create_params.rb | 2 +- .../connections/account_create_params.rb | 2 +- .../connections/account_update_params.rb | 2 +- .../models/sandbox/directory_create_params.rb | 2 +- .../sandbox/employment_update_params.rb | 2 +- .../sandbox/individual_update_params.rb | 2 +- .../models/sandbox/job_create_params.rb | 2 +- .../jobs/configuration_retrieve_params.rb | 2 +- .../jobs/configuration_update_params.rb | 2 +- .../models/sandbox/payment_create_params.rb | 2 +- lib/finch-api/page.rb | 8 +- lib/finch-api/pooled_net_requester.rb | 180 --- lib/finch-api/request_options.rb | 33 - lib/finch-api/responses_page.rb | 6 +- lib/finch-api/single_page.rb | 6 +- lib/finch-api/transport/base_client.rb | 459 +++++++ .../transport/pooled_net_requester.rb | 182 +++ lib/finch-api/type.rb | 23 + lib/finch-api/type/array_of.rb | 110 ++ lib/finch-api/type/base_model.rb | 355 +++++ lib/finch-api/type/base_page.rb | 61 + lib/finch-api/type/boolean_model.rb | 52 + lib/finch-api/type/converter.rb | 211 +++ lib/finch-api/type/enum.rb | 105 ++ lib/finch-api/type/hash_of.rb | 136 ++ lib/finch-api/type/request_parameters.rb | 38 + lib/finch-api/type/union.rb | 204 +++ lib/finch-api/type/unknown.rb | 56 + rbi/lib/finch-api/base_client.rbi | 196 --- rbi/lib/finch-api/base_model.rbi | 609 --------- rbi/lib/finch-api/base_page.rbi | 36 - rbi/lib/finch-api/client.rbi | 2 +- rbi/lib/finch-api/individuals_page.rbi | 2 +- .../models/access_token_create_params.rbi | 2 +- .../models/account_disconnect_params.rbi | 2 +- .../models/account_introspect_params.rbi | 2 +- .../models/connect/session_new_params.rbi | 2 +- .../connect/session_reauthenticate_params.rbi | 2 +- .../models/hris/benefit_create_params.rbi | 2 +- .../models/hris/benefit_list_params.rbi | 2 +- ...benefit_list_supported_benefits_params.rbi | 2 +- .../models/hris/benefit_retrieve_params.rbi | 2 +- .../models/hris/benefit_update_params.rbi | 2 +- .../individual_enroll_many_params.rbi | 2 +- .../individual_enrolled_ids_params.rbi | 2 +- ...dividual_retrieve_many_benefits_params.rbi | 2 +- .../individual_unenroll_many_params.rbi | 2 +- .../models/hris/company_retrieve_params.rbi | 2 +- .../directory_list_individuals_params.rbi | 2 +- .../models/hris/directory_list_params.rbi | 2 +- .../models/hris/document_list_params.rbi | 2 +- .../models/hris/document_retreive_params.rbi | 2 +- .../hris/employment_retrieve_many_params.rbi | 2 +- .../hris/individual_retrieve_many_params.rbi | 2 +- .../pay_statement_retrieve_many_params.rbi | 2 +- .../models/hris/payment_list_params.rbi | 2 +- .../models/jobs/automated_create_params.rbi | 2 +- .../models/jobs/automated_list_params.rbi | 2 +- .../models/jobs/automated_retrieve_params.rbi | 2 +- .../models/jobs/manual_retrieve_params.rbi | 2 +- .../models/payroll/pay_group_list_params.rbi | 2 +- .../payroll/pay_group_retrieve_params.rbi | 2 +- .../finch-api/models/provider_list_params.rbi | 2 +- .../request_forwarding_forward_params.rbi | 2 +- .../models/sandbox/company_update_params.rbi | 2 +- .../sandbox/connection_create_params.rbi | 2 +- .../connections/account_create_params.rbi | 2 +- .../connections/account_update_params.rbi | 2 +- .../sandbox/directory_create_params.rbi | 2 +- .../sandbox/directory_create_response.rbi | 2 +- .../sandbox/employment_update_params.rbi | 2 +- .../sandbox/individual_update_params.rbi | 2 +- .../models/sandbox/job_create_params.rbi | 2 +- .../jobs/configuration_retrieve_params.rbi | 2 +- .../jobs/configuration_retrieve_response.rbi | 5 +- .../jobs/configuration_update_params.rbi | 2 +- .../models/sandbox/payment_create_params.rbi | 2 +- rbi/lib/finch-api/page.rbi | 2 +- rbi/lib/finch-api/pooled_net_requester.rbi | 59 - rbi/lib/finch-api/request_options.rbi | 15 - rbi/lib/finch-api/responses_page.rbi | 2 +- rbi/lib/finch-api/single_page.rbi | 2 +- rbi/lib/finch-api/transport/base_client.rbi | 204 +++ .../transport/pooled_net_requester.rbi | 64 + rbi/lib/finch-api/type.rbi | 23 + rbi/lib/finch-api/type/array_of.rbi | 84 ++ rbi/lib/finch-api/type/base_model.rbi | 191 +++ rbi/lib/finch-api/type/base_page.rbi | 38 + rbi/lib/finch-api/type/boolean_model.rbi | 41 + rbi/lib/finch-api/type/converter.rbi | 101 ++ rbi/lib/finch-api/type/enum.rbi | 58 + rbi/lib/finch-api/type/hash_of.rbi | 84 ++ rbi/lib/finch-api/type/request_parameters.rbi | 20 + rbi/lib/finch-api/type/union.rbi | 66 + rbi/lib/finch-api/type/unknown.rbi | 37 + sig/finch-api/base_client.rbs | 106 -- sig/finch-api/base_model.rbs | 248 ---- sig/finch-api/base_page.rbs | 20 - sig/finch-api/client.rbs | 2 +- sig/finch-api/individuals_page.rbs | 2 +- .../models/access_token_create_params.rbs | 2 +- .../models/account_disconnect_params.rbs | 2 +- .../models/account_introspect_params.rbs | 2 +- .../models/connect/session_new_params.rbs | 2 +- .../connect/session_reauthenticate_params.rbs | 2 +- .../models/hris/benefit_create_params.rbs | 2 +- .../models/hris/benefit_list_params.rbs | 2 +- ...benefit_list_supported_benefits_params.rbs | 2 +- .../models/hris/benefit_retrieve_params.rbs | 2 +- .../models/hris/benefit_update_params.rbs | 2 +- .../individual_enroll_many_params.rbs | 2 +- .../individual_enrolled_ids_params.rbs | 2 +- ...dividual_retrieve_many_benefits_params.rbs | 2 +- .../individual_unenroll_many_params.rbs | 2 +- .../models/hris/company_retrieve_params.rbs | 2 +- .../directory_list_individuals_params.rbs | 2 +- .../models/hris/directory_list_params.rbs | 2 +- .../models/hris/document_list_params.rbs | 2 +- .../models/hris/document_retreive_params.rbs | 2 +- .../hris/employment_retrieve_many_params.rbs | 2 +- .../hris/individual_retrieve_many_params.rbs | 2 +- .../pay_statement_retrieve_many_params.rbs | 2 +- .../models/hris/payment_list_params.rbs | 2 +- .../models/jobs/automated_create_params.rbs | 2 +- .../models/jobs/automated_list_params.rbs | 2 +- .../models/jobs/automated_retrieve_params.rbs | 2 +- .../models/jobs/manual_retrieve_params.rbs | 2 +- .../models/payroll/pay_group_list_params.rbs | 2 +- .../payroll/pay_group_retrieve_params.rbs | 2 +- sig/finch-api/models/provider_list_params.rbs | 2 +- .../request_forwarding_forward_params.rbs | 2 +- .../models/sandbox/company_update_params.rbs | 2 +- .../sandbox/connection_create_params.rbs | 2 +- .../connections/account_create_params.rbs | 2 +- .../connections/account_update_params.rbs | 2 +- .../sandbox/directory_create_params.rbs | 2 +- .../sandbox/employment_update_params.rbs | 2 +- .../sandbox/individual_update_params.rbs | 2 +- .../models/sandbox/job_create_params.rbs | 2 +- .../jobs/configuration_retrieve_params.rbs | 2 +- .../jobs/configuration_update_params.rbs | 2 +- .../models/sandbox/payment_create_params.rbs | 2 +- sig/finch-api/page.rbs | 2 +- sig/finch-api/pooled_net_requester.rbs | 37 - sig/finch-api/request_options.rbs | 10 - sig/finch-api/responses_page.rbs | 2 +- sig/finch-api/single_page.rbs | 2 +- sig/finch-api/transport/base_client.rbs | 110 ++ .../transport/pooled_net_requester.rbs | 39 + sig/finch-api/type.rbs | 22 + sig/finch-api/type/array_of.rbs | 36 + sig/finch-api/type/base_model.rbs | 73 + sig/finch-api/type/base_page.rbs | 22 + sig/finch-api/type/boolean_model.rbs | 18 + sig/finch-api/type/converter.rbs | 36 + sig/finch-api/type/enum.rbs | 22 + sig/finch-api/type/hash_of.rbs | 36 + sig/finch-api/type/request_parameters.rbs | 13 + sig/finch-api/type/union.rbs | 37 + sig/finch-api/type/unknown.rbs | 18 + test/finch-api/base_model_test.rb | 20 +- 199 files changed, 3664 insertions(+), 3406 deletions(-) delete mode 100644 lib/finch-api/base_client.rb delete mode 100644 lib/finch-api/base_model.rb delete mode 100644 lib/finch-api/base_page.rb delete mode 100644 lib/finch-api/pooled_net_requester.rb create mode 100644 lib/finch-api/transport/base_client.rb create mode 100644 lib/finch-api/transport/pooled_net_requester.rb create mode 100644 lib/finch-api/type.rb create mode 100644 lib/finch-api/type/array_of.rb create mode 100644 lib/finch-api/type/base_model.rb create mode 100644 lib/finch-api/type/base_page.rb create mode 100644 lib/finch-api/type/boolean_model.rb create mode 100644 lib/finch-api/type/converter.rb create mode 100644 lib/finch-api/type/enum.rb create mode 100644 lib/finch-api/type/hash_of.rb create mode 100644 lib/finch-api/type/request_parameters.rb create mode 100644 lib/finch-api/type/union.rb create mode 100644 lib/finch-api/type/unknown.rb delete mode 100644 rbi/lib/finch-api/base_client.rbi delete mode 100644 rbi/lib/finch-api/base_model.rbi delete mode 100644 rbi/lib/finch-api/base_page.rbi delete mode 100644 rbi/lib/finch-api/pooled_net_requester.rbi create mode 100644 rbi/lib/finch-api/transport/base_client.rbi create mode 100644 rbi/lib/finch-api/transport/pooled_net_requester.rbi create mode 100644 rbi/lib/finch-api/type.rbi create mode 100644 rbi/lib/finch-api/type/array_of.rbi create mode 100644 rbi/lib/finch-api/type/base_model.rbi create mode 100644 rbi/lib/finch-api/type/base_page.rbi create mode 100644 rbi/lib/finch-api/type/boolean_model.rbi create mode 100644 rbi/lib/finch-api/type/converter.rbi create mode 100644 rbi/lib/finch-api/type/enum.rbi create mode 100644 rbi/lib/finch-api/type/hash_of.rbi create mode 100644 rbi/lib/finch-api/type/request_parameters.rbi create mode 100644 rbi/lib/finch-api/type/union.rbi create mode 100644 rbi/lib/finch-api/type/unknown.rbi delete mode 100644 sig/finch-api/base_client.rbs delete mode 100644 sig/finch-api/base_model.rbs delete mode 100644 sig/finch-api/base_page.rbs delete mode 100644 sig/finch-api/pooled_net_requester.rbs create mode 100644 sig/finch-api/transport/base_client.rbs create mode 100644 sig/finch-api/transport/pooled_net_requester.rbs create mode 100644 sig/finch-api/type.rbs create mode 100644 sig/finch-api/type/array_of.rbs create mode 100644 sig/finch-api/type/base_model.rbs create mode 100644 sig/finch-api/type/base_page.rbs create mode 100644 sig/finch-api/type/boolean_model.rbs create mode 100644 sig/finch-api/type/converter.rbs create mode 100644 sig/finch-api/type/enum.rbs create mode 100644 sig/finch-api/type/hash_of.rbs create mode 100644 sig/finch-api/type/request_parameters.rbs create mode 100644 sig/finch-api/type/union.rbs create mode 100644 sig/finch-api/type/unknown.rbs diff --git a/lib/finch-api.rb b/lib/finch-api.rb index 575c5069..66b7eb27 100644 --- a/lib/finch-api.rb +++ b/lib/finch-api.rb @@ -36,12 +36,21 @@ # Package files. require_relative "finch-api/version" require_relative "finch-api/util" -require_relative "finch-api/base_model" -require_relative "finch-api/base_page" +require_relative "finch-api/type/converter" +require_relative "finch-api/type/unknown" +require_relative "finch-api/type/boolean_model" +require_relative "finch-api/type/enum" +require_relative "finch-api/type/union" +require_relative "finch-api/type/array_of" +require_relative "finch-api/type/hash_of" +require_relative "finch-api/type/base_model" +require_relative "finch-api/type/base_page" +require_relative "finch-api/type/request_parameters" +require_relative "finch-api/type" require_relative "finch-api/request_options" require_relative "finch-api/errors" -require_relative "finch-api/base_client" -require_relative "finch-api/pooled_net_requester" +require_relative "finch-api/transport/base_client" +require_relative "finch-api/transport/pooled_net_requester" require_relative "finch-api/client" require_relative "finch-api/individuals_page" require_relative "finch-api/page" diff --git a/lib/finch-api/base_client.rb b/lib/finch-api/base_client.rb deleted file mode 100644 index a601f5db..00000000 --- a/lib/finch-api/base_client.rb +++ /dev/null @@ -1,457 +0,0 @@ -# frozen_string_literal: true - -module FinchAPI - # @api private - # - # @abstract - class BaseClient - # from whatwg fetch spec - MAX_REDIRECTS = 20 - - # rubocop:disable Style/MutableConstant - PLATFORM_HEADERS = - { - "x-stainless-arch" => FinchAPI::Util.arch, - "x-stainless-lang" => "ruby", - "x-stainless-os" => FinchAPI::Util.os, - "x-stainless-package-version" => FinchAPI::VERSION, - "x-stainless-runtime" => ::RUBY_ENGINE, - "x-stainless-runtime-version" => ::RUBY_ENGINE_VERSION - } - # rubocop:enable Style/MutableConstant - - class << self - # @api private - # - # @param req [Hash{Symbol=>Object}] - # - # @raise [ArgumentError] - def validate!(req) - keys = [:method, :path, :query, :headers, :body, :unwrap, :page, :stream, :model, :options] - case req - in Hash - req.each_key do |k| - unless keys.include?(k) - raise ArgumentError.new("Request `req` keys must be one of #{keys}, got #{k.inspect}") - end - end - else - raise ArgumentError.new("Request `req` must be a Hash or RequestOptions, got #{req.inspect}") - end - end - - # @api private - # - # @param status [Integer] - # @param headers [Hash{String=>String}, Net::HTTPHeader] - # - # @return [Boolean] - def should_retry?(status, headers:) - coerced = FinchAPI::Util.coerce_boolean(headers["x-should-retry"]) - case [coerced, status] - in [true | false, _] - coerced - in [_, 408 | 409 | 429 | (500..)] - # retry on: - # 408: timeouts - # 409: locks - # 429: rate limits - # 500+: unknown errors - true - else - false - end - end - - # @api private - # - # @param request [Hash{Symbol=>Object}] . - # - # @option request [Symbol] :method - # - # @option request [URI::Generic] :url - # - # @option request [Hash{String=>String}] :headers - # - # @option request [Object] :body - # - # @option request [Integer] :max_retries - # - # @option request [Float] :timeout - # - # @param status [Integer] - # - # @param response_headers [Hash{String=>String}, Net::HTTPHeader] - # - # @return [Hash{Symbol=>Object}] - def follow_redirect(request, status:, response_headers:) - method, url, headers = request.fetch_values(:method, :url, :headers) - location = - Kernel.then do - URI.join(url, response_headers["location"]) - rescue ArgumentError - message = "Server responded with status #{status} but no valid location header." - raise FinchAPI::APIConnectionError.new(url: url, message: message) - end - - request = {**request, url: location} - - case [url.scheme, location.scheme] - in ["https", "http"] - message = "Tried to redirect to a insecure URL" - raise FinchAPI::APIConnectionError.new(url: url, message: message) - else - nil - end - - # from whatwg fetch spec - case [status, method] - in [301 | 302, :post] | [303, _] - drop = %w[content-encoding content-language content-length content-location content-type] - request = { - **request, - method: method == :head ? :head : :get, - headers: headers.except(*drop), - body: nil - } - else - end - - # from undici - if FinchAPI::Util.uri_origin(url) != FinchAPI::Util.uri_origin(location) - drop = %w[authorization cookie host proxy-authorization] - request = {**request, headers: request.fetch(:headers).except(*drop)} - end - - request - end - - # @api private - # - # @param status [Integer, FinchAPI::APIConnectionError] - # @param stream [Enumerable, nil] - def reap_connection!(status, stream:) - case status - in (..199) | (300..499) - stream&.each { next } - in FinchAPI::APIConnectionError | (500..) - FinchAPI::Util.close_fused!(stream) - else - end - end - end - - # @api private - # @return [FinchAPI::PooledNetRequester] - attr_accessor :requester - - # @api private - # - # @param base_url [String] - # @param timeout [Float] - # @param max_retries [Integer] - # @param initial_retry_delay [Float] - # @param max_retry_delay [Float] - # @param headers [Hash{String=>String, Integer, Array, nil}] - # @param idempotency_header [String, nil] - def initialize( - base_url:, - timeout: 0.0, - max_retries: 0, - initial_retry_delay: 0.0, - max_retry_delay: 0.0, - headers: {}, - idempotency_header: nil - ) - @requester = FinchAPI::PooledNetRequester.new - @headers = FinchAPI::Util.normalized_headers( - self.class::PLATFORM_HEADERS, - { - "accept" => "application/json", - "content-type" => "application/json" - }, - headers - ) - @base_url = FinchAPI::Util.parse_uri(base_url) - @idempotency_header = idempotency_header&.to_s&.downcase - @max_retries = max_retries - @timeout = timeout - @initial_retry_delay = initial_retry_delay - @max_retry_delay = max_retry_delay - end - - # @api private - # - # @return [Hash{String=>String}] - private def auth_headers = {} - - # @api private - # - # @return [String] - private def generate_idempotency_key = "stainless-ruby-retry-#{SecureRandom.uuid}" - - # @api private - # - # @param req [Hash{Symbol=>Object}] . - # - # @option req [Symbol] :method - # - # @option req [String, Array] :path - # - # @option req [Hash{String=>Array, String, nil}, nil] :query - # - # @option req [Hash{String=>String, Integer, Array, nil}, nil] :headers - # - # @option req [Object, nil] :body - # - # @option req [Symbol, nil] :unwrap - # - # @option req [Class, nil] :page - # - # @option req [Class, nil] :stream - # - # @option req [FinchAPI::Converter, Class, nil] :model - # - # @param opts [Hash{Symbol=>Object}] . - # - # @option opts [String, nil] :idempotency_key - # - # @option opts [Hash{String=>Array, String, nil}, nil] :extra_query - # - # @option opts [Hash{String=>String, nil}, nil] :extra_headers - # - # @option opts [Object, nil] :extra_body - # - # @option opts [Integer, nil] :max_retries - # - # @option opts [Float, nil] :timeout - # - # @return [Hash{Symbol=>Object}] - private def build_request(req, opts) - method, uninterpolated_path = req.fetch_values(:method, :path) - - path = FinchAPI::Util.interpolate_path(uninterpolated_path) - - query = FinchAPI::Util.deep_merge(req[:query].to_h, opts[:extra_query].to_h) - - headers = FinchAPI::Util.normalized_headers( - @headers, - auth_headers, - req[:headers].to_h, - opts[:extra_headers].to_h - ) - - if @idempotency_header && - !headers.key?(@idempotency_header) && - !Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase) - headers[@idempotency_header] = opts.fetch(:idempotency_key) { generate_idempotency_key } - end - - unless headers.key?("x-stainless-retry-count") - headers["x-stainless-retry-count"] = "0" - end - - timeout = opts.fetch(:timeout, @timeout).to_f.clamp((0..)) - unless headers.key?("x-stainless-timeout") || timeout.zero? - headers["x-stainless-timeout"] = timeout.to_s - end - - headers.reject! { |_, v| v.to_s.empty? } - - body = - case method - in :get | :head | :options | :trace - nil - else - FinchAPI::Util.deep_merge(*[req[:body], opts[:extra_body]].compact) - end - - headers, encoded = FinchAPI::Util.encode_content(headers, body) - { - method: method, - url: FinchAPI::Util.join_parsed_uri(@base_url, {**req, path: path, query: query}), - headers: headers, - body: encoded, - max_retries: opts.fetch(:max_retries, @max_retries), - timeout: timeout - } - end - - # @api private - # - # @param headers [Hash{String=>String}] - # @param retry_count [Integer] - # - # @return [Float] - private def retry_delay(headers, retry_count:) - # Non-standard extension - span = Float(headers["retry-after-ms"], exception: false)&.then { _1 / 1000 } - return span if span - - retry_header = headers["retry-after"] - return span if (span = Float(retry_header, exception: false)) - - span = retry_header&.then do - Time.httpdate(_1) - Time.now - rescue ArgumentError - nil - end - return span if span - - scale = retry_count**2 - jitter = 1 - (0.25 * rand) - (@initial_retry_delay * scale * jitter).clamp(0, @max_retry_delay) - end - - # @api private - # - # @param request [Hash{Symbol=>Object}] . - # - # @option request [Symbol] :method - # - # @option request [URI::Generic] :url - # - # @option request [Hash{String=>String}] :headers - # - # @option request [Object] :body - # - # @option request [Integer] :max_retries - # - # @option request [Float] :timeout - # - # @param redirect_count [Integer] - # - # @param retry_count [Integer] - # - # @param send_retry_header [Boolean] - # - # @raise [FinchAPI::APIError] - # @return [Array(Integer, Net::HTTPResponse, Enumerable)] - private def send_request(request, redirect_count:, retry_count:, send_retry_header:) - url, headers, max_retries, timeout = request.fetch_values(:url, :headers, :max_retries, :timeout) - input = {**request.except(:timeout), deadline: FinchAPI::Util.monotonic_secs + timeout} - - if send_retry_header - headers["x-stainless-retry-count"] = retry_count.to_s - end - - begin - status, response, stream = @requester.execute(input) - rescue FinchAPI::APIConnectionError => e - status = e - end - - case status - in ..299 - [status, response, stream] - in 300..399 if redirect_count >= self.class::MAX_REDIRECTS - self.class.reap_connection!(status, stream: stream) - - message = "Failed to complete the request within #{self.class::MAX_REDIRECTS} redirects." - raise FinchAPI::APIConnectionError.new(url: url, message: message) - in 300..399 - self.class.reap_connection!(status, stream: stream) - - request = self.class.follow_redirect(request, status: status, response_headers: response) - send_request( - request, - redirect_count: redirect_count + 1, - retry_count: retry_count, - send_retry_header: send_retry_header - ) - in FinchAPI::APIConnectionError if retry_count >= max_retries - raise status - in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response) - decoded = Kernel.then do - FinchAPI::Util.decode_content(response, stream: stream, suppress_error: true) - ensure - self.class.reap_connection!(status, stream: stream) - end - - raise FinchAPI::APIStatusError.for( - url: url, - status: status, - body: decoded, - request: nil, - response: response - ) - in (400..) | FinchAPI::APIConnectionError - self.class.reap_connection!(status, stream: stream) - - delay = retry_delay(response, retry_count: retry_count) - sleep(delay) - - send_request( - request, - redirect_count: redirect_count, - retry_count: retry_count + 1, - send_retry_header: send_retry_header - ) - end - end - - # Execute the request specified by `req`. This is the method that all resource - # methods call into. - # - # @param req [Hash{Symbol=>Object}] . - # - # @option req [Symbol] :method - # - # @option req [String, Array] :path - # - # @option req [Hash{String=>Array, String, nil}, nil] :query - # - # @option req [Hash{String=>String, Integer, Array, nil}, nil] :headers - # - # @option req [Object, nil] :body - # - # @option req [Symbol, nil] :unwrap - # - # @option req [Class, nil] :page - # - # @option req [Class, nil] :stream - # - # @option req [FinchAPI::Converter, Class, nil] :model - # - # @option req [FinchAPI::RequestOptions, Hash{Symbol=>Object}, nil] :options - # - # @raise [FinchAPI::APIError] - # @return [Object] - def request(req) - self.class.validate!(req) - model = req.fetch(:model) { FinchAPI::Unknown } - opts = req[:options].to_h - FinchAPI::RequestOptions.validate!(opts) - request = build_request(req.except(:options), opts) - url = request.fetch(:url) - - # Don't send the current retry count in the headers if the caller modified the header defaults. - send_retry_header = request.fetch(:headers)["x-stainless-retry-count"] == "0" - status, response, stream = send_request( - request, - redirect_count: 0, - retry_count: 0, - send_retry_header: send_retry_header - ) - - decoded = FinchAPI::Util.decode_content(response, stream: stream) - case req - in { stream: Class => st } - st.new(model: model, url: url, status: status, response: response, stream: decoded) - in { page: Class => page } - page.new(client: self, req: req, headers: response, page_data: decoded) - else - unwrapped = FinchAPI::Util.dig(decoded, req[:unwrap]) - FinchAPI::Converter.coerce(model, unwrapped) - end - end - - # @return [String] - def inspect - # rubocop:disable Layout/LineLength - base_url = FinchAPI::Util.unparse_uri(@base_url) - "#<#{self.class.name}:0x#{object_id.to_s(16)} base_url=#{base_url} max_retries=#{@max_retries} timeout=#{@timeout}>" - # rubocop:enable Layout/LineLength - end - end -end diff --git a/lib/finch-api/base_model.rb b/lib/finch-api/base_model.rb deleted file mode 100644 index e95b064c..00000000 --- a/lib/finch-api/base_model.rb +++ /dev/null @@ -1,1174 +0,0 @@ -# frozen_string_literal: true - -module FinchAPI - # @api private - module Converter - # rubocop:disable Lint/UnusedMethodArgument - - # @api private - # - # @param value [Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Object] - def coerce(value, state:) = (raise NotImplementedError) - - # @api private - # - # @param value [Object] - # - # @return [Object] - def dump(value) - case value - in Array - value.map { FinchAPI::Unknown.dump(_1) } - in Hash - value.transform_values { FinchAPI::Unknown.dump(_1) } - in FinchAPI::BaseModel - value.class.dump(value) - else - value - end - end - - # rubocop:enable Lint/UnusedMethodArgument - - class << self - # @api private - # - # @param spec [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - # - # @return [Proc] - def type_info(spec) - case spec - in Proc - spec - in Hash - type_info(spec.slice(:const, :enum, :union).first&.last) - in true | false - -> { FinchAPI::BooleanModel } - in FinchAPI::Converter | Class | Symbol - -> { spec } - in NilClass | Integer | Float - -> { spec.class } - end - end - - # @api private - # - # Based on `target`, transform `value` into `target`, to the extent possible: - # - # 1. if the given `value` conforms to `target` already, return the given `value` - # 2. if it's possible and safe to convert the given `value` to `target`, then the - # converted value - # 3. otherwise, the given `value` unaltered - # - # The coercion process is subject to improvement between minor release versions. - # See https://docs.pydantic.dev/latest/concepts/unions/#smart-mode - # - # @param target [FinchAPI::Converter, Class] - # - # @param value [Object] - # - # @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`, or `:strong`. This informs the - # coercion strategy when we have to decide between multiple possible conversion - # targets: - # - # - `true`: the conversion must be exact, with minimum coercion. - # - `false`: the conversion can be approximate, with some coercion. - # - `:strong`: the conversion must be exact, with no coercion, and raise an error - # if not possible. - # - # The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For - # any given conversion attempt, the exactness will be updated based on how closely - # the value recursively matches the target type: - # - # - `yes`: the value can be converted to the target type with minimum coercion. - # - `maybe`: the value can be converted to the target type with some reasonable - # coercion. - # - `no`: the value cannot be converted to the target type. - # - # See implementation below for more details. - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Object] - def coerce(target, value, state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0}) - strictness, exactness = state.fetch_values(:strictness, :exactness) - - case target - in FinchAPI::Converter - return target.coerce(value, state: state) - in Class - if value.is_a?(target) - exactness[:yes] += 1 - return value - end - - case target - in -> { _1 <= NilClass } - exactness[value.nil? ? :yes : :maybe] += 1 - return nil - in -> { _1 <= Integer } - if value.is_a?(Integer) - exactness[:yes] += 1 - return value - elsif strictness == :strong - message = "no implicit conversion of #{value.class} into #{target.inspect}" - raise TypeError.new(message) - else - Kernel.then do - return Integer(value).tap { exactness[:maybe] += 1 } - rescue ArgumentError, TypeError - end - end - in -> { _1 <= Float } - if value.is_a?(Numeric) - exactness[:yes] += 1 - return Float(value) - elsif strictness == :strong - message = "no implicit conversion of #{value.class} into #{target.inspect}" - raise TypeError.new(message) - else - Kernel.then do - return Float(value).tap { exactness[:maybe] += 1 } - rescue ArgumentError, TypeError - end - end - in -> { _1 <= String } - case value - in String | Symbol | Numeric - exactness[value.is_a?(Numeric) ? :maybe : :yes] += 1 - return value.to_s - else - if strictness == :strong - message = "no implicit conversion of #{value.class} into #{target.inspect}" - raise TypeError.new(message) - end - end - in -> { _1 <= Date || _1 <= Time } - Kernel.then do - return target.parse(value).tap { exactness[:yes] += 1 } - rescue ArgumentError, TypeError => e - raise e if strictness == :strong - end - in -> { _1 <= IO } if value.is_a?(String) - exactness[:yes] += 1 - return StringIO.new(value.b) - else - end - in Symbol - if (value.is_a?(Symbol) || value.is_a?(String)) && value.to_sym == target - exactness[:yes] += 1 - return target - elsif strictness == :strong - message = "cannot convert non-matching #{value.class} into #{target.inspect}" - raise ArgumentError.new(message) - end - else - end - - exactness[:no] += 1 - value - end - - # @api private - # - # @param target [FinchAPI::Converter, Class] - # @param value [Object] - # - # @return [Object] - def dump(target, value) - target.is_a?(FinchAPI::Converter) ? target.dump(value) : FinchAPI::Unknown.dump(value) - end - end - end - - # @api private - # - # @abstract - # - # When we don't know what to expect for the value. - class Unknown - extend FinchAPI::Converter - - # rubocop:disable Lint/UnusedMethodArgument - - # @param other [Object] - # - # @return [Boolean] - def self.===(other) = true - - # @param other [Object] - # - # @return [Boolean] - def self.==(other) = other.is_a?(Class) && other <= FinchAPI::Unknown - - class << self - # @api private - # - # @param value [Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Object] - def coerce(value, state:) - state.fetch(:exactness)[:yes] += 1 - value - end - - # @!parse - # # @api private - # # - # # @param value [Object] - # # - # # @return [Object] - # def dump(value) = super - end - - # rubocop:enable Lint/UnusedMethodArgument - end - - # @api private - # - # @abstract - # - # Ruby has no Boolean class; this is something for models to refer to. - class BooleanModel - extend FinchAPI::Converter - - # @param other [Object] - # - # @return [Boolean] - def self.===(other) = other == true || other == false - - # @param other [Object] - # - # @return [Boolean] - def self.==(other) = other.is_a?(Class) && other <= FinchAPI::BooleanModel - - class << self - # @api private - # - # @param value [Boolean, Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Boolean, Object] - def coerce(value, state:) - state.fetch(:exactness)[value == true || value == false ? :yes : :no] += 1 - value - end - - # @!parse - # # @api private - # # - # # @param value [Boolean, Object] - # # - # # @return [Boolean, Object] - # def dump(value) = super - end - end - - # @api private - # - # A value from among a specified list of options. OpenAPI enum values map to Ruby - # values in the SDK as follows: - # - # 1. boolean => true | false - # 2. integer => Integer - # 3. float => Float - # 4. string => Symbol - # - # We can therefore convert string values to Symbols, but can't convert other - # values safely. - # - # @example - # # `connection_status_type` is a `FinchAPI::Models::ConnectionStatusType` - # case connection_status_type - # when FinchAPI::Models::ConnectionStatusType::PENDING - # # ... - # when FinchAPI::Models::ConnectionStatusType::PROCESSING - # # ... - # when FinchAPI::Models::ConnectionStatusType::CONNECTED - # # ... - # else - # puts(connection_status_type) - # end - # - # @example - # case connection_status_type - # in :pending - # # ... - # in :processing - # # ... - # in :connected - # # ... - # else - # puts(connection_status_type) - # end - module Enum - include FinchAPI::Converter - - # All of the valid Symbol values for this enum. - # - # @return [Array] - def values = (@values ||= constants.map { const_get(_1) }) - - # @api private - # - # Guard against thread safety issues by instantiating `@values`. - private def finalize! = values - - # @param other [Object] - # - # @return [Boolean] - def ===(other) = values.include?(other) - - # @param other [Object] - # - # @return [Boolean] - def ==(other) - other.is_a?(Module) && other.singleton_class <= FinchAPI::Enum && other.values.to_set == values.to_set - end - - # @api private - # - # Unlike with primitives, `Enum` additionally validates that the value is a member - # of the enum. - # - # @param value [String, Symbol, Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Symbol, Object] - def coerce(value, state:) - exactness = state.fetch(:exactness) - val = value.is_a?(String) ? value.to_sym : value - - if values.include?(val) - exactness[:yes] += 1 - val - else - exactness[values.first&.class == val.class ? :maybe : :no] += 1 - value - end - end - - # @!parse - # # @api private - # # - # # @param value [Symbol, Object] - # # - # # @return [Symbol, Object] - # def dump(value) = super - end - - # @api private - # - # @example - # # `document_retreive_response` is a `FinchAPI::Models::HRIS::DocumentRetreiveResponse` - # case document_retreive_response - # when FinchAPI::Models::HRIS::W42020 - # puts(document_retreive_response.data) - # when FinchAPI::Models::HRIS::W42005 - # puts(document_retreive_response.type) - # else - # puts(document_retreive_response) - # end - # - # @example - # case document_retreive_response - # in {type: :w4_2020, data: data, year: year} - # puts(data) - # in {type: :w4_2005, data: data, year: year} - # puts(year) - # else - # puts(document_retreive_response) - # end - module Union - include FinchAPI::Converter - - # @api private - # - # All of the specified variant info for this union. - # - # @return [Array] - private def known_variants = (@known_variants ||= []) - - # @api private - # - # @return [Array] - protected def derefed_variants - @known_variants.map { |key, variant_fn| [key, variant_fn.call] } - end - - # All of the specified variants for this union. - # - # @return [Array] - def variants = derefed_variants.map(&:last) - - # @api private - # - # @param property [Symbol] - private def discriminator(property) - case property - in Symbol - @discriminator = property - end - end - - # @api private - # - # @param key [Symbol, Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - private def variant(key, spec = nil) - variant_info = - case key - in Symbol - [key, FinchAPI::Converter.type_info(spec)] - in Proc | FinchAPI::Converter | Class | Hash - [nil, FinchAPI::Converter.type_info(key)] - end - - known_variants << variant_info - end - - # @api private - # - # @param value [Object] - # - # @return [FinchAPI::Converter, Class, nil] - private def resolve_variant(value) - case [@discriminator, value] - in [_, FinchAPI::BaseModel] - value.class - in [Symbol, Hash] - key = value.fetch(@discriminator) do - value.fetch(@discriminator.to_s, FinchAPI::Util::OMIT) - end - - return nil if key == FinchAPI::Util::OMIT - - key = key.to_sym if key.is_a?(String) - known_variants.find { |k,| k == key }&.last&.call - else - nil - end - end - - # rubocop:disable Style/HashEachMethods - # rubocop:disable Style/CaseEquality - - # @param other [Object] - # - # @return [Boolean] - def ===(other) - known_variants.any? do |_, variant_fn| - variant_fn.call === other - end - end - - # @param other [Object] - # - # @return [Boolean] - def ==(other) - other.is_a?(Module) && other.singleton_class <= FinchAPI::Union && other.derefed_variants == derefed_variants - end - - # @api private - # - # @param value [Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Object] - def coerce(value, state:) - if (target = resolve_variant(value)) - return FinchAPI::Converter.coerce(target, value, state: state) - end - - strictness = state.fetch(:strictness) - exactness = state.fetch(:exactness) - state[:strictness] = strictness == :strong ? true : strictness - - alternatives = [] - known_variants.each do |_, variant_fn| - target = variant_fn.call - exact = state[:exactness] = {yes: 0, no: 0, maybe: 0} - state[:branched] += 1 - - coerced = FinchAPI::Converter.coerce(target, value, state: state) - yes, no, maybe = exact.values - if (no + maybe).zero? || (!strictness && yes.positive?) - exact.each { exactness[_1] += _2 } - state[:exactness] = exactness - return coerced - elsif maybe.positive? - alternatives << [[-yes, -maybe, no], exact, coerced] - end - end - - case alternatives.sort_by(&:first) - in [] - exactness[:no] += 1 - if strictness == :strong - message = "no possible conversion of #{value.class} into a variant of #{target.inspect}" - raise ArgumentError.new(message) - end - value - in [[_, exact, coerced], *] - exact.each { exactness[_1] += _2 } - coerced - end - .tap { state[:exactness] = exactness } - ensure - state[:strictness] = strictness - end - - # @api private - # - # @param value [Object] - # - # @return [Object] - def dump(value) - if (target = resolve_variant(value)) - return FinchAPI::Converter.dump(target, value) - end - - known_variants.each do - target = _2.call - return FinchAPI::Converter.dump(target, value) if target === value - end - - super - end - - # rubocop:enable Style/CaseEquality - # rubocop:enable Style/HashEachMethods - end - - # @api private - # - # @abstract - # - # Array of items of a given type. - class ArrayOf - include FinchAPI::Converter - - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - def self.[](type_info, spec = {}) = new(type_info, spec) - - # @param other [Object] - # - # @return [Boolean] - def ===(other) = other.is_a?(Array) && other.all?(item_type) - - # @param other [Object] - # - # @return [Boolean] - def ==(other) = other.is_a?(FinchAPI::ArrayOf) && other.nilable? == nilable? && other.item_type == item_type - - # @api private - # - # @param value [Enumerable, Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Array, Object] - def coerce(value, state:) - exactness = state.fetch(:exactness) - - unless value.is_a?(Array) - exactness[:no] += 1 - return value - end - - target = item_type - exactness[:yes] += 1 - value - .map do |item| - case [nilable?, item] - in [true, nil] - exactness[:yes] += 1 - nil - else - FinchAPI::Converter.coerce(target, item, state: state) - end - end - end - - # @api private - # - # @param value [Enumerable, Object] - # - # @return [Array, Object] - def dump(value) - target = item_type - value.is_a?(Array) ? value.map { FinchAPI::Converter.dump(target, _1) } : super - end - - # @api private - # - # @return [FinchAPI::Converter, Class] - protected def item_type = @item_type_fn.call - - # @api private - # - # @return [Boolean] - protected def nilable? = @nilable - - # @api private - # - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - def initialize(type_info, spec = {}) - @item_type_fn = FinchAPI::Converter.type_info(type_info || spec) - @nilable = spec[:nil?] - end - end - - # @api private - # - # @abstract - # - # Hash of items of a given type. - class HashOf - include FinchAPI::Converter - - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - def self.[](type_info, spec = {}) = new(type_info, spec) - - # @param other [Object] - # - # @return [Boolean] - def ===(other) - type = item_type - case other - in Hash - other.all? do |key, val| - case [key, val] - in [Symbol | String, ^type] - true - else - false - end - end - else - false - end - end - - # @param other [Object] - # - # @return [Boolean] - def ==(other) = other.is_a?(FinchAPI::HashOf) && other.nilable? == nilable? && other.item_type == item_type - - # @api private - # - # @param value [Hash{Object=>Object}, Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [Hash{Symbol=>Object}, Object] - def coerce(value, state:) - exactness = state.fetch(:exactness) - - unless value.is_a?(Hash) - exactness[:no] += 1 - return value - end - - target = item_type - exactness[:yes] += 1 - value - .to_h do |key, val| - k = key.is_a?(String) ? key.to_sym : key - v = - case [nilable?, val] - in [true, nil] - exactness[:yes] += 1 - nil - else - FinchAPI::Converter.coerce(target, val, state: state) - end - - exactness[:no] += 1 unless k.is_a?(Symbol) - [k, v] - end - end - - # @api private - # - # @param value [Hash{Object=>Object}, Object] - # - # @return [Hash{Symbol=>Object}, Object] - def dump(value) - target = item_type - value.is_a?(Hash) ? value.transform_values { FinchAPI::Converter.dump(target, _1) } : super - end - - # @api private - # - # @return [FinchAPI::Converter, Class] - protected def item_type = @item_type_fn.call - - # @api private - # - # @return [Boolean] - protected def nilable? = @nilable - - # @api private - # - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - def initialize(type_info, spec = {}) - @item_type_fn = FinchAPI::Converter.type_info(type_info || spec) - @nilable = spec[:nil?] - end - end - - # @abstract - # - # @example - # # `operation_support_matrix` is a `FinchAPI::Models::OperationSupportMatrix` - # operation_support_matrix => { - # create: create, - # delete: delete, - # read: read - # } - class BaseModel - extend FinchAPI::Converter - - class << self - # @api private - # - # Assumes superclass fields are totally defined before fields are accessed / - # defined on subclasses. - # - # @return [Hash{Symbol=>Hash{Symbol=>Object}}] - def known_fields - @known_fields ||= (self < FinchAPI::BaseModel ? superclass.known_fields.dup : {}) - end - - # @api private - # - # @return [Hash{Symbol=>Hash{Symbol=>Object}}] - def fields - known_fields.transform_values do |field| - {**field.except(:type_fn), type: field.fetch(:type_fn).call} - end - end - - # @api private - # - # @param name_sym [Symbol] - # - # @param required [Boolean] - # - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - private def add_field(name_sym, required:, type_info:, spec:) - type_fn, info = - case type_info - in Proc | FinchAPI::Converter | Class - [FinchAPI::Converter.type_info({**spec, union: type_info}), spec] - in Hash - [FinchAPI::Converter.type_info(type_info), type_info] - end - - setter = "#{name_sym}=" - api_name = info.fetch(:api_name, name_sym) - nilable = info[:nil?] - const = required && !nilable ? info.fetch(:const, FinchAPI::Util::OMIT) : FinchAPI::Util::OMIT - - [name_sym, setter].each { undef_method(_1) } if known_fields.key?(name_sym) - - known_fields[name_sym] = - { - mode: @mode, - api_name: api_name, - required: required, - nilable: nilable, - const: const, - type_fn: type_fn - } - - define_method(setter) { @data.store(name_sym, _1) } - - define_method(name_sym) do - target = type_fn.call - value = @data.fetch(name_sym) { const == FinchAPI::Util::OMIT ? nil : const } - state = {strictness: :strong, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} - (nilable || !required) && value.nil? ? nil : FinchAPI::Converter.coerce(target, value, state: state) - rescue StandardError - cls = self.class.name.split("::").last - message = "Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}. To get the unparsed API response, use #{cls}[:#{__method__}]." - raise FinchAPI::ConversionError.new(message) - end - end - - # @api private - # - # @param name_sym [Symbol] - # - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - def required(name_sym, type_info, spec = {}) - add_field(name_sym, required: true, type_info: type_info, spec: spec) - end - - # @api private - # - # @param name_sym [Symbol] - # - # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] - # - # @param spec [Hash{Symbol=>Object}] . - # - # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const - # - # @option spec [Proc] :enum - # - # @option spec [Proc] :union - # - # @option spec [Boolean] :"nil?" - def optional(name_sym, type_info, spec = {}) - add_field(name_sym, required: false, type_info: type_info, spec: spec) - end - - # @api private - # - # `request_only` attributes not excluded from `.#coerce` when receiving responses - # even if well behaved servers should not send them - # - # @param blk [Proc] - private def request_only(&blk) - @mode = :dump - blk.call - ensure - @mode = nil - end - - # @api private - # - # `response_only` attributes are omitted from `.#dump` when making requests - # - # @param blk [Proc] - private def response_only(&blk) - @mode = :coerce - blk.call - ensure - @mode = nil - end - - # @param other [Object] - # - # @return [Boolean] - def ==(other) = other.is_a?(Class) && other <= FinchAPI::BaseModel && other.fields == fields - end - - # @param other [Object] - # - # @return [Boolean] - def ==(other) = self.class == other.class && @data == other.to_h - - class << self - # @api private - # - # @param value [FinchAPI::BaseModel, Hash{Object=>Object}, Object] - # - # @param state [Hash{Symbol=>Object}] . - # - # @option state [Boolean, :strong] :strictness - # - # @option state [Hash{Symbol=>Object}] :exactness - # - # @option state [Integer] :branched - # - # @return [FinchAPI::BaseModel, Object] - def coerce(value, state:) - exactness = state.fetch(:exactness) - - if value.is_a?(self.class) - exactness[:yes] += 1 - return value - end - - unless (val = FinchAPI::Util.coerce_hash(value)).is_a?(Hash) - exactness[:no] += 1 - return value - end - exactness[:yes] += 1 - - keys = val.keys.to_set - instance = new - data = instance.to_h - - fields.each do |name, field| - mode, required, target = field.fetch_values(:mode, :required, :type) - api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const) - - unless val.key?(api_name) - if const != FinchAPI::Util::OMIT - exactness[:yes] += 1 - elsif required && mode != :dump - exactness[nilable ? :maybe : :no] += 1 - else - exactness[:yes] += 1 - end - next - end - - item = val.fetch(api_name) - keys.delete(api_name) - - converted = - if item.nil? && (nilable || !required) - exactness[nilable ? :yes : :maybe] += 1 - nil - else - coerced = FinchAPI::Converter.coerce(target, item, state: state) - case target - in FinchAPI::Converter | Symbol - coerced - else - item - end - end - data.store(name, converted) - end - - keys.each { data.store(_1, val.fetch(_1)) } - instance - end - - # @api private - # - # @param value [FinchAPI::BaseModel, Object] - # - # @return [Hash{Object=>Object}, Object] - def dump(value) - unless (coerced = FinchAPI::Util.coerce_hash(value)).is_a?(Hash) - return super - end - - acc = {} - - coerced.each do |key, val| - name = key.is_a?(String) ? key.to_sym : key - case (field = known_fields[name]) - in nil - acc.store(name, super(val)) - else - mode, api_name, type_fn = field.fetch_values(:mode, :api_name, :type_fn) - case mode - in :coerce - next - else - target = type_fn.call - acc.store(api_name, FinchAPI::Converter.dump(target, val)) - end - end - end - - known_fields.each_value do |field| - mode, api_name, const = field.fetch_values(:mode, :api_name, :const) - next if mode == :coerce || acc.key?(api_name) || const == FinchAPI::Util::OMIT - acc.store(api_name, const) - end - - acc - end - end - - # Returns the raw value associated with the given key, if found. Otherwise, nil is - # returned. - # - # It is valid to lookup keys that are not in the API spec, for example to access - # undocumented features. This method does not parse response data into - # higher-level types. Lookup by anything other than a Symbol is an ArgumentError. - # - # @param key [Symbol] - # - # @return [Object, nil] - def [](key) - unless key.instance_of?(Symbol) - raise ArgumentError.new("Expected symbol key for lookup, got #{key.inspect}") - end - - @data[key] - end - - # Returns a Hash of the data underlying this object. O(1) - # - # Keys are Symbols and values are the raw values from the response. The return - # value indicates which values were ever set on the object. i.e. there will be a - # key in this hash if they ever were, even if the set value was nil. - # - # This method is not recursive. The returned value is shared by the object, so it - # should not be mutated. - # - # @return [Hash{Symbol=>Object}] - def to_h = @data - - alias_method :to_hash, :to_h - - # @param keys [Array, nil] - # - # @return [Hash{Symbol=>Object}] - def deconstruct_keys(keys) - (keys || self.class.known_fields.keys) - .filter_map do |k| - unless self.class.known_fields.key?(k) - next - end - - [k, public_send(k)] - end - .to_h - end - - # Create a new instance of a model. - # - # @param data [Hash{Symbol=>Object}, FinchAPI::BaseModel] - def initialize(data = {}) - case FinchAPI::Util.coerce_hash(data) - in Hash => coerced - @data = coerced - else - raise ArgumentError.new("Expected a #{Hash} or #{FinchAPI::BaseModel}, got #{data.inspect}") - end - end - - # @return [String] - def inspect - rows = self.class.known_fields.keys.map do - "#{_1}=#{@data.key?(_1) ? public_send(_1) : ''}" - rescue FinchAPI::ConversionError - "#{_1}=#{@data.fetch(_1)}" - end - "#<#{self.class.name}:0x#{object_id.to_s(16)} #{rows.join(' ')}>" - end - end -end diff --git a/lib/finch-api/base_page.rb b/lib/finch-api/base_page.rb deleted file mode 100644 index 4ceaf25e..00000000 --- a/lib/finch-api/base_page.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -module FinchAPI - # @example - # if page.has_next? - # page = page.next_page - # end - # - # @example - # page.auto_paging_each do |access_token| - # puts(access_token) - # end - # - # @example - # access_tokens = - # page - # .to_enum - # .lazy - # .select { _1.object_id.even? } - # .map(&:itself) - # .take(2) - # .to_a - # - # access_tokens => Array - module BasePage - # rubocop:disable Lint/UnusedMethodArgument - - # @return [Boolean] - def next_page? = (raise NotImplementedError) - - # @raise [FinchAPI::APIError] - # @return [FinchAPI::BasePage] - def next_page = (raise NotImplementedError) - - # @param blk [Proc] - # - # @return [void] - def auto_paging_each(&) = (raise NotImplementedError) - - # @return [Enumerable] - def to_enum = super(:auto_paging_each) - - alias_method :enum_for, :to_enum - - # @api private - # - # @param client [FinchAPI::BaseClient] - # @param req [Hash{Symbol=>Object}] - # @param headers [Hash{String=>String}, Net::HTTPHeader] - # @param page_data [Object] - def initialize(client:, req:, headers:, page_data:) - @client = client - @req = req - super() - end - - # rubocop:enable Lint/UnusedMethodArgument - end -end diff --git a/lib/finch-api/client.rb b/lib/finch-api/client.rb index 78220550..9450ff86 100644 --- a/lib/finch-api/client.rb +++ b/lib/finch-api/client.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module FinchAPI - class Client < FinchAPI::BaseClient + class Client < FinchAPI::Transport::BaseClient # Default max number of retries to attempt after a failed retryable request. DEFAULT_MAX_RETRIES = 2 diff --git a/lib/finch-api/individuals_page.rb b/lib/finch-api/individuals_page.rb index 09b1d549..90849b22 100644 --- a/lib/finch-api/individuals_page.rb +++ b/lib/finch-api/individuals_page.rb @@ -23,7 +23,7 @@ module FinchAPI # # directories => Array class IndividualsPage - include FinchAPI::BasePage + include FinchAPI::Type::BasePage # @return [Array, nil] attr_accessor :individuals @@ -33,7 +33,7 @@ class IndividualsPage # @api private # - # @param client [FinchAPI::BaseClient] + # @param client [FinchAPI::Transport::BaseClient] # @param req [Hash{Symbol=>Object}] # @param headers [Hash{String=>String}, Net::HTTPHeader] # @param page_data [Hash{Symbol=>Object}] @@ -43,13 +43,13 @@ def initialize(client:, req:, headers:, page_data:) case page_data in {individuals: Array | nil => individuals} - @individuals = individuals&.map { FinchAPI::Converter.coerce(model, _1) } + @individuals = individuals&.map { FinchAPI::Type::Converter.coerce(model, _1) } else end case page_data in {paging: Hash | nil => paging} - @paging = FinchAPI::Converter.coerce(FinchAPI::Models::Paging, paging) + @paging = FinchAPI::Type::Converter.coerce(FinchAPI::Models::Paging, paging) else end end diff --git a/lib/finch-api/models/access_token_create_params.rb b/lib/finch-api/models/access_token_create_params.rb index bedadb30..525948b3 100644 --- a/lib/finch-api/models/access_token_create_params.rb +++ b/lib/finch-api/models/access_token_create_params.rb @@ -4,7 +4,7 @@ module FinchAPI module Models class AccessTokenCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute code diff --git a/lib/finch-api/models/account_disconnect_params.rb b/lib/finch-api/models/account_disconnect_params.rb index a3ca96b9..e8810332 100644 --- a/lib/finch-api/models/account_disconnect_params.rb +++ b/lib/finch-api/models/account_disconnect_params.rb @@ -4,7 +4,7 @@ module FinchAPI module Models class AccountDisconnectParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/account_introspect_params.rb b/lib/finch-api/models/account_introspect_params.rb index b0841e55..cbdbb052 100644 --- a/lib/finch-api/models/account_introspect_params.rb +++ b/lib/finch-api/models/account_introspect_params.rb @@ -4,7 +4,7 @@ module FinchAPI module Models class AccountIntrospectParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/connect/session_new_params.rb b/lib/finch-api/models/connect/session_new_params.rb index 8761f443..00cca690 100644 --- a/lib/finch-api/models/connect/session_new_params.rb +++ b/lib/finch-api/models/connect/session_new_params.rb @@ -5,7 +5,7 @@ module Models module Connect class SessionNewParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute customer_id diff --git a/lib/finch-api/models/connect/session_reauthenticate_params.rb b/lib/finch-api/models/connect/session_reauthenticate_params.rb index 51d90696..7b76bcb4 100644 --- a/lib/finch-api/models/connect/session_reauthenticate_params.rb +++ b/lib/finch-api/models/connect/session_reauthenticate_params.rb @@ -5,7 +5,7 @@ module Models module Connect class SessionReauthenticateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute connection_id diff --git a/lib/finch-api/models/hris/benefit_create_params.rb b/lib/finch-api/models/hris/benefit_create_params.rb index 53b35a22..c5561dfa 100644 --- a/lib/finch-api/models/hris/benefit_create_params.rb +++ b/lib/finch-api/models/hris/benefit_create_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class BenefitCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] description diff --git a/lib/finch-api/models/hris/benefit_list_params.rb b/lib/finch-api/models/hris/benefit_list_params.rb index 7e9b98bf..df51bff0 100644 --- a/lib/finch-api/models/hris/benefit_list_params.rb +++ b/lib/finch-api/models/hris/benefit_list_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class BenefitListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rb b/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rb index 2420ca2b..d8f351bf 100644 --- a/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rb +++ b/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class BenefitListSupportedBenefitsParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/hris/benefit_retrieve_params.rb b/lib/finch-api/models/hris/benefit_retrieve_params.rb index ad4cf795..a859e0c2 100644 --- a/lib/finch-api/models/hris/benefit_retrieve_params.rb +++ b/lib/finch-api/models/hris/benefit_retrieve_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class BenefitRetrieveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/hris/benefit_update_params.rb b/lib/finch-api/models/hris/benefit_update_params.rb index b6d58178..618c81e1 100644 --- a/lib/finch-api/models/hris/benefit_update_params.rb +++ b/lib/finch-api/models/hris/benefit_update_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class BenefitUpdateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] description diff --git a/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rb b/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rb index 5e068387..0f06b59f 100644 --- a/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rb +++ b/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rb @@ -6,7 +6,7 @@ module HRIS module Benefits class IndividualEnrollManyParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] individuals diff --git a/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rb b/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rb index 52252fc6..92171811 100644 --- a/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rb +++ b/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rb @@ -6,7 +6,7 @@ module HRIS module Benefits class IndividualEnrolledIDsParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rb b/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rb index 28085efa..76dcf11c 100644 --- a/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rb +++ b/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rb @@ -6,7 +6,7 @@ module HRIS module Benefits class IndividualRetrieveManyBenefitsParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] individual_ids diff --git a/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rb b/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rb index 65d1a47c..f132f3a3 100644 --- a/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rb +++ b/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rb @@ -6,7 +6,7 @@ module HRIS module Benefits class IndividualUnenrollManyParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] individual_ids diff --git a/lib/finch-api/models/hris/company_retrieve_params.rb b/lib/finch-api/models/hris/company_retrieve_params.rb index df644b1c..b1469611 100644 --- a/lib/finch-api/models/hris/company_retrieve_params.rb +++ b/lib/finch-api/models/hris/company_retrieve_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class CompanyRetrieveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/hris/directory_list_individuals_params.rb b/lib/finch-api/models/hris/directory_list_individuals_params.rb index 49883a9e..3835dd1d 100644 --- a/lib/finch-api/models/hris/directory_list_individuals_params.rb +++ b/lib/finch-api/models/hris/directory_list_individuals_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class DirectoryListIndividualsParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] limit diff --git a/lib/finch-api/models/hris/directory_list_params.rb b/lib/finch-api/models/hris/directory_list_params.rb index f6c5353b..c0bd6b93 100644 --- a/lib/finch-api/models/hris/directory_list_params.rb +++ b/lib/finch-api/models/hris/directory_list_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class DirectoryListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] limit diff --git a/lib/finch-api/models/hris/document_list_params.rb b/lib/finch-api/models/hris/document_list_params.rb index 2e077b06..3b8aded9 100644 --- a/lib/finch-api/models/hris/document_list_params.rb +++ b/lib/finch-api/models/hris/document_list_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class DocumentListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] individual_ids diff --git a/lib/finch-api/models/hris/document_retreive_params.rb b/lib/finch-api/models/hris/document_retreive_params.rb index b84c305d..06162733 100644 --- a/lib/finch-api/models/hris/document_retreive_params.rb +++ b/lib/finch-api/models/hris/document_retreive_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class DocumentRetreiveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/hris/employment_retrieve_many_params.rb b/lib/finch-api/models/hris/employment_retrieve_many_params.rb index 9f855a9a..33a8f7e5 100644 --- a/lib/finch-api/models/hris/employment_retrieve_many_params.rb +++ b/lib/finch-api/models/hris/employment_retrieve_many_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class EmploymentRetrieveManyParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute requests diff --git a/lib/finch-api/models/hris/individual_retrieve_many_params.rb b/lib/finch-api/models/hris/individual_retrieve_many_params.rb index 9f13fa0c..31fe1f6c 100644 --- a/lib/finch-api/models/hris/individual_retrieve_many_params.rb +++ b/lib/finch-api/models/hris/individual_retrieve_many_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class IndividualRetrieveManyParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute options diff --git a/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rb b/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rb index 14115d78..14b1d4e2 100644 --- a/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rb +++ b/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class PayStatementRetrieveManyParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute requests diff --git a/lib/finch-api/models/hris/payment_list_params.rb b/lib/finch-api/models/hris/payment_list_params.rb index 4f5e614f..8e5bce25 100644 --- a/lib/finch-api/models/hris/payment_list_params.rb +++ b/lib/finch-api/models/hris/payment_list_params.rb @@ -5,7 +5,7 @@ module Models module HRIS class PaymentListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute end_date diff --git a/lib/finch-api/models/jobs/automated_create_params.rb b/lib/finch-api/models/jobs/automated_create_params.rb index a0993cab..e928f0f2 100644 --- a/lib/finch-api/models/jobs/automated_create_params.rb +++ b/lib/finch-api/models/jobs/automated_create_params.rb @@ -5,7 +5,7 @@ module Models module Jobs class AutomatedCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute type diff --git a/lib/finch-api/models/jobs/automated_list_params.rb b/lib/finch-api/models/jobs/automated_list_params.rb index 8ed6809e..84e6123e 100644 --- a/lib/finch-api/models/jobs/automated_list_params.rb +++ b/lib/finch-api/models/jobs/automated_list_params.rb @@ -5,7 +5,7 @@ module Models module Jobs class AutomatedListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] limit diff --git a/lib/finch-api/models/jobs/automated_retrieve_params.rb b/lib/finch-api/models/jobs/automated_retrieve_params.rb index bf115a42..258cfc9f 100644 --- a/lib/finch-api/models/jobs/automated_retrieve_params.rb +++ b/lib/finch-api/models/jobs/automated_retrieve_params.rb @@ -5,7 +5,7 @@ module Models module Jobs class AutomatedRetrieveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/jobs/manual_retrieve_params.rb b/lib/finch-api/models/jobs/manual_retrieve_params.rb index 175d6ac3..c3aa78c7 100644 --- a/lib/finch-api/models/jobs/manual_retrieve_params.rb +++ b/lib/finch-api/models/jobs/manual_retrieve_params.rb @@ -5,7 +5,7 @@ module Models module Jobs class ManualRetrieveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/payroll/pay_group_list_params.rb b/lib/finch-api/models/payroll/pay_group_list_params.rb index 91a45f81..b369ebd9 100644 --- a/lib/finch-api/models/payroll/pay_group_list_params.rb +++ b/lib/finch-api/models/payroll/pay_group_list_params.rb @@ -5,7 +5,7 @@ module Models module Payroll class PayGroupListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] individual_id diff --git a/lib/finch-api/models/payroll/pay_group_retrieve_params.rb b/lib/finch-api/models/payroll/pay_group_retrieve_params.rb index 2a79cfa7..35ce8db5 100644 --- a/lib/finch-api/models/payroll/pay_group_retrieve_params.rb +++ b/lib/finch-api/models/payroll/pay_group_retrieve_params.rb @@ -5,7 +5,7 @@ module Models module Payroll class PayGroupRetrieveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/provider_list_params.rb b/lib/finch-api/models/provider_list_params.rb index 9de4c3f3..df7c302f 100644 --- a/lib/finch-api/models/provider_list_params.rb +++ b/lib/finch-api/models/provider_list_params.rb @@ -4,7 +4,7 @@ module FinchAPI module Models class ProviderListParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/request_forwarding_forward_params.rb b/lib/finch-api/models/request_forwarding_forward_params.rb index a95f7ad7..55f13b68 100644 --- a/lib/finch-api/models/request_forwarding_forward_params.rb +++ b/lib/finch-api/models/request_forwarding_forward_params.rb @@ -4,7 +4,7 @@ module FinchAPI module Models class RequestForwardingForwardParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute method_ diff --git a/lib/finch-api/models/sandbox/company_update_params.rb b/lib/finch-api/models/sandbox/company_update_params.rb index fcffc5f7..7d01c210 100644 --- a/lib/finch-api/models/sandbox/company_update_params.rb +++ b/lib/finch-api/models/sandbox/company_update_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class CompanyUpdateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute accounts diff --git a/lib/finch-api/models/sandbox/connection_create_params.rb b/lib/finch-api/models/sandbox/connection_create_params.rb index c0396eef..81e8b7f6 100644 --- a/lib/finch-api/models/sandbox/connection_create_params.rb +++ b/lib/finch-api/models/sandbox/connection_create_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class ConnectionCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute provider_id diff --git a/lib/finch-api/models/sandbox/connections/account_create_params.rb b/lib/finch-api/models/sandbox/connections/account_create_params.rb index b241178d..0a1383c2 100644 --- a/lib/finch-api/models/sandbox/connections/account_create_params.rb +++ b/lib/finch-api/models/sandbox/connections/account_create_params.rb @@ -6,7 +6,7 @@ module Sandbox module Connections class AccountCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute company_id diff --git a/lib/finch-api/models/sandbox/connections/account_update_params.rb b/lib/finch-api/models/sandbox/connections/account_update_params.rb index 65e12214..0a3f7e3d 100644 --- a/lib/finch-api/models/sandbox/connections/account_update_params.rb +++ b/lib/finch-api/models/sandbox/connections/account_update_params.rb @@ -6,7 +6,7 @@ module Sandbox module Connections class AccountUpdateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] connection_status diff --git a/lib/finch-api/models/sandbox/directory_create_params.rb b/lib/finch-api/models/sandbox/directory_create_params.rb index ef6d9eab..4a5f9e66 100644 --- a/lib/finch-api/models/sandbox/directory_create_params.rb +++ b/lib/finch-api/models/sandbox/directory_create_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class DirectoryCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] body diff --git a/lib/finch-api/models/sandbox/employment_update_params.rb b/lib/finch-api/models/sandbox/employment_update_params.rb index c9c07878..efdb368b 100644 --- a/lib/finch-api/models/sandbox/employment_update_params.rb +++ b/lib/finch-api/models/sandbox/employment_update_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class EmploymentUpdateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute class_code diff --git a/lib/finch-api/models/sandbox/individual_update_params.rb b/lib/finch-api/models/sandbox/individual_update_params.rb index 028581c9..e51fb6d2 100644 --- a/lib/finch-api/models/sandbox/individual_update_params.rb +++ b/lib/finch-api/models/sandbox/individual_update_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class IndividualUpdateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute dob diff --git a/lib/finch-api/models/sandbox/job_create_params.rb b/lib/finch-api/models/sandbox/job_create_params.rb index de341449..ad9d1646 100644 --- a/lib/finch-api/models/sandbox/job_create_params.rb +++ b/lib/finch-api/models/sandbox/job_create_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class JobCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute type diff --git a/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rb b/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rb index a88f09f2..23efcea6 100644 --- a/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rb +++ b/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rb @@ -6,7 +6,7 @@ module Sandbox module Jobs class ConfigurationRetrieveParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/sandbox/jobs/configuration_update_params.rb b/lib/finch-api/models/sandbox/jobs/configuration_update_params.rb index 7237bcd9..540fbf19 100644 --- a/lib/finch-api/models/sandbox/jobs/configuration_update_params.rb +++ b/lib/finch-api/models/sandbox/jobs/configuration_update_params.rb @@ -6,7 +6,7 @@ module Sandbox module Jobs class ConfigurationUpdateParams < FinchAPI::Models::Sandbox::Jobs::SandboxJobConfiguration # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!parse diff --git a/lib/finch-api/models/sandbox/payment_create_params.rb b/lib/finch-api/models/sandbox/payment_create_params.rb index 35306e20..52c83a28 100644 --- a/lib/finch-api/models/sandbox/payment_create_params.rb +++ b/lib/finch-api/models/sandbox/payment_create_params.rb @@ -5,7 +5,7 @@ module Models module Sandbox class PaymentCreateParams < FinchAPI::BaseModel # @!parse - # extend FinchAPI::RequestParameters::Converter + # extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # @!attribute [r] end_date diff --git a/lib/finch-api/page.rb b/lib/finch-api/page.rb index fde0c8cf..b0eb004b 100644 --- a/lib/finch-api/page.rb +++ b/lib/finch-api/page.rb @@ -23,7 +23,7 @@ module FinchAPI # # items => Array class Page - include FinchAPI::BasePage + include FinchAPI::Type::BasePage # @return [Array, nil] attr_accessor :data @@ -33,7 +33,7 @@ class Page # @api private # - # @param client [FinchAPI::BaseClient] + # @param client [FinchAPI::Transport::BaseClient] # @param req [Hash{Symbol=>Object}] # @param headers [Hash{String=>String}, Net::HTTPHeader] # @param page_data [Hash{Symbol=>Object}] @@ -43,13 +43,13 @@ def initialize(client:, req:, headers:, page_data:) case page_data in {data: Array | nil => data} - @data = data&.map { FinchAPI::Converter.coerce(model, _1) } + @data = data&.map { FinchAPI::Type::Converter.coerce(model, _1) } else end case page_data in {paging: Hash | nil => paging} - @paging = FinchAPI::Converter.coerce(FinchAPI::Models::Paging, paging) + @paging = FinchAPI::Type::Converter.coerce(FinchAPI::Models::Paging, paging) else end end diff --git a/lib/finch-api/pooled_net_requester.rb b/lib/finch-api/pooled_net_requester.rb deleted file mode 100644 index b0f9134e..00000000 --- a/lib/finch-api/pooled_net_requester.rb +++ /dev/null @@ -1,180 +0,0 @@ -# frozen_string_literal: true - -module FinchAPI - # @api private - class PooledNetRequester - # from the golang stdlib - # https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49 - KEEP_ALIVE_TIMEOUT = 30 - - class << self - # @api private - # - # @param url [URI::Generic] - # - # @return [Net::HTTP] - def connect(url) - port = - case [url.port, url.scheme] - in [Integer, _] - url.port - in [nil, "http" | "ws"] - Net::HTTP.http_default_port - in [nil, "https" | "wss"] - Net::HTTP.https_default_port - end - - Net::HTTP.new(url.host, port).tap do - _1.use_ssl = %w[https wss].include?(url.scheme) - _1.max_retries = 0 - end - end - - # @api private - # - # @param conn [Net::HTTP] - # @param deadline [Float] - def calibrate_socket_timeout(conn, deadline) - timeout = deadline - FinchAPI::Util.monotonic_secs - conn.open_timeout = conn.read_timeout = conn.write_timeout = conn.continue_timeout = timeout - end - - # @api private - # - # @param request [Hash{Symbol=>Object}] . - # - # @option request [Symbol] :method - # - # @option request [URI::Generic] :url - # - # @option request [Hash{String=>String}] :headers - # - # @param blk [Proc] - # - # @yieldparam [String] - # @return [Net::HTTPGenericRequest] - def build_request(request, &) - method, url, headers, body = request.fetch_values(:method, :url, :headers, :body) - req = Net::HTTPGenericRequest.new( - method.to_s.upcase, - !body.nil?, - method != :head, - url.to_s - ) - - headers.each { req[_1] = _2 } - - case body - in nil - nil - in String - req["content-length"] ||= body.bytesize.to_s unless req["transfer-encoding"] - req.body_stream = FinchAPI::Util::ReadIOAdapter.new(body, &) - in StringIO - req["content-length"] ||= body.size.to_s unless req["transfer-encoding"] - req.body_stream = FinchAPI::Util::ReadIOAdapter.new(body, &) - in IO | Enumerator - req["transfer-encoding"] ||= "chunked" unless req["content-length"] - req.body_stream = FinchAPI::Util::ReadIOAdapter.new(body, &) - end - - req - end - end - - # @api private - # - # @param url [URI::Generic] - # @param deadline [Float] - # @param blk [Proc] - # - # @raise [Timeout::Error] - # @yieldparam [Net::HTTP] - private def with_pool(url, deadline:, &blk) - origin = FinchAPI::Util.uri_origin(url) - timeout = deadline - FinchAPI::Util.monotonic_secs - pool = - @mutex.synchronize do - @pools[origin] ||= ConnectionPool.new(size: @size) do - self.class.connect(url) - end - end - - pool.with(timeout: timeout, &blk) - end - - # @api private - # - # @param request [Hash{Symbol=>Object}] . - # - # @option request [Symbol] :method - # - # @option request [URI::Generic] :url - # - # @option request [Hash{String=>String}] :headers - # - # @option request [Object] :body - # - # @option request [Float] :deadline - # - # @return [Array(Integer, Net::HTTPResponse, Enumerable)] - def execute(request) - url, deadline = request.fetch_values(:url, :deadline) - - eof = false - finished = false - enum = Enumerator.new do |y| - with_pool(url, deadline: deadline) do |conn| - next if finished - - req = self.class.build_request(request) do - self.class.calibrate_socket_timeout(conn, deadline) - end - - self.class.calibrate_socket_timeout(conn, deadline) - unless conn.started? - conn.keep_alive_timeout = self.class::KEEP_ALIVE_TIMEOUT - conn.start - end - - self.class.calibrate_socket_timeout(conn, deadline) - conn.request(req) do |rsp| - y << [conn, req, rsp] - break if finished - - rsp.read_body do |bytes| - y << bytes - break if finished - - self.class.calibrate_socket_timeout(conn, deadline) - end - eof = true - end - end - rescue Timeout::Error - raise FinchAPI::APITimeoutError - end - - conn, _, response = enum.next - body = FinchAPI::Util.fused_enum(enum, external: true) do - finished = true - tap do - enum.next - rescue StopIteration - nil - end - conn.finish if !eof && conn&.started? - end - [Integer(response.code), response, (response.body = body)] - end - - # @api private - # - # @param size [Integer] - def initialize(size: Etc.nprocessors) - @mutex = Mutex.new - @size = size - @pools = {} - end - end -end diff --git a/lib/finch-api/request_options.rb b/lib/finch-api/request_options.rb index a6f9db8a..57bf68a8 100644 --- a/lib/finch-api/request_options.rb +++ b/lib/finch-api/request_options.rb @@ -1,39 +1,6 @@ # frozen_string_literal: true module FinchAPI - # @api private - module RequestParameters - # @!parse - # # Options to specify HTTP behaviour for this request. - # # @return [FinchAPI::RequestOptions, Hash{Symbol=>Object}] - # attr_accessor :request_options - - # @param mod [Module] - def self.included(mod) - return unless mod <= FinchAPI::BaseModel - - mod.extend(FinchAPI::RequestParameters::Converter) - mod.optional(:request_options, FinchAPI::RequestOptions) - end - - # @api private - module Converter - # @api private - # - # @param params [Object] - # - # @return [Array(Object, Hash{Symbol=>Object})] - def dump_request(params) - case (dumped = dump(params)) - in Hash - [dumped.except(:request_options), dumped[:request_options]] - else - [dumped, nil] - end - end - end - end - # Specify HTTP behaviour to use for a specific request. These options supplement # or override those provided at the client level. # diff --git a/lib/finch-api/responses_page.rb b/lib/finch-api/responses_page.rb index ecff105d..f39f95fb 100644 --- a/lib/finch-api/responses_page.rb +++ b/lib/finch-api/responses_page.rb @@ -23,14 +23,14 @@ module FinchAPI # # individuals => Array class ResponsesPage - include FinchAPI::BasePage + include FinchAPI::Type::BasePage # @return [Array, nil] attr_accessor :responses # @api private # - # @param client [FinchAPI::BaseClient] + # @param client [FinchAPI::Transport::BaseClient] # @param req [Hash{Symbol=>Object}] # @param headers [Hash{String=>String}, Net::HTTPHeader] # @param page_data [Array] @@ -40,7 +40,7 @@ def initialize(client:, req:, headers:, page_data:) case page_data in {responses: Array | nil => responses} - @responses = responses&.map { FinchAPI::Converter.coerce(model, _1) } + @responses = responses&.map { FinchAPI::Type::Converter.coerce(model, _1) } else end end diff --git a/lib/finch-api/single_page.rb b/lib/finch-api/single_page.rb index e05e9e68..0f7ff928 100644 --- a/lib/finch-api/single_page.rb +++ b/lib/finch-api/single_page.rb @@ -23,11 +23,11 @@ module FinchAPI # # payments => Array class SinglePage < ::Array - include FinchAPI::BasePage + include FinchAPI::Type::BasePage # @api private # - # @param client [FinchAPI::BaseClient] + # @param client [FinchAPI::Transport::BaseClient] # @param req [Hash{Symbol=>Object}] # @param headers [Hash{String=>String}, Net::HTTPHeader] # @param page_data [Array] @@ -37,7 +37,7 @@ def initialize(client:, req:, headers:, page_data:) case page_data in Array - replace(page_data.map { FinchAPI::Converter.coerce(model, _1) }) + replace(page_data.map { FinchAPI::Type::Converter.coerce(model, _1) }) else end end diff --git a/lib/finch-api/transport/base_client.rb b/lib/finch-api/transport/base_client.rb new file mode 100644 index 00000000..28815800 --- /dev/null +++ b/lib/finch-api/transport/base_client.rb @@ -0,0 +1,459 @@ +# frozen_string_literal: true + +module FinchAPI + module Transport + # @api private + # + # @abstract + class BaseClient + # from whatwg fetch spec + MAX_REDIRECTS = 20 + + # rubocop:disable Style/MutableConstant + PLATFORM_HEADERS = + { + "x-stainless-arch" => FinchAPI::Util.arch, + "x-stainless-lang" => "ruby", + "x-stainless-os" => FinchAPI::Util.os, + "x-stainless-package-version" => FinchAPI::VERSION, + "x-stainless-runtime" => ::RUBY_ENGINE, + "x-stainless-runtime-version" => ::RUBY_ENGINE_VERSION + } + # rubocop:enable Style/MutableConstant + + class << self + # @api private + # + # @param req [Hash{Symbol=>Object}] + # + # @raise [ArgumentError] + def validate!(req) + keys = [:method, :path, :query, :headers, :body, :unwrap, :page, :stream, :model, :options] + case req + in Hash + req.each_key do |k| + unless keys.include?(k) + raise ArgumentError.new("Request `req` keys must be one of #{keys}, got #{k.inspect}") + end + end + else + raise ArgumentError.new("Request `req` must be a Hash or RequestOptions, got #{req.inspect}") + end + end + + # @api private + # + # @param status [Integer] + # @param headers [Hash{String=>String}, Net::HTTPHeader] + # + # @return [Boolean] + def should_retry?(status, headers:) + coerced = FinchAPI::Util.coerce_boolean(headers["x-should-retry"]) + case [coerced, status] + in [true | false, _] + coerced + in [_, 408 | 409 | 429 | (500..)] + # retry on: + # 408: timeouts + # 409: locks + # 429: rate limits + # 500+: unknown errors + true + else + false + end + end + + # @api private + # + # @param request [Hash{Symbol=>Object}] . + # + # @option request [Symbol] :method + # + # @option request [URI::Generic] :url + # + # @option request [Hash{String=>String}] :headers + # + # @option request [Object] :body + # + # @option request [Integer] :max_retries + # + # @option request [Float] :timeout + # + # @param status [Integer] + # + # @param response_headers [Hash{String=>String}, Net::HTTPHeader] + # + # @return [Hash{Symbol=>Object}] + def follow_redirect(request, status:, response_headers:) + method, url, headers = request.fetch_values(:method, :url, :headers) + location = + Kernel.then do + URI.join(url, response_headers["location"]) + rescue ArgumentError + message = "Server responded with status #{status} but no valid location header." + raise FinchAPI::APIConnectionError.new(url: url, message: message) + end + + request = {**request, url: location} + + case [url.scheme, location.scheme] + in ["https", "http"] + message = "Tried to redirect to a insecure URL" + raise FinchAPI::APIConnectionError.new(url: url, message: message) + else + nil + end + + # from whatwg fetch spec + case [status, method] + in [301 | 302, :post] | [303, _] + drop = %w[content-encoding content-language content-length content-location content-type] + request = { + **request, + method: method == :head ? :head : :get, + headers: headers.except(*drop), + body: nil + } + else + end + + # from undici + if FinchAPI::Util.uri_origin(url) != FinchAPI::Util.uri_origin(location) + drop = %w[authorization cookie host proxy-authorization] + request = {**request, headers: request.fetch(:headers).except(*drop)} + end + + request + end + + # @api private + # + # @param status [Integer, FinchAPI::APIConnectionError] + # @param stream [Enumerable, nil] + def reap_connection!(status, stream:) + case status + in (..199) | (300..499) + stream&.each { next } + in FinchAPI::APIConnectionError | (500..) + FinchAPI::Util.close_fused!(stream) + else + end + end + end + + # @api private + # @return [FinchAPI::Transport::PooledNetRequester] + attr_accessor :requester + + # @api private + # + # @param base_url [String] + # @param timeout [Float] + # @param max_retries [Integer] + # @param initial_retry_delay [Float] + # @param max_retry_delay [Float] + # @param headers [Hash{String=>String, Integer, Array, nil}] + # @param idempotency_header [String, nil] + def initialize( + base_url:, + timeout: 0.0, + max_retries: 0, + initial_retry_delay: 0.0, + max_retry_delay: 0.0, + headers: {}, + idempotency_header: nil + ) + @requester = FinchAPI::Transport::PooledNetRequester.new + @headers = FinchAPI::Util.normalized_headers( + self.class::PLATFORM_HEADERS, + { + "accept" => "application/json", + "content-type" => "application/json" + }, + headers + ) + @base_url = FinchAPI::Util.parse_uri(base_url) + @idempotency_header = idempotency_header&.to_s&.downcase + @max_retries = max_retries + @timeout = timeout + @initial_retry_delay = initial_retry_delay + @max_retry_delay = max_retry_delay + end + + # @api private + # + # @return [Hash{String=>String}] + private def auth_headers = {} + + # @api private + # + # @return [String] + private def generate_idempotency_key = "stainless-ruby-retry-#{SecureRandom.uuid}" + + # @api private + # + # @param req [Hash{Symbol=>Object}] . + # + # @option req [Symbol] :method + # + # @option req [String, Array] :path + # + # @option req [Hash{String=>Array, String, nil}, nil] :query + # + # @option req [Hash{String=>String, Integer, Array, nil}, nil] :headers + # + # @option req [Object, nil] :body + # + # @option req [Symbol, nil] :unwrap + # + # @option req [Class, nil] :page + # + # @option req [Class, nil] :stream + # + # @option req [FinchAPI::Type::Converter, Class, nil] :model + # + # @param opts [Hash{Symbol=>Object}] . + # + # @option opts [String, nil] :idempotency_key + # + # @option opts [Hash{String=>Array, String, nil}, nil] :extra_query + # + # @option opts [Hash{String=>String, nil}, nil] :extra_headers + # + # @option opts [Object, nil] :extra_body + # + # @option opts [Integer, nil] :max_retries + # + # @option opts [Float, nil] :timeout + # + # @return [Hash{Symbol=>Object}] + private def build_request(req, opts) + method, uninterpolated_path = req.fetch_values(:method, :path) + + path = FinchAPI::Util.interpolate_path(uninterpolated_path) + + query = FinchAPI::Util.deep_merge(req[:query].to_h, opts[:extra_query].to_h) + + headers = FinchAPI::Util.normalized_headers( + @headers, + auth_headers, + req[:headers].to_h, + opts[:extra_headers].to_h + ) + + if @idempotency_header && + !headers.key?(@idempotency_header) && + !Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase) + headers[@idempotency_header] = opts.fetch(:idempotency_key) { generate_idempotency_key } + end + + unless headers.key?("x-stainless-retry-count") + headers["x-stainless-retry-count"] = "0" + end + + timeout = opts.fetch(:timeout, @timeout).to_f.clamp((0..)) + unless headers.key?("x-stainless-timeout") || timeout.zero? + headers["x-stainless-timeout"] = timeout.to_s + end + + headers.reject! { |_, v| v.to_s.empty? } + + body = + case method + in :get | :head | :options | :trace + nil + else + FinchAPI::Util.deep_merge(*[req[:body], opts[:extra_body]].compact) + end + + headers, encoded = FinchAPI::Util.encode_content(headers, body) + { + method: method, + url: FinchAPI::Util.join_parsed_uri(@base_url, {**req, path: path, query: query}), + headers: headers, + body: encoded, + max_retries: opts.fetch(:max_retries, @max_retries), + timeout: timeout + } + end + + # @api private + # + # @param headers [Hash{String=>String}] + # @param retry_count [Integer] + # + # @return [Float] + private def retry_delay(headers, retry_count:) + # Non-standard extension + span = Float(headers["retry-after-ms"], exception: false)&.then { _1 / 1000 } + return span if span + + retry_header = headers["retry-after"] + return span if (span = Float(retry_header, exception: false)) + + span = retry_header&.then do + Time.httpdate(_1) - Time.now + rescue ArgumentError + nil + end + return span if span + + scale = retry_count**2 + jitter = 1 - (0.25 * rand) + (@initial_retry_delay * scale * jitter).clamp(0, @max_retry_delay) + end + + # @api private + # + # @param request [Hash{Symbol=>Object}] . + # + # @option request [Symbol] :method + # + # @option request [URI::Generic] :url + # + # @option request [Hash{String=>String}] :headers + # + # @option request [Object] :body + # + # @option request [Integer] :max_retries + # + # @option request [Float] :timeout + # + # @param redirect_count [Integer] + # + # @param retry_count [Integer] + # + # @param send_retry_header [Boolean] + # + # @raise [FinchAPI::APIError] + # @return [Array(Integer, Net::HTTPResponse, Enumerable)] + private def send_request(request, redirect_count:, retry_count:, send_retry_header:) + url, headers, max_retries, timeout = request.fetch_values(:url, :headers, :max_retries, :timeout) + input = {**request.except(:timeout), deadline: FinchAPI::Util.monotonic_secs + timeout} + + if send_retry_header + headers["x-stainless-retry-count"] = retry_count.to_s + end + + begin + status, response, stream = @requester.execute(input) + rescue FinchAPI::APIConnectionError => e + status = e + end + + case status + in ..299 + [status, response, stream] + in 300..399 if redirect_count >= self.class::MAX_REDIRECTS + self.class.reap_connection!(status, stream: stream) + + message = "Failed to complete the request within #{self.class::MAX_REDIRECTS} redirects." + raise FinchAPI::APIConnectionError.new(url: url, message: message) + in 300..399 + self.class.reap_connection!(status, stream: stream) + + request = self.class.follow_redirect(request, status: status, response_headers: response) + send_request( + request, + redirect_count: redirect_count + 1, + retry_count: retry_count, + send_retry_header: send_retry_header + ) + in FinchAPI::APIConnectionError if retry_count >= max_retries + raise status + in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response) + decoded = Kernel.then do + FinchAPI::Util.decode_content(response, stream: stream, suppress_error: true) + ensure + self.class.reap_connection!(status, stream: stream) + end + + raise FinchAPI::APIStatusError.for( + url: url, + status: status, + body: decoded, + request: nil, + response: response + ) + in (400..) | FinchAPI::APIConnectionError + self.class.reap_connection!(status, stream: stream) + + delay = retry_delay(response, retry_count: retry_count) + sleep(delay) + + send_request( + request, + redirect_count: redirect_count, + retry_count: retry_count + 1, + send_retry_header: send_retry_header + ) + end + end + + # Execute the request specified by `req`. This is the method that all resource + # methods call into. + # + # @param req [Hash{Symbol=>Object}] . + # + # @option req [Symbol] :method + # + # @option req [String, Array] :path + # + # @option req [Hash{String=>Array, String, nil}, nil] :query + # + # @option req [Hash{String=>String, Integer, Array, nil}, nil] :headers + # + # @option req [Object, nil] :body + # + # @option req [Symbol, nil] :unwrap + # + # @option req [Class, nil] :page + # + # @option req [Class, nil] :stream + # + # @option req [FinchAPI::Type::Converter, Class, nil] :model + # + # @option req [FinchAPI::RequestOptions, Hash{Symbol=>Object}, nil] :options + # + # @raise [FinchAPI::APIError] + # @return [Object] + def request(req) + self.class.validate!(req) + model = req.fetch(:model) { FinchAPI::Unknown } + opts = req[:options].to_h + FinchAPI::RequestOptions.validate!(opts) + request = build_request(req.except(:options), opts) + url = request.fetch(:url) + + # Don't send the current retry count in the headers if the caller modified the header defaults. + send_retry_header = request.fetch(:headers)["x-stainless-retry-count"] == "0" + status, response, stream = send_request( + request, + redirect_count: 0, + retry_count: 0, + send_retry_header: send_retry_header + ) + + decoded = FinchAPI::Util.decode_content(response, stream: stream) + case req + in { stream: Class => st } + st.new(model: model, url: url, status: status, response: response, stream: decoded) + in { page: Class => page } + page.new(client: self, req: req, headers: response, page_data: decoded) + else + unwrapped = FinchAPI::Util.dig(decoded, req[:unwrap]) + FinchAPI::Type::Converter.coerce(model, unwrapped) + end + end + + # @return [String] + def inspect + # rubocop:disable Layout/LineLength + base_url = FinchAPI::Util.unparse_uri(@base_url) + "#<#{self.class.name}:0x#{object_id.to_s(16)} base_url=#{base_url} max_retries=#{@max_retries} timeout=#{@timeout}>" + # rubocop:enable Layout/LineLength + end + end + end +end diff --git a/lib/finch-api/transport/pooled_net_requester.rb b/lib/finch-api/transport/pooled_net_requester.rb new file mode 100644 index 00000000..1a947803 --- /dev/null +++ b/lib/finch-api/transport/pooled_net_requester.rb @@ -0,0 +1,182 @@ +# frozen_string_literal: true + +module FinchAPI + module Transport + # @api private + class PooledNetRequester + # from the golang stdlib + # https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49 + KEEP_ALIVE_TIMEOUT = 30 + + class << self + # @api private + # + # @param url [URI::Generic] + # + # @return [Net::HTTP] + def connect(url) + port = + case [url.port, url.scheme] + in [Integer, _] + url.port + in [nil, "http" | "ws"] + Net::HTTP.http_default_port + in [nil, "https" | "wss"] + Net::HTTP.https_default_port + end + + Net::HTTP.new(url.host, port).tap do + _1.use_ssl = %w[https wss].include?(url.scheme) + _1.max_retries = 0 + end + end + + # @api private + # + # @param conn [Net::HTTP] + # @param deadline [Float] + def calibrate_socket_timeout(conn, deadline) + timeout = deadline - FinchAPI::Util.monotonic_secs + conn.open_timeout = conn.read_timeout = conn.write_timeout = conn.continue_timeout = timeout + end + + # @api private + # + # @param request [Hash{Symbol=>Object}] . + # + # @option request [Symbol] :method + # + # @option request [URI::Generic] :url + # + # @option request [Hash{String=>String}] :headers + # + # @param blk [Proc] + # + # @yieldparam [String] + # @return [Net::HTTPGenericRequest] + def build_request(request, &) + method, url, headers, body = request.fetch_values(:method, :url, :headers, :body) + req = Net::HTTPGenericRequest.new( + method.to_s.upcase, + !body.nil?, + method != :head, + url.to_s + ) + + headers.each { req[_1] = _2 } + + case body + in nil + nil + in String + req["content-length"] ||= body.bytesize.to_s unless req["transfer-encoding"] + req.body_stream = FinchAPI::Util::ReadIOAdapter.new(body, &) + in StringIO + req["content-length"] ||= body.size.to_s unless req["transfer-encoding"] + req.body_stream = FinchAPI::Util::ReadIOAdapter.new(body, &) + in IO | Enumerator + req["transfer-encoding"] ||= "chunked" unless req["content-length"] + req.body_stream = FinchAPI::Util::ReadIOAdapter.new(body, &) + end + + req + end + end + + # @api private + # + # @param url [URI::Generic] + # @param deadline [Float] + # @param blk [Proc] + # + # @raise [Timeout::Error] + # @yieldparam [Net::HTTP] + private def with_pool(url, deadline:, &blk) + origin = FinchAPI::Util.uri_origin(url) + timeout = deadline - FinchAPI::Util.monotonic_secs + pool = + @mutex.synchronize do + @pools[origin] ||= ConnectionPool.new(size: @size) do + self.class.connect(url) + end + end + + pool.with(timeout: timeout, &blk) + end + + # @api private + # + # @param request [Hash{Symbol=>Object}] . + # + # @option request [Symbol] :method + # + # @option request [URI::Generic] :url + # + # @option request [Hash{String=>String}] :headers + # + # @option request [Object] :body + # + # @option request [Float] :deadline + # + # @return [Array(Integer, Net::HTTPResponse, Enumerable)] + def execute(request) + url, deadline = request.fetch_values(:url, :deadline) + + eof = false + finished = false + enum = Enumerator.new do |y| + with_pool(url, deadline: deadline) do |conn| + next if finished + + req = self.class.build_request(request) do + self.class.calibrate_socket_timeout(conn, deadline) + end + + self.class.calibrate_socket_timeout(conn, deadline) + unless conn.started? + conn.keep_alive_timeout = self.class::KEEP_ALIVE_TIMEOUT + conn.start + end + + self.class.calibrate_socket_timeout(conn, deadline) + conn.request(req) do |rsp| + y << [conn, req, rsp] + break if finished + + rsp.read_body do |bytes| + y << bytes + break if finished + + self.class.calibrate_socket_timeout(conn, deadline) + end + eof = true + end + end + rescue Timeout::Error + raise FinchAPI::APITimeoutError + end + + conn, _, response = enum.next + body = FinchAPI::Util.fused_enum(enum, external: true) do + finished = true + tap do + enum.next + rescue StopIteration + nil + end + conn.finish if !eof && conn&.started? + end + [Integer(response.code), response, (response.body = body)] + end + + # @api private + # + # @param size [Integer] + def initialize(size: Etc.nprocessors) + @mutex = Mutex.new + @size = size + @pools = {} + end + end + end +end diff --git a/lib/finch-api/type.rb b/lib/finch-api/type.rb new file mode 100644 index 00000000..63e3c564 --- /dev/null +++ b/lib/finch-api/type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module FinchAPI + Unknown = FinchAPI::Type::Unknown + + BooleanModel = FinchAPI::Type::BooleanModel + + Enum = FinchAPI::Type::Enum + + Union = FinchAPI::Type::Union + + ArrayOf = FinchAPI::Type::ArrayOf + + HashOf = FinchAPI::Type::HashOf + + BaseModel = FinchAPI::Type::BaseModel + + RequestParameters = FinchAPI::Type::RequestParameters + + # This module contains various type declarations. + module Type + end +end diff --git a/lib/finch-api/type/array_of.rb b/lib/finch-api/type/array_of.rb new file mode 100644 index 00000000..0982bfab --- /dev/null +++ b/lib/finch-api/type/array_of.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + # + # @abstract + # + # Array of items of a given type. + class ArrayOf + include FinchAPI::Type::Converter + + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + def self.[](type_info, spec = {}) = new(type_info, spec) + + # @param other [Object] + # + # @return [Boolean] + def ===(other) = other.is_a?(Array) && other.all?(item_type) + + # @param other [Object] + # + # @return [Boolean] + def ==(other) = other.is_a?(FinchAPI::ArrayOf) && other.nilable? == nilable? && other.item_type == item_type + + # @api private + # + # @param value [Enumerable, Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Array, Object] + def coerce(value, state:) + exactness = state.fetch(:exactness) + + unless value.is_a?(Array) + exactness[:no] += 1 + return value + end + + target = item_type + exactness[:yes] += 1 + value + .map do |item| + case [nilable?, item] + in [true, nil] + exactness[:yes] += 1 + nil + else + FinchAPI::Type::Converter.coerce(target, item, state: state) + end + end + end + + # @api private + # + # @param value [Enumerable, Object] + # + # @return [Array, Object] + def dump(value) + target = item_type + value.is_a?(Array) ? value.map { FinchAPI::Type::Converter.dump(target, _1) } : super + end + + # @api private + # + # @return [FinchAPI::Type::Converter, Class] + protected def item_type = @item_type_fn.call + + # @api private + # + # @return [Boolean] + protected def nilable? = @nilable + + # @api private + # + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + def initialize(type_info, spec = {}) + @item_type_fn = FinchAPI::Type::Converter.type_info(type_info || spec) + @nilable = spec[:nil?] + end + end + end +end diff --git a/lib/finch-api/type/base_model.rb b/lib/finch-api/type/base_model.rb new file mode 100644 index 00000000..0bd19789 --- /dev/null +++ b/lib/finch-api/type/base_model.rb @@ -0,0 +1,355 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @abstract + # + # @example + # # `operation_support_matrix` is a `FinchAPI::Models::OperationSupportMatrix` + # operation_support_matrix => { + # create: create, + # delete: delete, + # read: read + # } + class BaseModel + extend FinchAPI::Type::Converter + + class << self + # @api private + # + # Assumes superclass fields are totally defined before fields are accessed / + # defined on subclasses. + # + # @return [Hash{Symbol=>Hash{Symbol=>Object}}] + def known_fields + @known_fields ||= (self < FinchAPI::BaseModel ? superclass.known_fields.dup : {}) + end + + # @api private + # + # @return [Hash{Symbol=>Hash{Symbol=>Object}}] + def fields + known_fields.transform_values do |field| + {**field.except(:type_fn), type: field.fetch(:type_fn).call} + end + end + + # @api private + # + # @param name_sym [Symbol] + # + # @param required [Boolean] + # + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + private def add_field(name_sym, required:, type_info:, spec:) + type_fn, info = + case type_info + in Proc | FinchAPI::Type::Converter | Class + [FinchAPI::Type::Converter.type_info({**spec, union: type_info}), spec] + in Hash + [FinchAPI::Type::Converter.type_info(type_info), type_info] + end + + setter = "#{name_sym}=" + api_name = info.fetch(:api_name, name_sym) + nilable = info[:nil?] + const = required && !nilable ? info.fetch(:const, FinchAPI::Util::OMIT) : FinchAPI::Util::OMIT + + [name_sym, setter].each { undef_method(_1) } if known_fields.key?(name_sym) + + known_fields[name_sym] = + { + mode: @mode, + api_name: api_name, + required: required, + nilable: nilable, + const: const, + type_fn: type_fn + } + + define_method(setter) { @data.store(name_sym, _1) } + + define_method(name_sym) do + target = type_fn.call + value = @data.fetch(name_sym) { const == FinchAPI::Util::OMIT ? nil : const } + state = {strictness: :strong, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} + if (nilable || !required) && value.nil? + nil + else + FinchAPI::Type::Converter.coerce( + target, + value, + state: state + ) + end + rescue StandardError + cls = self.class.name.split("::").last + message = "Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}. To get the unparsed API response, use #{cls}[:#{__method__}]." + raise FinchAPI::ConversionError.new(message) + end + end + + # @api private + # + # @param name_sym [Symbol] + # + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + def required(name_sym, type_info, spec = {}) + add_field(name_sym, required: true, type_info: type_info, spec: spec) + end + + # @api private + # + # @param name_sym [Symbol] + # + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + def optional(name_sym, type_info, spec = {}) + add_field(name_sym, required: false, type_info: type_info, spec: spec) + end + + # @api private + # + # `request_only` attributes not excluded from `.#coerce` when receiving responses + # even if well behaved servers should not send them + # + # @param blk [Proc] + private def request_only(&blk) + @mode = :dump + blk.call + ensure + @mode = nil + end + + # @api private + # + # `response_only` attributes are omitted from `.#dump` when making requests + # + # @param blk [Proc] + private def response_only(&blk) + @mode = :coerce + blk.call + ensure + @mode = nil + end + + # @param other [Object] + # + # @return [Boolean] + def ==(other) = other.is_a?(Class) && other <= FinchAPI::BaseModel && other.fields == fields + end + + # @param other [Object] + # + # @return [Boolean] + def ==(other) = self.class == other.class && @data == other.to_h + + class << self + # @api private + # + # @param value [FinchAPI::BaseModel, Hash{Object=>Object}, Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [FinchAPI::BaseModel, Object] + def coerce(value, state:) + exactness = state.fetch(:exactness) + + if value.is_a?(self.class) + exactness[:yes] += 1 + return value + end + + unless (val = FinchAPI::Util.coerce_hash(value)).is_a?(Hash) + exactness[:no] += 1 + return value + end + exactness[:yes] += 1 + + keys = val.keys.to_set + instance = new + data = instance.to_h + + fields.each do |name, field| + mode, required, target = field.fetch_values(:mode, :required, :type) + api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const) + + unless val.key?(api_name) + if const != FinchAPI::Util::OMIT + exactness[:yes] += 1 + elsif required && mode != :dump + exactness[nilable ? :maybe : :no] += 1 + else + exactness[:yes] += 1 + end + next + end + + item = val.fetch(api_name) + keys.delete(api_name) + + converted = + if item.nil? && (nilable || !required) + exactness[nilable ? :yes : :maybe] += 1 + nil + else + coerced = FinchAPI::Type::Converter.coerce(target, item, state: state) + case target + in FinchAPI::Type::Converter | Symbol + coerced + else + item + end + end + data.store(name, converted) + end + + keys.each { data.store(_1, val.fetch(_1)) } + instance + end + + # @api private + # + # @param value [FinchAPI::BaseModel, Object] + # + # @return [Hash{Object=>Object}, Object] + def dump(value) + unless (coerced = FinchAPI::Util.coerce_hash(value)).is_a?(Hash) + return super + end + + acc = {} + + coerced.each do |key, val| + name = key.is_a?(String) ? key.to_sym : key + case (field = known_fields[name]) + in nil + acc.store(name, super(val)) + else + mode, api_name, type_fn = field.fetch_values(:mode, :api_name, :type_fn) + case mode + in :coerce + next + else + target = type_fn.call + acc.store(api_name, FinchAPI::Type::Converter.dump(target, val)) + end + end + end + + known_fields.each_value do |field| + mode, api_name, const = field.fetch_values(:mode, :api_name, :const) + next if mode == :coerce || acc.key?(api_name) || const == FinchAPI::Util::OMIT + acc.store(api_name, const) + end + + acc + end + end + + # Returns the raw value associated with the given key, if found. Otherwise, nil is + # returned. + # + # It is valid to lookup keys that are not in the API spec, for example to access + # undocumented features. This method does not parse response data into + # higher-level types. Lookup by anything other than a Symbol is an ArgumentError. + # + # @param key [Symbol] + # + # @return [Object, nil] + def [](key) + unless key.instance_of?(Symbol) + raise ArgumentError.new("Expected symbol key for lookup, got #{key.inspect}") + end + + @data[key] + end + + # Returns a Hash of the data underlying this object. O(1) + # + # Keys are Symbols and values are the raw values from the response. The return + # value indicates which values were ever set on the object. i.e. there will be a + # key in this hash if they ever were, even if the set value was nil. + # + # This method is not recursive. The returned value is shared by the object, so it + # should not be mutated. + # + # @return [Hash{Symbol=>Object}] + def to_h = @data + + alias_method :to_hash, :to_h + + # @param keys [Array, nil] + # + # @return [Hash{Symbol=>Object}] + def deconstruct_keys(keys) + (keys || self.class.known_fields.keys) + .filter_map do |k| + unless self.class.known_fields.key?(k) + next + end + + [k, public_send(k)] + end + .to_h + end + + # Create a new instance of a model. + # + # @param data [Hash{Symbol=>Object}, FinchAPI::BaseModel] + def initialize(data = {}) + case FinchAPI::Util.coerce_hash(data) + in Hash => coerced + @data = coerced + else + raise ArgumentError.new("Expected a #{Hash} or #{FinchAPI::BaseModel}, got #{data.inspect}") + end + end + + # @return [String] + def inspect + rows = self.class.known_fields.keys.map do + "#{_1}=#{@data.key?(_1) ? public_send(_1) : ''}" + rescue FinchAPI::ConversionError + "#{_1}=#{@data.fetch(_1)}" + end + "#<#{self.class.name}:0x#{object_id.to_s(16)} #{rows.join(' ')}>" + end + end + end +end diff --git a/lib/finch-api/type/base_page.rb b/lib/finch-api/type/base_page.rb new file mode 100644 index 00000000..9cd0d228 --- /dev/null +++ b/lib/finch-api/type/base_page.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @example + # if page.has_next? + # page = page.next_page + # end + # + # @example + # page.auto_paging_each do |access_token| + # puts(access_token) + # end + # + # @example + # access_tokens = + # page + # .to_enum + # .lazy + # .select { _1.object_id.even? } + # .map(&:itself) + # .take(2) + # .to_a + # + # access_tokens => Array + module BasePage + # rubocop:disable Lint/UnusedMethodArgument + + # @return [Boolean] + def next_page? = (raise NotImplementedError) + + # @raise [FinchAPI::APIError] + # @return [FinchAPI::Type::BasePage] + def next_page = (raise NotImplementedError) + + # @param blk [Proc] + # + # @return [void] + def auto_paging_each(&) = (raise NotImplementedError) + + # @return [Enumerable] + def to_enum = super(:auto_paging_each) + + alias_method :enum_for, :to_enum + + # @api private + # + # @param client [FinchAPI::Transport::BaseClient] + # @param req [Hash{Symbol=>Object}] + # @param headers [Hash{String=>String}, Net::HTTPHeader] + # @param page_data [Object] + def initialize(client:, req:, headers:, page_data:) + @client = client + @req = req + super() + end + + # rubocop:enable Lint/UnusedMethodArgument + end + end +end diff --git a/lib/finch-api/type/boolean_model.rb b/lib/finch-api/type/boolean_model.rb new file mode 100644 index 00000000..38735b00 --- /dev/null +++ b/lib/finch-api/type/boolean_model.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + # + # @abstract + # + # Ruby has no Boolean class; this is something for models to refer to. + class BooleanModel + extend FinchAPI::Type::Converter + + # @param other [Object] + # + # @return [Boolean] + def self.===(other) = other == true || other == false + + # @param other [Object] + # + # @return [Boolean] + def self.==(other) = other.is_a?(Class) && other <= FinchAPI::BooleanModel + + class << self + # @api private + # + # @param value [Boolean, Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Boolean, Object] + def coerce(value, state:) + state.fetch(:exactness)[value == true || value == false ? :yes : :no] += 1 + value + end + + # @!parse + # # @api private + # # + # # @param value [Boolean, Object] + # # + # # @return [Boolean, Object] + # def dump(value) = super + end + end + end +end diff --git a/lib/finch-api/type/converter.rb b/lib/finch-api/type/converter.rb new file mode 100644 index 00000000..911c1e34 --- /dev/null +++ b/lib/finch-api/type/converter.rb @@ -0,0 +1,211 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + module Converter + # rubocop:disable Lint/UnusedMethodArgument + + # @api private + # + # @param value [Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Object] + def coerce(value, state:) = (raise NotImplementedError) + + # @api private + # + # @param value [Object] + # + # @return [Object] + def dump(value) + case value + in Array + value.map { FinchAPI::Unknown.dump(_1) } + in Hash + value.transform_values { FinchAPI::Unknown.dump(_1) } + in FinchAPI::BaseModel + value.class.dump(value) + else + value + end + end + + # rubocop:enable Lint/UnusedMethodArgument + + class << self + # @api private + # + # @param spec [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + # + # @return [Proc] + def type_info(spec) + case spec + in Proc + spec + in Hash + type_info(spec.slice(:const, :enum, :union).first&.last) + in true | false + -> { FinchAPI::BooleanModel } + in FinchAPI::Type::Converter | Class | Symbol + -> { spec } + in NilClass | Integer | Float + -> { spec.class } + end + end + + # @api private + # + # Based on `target`, transform `value` into `target`, to the extent possible: + # + # 1. if the given `value` conforms to `target` already, return the given `value` + # 2. if it's possible and safe to convert the given `value` to `target`, then the + # converted value + # 3. otherwise, the given `value` unaltered + # + # The coercion process is subject to improvement between minor release versions. + # See https://docs.pydantic.dev/latest/concepts/unions/#smart-mode + # + # @param target [FinchAPI::Type::Converter, Class] + # + # @param value [Object] + # + # @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`, or `:strong`. This informs the + # coercion strategy when we have to decide between multiple possible conversion + # targets: + # + # - `true`: the conversion must be exact, with minimum coercion. + # - `false`: the conversion can be approximate, with some coercion. + # - `:strong`: the conversion must be exact, with no coercion, and raise an error + # if not possible. + # + # The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For + # any given conversion attempt, the exactness will be updated based on how closely + # the value recursively matches the target type: + # + # - `yes`: the value can be converted to the target type with minimum coercion. + # - `maybe`: the value can be converted to the target type with some reasonable + # coercion. + # - `no`: the value cannot be converted to the target type. + # + # See implementation below for more details. + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Object] + def coerce( + target, + value, + state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} + ) + strictness, exactness = state.fetch_values(:strictness, :exactness) + + case target + in FinchAPI::Type::Converter + return target.coerce(value, state: state) + in Class + if value.is_a?(target) + exactness[:yes] += 1 + return value + end + + case target + in -> { _1 <= NilClass } + exactness[value.nil? ? :yes : :maybe] += 1 + return nil + in -> { _1 <= Integer } + if value.is_a?(Integer) + exactness[:yes] += 1 + return value + elsif strictness == :strong + message = "no implicit conversion of #{value.class} into #{target.inspect}" + raise TypeError.new(message) + else + Kernel.then do + return Integer(value).tap { exactness[:maybe] += 1 } + rescue ArgumentError, TypeError + end + end + in -> { _1 <= Float } + if value.is_a?(Numeric) + exactness[:yes] += 1 + return Float(value) + elsif strictness == :strong + message = "no implicit conversion of #{value.class} into #{target.inspect}" + raise TypeError.new(message) + else + Kernel.then do + return Float(value).tap { exactness[:maybe] += 1 } + rescue ArgumentError, TypeError + end + end + in -> { _1 <= String } + case value + in String | Symbol | Numeric + exactness[value.is_a?(Numeric) ? :maybe : :yes] += 1 + return value.to_s + else + if strictness == :strong + message = "no implicit conversion of #{value.class} into #{target.inspect}" + raise TypeError.new(message) + end + end + in -> { _1 <= Date || _1 <= Time } + Kernel.then do + return target.parse(value).tap { exactness[:yes] += 1 } + rescue ArgumentError, TypeError => e + raise e if strictness == :strong + end + in -> { _1 <= IO } if value.is_a?(String) + exactness[:yes] += 1 + return StringIO.new(value.b) + else + end + in Symbol + if (value.is_a?(Symbol) || value.is_a?(String)) && value.to_sym == target + exactness[:yes] += 1 + return target + elsif strictness == :strong + message = "cannot convert non-matching #{value.class} into #{target.inspect}" + raise ArgumentError.new(message) + end + else + end + + exactness[:no] += 1 + value + end + + # @api private + # + # @param target [FinchAPI::Type::Converter, Class] + # @param value [Object] + # + # @return [Object] + def dump(target, value) + target.is_a?(FinchAPI::Type::Converter) ? target.dump(value) : FinchAPI::Unknown.dump(value) + end + end + end + end +end diff --git a/lib/finch-api/type/enum.rb b/lib/finch-api/type/enum.rb new file mode 100644 index 00000000..57e80499 --- /dev/null +++ b/lib/finch-api/type/enum.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + # + # A value from among a specified list of options. OpenAPI enum values map to Ruby + # values in the SDK as follows: + # + # 1. boolean => true | false + # 2. integer => Integer + # 3. float => Float + # 4. string => Symbol + # + # We can therefore convert string values to Symbols, but can't convert other + # values safely. + # + # @example + # # `connection_status_type` is a `FinchAPI::Models::ConnectionStatusType` + # case connection_status_type + # when FinchAPI::Models::ConnectionStatusType::PENDING + # # ... + # when FinchAPI::Models::ConnectionStatusType::PROCESSING + # # ... + # when FinchAPI::Models::ConnectionStatusType::CONNECTED + # # ... + # else + # puts(connection_status_type) + # end + # + # @example + # case connection_status_type + # in :pending + # # ... + # in :processing + # # ... + # in :connected + # # ... + # else + # puts(connection_status_type) + # end + module Enum + include FinchAPI::Type::Converter + + # All of the valid Symbol values for this enum. + # + # @return [Array] + def values = (@values ||= constants.map { const_get(_1) }) + + # @api private + # + # Guard against thread safety issues by instantiating `@values`. + private def finalize! = values + + # @param other [Object] + # + # @return [Boolean] + def ===(other) = values.include?(other) + + # @param other [Object] + # + # @return [Boolean] + def ==(other) + other.is_a?(Module) && other.singleton_class <= FinchAPI::Enum && other.values.to_set == values.to_set + end + + # @api private + # + # Unlike with primitives, `Enum` additionally validates that the value is a member + # of the enum. + # + # @param value [String, Symbol, Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Symbol, Object] + def coerce(value, state:) + exactness = state.fetch(:exactness) + val = value.is_a?(String) ? value.to_sym : value + + if values.include?(val) + exactness[:yes] += 1 + val + else + exactness[values.first&.class == val.class ? :maybe : :no] += 1 + value + end + end + + # @!parse + # # @api private + # # + # # @param value [Symbol, Object] + # # + # # @return [Symbol, Object] + # def dump(value) = super + end + end +end diff --git a/lib/finch-api/type/hash_of.rb b/lib/finch-api/type/hash_of.rb new file mode 100644 index 00000000..061e8f1c --- /dev/null +++ b/lib/finch-api/type/hash_of.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + # + # @abstract + # + # Hash of items of a given type. + class HashOf + include FinchAPI::Type::Converter + + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + def self.[](type_info, spec = {}) = new(type_info, spec) + + # @param other [Object] + # + # @return [Boolean] + def ===(other) + type = item_type + case other + in Hash + other.all? do |key, val| + case [key, val] + in [Symbol | String, ^type] + true + else + false + end + end + else + false + end + end + + # @param other [Object] + # + # @return [Boolean] + def ==(other) = other.is_a?(FinchAPI::HashOf) && other.nilable? == nilable? && other.item_type == item_type + + # @api private + # + # @param value [Hash{Object=>Object}, Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Hash{Symbol=>Object}, Object] + def coerce(value, state:) + exactness = state.fetch(:exactness) + + unless value.is_a?(Hash) + exactness[:no] += 1 + return value + end + + target = item_type + exactness[:yes] += 1 + value + .to_h do |key, val| + k = key.is_a?(String) ? key.to_sym : key + v = + case [nilable?, val] + in [true, nil] + exactness[:yes] += 1 + nil + else + FinchAPI::Type::Converter.coerce(target, val, state: state) + end + + exactness[:no] += 1 unless k.is_a?(Symbol) + [k, v] + end + end + + # @api private + # + # @param value [Hash{Object=>Object}, Object] + # + # @return [Hash{Symbol=>Object}, Object] + def dump(value) + target = item_type + if value.is_a?(Hash) + value.transform_values do + FinchAPI::Type::Converter.dump(target, _1) + end + else + super + end + end + + # @api private + # + # @return [FinchAPI::Type::Converter, Class] + protected def item_type = @item_type_fn.call + + # @api private + # + # @return [Boolean] + protected def nilable? = @nilable + + # @api private + # + # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + def initialize(type_info, spec = {}) + @item_type_fn = FinchAPI::Type::Converter.type_info(type_info || spec) + @nilable = spec[:nil?] + end + end + end +end diff --git a/lib/finch-api/type/request_parameters.rb b/lib/finch-api/type/request_parameters.rb new file mode 100644 index 00000000..fad5d1c4 --- /dev/null +++ b/lib/finch-api/type/request_parameters.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + module RequestParameters + # @!parse + # # Options to specify HTTP behaviour for this request. + # # @return [FinchAPI::RequestOptions, Hash{Symbol=>Object}] + # attr_accessor :request_options + + # @param mod [Module] + def self.included(mod) + return unless mod <= FinchAPI::BaseModel + + mod.extend(FinchAPI::Type::RequestParameters::Converter) + mod.optional(:request_options, FinchAPI::RequestOptions) + end + + # @api private + module Converter + # @api private + # + # @param params [Object] + # + # @return [Array(Object, Hash{Symbol=>Object})] + def dump_request(params) + case (dumped = dump(params)) + in Hash + [dumped.except(:request_options), dumped[:request_options]] + else + [dumped, nil] + end + end + end + end + end +end diff --git a/lib/finch-api/type/union.rb b/lib/finch-api/type/union.rb new file mode 100644 index 00000000..3b73e76d --- /dev/null +++ b/lib/finch-api/type/union.rb @@ -0,0 +1,204 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + # + # @example + # # `document_retreive_response` is a `FinchAPI::Models::HRIS::DocumentRetreiveResponse` + # case document_retreive_response + # when FinchAPI::Models::HRIS::W42020 + # puts(document_retreive_response.data) + # when FinchAPI::Models::HRIS::W42005 + # puts(document_retreive_response.type) + # else + # puts(document_retreive_response) + # end + # + # @example + # case document_retreive_response + # in {type: :w4_2020, data: data, year: year} + # puts(data) + # in {type: :w4_2005, data: data, year: year} + # puts(year) + # else + # puts(document_retreive_response) + # end + module Union + include FinchAPI::Type::Converter + + # @api private + # + # All of the specified variant info for this union. + # + # @return [Array] + private def known_variants = (@known_variants ||= []) + + # @api private + # + # @return [Array] + protected def derefed_variants + @known_variants.map { |key, variant_fn| [key, variant_fn.call] } + end + + # All of the specified variants for this union. + # + # @return [Array] + def variants = derefed_variants.map(&:last) + + # @api private + # + # @param property [Symbol] + private def discriminator(property) + case property + in Symbol + @discriminator = property + end + end + + # @api private + # + # @param key [Symbol, Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] + # + # @param spec [Hash{Symbol=>Object}, Proc, FinchAPI::Type::Converter, Class] . + # + # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const + # + # @option spec [Proc] :enum + # + # @option spec [Proc] :union + # + # @option spec [Boolean] :"nil?" + private def variant(key, spec = nil) + variant_info = + case key + in Symbol + [key, FinchAPI::Type::Converter.type_info(spec)] + in Proc | FinchAPI::Type::Converter | Class | Hash + [nil, FinchAPI::Type::Converter.type_info(key)] + end + + known_variants << variant_info + end + + # @api private + # + # @param value [Object] + # + # @return [FinchAPI::Type::Converter, Class, nil] + private def resolve_variant(value) + case [@discriminator, value] + in [_, FinchAPI::BaseModel] + value.class + in [Symbol, Hash] + key = value.fetch(@discriminator) do + value.fetch(@discriminator.to_s, FinchAPI::Util::OMIT) + end + + return nil if key == FinchAPI::Util::OMIT + + key = key.to_sym if key.is_a?(String) + known_variants.find { |k,| k == key }&.last&.call + else + nil + end + end + + # rubocop:disable Style/HashEachMethods + # rubocop:disable Style/CaseEquality + + # @param other [Object] + # + # @return [Boolean] + def ===(other) + known_variants.any? do |_, variant_fn| + variant_fn.call === other + end + end + + # @param other [Object] + # + # @return [Boolean] + def ==(other) + other.is_a?(Module) && other.singleton_class <= FinchAPI::Union && other.derefed_variants == derefed_variants + end + + # @api private + # + # @param value [Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Object] + def coerce(value, state:) + if (target = resolve_variant(value)) + return FinchAPI::Type::Converter.coerce(target, value, state: state) + end + + strictness = state.fetch(:strictness) + exactness = state.fetch(:exactness) + state[:strictness] = strictness == :strong ? true : strictness + + alternatives = [] + known_variants.each do |_, variant_fn| + target = variant_fn.call + exact = state[:exactness] = {yes: 0, no: 0, maybe: 0} + state[:branched] += 1 + + coerced = FinchAPI::Type::Converter.coerce(target, value, state: state) + yes, no, maybe = exact.values + if (no + maybe).zero? || (!strictness && yes.positive?) + exact.each { exactness[_1] += _2 } + state[:exactness] = exactness + return coerced + elsif maybe.positive? + alternatives << [[-yes, -maybe, no], exact, coerced] + end + end + + case alternatives.sort_by(&:first) + in [] + exactness[:no] += 1 + if strictness == :strong + message = "no possible conversion of #{value.class} into a variant of #{target.inspect}" + raise ArgumentError.new(message) + end + value + in [[_, exact, coerced], *] + exact.each { exactness[_1] += _2 } + coerced + end + .tap { state[:exactness] = exactness } + ensure + state[:strictness] = strictness + end + + # @api private + # + # @param value [Object] + # + # @return [Object] + def dump(value) + if (target = resolve_variant(value)) + return FinchAPI::Type::Converter.dump(target, value) + end + + known_variants.each do + target = _2.call + return FinchAPI::Type::Converter.dump(target, value) if target === value + end + + super + end + + # rubocop:enable Style/CaseEquality + # rubocop:enable Style/HashEachMethods + end + end +end diff --git a/lib/finch-api/type/unknown.rb b/lib/finch-api/type/unknown.rb new file mode 100644 index 00000000..3b93a847 --- /dev/null +++ b/lib/finch-api/type/unknown.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module FinchAPI + module Type + # @api private + # + # @abstract + # + # When we don't know what to expect for the value. + class Unknown + extend FinchAPI::Type::Converter + + # rubocop:disable Lint/UnusedMethodArgument + + # @param other [Object] + # + # @return [Boolean] + def self.===(other) = true + + # @param other [Object] + # + # @return [Boolean] + def self.==(other) = other.is_a?(Class) && other <= FinchAPI::Unknown + + class << self + # @api private + # + # @param value [Object] + # + # @param state [Hash{Symbol=>Object}] . + # + # @option state [Boolean, :strong] :strictness + # + # @option state [Hash{Symbol=>Object}] :exactness + # + # @option state [Integer] :branched + # + # @return [Object] + def coerce(value, state:) + state.fetch(:exactness)[:yes] += 1 + value + end + + # @!parse + # # @api private + # # + # # @param value [Object] + # # + # # @return [Object] + # def dump(value) = super + end + + # rubocop:enable Lint/UnusedMethodArgument + end + end +end diff --git a/rbi/lib/finch-api/base_client.rbi b/rbi/lib/finch-api/base_client.rbi deleted file mode 100644 index 356ef4ca..00000000 --- a/rbi/lib/finch-api/base_client.rbi +++ /dev/null @@ -1,196 +0,0 @@ -# typed: strong - -module FinchAPI - # @api private - class BaseClient - abstract! - - RequestComponentsShape = - T.type_alias do - { - method: Symbol, - path: T.any(String, T::Array[String]), - query: T.nilable(T::Hash[String, T.nilable(T.any(T::Array[String], String))]), - headers: T.nilable( - T::Hash[String, - T.nilable( - T.any( - String, - Integer, - T::Array[T.nilable(T.any(String, Integer))] - ) - )] - ), - body: T.nilable(T.anything), - unwrap: T.nilable(Symbol), - page: T.nilable(T::Class[FinchAPI::BasePage[FinchAPI::BaseModel]]), - stream: T.nilable(T::Class[T.anything]), - model: T.nilable(FinchAPI::Converter::Input), - options: T.nilable(T.any(FinchAPI::RequestOptions, FinchAPI::Util::AnyHash)) - } - end - - RequestInputShape = - T.type_alias do - { - method: Symbol, - url: URI::Generic, - headers: T::Hash[String, String], - body: T.anything, - max_retries: Integer, - timeout: Float - } - end - - # from whatwg fetch spec - MAX_REDIRECTS = 20 - - PLATFORM_HEADERS = T::Hash[String, String] - - class << self - # @api private - sig { params(req: FinchAPI::BaseClient::RequestComponentsShape).void } - def validate!(req) - end - - # @api private - sig do - params(status: Integer, headers: T.any(T::Hash[String, String], Net::HTTPHeader)).returns(T::Boolean) - end - def should_retry?(status, headers:) - end - - # @api private - sig do - params( - request: FinchAPI::BaseClient::RequestInputShape, - status: Integer, - response_headers: T.any(T::Hash[String, String], Net::HTTPHeader) - ) - .returns(FinchAPI::BaseClient::RequestInputShape) - end - def follow_redirect(request, status:, response_headers:) - end - - # @api private - sig do - params( - status: T.any(Integer, FinchAPI::APIConnectionError), - stream: T.nilable(T::Enumerable[String]) - ).void - end - def reap_connection!(status, stream:) - end - end - - # @api private - sig { returns(FinchAPI::PooledNetRequester) } - attr_accessor :requester - - # @api private - sig do - params( - base_url: String, - timeout: Float, - max_retries: Integer, - initial_retry_delay: Float, - max_retry_delay: Float, - headers: T::Hash[String, - T.nilable(T.any(String, Integer, T::Array[T.nilable(T.any(String, Integer))]))], - idempotency_header: T.nilable(String) - ) - .returns(T.attached_class) - end - def self.new( - base_url:, - timeout: 0.0, - max_retries: 0, - initial_retry_delay: 0.0, - max_retry_delay: 0.0, - headers: {}, - idempotency_header: nil - ) - end - - # @api private - sig { overridable.returns(T::Hash[String, String]) } - private def auth_headers - end - - # @api private - sig { returns(String) } - private def generate_idempotency_key - end - - # @api private - sig do - overridable - .params(req: FinchAPI::BaseClient::RequestComponentsShape, opts: FinchAPI::Util::AnyHash) - .returns(FinchAPI::BaseClient::RequestInputShape) - end - private def build_request(req, opts) - end - - # @api private - sig { params(headers: T::Hash[String, String], retry_count: Integer).returns(Float) } - private def retry_delay(headers, retry_count:) - end - - # @api private - sig do - params( - request: FinchAPI::BaseClient::RequestInputShape, - redirect_count: Integer, - retry_count: Integer, - send_retry_header: T::Boolean - ) - .returns([Integer, Net::HTTPResponse, T::Enumerable[String]]) - end - private def send_request(request, redirect_count:, retry_count:, send_retry_header:) - end - - # Execute the request specified by `req`. This is the method that all resource - # methods call into. - sig do - params( - method: Symbol, - path: T.any(String, T::Array[String]), - query: T.nilable(T::Hash[String, T.nilable(T.any(T::Array[String], String))]), - headers: T.nilable( - T::Hash[String, - T.nilable( - T.any( - String, - Integer, - T::Array[T.nilable(T.any(String, Integer))] - ) - )] - ), - body: T.nilable(T.anything), - unwrap: T.nilable(Symbol), - page: T.nilable(T::Class[FinchAPI::BasePage[FinchAPI::BaseModel]]), - stream: T.nilable(T::Class[T.anything]), - model: T.nilable(FinchAPI::Converter::Input), - options: T.nilable(T.any(FinchAPI::RequestOptions, FinchAPI::Util::AnyHash)) - ) - .returns(T.anything) - end - def request( - method, - path, - query: {}, - headers: {}, - body: nil, - unwrap: nil, - page: nil, - stream: nil, - model: FinchAPI::Unknown, - options: {} - ) - end - - sig { returns(String) } - def inspect - end - end -end diff --git a/rbi/lib/finch-api/base_model.rbi b/rbi/lib/finch-api/base_model.rbi deleted file mode 100644 index c1651638..00000000 --- a/rbi/lib/finch-api/base_model.rbi +++ /dev/null @@ -1,609 +0,0 @@ -# typed: strong - -module FinchAPI - # @api private - module Converter - Input = T.type_alias { T.any(FinchAPI::Converter, T::Class[T.anything]) } - - State = - T.type_alias do - { - strictness: T.any(T::Boolean, Symbol), - exactness: {yes: Integer, no: Integer, maybe: Integer}, - branched: Integer - } - end - - # @api private - sig { overridable.params(value: T.anything, state: FinchAPI::Converter::State).returns(T.anything) } - def coerce(value, state:) - end - - # @api private - sig { overridable.params(value: T.anything).returns(T.anything) } - def dump(value) - end - - class << self - # @api private - sig do - params( - spec: T.any( - { - const: T.nilable(T.any(NilClass, T::Boolean, Integer, Float, Symbol)), - enum: T.nilable(T.proc.returns(FinchAPI::Converter::Input)), - union: T.nilable(T.proc.returns(FinchAPI::Converter::Input)) - }, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ) - ) - .returns(T.proc.returns(T.anything)) - end - def self.type_info(spec) - end - - # @api private - # - # Based on `target`, transform `value` into `target`, to the extent possible: - # - # 1. if the given `value` conforms to `target` already, return the given `value` - # 2. if it's possible and safe to convert the given `value` to `target`, then the - # converted value - # 3. otherwise, the given `value` unaltered - # - # The coercion process is subject to improvement between minor release versions. - # See https://docs.pydantic.dev/latest/concepts/unions/#smart-mode - sig do - params(target: FinchAPI::Converter::Input, value: T.anything, state: FinchAPI::Converter::State) - .returns(T.anything) - end - def self.coerce( - target, - value, - # The `strictness` is one of `true`, `false`, or `:strong`. This informs the - # coercion strategy when we have to decide between multiple possible conversion - # targets: - # - # - `true`: the conversion must be exact, with minimum coercion. - # - `false`: the conversion can be approximate, with some coercion. - # - `:strong`: the conversion must be exact, with no coercion, and raise an error - # if not possible. - # - # The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For - # any given conversion attempt, the exactness will be updated based on how closely - # the value recursively matches the target type: - # - # - `yes`: the value can be converted to the target type with minimum coercion. - # - `maybe`: the value can be converted to the target type with some reasonable - # coercion. - # - `no`: the value cannot be converted to the target type. - # - # See implementation below for more details. - state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} - ) - end - - # @api private - sig { params(target: FinchAPI::Converter::Input, value: T.anything).returns(T.anything) } - def self.dump(target, value) - end - end - end - - # @api private - # - # When we don't know what to expect for the value. - class Unknown - extend FinchAPI::Converter - - abstract! - final! - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def self.===(other) - end - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def self.==(other) - end - - class << self - # @api private - sig(:final) do - override.params(value: T.anything, state: FinchAPI::Converter::State).returns(T.anything) - end - def coerce(value, state:) - end - - # @api private - sig(:final) { override.params(value: T.anything).returns(T.anything) } - def dump(value) - end - end - end - - # @api private - # - # Ruby has no Boolean class; this is something for models to refer to. - class BooleanModel - extend FinchAPI::Converter - - abstract! - final! - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def self.===(other) - end - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def self.==(other) - end - - class << self - # @api private - sig(:final) do - override - .params(value: T.any(T::Boolean, T.anything), state: FinchAPI::Converter::State) - .returns(T.any(T::Boolean, T.anything)) - end - def coerce(value, state:) - end - - # @api private - sig(:final) do - override.params(value: T.any(T::Boolean, T.anything)).returns(T.any(T::Boolean, T.anything)) - end - def dump(value) - end - end - end - - # @api private - # - # A value from among a specified list of options. OpenAPI enum values map to Ruby - # values in the SDK as follows: - # - # 1. boolean => true | false - # 2. integer => Integer - # 3. float => Float - # 4. string => Symbol - # - # We can therefore convert string values to Symbols, but can't convert other - # values safely. - module Enum - include FinchAPI::Converter - - # All of the valid Symbol values for this enum. - sig { overridable.returns(T::Array[T.any(NilClass, T::Boolean, Integer, Float, Symbol)]) } - def values - end - - # @api private - # - # Guard against thread safety issues by instantiating `@values`. - sig { void } - private def finalize! - end - - sig { params(other: T.anything).returns(T::Boolean) } - def ===(other) - end - - sig { params(other: T.anything).returns(T::Boolean) } - def ==(other) - end - - # @api private - # - # Unlike with primitives, `Enum` additionally validates that the value is a member - # of the enum. - sig do - override - .params(value: T.any(String, Symbol, T.anything), state: FinchAPI::Converter::State) - .returns(T.any(Symbol, T.anything)) - end - def coerce(value, state:) - end - - # @api private - sig { override.params(value: T.any(Symbol, T.anything)).returns(T.any(Symbol, T.anything)) } - def dump(value) - end - end - - # @api private - module Union - include FinchAPI::Converter - - # @api private - # - # All of the specified variant info for this union. - sig { returns(T::Array[[T.nilable(Symbol), T.proc.returns(FinchAPI::Converter::Input)]]) } - private def known_variants - end - - # @api private - sig { returns(T::Array[[T.nilable(Symbol), T.anything]]) } - protected def derefed_variants - end - - # All of the specified variants for this union. - sig { overridable.returns(T::Array[T.anything]) } - def variants - end - - # @api private - sig { params(property: Symbol).void } - private def discriminator(property) - end - - # @api private - sig do - params( - key: T.any(Symbol, FinchAPI::Util::AnyHash, T.proc.returns(T.anything), T.anything), - spec: T.any(FinchAPI::Util::AnyHash, T.proc.returns(T.anything), T.anything) - ) - .void - end - private def variant(key, spec = nil) - end - - # @api private - sig { params(value: T.anything).returns(T.nilable(T.anything)) } - private def resolve_variant(value) - end - - sig { params(other: T.anything).returns(T::Boolean) } - def ===(other) - end - - sig { params(other: T.anything).returns(T::Boolean) } - def ==(other) - end - - # @api private - sig { override.params(value: T.anything, state: FinchAPI::Converter::State).returns(T.anything) } - def coerce(value, state:) - end - - # @api private - sig { override.params(value: T.anything).returns(T.anything) } - def dump(value) - end - end - - # @api private - # - # Array of items of a given type. - class ArrayOf - include FinchAPI::Converter - - abstract! - final! - - sig(:final) do - params( - type_info: T.any( - FinchAPI::Util::AnyHash, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .returns(T.attached_class) - end - def self.[](type_info, spec = {}) - end - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def ===(other) - end - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def ==(other) - end - - # @api private - sig(:final) do - override - .params(value: T.any(T::Enumerable[T.anything], T.anything), state: FinchAPI::Converter::State) - .returns(T.any(T::Array[T.anything], T.anything)) - end - def coerce(value, state:) - end - - # @api private - sig(:final) do - override - .params(value: T.any(T::Enumerable[T.anything], T.anything)) - .returns(T.any(T::Array[T.anything], T.anything)) - end - def dump(value) - end - - # @api private - sig(:final) { returns(T.anything) } - protected def item_type - end - - # @api private - sig(:final) { returns(T::Boolean) } - protected def nilable? - end - - # @api private - sig(:final) do - params( - type_info: T.any( - FinchAPI::Util::AnyHash, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .void - end - def initialize(type_info, spec = {}) - end - end - - # @api private - # - # Hash of items of a given type. - class HashOf - include FinchAPI::Converter - - abstract! - final! - - sig(:final) do - params( - type_info: T.any( - FinchAPI::Util::AnyHash, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .returns(T.attached_class) - end - def self.[](type_info, spec = {}) - end - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def ===(other) - end - - sig(:final) { params(other: T.anything).returns(T::Boolean) } - def ==(other) - end - - # @api private - sig(:final) do - override - .params(value: T.any(T::Hash[T.anything, T.anything], T.anything), state: FinchAPI::Converter::State) - .returns(T.any(FinchAPI::Util::AnyHash, T.anything)) - end - def coerce(value, state:) - end - - # @api private - sig(:final) do - override - .params(value: T.any(T::Hash[T.anything, T.anything], T.anything)) - .returns(T.any(FinchAPI::Util::AnyHash, T.anything)) - end - def dump(value) - end - - # @api private - sig(:final) { returns(T.anything) } - protected def item_type - end - - # @api private - sig(:final) { returns(T::Boolean) } - protected def nilable? - end - - # @api private - sig(:final) do - params( - type_info: T.any( - FinchAPI::Util::AnyHash, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .void - end - def initialize(type_info, spec = {}) - end - end - - class BaseModel - extend FinchAPI::Converter - - abstract! - - KnownFieldShape = T.type_alias { {mode: T.nilable(Symbol), required: T::Boolean, nilable: T::Boolean} } - - class << self - # @api private - # - # Assumes superclass fields are totally defined before fields are accessed / - # defined on subclasses. - sig do - returns( - T::Hash[Symbol, - T.all( - FinchAPI::BaseModel::KnownFieldShape, - {type_fn: T.proc.returns(FinchAPI::Converter::Input)} - )] - ) - end - def known_fields - end - - # @api private - sig do - returns( - T::Hash[Symbol, - T.all(FinchAPI::BaseModel::KnownFieldShape, {type: FinchAPI::Converter::Input})] - ) - end - def fields - end - - # @api private - sig do - params( - name_sym: Symbol, - required: T::Boolean, - type_info: T.any( - { - const: T.nilable(T.any(NilClass, T::Boolean, Integer, Float, Symbol)), - enum: T.nilable(T.proc.returns(FinchAPI::Converter::Input)), - union: T.nilable(T.proc.returns(FinchAPI::Converter::Input)), - api_name: Symbol, - nil?: T::Boolean - }, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .void - end - private def add_field(name_sym, required:, type_info:, spec:) - end - - # @api private - sig do - params( - name_sym: Symbol, - type_info: T.any( - FinchAPI::Util::AnyHash, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .void - end - def required(name_sym, type_info, spec = {}) - end - - # @api private - sig do - params( - name_sym: Symbol, - type_info: T.any( - FinchAPI::Util::AnyHash, - T.proc.returns(FinchAPI::Converter::Input), - FinchAPI::Converter::Input - ), - spec: FinchAPI::Util::AnyHash - ) - .void - end - def optional(name_sym, type_info, spec = {}) - end - - # @api private - # - # `request_only` attributes not excluded from `.#coerce` when receiving responses - # even if well behaved servers should not send them - sig { params(blk: T.proc.void).void } - private def request_only(&blk) - end - - # @api private - # - # `response_only` attributes are omitted from `.#dump` when making requests - sig { params(blk: T.proc.void).void } - private def response_only(&blk) - end - - sig { params(other: T.anything).returns(T::Boolean) } - def ==(other) - end - end - - sig { params(other: T.anything).returns(T::Boolean) } - def ==(other) - end - - class << self - # @api private - sig do - override - .params( - value: T.any(FinchAPI::BaseModel, T::Hash[T.anything, T.anything], T.anything), - state: FinchAPI::Converter::State - ) - .returns(T.any(T.attached_class, T.anything)) - end - def coerce(value, state:) - end - - # @api private - sig do - override - .params(value: T.any(T.attached_class, T.anything)) - .returns(T.any(T::Hash[T.anything, T.anything], T.anything)) - end - def dump(value) - end - end - - # Returns the raw value associated with the given key, if found. Otherwise, nil is - # returned. - # - # It is valid to lookup keys that are not in the API spec, for example to access - # undocumented features. This method does not parse response data into - # higher-level types. Lookup by anything other than a Symbol is an ArgumentError. - sig { params(key: Symbol).returns(T.nilable(T.anything)) } - def [](key) - end - - # Returns a Hash of the data underlying this object. O(1) - # - # Keys are Symbols and values are the raw values from the response. The return - # value indicates which values were ever set on the object. i.e. there will be a - # key in this hash if they ever were, even if the set value was nil. - # - # This method is not recursive. The returned value is shared by the object, so it - # should not be mutated. - sig { overridable.returns(FinchAPI::Util::AnyHash) } - def to_h - end - - # Returns a Hash of the data underlying this object. O(1) - # - # Keys are Symbols and values are the raw values from the response. The return - # value indicates which values were ever set on the object. i.e. there will be a - # key in this hash if they ever were, even if the set value was nil. - # - # This method is not recursive. The returned value is shared by the object, so it - # should not be mutated. - sig { overridable.returns(FinchAPI::Util::AnyHash) } - def to_hash - end - - sig { params(keys: T.nilable(T::Array[Symbol])).returns(FinchAPI::Util::AnyHash) } - def deconstruct_keys(keys) - end - - # Create a new instance of a model. - sig { params(data: T.any(T::Hash[Symbol, T.anything], T.self_type)).returns(T.attached_class) } - def self.new(data = {}) - end - - sig { returns(String) } - def inspect - end - end -end diff --git a/rbi/lib/finch-api/base_page.rbi b/rbi/lib/finch-api/base_page.rbi deleted file mode 100644 index 0b481300..00000000 --- a/rbi/lib/finch-api/base_page.rbi +++ /dev/null @@ -1,36 +0,0 @@ -# typed: strong - -module FinchAPI - module BasePage - Elem = type_member(:out) - - sig { overridable.returns(T::Boolean) } - def next_page? - end - - sig { overridable.returns(T.self_type) } - def next_page - end - - sig { overridable.params(blk: T.proc.params(arg0: Elem).void).void } - def auto_paging_each(&blk) - end - - sig { returns(T::Enumerable[Elem]) } - def to_enum - end - - # @api private - sig do - params( - client: FinchAPI::BaseClient, - req: FinchAPI::BaseClient::RequestComponentsShape, - headers: T.any(T::Hash[String, String], Net::HTTPHeader), - page_data: T.anything - ) - .void - end - def initialize(client:, req:, headers:, page_data:) - end - end -end diff --git a/rbi/lib/finch-api/client.rbi b/rbi/lib/finch-api/client.rbi index 6af43f2c..bcdc261e 100644 --- a/rbi/lib/finch-api/client.rbi +++ b/rbi/lib/finch-api/client.rbi @@ -1,7 +1,7 @@ # typed: strong module FinchAPI - class Client < FinchAPI::BaseClient + class Client < FinchAPI::Transport::BaseClient DEFAULT_MAX_RETRIES = 2 DEFAULT_TIMEOUT_IN_SECONDS = T.let(60.0, Float) diff --git a/rbi/lib/finch-api/individuals_page.rbi b/rbi/lib/finch-api/individuals_page.rbi index dc735152..3e0af2ef 100644 --- a/rbi/lib/finch-api/individuals_page.rbi +++ b/rbi/lib/finch-api/individuals_page.rbi @@ -2,7 +2,7 @@ module FinchAPI class IndividualsPage - include FinchAPI::BasePage + include FinchAPI::Type::BasePage Elem = type_member diff --git a/rbi/lib/finch-api/models/access_token_create_params.rbi b/rbi/lib/finch-api/models/access_token_create_params.rbi index 2b02d4b9..65374866 100644 --- a/rbi/lib/finch-api/models/access_token_create_params.rbi +++ b/rbi/lib/finch-api/models/access_token_create_params.rbi @@ -3,7 +3,7 @@ module FinchAPI module Models class AccessTokenCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(String) } diff --git a/rbi/lib/finch-api/models/account_disconnect_params.rbi b/rbi/lib/finch-api/models/account_disconnect_params.rbi index 9a204527..5b89384f 100644 --- a/rbi/lib/finch-api/models/account_disconnect_params.rbi +++ b/rbi/lib/finch-api/models/account_disconnect_params.rbi @@ -3,7 +3,7 @@ module FinchAPI module Models class AccountDisconnectParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/account_introspect_params.rbi b/rbi/lib/finch-api/models/account_introspect_params.rbi index 183bc5bb..39f33a32 100644 --- a/rbi/lib/finch-api/models/account_introspect_params.rbi +++ b/rbi/lib/finch-api/models/account_introspect_params.rbi @@ -3,7 +3,7 @@ module FinchAPI module Models class AccountIntrospectParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/connect/session_new_params.rbi b/rbi/lib/finch-api/models/connect/session_new_params.rbi index d87b295f..784c1e83 100644 --- a/rbi/lib/finch-api/models/connect/session_new_params.rbi +++ b/rbi/lib/finch-api/models/connect/session_new_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Connect class SessionNewParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(String) } diff --git a/rbi/lib/finch-api/models/connect/session_reauthenticate_params.rbi b/rbi/lib/finch-api/models/connect/session_reauthenticate_params.rbi index f1306ba9..52d255d3 100644 --- a/rbi/lib/finch-api/models/connect/session_reauthenticate_params.rbi +++ b/rbi/lib/finch-api/models/connect/session_reauthenticate_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Connect class SessionReauthenticateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The ID of the existing connection to reauthenticate diff --git a/rbi/lib/finch-api/models/hris/benefit_create_params.rbi b/rbi/lib/finch-api/models/hris/benefit_create_params.rbi index 4a8c86a7..044347e1 100644 --- a/rbi/lib/finch-api/models/hris/benefit_create_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefit_create_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class BenefitCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Name of the benefit as it appears in the provider and pay statements. Recommend diff --git a/rbi/lib/finch-api/models/hris/benefit_list_params.rbi b/rbi/lib/finch-api/models/hris/benefit_list_params.rbi index f0175d26..a6c61cec 100644 --- a/rbi/lib/finch-api/models/hris/benefit_list_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefit_list_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class BenefitListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rbi b/rbi/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rbi index c9b14062..f7fb6803 100644 --- a/rbi/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class BenefitListSupportedBenefitsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/hris/benefit_retrieve_params.rbi b/rbi/lib/finch-api/models/hris/benefit_retrieve_params.rbi index 38b0371d..aab7154e 100644 --- a/rbi/lib/finch-api/models/hris/benefit_retrieve_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefit_retrieve_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class BenefitRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/hris/benefit_update_params.rbi b/rbi/lib/finch-api/models/hris/benefit_update_params.rbi index 3b5343a9..f8d06c9a 100644 --- a/rbi/lib/finch-api/models/hris/benefit_update_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefit_update_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class BenefitUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Updated name or description. diff --git a/rbi/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rbi b/rbi/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rbi index 7a911dca..6d484da7 100644 --- a/rbi/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module HRIS module Benefits class IndividualEnrollManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Array of the individual_id to enroll and a configuration object. diff --git a/rbi/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbi b/rbi/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbi index 0a8f9470..d6f289f6 100644 --- a/rbi/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module HRIS module Benefits class IndividualEnrolledIDsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbi b/rbi/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbi index 650ad7c8..63a57ee2 100644 --- a/rbi/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module HRIS module Benefits class IndividualRetrieveManyBenefitsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # comma-delimited list of stable Finch uuids for each individual. If empty, diff --git a/rbi/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rbi b/rbi/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rbi index 9a5bc734..7b2b615f 100644 --- a/rbi/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rbi +++ b/rbi/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module HRIS module Benefits class IndividualUnenrollManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Array of individual_ids to unenroll. diff --git a/rbi/lib/finch-api/models/hris/company_retrieve_params.rbi b/rbi/lib/finch-api/models/hris/company_retrieve_params.rbi index ad51c2bc..6032b03c 100644 --- a/rbi/lib/finch-api/models/hris/company_retrieve_params.rbi +++ b/rbi/lib/finch-api/models/hris/company_retrieve_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class CompanyRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/hris/directory_list_individuals_params.rbi b/rbi/lib/finch-api/models/hris/directory_list_individuals_params.rbi index b616e087..62401a2c 100644 --- a/rbi/lib/finch-api/models/hris/directory_list_individuals_params.rbi +++ b/rbi/lib/finch-api/models/hris/directory_list_individuals_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class DirectoryListIndividualsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Number of employees to return (defaults to all) diff --git a/rbi/lib/finch-api/models/hris/directory_list_params.rbi b/rbi/lib/finch-api/models/hris/directory_list_params.rbi index df9594b7..42313e6b 100644 --- a/rbi/lib/finch-api/models/hris/directory_list_params.rbi +++ b/rbi/lib/finch-api/models/hris/directory_list_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class DirectoryListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Number of employees to return (defaults to all) diff --git a/rbi/lib/finch-api/models/hris/document_list_params.rbi b/rbi/lib/finch-api/models/hris/document_list_params.rbi index 1a0660bc..75610793 100644 --- a/rbi/lib/finch-api/models/hris/document_list_params.rbi +++ b/rbi/lib/finch-api/models/hris/document_list_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class DocumentListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Comma-delimited list of stable Finch uuids for each individual. If empty, diff --git a/rbi/lib/finch-api/models/hris/document_retreive_params.rbi b/rbi/lib/finch-api/models/hris/document_retreive_params.rbi index 50c4082e..63fee264 100644 --- a/rbi/lib/finch-api/models/hris/document_retreive_params.rbi +++ b/rbi/lib/finch-api/models/hris/document_retreive_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class DocumentRetreiveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/hris/employment_retrieve_many_params.rbi b/rbi/lib/finch-api/models/hris/employment_retrieve_many_params.rbi index 5328d35e..01339ff9 100644 --- a/rbi/lib/finch-api/models/hris/employment_retrieve_many_params.rbi +++ b/rbi/lib/finch-api/models/hris/employment_retrieve_many_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class EmploymentRetrieveManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The array of batch requests. diff --git a/rbi/lib/finch-api/models/hris/individual_retrieve_many_params.rbi b/rbi/lib/finch-api/models/hris/individual_retrieve_many_params.rbi index c1a70c1d..db8515ec 100644 --- a/rbi/lib/finch-api/models/hris/individual_retrieve_many_params.rbi +++ b/rbi/lib/finch-api/models/hris/individual_retrieve_many_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class IndividualRetrieveManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(T.nilable(FinchAPI::Models::HRIS::IndividualRetrieveManyParams::Options)) } diff --git a/rbi/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rbi b/rbi/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rbi index 165efc26..45115323 100644 --- a/rbi/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rbi +++ b/rbi/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class PayStatementRetrieveManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The array of batch requests. diff --git a/rbi/lib/finch-api/models/hris/payment_list_params.rbi b/rbi/lib/finch-api/models/hris/payment_list_params.rbi index 0287f985..cf033dcd 100644 --- a/rbi/lib/finch-api/models/hris/payment_list_params.rbi +++ b/rbi/lib/finch-api/models/hris/payment_list_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module HRIS class PaymentListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The end date to retrieve payments by a company (inclusive) in `YYYY-MM-DD` diff --git a/rbi/lib/finch-api/models/jobs/automated_create_params.rbi b/rbi/lib/finch-api/models/jobs/automated_create_params.rbi index eb10d8e7..fbb9d827 100644 --- a/rbi/lib/finch-api/models/jobs/automated_create_params.rbi +++ b/rbi/lib/finch-api/models/jobs/automated_create_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Jobs class AutomatedCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The type of job to start. diff --git a/rbi/lib/finch-api/models/jobs/automated_list_params.rbi b/rbi/lib/finch-api/models/jobs/automated_list_params.rbi index 644ff55f..e4d01c52 100644 --- a/rbi/lib/finch-api/models/jobs/automated_list_params.rbi +++ b/rbi/lib/finch-api/models/jobs/automated_list_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Jobs class AutomatedListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Number of items to return diff --git a/rbi/lib/finch-api/models/jobs/automated_retrieve_params.rbi b/rbi/lib/finch-api/models/jobs/automated_retrieve_params.rbi index f4e49c4c..5f5b5afb 100644 --- a/rbi/lib/finch-api/models/jobs/automated_retrieve_params.rbi +++ b/rbi/lib/finch-api/models/jobs/automated_retrieve_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Jobs class AutomatedRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/jobs/manual_retrieve_params.rbi b/rbi/lib/finch-api/models/jobs/manual_retrieve_params.rbi index f23caf2a..225181dd 100644 --- a/rbi/lib/finch-api/models/jobs/manual_retrieve_params.rbi +++ b/rbi/lib/finch-api/models/jobs/manual_retrieve_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Jobs class ManualRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/payroll/pay_group_list_params.rbi b/rbi/lib/finch-api/models/payroll/pay_group_list_params.rbi index 27d545d3..187e9b8e 100644 --- a/rbi/lib/finch-api/models/payroll/pay_group_list_params.rbi +++ b/rbi/lib/finch-api/models/payroll/pay_group_list_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Payroll class PayGroupListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(T.nilable(String)) } diff --git a/rbi/lib/finch-api/models/payroll/pay_group_retrieve_params.rbi b/rbi/lib/finch-api/models/payroll/pay_group_retrieve_params.rbi index c8bc2f5d..95823d0e 100644 --- a/rbi/lib/finch-api/models/payroll/pay_group_retrieve_params.rbi +++ b/rbi/lib/finch-api/models/payroll/pay_group_retrieve_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Payroll class PayGroupRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/provider_list_params.rbi b/rbi/lib/finch-api/models/provider_list_params.rbi index 4c5e4ae7..129b1321 100644 --- a/rbi/lib/finch-api/models/provider_list_params.rbi +++ b/rbi/lib/finch-api/models/provider_list_params.rbi @@ -3,7 +3,7 @@ module FinchAPI module Models class ProviderListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/request_forwarding_forward_params.rbi b/rbi/lib/finch-api/models/request_forwarding_forward_params.rbi index b45804fc..cbbe2b5f 100644 --- a/rbi/lib/finch-api/models/request_forwarding_forward_params.rbi +++ b/rbi/lib/finch-api/models/request_forwarding_forward_params.rbi @@ -3,7 +3,7 @@ module FinchAPI module Models class RequestForwardingForwardParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The HTTP method for the forwarded request. Valid values include: `GET` , `POST` diff --git a/rbi/lib/finch-api/models/sandbox/company_update_params.rbi b/rbi/lib/finch-api/models/sandbox/company_update_params.rbi index cd28482e..513de018 100644 --- a/rbi/lib/finch-api/models/sandbox/company_update_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/company_update_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class CompanyUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # An array of bank account objects associated with the payroll/HRIS system. diff --git a/rbi/lib/finch-api/models/sandbox/connection_create_params.rbi b/rbi/lib/finch-api/models/sandbox/connection_create_params.rbi index 46d30729..59750e2b 100644 --- a/rbi/lib/finch-api/models/sandbox/connection_create_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/connection_create_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class ConnectionCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The provider associated with the connection diff --git a/rbi/lib/finch-api/models/sandbox/connections/account_create_params.rbi b/rbi/lib/finch-api/models/sandbox/connections/account_create_params.rbi index 60c89844..78f521a4 100644 --- a/rbi/lib/finch-api/models/sandbox/connections/account_create_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/connections/account_create_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module Sandbox module Connections class AccountCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(String) } diff --git a/rbi/lib/finch-api/models/sandbox/connections/account_update_params.rbi b/rbi/lib/finch-api/models/sandbox/connections/account_update_params.rbi index a02e3d99..baf486c8 100644 --- a/rbi/lib/finch-api/models/sandbox/connections/account_update_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/connections/account_update_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module Sandbox module Connections class AccountUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(T.nilable(FinchAPI::Models::ConnectionStatusType::OrSymbol)) } diff --git a/rbi/lib/finch-api/models/sandbox/directory_create_params.rbi b/rbi/lib/finch-api/models/sandbox/directory_create_params.rbi index f2e6f7ac..c5f5dc35 100644 --- a/rbi/lib/finch-api/models/sandbox/directory_create_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/directory_create_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class DirectoryCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Array of individuals to create. Takes all combined fields from `/individual` and diff --git a/rbi/lib/finch-api/models/sandbox/directory_create_response.rbi b/rbi/lib/finch-api/models/sandbox/directory_create_response.rbi index 94d3faa9..db5f70a4 100644 --- a/rbi/lib/finch-api/models/sandbox/directory_create_response.rbi +++ b/rbi/lib/finch-api/models/sandbox/directory_create_response.rbi @@ -3,7 +3,7 @@ module FinchAPI module Models module Sandbox - DirectoryCreateResponse = T.let(FinchAPI::ArrayOf[FinchAPI::Unknown], FinchAPI::Converter) + DirectoryCreateResponse = T.let(FinchAPI::ArrayOf[FinchAPI::Unknown], FinchAPI::Type::Converter) end end end diff --git a/rbi/lib/finch-api/models/sandbox/employment_update_params.rbi b/rbi/lib/finch-api/models/sandbox/employment_update_params.rbi index e5ea2b98..a622d232 100644 --- a/rbi/lib/finch-api/models/sandbox/employment_update_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/employment_update_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class EmploymentUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # Worker's compensation classification code for this employee diff --git a/rbi/lib/finch-api/models/sandbox/individual_update_params.rbi b/rbi/lib/finch-api/models/sandbox/individual_update_params.rbi index f807d142..83eaa937 100644 --- a/rbi/lib/finch-api/models/sandbox/individual_update_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/individual_update_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class IndividualUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(T.nilable(String)) } diff --git a/rbi/lib/finch-api/models/sandbox/job_create_params.rbi b/rbi/lib/finch-api/models/sandbox/job_create_params.rbi index 8db17e55..20a51fcb 100644 --- a/rbi/lib/finch-api/models/sandbox/job_create_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/job_create_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class JobCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters # The type of job to start. Currently the only supported type is `data_sync_all` diff --git a/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbi b/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbi index 4f636988..c7b9a8d3 100644 --- a/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module Sandbox module Jobs class ConfigurationRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_response.rbi b/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_response.rbi index 6c4fca76..0058bfc8 100644 --- a/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_response.rbi +++ b/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_response.rbi @@ -5,7 +5,10 @@ module FinchAPI module Sandbox module Jobs ConfigurationRetrieveResponse = - T.let(FinchAPI::ArrayOf[FinchAPI::Models::Sandbox::Jobs::SandboxJobConfiguration], FinchAPI::Converter) + T.let( + FinchAPI::ArrayOf[FinchAPI::Models::Sandbox::Jobs::SandboxJobConfiguration], + FinchAPI::Type::Converter + ) end end end diff --git a/rbi/lib/finch-api/models/sandbox/jobs/configuration_update_params.rbi b/rbi/lib/finch-api/models/sandbox/jobs/configuration_update_params.rbi index 01b47b93..aaa2d816 100644 --- a/rbi/lib/finch-api/models/sandbox/jobs/configuration_update_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/jobs/configuration_update_params.rbi @@ -5,7 +5,7 @@ module FinchAPI module Sandbox module Jobs class ConfigurationUpdateParams < FinchAPI::Models::Sandbox::Jobs::SandboxJobConfiguration - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig do diff --git a/rbi/lib/finch-api/models/sandbox/payment_create_params.rbi b/rbi/lib/finch-api/models/sandbox/payment_create_params.rbi index 4bce37f4..f41dee5d 100644 --- a/rbi/lib/finch-api/models/sandbox/payment_create_params.rbi +++ b/rbi/lib/finch-api/models/sandbox/payment_create_params.rbi @@ -4,7 +4,7 @@ module FinchAPI module Models module Sandbox class PaymentCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters sig { returns(T.nilable(String)) } diff --git a/rbi/lib/finch-api/page.rbi b/rbi/lib/finch-api/page.rbi index f1019dbe..67e95f32 100644 --- a/rbi/lib/finch-api/page.rbi +++ b/rbi/lib/finch-api/page.rbi @@ -2,7 +2,7 @@ module FinchAPI class Page - include FinchAPI::BasePage + include FinchAPI::Type::BasePage Elem = type_member diff --git a/rbi/lib/finch-api/pooled_net_requester.rbi b/rbi/lib/finch-api/pooled_net_requester.rbi deleted file mode 100644 index 5ec8a478..00000000 --- a/rbi/lib/finch-api/pooled_net_requester.rbi +++ /dev/null @@ -1,59 +0,0 @@ -# typed: strong - -module FinchAPI - # @api private - class PooledNetRequester - RequestShape = - T.type_alias do - { - method: Symbol, - url: URI::Generic, - headers: T::Hash[String, String], - body: T.anything, - deadline: Float - } - end - - # from the golang stdlib - # https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49 - KEEP_ALIVE_TIMEOUT = 30 - - class << self - # @api private - sig { params(url: URI::Generic).returns(Net::HTTP) } - def connect(url) - end - - # @api private - sig { params(conn: Net::HTTP, deadline: Float).void } - def calibrate_socket_timeout(conn, deadline) - end - - # @api private - sig do - params(request: FinchAPI::PooledNetRequester::RequestShape, blk: T.proc.params(arg0: String).void) - .returns(Net::HTTPGenericRequest) - end - def build_request(request, &blk) - end - end - - # @api private - sig { params(url: URI::Generic, deadline: Float, blk: T.proc.params(arg0: Net::HTTP).void).void } - private def with_pool(url, deadline:, &blk) - end - - # @api private - sig do - params(request: FinchAPI::PooledNetRequester::RequestShape) - .returns([Integer, Net::HTTPResponse, T::Enumerable[String]]) - end - def execute(request) - end - - # @api private - sig { params(size: Integer).returns(T.attached_class) } - def self.new(size: Etc.nprocessors) - end - end -end diff --git a/rbi/lib/finch-api/request_options.rbi b/rbi/lib/finch-api/request_options.rbi index 9c6d0e10..259f90db 100644 --- a/rbi/lib/finch-api/request_options.rbi +++ b/rbi/lib/finch-api/request_options.rbi @@ -1,21 +1,6 @@ # typed: strong module FinchAPI - # @api private - module RequestParameters - # Options to specify HTTP behaviour for this request. - sig { returns(T.any(FinchAPI::RequestOptions, FinchAPI::Util::AnyHash)) } - attr_accessor :request_options - - # @api private - module Converter - # @api private - sig { params(params: T.anything).returns([T.anything, FinchAPI::Util::AnyHash]) } - def dump_request(params) - end - end - end - # Specify HTTP behaviour to use for a specific request. These options supplement # or override those provided at the client level. # diff --git a/rbi/lib/finch-api/responses_page.rbi b/rbi/lib/finch-api/responses_page.rbi index e30b83c1..0ba0a1a3 100644 --- a/rbi/lib/finch-api/responses_page.rbi +++ b/rbi/lib/finch-api/responses_page.rbi @@ -2,7 +2,7 @@ module FinchAPI class ResponsesPage - include FinchAPI::BasePage + include FinchAPI::Type::BasePage Elem = type_member diff --git a/rbi/lib/finch-api/single_page.rbi b/rbi/lib/finch-api/single_page.rbi index cc98a43f..4e812475 100644 --- a/rbi/lib/finch-api/single_page.rbi +++ b/rbi/lib/finch-api/single_page.rbi @@ -2,7 +2,7 @@ module FinchAPI class SinglePage < ::Array - include FinchAPI::BasePage + include FinchAPI::Type::BasePage Elem = type_member diff --git a/rbi/lib/finch-api/transport/base_client.rbi b/rbi/lib/finch-api/transport/base_client.rbi new file mode 100644 index 00000000..f0b26490 --- /dev/null +++ b/rbi/lib/finch-api/transport/base_client.rbi @@ -0,0 +1,204 @@ +# typed: strong + +module FinchAPI + module Transport + # @api private + class BaseClient + abstract! + + RequestComponentsShape = + T.type_alias do + { + method: Symbol, + path: T.any(String, T::Array[String]), + query: T.nilable(T::Hash[String, T.nilable(T.any(T::Array[String], String))]), + headers: T.nilable( + T::Hash[String, + T.nilable( + T.any( + String, + Integer, + T::Array[T.nilable(T.any(String, Integer))] + ) + )] + ), + body: T.nilable(T.anything), + unwrap: T.nilable(Symbol), + page: T.nilable(T::Class[FinchAPI::Type::BasePage[FinchAPI::BaseModel]]), + stream: T.nilable(T::Class[T.anything]), + model: T.nilable(FinchAPI::Type::Converter::Input), + options: T.nilable(T.any(FinchAPI::RequestOptions, FinchAPI::Util::AnyHash)) + } + end + + RequestInputShape = + T.type_alias do + { + method: Symbol, + url: URI::Generic, + headers: T::Hash[String, String], + body: T.anything, + max_retries: Integer, + timeout: Float + } + end + + # from whatwg fetch spec + MAX_REDIRECTS = 20 + + PLATFORM_HEADERS = T::Hash[String, String] + + class << self + # @api private + sig { params(req: FinchAPI::Transport::BaseClient::RequestComponentsShape).void } + def validate!(req) + end + + # @api private + sig do + params( + status: Integer, + headers: T.any( + T::Hash[String, String], + Net::HTTPHeader + ) + ).returns(T::Boolean) + end + def should_retry?(status, headers:) + end + + # @api private + sig do + params( + request: FinchAPI::Transport::BaseClient::RequestInputShape, + status: Integer, + response_headers: T.any(T::Hash[String, String], Net::HTTPHeader) + ) + .returns(FinchAPI::Transport::BaseClient::RequestInputShape) + end + def follow_redirect(request, status:, response_headers:) + end + + # @api private + sig do + params( + status: T.any(Integer, FinchAPI::APIConnectionError), + stream: T.nilable(T::Enumerable[String]) + ).void + end + def reap_connection!(status, stream:) + end + end + + # @api private + sig { returns(FinchAPI::Transport::PooledNetRequester) } + attr_accessor :requester + + # @api private + sig do + params( + base_url: String, + timeout: Float, + max_retries: Integer, + initial_retry_delay: Float, + max_retry_delay: Float, + headers: T::Hash[String, + T.nilable(T.any(String, Integer, T::Array[T.nilable(T.any(String, Integer))]))], + idempotency_header: T.nilable(String) + ) + .returns(T.attached_class) + end + def self.new( + base_url:, + timeout: 0.0, + max_retries: 0, + initial_retry_delay: 0.0, + max_retry_delay: 0.0, + headers: {}, + idempotency_header: nil + ) + end + + # @api private + sig { overridable.returns(T::Hash[String, String]) } + private def auth_headers + end + + # @api private + sig { returns(String) } + private def generate_idempotency_key + end + + # @api private + sig do + overridable + .params(req: FinchAPI::Transport::BaseClient::RequestComponentsShape, opts: FinchAPI::Util::AnyHash) + .returns(FinchAPI::Transport::BaseClient::RequestInputShape) + end + private def build_request(req, opts) + end + + # @api private + sig { params(headers: T::Hash[String, String], retry_count: Integer).returns(Float) } + private def retry_delay(headers, retry_count:) + end + + # @api private + sig do + params( + request: FinchAPI::Transport::BaseClient::RequestInputShape, + redirect_count: Integer, + retry_count: Integer, + send_retry_header: T::Boolean + ) + .returns([Integer, Net::HTTPResponse, T::Enumerable[String]]) + end + private def send_request(request, redirect_count:, retry_count:, send_retry_header:) + end + + # Execute the request specified by `req`. This is the method that all resource + # methods call into. + sig do + params( + method: Symbol, + path: T.any(String, T::Array[String]), + query: T.nilable(T::Hash[String, T.nilable(T.any(T::Array[String], String))]), + headers: T.nilable( + T::Hash[String, + T.nilable( + T.any( + String, + Integer, + T::Array[T.nilable(T.any(String, Integer))] + ) + )] + ), + body: T.nilable(T.anything), + unwrap: T.nilable(Symbol), + page: T.nilable(T::Class[FinchAPI::Type::BasePage[FinchAPI::BaseModel]]), + stream: T.nilable(T::Class[T.anything]), + model: T.nilable(FinchAPI::Type::Converter::Input), + options: T.nilable(T.any(FinchAPI::RequestOptions, FinchAPI::Util::AnyHash)) + ) + .returns(T.anything) + end + def request( + method, + path, + query: {}, + headers: {}, + body: nil, + unwrap: nil, + page: nil, + stream: nil, + model: FinchAPI::Unknown, + options: {} + ) + end + + sig { returns(String) } + def inspect + end + end + end +end diff --git a/rbi/lib/finch-api/transport/pooled_net_requester.rbi b/rbi/lib/finch-api/transport/pooled_net_requester.rbi new file mode 100644 index 00000000..36effc04 --- /dev/null +++ b/rbi/lib/finch-api/transport/pooled_net_requester.rbi @@ -0,0 +1,64 @@ +# typed: strong + +module FinchAPI + module Transport + # @api private + class PooledNetRequester + RequestShape = + T.type_alias do + { + method: Symbol, + url: URI::Generic, + headers: T::Hash[String, String], + body: T.anything, + deadline: Float + } + end + + # from the golang stdlib + # https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49 + KEEP_ALIVE_TIMEOUT = 30 + + class << self + # @api private + sig { params(url: URI::Generic).returns(Net::HTTP) } + def connect(url) + end + + # @api private + sig { params(conn: Net::HTTP, deadline: Float).void } + def calibrate_socket_timeout(conn, deadline) + end + + # @api private + sig do + params( + request: FinchAPI::Transport::PooledNetRequester::RequestShape, + blk: T.proc.params(arg0: String).void + ) + .returns(Net::HTTPGenericRequest) + end + def build_request(request, &blk) + end + end + + # @api private + sig { params(url: URI::Generic, deadline: Float, blk: T.proc.params(arg0: Net::HTTP).void).void } + private def with_pool(url, deadline:, &blk) + end + + # @api private + sig do + params(request: FinchAPI::Transport::PooledNetRequester::RequestShape) + .returns([Integer, Net::HTTPResponse, T::Enumerable[String]]) + end + def execute(request) + end + + # @api private + sig { params(size: Integer).returns(T.attached_class) } + def self.new(size: Etc.nprocessors) + end + end + end +end diff --git a/rbi/lib/finch-api/type.rbi b/rbi/lib/finch-api/type.rbi new file mode 100644 index 00000000..bf175993 --- /dev/null +++ b/rbi/lib/finch-api/type.rbi @@ -0,0 +1,23 @@ +# typed: strong + +module FinchAPI + Unknown = FinchAPI::Type::Unknown + + BooleanModel = FinchAPI::Type::BooleanModel + + Enum = FinchAPI::Type::Enum + + Union = FinchAPI::Type::Union + + ArrayOf = FinchAPI::Type::ArrayOf + + HashOf = FinchAPI::Type::HashOf + + BaseModel = FinchAPI::Type::BaseModel + + RequestParameters = FinchAPI::Type::RequestParameters + + # This module contains various type declarations. + module Type + end +end diff --git a/rbi/lib/finch-api/type/array_of.rbi b/rbi/lib/finch-api/type/array_of.rbi new file mode 100644 index 00000000..b5610565 --- /dev/null +++ b/rbi/lib/finch-api/type/array_of.rbi @@ -0,0 +1,84 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + # + # Array of items of a given type. + class ArrayOf + include FinchAPI::Type::Converter + + abstract! + final! + + sig(:final) do + params( + type_info: T.any( + FinchAPI::Util::AnyHash, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .returns(T.attached_class) + end + def self.[](type_info, spec = {}) + end + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def ===(other) + end + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def ==(other) + end + + # @api private + sig(:final) do + override + .params(value: T.any( + T::Enumerable[T.anything], + T.anything + ), + state: FinchAPI::Type::Converter::State) + .returns(T.any(T::Array[T.anything], T.anything)) + end + def coerce(value, state:) + end + + # @api private + sig(:final) do + override + .params(value: T.any(T::Enumerable[T.anything], T.anything)) + .returns(T.any(T::Array[T.anything], T.anything)) + end + def dump(value) + end + + # @api private + sig(:final) { returns(T.anything) } + protected def item_type + end + + # @api private + sig(:final) { returns(T::Boolean) } + protected def nilable? + end + + # @api private + sig(:final) do + params( + type_info: T.any( + FinchAPI::Util::AnyHash, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .void + end + def initialize(type_info, spec = {}) + end + end + end +end diff --git a/rbi/lib/finch-api/type/base_model.rbi b/rbi/lib/finch-api/type/base_model.rbi new file mode 100644 index 00000000..d0781091 --- /dev/null +++ b/rbi/lib/finch-api/type/base_model.rbi @@ -0,0 +1,191 @@ +# typed: strong + +module FinchAPI + module Type + class BaseModel + extend FinchAPI::Type::Converter + + abstract! + + KnownFieldShape = T.type_alias { {mode: T.nilable(Symbol), required: T::Boolean, nilable: T::Boolean} } + + class << self + # @api private + # + # Assumes superclass fields are totally defined before fields are accessed / + # defined on subclasses. + sig do + returns( + T::Hash[ + Symbol, + T.all( + FinchAPI::BaseModel::KnownFieldShape, + {type_fn: T.proc.returns(FinchAPI::Type::Converter::Input)} + ) + ] + ) + end + def known_fields + end + + # @api private + sig do + returns( + T::Hash[Symbol, + T.all(FinchAPI::BaseModel::KnownFieldShape, {type: FinchAPI::Type::Converter::Input})] + ) + end + def fields + end + + # @api private + sig do + params( + name_sym: Symbol, + required: T::Boolean, + type_info: T.any( + { + const: T.nilable(T.any(NilClass, T::Boolean, Integer, Float, Symbol)), + enum: T.nilable(T.proc.returns(FinchAPI::Type::Converter::Input)), + union: T.nilable(T.proc.returns(FinchAPI::Type::Converter::Input)), + api_name: Symbol, + nil?: T::Boolean + }, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .void + end + private def add_field(name_sym, required:, type_info:, spec:) + end + + # @api private + sig do + params( + name_sym: Symbol, + type_info: T.any( + FinchAPI::Util::AnyHash, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .void + end + def required(name_sym, type_info, spec = {}) + end + + # @api private + sig do + params( + name_sym: Symbol, + type_info: T.any( + FinchAPI::Util::AnyHash, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .void + end + def optional(name_sym, type_info, spec = {}) + end + + # @api private + # + # `request_only` attributes not excluded from `.#coerce` when receiving responses + # even if well behaved servers should not send them + sig { params(blk: T.proc.void).void } + private def request_only(&blk) + end + + # @api private + # + # `response_only` attributes are omitted from `.#dump` when making requests + sig { params(blk: T.proc.void).void } + private def response_only(&blk) + end + + sig { params(other: T.anything).returns(T::Boolean) } + def ==(other) + end + end + + sig { params(other: T.anything).returns(T::Boolean) } + def ==(other) + end + + class << self + # @api private + sig do + override + .params( + value: T.any(FinchAPI::BaseModel, T::Hash[T.anything, T.anything], T.anything), + state: FinchAPI::Type::Converter::State + ) + .returns(T.any(T.attached_class, T.anything)) + end + def coerce(value, state:) + end + + # @api private + sig do + override + .params(value: T.any(T.attached_class, T.anything)) + .returns(T.any(T::Hash[T.anything, T.anything], T.anything)) + end + def dump(value) + end + end + + # Returns the raw value associated with the given key, if found. Otherwise, nil is + # returned. + # + # It is valid to lookup keys that are not in the API spec, for example to access + # undocumented features. This method does not parse response data into + # higher-level types. Lookup by anything other than a Symbol is an ArgumentError. + sig { params(key: Symbol).returns(T.nilable(T.anything)) } + def [](key) + end + + # Returns a Hash of the data underlying this object. O(1) + # + # Keys are Symbols and values are the raw values from the response. The return + # value indicates which values were ever set on the object. i.e. there will be a + # key in this hash if they ever were, even if the set value was nil. + # + # This method is not recursive. The returned value is shared by the object, so it + # should not be mutated. + sig { overridable.returns(FinchAPI::Util::AnyHash) } + def to_h + end + + # Returns a Hash of the data underlying this object. O(1) + # + # Keys are Symbols and values are the raw values from the response. The return + # value indicates which values were ever set on the object. i.e. there will be a + # key in this hash if they ever were, even if the set value was nil. + # + # This method is not recursive. The returned value is shared by the object, so it + # should not be mutated. + sig { overridable.returns(FinchAPI::Util::AnyHash) } + def to_hash + end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(FinchAPI::Util::AnyHash) } + def deconstruct_keys(keys) + end + + # Create a new instance of a model. + sig { params(data: T.any(T::Hash[Symbol, T.anything], T.self_type)).returns(T.attached_class) } + def self.new(data = {}) + end + + sig { returns(String) } + def inspect + end + end + end +end diff --git a/rbi/lib/finch-api/type/base_page.rbi b/rbi/lib/finch-api/type/base_page.rbi new file mode 100644 index 00000000..89e3a4b0 --- /dev/null +++ b/rbi/lib/finch-api/type/base_page.rbi @@ -0,0 +1,38 @@ +# typed: strong + +module FinchAPI + module Type + module BasePage + Elem = type_member(:out) + + sig { overridable.returns(T::Boolean) } + def next_page? + end + + sig { overridable.returns(T.self_type) } + def next_page + end + + sig { overridable.params(blk: T.proc.params(arg0: Elem).void).void } + def auto_paging_each(&blk) + end + + sig { returns(T::Enumerable[Elem]) } + def to_enum + end + + # @api private + sig do + params( + client: FinchAPI::Transport::BaseClient, + req: FinchAPI::Transport::BaseClient::RequestComponentsShape, + headers: T.any(T::Hash[String, String], Net::HTTPHeader), + page_data: T.anything + ) + .void + end + def initialize(client:, req:, headers:, page_data:) + end + end + end +end diff --git a/rbi/lib/finch-api/type/boolean_model.rbi b/rbi/lib/finch-api/type/boolean_model.rbi new file mode 100644 index 00000000..1087c893 --- /dev/null +++ b/rbi/lib/finch-api/type/boolean_model.rbi @@ -0,0 +1,41 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + # + # Ruby has no Boolean class; this is something for models to refer to. + class BooleanModel + extend FinchAPI::Type::Converter + + abstract! + final! + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def self.===(other) + end + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def self.==(other) + end + + class << self + # @api private + sig(:final) do + override + .params(value: T.any(T::Boolean, T.anything), state: FinchAPI::Type::Converter::State) + .returns(T.any(T::Boolean, T.anything)) + end + def coerce(value, state:) + end + + # @api private + sig(:final) do + override.params(value: T.any(T::Boolean, T.anything)).returns(T.any(T::Boolean, T.anything)) + end + def dump(value) + end + end + end + end +end diff --git a/rbi/lib/finch-api/type/converter.rbi b/rbi/lib/finch-api/type/converter.rbi new file mode 100644 index 00000000..14425cf7 --- /dev/null +++ b/rbi/lib/finch-api/type/converter.rbi @@ -0,0 +1,101 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + module Converter + Input = T.type_alias { T.any(FinchAPI::Type::Converter, T::Class[T.anything]) } + + State = + T.type_alias do + { + strictness: T.any(T::Boolean, Symbol), + exactness: {yes: Integer, no: Integer, maybe: Integer}, + branched: Integer + } + end + + # @api private + sig do + overridable.params(value: T.anything, state: FinchAPI::Type::Converter::State).returns(T.anything) + end + def coerce(value, state:) + end + + # @api private + sig { overridable.params(value: T.anything).returns(T.anything) } + def dump(value) + end + + class << self + # @api private + sig do + params( + spec: T.any( + { + const: T.nilable(T.any(NilClass, T::Boolean, Integer, Float, Symbol)), + enum: T.nilable(T.proc.returns(FinchAPI::Type::Converter::Input)), + union: T.nilable(T.proc.returns(FinchAPI::Type::Converter::Input)) + }, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ) + ) + .returns(T.proc.returns(T.anything)) + end + def self.type_info(spec) + end + + # @api private + # + # Based on `target`, transform `value` into `target`, to the extent possible: + # + # 1. if the given `value` conforms to `target` already, return the given `value` + # 2. if it's possible and safe to convert the given `value` to `target`, then the + # converted value + # 3. otherwise, the given `value` unaltered + # + # The coercion process is subject to improvement between minor release versions. + # See https://docs.pydantic.dev/latest/concepts/unions/#smart-mode + sig do + params( + target: FinchAPI::Type::Converter::Input, + value: T.anything, + state: FinchAPI::Type::Converter::State + ) + .returns(T.anything) + end + def self.coerce( + target, + value, + # The `strictness` is one of `true`, `false`, or `:strong`. This informs the + # coercion strategy when we have to decide between multiple possible conversion + # targets: + # + # - `true`: the conversion must be exact, with minimum coercion. + # - `false`: the conversion can be approximate, with some coercion. + # - `:strong`: the conversion must be exact, with no coercion, and raise an error + # if not possible. + # + # The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For + # any given conversion attempt, the exactness will be updated based on how closely + # the value recursively matches the target type: + # + # - `yes`: the value can be converted to the target type with minimum coercion. + # - `maybe`: the value can be converted to the target type with some reasonable + # coercion. + # - `no`: the value cannot be converted to the target type. + # + # See implementation below for more details. + state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} + ) + end + + # @api private + sig { params(target: FinchAPI::Type::Converter::Input, value: T.anything).returns(T.anything) } + def self.dump(target, value) + end + end + end + end +end diff --git a/rbi/lib/finch-api/type/enum.rbi b/rbi/lib/finch-api/type/enum.rbi new file mode 100644 index 00000000..a7dc663b --- /dev/null +++ b/rbi/lib/finch-api/type/enum.rbi @@ -0,0 +1,58 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + # + # A value from among a specified list of options. OpenAPI enum values map to Ruby + # values in the SDK as follows: + # + # 1. boolean => true | false + # 2. integer => Integer + # 3. float => Float + # 4. string => Symbol + # + # We can therefore convert string values to Symbols, but can't convert other + # values safely. + module Enum + include FinchAPI::Type::Converter + + # All of the valid Symbol values for this enum. + sig { overridable.returns(T::Array[T.any(NilClass, T::Boolean, Integer, Float, Symbol)]) } + def values + end + + # @api private + # + # Guard against thread safety issues by instantiating `@values`. + sig { void } + private def finalize! + end + + sig { params(other: T.anything).returns(T::Boolean) } + def ===(other) + end + + sig { params(other: T.anything).returns(T::Boolean) } + def ==(other) + end + + # @api private + # + # Unlike with primitives, `Enum` additionally validates that the value is a member + # of the enum. + sig do + override + .params(value: T.any(String, Symbol, T.anything), state: FinchAPI::Type::Converter::State) + .returns(T.any(Symbol, T.anything)) + end + def coerce(value, state:) + end + + # @api private + sig { override.params(value: T.any(Symbol, T.anything)).returns(T.any(Symbol, T.anything)) } + def dump(value) + end + end + end +end diff --git a/rbi/lib/finch-api/type/hash_of.rbi b/rbi/lib/finch-api/type/hash_of.rbi new file mode 100644 index 00000000..90be1e97 --- /dev/null +++ b/rbi/lib/finch-api/type/hash_of.rbi @@ -0,0 +1,84 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + # + # Hash of items of a given type. + class HashOf + include FinchAPI::Type::Converter + + abstract! + final! + + sig(:final) do + params( + type_info: T.any( + FinchAPI::Util::AnyHash, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .returns(T.attached_class) + end + def self.[](type_info, spec = {}) + end + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def ===(other) + end + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def ==(other) + end + + # @api private + sig(:final) do + override + .params(value: T.any( + T::Hash[T.anything, T.anything], + T.anything + ), + state: FinchAPI::Type::Converter::State) + .returns(T.any(FinchAPI::Util::AnyHash, T.anything)) + end + def coerce(value, state:) + end + + # @api private + sig(:final) do + override + .params(value: T.any(T::Hash[T.anything, T.anything], T.anything)) + .returns(T.any(FinchAPI::Util::AnyHash, T.anything)) + end + def dump(value) + end + + # @api private + sig(:final) { returns(T.anything) } + protected def item_type + end + + # @api private + sig(:final) { returns(T::Boolean) } + protected def nilable? + end + + # @api private + sig(:final) do + params( + type_info: T.any( + FinchAPI::Util::AnyHash, + T.proc.returns(FinchAPI::Type::Converter::Input), + FinchAPI::Type::Converter::Input + ), + spec: FinchAPI::Util::AnyHash + ) + .void + end + def initialize(type_info, spec = {}) + end + end + end +end diff --git a/rbi/lib/finch-api/type/request_parameters.rbi b/rbi/lib/finch-api/type/request_parameters.rbi new file mode 100644 index 00000000..e41e3467 --- /dev/null +++ b/rbi/lib/finch-api/type/request_parameters.rbi @@ -0,0 +1,20 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + module RequestParameters + # Options to specify HTTP behaviour for this request. + sig { returns(T.any(FinchAPI::RequestOptions, FinchAPI::Util::AnyHash)) } + attr_accessor :request_options + + # @api private + module Converter + # @api private + sig { params(params: T.anything).returns([T.anything, FinchAPI::Util::AnyHash]) } + def dump_request(params) + end + end + end + end +end diff --git a/rbi/lib/finch-api/type/union.rbi b/rbi/lib/finch-api/type/union.rbi new file mode 100644 index 00000000..4e7f7a06 --- /dev/null +++ b/rbi/lib/finch-api/type/union.rbi @@ -0,0 +1,66 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + module Union + include FinchAPI::Type::Converter + + # @api private + # + # All of the specified variant info for this union. + sig { returns(T::Array[[T.nilable(Symbol), T.proc.returns(FinchAPI::Type::Converter::Input)]]) } + private def known_variants + end + + # @api private + sig { returns(T::Array[[T.nilable(Symbol), T.anything]]) } + protected def derefed_variants + end + + # All of the specified variants for this union. + sig { overridable.returns(T::Array[T.anything]) } + def variants + end + + # @api private + sig { params(property: Symbol).void } + private def discriminator(property) + end + + # @api private + sig do + params( + key: T.any(Symbol, FinchAPI::Util::AnyHash, T.proc.returns(T.anything), T.anything), + spec: T.any(FinchAPI::Util::AnyHash, T.proc.returns(T.anything), T.anything) + ) + .void + end + private def variant(key, spec = nil) + end + + # @api private + sig { params(value: T.anything).returns(T.nilable(T.anything)) } + private def resolve_variant(value) + end + + sig { params(other: T.anything).returns(T::Boolean) } + def ===(other) + end + + sig { params(other: T.anything).returns(T::Boolean) } + def ==(other) + end + + # @api private + sig { override.params(value: T.anything, state: FinchAPI::Type::Converter::State).returns(T.anything) } + def coerce(value, state:) + end + + # @api private + sig { override.params(value: T.anything).returns(T.anything) } + def dump(value) + end + end + end +end diff --git a/rbi/lib/finch-api/type/unknown.rbi b/rbi/lib/finch-api/type/unknown.rbi new file mode 100644 index 00000000..684275a9 --- /dev/null +++ b/rbi/lib/finch-api/type/unknown.rbi @@ -0,0 +1,37 @@ +# typed: strong + +module FinchAPI + module Type + # @api private + # + # When we don't know what to expect for the value. + class Unknown + extend FinchAPI::Type::Converter + + abstract! + final! + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def self.===(other) + end + + sig(:final) { params(other: T.anything).returns(T::Boolean) } + def self.==(other) + end + + class << self + # @api private + sig(:final) do + override.params(value: T.anything, state: FinchAPI::Type::Converter::State).returns(T.anything) + end + def coerce(value, state:) + end + + # @api private + sig(:final) { override.params(value: T.anything).returns(T.anything) } + def dump(value) + end + end + end + end +end diff --git a/sig/finch-api/base_client.rbs b/sig/finch-api/base_client.rbs deleted file mode 100644 index 2ce0a80a..00000000 --- a/sig/finch-api/base_client.rbs +++ /dev/null @@ -1,106 +0,0 @@ -module FinchAPI - class BaseClient - type request_components = - { - method: Symbol, - path: String | ::Array[String], - query: ::Hash[String, (::Array[String] | String)?]?, - headers: ::Hash[String, (String - | Integer - | ::Array[(String | Integer)?])?]?, - body: top?, - unwrap: Symbol?, - page: Class?, - stream: Class?, - model: FinchAPI::Converter::input?, - options: FinchAPI::request_opts? - } - - type request_input = - { - method: Symbol, - url: URI::Generic, - headers: ::Hash[String, String], - body: top, - max_retries: Integer, - timeout: Float - } - - MAX_REDIRECTS: 20 - - PLATFORM_HEADERS: ::Hash[String, String] - - def self.validate!: (FinchAPI::BaseClient::request_components req) -> void - - def self.should_retry?: ( - Integer status, - headers: ::Hash[String, String] - ) -> bool - - def self.follow_redirect: ( - FinchAPI::BaseClient::request_input request, - status: Integer, - response_headers: ::Hash[String, String] - ) -> FinchAPI::BaseClient::request_input - - def self.reap_connection!: ( - Integer | FinchAPI::APIConnectionError status, - stream: Enumerable[String]? - ) -> void - - # @api private - attr_accessor requester: FinchAPI::PooledNetRequester - - def initialize: ( - base_url: String, - ?timeout: Float, - ?max_retries: Integer, - ?initial_retry_delay: Float, - ?max_retry_delay: Float, - ?headers: ::Hash[String, (String - | Integer - | ::Array[(String | Integer)?])?], - ?idempotency_header: String? - ) -> void - - private def auth_headers: -> ::Hash[String, String] - - private def generate_idempotency_key: -> String - - private def build_request: ( - FinchAPI::BaseClient::request_components req, - FinchAPI::request_options opts - ) -> FinchAPI::BaseClient::request_input - - private def retry_delay: ( - ::Hash[String, String] headers, - retry_count: Integer - ) -> Float - - private def send_request: ( - FinchAPI::BaseClient::request_input request, - redirect_count: Integer, - retry_count: Integer, - send_retry_header: bool - ) -> [Integer, top, Enumerable[String]] - - def request: - ( - Symbol method, - String | ::Array[String] path, - ?query: ::Hash[String, (::Array[String] | String)?]?, - ?headers: ::Hash[String, (String - | Integer - | ::Array[(String | Integer)?])?]?, - ?body: top?, - ?unwrap: Symbol?, - ?page: Class?, - ?stream: Class?, - ?model: FinchAPI::Converter::input?, - ?options: FinchAPI::request_opts? - ) -> top - | (FinchAPI::BaseClient::request_components req) -> top - - def inspect: -> String - end -end diff --git a/sig/finch-api/base_model.rbs b/sig/finch-api/base_model.rbs deleted file mode 100644 index 2553080d..00000000 --- a/sig/finch-api/base_model.rbs +++ /dev/null @@ -1,248 +0,0 @@ -module FinchAPI - module Converter - type input = FinchAPI::Converter | Class - - type state = - { - strictness: bool | :strong, - exactness: { yes: Integer, no: Integer, maybe: Integer }, - branched: Integer - } - - def coerce: (top value, state: FinchAPI::Converter::state) -> top - - def dump: (top value) -> top - - def self.type_info: ( - { - const: (nil | bool | Integer | Float | Symbol)?, - enum: ^-> FinchAPI::Converter::input?, - union: ^-> FinchAPI::Converter::input? - } - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input spec - ) -> (^-> top) - - def self.coerce: ( - FinchAPI::Converter::input target, - top value, - ?state: FinchAPI::Converter::state - ) -> top - - def self.dump: (FinchAPI::Converter::input target, top value) -> top - end - - class Unknown - extend FinchAPI::Converter - - def self.===: (top other) -> bool - - def self.==: (top other) -> bool - - def self.coerce: (top value, state: FinchAPI::Converter::state) -> top - - def self.dump: (top value) -> top - end - - class BooleanModel - extend FinchAPI::Converter - - def self.===: (top other) -> bool - - def self.==: (top other) -> bool - - def self.coerce: ( - bool | top value, - state: FinchAPI::Converter::state - ) -> (bool | top) - - def self.dump: (bool | top value) -> (bool | top) - end - - module Enum - include FinchAPI::Converter - - def self.values: -> ::Array[(nil | bool | Integer | Float | Symbol)] - - private def self.finalize!: -> void - - def ===: (top other) -> bool - - def ==: (top other) -> bool - - def coerce: ( - String | Symbol | top value, - state: FinchAPI::Converter::state - ) -> (Symbol | top) - - def dump: (Symbol | top value) -> (Symbol | top) - end - - module Union - include FinchAPI::Converter - - private def self.known_variants: -> ::Array[[Symbol?, (^-> FinchAPI::Converter::input)]] - - def self.derefed_variants: -> ::Array[[Symbol?, top]] - - def self.variants: -> ::Array[top] - - private def self.discriminator: (Symbol property) -> void - - private def self.variant: ( - Symbol - | ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input key, - ?::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input spec - ) -> void - - private def self.resolve_variant: (top value) -> FinchAPI::Converter::input? - - def ===: (top other) -> bool - - def ==: (top other) -> bool - - def coerce: (top value, state: FinchAPI::Converter::state) -> top - - def dump: (top value) -> top - end - - class ArrayOf - include FinchAPI::Converter - - def self.[]: ( - ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input type_info, - ?::Hash[Symbol, top] spec - ) -> instance - - def ===: (top other) -> bool - - def ==: (top other) -> bool - - def coerce: ( - Enumerable[top] | top value, - state: FinchAPI::Converter::state - ) -> (::Array[top] | top) - - def dump: (Enumerable[top] | top value) -> (::Array[top] | top) - - def item_type: -> top - - def nilable?: -> bool - - def initialize: ( - ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input type_info, - ?::Hash[Symbol, top] spec - ) -> void - end - - class HashOf - include FinchAPI::Converter - - def self.[]: ( - ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input type_info, - ?::Hash[Symbol, top] spec - ) -> instance - - def ===: (top other) -> bool - - def ==: (top other) -> bool - - def coerce: ( - ::Hash[top, top] | top value, - state: FinchAPI::Converter::state - ) -> (::Hash[Symbol, top] | top) - - def dump: (::Hash[top, top] | top value) -> (::Hash[Symbol, top] | top) - - def item_type: -> top - - def nilable?: -> bool - - def initialize: ( - ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input type_info, - ?::Hash[Symbol, top] spec - ) -> void - end - - class BaseModel - extend FinchAPI::Converter - - type known_field = - { mode: (:coerce | :dump)?, required: bool, nilable: bool } - - def self.known_fields: -> ::Hash[Symbol, (FinchAPI::BaseModel::known_field - & { type_fn: (^-> FinchAPI::Converter::input) })] - - def self.fields: -> ::Hash[Symbol, (FinchAPI::BaseModel::known_field - & { type: FinchAPI::Converter::input })] - - private def self.add_field: ( - Symbol name_sym, - required: bool, - type_info: { - const: (nil | bool | Integer | Float | Symbol)?, - enum: ^-> FinchAPI::Converter::input?, - union: ^-> FinchAPI::Converter::input?, - api_name: Symbol - } - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input, - spec: ::Hash[Symbol, top] - ) -> void - - def self.required: ( - Symbol name_sym, - ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input type_info, - ?::Hash[Symbol, top] spec - ) -> void - - def self.optional: ( - Symbol name_sym, - ::Hash[Symbol, top] - | ^-> FinchAPI::Converter::input - | FinchAPI::Converter::input type_info, - ?::Hash[Symbol, top] spec - ) -> void - - private def self.request_only: { -> void } -> void - - private def self.response_only: { -> void } -> void - - def self.==: (top other) -> bool - - def ==: (top other) -> bool - - def self.coerce: ( - FinchAPI::BaseModel | ::Hash[top, top] | top value, - state: FinchAPI::Converter::state - ) -> (instance | top) - - def self.dump: (instance | top value) -> (::Hash[top, top] | top) - - def []: (Symbol key) -> top? - - def to_h: -> ::Hash[Symbol, top] - - alias to_hash to_h - - def deconstruct_keys: (::Array[Symbol]? keys) -> ::Hash[Symbol, top] - - def initialize: (?::Hash[Symbol, top] | self data) -> void - - def inspect: -> String - end -end diff --git a/sig/finch-api/base_page.rbs b/sig/finch-api/base_page.rbs deleted file mode 100644 index 091a57cd..00000000 --- a/sig/finch-api/base_page.rbs +++ /dev/null @@ -1,20 +0,0 @@ -module FinchAPI - module BasePage[Elem] - def next_page?: -> bool - - def next_page: -> self - - def auto_paging_each: { (Elem arg0) -> void } -> void - - def to_enum: -> Enumerable[Elem] - - alias enum_for to_enum - - def initialize: ( - client: FinchAPI::BaseClient, - req: FinchAPI::BaseClient::request_components, - headers: ::Hash[String, String], - page_data: top - ) -> void - end -end diff --git a/sig/finch-api/client.rbs b/sig/finch-api/client.rbs index cb5dfcfe..113c7f68 100644 --- a/sig/finch-api/client.rbs +++ b/sig/finch-api/client.rbs @@ -1,5 +1,5 @@ module FinchAPI - class Client < FinchAPI::BaseClient + class Client < FinchAPI::Transport::BaseClient DEFAULT_MAX_RETRIES: 2 DEFAULT_TIMEOUT_IN_SECONDS: Float diff --git a/sig/finch-api/individuals_page.rbs b/sig/finch-api/individuals_page.rbs index 410416e8..d502c158 100644 --- a/sig/finch-api/individuals_page.rbs +++ b/sig/finch-api/individuals_page.rbs @@ -1,6 +1,6 @@ module FinchAPI class IndividualsPage[Elem] - include FinchAPI::BasePage[Elem] + include FinchAPI::Type::BasePage[Elem] attr_accessor individuals: ::Array[Elem]? diff --git a/sig/finch-api/models/access_token_create_params.rbs b/sig/finch-api/models/access_token_create_params.rbs index 429c58fa..54ab1667 100644 --- a/sig/finch-api/models/access_token_create_params.rbs +++ b/sig/finch-api/models/access_token_create_params.rbs @@ -10,7 +10,7 @@ module FinchAPI & FinchAPI::request_parameters class AccessTokenCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor code: String diff --git a/sig/finch-api/models/account_disconnect_params.rbs b/sig/finch-api/models/account_disconnect_params.rbs index a0ef5609..cb31e96a 100644 --- a/sig/finch-api/models/account_disconnect_params.rbs +++ b/sig/finch-api/models/account_disconnect_params.rbs @@ -3,7 +3,7 @@ module FinchAPI type account_disconnect_params = { } & FinchAPI::request_parameters class AccountDisconnectParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/account_introspect_params.rbs b/sig/finch-api/models/account_introspect_params.rbs index 2068708e..c416ef48 100644 --- a/sig/finch-api/models/account_introspect_params.rbs +++ b/sig/finch-api/models/account_introspect_params.rbs @@ -3,7 +3,7 @@ module FinchAPI type account_introspect_params = { } & FinchAPI::request_parameters class AccountIntrospectParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/connect/session_new_params.rbs b/sig/finch-api/models/connect/session_new_params.rbs index e5d31aa1..72d134a0 100644 --- a/sig/finch-api/models/connect/session_new_params.rbs +++ b/sig/finch-api/models/connect/session_new_params.rbs @@ -16,7 +16,7 @@ module FinchAPI & FinchAPI::request_parameters class SessionNewParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor customer_id: String diff --git a/sig/finch-api/models/connect/session_reauthenticate_params.rbs b/sig/finch-api/models/connect/session_reauthenticate_params.rbs index 33d3d200..e161c491 100644 --- a/sig/finch-api/models/connect/session_reauthenticate_params.rbs +++ b/sig/finch-api/models/connect/session_reauthenticate_params.rbs @@ -11,7 +11,7 @@ module FinchAPI & FinchAPI::request_parameters class SessionReauthenticateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor connection_id: String diff --git a/sig/finch-api/models/hris/benefit_create_params.rbs b/sig/finch-api/models/hris/benefit_create_params.rbs index 1408032f..0df19218 100644 --- a/sig/finch-api/models/hris/benefit_create_params.rbs +++ b/sig/finch-api/models/hris/benefit_create_params.rbs @@ -10,7 +10,7 @@ module FinchAPI & FinchAPI::request_parameters class BenefitCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader description: String? diff --git a/sig/finch-api/models/hris/benefit_list_params.rbs b/sig/finch-api/models/hris/benefit_list_params.rbs index ece372b4..fea74e89 100644 --- a/sig/finch-api/models/hris/benefit_list_params.rbs +++ b/sig/finch-api/models/hris/benefit_list_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type benefit_list_params = { } & FinchAPI::request_parameters class BenefitListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/hris/benefit_list_supported_benefits_params.rbs b/sig/finch-api/models/hris/benefit_list_supported_benefits_params.rbs index d159fa20..d1de2c0b 100644 --- a/sig/finch-api/models/hris/benefit_list_supported_benefits_params.rbs +++ b/sig/finch-api/models/hris/benefit_list_supported_benefits_params.rbs @@ -5,7 +5,7 @@ module FinchAPI { } & FinchAPI::request_parameters class BenefitListSupportedBenefitsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/hris/benefit_retrieve_params.rbs b/sig/finch-api/models/hris/benefit_retrieve_params.rbs index 06135267..e272124d 100644 --- a/sig/finch-api/models/hris/benefit_retrieve_params.rbs +++ b/sig/finch-api/models/hris/benefit_retrieve_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type benefit_retrieve_params = { } & FinchAPI::request_parameters class BenefitRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/hris/benefit_update_params.rbs b/sig/finch-api/models/hris/benefit_update_params.rbs index 2061368d..9f92a228 100644 --- a/sig/finch-api/models/hris/benefit_update_params.rbs +++ b/sig/finch-api/models/hris/benefit_update_params.rbs @@ -5,7 +5,7 @@ module FinchAPI { description: String } & FinchAPI::request_parameters class BenefitUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader description: String? diff --git a/sig/finch-api/models/hris/benefits/individual_enroll_many_params.rbs b/sig/finch-api/models/hris/benefits/individual_enroll_many_params.rbs index b1c8ac0b..1aa006f8 100644 --- a/sig/finch-api/models/hris/benefits/individual_enroll_many_params.rbs +++ b/sig/finch-api/models/hris/benefits/individual_enroll_many_params.rbs @@ -9,7 +9,7 @@ module FinchAPI & FinchAPI::request_parameters class IndividualEnrollManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader individuals: ::Array[FinchAPI::Models::HRIS::Benefits::IndividualEnrollManyParams::Individual]? diff --git a/sig/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbs b/sig/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbs index 2eab6aaa..223ede3f 100644 --- a/sig/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbs +++ b/sig/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbs @@ -6,7 +6,7 @@ module FinchAPI { } & FinchAPI::request_parameters class IndividualEnrolledIDsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbs b/sig/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbs index 108977cb..bb46cd6a 100644 --- a/sig/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbs +++ b/sig/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbs @@ -6,7 +6,7 @@ module FinchAPI { individual_ids: String } & FinchAPI::request_parameters class IndividualRetrieveManyBenefitsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader individual_ids: String? diff --git a/sig/finch-api/models/hris/benefits/individual_unenroll_many_params.rbs b/sig/finch-api/models/hris/benefits/individual_unenroll_many_params.rbs index fb69c98c..f06582f5 100644 --- a/sig/finch-api/models/hris/benefits/individual_unenroll_many_params.rbs +++ b/sig/finch-api/models/hris/benefits/individual_unenroll_many_params.rbs @@ -6,7 +6,7 @@ module FinchAPI { individual_ids: ::Array[String] } & FinchAPI::request_parameters class IndividualUnenrollManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader individual_ids: ::Array[String]? diff --git a/sig/finch-api/models/hris/company_retrieve_params.rbs b/sig/finch-api/models/hris/company_retrieve_params.rbs index 4dbe3c88..a3e5e530 100644 --- a/sig/finch-api/models/hris/company_retrieve_params.rbs +++ b/sig/finch-api/models/hris/company_retrieve_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type company_retrieve_params = { } & FinchAPI::request_parameters class CompanyRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/hris/directory_list_individuals_params.rbs b/sig/finch-api/models/hris/directory_list_individuals_params.rbs index 05187495..b5c41c85 100644 --- a/sig/finch-api/models/hris/directory_list_individuals_params.rbs +++ b/sig/finch-api/models/hris/directory_list_individuals_params.rbs @@ -5,7 +5,7 @@ module FinchAPI { limit: Integer, offset: Integer } & FinchAPI::request_parameters class DirectoryListIndividualsParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader limit: Integer? diff --git a/sig/finch-api/models/hris/directory_list_params.rbs b/sig/finch-api/models/hris/directory_list_params.rbs index 340ad765..a7ca45d0 100644 --- a/sig/finch-api/models/hris/directory_list_params.rbs +++ b/sig/finch-api/models/hris/directory_list_params.rbs @@ -5,7 +5,7 @@ module FinchAPI { limit: Integer, offset: Integer } & FinchAPI::request_parameters class DirectoryListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader limit: Integer? diff --git a/sig/finch-api/models/hris/document_list_params.rbs b/sig/finch-api/models/hris/document_list_params.rbs index 99b460c9..be825109 100644 --- a/sig/finch-api/models/hris/document_list_params.rbs +++ b/sig/finch-api/models/hris/document_list_params.rbs @@ -11,7 +11,7 @@ module FinchAPI & FinchAPI::request_parameters class DocumentListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader individual_ids: ::Array[String]? diff --git a/sig/finch-api/models/hris/document_retreive_params.rbs b/sig/finch-api/models/hris/document_retreive_params.rbs index bd91a63b..db25c975 100644 --- a/sig/finch-api/models/hris/document_retreive_params.rbs +++ b/sig/finch-api/models/hris/document_retreive_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type document_retreive_params = { } & FinchAPI::request_parameters class DocumentRetreiveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/hris/employment_retrieve_many_params.rbs b/sig/finch-api/models/hris/employment_retrieve_many_params.rbs index 0c3efcf7..954fc1e1 100644 --- a/sig/finch-api/models/hris/employment_retrieve_many_params.rbs +++ b/sig/finch-api/models/hris/employment_retrieve_many_params.rbs @@ -8,7 +8,7 @@ module FinchAPI & FinchAPI::request_parameters class EmploymentRetrieveManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor requests: ::Array[FinchAPI::Models::HRIS::EmploymentRetrieveManyParams::Request] diff --git a/sig/finch-api/models/hris/individual_retrieve_many_params.rbs b/sig/finch-api/models/hris/individual_retrieve_many_params.rbs index d49d4158..ca12404a 100644 --- a/sig/finch-api/models/hris/individual_retrieve_many_params.rbs +++ b/sig/finch-api/models/hris/individual_retrieve_many_params.rbs @@ -9,7 +9,7 @@ module FinchAPI & FinchAPI::request_parameters class IndividualRetrieveManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor options: FinchAPI::Models::HRIS::IndividualRetrieveManyParams::Options? diff --git a/sig/finch-api/models/hris/pay_statement_retrieve_many_params.rbs b/sig/finch-api/models/hris/pay_statement_retrieve_many_params.rbs index c58f5ce7..204eb1cf 100644 --- a/sig/finch-api/models/hris/pay_statement_retrieve_many_params.rbs +++ b/sig/finch-api/models/hris/pay_statement_retrieve_many_params.rbs @@ -8,7 +8,7 @@ module FinchAPI & FinchAPI::request_parameters class PayStatementRetrieveManyParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor requests: ::Array[FinchAPI::Models::HRIS::PayStatementRetrieveManyParams::Request] diff --git a/sig/finch-api/models/hris/payment_list_params.rbs b/sig/finch-api/models/hris/payment_list_params.rbs index 92ed6229..a9f505df 100644 --- a/sig/finch-api/models/hris/payment_list_params.rbs +++ b/sig/finch-api/models/hris/payment_list_params.rbs @@ -5,7 +5,7 @@ module FinchAPI { end_date: Date, start_date: Date } & FinchAPI::request_parameters class PaymentListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor end_date: Date diff --git a/sig/finch-api/models/jobs/automated_create_params.rbs b/sig/finch-api/models/jobs/automated_create_params.rbs index 3338797d..a367a41f 100644 --- a/sig/finch-api/models/jobs/automated_create_params.rbs +++ b/sig/finch-api/models/jobs/automated_create_params.rbs @@ -9,7 +9,7 @@ module FinchAPI & FinchAPI::request_parameters class AutomatedCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor type: FinchAPI::Models::Jobs::AutomatedCreateParams::type_ diff --git a/sig/finch-api/models/jobs/automated_list_params.rbs b/sig/finch-api/models/jobs/automated_list_params.rbs index c0685155..e414d532 100644 --- a/sig/finch-api/models/jobs/automated_list_params.rbs +++ b/sig/finch-api/models/jobs/automated_list_params.rbs @@ -5,7 +5,7 @@ module FinchAPI { limit: Integer, offset: Integer } & FinchAPI::request_parameters class AutomatedListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader limit: Integer? diff --git a/sig/finch-api/models/jobs/automated_retrieve_params.rbs b/sig/finch-api/models/jobs/automated_retrieve_params.rbs index 9a06a75c..7b77da80 100644 --- a/sig/finch-api/models/jobs/automated_retrieve_params.rbs +++ b/sig/finch-api/models/jobs/automated_retrieve_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type automated_retrieve_params = { } & FinchAPI::request_parameters class AutomatedRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/jobs/manual_retrieve_params.rbs b/sig/finch-api/models/jobs/manual_retrieve_params.rbs index 4bfcc450..7345a80e 100644 --- a/sig/finch-api/models/jobs/manual_retrieve_params.rbs +++ b/sig/finch-api/models/jobs/manual_retrieve_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type manual_retrieve_params = { } & FinchAPI::request_parameters class ManualRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/payroll/pay_group_list_params.rbs b/sig/finch-api/models/payroll/pay_group_list_params.rbs index 678483f7..f8680b17 100644 --- a/sig/finch-api/models/payroll/pay_group_list_params.rbs +++ b/sig/finch-api/models/payroll/pay_group_list_params.rbs @@ -6,7 +6,7 @@ module FinchAPI & FinchAPI::request_parameters class PayGroupListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader individual_id: String? diff --git a/sig/finch-api/models/payroll/pay_group_retrieve_params.rbs b/sig/finch-api/models/payroll/pay_group_retrieve_params.rbs index 11199b48..83d5df24 100644 --- a/sig/finch-api/models/payroll/pay_group_retrieve_params.rbs +++ b/sig/finch-api/models/payroll/pay_group_retrieve_params.rbs @@ -4,7 +4,7 @@ module FinchAPI type pay_group_retrieve_params = { } & FinchAPI::request_parameters class PayGroupRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/provider_list_params.rbs b/sig/finch-api/models/provider_list_params.rbs index 08a78938..6482e7b3 100644 --- a/sig/finch-api/models/provider_list_params.rbs +++ b/sig/finch-api/models/provider_list_params.rbs @@ -3,7 +3,7 @@ module FinchAPI type provider_list_params = { } & FinchAPI::request_parameters class ProviderListParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/request_forwarding_forward_params.rbs b/sig/finch-api/models/request_forwarding_forward_params.rbs index 1551bffb..6f507dd6 100644 --- a/sig/finch-api/models/request_forwarding_forward_params.rbs +++ b/sig/finch-api/models/request_forwarding_forward_params.rbs @@ -11,7 +11,7 @@ module FinchAPI & FinchAPI::request_parameters class RequestForwardingForwardParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor method_: String diff --git a/sig/finch-api/models/sandbox/company_update_params.rbs b/sig/finch-api/models/sandbox/company_update_params.rbs index 6ed708e3..dfc48c42 100644 --- a/sig/finch-api/models/sandbox/company_update_params.rbs +++ b/sig/finch-api/models/sandbox/company_update_params.rbs @@ -15,7 +15,7 @@ module FinchAPI & FinchAPI::request_parameters class CompanyUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor accounts: ::Array[FinchAPI::Models::Sandbox::CompanyUpdateParams::Account]? diff --git a/sig/finch-api/models/sandbox/connection_create_params.rbs b/sig/finch-api/models/sandbox/connection_create_params.rbs index 67a6b792..eac61b79 100644 --- a/sig/finch-api/models/sandbox/connection_create_params.rbs +++ b/sig/finch-api/models/sandbox/connection_create_params.rbs @@ -11,7 +11,7 @@ module FinchAPI & FinchAPI::request_parameters class ConnectionCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor provider_id: String diff --git a/sig/finch-api/models/sandbox/connections/account_create_params.rbs b/sig/finch-api/models/sandbox/connections/account_create_params.rbs index e0269f75..14d08390 100644 --- a/sig/finch-api/models/sandbox/connections/account_create_params.rbs +++ b/sig/finch-api/models/sandbox/connections/account_create_params.rbs @@ -12,7 +12,7 @@ module FinchAPI & FinchAPI::request_parameters class AccountCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor company_id: String diff --git a/sig/finch-api/models/sandbox/connections/account_update_params.rbs b/sig/finch-api/models/sandbox/connections/account_update_params.rbs index bf37b69b..67248df6 100644 --- a/sig/finch-api/models/sandbox/connections/account_update_params.rbs +++ b/sig/finch-api/models/sandbox/connections/account_update_params.rbs @@ -7,7 +7,7 @@ module FinchAPI & FinchAPI::request_parameters class AccountUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader connection_status: FinchAPI::Models::connection_status_type? diff --git a/sig/finch-api/models/sandbox/directory_create_params.rbs b/sig/finch-api/models/sandbox/directory_create_params.rbs index 7f91b296..dbbf2c14 100644 --- a/sig/finch-api/models/sandbox/directory_create_params.rbs +++ b/sig/finch-api/models/sandbox/directory_create_params.rbs @@ -8,7 +8,7 @@ module FinchAPI & FinchAPI::request_parameters class DirectoryCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader body: ::Array[FinchAPI::Models::Sandbox::DirectoryCreateParams::Body]? diff --git a/sig/finch-api/models/sandbox/employment_update_params.rbs b/sig/finch-api/models/sandbox/employment_update_params.rbs index d47b4a39..00620e89 100644 --- a/sig/finch-api/models/sandbox/employment_update_params.rbs +++ b/sig/finch-api/models/sandbox/employment_update_params.rbs @@ -25,7 +25,7 @@ module FinchAPI & FinchAPI::request_parameters class EmploymentUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor class_code: String? diff --git a/sig/finch-api/models/sandbox/individual_update_params.rbs b/sig/finch-api/models/sandbox/individual_update_params.rbs index fe1bdbd5..60d1994d 100644 --- a/sig/finch-api/models/sandbox/individual_update_params.rbs +++ b/sig/finch-api/models/sandbox/individual_update_params.rbs @@ -19,7 +19,7 @@ module FinchAPI & FinchAPI::request_parameters class IndividualUpdateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor dob: String? diff --git a/sig/finch-api/models/sandbox/job_create_params.rbs b/sig/finch-api/models/sandbox/job_create_params.rbs index 0e7b8862..42d38738 100644 --- a/sig/finch-api/models/sandbox/job_create_params.rbs +++ b/sig/finch-api/models/sandbox/job_create_params.rbs @@ -6,7 +6,7 @@ module FinchAPI & FinchAPI::request_parameters class JobCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_accessor type: FinchAPI::Models::Sandbox::JobCreateParams::type_ diff --git a/sig/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbs b/sig/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbs index 767087b0..37202037 100644 --- a/sig/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbs +++ b/sig/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbs @@ -5,7 +5,7 @@ module FinchAPI type configuration_retrieve_params = { } & FinchAPI::request_parameters class ConfigurationRetrieveParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/sandbox/jobs/configuration_update_params.rbs b/sig/finch-api/models/sandbox/jobs/configuration_update_params.rbs index 77d39bf2..f8b8014c 100644 --- a/sig/finch-api/models/sandbox/jobs/configuration_update_params.rbs +++ b/sig/finch-api/models/sandbox/jobs/configuration_update_params.rbs @@ -5,7 +5,7 @@ module FinchAPI type configuration_update_params = { } & FinchAPI::request_parameters class ConfigurationUpdateParams < FinchAPI::Models::Sandbox::Jobs::SandboxJobConfiguration - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters def initialize: (?request_options: FinchAPI::request_opts) -> void diff --git a/sig/finch-api/models/sandbox/payment_create_params.rbs b/sig/finch-api/models/sandbox/payment_create_params.rbs index d858d2ba..5e90cb1c 100644 --- a/sig/finch-api/models/sandbox/payment_create_params.rbs +++ b/sig/finch-api/models/sandbox/payment_create_params.rbs @@ -10,7 +10,7 @@ module FinchAPI & FinchAPI::request_parameters class PaymentCreateParams < FinchAPI::BaseModel - extend FinchAPI::RequestParameters::Converter + extend FinchAPI::Type::RequestParameters::Converter include FinchAPI::RequestParameters attr_reader end_date: String? diff --git a/sig/finch-api/page.rbs b/sig/finch-api/page.rbs index 4da9a16c..f348aa7a 100644 --- a/sig/finch-api/page.rbs +++ b/sig/finch-api/page.rbs @@ -1,6 +1,6 @@ module FinchAPI class Page[Elem] - include FinchAPI::BasePage[Elem] + include FinchAPI::Type::BasePage[Elem] attr_accessor data: ::Array[Elem]? diff --git a/sig/finch-api/pooled_net_requester.rbs b/sig/finch-api/pooled_net_requester.rbs deleted file mode 100644 index 32ebb5b5..00000000 --- a/sig/finch-api/pooled_net_requester.rbs +++ /dev/null @@ -1,37 +0,0 @@ -module FinchAPI - class PooledNetRequester - type request = - { - method: Symbol, - url: URI::Generic, - headers: ::Hash[String, String], - body: top, - deadline: Float - } - - KEEP_ALIVE_TIMEOUT: 30 - - def self.connect: (URI::Generic url) -> top - - def self.calibrate_socket_timeout: (top conn, Float deadline) -> void - - def self.build_request: ( - FinchAPI::PooledNetRequester::request request - ) { - (String arg0) -> void - } -> top - - private def with_pool: ( - URI::Generic url, - deadline: Float - ) { - (top arg0) -> void - } -> void - - def execute: ( - FinchAPI::PooledNetRequester::request request - ) -> [Integer, top, Enumerable[String]] - - def initialize: (?size: Integer) -> void - end -end diff --git a/sig/finch-api/request_options.rbs b/sig/finch-api/request_options.rbs index 32a98342..12ac2fe0 100644 --- a/sig/finch-api/request_options.rbs +++ b/sig/finch-api/request_options.rbs @@ -2,16 +2,6 @@ module FinchAPI type request_opts = FinchAPI::RequestOptions | FinchAPI::request_options | ::Hash[Symbol, top] - type request_parameters = { request_options: FinchAPI::request_opts } - - module RequestParameters - attr_accessor request_options: FinchAPI::request_opts - - module Converter - def dump_request: (top params) -> [top, ::Hash[Symbol, top]] - end - end - type request_options = { idempotency_key: String?, diff --git a/sig/finch-api/responses_page.rbs b/sig/finch-api/responses_page.rbs index ed66e5c0..795c5990 100644 --- a/sig/finch-api/responses_page.rbs +++ b/sig/finch-api/responses_page.rbs @@ -1,6 +1,6 @@ module FinchAPI class ResponsesPage[Elem] - include FinchAPI::BasePage[Elem] + include FinchAPI::Type::BasePage[Elem] attr_accessor responses: ::Array[Elem]? diff --git a/sig/finch-api/single_page.rbs b/sig/finch-api/single_page.rbs index 80e999db..725f0f65 100644 --- a/sig/finch-api/single_page.rbs +++ b/sig/finch-api/single_page.rbs @@ -1,6 +1,6 @@ module FinchAPI class SinglePage[Elem] < ::Array[Elem] - include FinchAPI::BasePage[Elem] + include FinchAPI::Type::BasePage[Elem] def next_page?: -> bool diff --git a/sig/finch-api/transport/base_client.rbs b/sig/finch-api/transport/base_client.rbs new file mode 100644 index 00000000..e13de591 --- /dev/null +++ b/sig/finch-api/transport/base_client.rbs @@ -0,0 +1,110 @@ +module FinchAPI + module Transport + class BaseClient + type request_components = + { + method: Symbol, + path: String | ::Array[String], + query: ::Hash[String, (::Array[String] | String)?]?, + headers: ::Hash[String, (String + | Integer + | ::Array[(String | Integer)?])?]?, + body: top?, + unwrap: Symbol?, + page: Class?, + stream: Class?, + model: FinchAPI::Type::Converter::input?, + options: FinchAPI::request_opts? + } + + type request_input = + { + method: Symbol, + url: URI::Generic, + headers: ::Hash[String, String], + body: top, + max_retries: Integer, + timeout: Float + } + + MAX_REDIRECTS: 20 + + PLATFORM_HEADERS: ::Hash[String, String] + + def self.validate!: ( + FinchAPI::Transport::BaseClient::request_components req + ) -> void + + def self.should_retry?: ( + Integer status, + headers: ::Hash[String, String] + ) -> bool + + def self.follow_redirect: ( + FinchAPI::Transport::BaseClient::request_input request, + status: Integer, + response_headers: ::Hash[String, String] + ) -> FinchAPI::Transport::BaseClient::request_input + + def self.reap_connection!: ( + Integer | FinchAPI::APIConnectionError status, + stream: Enumerable[String]? + ) -> void + + # @api private + attr_accessor requester: FinchAPI::Transport::PooledNetRequester + + def initialize: ( + base_url: String, + ?timeout: Float, + ?max_retries: Integer, + ?initial_retry_delay: Float, + ?max_retry_delay: Float, + ?headers: ::Hash[String, (String + | Integer + | ::Array[(String | Integer)?])?], + ?idempotency_header: String? + ) -> void + + private def auth_headers: -> ::Hash[String, String] + + private def generate_idempotency_key: -> String + + private def build_request: ( + FinchAPI::Transport::BaseClient::request_components req, + FinchAPI::request_options opts + ) -> FinchAPI::Transport::BaseClient::request_input + + private def retry_delay: ( + ::Hash[String, String] headers, + retry_count: Integer + ) -> Float + + private def send_request: ( + FinchAPI::Transport::BaseClient::request_input request, + redirect_count: Integer, + retry_count: Integer, + send_retry_header: bool + ) -> [Integer, top, Enumerable[String]] + + def request: + ( + Symbol method, + String | ::Array[String] path, + ?query: ::Hash[String, (::Array[String] | String)?]?, + ?headers: ::Hash[String, (String + | Integer + | ::Array[(String | Integer)?])?]?, + ?body: top?, + ?unwrap: Symbol?, + ?page: Class?, + ?stream: Class?, + ?model: FinchAPI::Type::Converter::input?, + ?options: FinchAPI::request_opts? + ) -> top + | (FinchAPI::Transport::BaseClient::request_components req) -> top + + def inspect: -> String + end + end +end diff --git a/sig/finch-api/transport/pooled_net_requester.rbs b/sig/finch-api/transport/pooled_net_requester.rbs new file mode 100644 index 00000000..5e0d0f56 --- /dev/null +++ b/sig/finch-api/transport/pooled_net_requester.rbs @@ -0,0 +1,39 @@ +module FinchAPI + module Transport + class PooledNetRequester + type request = + { + method: Symbol, + url: URI::Generic, + headers: ::Hash[String, String], + body: top, + deadline: Float + } + + KEEP_ALIVE_TIMEOUT: 30 + + def self.connect: (URI::Generic url) -> top + + def self.calibrate_socket_timeout: (top conn, Float deadline) -> void + + def self.build_request: ( + FinchAPI::Transport::PooledNetRequester::request request + ) { + (String arg0) -> void + } -> top + + private def with_pool: ( + URI::Generic url, + deadline: Float + ) { + (top arg0) -> void + } -> void + + def execute: ( + FinchAPI::Transport::PooledNetRequester::request request + ) -> [Integer, top, Enumerable[String]] + + def initialize: (?size: Integer) -> void + end + end +end diff --git a/sig/finch-api/type.rbs b/sig/finch-api/type.rbs new file mode 100644 index 00000000..6f2d3043 --- /dev/null +++ b/sig/finch-api/type.rbs @@ -0,0 +1,22 @@ +module FinchAPI + class Unknown = FinchAPI::Type::Unknown + + class BooleanModel = FinchAPI::Type::BooleanModel + + module Enum = FinchAPI::Type::Enum + + module Union = FinchAPI::Type::Union + + class ArrayOf = FinchAPI::Type::ArrayOf + + class HashOf = FinchAPI::Type::HashOf + + class BaseModel = FinchAPI::Type::BaseModel + + type request_parameters = FinchAPI::Type::request_parameters + + module RequestParameters = FinchAPI::Type::RequestParameters + + module Type + end +end diff --git a/sig/finch-api/type/array_of.rbs b/sig/finch-api/type/array_of.rbs new file mode 100644 index 00000000..b2f05c36 --- /dev/null +++ b/sig/finch-api/type/array_of.rbs @@ -0,0 +1,36 @@ +module FinchAPI + module Type + class ArrayOf + include FinchAPI::Type::Converter + + def self.[]: ( + ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input type_info, + ?::Hash[Symbol, top] spec + ) -> instance + + def ===: (top other) -> bool + + def ==: (top other) -> bool + + def coerce: ( + Enumerable[top] | top value, + state: FinchAPI::Type::Converter::state + ) -> (::Array[top] | top) + + def dump: (Enumerable[top] | top value) -> (::Array[top] | top) + + def item_type: -> top + + def nilable?: -> bool + + def initialize: ( + ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input type_info, + ?::Hash[Symbol, top] spec + ) -> void + end + end +end diff --git a/sig/finch-api/type/base_model.rbs b/sig/finch-api/type/base_model.rbs new file mode 100644 index 00000000..843c3a9e --- /dev/null +++ b/sig/finch-api/type/base_model.rbs @@ -0,0 +1,73 @@ +module FinchAPI + module Type + class BaseModel + extend FinchAPI::Type::Converter + + type known_field = + { mode: (:coerce | :dump)?, required: bool, nilable: bool } + + def self.known_fields: -> ::Hash[Symbol, (FinchAPI::BaseModel::known_field + & { type_fn: (^-> FinchAPI::Type::Converter::input) })] + + def self.fields: -> ::Hash[Symbol, (FinchAPI::BaseModel::known_field + & { type: FinchAPI::Type::Converter::input })] + + private def self.add_field: ( + Symbol name_sym, + required: bool, + type_info: { + const: (nil | bool | Integer | Float | Symbol)?, + enum: ^-> FinchAPI::Type::Converter::input?, + union: ^-> FinchAPI::Type::Converter::input?, + api_name: Symbol + } + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input, + spec: ::Hash[Symbol, top] + ) -> void + + def self.required: ( + Symbol name_sym, + ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input type_info, + ?::Hash[Symbol, top] spec + ) -> void + + def self.optional: ( + Symbol name_sym, + ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input type_info, + ?::Hash[Symbol, top] spec + ) -> void + + private def self.request_only: { -> void } -> void + + private def self.response_only: { -> void } -> void + + def self.==: (top other) -> bool + + def ==: (top other) -> bool + + def self.coerce: ( + FinchAPI::BaseModel | ::Hash[top, top] | top value, + state: FinchAPI::Type::Converter::state + ) -> (instance | top) + + def self.dump: (instance | top value) -> (::Hash[top, top] | top) + + def []: (Symbol key) -> top? + + def to_h: -> ::Hash[Symbol, top] + + alias to_hash to_h + + def deconstruct_keys: (::Array[Symbol]? keys) -> ::Hash[Symbol, top] + + def initialize: (?::Hash[Symbol, top] | self data) -> void + + def inspect: -> String + end + end +end diff --git a/sig/finch-api/type/base_page.rbs b/sig/finch-api/type/base_page.rbs new file mode 100644 index 00000000..b7255d76 --- /dev/null +++ b/sig/finch-api/type/base_page.rbs @@ -0,0 +1,22 @@ +module FinchAPI + module Type + module BasePage[Elem] + def next_page?: -> bool + + def next_page: -> self + + def auto_paging_each: { (Elem arg0) -> void } -> void + + def to_enum: -> Enumerable[Elem] + + alias enum_for to_enum + + def initialize: ( + client: FinchAPI::Transport::BaseClient, + req: FinchAPI::Transport::BaseClient::request_components, + headers: ::Hash[String, String], + page_data: top + ) -> void + end + end +end diff --git a/sig/finch-api/type/boolean_model.rbs b/sig/finch-api/type/boolean_model.rbs new file mode 100644 index 00000000..48a057ca --- /dev/null +++ b/sig/finch-api/type/boolean_model.rbs @@ -0,0 +1,18 @@ +module FinchAPI + module Type + class BooleanModel + extend FinchAPI::Type::Converter + + def self.===: (top other) -> bool + + def self.==: (top other) -> bool + + def self.coerce: ( + bool | top value, + state: FinchAPI::Type::Converter::state + ) -> (bool | top) + + def self.dump: (bool | top value) -> (bool | top) + end + end +end diff --git a/sig/finch-api/type/converter.rbs b/sig/finch-api/type/converter.rbs new file mode 100644 index 00000000..3f38009e --- /dev/null +++ b/sig/finch-api/type/converter.rbs @@ -0,0 +1,36 @@ +module FinchAPI + module Type + module Converter + type input = FinchAPI::Type::Converter | Class + + type state = + { + strictness: bool | :strong, + exactness: { yes: Integer, no: Integer, maybe: Integer }, + branched: Integer + } + + def coerce: (top value, state: FinchAPI::Type::Converter::state) -> top + + def dump: (top value) -> top + + def self.type_info: ( + { + const: (nil | bool | Integer | Float | Symbol)?, + enum: ^-> FinchAPI::Type::Converter::input?, + union: ^-> FinchAPI::Type::Converter::input? + } + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input spec + ) -> (^-> top) + + def self.coerce: ( + FinchAPI::Type::Converter::input target, + top value, + ?state: FinchAPI::Type::Converter::state + ) -> top + + def self.dump: (FinchAPI::Type::Converter::input target, top value) -> top + end + end +end diff --git a/sig/finch-api/type/enum.rbs b/sig/finch-api/type/enum.rbs new file mode 100644 index 00000000..2a0ad02a --- /dev/null +++ b/sig/finch-api/type/enum.rbs @@ -0,0 +1,22 @@ +module FinchAPI + module Type + module Enum + include FinchAPI::Type::Converter + + def self.values: -> ::Array[(nil | bool | Integer | Float | Symbol)] + + private def self.finalize!: -> void + + def ===: (top other) -> bool + + def ==: (top other) -> bool + + def coerce: ( + String | Symbol | top value, + state: FinchAPI::Type::Converter::state + ) -> (Symbol | top) + + def dump: (Symbol | top value) -> (Symbol | top) + end + end +end diff --git a/sig/finch-api/type/hash_of.rbs b/sig/finch-api/type/hash_of.rbs new file mode 100644 index 00000000..ec08dfb9 --- /dev/null +++ b/sig/finch-api/type/hash_of.rbs @@ -0,0 +1,36 @@ +module FinchAPI + module Type + class HashOf + include FinchAPI::Type::Converter + + def self.[]: ( + ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input type_info, + ?::Hash[Symbol, top] spec + ) -> instance + + def ===: (top other) -> bool + + def ==: (top other) -> bool + + def coerce: ( + ::Hash[top, top] | top value, + state: FinchAPI::Type::Converter::state + ) -> (::Hash[Symbol, top] | top) + + def dump: (::Hash[top, top] | top value) -> (::Hash[Symbol, top] | top) + + def item_type: -> top + + def nilable?: -> bool + + def initialize: ( + ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input type_info, + ?::Hash[Symbol, top] spec + ) -> void + end + end +end diff --git a/sig/finch-api/type/request_parameters.rbs b/sig/finch-api/type/request_parameters.rbs new file mode 100644 index 00000000..7e31ff42 --- /dev/null +++ b/sig/finch-api/type/request_parameters.rbs @@ -0,0 +1,13 @@ +module FinchAPI + module Type + type request_parameters = { request_options: FinchAPI::request_opts } + + module RequestParameters + attr_accessor request_options: FinchAPI::request_opts + + module Converter + def dump_request: (top params) -> [top, ::Hash[Symbol, top]] + end + end + end +end diff --git a/sig/finch-api/type/union.rbs b/sig/finch-api/type/union.rbs new file mode 100644 index 00000000..d5068f93 --- /dev/null +++ b/sig/finch-api/type/union.rbs @@ -0,0 +1,37 @@ +module FinchAPI + module Type + module Union + include FinchAPI::Type::Converter + + private def self.known_variants: -> ::Array[[Symbol?, (^-> FinchAPI::Type::Converter::input)]] + + def self.derefed_variants: -> ::Array[[Symbol?, top]] + + def self.variants: -> ::Array[top] + + private def self.discriminator: (Symbol property) -> void + + private def self.variant: ( + Symbol + | ::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input key, + ?::Hash[Symbol, top] + | ^-> FinchAPI::Type::Converter::input + | FinchAPI::Type::Converter::input spec + ) -> void + + private def self.resolve_variant: ( + top value + ) -> FinchAPI::Type::Converter::input? + + def ===: (top other) -> bool + + def ==: (top other) -> bool + + def coerce: (top value, state: FinchAPI::Type::Converter::state) -> top + + def dump: (top value) -> top + end + end +end diff --git a/sig/finch-api/type/unknown.rbs b/sig/finch-api/type/unknown.rbs new file mode 100644 index 00000000..ae98c008 --- /dev/null +++ b/sig/finch-api/type/unknown.rbs @@ -0,0 +1,18 @@ +module FinchAPI + module Type + class Unknown + extend FinchAPI::Type::Converter + + def self.===: (top other) -> bool + + def self.==: (top other) -> bool + + def self.coerce: ( + top value, + state: FinchAPI::Type::Converter::state + ) -> top + + def self.dump: (top value) -> top + end + end +end diff --git a/test/finch-api/base_model_test.rb b/test/finch-api/base_model_test.rb index cb88957b..a382546c 100644 --- a/test/finch-api/base_model_test.rb +++ b/test/finch-api/base_model_test.rb @@ -32,7 +32,7 @@ def test_typing converters.each do |conv| assert_pattern do - conv => FinchAPI::Converter + conv => FinchAPI::Type::Converter end end end @@ -68,7 +68,7 @@ def test_coerce exactness, expect = rhs state = {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} assert_pattern do - FinchAPI::Converter.coerce(target, input, state: state) => ^expect + FinchAPI::Type::Converter.coerce(target, input, state: state) => ^expect state.fetch(:exactness).filter { _2.nonzero? }.to_h => ^exactness end end @@ -99,7 +99,7 @@ def test_dump target, input = _1 expect = _2 assert_pattern do - FinchAPI::Converter.dump(target, input) => ^expect + FinchAPI::Type::Converter.dump(target, input) => ^expect end end end @@ -118,7 +118,7 @@ def test_coerce_errors target, input = _1 state = {strictness: :strong, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} assert_raises(_2) do - FinchAPI::Converter.coerce(target, input, state: state) + FinchAPI::Type::Converter.coerce(target, input, state: state) end end end @@ -179,7 +179,7 @@ def test_coerce exactness, expect = rhs state = {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} assert_pattern do - FinchAPI::Converter.coerce(target, input, state: state) => ^expect + FinchAPI::Type::Converter.coerce(target, input, state: state) => ^expect state.fetch(:exactness).filter { _2.nonzero? }.to_h => ^exactness end end @@ -207,7 +207,7 @@ def test_dump target, input = _1 expect = _2 assert_pattern do - FinchAPI::Converter.dump(target, input) => ^expect + FinchAPI::Type::Converter.dump(target, input) => ^expect end end end @@ -253,7 +253,7 @@ def test_coerce exactness, expect = rhs state = {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} assert_pattern do - FinchAPI::Converter.coerce(target, input, state: state) => ^expect + FinchAPI::Type::Converter.coerce(target, input, state: state) => ^expect state.fetch(:exactness).filter { _2.nonzero? }.to_h => ^exactness end end @@ -333,7 +333,7 @@ def test_coerce exactness, expect = rhs state = {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} assert_pattern do - coerced = FinchAPI::Converter.coerce(target, input, state: state) + coerced = FinchAPI::Type::Converter.coerce(target, input, state: state) assert_equal(coerced, coerced) if coerced.is_a?(FinchAPI::BaseModel) coerced.to_h => ^expect @@ -363,7 +363,7 @@ def test_dump target, input = _1 expect = _2 assert_pattern do - FinchAPI::Converter.dump(target, input) => ^expect + FinchAPI::Type::Converter.dump(target, input) => ^expect end end end @@ -509,7 +509,7 @@ def test_coerce exactness, branched, expect = rhs state = {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0} assert_pattern do - coerced = FinchAPI::Converter.coerce(target, input, state: state) + coerced = FinchAPI::Type::Converter.coerce(target, input, state: state) assert_equal(coerced, coerced) if coerced.is_a?(FinchAPI::BaseModel) coerced.to_h => ^expect From 9cfaabdde3e58f17d09edbc304f3810618d722af Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 17:37:56 +0000 Subject: [PATCH 3/5] chore: more accurate type annotations for SDK internals (#83) --- rbi/lib/finch-api/type/array_of.rbi | 12 +++++------- rbi/lib/finch-api/type/hash_of.rbi | 4 +++- sig/finch-api/type/array_of.rbs | 8 ++++---- sig/finch-api/type/hash_of.rbs | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rbi/lib/finch-api/type/array_of.rbi b/rbi/lib/finch-api/type/array_of.rbi index b5610565..e8efa199 100644 --- a/rbi/lib/finch-api/type/array_of.rbi +++ b/rbi/lib/finch-api/type/array_of.rbi @@ -11,6 +11,8 @@ module FinchAPI abstract! final! + Elem = type_member(:out) + sig(:final) do params( type_info: T.any( @@ -36,11 +38,7 @@ module FinchAPI # @api private sig(:final) do override - .params(value: T.any( - T::Enumerable[T.anything], - T.anything - ), - state: FinchAPI::Type::Converter::State) + .params(value: T.any(T::Enumerable[Elem], T.anything), state: FinchAPI::Type::Converter::State) .returns(T.any(T::Array[T.anything], T.anything)) end def coerce(value, state:) @@ -49,14 +47,14 @@ module FinchAPI # @api private sig(:final) do override - .params(value: T.any(T::Enumerable[T.anything], T.anything)) + .params(value: T.any(T::Enumerable[Elem], T.anything)) .returns(T.any(T::Array[T.anything], T.anything)) end def dump(value) end # @api private - sig(:final) { returns(T.anything) } + sig(:final) { returns(Elem) } protected def item_type end diff --git a/rbi/lib/finch-api/type/hash_of.rbi b/rbi/lib/finch-api/type/hash_of.rbi index 90be1e97..5e222725 100644 --- a/rbi/lib/finch-api/type/hash_of.rbi +++ b/rbi/lib/finch-api/type/hash_of.rbi @@ -11,6 +11,8 @@ module FinchAPI abstract! final! + Elem = type_member(:out) + sig(:final) do params( type_info: T.any( @@ -56,7 +58,7 @@ module FinchAPI end # @api private - sig(:final) { returns(T.anything) } + sig(:final) { returns(Elem) } protected def item_type end diff --git a/sig/finch-api/type/array_of.rbs b/sig/finch-api/type/array_of.rbs index b2f05c36..f6f7f49e 100644 --- a/sig/finch-api/type/array_of.rbs +++ b/sig/finch-api/type/array_of.rbs @@ -1,6 +1,6 @@ module FinchAPI module Type - class ArrayOf + class ArrayOf[Elem] include FinchAPI::Type::Converter def self.[]: ( @@ -15,13 +15,13 @@ module FinchAPI def ==: (top other) -> bool def coerce: ( - Enumerable[top] | top value, + Enumerable[Elem] | top value, state: FinchAPI::Type::Converter::state ) -> (::Array[top] | top) - def dump: (Enumerable[top] | top value) -> (::Array[top] | top) + def dump: (Enumerable[Elem] | top value) -> (::Array[top] | top) - def item_type: -> top + def item_type: -> Elem def nilable?: -> bool diff --git a/sig/finch-api/type/hash_of.rbs b/sig/finch-api/type/hash_of.rbs index ec08dfb9..8cc3ddf7 100644 --- a/sig/finch-api/type/hash_of.rbs +++ b/sig/finch-api/type/hash_of.rbs @@ -1,6 +1,6 @@ module FinchAPI module Type - class HashOf + class HashOf[Elem] include FinchAPI::Type::Converter def self.[]: ( @@ -21,7 +21,7 @@ module FinchAPI def dump: (::Hash[top, top] | top value) -> (::Hash[Symbol, top] | top) - def item_type: -> top + def item_type: -> Elem def nilable?: -> bool From e868827d1be8683eaa7fb677e32dd189b2ec08c3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 18:45:07 +0000 Subject: [PATCH 4/5] chore: update readme (#84) --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0033c802..da382342 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ The underlying REST API documentation can be found on [developer.tryfinch.com](h ## Installation -To use this gem during the beta, install directly from GitHub with Bundler by adding the following to your application's `Gemfile`: +To use this gem, install via Bundler by adding the following to your application's `Gemfile`: ```ruby -gem "finch-api", git: "https://github.com/Finch-API/finch-api-ruby", branch: "main" +gem "finch-api", "~> 0.1.0.pre.alpha.4" ``` To fetch an initial copy of the gem: @@ -24,12 +24,6 @@ To fetch an initial copy of the gem: bundle install ``` -To update the version used by your application when updates are pushed to GitHub: - -```sh -bundle update finch-api -``` - ## Usage ```ruby From 661a2b098e70508b3b23d3ca09c692d692a439a9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 18:45:29 +0000 Subject: [PATCH 5/5] release: 0.1.0-alpha.5 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 11 +++++++++++ Gemfile.lock | 2 +- lib/finch-api/version.rb | 2 +- rbi/lib/finch-api/version.rbi | 2 +- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b56c3d0b..e8285b71 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.4" + ".": "0.1.0-alpha.5" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ca808762..f4c1daa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.1.0-alpha.5 (2025-03-31) + +Full Changelog: [v0.1.0-alpha.4...v0.1.0-alpha.5](https://github.com/Finch-API/finch-api-ruby/compare/v0.1.0-alpha.4...v0.1.0-alpha.5) + +### Chores + +* **internal:** version bump ([#80](https://github.com/Finch-API/finch-api-ruby/issues/80)) ([9dc9569](https://github.com/Finch-API/finch-api-ruby/commit/9dc9569385307fa31597a0da5ca0f5819925b3f7)) +* more accurate type annotations for SDK internals ([#83](https://github.com/Finch-API/finch-api-ruby/issues/83)) ([9cfaabd](https://github.com/Finch-API/finch-api-ruby/commit/9cfaabdde3e58f17d09edbc304f3810618d722af)) +* relocate internal modules ([#82](https://github.com/Finch-API/finch-api-ruby/issues/82)) ([899a7c0](https://github.com/Finch-API/finch-api-ruby/commit/899a7c0fdf4968dcc552fb5dedfb0c5809562b06)) +* update readme ([#84](https://github.com/Finch-API/finch-api-ruby/issues/84)) ([e868827](https://github.com/Finch-API/finch-api-ruby/commit/e868827d1be8683eaa7fb677e32dd189b2ec08c3)) + ## 0.1.0-alpha.4 (2025-03-31) Full Changelog: [v0.1.0-alpha.3...v0.1.0-alpha.4](https://github.com/Finch-API/finch-api-ruby/compare/v0.1.0-alpha.3...v0.1.0-alpha.4) diff --git a/Gemfile.lock b/Gemfile.lock index 7b314324..87366e02 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT PATH remote: . specs: - finch-api (0.1.0.pre.alpha.4) + finch-api (0.1.0.pre.alpha.5) connection_pool GEM diff --git a/lib/finch-api/version.rb b/lib/finch-api/version.rb index 53914ff7..55cd0870 100644 --- a/lib/finch-api/version.rb +++ b/lib/finch-api/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module FinchAPI - VERSION = "0.1.0-alpha.4" + VERSION = "0.1.0-alpha.5" end diff --git a/rbi/lib/finch-api/version.rbi b/rbi/lib/finch-api/version.rbi index 1b646ed6..4fc0d2de 100644 --- a/rbi/lib/finch-api/version.rbi +++ b/rbi/lib/finch-api/version.rbi @@ -1,5 +1,5 @@ # typed: strong module FinchAPI - VERSION = "0.1.0-alpha.4" + VERSION = "0.1.0-alpha.5" end