statsig 1.30.0 → 1.32.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/statsig_user.rb CHANGED
@@ -1,65 +1,49 @@
1
- # typed: true
2
-
3
- require 'sorbet-runtime'
4
1
  require 'json'
2
+ require 'constants'
5
3
 
6
4
  ##
7
5
  # The user object to be evaluated against your Statsig configurations (gates/experiments/dynamic configs).
8
6
  class StatsigUser
9
- extend T::Sig
10
7
 
11
- sig { returns(T.any(String, NilClass)) }
12
8
  # An identifier for this user. Evaluated against the User ID criteria. (https://docs.statsig.com/feature-gates/conditions#userid)
13
9
  attr_accessor :user_id
14
10
 
15
- sig { returns(T.any(String, NilClass)) }
16
11
  # An identifier for this user. Evaluated against the Email criteria. (https://docs.statsig.com/feature-gates/conditions#email)
17
12
  attr_accessor :email
18
13
 
19
- sig { returns(T.any(String, NilClass)) }
20
14
  # An IP address associated with this user. Evaluated against the IP Address criteria. (https://docs.statsig.com/feature-gates/conditions#ip)
21
15
  attr_accessor :ip
22
16
 
23
- sig { returns(T.any(String, NilClass)) }
24
17
  # A user agent string associated with this user. Evaluated against Browser Version and Name (https://docs.statsig.com/feature-gates/conditions#browser-version)
25
18
  attr_accessor :user_agent
26
19
 
27
- sig { returns(T.any(String, NilClass)) }
28
20
  # The country code associated with this user (e.g New Zealand => NZ). Evaluated against the Country criteria. (https://docs.statsig.com/feature-gates/conditions#country)
29
21
  attr_accessor :country
30
22
 
31
- sig { returns(T.any(String, NilClass)) }
32
23
  # An locale for this user.
33
24
  attr_accessor :locale
34
25
 
35
- sig { returns(T.any(String, NilClass)) }
36
26
  # The current app version the user is interacting with. Evaluated against the App Version criteria. (https://docs.statsig.com/feature-gates/conditions#app-version)
37
27
  attr_accessor :app_version
38
28
 
39
- sig { returns(T.any(T::Hash[String, String], NilClass)) }
40
29
  # A Hash you can use to set environment variables that apply to this user. e.g. { "tier" => "development" }
41
30
  attr_accessor :statsig_environment
42
31
 
43
- sig { returns(T.any(T::Hash[String, String], NilClass)) }
44
32
  # Any Custom IDs to associated with the user. (See https://docs.statsig.com/guides/experiment-on-custom-id-types)
45
33
  attr_accessor :custom_ids
46
34
 
47
- sig { returns(T.any(T::Hash[String, String], NilClass)) }
48
35
  # Any value you wish to use in evaluation, but do not want logged with events, can be stored in this field.
49
36
  attr_accessor :private_attributes
50
37
 
51
- sig { returns(T.any(T::Hash[String, T.untyped], NilClass)) }
52
38
  def custom
53
39
  @custom
54
40
  end
55
41
 
56
- sig { params(value: T.any(T::Hash[String, T.untyped], NilClass)).void }
57
42
  # Any custom fields for this user. Evaluated against the Custom criteria. (https://docs.statsig.com/feature-gates/conditions#custom)
58
43
  def custom=(value)
59
44
  @custom = value.is_a?(Hash) ? value : Hash.new
60
45
  end
61
46
 
62
- sig { params(user_hash: T.any(T::Hash[T.any(String, Symbol), T.untyped], NilClass)).void }
63
47
  def initialize(user_hash)
64
48
  the_hash = user_hash
65
49
  begin
@@ -83,55 +67,56 @@ class StatsigUser
83
67
 
84
68
  def serialize(for_logging)
85
69
  hash = {
86
- 'userID' => @user_id,
87
- 'email' => @email,
88
- 'ip' => @ip,
89
- 'userAgent' => @user_agent,
90
- 'country' => @country,
91
- 'locale' => @locale,
92
- 'appVersion' => @app_version,
93
- 'custom' => @custom,
94
- 'statsigEnvironment' => @statsig_environment,
95
- 'privateAttributes' => @private_attributes,
96
- 'customIDs' => @custom_ids,
70
+ :userID => @user_id,
71
+ :email => @email,
72
+ :ip => @ip,
73
+ :userAgent => @user_agent,
74
+ :country => @country,
75
+ :locale => @locale,
76
+ :appVersion => @app_version,
77
+ :custom => @custom,
78
+ :statsigEnvironment => @statsig_environment,
79
+ :privateAttributes => @private_attributes,
80
+ :customIDs => @custom_ids,
97
81
  }
