openfeature-sdk-sorbet 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -3
- data/CHANGELOG.md +20 -0
- data/Gemfile.lock +9 -9
- data/README.md +9 -1
- data/lib/open_feature/client.rb +63 -13
- data/lib/open_feature/configuration.rb +9 -13
- data/lib/open_feature/evaluation_context.rb +40 -0
- data/lib/open_feature/evaluation_context_builder.rb +26 -0
- data/lib/open_feature.rb +21 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0df7fa6e69c0e30dd01d5e5f0aad7b5543787ed2ab7a11ab35d7b034ffe1dc6
|
4
|
+
data.tar.gz: 22de53663fcd170d801f9ed12e0fb7bef01618b685ca61f2dbe486801d5fdcc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b31be23ed317d0e8d1418085f2e4adb655030d023a08cf1eb3ef450fa5aaf091319bdd6cd4af57d28d795e48711c705499aed23181c9f894919c01af8a7e8495
|
7
|
+
data.tar.gz: b3bdf0316cd4637a7970791f2d2b5d4d3407bb45cd14b613fd268ce5f4e3486d6cdbe5731c955b5c92f4b9f26196d1a514dc8f54f683f8ec776f345f102f7173
|
data/.rubocop.yml
CHANGED
@@ -30,9 +30,7 @@ Metrics/ClassLength:
|
|
30
30
|
|
31
31
|
Metrics/MethodLength:
|
32
32
|
Exclude:
|
33
|
-
- test
|
34
|
-
- test/open_feature/multiple_source_provider_test.rb
|
35
|
-
- test/support/test_provider.rb
|
33
|
+
- test/**/*
|
36
34
|
|
37
35
|
Style/AccessorGrouping:
|
38
36
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.2.0] - 2023-05-17
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Added ability to set evaluation context globally on the `Configuration` singleton, i.e. `OpenFeature::Configuration.instance.evaluation_context = OpenFeature::EvaluationContext.new(fields: { "globally" => "available" })`.
|
14
|
+
- Added ability to set evaluation context globally on the `OpenFeature` module, i.e. `OpenFeature.set_evaluation_context(OpenFeature::EvaluationContext.new(fields: { "globally" => "available" }))`.
|
15
|
+
- Added ability to set evaluation context on a `Client` instance, i.e. `client.evaluation_context = OpenFeature::EvaluationContext.new(fields: { "client" => "available" })`.
|
16
|
+
- Added ability to set hooks and evaluation context on `Client` initialization, i.e. `OpenFeature.create_client(name: "my_client", evaluation_context: OpenFeature::EvaluationContext.new(fields: { "client" => "available" }), hooks: OpenFeature::Hook.new)`
|
17
|
+
- Added `Configuration#reset!` to reset global configuration to the default state.
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
|
21
|
+
- Renamed `Configuration#set_provider` to `Configuration#provider=`.
|
22
|
+
- Renamed `Configuration#add_provider` to `Configuration#hooks=`.
|
23
|
+
- During flag initialization, contexts are now merged. The invocation context takes precedence over the client context which takes precedence over the global context.
|
24
|
+
|
25
|
+
### Removed
|
26
|
+
|
27
|
+
- Removed `Configuration#clear_hooks!` in favor of `Configuration#reset!`.
|
28
|
+
|
9
29
|
## [0.1.2] - 2023-05-16
|
10
30
|
|
11
31
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openfeature-sdk-sorbet (0.
|
4
|
+
openfeature-sdk-sorbet (0.2.0)
|
5
5
|
sorbet-runtime (~> 0.5)
|
6
6
|
sorbet-struct-comparable (~> 1.3)
|
7
7
|
zeitwerk (~> 2.6)
|
@@ -56,14 +56,14 @@ GEM
|
|
56
56
|
rubocop-sorbet (0.7.0)
|
57
57
|
rubocop (>= 0.90.0)
|
58
58
|
ruby-progressbar (1.13.0)
|
59
|
-
sorbet (0.5.
|
60
|
-
sorbet-static (= 0.5.
|
61
|
-
sorbet-runtime (0.5.
|
62
|
-
sorbet-static (0.5.
|
63
|
-
sorbet-static (0.5.
|
64
|
-
sorbet-static-and-runtime (0.5.
|
65
|
-
sorbet (= 0.5.
|
66
|
-
sorbet-runtime (= 0.5.
|
59
|
+
sorbet (0.5.10830)
|
60
|
+
sorbet-static (= 0.5.10830)
|
61
|
+
sorbet-runtime (0.5.10830)
|
62
|
+
sorbet-static (0.5.10830-universal-darwin-22)
|
63
|
+
sorbet-static (0.5.10830-x86_64-linux)
|
64
|
+
sorbet-static-and-runtime (0.5.10830)
|
65
|
+
sorbet (= 0.5.10830)
|
66
|
+
sorbet-runtime (= 0.5.10830)
|
67
67
|
sorbet-struct-comparable (1.3.0)
|
68
68
|
sorbet-runtime (>= 0.5)
|
69
69
|
spoom (1.2.1)
|
data/README.md
CHANGED
@@ -26,9 +26,10 @@ require "open_feature"
|
|
26
26
|
# Configure global API properties
|
27
27
|
|
28
28
|
OpenFeature.set_provider(OpenFeature::NoOpProvider.new)
|
29
|
+
OpenFeature.set_evaluation_context(OpenFeature::EvaluationContext.new(fields: { "globally" => "available" }))
|
29
30
|
OpenFeature.add_hooks([OpenFeature::Hook.new]) # experimental, not fully supported
|
30
31
|
|
31
|
-
client = OpenFeature.create_client
|
32
|
+
client = OpenFeature.create_client(evaluation_context: OpenFeature::EvaluationContext.new(fields: { "client" => "available" }))
|
32
33
|
|
33
34
|
# Fetch boolean value
|
34
35
|
# Also methods available for String, Number, Integer, Float and Structure (Hash)
|
@@ -37,6 +38,9 @@ bool_value = client.fetch_boolean_value(flag_key: "my_toggle", default_value: fa
|
|
37
38
|
# Sorbet sprinkles in type safety
|
38
39
|
bool_value = client.fetch_boolean_value(flag_key: "my_toggle", default_value: "bad!") # => raises TypeError from Sorbet, invalid default value
|
39
40
|
|
41
|
+
# Additional evaluation context can be provided during invocation
|
42
|
+
number_value = client.fetch_number_value(flag_key: "my_toggle", default_value: 1, context: OpenFeature::EvaluationContext.new(fields: { "only_this_call_site" => 10 })) # => merges client and global context
|
43
|
+
|
40
44
|
# Fetch structure evaluation details
|
41
45
|
structure_evaluation_details = client.fetch_structure_details(flag_key: "my_structure", default_value: { "a" => "fallback" }) # => EvaluationDetails(value: Hash, flag_key: "my_structure", ...)
|
42
46
|
```
|
@@ -45,6 +49,10 @@ structure_evaluation_details = client.fetch_structure_details(flag_key: "my_stru
|
|
45
49
|
|
46
50
|
The OpenFeature specification defines [Structure as a potential return type](https://openfeature.dev/specification/types#structure). This is somewhat ambiguous in Ruby, further complicated by `T::Struct` that we get from Sorbet. For now, the type I've elected here is `T.any(T::Array[T.untyped], T::Hash[T.untyped, T.untyped]` (loosely, either an Array of untyped members or a Hash with untyped keys and untyped values) for flexibility but with a little more structure than a YML or JSON parsable string. This decision might change in the future upon further interpretation or new versions of the specification.
|
47
51
|
|
52
|
+
### Evaluation Context
|
53
|
+
|
54
|
+
We support global evaluation context (set on the `OpenFeature` module), client evaluation context (set on client instances or during client initialization) and invocation evaluation context (passed in during flag evaluation). In compliance with the specification, the invocation context merges into the client context which merges into the global context. Fields in invocation context take precedence over fields in the client context which take precedence over fields in the global context.
|
55
|
+
|
48
56
|
### Provider Interface
|
49
57
|
|
50
58
|
By default, this implementation sets the provider to the `OpenFeature::NoOpProvider` which always returns the default value. It's up to the individual teams to define their own providers based on their flag source (in the future, I'll release open-source providers based on various, common vendors).
|
data/lib/open_feature/client.rb
CHANGED
@@ -9,14 +9,25 @@ module OpenFeature
|
|
9
9
|
sig { returns(ClientMetadata) }
|
10
10
|
attr_reader :client_metadata
|
11
11
|
|
12
|
+
sig { returns(T.nilable(EvaluationContext)) }
|
13
|
+
attr_accessor :evaluation_context
|
14
|
+
|
12
15
|
sig { returns(T::Array[Hook]) }
|
13
16
|
attr_reader :hooks
|
14
17
|
|
15
|
-
sig
|
16
|
-
|
18
|
+
sig do
|
19
|
+
params(
|
20
|
+
provider: Provider,
|
21
|
+
name: T.nilable(String),
|
22
|
+
evaluation_context: T.nilable(EvaluationContext),
|
23
|
+
hooks: T::Array[Hook]
|
24
|
+
).void
|
25
|
+
end
|
26
|
+
def initialize(provider:, name: nil, evaluation_context: nil, hooks: [])
|
17
27
|
@provider = provider
|
18
28
|
@client_metadata = T.let(ClientMetadata.new(name: name), ClientMetadata)
|
19
|
-
@
|
29
|
+
@evaluation_context = evaluation_context
|
30
|
+
@hooks = hooks
|
20
31
|
end
|
21
32
|
|
22
33
|
sig { params(hooks: T.any(Hook, T::Array[Hook])).void }
|
@@ -33,7 +44,9 @@ module OpenFeature
|
|
33
44
|
).returns(T::Boolean)
|
34
45
|
end
|
35
46
|
def fetch_boolean_value(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
36
|
-
provider
|
47
|
+
provider
|
48
|
+
.resolve_boolean_value(flag_key: flag_key, default_value: default_value, context: build_context(context))
|
49
|
+
.value
|
37
50
|
rescue StandardError
|
38
51
|
default_value
|
39
52
|
end
|
@@ -47,7 +60,11 @@ module OpenFeature
|
|
47
60
|
).returns(EvaluationDetails[T::Boolean])
|
48
61
|
end
|
49
62
|
def fetch_boolean_details(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
50
|
-
details = provider.resolve_boolean_value(
|
63
|
+
details = provider.resolve_boolean_value(
|
64
|
+
flag_key: flag_key,
|
65
|
+
default_value: default_value,
|
66
|
+
context: build_context(context)
|
67
|
+
)
|
51
68
|
|
52
69
|
EvaluationDetails.from_resolution_details(details, flag_key: flag_key)
|
53
70
|
rescue StandardError => e
|
@@ -63,7 +80,9 @@ module OpenFeature
|
|
63
80
|
).returns(String)
|
64
81
|
end
|
65
82
|
def fetch_string_value(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
66
|
-
provider
|
83
|
+
provider
|
84
|
+
.resolve_string_value(flag_key: flag_key, default_value: default_value, context: build_context(context))
|
85
|
+
.value
|
67
86
|
rescue StandardError
|
68
87
|
default_value
|
69
88
|
end
|
@@ -77,7 +96,11 @@ module OpenFeature
|
|
77
96
|
).returns(EvaluationDetails[String])
|
78
97
|
end
|
79
98
|
def fetch_string_details(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
80
|
-
details = provider.resolve_string_value(
|
99
|
+
details = provider.resolve_string_value(
|
100
|
+
flag_key: flag_key,
|
101
|
+
default_value: default_value,
|
102
|
+
context: build_context(context)
|
103
|
+
)
|
81
104
|
|
82
105
|
EvaluationDetails.from_resolution_details(details, flag_key: flag_key)
|
83
106
|
rescue StandardError => e
|
@@ -93,7 +116,9 @@ module OpenFeature
|
|
93
116
|
).returns(Numeric)
|
94
117
|
end
|
95
118
|
def fetch_number_value(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
96
|
-
provider
|
119
|
+
provider
|
120
|
+
.resolve_number_value(flag_key: flag_key, default_value: default_value, context: build_context(context))
|
121
|
+
.value
|
97
122
|
rescue StandardError
|
98
123
|
default_value
|
99
124
|
end
|
@@ -107,7 +132,11 @@ module OpenFeature
|
|
107
132
|
).returns(EvaluationDetails[Numeric])
|
108
133
|
end
|
109
134
|
def fetch_number_details(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
110
|
-
details = provider.resolve_number_value(
|
135
|
+
details = provider.resolve_number_value(
|
136
|
+
flag_key: flag_key,
|
137
|
+
default_value: default_value,
|
138
|
+
context: build_context(context)
|
139
|
+
)
|
111
140
|
|
112
141
|
EvaluationDetails.from_resolution_details(details, flag_key: flag_key)
|
113
142
|
rescue StandardError => e
|
@@ -123,7 +152,10 @@ module OpenFeature
|
|
123
152
|
).returns(Integer)
|
124
153
|
end
|
125
154
|
def fetch_integer_value(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
126
|
-
provider
|
155
|
+
provider
|
156
|
+
.resolve_number_value(flag_key: flag_key, default_value: default_value, context: build_context(context))
|
157
|
+
.value
|
158
|
+
.to_i
|
127
159
|
rescue StandardError
|
128
160
|
default_value
|
129
161
|
end
|
@@ -137,7 +169,10 @@ module OpenFeature
|
|
137
169
|
).returns(Float)
|
138
170
|
end
|
139
171
|
def fetch_float_value(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
140
|
-
provider
|
172
|
+
provider
|
173
|
+
.resolve_number_value(flag_key: flag_key, default_value: default_value, context: build_context(context))
|
174
|
+
.value
|
175
|
+
.to_f
|
141
176
|
rescue StandardError
|
142
177
|
default_value
|
143
178
|
end
|
@@ -151,7 +186,9 @@ module OpenFeature
|
|
151
186
|
).returns(Structure)
|
152
187
|
end
|
153
188
|
def fetch_structure_value(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
154
|
-
provider
|
189
|
+
provider
|
190
|
+
.resolve_structure_value(flag_key: flag_key, default_value: default_value, context: build_context(context))
|
191
|
+
.value
|
155
192
|
rescue StandardError
|
156
193
|
default_value
|
157
194
|
end
|
@@ -165,7 +202,11 @@ module OpenFeature
|
|
165
202
|
).returns(EvaluationDetails[Structure])
|
166
203
|
end
|
167
204
|
def fetch_structure_details(flag_key:, default_value:, context: nil, options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
168
|
-
details = provider.resolve_structure_value(
|
205
|
+
details = provider.resolve_structure_value(
|
206
|
+
flag_key: flag_key,
|
207
|
+
default_value: default_value,
|
208
|
+
context: build_context(context)
|
209
|
+
)
|
169
210
|
|
170
211
|
EvaluationDetails.from_resolution_details(details, flag_key: flag_key)
|
171
212
|
rescue StandardError => e
|
@@ -176,5 +217,14 @@ module OpenFeature
|
|
176
217
|
|
177
218
|
sig { returns(Provider) }
|
178
219
|
attr_reader :provider
|
220
|
+
|
221
|
+
sig { params(invocation_context: T.nilable(EvaluationContext)).returns(T.nilable(EvaluationContext)) }
|
222
|
+
def build_context(invocation_context)
|
223
|
+
EvaluationContextBuilder.new.call(
|
224
|
+
global_context: OpenFeature.configuration.evaluation_context,
|
225
|
+
client_context: evaluation_context,
|
226
|
+
invocation_context: invocation_context
|
227
|
+
)
|
228
|
+
end
|
179
229
|
end
|
180
230
|
end
|
@@ -13,14 +13,18 @@ module OpenFeature
|
|
13
13
|
include Singleton
|
14
14
|
|
15
15
|
sig { returns(Provider) }
|
16
|
-
|
16
|
+
attr_accessor :provider
|
17
|
+
|
18
|
+
sig { returns(T.nilable(EvaluationContext)) }
|
19
|
+
attr_accessor :evaluation_context
|
17
20
|
|
18
21
|
sig { returns(T::Array[Hook]) }
|
19
|
-
|
22
|
+
attr_accessor :hooks
|
20
23
|
|
21
24
|
sig { void }
|
22
25
|
def initialize
|
23
26
|
@provider = T.let(NoOpProvider.new, Provider)
|
27
|
+
@evaluation_context = T.let(nil, T.nilable(EvaluationContext))
|
24
28
|
@hooks = T.let([], T::Array[Hook])
|
25
29
|
end
|
26
30
|
|
@@ -29,19 +33,11 @@ module OpenFeature
|
|
29
33
|
provider.metadata
|
30
34
|
end
|
31
35
|
|
32
|
-
sig { params(provider: Provider).void }
|
33
|
-
def set_provider(provider) # rubocop:disable Naming/AccessorMethodName
|
34
|
-
@provider = provider
|
35
|
-
end
|
36
|
-
|
37
|
-
sig { params(hooks: T.any(Hook, T::Array[Hook])).void }
|
38
|
-
def add_hooks(hooks)
|
39
|
-
@hooks.concat(Array(hooks))
|
40
|
-
end
|
41
|
-
|
42
36
|
sig { void }
|
43
|
-
def
|
37
|
+
def reset!
|
38
|
+
@provider = OpenFeature::NoOpProvider.new
|
44
39
|
@hooks = []
|
40
|
+
@evaluation_context = nil
|
45
41
|
end
|
46
42
|
end
|
47
43
|
end
|
@@ -1,10 +1,50 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "date"
|
5
|
+
|
4
6
|
module OpenFeature
|
5
7
|
# Provides ambient information for the purposes of flag evaluation.
|
6
8
|
# Currently does not meet specification!
|
7
9
|
class EvaluationContext < T::Struct
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
include T::Struct::ActsAsComparable
|
13
|
+
|
14
|
+
FieldValueType = T.type_alias { T.any(T::Boolean, String, Numeric, DateTime, Structure) }
|
15
|
+
|
8
16
|
const :targeting_key, T.nilable(String)
|
17
|
+
const :fields, T::Hash[String, FieldValueType], default: {}
|
18
|
+
|
19
|
+
sig { params(method_name: Symbol).returns(T::Boolean) }
|
20
|
+
def respond_to_missing?(method_name)
|
21
|
+
fields.key?(method_name.to_s)
|
22
|
+
end
|
23
|
+
|
24
|
+
sig { params(method_name: Symbol).returns(T.nilable(FieldValueType)) }
|
25
|
+
def method_missing(method_name)
|
26
|
+
fields.fetch(method_name.to_s, nil)
|
27
|
+
end
|
28
|
+
|
29
|
+
sig { params(key: String, value: FieldValueType).returns(EvaluationContext) }
|
30
|
+
def add_field(key, value)
|
31
|
+
EvaluationContext.new(
|
32
|
+
targeting_key: targeting_key,
|
33
|
+
fields: fields.merge({ key => value })
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { returns(T::Hash[String, FieldValueType]) }
|
38
|
+
def to_h
|
39
|
+
targeting_key.nil? ? fields : fields.merge("targeting_key" => targeting_key)
|
40
|
+
end
|
41
|
+
|
42
|
+
sig { params(overriding_context: EvaluationContext).returns(EvaluationContext) }
|
43
|
+
def merge(overriding_context)
|
44
|
+
EvaluationContext.new(
|
45
|
+
targeting_key: overriding_context.targeting_key || targeting_key,
|
46
|
+
fields: fields.merge(overriding_context.fields)
|
47
|
+
)
|
48
|
+
end
|
9
49
|
end
|
10
50
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module OpenFeature
|
5
|
+
# Used to combine evaluation contexts from different sources
|
6
|
+
class EvaluationContextBuilder
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig do
|
10
|
+
params(
|
11
|
+
global_context: T.nilable(EvaluationContext),
|
12
|
+
client_context: T.nilable(EvaluationContext),
|
13
|
+
invocation_context: T.nilable(EvaluationContext)
|
14
|
+
).returns(T.nilable(EvaluationContext))
|
15
|
+
end
|
16
|
+
def call(global_context:, client_context:, invocation_context:)
|
17
|
+
available_contexts = [global_context, client_context, invocation_context].compact
|
18
|
+
|
19
|
+
return nil if available_contexts.empty?
|
20
|
+
|
21
|
+
available_contexts.reduce(EvaluationContext.new) do |built_context, context|
|
22
|
+
built_context.merge(context)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/open_feature.rb
CHANGED
@@ -19,17 +19,33 @@ module OpenFeature
|
|
19
19
|
|
20
20
|
sig { params(provider: Provider).void }
|
21
21
|
def set_provider(provider) # rubocop:disable Naming/AccessorMethodName
|
22
|
-
configuration.
|
22
|
+
configuration.provider = provider
|
23
|
+
end
|
24
|
+
|
25
|
+
sig { params(context: EvaluationContext).void }
|
26
|
+
def set_evaluation_context(context) # rubocop:disable Naming/AccessorMethodName
|
27
|
+
configuration.evaluation_context = context
|
23
28
|
end
|
24
29
|
|
25
30
|
sig { params(hooks: T.any(Hook, T::Array[Hook])).void }
|
26
31
|
def add_hooks(hooks)
|
27
|
-
configuration.
|
32
|
+
configuration.hooks.concat(Array(hooks))
|
28
33
|
end
|
29
34
|
|
30
|
-
sig
|
31
|
-
|
32
|
-
|
35
|
+
sig do
|
36
|
+
params(
|
37
|
+
name: T.nilable(String),
|
38
|
+
evaluation_context: T.nilable(EvaluationContext),
|
39
|
+
hooks: T.nilable(T.any(Hook, T::Array[Hook]))
|
40
|
+
).returns(Client)
|
41
|
+
end
|
42
|
+
def create_client(name: nil, evaluation_context: nil, hooks: nil)
|
43
|
+
Client.new(
|
44
|
+
provider: configuration.provider,
|
45
|
+
name: name,
|
46
|
+
evaluation_context: evaluation_context,
|
47
|
+
hooks: Array(hooks)
|
48
|
+
)
|
33
49
|
end
|
34
50
|
|
35
51
|
sig { returns(Configuration) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openfeature-sdk-sorbet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max VelDink
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/open_feature/configuration.rb
|
77
77
|
- lib/open_feature/error_code.rb
|
78
78
|
- lib/open_feature/evaluation_context.rb
|
79
|
+
- lib/open_feature/evaluation_context_builder.rb
|
79
80
|
- lib/open_feature/evaluation_details.rb
|
80
81
|
- lib/open_feature/evaluation_options.rb
|
81
82
|
- lib/open_feature/flag_metadata.rb
|