subflag-openfeature-provider 0.1.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40e8537098d52a561735926123fc60c1ad200f3762151588e101f815447cf822
4
- data.tar.gz: 42821e1d8a10786803898a2d17d1c82002f24a314351cb3b61aa7b43c0cca2ba
3
+ metadata.gz: 9914622ce4a7e664e18441f4c979ad8c9a9f90a9335efc437523b1695fa0823d
4
+ data.tar.gz: a1b4dd15bd439397c2da8b38c90b8f81e98d4de040189c8b68e62a68e202ec3a
5
5
  SHA512:
6
- metadata.gz: 8ae9b2658c93632d4cbcbee3af96c27fccda6c099f8f144a225b79961298f5851f7757c7404583bc235fc643f510ce0175fb579def7ebf285f9d97bb3f14cf67
7
- data.tar.gz: e59f3c5b24a9a3f18fad1ceb09fb1d0dda9084f355abfd8d2862f3da81fcf4dc564dbf7143cbfa4fc948482a0efe69c8a94444f1b47c19d076ba5c0605fd0cd4
6
+ metadata.gz: e1a8d3e652e1c54d5154e14d2e7ac6a2701e64868c25ad119f91bec8783274f1bbc530e43f898b2b6b627deed2e15f5d3010053c9994ebbba1cf59848b43c238
7
+ data.tar.gz: 94e5f871a6485caa293980078c29a06c33aad49eecdd4409a846b4288d021a6eaf728b0ea85a577f83d6eacf8ebf172e9185417fbcdcef7dc7e50280e2c348b5
data/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.3.1] - 2025-12-07
6
+
7
+ ### Fixed
8
+
9
+ - `EvaluationResult.from_response` now accepts both camelCase (API format) and snake_case (Ruby format) keys, making `to_h` output compatible with `from_response`
10
+
11
+ ## [0.2.1] - 2025-11-30
12
+
13
+ ### Fixed
14
+
15
+ - Fixed Gemfile.lock sync issue
16
+
17
+ ## [0.2.0] - 2025-11-30
18
+
19
+ ### Changed
20
+
21
+ - **Breaking**: Provider now returns `OpenFeature::SDK::Provider::ResolutionDetails` instead of plain Hash
22
+ - Added `require "open_feature/sdk"` for proper SDK integration
23
+
24
+ ### Fixed
25
+
26
+ - Fixed compatibility with OpenFeature Ruby SDK 0.4.x
27
+
28
+ ## [0.1.0] - 2025-11-30
29
+
30
+ ### Added
31
+
32
+ - Initial release
33
+ - OpenFeature provider implementation for Subflag
34
+ - Support for boolean, string, integer, float, and object flag types
35
+ - Evaluation context support with targeting key
36
+ - Error handling with proper OpenFeature error codes
37
+ - Direct client usage without OpenFeature SDK
data/README.md CHANGED
@@ -19,7 +19,7 @@ bundle add subflag-openfeature-provider
19
19
  ### With OpenFeature SDK
20
20
 
