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.
- checksums.yaml +7 -0
- data/.ignore +2 -0
- data/CHANGELOG.md +15 -0
- data/README.md +205 -0
- data/SECURITY.md +23 -0
- data/lib/seerstack/client.rb +79 -0
- data/lib/seerstack/errors.rb +228 -0
- data/lib/seerstack/file_part.rb +58 -0
- data/lib/seerstack/internal/transport/base_client.rb +573 -0
- data/lib/seerstack/internal/transport/pooled_net_requester.rb +210 -0
- data/lib/seerstack/internal/type/array_of.rb +168 -0
- data/lib/seerstack/internal/type/base_model.rb +529 -0
- data/lib/seerstack/internal/type/base_page.rb +55 -0
- data/lib/seerstack/internal/type/boolean.rb +77 -0
- data/lib/seerstack/internal/type/converter.rb +327 -0
- data/lib/seerstack/internal/type/enum.rb +131 -0
- data/lib/seerstack/internal/type/file_input.rb +111 -0
- data/lib/seerstack/internal/type/hash_of.rb +188 -0
- data/lib/seerstack/internal/type/request_parameters.rb +42 -0
- data/lib/seerstack/internal/type/union.rb +237 -0
- data/lib/seerstack/internal/type/unknown.rb +81 -0
- data/lib/seerstack/internal/util.rb +920 -0
- data/lib/seerstack/internal.rb +20 -0
- data/lib/seerstack/models/event_capture_params.rb +38 -0
- data/lib/seerstack/models/event_capture_response.rb +16 -0
- data/lib/seerstack/models/user_identify_params.rb +38 -0
- data/lib/seerstack/models/user_identify_response.rb +16 -0
- data/lib/seerstack/models.rb +45 -0
- data/lib/seerstack/request_options.rb +77 -0
- data/lib/seerstack/resources/events.rb +38 -0
- data/lib/seerstack/resources/users.rb +38 -0
- data/lib/seerstack/version.rb +5 -0
- data/lib/seerstack.rb +61 -0
- data/manifest.yaml +17 -0
- data/rbi/seerstack/client.rbi +53 -0
- data/rbi/seerstack/errors.rbi +205 -0
- data/rbi/seerstack/file_part.rbi +37 -0
- data/rbi/seerstack/internal/transport/base_client.rbi +298 -0
- data/rbi/seerstack/internal/transport/pooled_net_requester.rbi +83 -0
- data/rbi/seerstack/internal/type/array_of.rbi +104 -0
- data/rbi/seerstack/internal/type/base_model.rbi +308 -0
- data/rbi/seerstack/internal/type/base_page.rbi +42 -0
- data/rbi/seerstack/internal/type/boolean.rbi +58 -0
- data/rbi/seerstack/internal/type/converter.rbi +216 -0
- data/rbi/seerstack/internal/type/enum.rbi +82 -0
- data/rbi/seerstack/internal/type/file_input.rbi +59 -0
- data/rbi/seerstack/internal/type/hash_of.rbi +104 -0
- data/rbi/seerstack/internal/type/request_parameters.rbi +29 -0
- data/rbi/seerstack/internal/type/union.rbi +128 -0
- data/rbi/seerstack/internal/type/unknown.rbi +58 -0
- data/rbi/seerstack/internal/util.rbi +487 -0
- data/rbi/seerstack/internal.rbi +18 -0
- data/rbi/seerstack/models/event_capture_params.rbi +68 -0
- data/rbi/seerstack/models/event_capture_response.rbi +26 -0
- data/rbi/seerstack/models/user_identify_params.rbi +68 -0
- data/rbi/seerstack/models/user_identify_response.rbi +26 -0
- data/rbi/seerstack/models.rbi +7 -0
- data/rbi/seerstack/request_options.rbi +59 -0
- data/rbi/seerstack/resources/events.rbi +31 -0
- data/rbi/seerstack/resources/users.rbi +31 -0
- data/rbi/seerstack/version.rbi +5 -0
- data/sig/seerstack/client.rbs +28 -0
- data/sig/seerstack/errors.rbs +117 -0
- data/sig/seerstack/file_part.rbs +21 -0
- data/sig/seerstack/internal/transport/base_client.rbs +133 -0
- data/sig/seerstack/internal/transport/pooled_net_requester.rbs +48 -0
- data/sig/seerstack/internal/type/array_of.rbs +48 -0
- data/sig/seerstack/internal/type/base_model.rbs +102 -0
- data/sig/seerstack/internal/type/base_page.rbs +24 -0
- data/sig/seerstack/internal/type/boolean.rbs +26 -0
- data/sig/seerstack/internal/type/converter.rbs +79 -0
- data/sig/seerstack/internal/type/enum.rbs +32 -0
- data/sig/seerstack/internal/type/file_input.rbs +25 -0
- data/sig/seerstack/internal/type/hash_of.rbs +48 -0
- data/sig/seerstack/internal/type/request_parameters.rbs +19 -0
- data/sig/seerstack/internal/type/union.rbs +52 -0
- data/sig/seerstack/internal/type/unknown.rbs +26 -0
- data/sig/seerstack/internal/util.rbs +185 -0
- data/sig/seerstack/internal.rbs +9 -0
- data/sig/seerstack/models/event_capture_params.rbs +47 -0
- data/sig/seerstack/models/event_capture_response.rbs +13 -0
- data/sig/seerstack/models/user_identify_params.rbs +47 -0
- data/sig/seerstack/models/user_identify_response.rbs +13 -0
- data/sig/seerstack/models.rbs +5 -0
- data/sig/seerstack/request_options.rbs +34 -0
- data/sig/seerstack/resources/events.rbs +15 -0
- data/sig/seerstack/resources/users.rbs +15 -0
- data/sig/seerstack/version.rbs +3 -0
- 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
|
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,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
|