1515require 'flagsmith/sdk/intervals'
1616require 'flagsmith/sdk/pooling_manager'
1717require 'flagsmith/sdk/models/flags'
18- require 'flagsmith/sdk/instance_methods '
18+ require 'flagsmith/sdk/models/segments '
1919
2020require 'flagsmith/engine/core'
2121
@@ -24,8 +24,6 @@ module Flagsmith
2424 # Ruby client for flagsmith.com
2525 class Client
2626 extend Forwardable
27- include Flagsmith ::SDK ::InstanceMethods
28- include Flagsmith ::Engine ::Core
2927 # A Flagsmith client.
3028 #
3129 # Provides an interface for interacting with the Flagsmith http API.
@@ -37,9 +35,11 @@ class Client
3735 # feature_enabled = environment_flags.is_feature_enabled('foo')
3836 # feature_value = identity_flags.get_feature_value('foo')
3937 #
40- # identity_flags = flagsmith.get_identity_flags('identifier', 'foo': 'bar')
38+ # identity_flags = flagsmith.get_identity_flags('identifier', { 'foo': 'bar'} )
4139 # feature_enabled_for_identity = identity_flags.is_feature_enabled('foo')
4240 # feature_value_for_identity = identity_flags.get_feature_value('foo')
41+ #
42+ # identity_segments = flagsmith.get_identity_segments('identifier', {'foo': 'bar'})
4343
4444 # Available Configs.
4545 #
@@ -58,12 +58,17 @@ def initialize(config)
5858 api_client
5959 analytics_processor
6060 environment_data_polling_manager
61+ engine
6162 end
6263
6364 def api_client
6465 @api_client ||= Flagsmith ::ApiClient . new ( @config )
6566 end
6667
68+ def engine
69+ @engine ||= Flagsmith ::Engine ::Engine . new
70+ end
71+
6772 def analytics_processor
6873 return nil unless @config . enable_analytics?
6974
@@ -94,5 +99,145 @@ def environment_from_api
9499 environment_data = api_client . get ( @config . environment_url ) . body
95100 Flagsmith ::Engine ::Environment . build ( environment_data )
96101 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
97242 end
98243end
0 commit comments