98
82
  if for_logging
99
- hash.delete('privateAttributes')
83
+ hash.delete(:privateAttributes)
100
84
  end
101
85
  hash.compact
102
86
  end
103
87
 
104
- def to_hash_without_stable_id()
88
+ def to_hash_without_stable_id
105
89
  hash = {}
90
+
106
91
  if @user_id != nil
107
- hash['userID'] = @user_id
92
+ hash[:userID] = @user_id
108
93
  end
109
94
  if @email != nil
110
- hash['email'] = @email
95
+ hash[:email] = @email
111
96
  end
112
97
  if @ip != nil
113
- hash['ip'] = @ip
98
+ hash[:ip] = @ip
114
99
  end
115
100
  if @user_agent != nil
116
- hash['userAgent'] = @user_agent
101
+ hash[:userAgent] = @user_agent
117
102
  end
118
103
  if @country != nil
119
- hash['country'] = @country
104
+ hash[:country] = @country
120
105
  end
121
106
  if @locale != nil
122
- hash['locale'] = @locale
107
+ hash[:locale] = @locale
123
108
  end
124
109
  if @app_version != nil
125
- hash['appVersion'] = @app_version
110
+ hash[:appVersion] = @app_version
126
111
  end
127
112
  if @custom != nil
128
- hash['custom'] = Statsig::HashUtils.sortHash(@custom)
113
+ hash[:custom] = Statsig::HashUtils.sortHash(@custom)
129
114
  end
130
115
  if @statsig_environment != nil
131
- hash['statsigEnvironment'] = @statsig_environment.clone.sort_by { |key| key }.to_h
116
+ hash[:statsigEnvironment] = @statsig_environment.clone.sort_by { |key| key }.to_h
132
117
  end
133
118
  if @private_attributes != nil
134
- hash['privateAttributes'] = Statsig::HashUtils.sortHash(@private_attributes)
119
+ hash[:privateAttributes] = Statsig::HashUtils.sortHash(@private_attributes)
135
120
  end
136
121
  custom_ids = {}
137
122
  if @custom_ids != nil
@@ -140,32 +125,12 @@ class StatsigUser
140
125
  custom_ids.delete("stableID")
141
126
  end
142
127
  end
143
- hash['customIDs'] = custom_ids.sort_by { |key| key }.to_h
128
+ hash[:customIDs] = custom_ids.sort_by { |key| key }.to_h
144
129
  return Statsig::HashUtils.djb2ForHash(hash.sort_by { |key| key }.to_h)
145
130
  end
146
131
 
147
- def value_lookup
148
- {
149
- 'userID' => @user_id,
150
- 'userid' => @user_id,
151
- 'user_id' => @user_id,
152
- 'email' => @email,
153
- 'ip' => @ip,
154
- 'userAgent' => @user_agent,
155
- 'useragent' => @user_agent,
156
- 'user_agent' => @user_agent,
157
- 'country' => @country,
158
- 'locale' => @locale,
159
- 'appVersion' => @app_version,
160
- 'appversion' => @app_version,
161
- 'app_version' => @app_version,
162
- 'custom' => @custom,
163
- 'privateAttributes' => @private_attributes,
164
- }
165
- end
166
-
167
132
  def get_unit_id(id_type)
168
- if id_type.is_a?(String) && id_type.downcase != 'userid'
133
+ if id_type.is_a?(String) && id_type != Statsig::Const::CML_USER_ID
169
134
  return nil unless @custom_ids.is_a? Hash
170
135
 
171
136
  return @custom_ids[id_type] || @custom_ids[id_type.downcase]
@@ -175,12 +140,6 @@ class StatsigUser
175
140
 
176
141
  private
177
142
 
178
- sig {
179
- params(user_hash: T.any(T::Hash[T.any(String, Symbol), T.untyped], NilClass),
180
- keys: T::Array[Symbol],
181
- type: T.untyped)
182
- .returns(T.untyped)
183
- }
184
143
  # Pulls fields from the user hash via Symbols and Strings
185
144
  def from_hash(user_hash, keys, type)
186
145
  if user_hash.nil?
data/lib/ua_parser.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: true
1
+
2
2
  require 'user_agent_parser'
3
3
 
4
4
  module UAParser
data/lib/uri_helper.rb CHANGED
@@ -1,24 +1,16 @@
1
- # typed: true
2
-
3
- require 'sorbet-runtime'
4
-
5
1
  class URIHelper
6
2
  class URIBuilder
7
- extend T::Sig
8
3
 
