oursprivacy-ingest 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 +16 -0
- data/README.md +206 -0
- data/SECURITY.md +27 -0
- data/lib/oursprivacy_ingest/client.rb +64 -0
- data/lib/oursprivacy_ingest/errors.rb +228 -0
- data/lib/oursprivacy_ingest/file_part.rb +58 -0
- data/lib/oursprivacy_ingest/internal/transport/base_client.rb +573 -0
- data/lib/oursprivacy_ingest/internal/transport/pooled_net_requester.rb +204 -0
- data/lib/oursprivacy_ingest/internal/type/array_of.rb +168 -0
- data/lib/oursprivacy_ingest/internal/type/base_model.rb +534 -0
- data/lib/oursprivacy_ingest/internal/type/base_page.rb +55 -0
- data/lib/oursprivacy_ingest/internal/type/boolean.rb +77 -0
- data/lib/oursprivacy_ingest/internal/type/converter.rb +327 -0
- data/lib/oursprivacy_ingest/internal/type/enum.rb +133 -0
- data/lib/oursprivacy_ingest/internal/type/file_input.rb +111 -0
- data/lib/oursprivacy_ingest/internal/type/hash_of.rb +188 -0
- data/lib/oursprivacy_ingest/internal/type/request_parameters.rb +42 -0
- data/lib/oursprivacy_ingest/internal/type/union.rb +245 -0
- data/lib/oursprivacy_ingest/internal/type/unknown.rb +81 -0
- data/lib/oursprivacy_ingest/internal/util.rb +915 -0
- data/lib/oursprivacy_ingest/internal.rb +20 -0
- data/lib/oursprivacy_ingest/models/track_event_params.rb +1009 -0
- data/lib/oursprivacy_ingest/models/track_event_response.rb +26 -0
- data/lib/oursprivacy_ingest/models/visitor_upsert_params.rb +972 -0
- data/lib/oursprivacy_ingest/models/visitor_upsert_response.rb +26 -0
- data/lib/oursprivacy_ingest/models.rb +48 -0
- data/lib/oursprivacy_ingest/request_options.rb +79 -0
- data/lib/oursprivacy_ingest/resources/track.rb +61 -0
- data/lib/oursprivacy_ingest/resources/visitor.rb +52 -0
- data/lib/oursprivacy_ingest/version.rb +5 -0
- data/lib/oursprivacy_ingest.rb +59 -0
- data/manifest.yaml +15 -0
- data/rbi/oursprivacy_ingest/client.rbi +46 -0
- data/rbi/oursprivacy_ingest/errors.rbi +205 -0
- data/rbi/oursprivacy_ingest/file_part.rbi +37 -0
- data/rbi/oursprivacy_ingest/internal/transport/base_client.rbi +305 -0
- data/rbi/oursprivacy_ingest/internal/transport/pooled_net_requester.rbi +80 -0
- data/rbi/oursprivacy_ingest/internal/type/array_of.rbi +108 -0
- data/rbi/oursprivacy_ingest/internal/type/base_model.rbi +316 -0
- data/rbi/oursprivacy_ingest/internal/type/base_page.rbi +43 -0
- data/rbi/oursprivacy_ingest/internal/type/boolean.rbi +58 -0
- data/rbi/oursprivacy_ingest/internal/type/converter.rbi +225 -0
- data/rbi/oursprivacy_ingest/internal/type/enum.rbi +82 -0
- data/rbi/oursprivacy_ingest/internal/type/file_input.rbi +59 -0
- data/rbi/oursprivacy_ingest/internal/type/hash_of.rbi +108 -0
- data/rbi/oursprivacy_ingest/internal/type/request_parameters.rbi +33 -0
- data/rbi/oursprivacy_ingest/internal/type/union.rbi +134 -0
- data/rbi/oursprivacy_ingest/internal/type/unknown.rbi +58 -0
- data/rbi/oursprivacy_ingest/internal/util.rbi +487 -0
- data/rbi/oursprivacy_ingest/internal.rbi +18 -0
- data/rbi/oursprivacy_ingest/models/track_event_params.rbi +1072 -0
- data/rbi/oursprivacy_ingest/models/track_event_response.rbi +71 -0
- data/rbi/oursprivacy_ingest/models/visitor_upsert_params.rbi +1035 -0
- data/rbi/oursprivacy_ingest/models/visitor_upsert_response.rbi +71 -0
- data/rbi/oursprivacy_ingest/models.rbi +7 -0
- data/rbi/oursprivacy_ingest/request_options.rbi +64 -0
- data/rbi/oursprivacy_ingest/resources/track.rbi +74 -0
- data/rbi/oursprivacy_ingest/resources/visitor.rbi +58 -0
- data/rbi/oursprivacy_ingest/version.rbi +5 -0
- data/sig/oursprivacy_ingest/client.rbs +25 -0
- data/sig/oursprivacy_ingest/errors.rbs +117 -0
- data/sig/oursprivacy_ingest/file_part.rbs +21 -0
- data/sig/oursprivacy_ingest/internal/transport/base_client.rbs +131 -0
- data/sig/oursprivacy_ingest/internal/transport/pooled_net_requester.rbs +45 -0
- data/sig/oursprivacy_ingest/internal/type/array_of.rbs +48 -0
- data/sig/oursprivacy_ingest/internal/type/base_model.rbs +106 -0
- data/sig/oursprivacy_ingest/internal/type/base_page.rbs +24 -0
- data/sig/oursprivacy_ingest/internal/type/boolean.rbs +26 -0
- data/sig/oursprivacy_ingest/internal/type/converter.rbs +79 -0
- data/sig/oursprivacy_ingest/internal/type/enum.rbs +32 -0
- data/sig/oursprivacy_ingest/internal/type/file_input.rbs +25 -0
- data/sig/oursprivacy_ingest/internal/type/hash_of.rbs +48 -0
- data/sig/oursprivacy_ingest/internal/type/request_parameters.rbs +20 -0
- data/sig/oursprivacy_ingest/internal/type/union.rbs +52 -0
- data/sig/oursprivacy_ingest/internal/type/unknown.rbs +26 -0
- data/sig/oursprivacy_ingest/internal/util.rbs +185 -0
- data/sig/oursprivacy_ingest/internal.rbs +10 -0
- data/sig/oursprivacy_ingest/models/track_event_params.rbs +673 -0
- data/sig/oursprivacy_ingest/models/track_event_response.rbs +28 -0
- data/sig/oursprivacy_ingest/models/visitor_upsert_params.rbs +653 -0
- data/sig/oursprivacy_ingest/models/visitor_upsert_response.rbs +28 -0
- data/sig/oursprivacy_ingest/models.rbs +5 -0
- data/sig/oursprivacy_ingest/request_options.rbs +36 -0
- data/sig/oursprivacy_ingest/resources/track.rbs +21 -0
- data/sig/oursprivacy_ingest/resources/visitor.rbs +17 -0
- data/sig/oursprivacy_ingest/version.rbs +3 -0
- metadata +146 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
module Models
|
|
5
|
+
# @see OursprivacyIngest::Resources::Visitor#upsert
|
|
6
|
+
class VisitorUpsertResponse < OursprivacyIngest::Internal::Type::BaseModel
|
|
7
|
+
# @!attribute success
|
|
8
|
+
#
|
|
9
|
+
# @return [Boolean, OursprivacyIngest::Models::VisitorUpsertResponse::Success]
|
|
10
|
+
required :success, enum: -> { OursprivacyIngest::Models::VisitorUpsertResponse::Success }
|
|
11
|
+
|
|
12
|
+
# @!method initialize(success:)
|
|
13
|
+
# @param success [Boolean, OursprivacyIngest::Models::VisitorUpsertResponse::Success]
|
|
14
|
+
|
|
15
|
+
# @see OursprivacyIngest::Models::VisitorUpsertResponse#success
|
|
16
|
+
module Success
|
|
17
|
+
extend OursprivacyIngest::Internal::Type::Enum
|
|
18
|
+
|
|
19
|
+
TRUE = true
|
|
20
|
+
|
|
21
|
+
# @!method self.values
|
|
22
|
+
# @return [Array<Boolean>]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
[
|
|
5
|
+
OursprivacyIngest::Internal::Type::BaseModel,
|
|
6
|
+
*OursprivacyIngest::Internal::Type::BaseModel.subclasses
|
|
7
|
+
].each do |cls|
|
|
8
|
+
cls.define_sorbet_constant!(:OrHash) { T.type_alias { T.any(cls, OursprivacyIngest::Internal::AnyHash) } }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
OursprivacyIngest::Internal::Util.walk_namespaces(OursprivacyIngest::Models).each do |mod|
|
|
12
|
+
case mod
|
|
13
|
+
in OursprivacyIngest::Internal::Type::Enum | OursprivacyIngest::Internal::Type::Union
|
|
14
|
+
mod.constants.each do |name|
|
|
15
|
+
case mod.const_get(name)
|
|
16
|
+
in true | false
|
|
17
|
+
mod.define_sorbet_constant!(:TaggedBoolean) { T.type_alias { T::Boolean } }
|
|
18
|
+
mod.define_sorbet_constant!(:OrBoolean) { T.type_alias { T::Boolean } }
|
|
19
|
+
in Integer
|
|
20
|
+
mod.define_sorbet_constant!(:TaggedInteger) { T.type_alias { Integer } }
|
|
21
|
+
mod.define_sorbet_constant!(:OrInteger) { T.type_alias { Integer } }
|
|
22
|
+
in Float
|
|
23
|
+
mod.define_sorbet_constant!(:TaggedFloat) { T.type_alias { Float } }
|
|
24
|
+
mod.define_sorbet_constant!(:OrFloat) { T.type_alias { Float } }
|
|
25
|
+
in Symbol
|
|
26
|
+
mod.define_sorbet_constant!(:TaggedSymbol) { T.type_alias { Symbol } }
|
|
27
|
+
mod.define_sorbet_constant!(:OrSymbol) { T.type_alias { T.any(Symbol, String) } }
|
|
28
|
+
else
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
else
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
OursprivacyIngest::Internal::Util.walk_namespaces(OursprivacyIngest::Models)
|
|
36
|
+
.lazy
|
|
37
|
+
.grep(OursprivacyIngest::Internal::Type::Union)
|
|
38
|
+
.each do |mod|
|
|
39
|
+
const = :Variants
|
|
40
|
+
next if mod.sorbet_constant_defined?(const)
|
|
41
|
+
|
|
42
|
+
mod.define_sorbet_constant!(const) { T.type_alias { mod.to_sorbet_type } }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
TrackEventParams = OursprivacyIngest::Models::TrackEventParams
|
|
46
|
+
|
|
47
|
+
VisitorUpsertParams = OursprivacyIngest::Models::VisitorUpsertParams
|
|
48
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
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 < OursprivacyIngest::Internal::Type::BaseModel
|
|
10
|
+
# @api private
|
|
11
|
+
#
|
|
12
|
+
# @param opts [OursprivacyIngest::RequestOptions, Hash{Symbol=>Object}]
|
|
13
|
+
#
|
|
14
|
+
# @raise [ArgumentError]
|
|
15
|
+
def self.validate!(opts)
|
|
16
|
+
case opts
|
|
17
|
+
in OursprivacyIngest::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,
|
|
41
|
+
OursprivacyIngest::Internal::Type::HashOf[OursprivacyIngest::Internal::Type::ArrayOf[String]]
|
|
42
|
+
|
|
43
|
+
# @!attribute extra_headers
|
|
44
|
+
# Extra headers to send with the request. These are `.merged`’d into any
|
|
45
|
+
# `extra_headers` given at the client level.
|
|
46
|
+
#
|
|
47
|
+
# @return [Hash{String=>String, nil}, nil]
|
|
48
|
+
optional :extra_headers, OursprivacyIngest::Internal::Type::HashOf[String, nil?: true]
|
|
49
|
+
|
|
50
|
+
# @!attribute extra_body
|
|
51
|
+
# Extra data to send with the request. These are deep merged into any data
|
|
52
|
+
# generated as part of the normal request.
|
|
53
|
+
#
|
|
54
|
+
# @return [Object, nil]
|
|
55
|
+
optional :extra_body,
|
|
56
|
+
OursprivacyIngest::Internal::Type::HashOf[OursprivacyIngest::Internal::Type::Unknown]
|
|
57
|
+
|
|
58
|
+
# @!attribute max_retries
|
|
59
|
+
# Maximum number of retries to attempt after a failed initial request.
|
|
60
|
+
#
|
|
61
|
+
# @return [Integer, nil]
|
|
62
|
+
optional :max_retries, Integer
|
|
63
|
+
|
|
64
|
+
# @!attribute timeout
|
|
65
|
+
# Request timeout in seconds.
|
|
66
|
+
#
|
|
67
|
+
# @return [Float, nil]
|
|
68
|
+
optional :timeout, Float
|
|
69
|
+
|
|
70
|
+
# @!method initialize(values = {})
|
|
71
|
+
# Returns a new instance of RequestOptions.
|
|
72
|
+
#
|
|
73
|
+
# @param values [Hash{Symbol=>Object}]
|
|
74
|
+
|
|
75
|
+
define_sorbet_constant!(:OrHash) do
|
|
76
|
+
T.type_alias { T.any(OursprivacyIngest::RequestOptions, OursprivacyIngest::Internal::AnyHash) }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
module Resources
|
|
5
|
+
class Track
|
|
6
|
+
# Some parameter documentations has been truncated, see
|
|
7
|
+
# {OursprivacyIngest::Models::TrackEventParams} for more details.
|
|
8
|
+
#
|
|
9
|
+
# Track events from your server. Please include at least one of: userId,
|
|
10
|
+
# externalId, or email. These properties help us associate events with existing
|
|
11
|
+
# users. For all fields, null values unset the property and undefined values do
|
|
12
|
+
# not unset existing properties.
|
|
13
|
+
#
|
|
14
|
+
# @overload event(token:, event:, default_properties: nil, distinct_id: nil, email: nil, event_properties: nil, external_id: nil, time: nil, user_id: nil, user_properties: nil, request_options: {})
|
|
15
|
+
#
|
|
16
|
+
# @param token [String] The token for your Ours Privacy Source. You can find this in the Ours dashboard.
|
|
17
|
+
#
|
|
18
|
+
# @param event [String] The name of the event you're tracking. This must be whitelisted in the Ours dash
|
|
19
|
+
#
|
|
20
|
+
# @param default_properties [OursprivacyIngest::Models::TrackEventParams::DefaultProperties, nil] These properties are used throughout the Ours app to pass known values onto dest
|
|
21
|
+
#
|
|
22
|
+
# @param distinct_id [String, nil] A unique identifier for the event. This helps prevent duplicate events.
|
|
23
|
+
#
|
|
24
|
+
# @param email [String, nil] The email address of a user. We will associate this event with the user or creat
|
|
25
|
+
#
|
|
26
|
+
# @param event_properties [Hash{Symbol=>Object, nil}, nil] Any additional event properties you want to pass along.
|
|
27
|
+
#
|
|
28
|
+
# @param external_id [String, nil] The externalId (the ID in your system) of a user. We will associate this event w
|
|
29
|
+
#
|
|
30
|
+
# @param time [Float, nil] The time at which the event occurred in milliseconds since UTC epoch. The time m
|
|
31
|
+
#
|
|
32
|
+
# @param user_id [String, nil] The Ours user id stored in local storage and cookies on your web properties. If
|
|
33
|
+
#
|
|
34
|
+
# @param user_properties [OursprivacyIngest::Models::TrackEventParams::UserProperties, nil] Properties to set on the visitor. (optional) You can also update these propertie
|
|
35
|
+
#
|
|
36
|
+
# @param request_options [OursprivacyIngest::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
37
|
+
#
|
|
38
|
+
# @return [OursprivacyIngest::Models::TrackEventResponse]
|
|
39
|
+
#
|
|
40
|
+
# @see OursprivacyIngest::Models::TrackEventParams
|
|
41
|
+
def event(params)
|
|
42
|
+
parsed, options = OursprivacyIngest::TrackEventParams.dump_request(params)
|
|
43
|
+
path = @client.base_url_overridden? ? "track" : "https://api.oursprivacy.com/api/v1/track"
|
|
44
|
+
@client.request(
|
|
45
|
+
method: :post,
|
|
46
|
+
path: path,
|
|
47
|
+
body: parsed,
|
|
48
|
+
model: OursprivacyIngest::Models::TrackEventResponse,
|
|
49
|
+
options: options
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @api private
|
|
54
|
+
#
|
|
55
|
+
# @param client [OursprivacyIngest::Client]
|
|
56
|
+
def initialize(client:)
|
|
57
|
+
@client = client
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
module Resources
|
|
5
|
+
class Visitor
|
|
6
|
+
# Some parameter documentations has been truncated, see
|
|
7
|
+
# {OursprivacyIngest::Models::VisitorUpsertParams} for more details.
|
|
8
|
+
#
|
|
9
|
+
# Define visitor properties on an existing visitor or create a new visitor. Note:
|
|
10
|
+
# This does not fire an event. If you want to fire an event, use the track method
|
|
11
|
+
# and include properties for the visitor.
|
|
12
|
+
#
|
|
13
|
+
# @overload upsert(token:, user_properties:, default_properties: nil, email: nil, external_id: nil, user_id: nil, request_options: {})
|
|
14
|
+
#
|
|
15
|
+
# @param token [String] The token for your Ours Privacy Source. You can find this in the Ours dashboard.
|
|
16
|
+
#
|
|
17
|
+
# @param user_properties [OursprivacyIngest::Models::VisitorUpsertParams::UserProperties] User properties to associate with this user. The existing user properties will b
|
|
18
|
+
#
|
|
19
|
+
# @param default_properties [OursprivacyIngest::Models::VisitorUpsertParams::DefaultProperties, nil] These properties are used throughout the Ours app to pass known values onto dest
|
|
20
|
+
#
|
|
21
|
+
# @param email [String, nil] The email address of a user. We will associate this event with the user or creat
|
|
22
|
+
#
|
|
23
|
+
# @param external_id [String, nil] The externalId (the ID in your system) of a user. We will associate this event w
|
|
24
|
+
#
|
|
25
|
+
# @param user_id [String, nil] The Ours user id stored in local storage and cookies on your web properties. If
|
|
26
|
+
#
|
|
27
|
+
# @param request_options [OursprivacyIngest::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
28
|
+
#
|
|
29
|
+
# @return [OursprivacyIngest::Models::VisitorUpsertResponse]
|
|
30
|
+
#
|
|
31
|
+
# @see OursprivacyIngest::Models::VisitorUpsertParams
|
|
32
|
+
def upsert(params)
|
|
33
|
+
parsed, options = OursprivacyIngest::VisitorUpsertParams.dump_request(params)
|
|
34
|
+
path = @client.base_url_overridden? ? "identify" : "https://api.oursprivacy.com/api/v1/identify"
|
|
35
|
+
@client.request(
|
|
36
|
+
method: :post,
|
|
37
|
+
path: path,
|
|
38
|
+
body: parsed,
|
|
39
|
+
model: OursprivacyIngest::Models::VisitorUpsertResponse,
|
|
40
|
+
options: options
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @api private
|
|
45
|
+
#
|
|
46
|
+
# @param client [OursprivacyIngest::Client]
|
|
47
|
+
def initialize(client:)
|
|
48
|
+
@client = client
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Standard libraries.
|
|
4
|
+
# rubocop:disable Lint/RedundantRequireStatement
|
|
5
|
+
require "English"
|
|
6
|
+
require "cgi"
|
|
7
|
+
require "date"
|
|
8
|
+
require "erb"
|
|
9
|
+
require "etc"
|
|
10
|
+
require "json"
|
|
11
|
+
require "net/http"
|
|
12
|
+
require "pathname"
|
|
13
|
+
require "rbconfig"
|
|
14
|
+
require "securerandom"
|
|
15
|
+
require "set"
|
|
16
|
+
require "stringio"
|
|
17
|
+
require "time"
|
|
18
|
+
require "uri"
|
|
19
|
+
# rubocop:enable Lint/RedundantRequireStatement
|
|
20
|
+
|
|
21
|
+
# We already ship the preferred sorbet manifests in the package itself.
|
|
22
|
+
# `tapioca` currently does not offer us a way to opt out of unnecessary compilation.
|
|
23
|
+
if Object.const_defined?(:Tapioca) &&
|
|
24
|
+
caller.chain([$PROGRAM_NAME]).chain(ARGV).any?(/tapioca/) &&
|
|
25
|
+
ARGV.none?(/dsl/)
|
|
26
|
+
return
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Gems.
|
|
30
|
+
require "connection_pool"
|
|
31
|
+
|
|
32
|
+
# Package files.
|
|
33
|
+
require_relative "oursprivacy_ingest/version"
|
|
34
|
+
require_relative "oursprivacy_ingest/internal/util"
|
|
35
|
+
require_relative "oursprivacy_ingest/internal/type/converter"
|
|
36
|
+
require_relative "oursprivacy_ingest/internal/type/unknown"
|
|
37
|
+
require_relative "oursprivacy_ingest/internal/type/boolean"
|
|
38
|
+
require_relative "oursprivacy_ingest/internal/type/file_input"
|
|
39
|
+
require_relative "oursprivacy_ingest/internal/type/enum"
|
|
40
|
+
require_relative "oursprivacy_ingest/internal/type/union"
|
|
41
|
+
require_relative "oursprivacy_ingest/internal/type/array_of"
|
|
42
|
+
require_relative "oursprivacy_ingest/internal/type/hash_of"
|
|
43
|
+
require_relative "oursprivacy_ingest/internal/type/base_model"
|
|
44
|
+
require_relative "oursprivacy_ingest/internal/type/base_page"
|
|
45
|
+
require_relative "oursprivacy_ingest/internal/type/request_parameters"
|
|
46
|
+
require_relative "oursprivacy_ingest/internal"
|
|
47
|
+
require_relative "oursprivacy_ingest/request_options"
|
|
48
|
+
require_relative "oursprivacy_ingest/file_part"
|
|
49
|
+
require_relative "oursprivacy_ingest/errors"
|
|
50
|
+
require_relative "oursprivacy_ingest/internal/transport/base_client"
|
|
51
|
+
require_relative "oursprivacy_ingest/internal/transport/pooled_net_requester"
|
|
52
|
+
require_relative "oursprivacy_ingest/client"
|
|
53
|
+
require_relative "oursprivacy_ingest/models/track_event_params"
|
|
54
|
+
require_relative "oursprivacy_ingest/models/track_event_response"
|
|
55
|
+
require_relative "oursprivacy_ingest/models/visitor_upsert_params"
|
|
56
|
+
require_relative "oursprivacy_ingest/models/visitor_upsert_response"
|
|
57
|
+
require_relative "oursprivacy_ingest/models"
|
|
58
|
+
require_relative "oursprivacy_ingest/resources/track"
|
|
59
|
+
require_relative "oursprivacy_ingest/resources/visitor"
|
data/manifest.yaml
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
class Client < OursprivacyIngest::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
|
+
sig { returns(OursprivacyIngest::Resources::Track) }
|
|
14
|
+
attr_reader :track
|
|
15
|
+
|
|
16
|
+
sig { returns(OursprivacyIngest::Resources::Visitor) }
|
|
17
|
+
attr_reader :visitor
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
sig { returns(T::Boolean) }
|
|
21
|
+
def base_url_overridden?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Creates and returns a new client for interacting with the API.
|
|
25
|
+
sig do
|
|
26
|
+
params(
|
|
27
|
+
base_url: T.nilable(String),
|
|
28
|
+
max_retries: Integer,
|
|
29
|
+
timeout: Float,
|
|
30
|
+
initial_retry_delay: Float,
|
|
31
|
+
max_retry_delay: Float
|
|
32
|
+
).returns(T.attached_class)
|
|
33
|
+
end
|
|
34
|
+
def self.new(
|
|
35
|
+
# Override the default base URL for the API, e.g.,
|
|
36
|
+
# `"https://api.example.com/v2/"`. Defaults to `ENV["OURS_PRIVACY_BASE_URL"]`
|
|
37
|
+
base_url: ENV["OURS_PRIVACY_BASE_URL"],
|
|
38
|
+
# Max number of retries to attempt after a failed retryable request.
|
|
39
|
+
max_retries: OursprivacyIngest::Client::DEFAULT_MAX_RETRIES,
|
|
40
|
+
timeout: OursprivacyIngest::Client::DEFAULT_TIMEOUT_IN_SECONDS,
|
|
41
|
+
initial_retry_delay: OursprivacyIngest::Client::DEFAULT_INITIAL_RETRY_DELAY,
|
|
42
|
+
max_retry_delay: OursprivacyIngest::Client::DEFAULT_MAX_RETRY_DELAY
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
module Errors
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
sig { returns(T.nilable(StandardError)) }
|
|
7
|
+
attr_accessor :cause
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class ConversionError < OursprivacyIngest::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 < OursprivacyIngest::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 < OursprivacyIngest::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 < OursprivacyIngest::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 < OursprivacyIngest::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 < OursprivacyIngest::Errors::APIStatusError
|
|
174
|
+
HTTP_STATUS = 400
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
class AuthenticationError < OursprivacyIngest::Errors::APIStatusError
|
|
178
|
+
HTTP_STATUS = 401
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class PermissionDeniedError < OursprivacyIngest::Errors::APIStatusError
|
|
182
|
+
HTTP_STATUS = 403
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
class NotFoundError < OursprivacyIngest::Errors::APIStatusError
|
|
186
|
+
HTTP_STATUS = 404
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
class ConflictError < OursprivacyIngest::Errors::APIStatusError
|
|
190
|
+
HTTP_STATUS = 409
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
class UnprocessableEntityError < OursprivacyIngest::Errors::APIStatusError
|
|
194
|
+
HTTP_STATUS = 422
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
class RateLimitError < OursprivacyIngest::Errors::APIStatusError
|
|
198
|
+
HTTP_STATUS = 429
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
class InternalServerError < OursprivacyIngest::Errors::APIStatusError
|
|
202
|
+
HTTP_STATUS = T.let((500..), T::Range[Integer])
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module OursprivacyIngest
|
|
4
|
+
class FilePart
|
|
5
|
+
sig { returns(T.any(Pathname, StringIO, IO, String)) }
|
|
6
|
+
attr_reader :content
|
|
7
|
+
|
|
8
|
+
sig { returns(T.nilable(String)) }
|
|
9
|
+
attr_reader :content_type
|
|
10
|
+
|
|
11
|
+
sig { returns(T.nilable(String)) }
|
|
12
|
+
attr_reader :filename
|
|
13
|
+
|
|
14
|
+
# @api private
|
|
15
|
+
sig { returns(String) }
|
|
16
|
+
private def read
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
sig { params(a: T.anything).returns(String) }
|
|
20
|
+
def to_json(*a)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
sig { params(a: T.anything).returns(String) }
|
|
24
|
+
def to_yaml(*a)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
sig do
|
|
28
|
+
params(
|
|
29
|
+
content: T.any(Pathname, StringIO, IO, String),
|
|
30
|
+
filename: T.nilable(T.any(Pathname, String)),
|
|
31
|
+
content_type: T.nilable(String)
|
|
32
|
+
).returns(T.attached_class)
|
|
33
|
+
end
|
|
34
|
+
def self.new(content, filename: nil, content_type: nil)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|