seerstack 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.ignore +2 -0
  3. data/CHANGELOG.md +15 -0
  4. data/README.md +205 -0
  5. data/SECURITY.md +23 -0
  6. data/lib/seerstack/client.rb +79 -0
  7. data/lib/seerstack/errors.rb +228 -0
  8. data/lib/seerstack/file_part.rb +58 -0
  9. data/lib/seerstack/internal/transport/base_client.rb +573 -0
  10. data/lib/seerstack/internal/transport/pooled_net_requester.rb +210 -0
  11. data/lib/seerstack/internal/type/array_of.rb +168 -0
  12. data/lib/seerstack/internal/type/base_model.rb +529 -0
  13. data/lib/seerstack/internal/type/base_page.rb +55 -0
  14. data/lib/seerstack/internal/type/boolean.rb +77 -0
  15. data/lib/seerstack/internal/type/converter.rb +327 -0
  16. data/lib/seerstack/internal/type/enum.rb +131 -0
  17. data/lib/seerstack/internal/type/file_input.rb +111 -0
  18. data/lib/seerstack/internal/type/hash_of.rb +188 -0
  19. data/lib/seerstack/internal/type/request_parameters.rb +42 -0
  20. data/lib/seerstack/internal/type/union.rb +237 -0
  21. data/lib/seerstack/internal/type/unknown.rb +81 -0
  22. data/lib/seerstack/internal/util.rb +920 -0
  23. data/lib/seerstack/internal.rb +20 -0
  24. data/lib/seerstack/models/event_capture_params.rb +38 -0
  25. data/lib/seerstack/models/event_capture_response.rb +16 -0
  26. data/lib/seerstack/models/user_identify_params.rb +38 -0
  27. data/lib/seerstack/models/user_identify_response.rb +16 -0
  28. data/lib/seerstack/models.rb +45 -0
  29. data/lib/seerstack/request_options.rb +77 -0
  30. data/lib/seerstack/resources/events.rb +38 -0
  31. data/lib/seerstack/resources/users.rb +38 -0
  32. data/lib/seerstack/version.rb +5 -0
  33. data/lib/seerstack.rb +61 -0
  34. data/manifest.yaml +17 -0
  35. data/rbi/seerstack/client.rbi +53 -0
  36. data/rbi/seerstack/errors.rbi +205 -0
  37. data/rbi/seerstack/file_part.rbi +37 -0
  38. data/rbi/seerstack/internal/transport/base_client.rbi +298 -0
  39. data/rbi/seerstack/internal/transport/pooled_net_requester.rbi +83 -0
  40. data/rbi/seerstack/internal/type/array_of.rbi +104 -0
  41. data/rbi/seerstack/internal/type/base_model.rbi +308 -0
  42. data/rbi/seerstack/internal/type/base_page.rbi +42 -0
  43. data/rbi/seerstack/internal/type/boolean.rbi +58 -0
  44. data/rbi/seerstack/internal/type/converter.rbi +216 -0
  45. data/rbi/seerstack/internal/type/enum.rbi +82 -0
  46. data/rbi/seerstack/internal/type/file_input.rbi +59 -0
  47. data/rbi/seerstack/internal/type/hash_of.rbi +104 -0
  48. data/rbi/seerstack/internal/type/request_parameters.rbi +29 -0
  49. data/rbi/seerstack/internal/type/union.rbi +128 -0
  50. data/rbi/seerstack/internal/type/unknown.rbi +58 -0
  51. data/rbi/seerstack/internal/util.rbi +487 -0
  52. data/rbi/seerstack/internal.rbi +18 -0
  53. data/rbi/seerstack/models/event_capture_params.rbi +68 -0
  54. data/rbi/seerstack/models/event_capture_response.rbi +26 -0
  55. data/rbi/seerstack/models/user_identify_params.rbi +68 -0
  56. data/rbi/seerstack/models/user_identify_response.rbi +26 -0
  57. data/rbi/seerstack/models.rbi +7 -0
  58. data/rbi/seerstack/request_options.rbi +59 -0
  59. data/rbi/seerstack/resources/events.rbi +31 -0
  60. data/rbi/seerstack/resources/users.rbi +31 -0
  61. data/rbi/seerstack/version.rbi +5 -0
  62. data/sig/seerstack/client.rbs +28 -0
  63. data/sig/seerstack/errors.rbs +117 -0
  64. data/sig/seerstack/file_part.rbs +21 -0
  65. data/sig/seerstack/internal/transport/base_client.rbs +133 -0
  66. data/sig/seerstack/internal/transport/pooled_net_requester.rbs +48 -0
  67. data/sig/seerstack/internal/type/array_of.rbs +48 -0
  68. data/sig/seerstack/internal/type/base_model.rbs +102 -0
  69. data/sig/seerstack/internal/type/base_page.rbs +24 -0
  70. data/sig/seerstack/internal/type/boolean.rbs +26 -0
  71. data/sig/seerstack/internal/type/converter.rbs +79 -0
  72. data/sig/seerstack/internal/type/enum.rbs +32 -0
  73. data/sig/seerstack/internal/type/file_input.rbs +25 -0
  74. data/sig/seerstack/internal/type/hash_of.rbs +48 -0
  75. data/sig/seerstack/internal/type/request_parameters.rbs +19 -0
  76. data/sig/seerstack/internal/type/union.rbs +52 -0
  77. data/sig/seerstack/internal/type/unknown.rbs +26 -0
  78. data/sig/seerstack/internal/util.rbs +185 -0
  79. data/sig/seerstack/internal.rbs +9 -0
  80. data/sig/seerstack/models/event_capture_params.rbs +47 -0
  81. data/sig/seerstack/models/event_capture_response.rbs +13 -0
  82. data/sig/seerstack/models/user_identify_params.rbs +47 -0
  83. data/sig/seerstack/models/user_identify_response.rbs +13 -0
  84. data/sig/seerstack/models.rbs +5 -0
  85. data/sig/seerstack/request_options.rbs +34 -0
  86. data/sig/seerstack/resources/events.rbs +15 -0
  87. data/sig/seerstack/resources/users.rbs +15 -0
  88. data/sig/seerstack/version.rbs +3 -0
  89. metadata +146 -0
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Internal
5
+ extend Seerstack::Internal::Util::SorbetRuntimeSupport
6
+
7
+ OMIT =
8
+ Object.new.tap do
9
+ _1.define_singleton_method(:inspect) { "#<#{Seerstack::Internal}::OMIT>" }
10
+ end
11
+ .freeze
12
+
13
+ define_sorbet_constant!(:AnyHash) do
14
+ T.type_alias { T::Hash[Symbol, T.anything] }
15
+ end
16
+ define_sorbet_constant!(:FileInput) do
17
+ T.type_alias { T.any(Pathname, StringIO, IO, String, Seerstack::FilePart) }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Models
5
+ # @see Seerstack::Resources::Events#capture
6
+ class EventCaptureParams < Seerstack::Internal::Type::BaseModel
7
+ extend Seerstack::Internal::Type::RequestParameters::Converter
8
+ include Seerstack::Internal::Type::RequestParameters
9
+
10
+ # @!attribute name
11
+ #
12
+ # @return [String]
13
+ required :name, String
14
+
15
+ # @!attribute data
16
+ #
17
+ # @return [Hash{Symbol=>Object, nil}, nil]
18
+ optional :data, Seerstack::Internal::Type::HashOf[Seerstack::Internal::Type::Unknown, nil?: true]
19
+
20
+ # @!attribute timestamp
21
+ #
22
+ # @return [Time, nil]
23
+ optional :timestamp, Time
24
+
25
+ # @!attribute user_id
26
+ #
27
+ # @return [String, nil]
28
+ optional :user_id, String
29
+
30
+ # @!method initialize(name:, data: nil, timestamp: nil, user_id: nil, request_options: {})
31
+ # @param name [String]
32
+ # @param data [Hash{Symbol=>Object, nil}]
33
+ # @param timestamp [Time]
34
+ # @param user_id [String]
35
+ # @param request_options [Seerstack::RequestOptions, Hash{Symbol=>Object}]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Models
5
+ # @see Seerstack::Resources::Events#capture
6
+ class EventCaptureResponse < Seerstack::Internal::Type::BaseModel
7
+ # @!attribute success
8
+ #
9
+ # @return [Boolean]
10
+ required :success, Seerstack::Internal::Type::Boolean
11
+
12
+ # @!method initialize(success:)
13
+ # @param success [Boolean]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Models
5
+ # @see Seerstack::Resources::Users#identify
6
+ class UserIdentifyParams < Seerstack::Internal::Type::BaseModel
7
+ extend Seerstack::Internal::Type::RequestParameters::Converter
8
+ include Seerstack::Internal::Type::RequestParameters
9
+
10
+ # @!attribute user_id
11
+ #
12
+ # @return [String]
13
+ required :user_id, String
14
+
15
+ # @!attribute attributes
16
+ #
17
+ # @return [Hash{Symbol=>Object, nil}, nil]
18
+ optional :attributes, Seerstack::Internal::Type::HashOf[Seerstack::Internal::Type::Unknown, nil?: true]
19
+
20
+ # @!attribute email
21
+ #
22
+ # @return [String, nil]
23
+ optional :email, String
24
+
25
+ # @!attribute name
26
+ #
27
+ # @return [String, nil]
28
+ optional :name, String
29
+
30
+ # @!method initialize(user_id:, attributes: nil, email: nil, name: nil, request_options: {})
31
+ # @param user_id [String]
32
+ # @param attributes [Hash{Symbol=>Object, nil}]
33
+ # @param email [String]
34
+ # @param name [String]
35
+ # @param request_options [Seerstack::RequestOptions, Hash{Symbol=>Object}]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Models
5
+ # @see Seerstack::Resources::Users#identify
6
+ class UserIdentifyResponse < Seerstack::Internal::Type::BaseModel
7
+ # @!attribute success
8
+ #
9
+ # @return [Boolean]
10
+ required :success, Seerstack::Internal::Type::Boolean
11
+
12
+ # @!method initialize(success:)
13
+ # @param success [Boolean]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ [Seerstack::Internal::Type::BaseModel, *Seerstack::Internal::Type::BaseModel.subclasses].each do |cls|
5
+ cls.define_sorbet_constant!(:OrHash) { T.type_alias { T.any(cls, Seerstack::Internal::AnyHash) } }
6
+ end
7
+
8
+ Seerstack::Internal::Util.walk_namespaces(Seerstack::Models).each do |mod|
9
+ case mod
10
+ in Seerstack::Internal::Type::Enum | Seerstack::Internal::Type::Union
11
+ mod.constants.each do |name|
12
+ case mod.const_get(name)
13
+ in true | false
14
+ mod.define_sorbet_constant!(:TaggedBoolean) { T.type_alias { T::Boolean } }
15
+ mod.define_sorbet_constant!(:OrBoolean) { T.type_alias { T::Boolean } }
16
+ in Integer
17
+ mod.define_sorbet_constant!(:TaggedInteger) { T.type_alias { Integer } }
18
+ mod.define_sorbet_constant!(:OrInteger) { T.type_alias { Integer } }
19
+ in Float
20
+ mod.define_sorbet_constant!(:TaggedFloat) { T.type_alias { Float } }
21
+ mod.define_sorbet_constant!(:OrFloat) { T.type_alias { Float } }
22
+ in Symbol
23
+ mod.define_sorbet_constant!(:TaggedSymbol) { T.type_alias { Symbol } }
24
+ mod.define_sorbet_constant!(:OrSymbol) { T.type_alias { T.any(Symbol, String) } }
25
+ else
26
+ end
27
+ end
28
+ else
29
+ end
30
+ end
31
+
32
+ Seerstack::Internal::Util.walk_namespaces(Seerstack::Models)
33
+ .lazy
34
+ .grep(Seerstack::Internal::Type::Union)
35
+ .each do |mod|
36
+ const = :Variants
37
+ next if mod.sorbet_constant_defined?(const)
38
+
39
+ mod.define_sorbet_constant!(const) { T.type_alias { mod.to_sorbet_type } }
40
+ end
41
+
42
+ EventCaptureParams = Seerstack::Models::EventCaptureParams
43
+
44
+ UserIdentifyParams = Seerstack::Models::UserIdentifyParams
45
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ # Specify HTTP behaviour to use for a specific request. These options supplement
5
+ # or override those provided at the client level.
6
+ #
7
+ # When making a request, you can pass an actual {RequestOptions} instance, or
8
+ # simply pass a Hash with symbol keys matching the attributes on this class.
9
+ class RequestOptions < Seerstack::Internal::Type::BaseModel
10
+ # @api private
11
+ #
12
+ # @param opts [Seerstack::RequestOptions, Hash{Symbol=>Object}]
13
+ #
14
+ # @raise [ArgumentError]
15
+ def self.validate!(opts)
16
+ case opts
17
+ in Seerstack::RequestOptions | Hash
18
+ opts.to_h.each_key do |k|
19
+ unless fields.include?(k)
20
+ raise ArgumentError.new("Request `opts` keys must be one of #{fields.keys}, got #{k.inspect}")
21
+ end
22
+ end
23
+ else
24
+ raise ArgumentError.new("Request `opts` must be a Hash or RequestOptions, got #{opts.inspect}")
25
+ end
26
+ end
27
+
28
+ # @!attribute idempotency_key
29
+ # Idempotency key to send with request and all associated retries. Will only be
30
+ # sent for write requests.
31
+ #
32
+ # @return [String, nil]
33
+ optional :idempotency_key, String
34
+
35
+ # @!attribute extra_query
36
+ # Extra query params to send with the request. These are `.merge`’d into any
37
+ # `query` given at the client level.
38
+ #
39
+ # @return [Hash{String=>Array<String>, String, nil}, nil]
40
+ optional :extra_query, Seerstack::Internal::Type::HashOf[Seerstack::Internal::Type::ArrayOf[String]]
41
+
42
+ # @!attribute extra_headers
43
+ # Extra headers to send with the request. These are `.merged`’d into any
44
+ # `extra_headers` given at the client level.
45
+ #
46
+ # @return [Hash{String=>String, nil}, nil]
47
+ optional :extra_headers, Seerstack::Internal::Type::HashOf[String, nil?: true]
48
+
49
+ # @!attribute extra_body
50
+ # Extra data to send with the request. These are deep merged into any data
51
+ # generated as part of the normal request.
52
+ #
53
+ # @return [Object, nil]
54
+ optional :extra_body, Seerstack::Internal::Type::HashOf[Seerstack::Internal::Type::Unknown]
55
+
56
+ # @!attribute max_retries
57
+ # Maximum number of retries to attempt after a failed initial request.
58
+ #
59
+ # @return [Integer, nil]
60
+ optional :max_retries, Integer
61
+
62
+ # @!attribute timeout
63
+ # Request timeout in seconds.
64
+ #
65
+ # @return [Float, nil]
66
+ optional :timeout, Float
67
+
68
+ # @!method initialize(values = {})
69
+ # Returns a new instance of RequestOptions.
70
+ #
71
+ # @param values [Hash{Symbol=>Object}]
72
+
73
+ define_sorbet_constant!(:OrHash) do
74
+ T.type_alias { T.any(Seerstack::RequestOptions, Seerstack::Internal::AnyHash) }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Resources
5
+ class Events
6
+ # Capture an event
7
+ #
8
+ # @overload capture(name:, data: nil, timestamp: nil, user_id: nil, request_options: {})
9
+ #
10
+ # @param name [String]
11
+ # @param data [Hash{Symbol=>Object, nil}]
12
+ # @param timestamp [Time]
13
+ # @param user_id [String]
14
+ # @param request_options [Seerstack::RequestOptions, Hash{Symbol=>Object}, nil]
15
+ #
16
+ # @return [Seerstack::Models::EventCaptureResponse]
17
+ #
18
+ # @see Seerstack::Models::EventCaptureParams
19
+ def capture(params)
20
+ parsed, options = Seerstack::EventCaptureParams.dump_request(params)
21
+ @client.request(
22
+ method: :post,
23
+ path: "capture",
24
+ body: parsed,
25
+ model: Seerstack::Models::EventCaptureResponse,
26
+ options: options
27
+ )
28
+ end
29
+
30
+ # @api private
31
+ #
32
+ # @param client [Seerstack::Client]
33
+ def initialize(client:)
34
+ @client = client
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ module Resources
5
+ class Users
6
+ # Identify a user
7
+ #
8
+ # @overload identify(user_id:, attributes: nil, email: nil, name: nil, request_options: {})
9
+ #
10
+ # @param user_id [String]
11
+ # @param attributes [Hash{Symbol=>Object, nil}]
12
+ # @param email [String]
13
+ # @param name [String]
14
+ # @param request_options [Seerstack::RequestOptions, Hash{Symbol=>Object}, nil]
15
+ #
16
+ # @return [Seerstack::Models::UserIdentifyResponse]
17
+ #
18
+ # @see Seerstack::Models::UserIdentifyParams
19
+ def identify(params)
20
+ parsed, options = Seerstack::UserIdentifyParams.dump_request(params)
21
+ @client.request(
22
+ method: :post,
23
+ path: "identify",
24
+ body: parsed,
25
+ model: Seerstack::Models::UserIdentifyResponse,
26
+ options: options
27
+ )
28
+ end
29
+
30
+ # @api private
31
+ #
32
+ # @param client [Seerstack::Client]
33
+ def initialize(client:)
34
+ @client = client
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Seerstack
4
+ VERSION = "0.1.0"
5
+ end
data/lib/seerstack.rb ADDED
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Standard libraries.
4
+ # rubocop:disable Lint/RedundantRequireStatement
5
+ require "English"
6
+ require "base64"
7
+ require "cgi"
8
+ require "date"
9
+ require "erb"
10
+ require "etc"
11
+ require "json"
12
+ require "net/http"
13
+ require "openssl"
14
+ require "pathname"
15
+ require "rbconfig"
16
+ require "securerandom"
17
+ require "set"
18
+ require "stringio"
19
+ require "time"
20
+ require "uri"
21
+ # rubocop:enable Lint/RedundantRequireStatement
22
+
23
+ # We already ship the preferred sorbet manifests in the package itself.
24
+ # `tapioca` currently does not offer us a way to opt out of unnecessary compilation.
25
+ if Object.const_defined?(:Tapioca) &&
26
+ caller.chain([$PROGRAM_NAME]).chain(ARGV).any?(/tapioca/) &&
27
+ ARGV.none?(/dsl/)
28
+ return
29
+ end
30
+
31
+ # Gems.
32
+ require "connection_pool"
33
+
34
+ # Package files.
35
+ require_relative "seerstack/version"
36
+ require_relative "seerstack/internal/util"
37
+ require_relative "seerstack/internal/type/converter"
38
+ require_relative "seerstack/internal/type/unknown"
39
+ require_relative "seerstack/internal/type/boolean"
40
+ require_relative "seerstack/internal/type/file_input"
41
+ require_relative "seerstack/internal/type/enum"
42
+ require_relative "seerstack/internal/type/union"
43
+ require_relative "seerstack/internal/type/array_of"
44
+ require_relative "seerstack/internal/type/hash_of"
45
+ require_relative "seerstack/internal/type/base_model"
46
+ require_relative "seerstack/internal/type/base_page"
47
+ require_relative "seerstack/internal/type/request_parameters"
48
+ require_relative "seerstack/internal"
49
+ require_relative "seerstack/request_options"
50
+ require_relative "seerstack/file_part"
51
+ require_relative "seerstack/errors"
52
+ require_relative "seerstack/internal/transport/base_client"
53
+ require_relative "seerstack/internal/transport/pooled_net_requester"
54
+ require_relative "seerstack/client"
55
+ require_relative "seerstack/models/event_capture_params"
56
+ require_relative "seerstack/models/event_capture_response"
57
+ require_relative "seerstack/models/user_identify_params"
58
+ require_relative "seerstack/models/user_identify_response"
59
+ require_relative "seerstack/models"
60
+ require_relative "seerstack/resources/events"
61
+ require_relative "seerstack/resources/users"
data/manifest.yaml ADDED
@@ -0,0 +1,17 @@
1
+ dependencies:
2
+ - English
3
+ - base64
4
+ - cgi
5
+ - date
6
+ - erb
7
+ - etc
8
+ - json
9
+ - net/http
10
+ - openssl
11
+ - pathname
12
+ - rbconfig
13
+ - securerandom
14
+ - set
15
+ - stringio
16
+ - time
17
+ - uri
@@ -0,0 +1,53 @@
1
+ # typed: strong
2
+
3
+ module Seerstack
4
+ class Client < Seerstack::Internal::Transport::BaseClient
5
+ DEFAULT_MAX_RETRIES = 2
6
+
7
+ DEFAULT_TIMEOUT_IN_SECONDS = T.let(60.0, Float)
8
+
9
+ DEFAULT_INITIAL_RETRY_DELAY = T.let(0.5, Float)
10
+
11
+ DEFAULT_MAX_RETRY_DELAY = T.let(8.0, Float)
12
+
13
+ # API key authentication via Bearer token
14
+ sig { returns(String) }
15
+ attr_reader :api_key
16
+
17
+ sig { returns(Seerstack::Resources::Events) }
18
+ attr_reader :events
19
+
20
+ sig { returns(Seerstack::Resources::Users) }
21
+ attr_reader :users
22
+
23
+ # @api private
24
+ sig { override.returns(T::Hash[String, String]) }
25
+ private def auth_headers
26
+ end
27
+
28
+ # Creates and returns a new client for interacting with the API.
29
+ sig do
30
+ params(
31
+ api_key: T.nilable(String),
32
+ base_url: T.nilable(String),
33
+ max_retries: Integer,
34
+ timeout: Float,
35
+ initial_retry_delay: Float,
36
+ max_retry_delay: Float
37
+ ).returns(T.attached_class)
38
+ end
39
+ def self.new(
40
+ # API key authentication via Bearer token Defaults to `ENV["SEERSTACK_API_KEY"]`
41
+ api_key: ENV["SEERSTACK_API_KEY"],
42
+ # Override the default base URL for the API, e.g.,
43
+ # `"https://api.example.com/v2/"`. Defaults to `ENV["SEERSTACK_BASE_URL"]`
44
+ base_url: ENV["SEERSTACK_BASE_URL"],
45
+ # Max number of retries to attempt after a failed retryable request.
46
+ max_retries: Seerstack::Client::DEFAULT_MAX_RETRIES,
47
+ timeout: Seerstack::Client::DEFAULT_TIMEOUT_IN_SECONDS,
48
+ initial_retry_delay: Seerstack::Client::DEFAULT_INITIAL_RETRY_DELAY,
49
+ max_retry_delay: Seerstack::Client::DEFAULT_MAX_RETRY_DELAY
50
+ )
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,205 @@
1
+ # typed: strong
2
+
3
+ module Seerstack
4
+ module Errors
5
+ class Error < StandardError
6
+ sig { returns(T.nilable(StandardError)) }
7
+ attr_accessor :cause
8
+ end
9
+
10
+ class ConversionError < Seerstack::Errors::Error
11
+ sig { returns(T.nilable(StandardError)) }
12
+ def cause
13
+ end
14
+
15
+ # @api private
16
+ sig do
17
+ params(
18
+ on: T::Class[StandardError],
19
+ method: Symbol,
20
+ target: T.anything,
21
+ value: T.anything,
22
+ cause: T.nilable(StandardError)
23
+ ).returns(T.attached_class)
24
+ end
25
+ def self.new(on:, method:, target:, value:, cause: nil)
26
+ end
27
+ end
28
+
29
+ class APIError < Seerstack::Errors::Error
30
+ sig { returns(URI::Generic) }
31
+ attr_accessor :url
32
+
33
+ sig { returns(T.nilable(Integer)) }
34
+ attr_accessor :status
35
+
36
+ sig { returns(T.nilable(T::Hash[String, String])) }
37
+ attr_accessor :headers
38
+
39
+ sig { returns(T.nilable(T.anything)) }
40
+ attr_accessor :body
41
+
42
+ # @api private
43
+ sig do
44
+ params(
45
+ url: URI::Generic,
46
+ status: T.nilable(Integer),
47
+ headers: T.nilable(T::Hash[String, String]),
48
+ body: T.nilable(Object),
49
+ request: NilClass,
50
+ response: NilClass,
51
+ message: T.nilable(String)
52
+ ).returns(T.attached_class)
53
+ end
54
+ def self.new(
55
+ url:,
56
+ status: nil,
57
+ headers: nil,
58
+ body: nil,
59
+ request: nil,
60
+ response: nil,
61
+ message: nil
62
+ )
63
+ end
64
+ end
65
+
66
+ class APIConnectionError < Seerstack::Errors::APIError
67
+ sig { returns(NilClass) }
68
+ attr_accessor :status
69
+
70
+ sig { returns(NilClass) }
71
+ attr_accessor :body
72
+
73
+ # @api private
74
+ sig do
75
+ params(
76
+ url: URI::Generic,
77
+ status: NilClass,
78
+ headers: T.nilable(T::Hash[String, String]),
79
+ body: NilClass,
80
+ request: NilClass,
81
+ response: NilClass,
82
+ message: T.nilable(String)
83
+ ).returns(T.attached_class)
84
+ end
85
+ def self.new(
86
+ url:,
87
+ status: nil,
88
+ headers: nil,
89
+ body: nil,
90
+ request: nil,
91
+ response: nil,
92
+ message: "Connection error."
93
+ )
94
+ end
95
+ end
96
+
97
+ class APITimeoutError < Seerstack::Errors::APIConnectionError
98
+ # @api private
99
+ sig do
100
+ params(
101
+ url: URI::Generic,
102
+ status: NilClass,
103
+ headers: T.nilable(T::Hash[String, String]),
104
+ body: NilClass,
105
+ request: NilClass,
106
+ response: NilClass,
107
+ message: T.nilable(String)
108
+ ).returns(T.attached_class)
109
+ end
110
+ def self.new(
111
+ url:,
112
+ status: nil,
113
+ headers: nil,
114
+ body: nil,
115
+ request: nil,
116
+ response: nil,
117
+ message: "Request timed out."
118
+ )
119
+ end
120
+ end
121
+
122
+ class APIStatusError < Seerstack::Errors::APIError
123
+ # @api private
124
+ sig do
125
+ params(
126
+ url: URI::Generic,
127
+ status: Integer,
128
+ headers: T.nilable(T::Hash[String, String]),
129
+ body: T.nilable(Object),
130
+ request: NilClass,
131
+ response: NilClass,
132
+ message: T.nilable(String)
133
+ ).returns(T.attached_class)
134
+ end
135
+ def self.for(
136
+ url:,
137
+ status:,
138
+ headers:,
139
+ body:,
140
+ request:,
141
+ response:,
142
+ message: nil
143
+ )
144
+ end
145
+
146
+ sig { returns(Integer) }
147
+ attr_accessor :status
148
+
149
+ # @api private
150
+ sig do
151
+ params(
152
+ url: URI::Generic,
153
+ status: Integer,
154
+ headers: T.nilable(T::Hash[String, String]),
155
+ body: T.nilable(Object),
156
+ request: NilClass,
157
+ response: NilClass,
158
+ message: T.nilable(String)
159
+ ).returns(T.attached_class)
160
+ end
161
+ def self.new(
162
+ url:,
163
+ status:,
164
+ headers:,
165
+ body:,
166
+ request:,
167
+ response:,
168
+ message: nil
169
+ )
170
+ end
171
+ end
172
+
173
+ class BadRequestError < Seerstack::Errors::APIStatusError
174
+ HTTP_STATUS = 400
175
+ end
176
+
177
+ class AuthenticationError < Seerstack::Errors::APIStatusError
178
+ HTTP_STATUS = 401
179
+ end
180
+
181
+ class PermissionDeniedError < Seerstack::Errors::APIStatusError
182
+ HTTP_STATUS = 403
183
+ end
184
+
185
+ class NotFoundError < Seerstack::Errors::APIStatusError
186
+ HTTP_STATUS = 404
187
+ end
188
+
189
+ class ConflictError < Seerstack::Errors::APIStatusError
190
+ HTTP_STATUS = 409
191
+ end
192
+
193
+ class UnprocessableEntityError < Seerstack::Errors::APIStatusError
194
+ HTTP_STATUS = 422
195
+ end
196
+
197
+ class RateLimitError < Seerstack::Errors::APIStatusError
198
+ HTTP_STATUS = 429
199
+ end
200
+
201
+ class InternalServerError < Seerstack::Errors::APIStatusError
202
+ HTTP_STATUS = T.let((500..), T::Range[Integer])
203
+ end
204
+ end
205
+ end