9
- sig { returns(StatsigOptions) }
10
4
  attr_accessor :options
11
5
 
12
- sig { params(options: StatsigOptions).void }
13
6
  def initialize(options)
14
7
  @options = options
15
8
  end
16
9
 
17
- sig { params(endpoint: String).returns(String) }
18
10
  def build_url(endpoint)
19
11
  api = @options.api_url_base
20
12
  if endpoint.include?('download_config_specs')
21
- api = T.must(@options.api_url_download_config_specs)
13
+ api = @options.api_url_download_config_specs
22
14
  end
23
15
  unless api.end_with?('/')
24
16
  api += '/'
@@ -1,27 +1,17 @@
1
- # typed: false
2
-
3
- require 'sorbet-runtime'
4
1
  require 'statsig_options'
5
2
 
6
3
  module Statsig
7
- UserPersistedValues = T.type_alias { T::Hash[String, Hash] }
8
-
9
4
  class UserPersistentStorageUtils
10
- extend T::Sig
11
5
 
12
- sig { returns(T::Hash[String, UserPersistedValues]) }
13
6
  attr_accessor :cache
14
7
 
15
- sig { returns(T.nilable(Interfaces::IUserPersistentStorage)) }
16
8
  attr_accessor :storage
17
9
 
18
- sig { params(options: StatsigOptions).void }
19
10
  def initialize(options)
20
11
  @storage = options.user_persistent_storage
21
12
  @cache = {}
22
13
  end
23
14
 
24
- sig { params(user: StatsigUser, id_type: String).returns(T.nilable(UserPersistedValues)) }
25
15
  def get_user_persisted_values(user, id_type)
26
16
  key = self.class.get_storage_key(user, id_type)
27
17
  return @cache[key] unless @cache[key].nil?
@@ -29,7 +19,6 @@ module Statsig
29
19
  return load_from_storage(key)
30
20
  end
31
21
 
32
- sig { params(key: String).returns(T.nilable(UserPersistedValues)) }
33
22
  def load_from_storage(key)
34
23
  return if @storage.nil?
35
24
 
@@ -50,7 +39,6 @@ module Statsig
50
39
  return nil
51
40
  end
52
41
 
53
- sig { params(user: StatsigUser, id_type: String, user_persisted_values: UserPersistedValues).void }
54
42
  def save_to_storage(user, id_type, user_persisted_values)
55
43
  return if @storage.nil?
56
44
 
@@ -65,7 +53,6 @@ module Statsig
65
53
  end
66
54
  end
67
55
 
68
- sig { params(user: StatsigUser, id_type: String, config_name: String).void }
69
56
  def remove_experiment_from_storage(user, id_type, config_name)
70
57
  persisted_values = get_user_persisted_values(user, id_type)
71
58
  unless persisted_values.nil?
@@ -74,7 +61,6 @@ module Statsig
74
61
  end
75
62
  end
76
63
 
77
- sig { params(user_persisted_values: T.nilable(UserPersistedValues), config_name: String, evaluation: ConfigResult).void }
78
64
  def add_evaluation_to_user_persisted_values(user_persisted_values, config_name, evaluation)
79
65
  if user_persisted_values.nil?
80
66
  user_persisted_values = {}
@@ -84,21 +70,18 @@ module Statsig
84
70
 
85
71
  private
86
72
 
87
- sig { params(values_string: String).returns(T.nilable(UserPersistedValues)) }
88
73
  def self.parse(values_string)
89
74
  return JSON.parse(values_string)
90
75
  rescue JSON::ParserError
91
76
  return nil
92
77
  end
93
78
 
94
- sig { params(values_object: UserPersistedValues).returns(T.nilable(String)) }
95
79
  def self.stringify(values_object)
96
80
  return JSON.generate(values_object)
97
81
  rescue StandardError
98
82
  return nil
99
83
  end
100
84
 
101
- sig { params(user: StatsigUser, id_type: String).returns(String) }
102
85
  def self.get_storage_key(user, id_type)
103
86
  "#{user.get_unit_id(id_type)}:#{id_type}"
104
87
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statsig
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.30.0
4
+ version: 1.32.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Statsig, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-05 00:00:00.000000000 Z
11
+ date: 2024-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -322,8 +322,10 @@ executables: []
322
322
  extensions: []
323
323
  extra_rdoc_files: []
324
324
  files:
325
+ - lib/api_config.rb
325
326
  - lib/client_initialize_helpers.rb
326
327
  - lib/config_result.rb
328
+ - lib/constants.rb
327
329
  - lib/diagnostics.rb
328
330
  - lib/dynamic_config.rb
329
331
  - lib/error_boundary.rb