15
15
require 'flagsmith/sdk/intervals'
16
16
require 'flagsmith/sdk/pooling_manager'
17
17
require 'flagsmith/sdk/models/flags'
18
- require 'flagsmith/sdk/instance_methods '
18
+ require 'flagsmith/sdk/models/segments '
19
19
20
20
require 'flagsmith/engine/core'
21
21
@@ -24,8 +24,6 @@ module Flagsmith
24
24
# Ruby client for flagsmith.com
25
25
class Client
26
26
extend Forwardable
27
- include Flagsmith ::SDK ::InstanceMethods
28
- include Flagsmith ::Engine ::Core
29
27
# A Flagsmith client.
30
28
#
31
29
# Provides an interface for interacting with the Flagsmith http API.
@@ -37,9 +35,11 @@ class Client
37
35
# feature_enabled = environment_flags.is_feature_enabled('foo')
38
36
# feature_value = identity_flags.get_feature_value('foo')
39
37
#
40
- # identity_flags = flagsmith.get_identity_flags('identifier', 'foo': 'bar')
38
+ # identity_flags = flagsmith.get_identity_flags('identifier', { 'foo': 'bar'} )
41
39
# feature_enabled_for_identity = identity_flags.is_feature_enabled('foo')
42
40
# feature_value_for_identity = identity_flags.get_feature_value('foo')
41
+ #
42
+ # identity_segments = flagsmith.get_identity_segments('identifier', {'foo': 'bar'})
43
43
44
44
# Available Configs.
45
45
#
@@ -58,12 +58,17 @@ def initialize(config)
58
58
api_client
59
59
analytics_processor
60
60
environment_data_polling_manager
61
+ engine
61
62
end
62
63
63
64
def api_client
64
65
@api_client ||= Flagsmith ::ApiClient . new ( @config )
65
66
end
66
67
68
+ def engine
69
+ @engine ||= Flagsmith ::Engine ::Engine . new
70
+ end
71
+
67
72
def analytics_processor
68
73
return nil unless @config . enable_analytics?
69
74
@@ -94,5 +99,145 @@ def environment_from_api
94
99
environment_data = api_client . get ( @config . environment_url ) . body
95
100
Flagsmith ::Engine ::Environment . build ( environment_data )
96
101
end
102
+
103
+ # Get all the default for flags for the current environment.
104
+ # @returns Flags object holding all the flags for the current environment.
105
+ def get_environment_flags # rubocop:disable Naming/AccessorMethodName
106
+ return environment_flags_from_document if @config . local_evaluation?
107
+
108
+ environment_flags_from_api
109
+ end
110
+
111
+ # Get all the flags for the current environment for a given identity. Will also
112
+ # upsert all traits to the Flagsmith API for future evaluations. Providing a
113
+ # trait with a value of None will remove the trait from the identity if it exists.
114
+ #
115
+ # identifier a unique identifier for the identity in the current
116
+ # environment, e.g. email address, username, uuid
117
+ # traits { key => value } is a dictionary of traits to add / update on the identity in
118
+ # Flagsmith, e.g. { "num_orders": 10 }
119
+ # returns Flags object holding all the flags for the given identity.
120
+ def get_identity_flags ( identifier , **traits )
121
+ return get_identity_flags_from_document ( identifier , traits ) if environment
122
+
123
+ get_identity_flags_from_api ( identifier , traits )
124
+ end
125
+
126
+ def feature_enabled? ( feature_name , default : false )
127
+ flag = get_environment_flags [ feature_name ]
128
+ return default if flag . nil?
129
+
130
+ flag . enabled?
131
+ end
132
+
133
+ def feature_enabled_for_identity? ( feature_name , user_id , default : false )
134
+ flag = get_identity_flags ( user_id ) [ feature_name ]
135
+ return default if flag . nil?
136
+
137
+ flag . enabled?
138
+ end
139
+
140
+ def get_value ( feature_name , default : nil )
141
+ flag = get_environment_flags [ feature_name ]
142
+ return default if flag . nil?
143
+
144
+ flag . value
145
+ end
146
+
147
+ def get_value_for_identity ( feature_name , user_id = nil , default : nil )
148
+ flag = get_identity_flags ( user_id ) [ feature_name ]
149
+ return default if flag . nil?
150
+
151
+ flag . value
152
+ end
153
+
154
+ def get_identity_segments ( identifier , traits = { } )
155
+ unless environment
156
+ raise Flagsmith ::ClientError ,
157
+ 'Local evaluation required to obtain identity segments.'
158
+ end
159
+
160
+ identity_model = build_identity_model ( identifier , traits )
161
+ segment_models = engine . get_identity_segments ( environment , identity_model )
162
+ return segment_models . map { |sm | Flagsmith ::Segments ::Segment . new ( id : sm . id , name : sm . name ) } . compact
163
+ end
164
+
165
+ private
166
+
167
+ def environment_flags_from_document
168
+ Flagsmith ::Flags ::Collection . from_feature_state_models (
169
+ engine . get_environment_feature_states ( environment ) ,
170
+ analytics_processor : analytics_processor ,
171
+ default_flag_handler : default_flag_handler
172
+ )
173
+ end
174
+
175
+ def get_identity_flags_from_document ( identifier , traits = { } )
176
+ identity_model = build_identity_model ( identifier , traits )
177
+
178
+ Flagsmith ::Flags ::Collection . from_feature_state_models (
179
+ engine . get_identity_feature_states ( environment , identity_model ) ,
180
+ analytics_processor : analytics_processor ,
181
+ default_flag_handler : default_flag_handler
182
+ )
183
+ end
184
+
185
+ def environment_flags_from_api
186
+ rescue_with_default_handler do
187
+ api_flags = api_client . get ( @config . environment_flags_url ) . body
188
+ api_flags = api_flags . select { |flag | flag [ :feature_segment ] . nil? }
189
+ Flagsmith ::Flags ::Collection . from_api (
190
+ api_flags ,
191
+ analytics_processor : analytics_processor ,
192
+ default_flag_handler : default_flag_handler
193
+ )
194
+ end
195
+ end
196
+
197
+ def get_identity_flags_from_api ( identifier , traits = { } )
198
+ rescue_with_default_handler do
199
+ data = generate_identities_data ( identifier , traits )
200
+ json_response = api_client . post ( @config . identities_url , data . to_json ) . body
201
+
202
+ Flagsmith ::Flags ::Collection . from_api (
203
+ json_response [ :flags ] ,
204
+ analytics_processor : analytics_processor ,
205
+ default_flag_handler : default_flag_handler
206
+ )
207
+ end
208
+ end
209
+
210
+ def rescue_with_default_handler
211
+ yield
212
+ rescue StandardError
213
+ if default_flag_handler
214
+ return Flagsmith ::Flags ::Collection . new (
215
+ { } ,
216
+ default_flag_handler : default_flag_handler
217
+ )
218
+ end
219
+ raise
220
+ end
221
+
222
+ def build_identity_model ( identifier , traits = { } )
223
+ unless environment
224
+ raise Flagsmith ::ClientError ,
225
+ 'Unable to build identity model when no local environment present.'
226
+ end
227
+
228
+ trait_models = traits . map do |key , value |
229
+ Flagsmith ::Engine ::Identities ::Trait . new ( trait_key : key , trait_value : value )
230
+ end
231
+ Flagsmith ::Engine ::Identity . new (
232
+ identity_traits : trait_models , environment_api_key : environment_key , identifier : identifier
233
+ )
234
+ end
235
+
236
+ def generate_identities_data ( identifier , traits = { } )
237
+ {
238
+ identifier : identifier ,
239
+ traits : traits . map { |key , value | { trait_key : key , trait_value : value } }
240
+ }
241
+ end
97
242
end
98
243
end
0 commit comments