flagsmith 3.1.1 → 4.0.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 +4 -4
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +12 -19
- data/.ruby-version +1 -1
- data/Gemfile.lock +52 -60
- data/example/Gemfile +1 -1
- data/example/Gemfile.lock +25 -20
- data/flagsmith.gemspec +6 -5
- data/lib/flagsmith/engine/features/models.rb +2 -4
- data/lib/flagsmith/engine/segments/constants.rb +3 -1
- data/lib/flagsmith/engine/segments/evaluator.rb +8 -5
- data/lib/flagsmith/engine/segments/models.rb +11 -6
- data/lib/flagsmith/sdk/config.rb +14 -3
- data/lib/flagsmith/sdk/models/flags.rb +23 -7
- data/lib/flagsmith/sdk/models/segments.rb +2 -1
- data/lib/flagsmith/sdk/offline_handlers.rb +17 -0
- data/lib/flagsmith/version.rb +1 -1
- data/lib/flagsmith.rb +95 -36
- metadata +20 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7e45006cc3caabc6941c7daaf58f339940cb1ea1fc3ec76be0a7897d84212fa
|
|
4
|
+
data.tar.gz: 32703828745194ea1befb791266e592e888c7fac888fd35c4cc6b6e9b6f3e204
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa77df821acafa8ccc9d0580845573b47fe0287c1937a7f8200d08532f559d77af1c41e6862a52a0ab90fec30cc020ea63068120aa95a95da41cff2b2a48e84d
|
|
7
|
+
data.tar.gz: 25f98c085b4b8253356fbc203e5605fa6ac53930e7ac8bbe7d2be1f5ba8dc8bf0374ca9a85b57bebafb08b9e57077dcc18637fca9b9d91a758ec404398de663a
|
data/.rubocop.yml
CHANGED
|
@@ -4,8 +4,10 @@ Layout/HashAlignment:
|
|
|
4
4
|
AllowMultipleStyles: true
|
|
5
5
|
EnforcedColonStyle: key
|
|
6
6
|
AllCops:
|
|
7
|
+
TargetRubyVersion: 3.0 # Pin to flagsmith.gemspec required_ruby_version
|
|
7
8
|
NewCops: enable
|
|
8
9
|
SuggestExtensions: false
|
|
9
10
|
Exclude:
|
|
10
11
|
- 'spec/**/*'
|
|
11
12
|
- 'example/**/*'
|
|
13
|
+
- 'vendor/**/*'
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,29 +1,22 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
|
-
# `rubocop --auto-gen-config
|
|
3
|
-
# on
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2023-07-20 10:26:52 UTC using RuboCop version 1.54.2.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
10
|
-
# Configuration parameters:
|
|
11
|
-
#
|
|
12
|
-
|
|
9
|
+
# Offense count: 6
|
|
10
|
+
# Configuration parameters: EnforcedStyle, AllowedGems, Include.
|
|
11
|
+
# SupportedStyles: Gemfile, gems.rb, gemspec
|
|
12
|
+
# Include: **/*.gemspec, **/Gemfile, **/gems.rb
|
|
13
|
+
Gemspec/DevelopmentDependencies:
|
|
13
14
|
Exclude:
|
|
14
|
-
- '
|
|
15
|
-
|
|
16
|
-
# Offense count: 1
|
|
17
|
-
# Configuration parameters: AllowedMethods.
|
|
18
|
-
# AllowedMethods: respond_to_missing?
|
|
19
|
-
Style/OptionalBooleanParameter:
|
|
20
|
-
Exclude:
|
|
21
|
-
- 'lib/flagsmith.rb'
|
|
15
|
+
- 'flagsmith.gemspec'
|
|
22
16
|
|
|
23
|
-
# Offense count:
|
|
24
|
-
#
|
|
25
|
-
# Configuration parameters:
|
|
17
|
+
# Offense count: 4
|
|
18
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
19
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
|
26
20
|
# URISchemes: http, https
|
|
27
21
|
Layout/LineLength:
|
|
28
|
-
|
|
29
|
-
- 'flagsmith.gemspec'
|
|
22
|
+
Max: 183
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.1.4
|
data/Gemfile.lock
CHANGED
|
@@ -1,84 +1,75 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
flagsmith (
|
|
5
|
-
faraday
|
|
4
|
+
flagsmith (4.0.0)
|
|
5
|
+
faraday (>= 2.0.1)
|
|
6
6
|
faraday-retry
|
|
7
|
-
faraday_middleware
|
|
8
7
|
semantic
|
|
9
8
|
|
|
10
9
|
GEM
|
|
11
10
|
remote: https://rubygems.org/
|
|
12
11
|
specs:
|
|
13
|
-
ast (2.4.
|
|
12
|
+
ast (2.4.2)
|
|
13
|
+
byebug (11.1.3)
|
|
14
14
|
coderay (1.1.3)
|
|
15
|
-
diff-lcs (1.
|
|
16
|
-
faraday (
|
|
17
|
-
faraday-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
faraday
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
faraday-rack (~> 1.0)
|
|
26
|
-
faraday-retry (~> 1.0)
|
|
27
|
-
ruby2_keywords (>= 0.0.4)
|
|
28
|
-
faraday-em_http (1.0.0)
|
|
29
|
-
faraday-em_synchrony (1.0.0)
|
|
30
|
-
faraday-excon (1.1.0)
|
|
31
|
-
faraday-httpclient (1.0.1)
|
|
32
|
-
faraday-multipart (1.0.4)
|
|
33
|
-
multipart-post (~> 2)
|
|
34
|
-
faraday-net_http (1.0.1)
|
|
35
|
-
faraday-net_http_persistent (1.2.0)
|
|
36
|
-
faraday-patron (1.0.0)
|
|
37
|
-
faraday-rack (1.0.0)
|
|
38
|
-
faraday-retry (1.0.3)
|
|
39
|
-
faraday_middleware (1.2.0)
|
|
40
|
-
faraday (~> 1.0)
|
|
41
|
-
gem-release (2.2.0)
|
|
15
|
+
diff-lcs (1.5.0)
|
|
16
|
+
faraday (2.9.0)
|
|
17
|
+
faraday-net_http (>= 2.0, < 3.2)
|
|
18
|
+
faraday-net_http (3.1.0)
|
|
19
|
+
net-http
|
|
20
|
+
faraday-retry (2.2.0)
|
|
21
|
+
faraday (~> 2.0)
|
|
22
|
+
gem-release (2.2.2)
|
|
23
|
+
json (2.7.1)
|
|
24
|
+
language_server-protocol (3.17.0.3)
|
|
42
25
|
method_source (1.0.0)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
net-http (0.4.1)
|
|
27
|
+
uri
|
|
28
|
+
parallel (1.24.0)
|
|
29
|
+
parser (3.3.0.4)
|
|
46
30
|
ast (~> 2.4.1)
|
|
47
|
-
|
|
31
|
+
racc
|
|
32
|
+
pry (0.14.2)
|
|
48
33
|
coderay (~> 1.1)
|
|
49
34
|
method_source (~> 1.0)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
rspec
|
|
59
|
-
rspec-
|
|
60
|
-
|
|
35
|
+
pry-byebug (3.10.1)
|
|
36
|
+
byebug (~> 11.0)
|
|
37
|
+
pry (>= 0.13, < 0.15)
|
|
38
|
+
racc (1.7.3)
|
|
39
|
+
rainbow (3.1.1)
|
|
40
|
+
rake (13.1.0)
|
|
41
|
+
regexp_parser (2.9.0)
|
|
42
|
+
rexml (3.2.6)
|
|
43
|
+
rspec (3.12.0)
|
|
44
|
+
rspec-core (~> 3.12.0)
|
|
45
|
+
rspec-expectations (~> 3.12.0)
|
|
46
|
+
rspec-mocks (~> 3.12.0)
|
|
47
|
+
rspec-core (3.12.2)
|
|
48
|
+
rspec-support (~> 3.12.0)
|
|
49
|
+
rspec-expectations (3.12.3)
|
|
61
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
62
|
-
rspec-support (~> 3.
|
|
63
|
-
rspec-mocks (3.
|
|
51
|
+
rspec-support (~> 3.12.0)
|
|
52
|
+
rspec-mocks (3.12.6)
|
|
64
53
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
65
|
-
rspec-support (~> 3.
|
|
66
|
-
rspec-support (3.
|
|
67
|
-
rubocop (1.
|
|
54
|
+
rspec-support (~> 3.12.0)
|
|
55
|
+
rspec-support (3.12.1)
|
|
56
|
+
rubocop (1.60.0)
|
|
57
|
+
json (~> 2.3)
|
|
58
|
+
language_server-protocol (>= 3.17.0)
|
|
68
59
|
parallel (~> 1.10)
|
|
69
|
-
parser (>=
|
|
60
|
+
parser (>= 3.3.0.2)
|
|
70
61
|
rainbow (>= 2.2.2, < 4.0)
|
|
71
62
|
regexp_parser (>= 1.8, < 3.0)
|
|
72
|
-
rexml
|
|
73
|
-
rubocop-ast (>= 1.
|
|
63
|
+
rexml (>= 3.2.5, < 4.0)
|
|
64
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
74
65
|
ruby-progressbar (~> 1.7)
|
|
75
|
-
unicode-display_width (>=
|
|
76
|
-
rubocop-ast (1.
|
|
77
|
-
parser (>= 2.
|
|
78
|
-
ruby-progressbar (1.
|
|
79
|
-
ruby2_keywords (0.0.5)
|
|
66
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
67
|
+
rubocop-ast (1.30.0)
|
|
68
|
+
parser (>= 3.2.1.0)
|
|
69
|
+
ruby-progressbar (1.13.0)
|
|
80
70
|
semantic (1.6.1)
|
|
81
|
-
unicode-display_width (
|
|
71
|
+
unicode-display_width (2.5.0)
|
|
72
|
+
uri (0.13.0)
|
|
82
73
|
|
|
83
74
|
PLATFORMS
|
|
84
75
|
ruby
|
|
@@ -88,6 +79,7 @@ DEPENDENCIES
|
|
|
88
79
|
flagsmith!
|
|
89
80
|
gem-release
|
|
90
81
|
pry
|
|
82
|
+
pry-byebug
|
|
91
83
|
rake
|
|
92
84
|
rspec
|
|
93
85
|
rubocop
|
data/example/Gemfile
CHANGED
data/example/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
flagsmith (3.
|
|
4
|
+
flagsmith (3.1.1)
|
|
5
5
|
faraday
|
|
6
6
|
faraday-retry
|
|
7
7
|
faraday_middleware
|
|
@@ -10,8 +10,8 @@ PATH
|
|
|
10
10
|
GEM
|
|
11
11
|
remote: https://rubygems.org/
|
|
12
12
|
specs:
|
|
13
|
-
addressable (2.8.
|
|
14
|
-
public_suffix (>= 2.0.2, <
|
|
13
|
+
addressable (2.8.4)
|
|
14
|
+
public_suffix (>= 2.0.2, < 6.0)
|
|
15
15
|
ast (2.4.2)
|
|
16
16
|
better_errors (2.9.1)
|
|
17
17
|
coderay (>= 1.0.0)
|
|
@@ -20,13 +20,14 @@ GEM
|
|
|
20
20
|
bigdecimal (1.4.4)
|
|
21
21
|
binding_of_caller (0.8.0)
|
|
22
22
|
debug_inspector (>= 0.0.1)
|
|
23
|
-
capybara (3.
|
|
23
|
+
capybara (3.39.0)
|
|
24
24
|
addressable
|
|
25
|
+
matrix
|
|
25
26
|
mini_mime (>= 0.1.3)
|
|
26
27
|
nokogiri (~> 1.8)
|
|
27
28
|
rack (>= 1.6.0)
|
|
28
29
|
rack-test (>= 0.6.3)
|
|
29
|
-
regexp_parser (
|
|
30
|
+
regexp_parser (>= 1.5, < 3.0)
|
|
30
31
|
xpath (~> 3.2)
|
|
31
32
|
coderay (1.1.3)
|
|
32
33
|
concurrent-ruby (1.1.10)
|
|
@@ -71,7 +72,7 @@ GEM
|
|
|
71
72
|
dry-logic (~> 0.4, >= 0.4.0)
|
|
72
73
|
dry-types (~> 0.11.0)
|
|
73
74
|
erubi (1.10.0)
|
|
74
|
-
faraday (1.10.
|
|
75
|
+
faraday (1.10.3)
|
|
75
76
|
faraday-em_http (~> 1.0)
|
|
76
77
|
faraday-em_synchrony (~> 1.0)
|
|
77
78
|
faraday-excon (~> 1.1)
|
|
@@ -87,8 +88,8 @@ GEM
|
|
|
87
88
|
faraday-em_synchrony (1.0.0)
|
|
88
89
|
faraday-excon (1.1.0)
|
|
89
90
|
faraday-httpclient (1.0.1)
|
|
90
|
-
faraday-multipart (1.0.
|
|
91
|
-
multipart-post (
|
|
91
|
+
faraday-multipart (1.0.4)
|
|
92
|
+
multipart-post (~> 2)
|
|
92
93
|
faraday-net_http (1.0.1)
|
|
93
94
|
faraday-net_http_persistent (1.2.0)
|
|
94
95
|
faraday-patron (1.0.0)
|
|
@@ -156,28 +157,31 @@ GEM
|
|
|
156
157
|
inflecto (0.0.2)
|
|
157
158
|
mail (2.7.1)
|
|
158
159
|
mini_mime (>= 0.1.1)
|
|
160
|
+
matrix (0.4.2)
|
|
159
161
|
method_source (1.0.0)
|
|
160
162
|
mini_mime (1.1.2)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
multipart-post (2.3.0)
|
|
164
|
+
nio4r (2.5.9)
|
|
165
|
+
nokogiri (1.14.3-arm64-darwin)
|
|
166
|
+
racc (~> 1.4)
|
|
167
|
+
nokogiri (1.14.3-x86_64-linux)
|
|
168
|
+
racc (~> 1.4)
|
|
166
169
|
parallel (1.20.1)
|
|
167
170
|
parser (3.1.2.0)
|
|
168
171
|
ast (~> 2.4.1)
|
|
169
172
|
pry (0.14.1)
|
|
170
173
|
coderay (~> 1.1)
|
|
171
174
|
method_source (~> 1.0)
|
|
172
|
-
public_suffix (
|
|
173
|
-
puma (
|
|
175
|
+
public_suffix (5.0.1)
|
|
176
|
+
puma (6.3.1)
|
|
174
177
|
nio4r (~> 2.0)
|
|
175
|
-
|
|
176
|
-
rack
|
|
177
|
-
|
|
178
|
+
racc (1.6.2)
|
|
179
|
+
rack (2.2.7)
|
|
180
|
+
rack-test (2.1.0)
|
|
181
|
+
rack (>= 1.3)
|
|
178
182
|
rainbow (3.1.1)
|
|
179
183
|
rake (13.0.6)
|
|
180
|
-
regexp_parser (
|
|
184
|
+
regexp_parser (2.8.0)
|
|
181
185
|
rexml (3.2.5)
|
|
182
186
|
rom (3.3.3)
|
|
183
187
|
concurrent-ruby (~> 1.0)
|
|
@@ -245,6 +249,7 @@ GEM
|
|
|
245
249
|
nokogiri (~> 1.8)
|
|
246
250
|
|
|
247
251
|
PLATFORMS
|
|
252
|
+
arm64-darwin-21
|
|
248
253
|
x86_64-linux
|
|
249
254
|
|
|
250
255
|
DEPENDENCIES
|
|
@@ -257,7 +262,7 @@ DEPENDENCIES
|
|
|
257
262
|
hanami-model (~> 1.3)
|
|
258
263
|
hanami-webconsole
|
|
259
264
|
pry
|
|
260
|
-
puma (~>
|
|
265
|
+
puma (~> 6.3)
|
|
261
266
|
rake
|
|
262
267
|
rspec
|
|
263
268
|
rubocop
|
data/flagsmith.gemspec
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
require File.expand_path('lib/flagsmith/version', __dir__)
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
|
-
spec.required_ruby_version = '>=
|
|
6
|
+
spec.required_ruby_version = '>= 3.0.0'
|
|
7
7
|
spec.name = 'flagsmith'
|
|
8
8
|
spec.version = Flagsmith::VERSION
|
|
9
|
-
spec.authors = ['Tom Stuart', 'Brian Moelk']
|
|
10
|
-
spec.email = ['tom@solidstategroup.com', 'bmoelk@gmail.com']
|
|
9
|
+
spec.authors = ['Tom Stuart', 'Brian Moelk', 'Zach Aysan']
|
|
10
|
+
spec.email = ['tom@solidstategroup.com', 'bmoelk@gmail.com', 'zachaysan@gmail.com']
|
|
11
11
|
# Specify which files should be added to the gem when it is released.
|
|
12
12
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
13
13
|
spec.files = Dir.chdir(__dir__) do
|
|
@@ -27,12 +27,13 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
spec.add_development_dependency 'bundler'
|
|
28
28
|
spec.add_development_dependency 'gem-release'
|
|
29
29
|
spec.add_development_dependency 'pry'
|
|
30
|
+
spec.add_development_dependency 'pry-byebug'
|
|
30
31
|
spec.add_development_dependency 'rake'
|
|
31
32
|
spec.add_development_dependency 'rspec'
|
|
32
33
|
spec.add_development_dependency 'rubocop'
|
|
33
34
|
|
|
34
|
-
spec.add_dependency 'faraday'
|
|
35
|
-
spec.add_dependency 'faraday_middleware'
|
|
35
|
+
spec.add_dependency 'faraday', '>= 2.0.1'
|
|
36
36
|
spec.add_dependency 'faraday-retry'
|
|
37
37
|
spec.add_dependency 'semantic'
|
|
38
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
38
39
|
end
|
|
@@ -40,9 +40,7 @@ module Flagsmith
|
|
|
40
40
|
multivariate_feature_state_values.sort.each do |multi_fs_value|
|
|
41
41
|
limit = multi_fs_value.percentage_allocation + start_percentage
|
|
42
42
|
|
|
43
|
-
if start_percentage <= percentage_value && percentage_value < limit
|
|
44
|
-
return multi_fs_value.multivariate_feature_option.value
|
|
45
|
-
end
|
|
43
|
+
return multi_fs_value.multivariate_feature_option.value if start_percentage <= percentage_value && percentage_value < limit
|
|
46
44
|
|
|
47
45
|
start_percentage = limit
|
|
48
46
|
end
|
|
@@ -165,7 +163,7 @@ module Flagsmith
|
|
|
165
163
|
attr_reader :priority
|
|
166
164
|
|
|
167
165
|
def initialize(params = {})
|
|
168
|
-
@priority = params[:priority]
|
|
166
|
+
@priority = params[:priority]&.to_i
|
|
169
167
|
end
|
|
170
168
|
end
|
|
171
169
|
end
|
|
@@ -25,6 +25,7 @@ module Flagsmith
|
|
|
25
25
|
IS_SET = 'IS_SET'
|
|
26
26
|
IS_NOT_SET = 'IS_NOT_SET'
|
|
27
27
|
MODULO = 'MODULO'
|
|
28
|
+
IN = 'IN'
|
|
28
29
|
|
|
29
30
|
CONDITION_OPERATORS = [
|
|
30
31
|
EQUAL,
|
|
@@ -37,7 +38,8 @@ module Flagsmith
|
|
|
37
38
|
NOT_EQUAL,
|
|
38
39
|
REGEX,
|
|
39
40
|
PERCENTAGE_SPLIT,
|
|
40
|
-
MODULO
|
|
41
|
+
MODULO,
|
|
42
|
+
IN
|
|
41
43
|
].freeze
|
|
42
44
|
end
|
|
43
45
|
end
|
|
@@ -36,6 +36,7 @@ module Flagsmith
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
# rubocop:disable Metrics/MethodLength
|
|
39
40
|
def traits_match_segment_rule(identity_traits, rule, segment_id, identity_id)
|
|
40
41
|
matching_block = lambda { |condition|
|
|
41
42
|
traits_match_segment_condition(identity_traits, condition, segment_id, identity_id)
|
|
@@ -44,23 +45,25 @@ module Flagsmith
|
|
|
44
45
|
matches_conditions =
|
|
45
46
|
if rule.conditions&.length&.positive?
|
|
46
47
|
rule.conditions.send(rule.matching_function, &matching_block)
|
|
47
|
-
else
|
|
48
|
+
else
|
|
49
|
+
true
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
matches_conditions &&
|
|
51
53
|
rule.rules.all? { |r| traits_match_segment_rule(identity_traits, r, segment_id, identity_id) }
|
|
52
54
|
end
|
|
55
|
+
# rubocop:enable Metrics/MethodLength
|
|
53
56
|
|
|
54
57
|
def traits_match_segment_condition(identity_traits, condition, segment_id, identity_id)
|
|
55
58
|
if condition.operator == PERCENTAGE_SPLIT
|
|
56
|
-
return hashed_percentage_for_object_ids([segment_id,
|
|
59
|
+
return hashed_percentage_for_object_ids([segment_id,
|
|
60
|
+
identity_id]) <= condition.value.to_f
|
|
57
61
|
end
|
|
58
62
|
|
|
59
63
|
trait = identity_traits.find { |t| t.key.to_s == condition.property }
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
end
|
|
65
|
+
return handle_trait_existence_conditions(trait, condition.operator) if [IS_SET,
|
|
66
|
+
IS_NOT_SET].include?(condition.operator)
|
|
64
67
|
|
|
65
68
|
return condition.match_trait_value?(trait.trait_value) if trait
|
|
66
69
|
|
|
@@ -56,10 +56,9 @@ module Flagsmith
|
|
|
56
56
|
|
|
57
57
|
def match_trait_value?(trait_value)
|
|
58
58
|
# handle some exceptions
|
|
59
|
-
if @value.is_a?(String) && @value.match?(/:semver$/)
|
|
60
|
-
trait_value = Semantic::Version.new(trait_value.gsub(/:semver$/, ''))
|
|
61
|
-
end
|
|
59
|
+
trait_value = Semantic::Version.new(trait_value.gsub(/:semver$/, '')) if @value.is_a?(String) && @value.match?(/:semver$/)
|
|
62
60
|
|
|
61
|
+
return match_in_value(trait_value) if @operator == IN
|
|
63
62
|
return match_modulo_value(trait_value) if @operator == MODULO
|
|
64
63
|
|
|
65
64
|
type_as_trait_value = format_to_type_of(trait_value)
|
|
@@ -73,8 +72,8 @@ module Flagsmith
|
|
|
73
72
|
{
|
|
74
73
|
'String' => ->(v) { v.to_s },
|
|
75
74
|
'Semantic::Version' => ->(v) { Semantic::Version.new(v.to_s.gsub(/:semver$/, '')) },
|
|
76
|
-
'TrueClass' => ->(v) { ['True', 'true', 'TRUE', true, 1, '1'].include?(v)
|
|
77
|
-
'FalseClass' => ->(v) { ['False', 'false', 'FALSE', false, 0, '0'].include?(v)
|
|
75
|
+
'TrueClass' => ->(v) { ['True', 'true', 'TRUE', true, 1, '1'].include?(v) },
|
|
76
|
+
'FalseClass' => ->(v) { !['False', 'false', 'FALSE', false, 0, '0'].include?(v) },
|
|
78
77
|
'Integer' => ->(v) { v.to_i },
|
|
79
78
|
'Float' => ->(v) { v.to_f }
|
|
80
79
|
}[input.class.to_s]
|
|
@@ -83,11 +82,17 @@ module Flagsmith
|
|
|
83
82
|
|
|
84
83
|
def match_modulo_value(trait_value)
|
|
85
84
|
divisor, remainder = @value.split('|')
|
|
86
|
-
trait_value.is_a?(Numeric) && trait_value % divisor.to_f == remainder.to_f
|
|
85
|
+
trait_value.is_a?(Numeric) && trait_value % divisor.to_f == remainder.to_f # rubocop:disable Lint/FloatComparison
|
|
87
86
|
rescue StandardError
|
|
88
87
|
false
|
|
89
88
|
end
|
|
90
89
|
|
|
90
|
+
def match_in_value(trait_value)
|
|
91
|
+
return @value.split(',').include?(trait_value.to_s) if trait_value.is_a?(String) || trait_value.is_a?(Integer)
|
|
92
|
+
|
|
93
|
+
false
|
|
94
|
+
end
|
|
95
|
+
|
|
91
96
|
class << self
|
|
92
97
|
def build(json)
|
|
93
98
|
new(**json.slice(:operator, :value).merge(property: json[:property_]))
|
data/lib/flagsmith/sdk/config.rb
CHANGED
|
@@ -6,7 +6,8 @@ module Flagsmith
|
|
|
6
6
|
DEFAULT_API_URL = 'https://edge.api.flagsmith.com/api/v1/'
|
|
7
7
|
OPTIONS = %i[
|
|
8
8
|
environment_key api_url custom_headers request_timeout_seconds enable_local_evaluation
|
|
9
|
-
environment_refresh_interval_seconds retries enable_analytics default_flag_handler
|
|
9
|
+
environment_refresh_interval_seconds retries enable_analytics default_flag_handler
|
|
10
|
+
offline_mode offline_handler logger
|
|
10
11
|
].freeze
|
|
11
12
|
|
|
12
13
|
# Available Configs
|
|
@@ -31,8 +32,12 @@ module Flagsmith
|
|
|
31
32
|
# API to power flag analytics charts
|
|
32
33
|
# +default_flag_handler+ - ruby block which will be used in the case where
|
|
33
34
|
# flags cannot be retrieved from the API or
|
|
34
|
-
# a non
|
|
35
|
+
# a non-existent feature is requested.
|
|
35
36
|
# The searched feature#name will be passed to the block as an argument.
|
|
37
|
+
# +offline_mode+ - if enabled, uses a locally provided file and
|
|
38
|
+
# bypasses requests to the api.
|
|
39
|
+
# +offline_handler+ - A file object that contains a JSON serialization of
|
|
40
|
+
# the entire environment, project, flags, etc.
|
|
36
41
|
# +logger+ - Pass your logger, default is Logger.new($stdout)
|
|
37
42
|
#
|
|
38
43
|
attr_reader(*OPTIONS)
|
|
@@ -51,6 +56,10 @@ module Flagsmith
|
|
|
51
56
|
@enable_analytics
|
|
52
57
|
end
|
|
53
58
|
|
|
59
|
+
def offline_mode?
|
|
60
|
+
@offline_mode
|
|
61
|
+
end
|
|
62
|
+
|
|
54
63
|
def environment_flags_url
|
|
55
64
|
'flags/'
|
|
56
65
|
end
|
|
@@ -78,13 +87,15 @@ module Flagsmith
|
|
|
78
87
|
@environment_refresh_interval_seconds = opts.fetch(:environment_refresh_interval_seconds, 60)
|
|
79
88
|
@enable_analytics = opts.fetch(:enable_analytics, false)
|
|
80
89
|
@default_flag_handler = opts[:default_flag_handler]
|
|
90
|
+
@offline_mode = opts.fetch(:offline_mode, false)
|
|
91
|
+
@offline_handler = opts[:offline_handler]
|
|
81
92
|
@logger = options.fetch(:logger, Logger.new($stdout).tap { |l| l.level = :debug })
|
|
82
93
|
end
|
|
83
94
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
84
95
|
|
|
85
96
|
class << self
|
|
86
97
|
def environment_key
|
|
87
|
-
ENV
|
|
98
|
+
ENV.fetch('FLAGSMITH_ENVIRONMENT_KEY', nil)
|
|
88
99
|
end
|
|
89
100
|
end
|
|
90
101
|
end
|
|
@@ -4,32 +4,34 @@ module Flagsmith
|
|
|
4
4
|
module Flags
|
|
5
5
|
class NotFound < StandardError; end
|
|
6
6
|
|
|
7
|
+
# Base data class for the flag entity
|
|
7
8
|
class BaseFlag
|
|
8
9
|
include Comparable
|
|
9
10
|
|
|
10
11
|
attr_reader :enabled, :value, :default
|
|
11
|
-
|
|
12
|
+
|
|
12
13
|
def initialize(enabled:, value:, default:)
|
|
13
14
|
@enabled = enabled
|
|
14
15
|
@value = value
|
|
15
16
|
@default = default
|
|
16
17
|
end
|
|
17
|
-
|
|
18
|
+
|
|
18
19
|
def enabled?
|
|
19
20
|
enabled
|
|
20
21
|
end
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
alias is_default default
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
# Flag class to be used by default handler logic
|
|
25
27
|
class DefaultFlag < BaseFlag
|
|
26
28
|
def initialize(enabled:, value:)
|
|
27
29
|
super(enabled: enabled, value: value, default: true)
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
# 'live' Flag class as returned by API or local evaluation
|
|
31
34
|
class Flag < BaseFlag
|
|
32
|
-
|
|
33
35
|
attr_reader :feature_name, :feature_id
|
|
34
36
|
|
|
35
37
|
def initialize(feature_name:, enabled:, value:, feature_id:)
|
|
@@ -77,15 +79,18 @@ module Flagsmith
|
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
|
|
82
|
+
# Implementation of a class to hold a collection of flags.
|
|
83
|
+
# Implements methods for working with the list to avoid requesting flags for each feature evaluation.
|
|
80
84
|
class Collection
|
|
81
85
|
include Enumerable
|
|
82
86
|
|
|
83
|
-
attr_reader :flags, :default_flag_handler, :analytics_processor
|
|
87
|
+
attr_reader :flags, :default_flag_handler, :analytics_processor, :offline_handler
|
|
84
88
|
|
|
85
|
-
def initialize(flags = {}, analytics_processor: nil, default_flag_handler: nil)
|
|
89
|
+
def initialize(flags = {}, analytics_processor: nil, default_flag_handler: nil, offline_handler: nil)
|
|
86
90
|
@flags = flags
|
|
87
91
|
@default_flag_handler = default_flag_handler
|
|
88
92
|
@analytics_processor = analytics_processor
|
|
93
|
+
@offline_handler = offline_handler
|
|
89
94
|
end
|
|
90
95
|
|
|
91
96
|
def each(&block)
|
|
@@ -115,16 +120,27 @@ module Flagsmith
|
|
|
115
120
|
end
|
|
116
121
|
alias get_feature_value feature_value
|
|
117
122
|
|
|
123
|
+
def get_flag_from_offline_handler(key)
|
|
124
|
+
@offline_handler.environment.feature_states.each do |feature_state|
|
|
125
|
+
return Flag.from_feature_state_model(feature_state, nil) if key == Flagsmith::Flags::Collection.normalize_key(feature_state.feature.name)
|
|
126
|
+
end
|
|
127
|
+
raise Flagsmith::Flags::NotFound,
|
|
128
|
+
"Feature does not exist: #{key}, offline_handler did not find a flag in this case."
|
|
129
|
+
end
|
|
130
|
+
|
|
118
131
|
# Get a specific flag given the feature name.
|
|
119
132
|
# :param feature_name: the name of the feature to retrieve the flag for.
|
|
120
133
|
# :return: BaseFlag object.
|
|
121
134
|
# :raises FlagsmithClientError: if feature doesn't exist
|
|
122
135
|
def get_flag(feature_name)
|
|
123
136
|
key = Flagsmith::Flags::Collection.normalize_key(feature_name)
|
|
137
|
+
|
|
124
138
|
flag = flags.fetch(key)
|
|
125
139
|
@analytics_processor.track_feature(flag.feature_name) if @analytics_processor && flag.feature_id
|
|
126
140
|
flag
|
|
127
141
|
rescue KeyError
|
|
142
|
+
return get_flag_from_offline_handler(key) if @offline_handler
|
|
143
|
+
|
|
128
144
|
return @default_flag_handler.call(feature_name) if @default_flag_handler
|
|
129
145
|
|
|
130
146
|
raise Flagsmith::Flags::NotFound,
|
|
@@ -159,7 +175,7 @@ module Flagsmith
|
|
|
159
175
|
def from_feature_state_models(feature_states, identity_id: nil, **args)
|
|
160
176
|
to_flag_object = lambda { |feature_state, acc|
|
|
161
177
|
acc[normalize_key(feature_state.feature.name)] =
|
|
162
|
-
|
|
178
|
+
Flagsmith::Flags::Flag.from_feature_state_model(feature_state, identity_id)
|
|
163
179
|
}
|
|
164
180
|
|
|
165
181
|
new(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Flagsmith
|
|
4
|
+
module OfflineHandlers
|
|
5
|
+
# Provides the offline_handler to the Flagsmith::Client.
|
|
6
|
+
class LocalFileHandler
|
|
7
|
+
attr_reader :environment
|
|
8
|
+
|
|
9
|
+
def initialize(environment_document_path)
|
|
10
|
+
environment_file = File.open(environment_document_path)
|
|
11
|
+
|
|
12
|
+
data = JSON.parse(environment_file.read, symbolize_names: true)
|
|
13
|
+
@environment = Flagsmith::Engine::Environment.build(data)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/flagsmith/version.rb
CHANGED
data/lib/flagsmith.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'pry'
|
|
4
|
+
require 'pry-byebug'
|
|
5
|
+
|
|
3
6
|
require 'faraday'
|
|
4
7
|
require 'faraday/retry'
|
|
5
|
-
require 'faraday_middleware'
|
|
6
8
|
|
|
7
9
|
# Hash#slice was added in ruby version 2.5
|
|
8
10
|
# This is the patch to use slice in earler versions
|
|
@@ -16,13 +18,14 @@ require 'flagsmith/sdk/intervals'
|
|
|
16
18
|
require 'flagsmith/sdk/pooling_manager'
|
|
17
19
|
require 'flagsmith/sdk/models/flags'
|
|
18
20
|
require 'flagsmith/sdk/models/segments'
|
|
21
|
+
require 'flagsmith/sdk/offline_handlers'
|
|
19
22
|
|
|
20
23
|
require 'flagsmith/engine/core'
|
|
21
24
|
|
|
22
25
|
# no-doc
|
|
23
26
|
module Flagsmith
|
|
24
27
|
# Ruby client for flagsmith.com
|
|
25
|
-
class Client
|
|
28
|
+
class Client # rubocop:disable Metrics/ClassLength
|
|
26
29
|
extend Forwardable
|
|
27
30
|
# A Flagsmith client.
|
|
28
31
|
#
|
|
@@ -44,7 +47,9 @@ module Flagsmith
|
|
|
44
47
|
# Available Configs.
|
|
45
48
|
#
|
|
46
49
|
# :environment_key, :api_url, :custom_headers, :request_timeout_seconds, :enable_local_evaluation,
|
|
47
|
-
# :environment_refresh_interval_seconds, :retries, :enable_analytics, :default_flag_handler
|
|
50
|
+
# :environment_refresh_interval_seconds, :retries, :enable_analytics, :default_flag_handler,
|
|
51
|
+
# :offline_mode, :offline_handler
|
|
52
|
+
#
|
|
48
53
|
# You can see full description in the Flagsmith::Config
|
|
49
54
|
|
|
50
55
|
attr_reader :config, :environment
|
|
@@ -55,10 +60,24 @@ module Flagsmith
|
|
|
55
60
|
@_mutex = Mutex.new
|
|
56
61
|
@config = Flagsmith::Config.new(config)
|
|
57
62
|
|
|
63
|
+
validate_offline_mode!
|
|
64
|
+
|
|
58
65
|
api_client
|
|
59
66
|
analytics_processor
|
|
60
67
|
environment_data_polling_manager
|
|
61
68
|
engine
|
|
69
|
+
load_offline_handler
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def validate_offline_mode!
|
|
73
|
+
if @config.offline_mode? && !@config.offline_handler
|
|
74
|
+
raise Flagsmith::ClientError,
|
|
75
|
+
'The offline_mode config param requires a matching offline_handler.'
|
|
76
|
+
end
|
|
77
|
+
return unless @config.offline_handler && @config.default_flag_handler
|
|
78
|
+
|
|
79
|
+
raise Flagsmith::ClientError,
|
|
80
|
+
'Cannot use offline_handler and default_flag_handler at the same time.'
|
|
62
81
|
end
|
|
63
82
|
|
|
64
83
|
def api_client
|
|
@@ -79,6 +98,10 @@ module Flagsmith
|
|
|
79
98
|
)
|
|
80
99
|
end
|
|
81
100
|
|
|
101
|
+
def load_offline_handler
|
|
102
|
+
@environment = offline_handler.environment if offline_handler
|
|
103
|
+
end
|
|
104
|
+
|
|
82
105
|
def environment_data_polling_manager
|
|
83
106
|
return nil unless @config.local_evaluation?
|
|
84
107
|
|
|
@@ -103,7 +126,7 @@ module Flagsmith
|
|
|
103
126
|
# Get all the default for flags for the current environment.
|
|
104
127
|
# @returns Flags object holding all the flags for the current environment.
|
|
105
128
|
def get_environment_flags # rubocop:disable Naming/AccessorMethodName
|
|
106
|
-
return environment_flags_from_document if @config.local_evaluation?
|
|
129
|
+
return environment_flags_from_document if @config.local_evaluation? || @config.offline_mode
|
|
107
130
|
|
|
108
131
|
environment_flags_from_api
|
|
109
132
|
end
|
|
@@ -153,13 +176,13 @@ module Flagsmith
|
|
|
153
176
|
|
|
154
177
|
def get_identity_segments(identifier, traits = {})
|
|
155
178
|
unless environment
|
|
156
|
-
raise Flagsmith::ClientError,
|
|
157
|
-
|
|
179
|
+
raise Flagsmith::ClientError,
|
|
180
|
+
'Local evaluation or offline handler is required to obtain identity segments.'
|
|
158
181
|
end
|
|
159
182
|
|
|
160
183
|
identity_model = build_identity_model(identifier, traits)
|
|
161
184
|
segment_models = engine.get_identity_segments(environment, identity_model)
|
|
162
|
-
|
|
185
|
+
segment_models.map { |sm| Flagsmith::Segments::Segment.new(id: sm.id, name: sm.name) }.compact
|
|
163
186
|
end
|
|
164
187
|
|
|
165
188
|
private
|
|
@@ -168,7 +191,8 @@ module Flagsmith
|
|
|
168
191
|
Flagsmith::Flags::Collection.from_feature_state_models(
|
|
169
192
|
engine.get_environment_feature_states(environment),
|
|
170
193
|
analytics_processor: analytics_processor,
|
|
171
|
-
default_flag_handler: default_flag_handler
|
|
194
|
+
default_flag_handler: default_flag_handler,
|
|
195
|
+
offline_handler: offline_handler
|
|
172
196
|
)
|
|
173
197
|
end
|
|
174
198
|
|
|
@@ -178,45 +202,80 @@ module Flagsmith
|
|
|
178
202
|
Flagsmith::Flags::Collection.from_feature_state_models(
|
|
179
203
|
engine.get_identity_feature_states(environment, identity_model),
|
|
180
204
|
analytics_processor: analytics_processor,
|
|
181
|
-
default_flag_handler: default_flag_handler
|
|
205
|
+
default_flag_handler: default_flag_handler,
|
|
206
|
+
offline_handler: offline_handler
|
|
182
207
|
)
|
|
183
208
|
end
|
|
184
209
|
|
|
210
|
+
# rubocop:disable Metrics/MethodLength
|
|
185
211
|
def environment_flags_from_api
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
212
|
+
if offline_handler
|
|
213
|
+
begin
|
|
214
|
+
process_environment_flags_from_api
|
|
215
|
+
rescue StandardError
|
|
216
|
+
environment_flags_from_document
|
|
217
|
+
end
|
|
218
|
+
else
|
|
219
|
+
begin
|
|
220
|
+
process_environment_flags_from_api
|
|
221
|
+
rescue StandardError
|
|
222
|
+
if default_flag_handler
|
|
223
|
+
return Flagsmith::Flags::Collection.new(
|
|
224
|
+
{},
|
|
225
|
+
default_flag_handler: default_flag_handler
|
|
226
|
+
)
|
|
227
|
+
end
|
|
228
|
+
raise
|
|
229
|
+
end
|
|
194
230
|
end
|
|
195
231
|
end
|
|
232
|
+
# rubocop:enable Metrics/MethodLength
|
|
233
|
+
|
|
234
|
+
def process_environment_flags_from_api
|
|
235
|
+
api_flags = api_client.get(@config.environment_flags_url).body
|
|
236
|
+
api_flags = api_flags.select { |flag| flag[:feature_segment].nil? }
|
|
237
|
+
Flagsmith::Flags::Collection.from_api(
|
|
238
|
+
api_flags,
|
|
239
|
+
analytics_processor: analytics_processor,
|
|
240
|
+
default_flag_handler: default_flag_handler,
|
|
241
|
+
offline_handler: offline_handler
|
|
242
|
+
)
|
|
243
|
+
end
|
|
196
244
|
|
|
245
|
+
# rubocop:disable Metrics/MethodLength
|
|
197
246
|
def get_identity_flags_from_api(identifier, traits = {})
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
247
|
+
if offline_handler
|
|
248
|
+
begin
|
|
249
|
+
process_identity_flags_from_api(identifier, traits)
|
|
250
|
+
rescue StandardError
|
|
251
|
+
get_identity_flags_from_document(identifier, traits)
|
|
252
|
+
end
|
|
253
|
+
else
|
|
254
|
+
begin
|
|
255
|
+
process_identity_flags_from_api(identifier, traits)
|
|
256
|
+
rescue StandardError
|
|
257
|
+
if default_flag_handler
|
|
258
|
+
return Flagsmith::Flags::Collection.new(
|
|
259
|
+
{},
|
|
260
|
+
default_flag_handler: default_flag_handler
|
|
261
|
+
)
|
|
262
|
+
end
|
|
263
|
+
raise
|
|
264
|
+
end
|
|
207
265
|
end
|
|
208
266
|
end
|
|
267
|
+
# rubocop:enable Metrics/MethodLength
|
|
209
268
|
|
|
210
|
-
def
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
269
|
+
def process_identity_flags_from_api(identifier, traits = {})
|
|
270
|
+
data = generate_identities_data(identifier, traits)
|
|
271
|
+
json_response = api_client.post(@config.identities_url, data.to_json).body
|
|
272
|
+
|
|
273
|
+
Flagsmith::Flags::Collection.from_api(
|
|
274
|
+
json_response[:flags],
|
|
275
|
+
analytics_processor: analytics_processor,
|
|
276
|
+
default_flag_handler: default_flag_handler,
|
|
277
|
+
offline_handler: offline_handler
|
|
278
|
+
)
|
|
220
279
|
end
|
|
221
280
|
|
|
222
281
|
def build_identity_model(identifier, traits = {})
|
metadata
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flagsmith
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tom Stuart
|
|
8
8
|
- Brian Moelk
|
|
9
|
-
|
|
9
|
+
- Zach Aysan
|
|
10
|
+
autorequire:
|
|
10
11
|
bindir: exe
|
|
11
12
|
cert_chain: []
|
|
12
|
-
date:
|
|
13
|
+
date: 2024-01-30 00:00:00.000000000 Z
|
|
13
14
|
dependencies:
|
|
14
15
|
- !ruby/object:Gem::Dependency
|
|
15
16
|
name: bundler
|
|
@@ -54,7 +55,7 @@ dependencies:
|
|
|
54
55
|
- !ruby/object:Gem::Version
|
|
55
56
|
version: '0'
|
|
56
57
|
- !ruby/object:Gem::Dependency
|
|
57
|
-
name:
|
|
58
|
+
name: pry-byebug
|
|
58
59
|
requirement: !ruby/object:Gem::Requirement
|
|
59
60
|
requirements:
|
|
60
61
|
- - ">="
|
|
@@ -68,7 +69,7 @@ dependencies:
|
|
|
68
69
|
- !ruby/object:Gem::Version
|
|
69
70
|
version: '0'
|
|
70
71
|
- !ruby/object:Gem::Dependency
|
|
71
|
-
name:
|
|
72
|
+
name: rake
|
|
72
73
|
requirement: !ruby/object:Gem::Requirement
|
|
73
74
|
requirements:
|
|
74
75
|
- - ">="
|
|
@@ -82,7 +83,7 @@ dependencies:
|
|
|
82
83
|
- !ruby/object:Gem::Version
|
|
83
84
|
version: '0'
|
|
84
85
|
- !ruby/object:Gem::Dependency
|
|
85
|
-
name:
|
|
86
|
+
name: rspec
|
|
86
87
|
requirement: !ruby/object:Gem::Requirement
|
|
87
88
|
requirements:
|
|
88
89
|
- - ">="
|
|
@@ -96,13 +97,13 @@ dependencies:
|
|
|
96
97
|
- !ruby/object:Gem::Version
|
|
97
98
|
version: '0'
|
|
98
99
|
- !ruby/object:Gem::Dependency
|
|
99
|
-
name:
|
|
100
|
+
name: rubocop
|
|
100
101
|
requirement: !ruby/object:Gem::Requirement
|
|
101
102
|
requirements:
|
|
102
103
|
- - ">="
|
|
103
104
|
- !ruby/object:Gem::Version
|
|
104
105
|
version: '0'
|
|
105
|
-
type: :
|
|
106
|
+
type: :development
|
|
106
107
|
prerelease: false
|
|
107
108
|
version_requirements: !ruby/object:Gem::Requirement
|
|
108
109
|
requirements:
|
|
@@ -110,19 +111,19 @@ dependencies:
|
|
|
110
111
|
- !ruby/object:Gem::Version
|
|
111
112
|
version: '0'
|
|
112
113
|
- !ruby/object:Gem::Dependency
|
|
113
|
-
name:
|
|
114
|
+
name: faraday
|
|
114
115
|
requirement: !ruby/object:Gem::Requirement
|
|
115
116
|
requirements:
|
|
116
117
|
- - ">="
|
|
117
118
|
- !ruby/object:Gem::Version
|
|
118
|
-
version:
|
|
119
|
+
version: 2.0.1
|
|
119
120
|
type: :runtime
|
|
120
121
|
prerelease: false
|
|
121
122
|
version_requirements: !ruby/object:Gem::Requirement
|
|
122
123
|
requirements:
|
|
123
124
|
- - ">="
|
|
124
125
|
- !ruby/object:Gem::Version
|
|
125
|
-
version:
|
|
126
|
+
version: 2.0.1
|
|
126
127
|
- !ruby/object:Gem::Dependency
|
|
127
128
|
name: faraday-retry
|
|
128
129
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -156,6 +157,7 @@ description: Ruby Client for Flagsmith. Ship features with confidence using feat
|
|
|
156
157
|
email:
|
|
157
158
|
- tom@solidstategroup.com
|
|
158
159
|
- bmoelk@gmail.com
|
|
160
|
+
- zachaysan@gmail.com
|
|
159
161
|
executables: []
|
|
160
162
|
extensions: []
|
|
161
163
|
extra_rdoc_files: []
|
|
@@ -224,12 +226,14 @@ files:
|
|
|
224
226
|
- lib/flagsmith/sdk/intervals.rb
|
|
225
227
|
- lib/flagsmith/sdk/models/flags.rb
|
|
226
228
|
- lib/flagsmith/sdk/models/segments.rb
|
|
229
|
+
- lib/flagsmith/sdk/offline_handlers.rb
|
|
227
230
|
- lib/flagsmith/sdk/pooling_manager.rb
|
|
228
231
|
- lib/flagsmith/version.rb
|
|
229
232
|
homepage: https://flagsmith.com
|
|
230
233
|
licenses: []
|
|
231
|
-
metadata:
|
|
232
|
-
|
|
234
|
+
metadata:
|
|
235
|
+
rubygems_mfa_required: 'true'
|
|
236
|
+
post_install_message:
|
|
233
237
|
rdoc_options: []
|
|
234
238
|
require_paths:
|
|
235
239
|
- lib
|
|
@@ -237,15 +241,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
237
241
|
requirements:
|
|
238
242
|
- - ">="
|
|
239
243
|
- !ruby/object:Gem::Version
|
|
240
|
-
version:
|
|
244
|
+
version: 3.0.0
|
|
241
245
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
242
246
|
requirements:
|
|
243
247
|
- - ">="
|
|
244
248
|
- !ruby/object:Gem::Version
|
|
245
249
|
version: '0'
|
|
246
250
|
requirements: []
|
|
247
|
-
rubygems_version: 3.3.
|
|
248
|
-
signing_key:
|
|
251
|
+
rubygems_version: 3.3.26
|
|
252
|
+
signing_key:
|
|
249
253
|
specification_version: 4
|
|
250
254
|
summary: Flagsmith - Ship features with confidence
|
|
251
255
|
test_files: []
|