21
21
  ```ruby
22
- require "openfeature/sdk"
22
+ require "open_feature/sdk"
23
23
  require "subflag"
24
24
 
25
25
  # Configure the provider
@@ -13,17 +13,22 @@ module Subflag
13
13
  ERROR
14
14
  ].freeze
15
15
 
16
- attr_reader :flag_key, :value, :variant, :reason
16
+ # Valid flag statuses
17
+ FLAG_STATUSES = %w[ACTIVE DEPRECATED].freeze
18
+
19
+ attr_reader :flag_key, :value, :variant, :reason, :flag_status
17
20
 
18
21
  # @param flag_key [String] The key of the evaluated flag
19
22
  # @param value [Object] The evaluated value (type depends on flag configuration)
20
23
  # @param variant [String] The name of the selected variant
21
24
  # @param reason [String] Why this value was selected (one of REASONS)
22
- def initialize(flag_key:, value:, variant:, reason:)
25
+ # @param flag_status [String, nil] Lifecycle status of the flag (ACTIVE, DEPRECATED)
26
+ def initialize(flag_key:, value:, variant:, reason:, flag_status: nil)
23
27
  @flag_key = flag_key
24
28
  @value = value
25
29
  @variant = variant
26
30
  @reason = reason
31
+ @flag_status = flag_status
27
32
  end
28
33
 
29
34
  # Create from API response hash
@@ -34,14 +39,23 @@ module Subflag
34
39
  flag_key: fetch_key(data, "flagKey"),
35
40
  value: fetch_key(data, "value"),
36
41
  variant: fetch_key(data, "variant"),
37
- reason: fetch_key(data, "reason")
42
+ reason: fetch_key(data, "reason"),
43
+ flag_status: fetch_key(data, "flagStatus")
38
44
  )
39
45
  end
40
46
 
41
- # Fetch a key from hash, checking both string and symbol keys
47
+ # Fetch a key from hash, checking string, symbol, and snake_case variants
42
48
  # Can't use || because false values would be skipped
43
49
  def self.fetch_key(data, key)
44
- data.key?(key) ? data[key] : data[key.to_sym]
50
+ # Try camelCase string (API format)
51
+ return data[key] if data.key?(key)
52
+ # Try camelCase symbol
53
+ return data[key.to_sym] if data.key?(key.to_sym)
54
+ # Try snake_case symbol (from to_h)
55
+ snake_key = key.gsub(/([a-z])([A-Z])/, '\1_\2').downcase.to_sym
56
+ return data[snake_key] if data.key?(snake_key)
57
+ # Try snake_case string
58
+ data[snake_key.to_s]
45
59
  end
46
60
 
47
61
  # Check if evaluation was successful (not an error)
@@ -50,6 +64,12 @@ module Subflag
50
64
  reason != "ERROR"
51
65
  end
52
66
 
67
+ # Check if the flag is deprecated
68
+ # @return [Boolean]
69
+ def deprecated?
70
+ @flag_status == "DEPRECATED"
71
+ end
72
+
53
73
  # Convert to hash
54
74
  # @return [Hash]
55
75
  def to_h
@@ -57,7 +77,8 @@ module Subflag
57
77
  flag_key: @flag_key,
58
78
  value: @value,
59
79
  variant: @variant,
60
- reason: @reason
80
+ reason: @reason,
81
+ flag_status: @flag_status
61
82
  }
62
83
  end
63
84
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "open_feature/sdk"
4
+
3
5
  module Subflag
4
6
  # OpenFeature provider for Subflag feature flag management.
5
7
  #
@@ -124,6 +126,9 @@ module Subflag
124
126
  context = EvaluationContext.from_openfeature(evaluation_context)
125
127
  result = @client.evaluate(flag_key, context: context)
126
128
 
129
+ # Warn if flag is deprecated
130
+ warn_if_deprecated(result)
131
+
127
132
  # Validate type matches
128
133
  unless type_matches?(result.value, expected_type)
129
134
  return error_result(
@@ -136,12 +141,12 @@ module Subflag
136
141
  # Convert value if needed (e.g., number -> integer)
137
142
  converted_value = convert_value(result.value, expected_type)
138
143
 
139
- {
144
+ OpenFeature::SDK::Provider::ResolutionDetails.new(
140
145
  value: converted_value,
141
146
  reason: map_reason(result.reason),
142
147
  variant: result.variant,
143
148
  flag_metadata: { flag_key: result.flag_key }
144
- }
149
+ )
145
150
  rescue FlagNotFoundError => e
146
151
  error_result(default_value, error_code: :flag_not_found, error_message: e.message)
147
152
  rescue AuthenticationError => e
@@ -200,14 +205,22 @@ module Subflag
200
205
  end
201
206
  end
202
207
 
203
- # Build error result hash
208
+ # Build error result
204
209
  def error_result(default_value, error_code:, error_message:)
205
- {
210
+ OpenFeature::SDK::Provider::ResolutionDetails.new(
206
211
  value: default_value,
207
212
  reason: :error,
208
213
  error_code: error_code,
209
214
  error_message: error_message
210
- }
215
+ )
216
+ end
217
+
218
+ # Log a warning if the flag is deprecated
219
+ def warn_if_deprecated(result)
220
+ return unless result.deprecated?
221
+
222
+ warn "[Subflag] Flag \"#{result.flag_key}\" is deprecated and scheduled for removal. " \
223
+ "Please migrate away from this flag."
211
224
  end
212
225
  end
213
226
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Subflag
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subflag-openfeature-provider
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Subflag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-30 00:00:00.000000000 Z
11
+ date: 2025-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -132,6 +132,7 @@ files:
132
132
  - ".rspec"
133
133
  - ".rspec_status"
134
134
  - ".rubocop.yml"
135
+ - CHANGELOG.md
135
136
  - README.md
136
137
  - Rakefile
137
138
  - lib/subflag.rb