featurehub-sdk 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +154 -0
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +107 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +12 -0
- data/featurehub-sdk.gemspec +45 -0
- data/featurehub-sdk.iml +83 -0
- data/lib/feature_hub/sdk/context.rb +191 -0
- data/lib/feature_hub/sdk/feature_hub_config.rb +125 -0
- data/lib/feature_hub/sdk/feature_repository.rb +110 -0
- data/lib/feature_hub/sdk/feature_state.rb +134 -0
- data/lib/feature_hub/sdk/impl/apply_features.rb +105 -0
- data/lib/feature_hub/sdk/impl/murmur3_percentage.rb +20 -0
- data/lib/feature_hub/sdk/impl/rollout_holders.rb +118 -0
- data/lib/feature_hub/sdk/impl/strategy_wrappers.rb +181 -0
- data/lib/feature_hub/sdk/interceptors.rb +54 -0
- data/lib/feature_hub/sdk/internal_feature_repository.rb +28 -0
- data/lib/feature_hub/sdk/percentage_calc.rb +12 -0
- data/lib/feature_hub/sdk/poll_edge_service.rb +132 -0
- data/lib/feature_hub/sdk/strategy_attributes.rb +227 -0
- data/lib/feature_hub/sdk/streaming_edge_service.rb +57 -0
- data/lib/feature_hub/sdk/version.rb +17 -0
- data/lib/featurehub-sdk.rb +30 -0
- data/sig/feature_hub/featurehub.rbs +256 -0
- metadata +146 -0
@@ -0,0 +1,227 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# these are bulk copied in from OpenAPI and left in original case
|
4
|
+
module FeatureHub
|
5
|
+
module Sdk
|
6
|
+
# rubocop:disable Naming/ConstantName
|
7
|
+
# rubocop:disable Metrics/ModuleLength
|
8
|
+
module StrategyAttributeCountryName
|
9
|
+
Afghanistan = "afghanistan"
|
10
|
+
Albania = "albania"
|
11
|
+
Algeria = "algeria"
|
12
|
+
Andorra = "andorra"
|
13
|
+
Angola = "angola"
|
14
|
+
AntiguaAndBarbuda = "antigua_and_barbuda"
|
15
|
+
Argentina = "argentina"
|
16
|
+
Armenia = "armenia"
|
17
|
+
Australia = "australia"
|
18
|
+
Austria = "austria"
|
19
|
+
Azerbaijan = "azerbaijan"
|
20
|
+
TheBahamas = "the_bahamas"
|
21
|
+
Bahrain = "bahrain"
|
22
|
+
Bangladesh = "bangladesh"
|
23
|
+
Barbados = "barbados"
|
24
|
+
Belarus = "belarus"
|
25
|
+
Belgium = "belgium"
|
26
|
+
Belize = "belize"
|
27
|
+
Benin = "benin"
|
28
|
+
Bhutan = "bhutan"
|
29
|
+
Bolivia = "bolivia"
|
30
|
+
BosniaAndHerzegovina = "bosnia_and_herzegovina"
|
31
|
+
Botswana = "botswana"
|
32
|
+
Brazil = "brazil"
|
33
|
+
Brunei = "brunei"
|
34
|
+
Bulgaria = "bulgaria"
|
35
|
+
BurkinaFaso = "burkina_faso"
|
36
|
+
Burundi = "burundi"
|
37
|
+
CaboVerde = "cabo_verde"
|
38
|
+
Cambodia = "cambodia"
|
39
|
+
Cameroon = "cameroon"
|
40
|
+
Canada = "canada"
|
41
|
+
CentralAfricanRepublic = "central_african_republic"
|
42
|
+
Chad = "chad"
|
43
|
+
Chile = "chile"
|
44
|
+
China = "china"
|
45
|
+
Colombia = "colombia"
|
46
|
+
Comoros = "comoros"
|
47
|
+
CongoDemocraticRepublicOfThe = "congo_democratic_republic_of_the"
|
48
|
+
CongoRepublicOfThe = "congo_republic_of_the"
|
49
|
+
CostaRica = "costa_rica"
|
50
|
+
CoteDivoire = "cote_divoire"
|
51
|
+
Croatia = "croatia"
|
52
|
+
Cuba = "cuba"
|
53
|
+
Cyprus = "cyprus"
|
54
|
+
CzechRepublic = "czech_republic"
|
55
|
+
Denmark = "denmark"
|
56
|
+
Djibouti = "djibouti"
|
57
|
+
Dominica = "dominica"
|
58
|
+
DominicanRepublic = "dominican_republic"
|
59
|
+
EastTimor = "east_timor"
|
60
|
+
Ecuador = "ecuador"
|
61
|
+
Egypt = "egypt"
|
62
|
+
ElSalvador = "el_salvador"
|
63
|
+
EquatorialGuinea = "equatorial_guinea"
|
64
|
+
Eritrea = "eritrea"
|
65
|
+
Estonia = "estonia"
|
66
|
+
Eswatini = "eswatini"
|
67
|
+
Ethiopia = "ethiopia"
|
68
|
+
Fiji = "fiji"
|
69
|
+
Finland = "finland"
|
70
|
+
France = "france"
|
71
|
+
Gabon = "gabon"
|
72
|
+
TheGambia = "the_gambia"
|
73
|
+
Georgia = "georgia"
|
74
|
+
Germany = "germany"
|
75
|
+
Ghana = "ghana"
|
76
|
+
Greece = "greece"
|
77
|
+
Grenada = "grenada"
|
78
|
+
Guatemala = "guatemala"
|
79
|
+
Guinea = "guinea"
|
80
|
+
GuineaBissau = "guinea_bissau"
|
81
|
+
Guyana = "guyana"
|
82
|
+
Haiti = "haiti"
|
83
|
+
Honduras = "honduras"
|
84
|
+
Hungary = "hungary"
|
85
|
+
Iceland = "iceland"
|
86
|
+
India = "india"
|
87
|
+
Indonesia = "indonesia"
|
88
|
+
Iran = "iran"
|
89
|
+
Iraq = "iraq"
|
90
|
+
Ireland = "ireland"
|
91
|
+
Israel = "israel"
|
92
|
+
Italy = "italy"
|
93
|
+
Jamaica = "jamaica"
|
94
|
+
Japan = "japan"
|
95
|
+
Jordan = "jordan"
|
96
|
+
Kazakhstan = "kazakhstan"
|
97
|
+
Kenya = "kenya"
|
98
|
+
Kiribati = "kiribati"
|
99
|
+
KoreaNorth = "korea_north"
|
100
|
+
KoreaSouth = "korea_south"
|
101
|
+
Kosovo = "kosovo"
|
102
|
+
Kuwait = "kuwait"
|
103
|
+
Kyrgyzstan = "kyrgyzstan"
|
104
|
+
Laos = "laos"
|
105
|
+
Latvia = "latvia"
|
106
|
+
Lebanon = "lebanon"
|
107
|
+
Lesotho = "lesotho"
|
108
|
+
Liberia = "liberia"
|
109
|
+
Libya = "libya"
|
110
|
+
Liechtenstein = "liechtenstein"
|
111
|
+
Lithuania = "lithuania"
|
112
|
+
Luxembourg = "luxembourg"
|
113
|
+
Madagascar = "madagascar"
|
114
|
+
Malawi = "malawi"
|
115
|
+
Malaysia = "malaysia"
|
116
|
+
Maldives = "maldives"
|
117
|
+
Mali = "mali"
|
118
|
+
Malta = "malta"
|
119
|
+
MarshallIslands = "marshall_islands"
|
120
|
+
Mauritania = "mauritania"
|
121
|
+
Mauritius = "mauritius"
|
122
|
+
Mexico = "mexico"
|
123
|
+
MicronesiaFederatedStatesOf = "micronesia_federated_states_of"
|
124
|
+
Moldova = "moldova"
|
125
|
+
Monaco = "monaco"
|
126
|
+
Mongolia = "mongolia"
|
127
|
+
Montenegro = "montenegro"
|
128
|
+
Morocco = "morocco"
|
129
|
+
Mozambique = "mozambique"
|
130
|
+
Myanmar = "myanmar"
|
131
|
+
Namibia = "namibia"
|
132
|
+
Nauru = "nauru"
|
133
|
+
Nepal = "nepal"
|
134
|
+
Netherlands = "netherlands"
|
135
|
+
NewZealand = "new_zealand"
|
136
|
+
Nicaragua = "nicaragua"
|
137
|
+
Niger = "niger"
|
138
|
+
Nigeria = "nigeria"
|
139
|
+
NorthMacedonia = "north_macedonia"
|
140
|
+
Norway = "norway"
|
141
|
+
Oman = "oman"
|
142
|
+
Pakistan = "pakistan"
|
143
|
+
Palau = "palau"
|
144
|
+
Panama = "panama"
|
145
|
+
PapuaNewGuinea = "papua_new_guinea"
|
146
|
+
Paraguay = "paraguay"
|
147
|
+
Peru = "peru"
|
148
|
+
Philippines = "philippines"
|
149
|
+
Poland = "poland"
|
150
|
+
Portugal = "portugal"
|
151
|
+
Qatar = "qatar"
|
152
|
+
Romania = "romania"
|
153
|
+
Russia = "russia"
|
154
|
+
Rwanda = "rwanda"
|
155
|
+
SaintKittsAndNevis = "saint_kitts_and_nevis"
|
156
|
+
SaintLucia = "saint_lucia"
|
157
|
+
SaintVincentAndTheGrenadines = "saint_vincent_and_the_grenadines"
|
158
|
+
Samoa = "samoa"
|
159
|
+
SanMarino = "san_marino"
|
160
|
+
SaoTomeAndPrincipe = "sao_tome_and_principe"
|
161
|
+
SaudiArabia = "saudi_arabia"
|
162
|
+
Senegal = "senegal"
|
163
|
+
Serbia = "serbia"
|
164
|
+
Seychelles = "seychelles"
|
165
|
+
SierraLeone = "sierra_leone"
|
166
|
+
Singapore = "singapore"
|
167
|
+
Slovakia = "slovakia"
|
168
|
+
Slovenia = "slovenia"
|
169
|
+
SolomonIslands = "solomon_islands"
|
170
|
+
Somalia = "somalia"
|
171
|
+
SouthAfrica = "south_africa"
|
172
|
+
Spain = "spain"
|
173
|
+
SriLanka = "sri_lanka"
|
174
|
+
Sudan = "sudan"
|
175
|
+
SudanSouth = "sudan_south"
|
176
|
+
Suriname = "suriname"
|
177
|
+
Sweden = "sweden"
|
178
|
+
Switzerland = "switzerland"
|
179
|
+
Syria = "syria"
|
180
|
+
Taiwan = "taiwan"
|
181
|
+
Tajikistan = "tajikistan"
|
182
|
+
Tanzania = "tanzania"
|
183
|
+
Thailand = "thailand"
|
184
|
+
Togo = "togo"
|
185
|
+
Tonga = "tonga"
|
186
|
+
TrinidadAndTobago = "trinidad_and_tobago"
|
187
|
+
Tunisia = "tunisia"
|
188
|
+
Turkey = "turkey"
|
189
|
+
Turkmenistan = "turkmenistan"
|
190
|
+
Tuvalu = "tuvalu"
|
191
|
+
Uganda = "uganda"
|
192
|
+
Ukraine = "ukraine"
|
193
|
+
UnitedArabEmirates = "united_arab_emirates"
|
194
|
+
UnitedKingdom = "united_kingdom"
|
195
|
+
UnitedStates = "united_states"
|
196
|
+
Uruguay = "uruguay"
|
197
|
+
Uzbekistan = "uzbekistan"
|
198
|
+
Vanuatu = "vanuatu"
|
199
|
+
VaticanCity = "vatican_city"
|
200
|
+
Venezuela = "venezuela"
|
201
|
+
Vietnam = "vietnam"
|
202
|
+
Yemen = "yemen"
|
203
|
+
Zambia = "zambia"
|
204
|
+
Zimbabwe = "zimbabwe"
|
205
|
+
end
|
206
|
+
|
207
|
+
module StrategyAttributeDeviceName
|
208
|
+
Browser = "browser"
|
209
|
+
Mobile = "mobile"
|
210
|
+
Desktop = "desktop"
|
211
|
+
Server = "server"
|
212
|
+
Watch = "watch"
|
213
|
+
Embedded = "embedded"
|
214
|
+
end
|
215
|
+
|
216
|
+
module StrategyAttributePlatformName
|
217
|
+
Linux = "linux"
|
218
|
+
Windows = "windows"
|
219
|
+
Macos = "macos"
|
220
|
+
Android = "android"
|
221
|
+
Ios = "ios"
|
222
|
+
end
|
223
|
+
|
224
|
+
# rubocop:enable Metrics/ModuleLength
|
225
|
+
# rubocop:enable Naming/ConstantName
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ld-eventsource"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module FeatureHub
|
7
|
+
module Sdk
|
8
|
+
# provides a streaming service
|
9
|
+
class StreamingEdgeService < FeatureHub::Sdk::EdgeService
|
10
|
+
attr_reader :repository, :sse_client, :url, :closed
|
11
|
+
|
12
|
+
def initialize(repository, api_keys, edge_url, logger = nil)
|
13
|
+
super(repository, api_keys, edge_url)
|
14
|
+
|
15
|
+
@url = "#{edge_url}features/#{api_keys[0]}"
|
16
|
+
@repository = repository
|
17
|
+
@sse_client = nil
|
18
|
+
@closed = true
|
19
|
+
@logger = logger || FeatureHub::Sdk.default_logger
|
20
|
+
end
|
21
|
+
|
22
|
+
def poll
|
23
|
+
start_streaming unless @sse_client
|
24
|
+
end
|
25
|
+
|
26
|
+
def active
|
27
|
+
!@closed && !@sse_client.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def close
|
31
|
+
@closed = true
|
32
|
+
return if @sse_client.nil?
|
33
|
+
|
34
|
+
@sse_client.close
|
35
|
+
@sse_client = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def start_streaming
|
41
|
+
@closed = false
|
42
|
+
@logger.info("streaming from #{@url}")
|
43
|
+
@sse_client = SSE::Client.new(@url) do |client|
|
44
|
+
client.on_event do |event|
|
45
|
+
@repository.notify(event.type, JSON.parse(event.data))
|
46
|
+
end
|
47
|
+
client.on_error do |error|
|
48
|
+
if error.is_a?(SSE::Errors::HTTPStatusError) && (error.status == 404)
|
49
|
+
@repository.notify("failure", nil)
|
50
|
+
close
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FeatureHub
|
4
|
+
# already documented elsewhere
|
5
|
+
module Sdk
|
6
|
+
VERSION = "1.0.0"
|
7
|
+
|
8
|
+
def default_logger
|
9
|
+
log = ::Logger.new($stdout)
|
10
|
+
log.level = ::Logger::WARN
|
11
|
+
log.progname = "featurehub-sdk"
|
12
|
+
log
|
13
|
+
end
|
14
|
+
|
15
|
+
module_function :default_logger
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "feature_hub/sdk/impl/rollout_holders"
|
4
|
+
require_relative "feature_hub/sdk/impl/apply_features"
|
5
|
+
require_relative "feature_hub/sdk/percentage_calc"
|
6
|
+
require_relative "feature_hub/sdk/impl/murmur3_percentage"
|
7
|
+
require_relative "feature_hub/sdk/version"
|
8
|
+
require_relative "feature_hub/sdk/context"
|
9
|
+
require_relative "feature_hub/sdk/feature_hub_config"
|
10
|
+
require_relative "feature_hub/sdk/internal_feature_repository"
|
11
|
+
require_relative "feature_hub/sdk/feature_repository"
|
12
|
+
require_relative "feature_hub/sdk/feature_state"
|
13
|
+
require_relative "feature_hub/sdk/interceptors"
|
14
|
+
require_relative "feature_hub/sdk/strategy_attributes"
|
15
|
+
require_relative "feature_hub/sdk/impl/strategy_wrappers"
|
16
|
+
require_relative "feature_hub/sdk/poll_edge_service"
|
17
|
+
require_relative "feature_hub/sdk/streaming_edge_service"
|
18
|
+
|
19
|
+
# the FeatureHub SDK namespace
|
20
|
+
module FeatureHub
|
21
|
+
# the main SDK
|
22
|
+
|
23
|
+
module Sdk
|
24
|
+
# classes inside here are intended to be internal details, do not rely on them
|
25
|
+
module Impl
|
26
|
+
end
|
27
|
+
|
28
|
+
class Error < StandardError; end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
module FeatureHub
|
2
|
+
module Sdk
|
3
|
+
VERSION: String
|
4
|
+
# See the writing guide of rbs: https://github.com/ruby/rbs#guides
|
5
|
+
#
|
6
|
+
|
7
|
+
class FeatureState
|
8
|
+
attr_reader key: Symbol
|
9
|
+
|
10
|
+
def initialize: (key: String, repo: InternalFeatureRepository,
|
11
|
+
feature_state: Hash[untyped, untyped]?, parent_state: FeatureState?, ctx: ClientContext?) -> void
|
12
|
+
|
13
|
+
def locked?: -> bool
|
14
|
+
def exists?: (top_feature: FeatureState?) -> bool
|
15
|
+
def id: -> String?
|
16
|
+
def feature_type: -> String?
|
17
|
+
|
18
|
+
def with_context: (ctx: ClientContext) -> FeatureState
|
19
|
+
|
20
|
+
def update_feature_state: (feature_state: Hash[untyped, untyped]) -> void
|
21
|
+
# this is the feature state of the top level, it always walks up
|
22
|
+
def feature_state: () -> Hash[untyped, untyped]
|
23
|
+
|
24
|
+
# this is strictly the internal feature state, further down from the top level it will be nil
|
25
|
+
def internal_feature_state: () -> Hash[untyped, untyped]
|
26
|
+
|
27
|
+
def value: () -> [bool? | String? | Float?]
|
28
|
+
|
29
|
+
def version: () -> int
|
30
|
+
|
31
|
+
def string: () -> String?
|
32
|
+
|
33
|
+
def number: () -> Float
|
34
|
+
|
35
|
+
def raw_json: () -> String?
|
36
|
+
|
37
|
+
def boolean: () -> bool?
|
38
|
+
|
39
|
+
def flag: () -> bool?
|
40
|
+
|
41
|
+
def enabled?: () -> bool
|
42
|
+
|
43
|
+
def set?: () -> bool?
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def top_feature_state: -> FeatureState
|
48
|
+
|
49
|
+
def _feature_state: -> Hash[untyped, untyped]
|
50
|
+
|
51
|
+
def _set_feature_state: (feature_state: Hash[untyped, untyped]) -> void
|
52
|
+
|
53
|
+
def get_value: (feature_type: String?) -> [bool? | String? | Float?]
|
54
|
+
end
|
55
|
+
|
56
|
+
class Applied
|
57
|
+
attr_reader matched: bool
|
58
|
+
attr_reader value: [bool? | String? | Float?]
|
59
|
+
|
60
|
+
def initialize:(matched: bool, value: [bool? | String? | Float?]) -> void
|
61
|
+
end
|
62
|
+
|
63
|
+
class InterceptorValue
|
64
|
+
def initialize: (val: [bool? | String? | Float? ]) -> void
|
65
|
+
def cast:(feature_type: String?) -> [bool? | String? | Float? ]
|
66
|
+
end
|
67
|
+
|
68
|
+
class ValueInterceptor
|
69
|
+
def intercepted_value: (feature_key: Symbol) -> InterceptorValue?
|
70
|
+
end
|
71
|
+
|
72
|
+
class EnvironmentInterceptor < ValueInterceptor
|
73
|
+
end
|
74
|
+
|
75
|
+
class PercentageCalculator
|
76
|
+
def determine_client_percentage: (percentage_text: String, feature_id: String) -> int
|
77
|
+
end
|
78
|
+
|
79
|
+
class ApplyFeatures
|
80
|
+
def initialize: (percent_calculator: PercentageCalculator?, matcher_repository: MatcherRepository?) -> void
|
81
|
+
def apply: (strategies: Array[RolloutStrategy], key: String, feature_value_id: String, context: ClientContext) -> Applied
|
82
|
+
def match_attribute: (context: ClientContext, rs: RolloutStrategyAttribute) -> bool
|
83
|
+
def self.determine_percentage_key: (context: ClientContext, rsi: RolloutStrategy) -> String?
|
84
|
+
end
|
85
|
+
|
86
|
+
class InternalFeatureRepository
|
87
|
+
def feature: (key: String) -> FeatureState?
|
88
|
+
def find_interceptor: (feature_value: String) -> InterceptorValue?
|
89
|
+
def ready?: -> bool
|
90
|
+
def not_ready!: -> void
|
91
|
+
def apply: (strategies: Array[RolloutStrategy], key: String, feature_id: String, context: ClientContext) -> Applied
|
92
|
+
def notify: (status: String, data: Hash[untyped, untyped]) -> void
|
93
|
+
end
|
94
|
+
|
95
|
+
class FeatureHubRepository < InternalFeatureRepository
|
96
|
+
@features: Hash[String, FeatureState]
|
97
|
+
@ready: bool
|
98
|
+
|
99
|
+
def initialize: (apply_features: nil | ApplyFeatures ) -> void
|
100
|
+
def apply:(strategies: Array[RolloutStrategy], key: String, feature_id: String, context: ClientContext) -> Applied
|
101
|
+
|
102
|
+
def notify: (status: String, data: Hash[untyped, untyped]) -> void
|
103
|
+
def feature: (key: String) -> FeatureState
|
104
|
+
def register_interceptor: (interceptor: ValueInterceptor) -> void
|
105
|
+
|
106
|
+
def find_interceptor: (feature_value: String) -> InterceptorValue?
|
107
|
+
def ready?: -> bool
|
108
|
+
def not_ready!: -> void
|
109
|
+
|
110
|
+
def extract_feature_state: -> Array[Hash[untyped, untyped]]
|
111
|
+
end
|
112
|
+
|
113
|
+
class ClientContext
|
114
|
+
attr_reader repo: InternalFeatureRepository
|
115
|
+
|
116
|
+
def initialize: (repository: InternalFeatureRepository) -> void
|
117
|
+
def user_key: (value: String) -> ClientContext
|
118
|
+
def session_key: (value: String) -> ClientContext
|
119
|
+
def version: (value: String) -> ClientContext
|
120
|
+
def country: (value: Symbol ) -> ClientContext
|
121
|
+
def platform: (value: Symbol ) -> ClientContext
|
122
|
+
def device: (value: Symbol ) -> ClientContext
|
123
|
+
def attribute_value: (key: String, values: Array[String] ) -> ClientContext
|
124
|
+
def clear: -> ClientContext
|
125
|
+
def get_attr: (key: String, default_val: String?) -> String?
|
126
|
+
def default_percentage_key: -> String?
|
127
|
+
def enabled: (key: String) -> bool?
|
128
|
+
|
129
|
+
def feature: (key: String) -> FeatureState
|
130
|
+
def set?: (key: String) -> bool?
|
131
|
+
def number: (key: String) -> Float?
|
132
|
+
def string: (key: String) -> String?
|
133
|
+
def json: (key: String) -> Hash[untyped, untyped]?
|
134
|
+
def raw_json: (key: String) -> String?
|
135
|
+
def flag: (key: String) -> bool?
|
136
|
+
def boolean: (key: String) -> bool?
|
137
|
+
def exists?: (key: String) -> bool
|
138
|
+
|
139
|
+
def build: -> ClientContext
|
140
|
+
def build_sync: -> ClientContext
|
141
|
+
def close: -> ClientContext
|
142
|
+
end
|
143
|
+
|
144
|
+
class EdgeService
|
145
|
+
def initialize: (repository: InternalFeatureRepository, api_keys: Array[String], edge_url: String) -> void
|
146
|
+
def poll: -> void
|
147
|
+
def context_change: (new_header: String?) -> void
|
148
|
+
def close: -> void
|
149
|
+
end
|
150
|
+
|
151
|
+
class ServerEvalFeatureContext < ClientContext
|
152
|
+
@edge: EdgeService
|
153
|
+
|
154
|
+
def initialize: (repository: InternalFeatureRepository, edge: EdgeService) -> void
|
155
|
+
end
|
156
|
+
|
157
|
+
class ClientEvalFeatureContext < ClientContext
|
158
|
+
@edge: EdgeService
|
159
|
+
|
160
|
+
def initialize: (repository: InternalFeatureRepository, edge: EdgeService) -> void
|
161
|
+
end
|
162
|
+
|
163
|
+
class FeatureHubConfig
|
164
|
+
attr_reader edge_url: String
|
165
|
+
attr_reader api_keys: Array[String]
|
166
|
+
attr_reader client_evaluated: bool
|
167
|
+
|
168
|
+
def initialize: (edge_url: String, api_keys: Array[String], repository: InternalFeatureRepository) -> void
|
169
|
+
|
170
|
+
def repository: (repository: InternalFeatureRepository?) -> InternalFeatureRepository
|
171
|
+
|
172
|
+
def init: -> void
|
173
|
+
|
174
|
+
def get_or_create_edge_service: -> EdgeService
|
175
|
+
|
176
|
+
# can't figure this out
|
177
|
+
# def edge_service_provider:
|
178
|
+
#
|
179
|
+
def use_polling_edge_service: (interval: int?) -> void
|
180
|
+
|
181
|
+
def new_context: -> ClientContext
|
182
|
+
|
183
|
+
def close: -> void
|
184
|
+
end
|
185
|
+
|
186
|
+
class PollingEdgeService
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
class RolloutStrategyCondition
|
191
|
+
def equals?: -> bool
|
192
|
+
def ends_with?: -> bool
|
193
|
+
def starts_with?: -> bool
|
194
|
+
def greater?: -> bool
|
195
|
+
def greater_equals?: -> bool
|
196
|
+
def less?: -> bool
|
197
|
+
def less_equals?: -> bool
|
198
|
+
def not_equals?: -> bool
|
199
|
+
def includes?: -> bool
|
200
|
+
def excludes?: -> bool
|
201
|
+
def regex?: -> bool
|
202
|
+
end
|
203
|
+
|
204
|
+
class RolloutStrategyAttribute
|
205
|
+
attr_reader id: String
|
206
|
+
attr_reader conditional: RolloutStrategyCondition
|
207
|
+
attr_reader field_name: String
|
208
|
+
attr_reader values: Array[[bool? | String? | Float?]]
|
209
|
+
attr_reader field_type: String
|
210
|
+
|
211
|
+
def float_values: -> Array[Float]
|
212
|
+
def str_values: -> Array[String]
|
213
|
+
end
|
214
|
+
|
215
|
+
class RolloutStrategy
|
216
|
+
attr_reader attributes: Array[RolloutStrategyAttribute]
|
217
|
+
attr_reader id: String
|
218
|
+
attr_reader name: String?
|
219
|
+
attr_reader percentage: int
|
220
|
+
attr_reader percentage_attributes: Array[String]
|
221
|
+
attr_reader value: [bool? | String? | Float?]
|
222
|
+
|
223
|
+
def percentage_attributes?: -> bool
|
224
|
+
def attributes?: -> bool
|
225
|
+
end
|
226
|
+
|
227
|
+
class StrategyMatcher
|
228
|
+
def match: (supplied_value: String, attr: RolloutStrategyAttribute ) -> bool
|
229
|
+
end
|
230
|
+
|
231
|
+
class BooleanMatcher < StrategyMatcher
|
232
|
+
def match: (supplied_value: String, attr: RolloutStrategyAttribute ) -> bool
|
233
|
+
end
|
234
|
+
|
235
|
+
class StringMatcher < StrategyMatcher
|
236
|
+
end
|
237
|
+
|
238
|
+
class NumberMatcher < StrategyMatcher
|
239
|
+
end
|
240
|
+
|
241
|
+
class SemanticVersionMatcher < StrategyMatcher
|
242
|
+
end
|
243
|
+
|
244
|
+
class IPNetworkMatcher < StrategyMatcher
|
245
|
+
end
|
246
|
+
|
247
|
+
class MatcherRepository
|
248
|
+
def find_matcher: (attr: RolloutStrategyAttribute) -> StrategyMatcher
|
249
|
+
end
|
250
|
+
|
251
|
+
class MatcherRegistry < MatcherRepository
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
end
|