posthog-ruby 2.3.1 → 2.4.1
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 +4 -4
- data/lib/posthog/client.rb +31 -0
- data/lib/posthog/feature_flags.rb +90 -20
- data/lib/posthog/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b0fe64cbfa7e53a76fdd9241fb1eff4b428babe557ae8ee1ce62c2a287e42a5
|
4
|
+
data.tar.gz: afc4e5c842f2b38e8c2f9fa0247dfb4a01db2021ffccbb8d3e62f6acc904bf88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23134246b45ee9c507e4fb52aca1539ecf2af4b036976f7f5a6c6fbe2dafc20f3a3da677014019f5366243b10f5c2b29521dc81e4911ea2820d966d21b5c54ea
|
7
|
+
data.tar.gz: 72dea55baf64ca45b28d5642e8881004a6f0f2dc5f9f43e30d27a3392949a3994a16d805ce20e7bf2ac9f94ddce3d1817df33b152664b0dc582170281f03587d
|
data/lib/posthog/client.rb
CHANGED
@@ -174,6 +174,7 @@ class PostHog
|
|
174
174
|
# group_properties: {"organization": {"name": "PostHog", "employees": 11}}
|
175
175
|
# ```
|
176
176
|
def get_feature_flag(key, distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false, send_feature_flag_events: true)
|
177
|
+
person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
177
178
|
feature_flag_response, flag_was_locally_evaluated = @feature_flags_poller.get_feature_flag(key, distinct_id, groups, person_properties, group_properties, only_evaluate_locally)
|
178
179
|
|
179
180
|
feature_flag_reported_key = "#{key}_#{feature_flag_response}"
|
@@ -204,6 +205,7 @@ class PostHog
|
|
204
205
|
#
|
205
206
|
# @return [Hash] String (not symbol) key value pairs of flag and their values
|
206
207
|
def get_all_flags(distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false)
|
208
|
+
person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
207
209
|
return @feature_flags_poller.get_all_flags(distinct_id, groups, person_properties, group_properties, only_evaluate_locally)
|
208
210
|
end
|
209
211
|
|
@@ -218,6 +220,7 @@ class PostHog
|
|
218
220
|
# @option [Boolean] only_evaluate_locally
|
219
221
|
#
|
220
222
|
def get_feature_flag_payload(key, distinct_id, match_value: nil, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false)
|
223
|
+
person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
221
224
|
@feature_flags_poller.get_feature_flag_payload(key, distinct_id, match_value, groups, person_properties, group_properties, only_evaluate_locally)
|
222
225
|
end
|
223
226
|
|
@@ -230,6 +233,7 @@ class PostHog
|
|
230
233
|
# @option [Boolean] only_evaluate_locally
|
231
234
|
#
|
232
235
|
def get_all_flags_and_payloads(distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false)
|
236
|
+
person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
233
237
|
@feature_flags_poller.get_all_flags_and_payloads(distinct_id, groups, person_properties, group_properties, only_evaluate_locally)
|
234
238
|
end
|
235
239
|
|
@@ -288,5 +292,32 @@ class PostHog
|
|
288
292
|
def worker_running?
|
289
293
|
@worker_thread && @worker_thread.alive?
|
290
294
|
end
|
295
|
+
|
296
|
+
def add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
297
|
+
|
298
|
+
groups ||= {}
|
299
|
+
person_properties ||= {}
|
300
|
+
group_properties ||= {}
|
301
|
+
|
302
|
+
symbolize_keys! groups
|
303
|
+
symbolize_keys! person_properties
|
304
|
+
symbolize_keys! group_properties
|
305
|
+
|
306
|
+
group_properties.each do |key, value|
|
307
|
+
symbolize_keys! value
|
308
|
+
end
|
309
|
+
|
310
|
+
all_person_properties = { "$current_distinct_id" => distinct_id }.merge(person_properties)
|
311
|
+
|
312
|
+
all_group_properties = {}
|
313
|
+
if groups
|
314
|
+
groups.each do |group_name, group_key|
|
315
|
+
all_group_properties[group_name] = {
|
316
|
+
"$group_key" => group_key}.merge(group_properties&.dig(group_name) || {})
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
return all_person_properties, all_group_properties
|
321
|
+
end
|
291
322
|
end
|
292
323
|
end
|
@@ -205,6 +205,52 @@ class PostHog
|
|
205
205
|
|
206
206
|
# Class methods
|
207
207
|
|
208
|
+
def self.compare(lhs, rhs, operator)
|
209
|
+
if operator == "gt"
|
210
|
+
return lhs > rhs
|
211
|
+
elsif operator == "gte"
|
212
|
+
return lhs >= rhs
|
213
|
+
elsif operator == "lt"
|
214
|
+
return lhs < rhs
|
215
|
+
elsif operator == "lte"
|
216
|
+
return lhs <= rhs
|
217
|
+
else
|
218
|
+
raise "Invalid operator: #{operator}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.relative_date_parse_for_feature_flag_matching(value)
|
223
|
+
match = /^([0-9]+)([a-z])$/.match(value)
|
224
|
+
parsed_dt = DateTime.now.new_offset(0)
|
225
|
+
if match
|
226
|
+
number = match[1].to_i
|
227
|
+
|
228
|
+
if number >= 10000
|
229
|
+
# Guard against overflow, disallow numbers greater than 10_000
|
230
|
+
return nil
|
231
|
+
end
|
232
|
+
|
233
|
+
interval = match[2]
|
234
|
+
if interval == "h"
|
235
|
+
parsed_dt = parsed_dt - (number/24r)
|
236
|
+
elsif interval == "d"
|
237
|
+
parsed_dt = parsed_dt.prev_day(number)
|
238
|
+
elsif interval == "w"
|
239
|
+
parsed_dt = parsed_dt.prev_day(number*7)
|
240
|
+
elsif interval == "m"
|
241
|
+
parsed_dt = parsed_dt.prev_month(number)
|
242
|
+
elsif interval == "y"
|
243
|
+
parsed_dt = parsed_dt.prev_year(number)
|
244
|
+
else
|
245
|
+
return nil
|
246
|
+
end
|
247
|
+
parsed_dt
|
248
|
+
else
|
249
|
+
nil
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
208
254
|
def self.match_property(property, property_values)
|
209
255
|
# only looks for matches where key exists in property_values
|
210
256
|
# doesn't support operator is_not_set
|
@@ -225,11 +271,21 @@ class PostHog
|
|
225
271
|
override_value = property_values[key]
|
226
272
|
|
227
273
|
case operator
|
228
|
-
when 'exact'
|
229
|
-
value.is_a?(Array)
|
230
|
-
|
231
|
-
|
232
|
-
|
274
|
+
when 'exact', 'is_not'
|
275
|
+
if value.is_a?(Array)
|
276
|
+
values_stringified = value.map { |val| val.to_s.downcase }
|
277
|
+
if operator == 'exact'
|
278
|
+
return values_stringified.any?(override_value.to_s.downcase)
|
279
|
+
else
|
280
|
+
return !values_stringified.any?(override_value.to_s.downcase)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
if operator == 'exact'
|
284
|
+
value.to_s.downcase == override_value.to_s.downcase
|
285
|
+
else
|
286
|
+
value.to_s.downcase != override_value.to_s.downcase
|
287
|
+
end
|
288
|
+
when 'is_set'
|
233
289
|
property_values.key?(key)
|
234
290
|
when 'icontains'
|
235
291
|
override_value.to_s.downcase.include?(value.to_s.downcase)
|
@@ -239,25 +295,39 @@ class PostHog
|
|
239
295
|
PostHog::Utils.is_valid_regex(value.to_s) && !Regexp.new(value.to_s).match(override_value.to_s).nil?
|
240
296
|
when 'not_regex'
|
241
297
|
PostHog::Utils.is_valid_regex(value.to_s) && Regexp.new(value.to_s).match(override_value.to_s).nil?
|
242
|
-
when 'gt'
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
298
|
+
when 'gt', 'gte', 'lt', 'lte'
|
299
|
+
parsed_value = nil
|
300
|
+
begin
|
301
|
+
parsed_value = Float(value)
|
302
|
+
rescue StandardError => e
|
303
|
+
end
|
304
|
+
if !parsed_value.nil? && !override_value.nil?
|
305
|
+
if override_value.is_a?(String)
|
306
|
+
self.compare(override_value, value.to_s, operator)
|
307
|
+
else
|
308
|
+
self.compare(override_value, parsed_value, operator)
|
309
|
+
end
|
310
|
+
else
|
311
|
+
self.compare(override_value.to_s, value.to_s, operator)
|
312
|
+
end
|
313
|
+
when 'is_date_before', 'is_date_after', 'is_relative_date_before', 'is_relative_date_after'
|
314
|
+
if operator == 'is_relative_date_before' || operator == 'is_relative_date_after'
|
315
|
+
parsed_date = self.relative_date_parse_for_feature_flag_matching(value.to_s)
|
316
|
+
override_date = PostHog::Utils.convert_to_datetime(override_value.to_s)
|
255
317
|
else
|
318
|
+
parsed_date = PostHog::Utils.convert_to_datetime(value.to_s)
|
319
|
+
override_date = PostHog::Utils.convert_to_datetime(override_value.to_s)
|
320
|
+
end
|
321
|
+
if !parsed_date
|
322
|
+
raise InconclusiveMatchError.new("Invalid date format")
|
323
|
+
end
|
324
|
+
if operator == 'is_date_before' or operator == 'is_relative_date_before'
|
325
|
+
return override_date < parsed_date
|
326
|
+
elsif operator == 'is_date_after' or operator == 'is_relative_date_after'
|
256
327
|
return override_date > parsed_date
|
257
328
|
end
|
258
329
|
else
|
259
|
-
|
260
|
-
false
|
330
|
+
raise InconclusiveMatchError.new("Unknown operator: #{operator}")
|
261
331
|
end
|
262
332
|
end
|
263
333
|
|
data/lib/posthog/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: posthog-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|