configcat-openfeature-provider 0.1.0
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 +7 -0
- data/.github/CODEOWNERS +1 -0
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/ci.yml +39 -0
- data/.github/workflows/publish.yml +23 -0
- data/.github/workflows/stale.yml +12 -0
- data/.gitignore +60 -0
- data/.rspec +4 -0
- data/.standard.yml +5 -0
- data/CHANGELOG.md +1 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +90 -0
- data/LICENSE +21 -0
- data/README.md +60 -0
- data/Rakefile +10 -0
- data/configcat-openfeature-provider.gemspec +41 -0
- data/lib/configcat-openfeature-provider/provider.rb +173 -0
- data/lib/configcat-openfeature-provider/version.rb +7 -0
- data/lib/configcat-openfeature-provider.rb +7 -0
- data/samples/provider-sample/Gemfile +3 -0
- data/samples/provider-sample/Gemfile.lock +25 -0
- data/samples/provider-sample/main.rb +38 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bed72c8e9d480f7f261be86b760a6328c2d30a37debbf2835f6f55e8eca8a6b7
|
4
|
+
data.tar.gz: 0af26ce4ad07589802f0dde75aa4f9be8b23d0345c4d84e60e608b23bf75bc41
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2a4c439d0849b523ddbd08228cde46f5e92747ea0936ad56d53598de61d352ccb5807a5cff04312b2f29c5aa92f6a367a3f32f7a8242bf55db267fcd385b5af5
|
7
|
+
data.tar.gz: d76022f65cbfd1f220ae452c0b1ffd48891a0be017d90f9ac9443f8c1ed5789483b5f3fdc6457767ec8ca97c53facf11c60983ff8903b15bcbbf1f284b2dc796
|
data/.github/CODEOWNERS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* @configcat/developers
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ '*' ]
|
6
|
+
paths-ignore:
|
7
|
+
- '**.md'
|
8
|
+
pull_request:
|
9
|
+
paths-ignore:
|
10
|
+
- '**.md'
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
standard:
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v4
|
17
|
+
- uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 3.2
|
20
|
+
- run: bundle install
|
21
|
+
- run: bundle exec rake standard
|
22
|
+
|
23
|
+
test:
|
24
|
+
runs-on: ubuntu-latest
|
25
|
+
name: Ruby ${{ matrix.ruby }}
|
26
|
+
strategy:
|
27
|
+
matrix:
|
28
|
+
ruby:
|
29
|
+
- "3.3"
|
30
|
+
- "3.2"
|
31
|
+
- "3.1"
|
32
|
+
|
33
|
+
steps:
|
34
|
+
- uses: actions/checkout@v4
|
35
|
+
- uses: ruby/setup-ruby@v1
|
36
|
+
with:
|
37
|
+
ruby-version: ${{ matrix.ruby }}
|
38
|
+
- run: bundle install
|
39
|
+
- run: bundle exec rspec
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Publish
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ]
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
publish:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v4
|
11
|
+
- uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 3.2
|
14
|
+
- name: Publish to RubyGems
|
15
|
+
run: |
|
16
|
+
mkdir -p $HOME/.gem
|
17
|
+
touch $HOME/.gem/credentials
|
18
|
+
chmod 0600 $HOME/.gem/credentials
|
19
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
20
|
+
gem build *.gemspec
|
21
|
+
gem push *.gem
|
22
|
+
env:
|
23
|
+
GEM_HOST_API_KEY: "${{ secrets.GEM_API_KEY }}"
|
data/.gitignore
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
# Used by dotenv library to load environment variables.
|
14
|
+
# .env
|
15
|
+
|
16
|
+
# Ignore Byebug command history file.
|
17
|
+
.byebug_history
|
18
|
+
|
19
|
+
## Specific to RubyMotion:
|
20
|
+
.dat*
|
21
|
+
.repl_history
|
22
|
+
build/
|
23
|
+
*.bridgesupport
|
24
|
+
build-iPhoneOS/
|
25
|
+
build-iPhoneSimulator/
|
26
|
+
|
27
|
+
## Specific to RubyMotion (use of CocoaPods):
|
28
|
+
#
|
29
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
30
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
31
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
32
|
+
#
|
33
|
+
# vendor/Pods/
|
34
|
+
|
35
|
+
## Documentation cache and generated files:
|
36
|
+
/.yardoc/
|
37
|
+
/_yardoc/
|
38
|
+
/doc/
|
39
|
+
/rdoc/
|
40
|
+
|
41
|
+
## Environment normalization:
|
42
|
+
/.bundle/
|
43
|
+
/vendor/bundle
|
44
|
+
/lib/bundler/man/
|
45
|
+
|
46
|
+
# for a library or gem, you might want to ignore these files since the code is
|
47
|
+
# intended to run in multiple environments; otherwise, check them in:
|
48
|
+
# Gemfile.lock
|
49
|
+
# .ruby-version
|
50
|
+
# .ruby-gemset
|
51
|
+
|
52
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
53
|
+
.rvmrc
|
54
|
+
|
55
|
+
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
56
|
+
# .rubocop-https?--*
|
57
|
+
|
58
|
+
.idea
|
59
|
+
|
60
|
+
.rspec_status
|
data/.rspec
ADDED
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Please check the [Github Releases](https://github.com/configcat/openfeature-ruby/releases) page for the changelog of the ConfigCat OpenFeature Provider for Ruby.
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Contributing to the ConfigCat OpenFeature Provider for Ruby
|
2
|
+
|
3
|
+
ConfigCat SDK is an open source project. Feedback and contribution are welcome. Contributions are made to this repo via Issues and Pull Requests.
|
4
|
+
|
5
|
+
## Submitting bug reports and feature requests
|
6
|
+
|
7
|
+
The ConfigCat SDK team monitors the [issue tracker](https://github.com/configcat/openfeature-ruby/issues) in the Provider repository. Bug reports and feature requests specific to this SDK should be filed in this issue tracker. The team will respond to all newly filed issues.
|
8
|
+
|
9
|
+
## Submitting pull requests
|
10
|
+
|
11
|
+
We encourage pull requests and other contributions from the community.
|
12
|
+
- Before submitting pull requests, ensure that all temporary or unintended code is removed.
|
13
|
+
- Be accompanied by a complete Pull Request template (loaded automatically when a PR is created).
|
14
|
+
- Add unit or integration tests for fixed or changed functionality.
|
15
|
+
|
16
|
+
When you submit a pull request or otherwise seek to include your change in the repository, you waive all your intellectual property rights, including your copyright and patent claims for the submission. For more details please read the [contribution agreement](https://github.com/configcat/legal/blob/main/contribution-agreement.md).
|
17
|
+
|
18
|
+
In general, we follow the ["fork-and-pull" Git workflow](https://github.com/susam/gitpr)
|
19
|
+
|
20
|
+
1. Fork the repository to your own GitHub account
|
21
|
+
2. Clone the project to your machine
|
22
|
+
3. Create a branch locally with a succinct but descriptive name
|
23
|
+
4. Commit changes to the branch
|
24
|
+
5. Following any formatting and testing guidelines specific to this repo
|
25
|
+
6. Push changes to your fork
|
26
|
+
7. Open a PR in our repository and follow the PR template so that we can efficiently review the changes.
|
27
|
+
|
28
|
+
## Build instructions
|
29
|
+
|
30
|
+
This provider is built with [Bundler](https://bundler.io). To install Bundler, run `gem install bundler`.
|
31
|
+
|
32
|
+
To install dependencies:
|
33
|
+
|
34
|
+
```bash
|
35
|
+
bundle install
|
36
|
+
```
|
37
|
+
|
38
|
+
## Running tests
|
39
|
+
|
40
|
+
```bash
|
41
|
+
bundle exec rspec spec
|
42
|
+
```
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
configcat-openfeature-provider (0.1.0)
|
5
|
+
configcat (~> 8.0.1)
|
6
|
+
openfeature-sdk (~> 0.4.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
ast (2.4.3)
|
12
|
+
concurrent-ruby (1.3.5)
|
13
|
+
configcat (8.0.1)
|
14
|
+
concurrent-ruby (~> 1.1)
|
15
|
+
semantic (~> 1.6)
|
16
|
+
diff-lcs (1.6.2)
|
17
|
+
json (2.12.2)
|
18
|
+
language_server-protocol (3.17.0.5)
|
19
|
+
lint_roller (1.1.0)
|
20
|
+
openfeature-sdk (0.4.0)
|
21
|
+
parallel (1.27.0)
|
22
|
+
parser (3.3.8.0)
|
23
|
+
ast (~> 2.4.1)
|
24
|
+
racc
|
25
|
+
prism (1.4.0)
|
26
|
+
racc (1.8.1)
|
27
|
+
rainbow (3.1.1)
|
28
|
+
rake (13.2.1)
|
29
|
+
regexp_parser (2.10.0)
|
30
|
+
rspec (3.12.0)
|
31
|
+
rspec-core (~> 3.12.0)
|
32
|
+
rspec-expectations (~> 3.12.0)
|
33
|
+
rspec-mocks (~> 3.12.0)
|
34
|
+
rspec-core (3.12.3)
|
35
|
+
rspec-support (~> 3.12.0)
|
36
|
+
rspec-expectations (3.12.4)
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
+
rspec-support (~> 3.12.0)
|
39
|
+
rspec-mocks (3.12.7)
|
40
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
41
|
+
rspec-support (~> 3.12.0)
|
42
|
+
rspec-support (3.12.2)
|
43
|
+
rubocop (1.75.7)
|
44
|
+
json (~> 2.3)
|
45
|
+
language_server-protocol (~> 3.17.0.2)
|
46
|
+
lint_roller (~> 1.1.0)
|
47
|
+
parallel (~> 1.10)
|
48
|
+
parser (>= 3.3.0.2)
|
49
|
+
rainbow (>= 2.2.2, < 4.0)
|
50
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
51
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
52
|
+
ruby-progressbar (~> 1.7)
|
53
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
54
|
+
rubocop-ast (1.44.1)
|
55
|
+
parser (>= 3.3.7.2)
|
56
|
+
prism (~> 1.4)
|
57
|
+
rubocop-performance (1.25.0)
|
58
|
+
lint_roller (~> 1.1)
|
59
|
+
rubocop (>= 1.75.0, < 2.0)
|
60
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
61
|
+
ruby-progressbar (1.13.0)
|
62
|
+
semantic (1.6.1)
|
63
|
+
standard (1.50.0)
|
64
|
+
language_server-protocol (~> 3.17.0.2)
|
65
|
+
lint_roller (~> 1.0)
|
66
|
+
rubocop (~> 1.75.5)
|
67
|
+
standard-custom (~> 1.0.0)
|
68
|
+
standard-performance (~> 1.8)
|
69
|
+
standard-custom (1.0.2)
|
70
|
+
lint_roller (~> 1.0)
|
71
|
+
rubocop (~> 1.50)
|
72
|
+
standard-performance (1.8.0)
|
73
|
+
lint_roller (~> 1.1)
|
74
|
+
rubocop-performance (~> 1.25.0)
|
75
|
+
unicode-display_width (3.1.4)
|
76
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
77
|
+
unicode-emoji (4.0.4)
|
78
|
+
|
79
|
+
PLATFORMS
|
80
|
+
x64-mingw-ucrt
|
81
|
+
|
82
|
+
DEPENDENCIES
|
83
|
+
configcat-openfeature-provider!
|
84
|
+
rake (~> 13.0)
|
85
|
+
rspec (~> 3.12)
|
86
|
+
standard
|
87
|
+
standard-performance
|
88
|
+
|
89
|
+
BUNDLED WITH
|
90
|
+
2.6.9
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 ConfigCat
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# ConfigCat OpenFeature Provider for Ruby
|
2
|
+
|
3
|
+
[](https://github.com/configcat/openfeature-ruby/actions/workflows/ci.yml)
|
4
|
+
[](https://rubygems.org/gems/configcat-openfeature-provider)
|
5
|
+
|
6
|
+
This repository contains an OpenFeature provider that allows [ConfigCat](https://configcat.com) to be used with the [OpenFeature Ruby SDK](https://github.com/open-feature/ruby-sdk).
|
7
|
+
|
8
|
+
## Requirements
|
9
|
+
- Ruby >= 3.1
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
```sh
|
14
|
+
gem install configcat-openfeature-provider
|
15
|
+
```
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
The initializer of `ConfigCat::OpenFeature::Provider` takes the SDK key and an optional `ConfigCat::ConfigCatOptions` argument containing the additional configuration options for the [ConfigCat Ruby SDK](https://github.com/configcat/ruby-sdk):
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require "configcat-openfeature-provider"
|
23
|
+
|
24
|
+
# Configure the OpenFeature API with the ConfigCat provider.
|
25
|
+
OpenFeature::SDK.configure do |config|
|
26
|
+
config.set_provider(ConfigCat::OpenFeature::Provider.new(
|
27
|
+
sdk_key: "<YOUR-CONFIGCAT-SDK-KEY>",
|
28
|
+
# Build options for the ConfigCat SDK.
|
29
|
+
options: ConfigCat::ConfigCatOptions.new(
|
30
|
+
polling_mode: ConfigCat::PollingMode.auto_poll,
|
31
|
+
offline: false
|
32
|
+
)))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Create a client.
|
36
|
+
client = OpenFeature::SDK.build_client
|
37
|
+
|
38
|
+
# Evaluate feature flag.
|
39
|
+
flag_value = client.fetch_boolean_value(
|
40
|
+
flag_key: "isMyAwesomeFeatureEnabled",
|
41
|
+
default_value: false
|
42
|
+
)
|
43
|
+
```
|
44
|
+
|
45
|
+
For more information about all the configuration options, see the [Ruby SDK documentation](https://configcat.com/docs/sdk-reference/ruby/#creating-the-configcat-client).
|
46
|
+
|
47
|
+
## Need help?
|
48
|
+
https://configcat.com/support
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
Contributions are welcome. For more info please read the [Contribution Guideline](CONTRIBUTING.md).
|
52
|
+
|
53
|
+
## About ConfigCat
|
54
|
+
ConfigCat is a feature flag and configuration management service that lets you separate releases from deployments. You can turn your features ON/OFF using <a href="https://app.configcat.com" target="_blank">ConfigCat Dashboard</a> even after they are deployed. ConfigCat lets you target specific groups of users based on region, email or any other custom user attribute.
|
55
|
+
|
56
|
+
ConfigCat is a <a href="https://configcat.com" target="_blank">hosted feature flag service</a>. Manage feature toggles across frontend, backend, mobile, desktop apps. <a href="https://configcat.com" target="_blank">Alternative to LaunchDarkly</a>. Management app + feature flag SDKs.
|
57
|
+
|
58
|
+
- [Official ConfigCat SDKs for other platforms](https://github.com/configcat)
|
59
|
+
- [Documentation](https://configcat.com/docs)
|
60
|
+
- [Blog](https://configcat.com/blog)
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/configcat-openfeature-provider/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "configcat-openfeature-provider"
|
7
|
+
spec.version = ConfigCat::OpenFeature::VERSION
|
8
|
+
spec.authors = ["ConfigCat"]
|
9
|
+
spec.email = ["developer@configcat.com"]
|
10
|
+
spec.licenses = ["MIT"]
|
11
|
+
|
12
|
+
spec.summary = "ConfigCat OpenFeature Provider for Ruby."
|
13
|
+
spec.description = "OpenFeature Provider that allows ConfigCat to be used with the OpenFeature Ruby SDK."
|
14
|
+
|
15
|
+
spec.homepage = "https://configcat.com"
|
16
|
+
|
17
|
+
spec.required_ruby_version = ">= 3.1"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/configcat/openfeature-ruby"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/configcat/openfeature-ruby/blob/main/CHANGELOG.md"
|
22
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/configcat/openfeature-ruby/issues"
|
23
|
+
spec.metadata["documentation_uri"] = "https://configcat.com/docs/sdk-reference/openfeature/ruby"
|
24
|
+
|
25
|
+
# Specify which files should be added to the gem when it is released.
|
26
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
27
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
28
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
|
+
end
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
spec.add_dependency "configcat", "~> 8.0.1"
|
35
|
+
spec.add_dependency "openfeature-sdk", "~> 0.4.0"
|
36
|
+
|
37
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
38
|
+
spec.add_development_dependency "rspec", "~> 3.12"
|
39
|
+
spec.add_development_dependency "standard"
|
40
|
+
spec.add_development_dependency "standard-performance"
|
41
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "open_feature/sdk"
|
4
|
+
require "configcat"
|
5
|
+
|
6
|
+
module ConfigCat
|
7
|
+
module OpenFeature
|
8
|
+
class Provider
|
9
|
+
PROVIDER_NAME = "ConfigCatProvider"
|
10
|
+
attr_reader :metadata
|
11
|
+
|
12
|
+
def initialize(sdk_key:, options: ConfigCatOptions.new)
|
13
|
+
@metadata = ::OpenFeature::SDK::Provider::ProviderMetadata.new(name: PROVIDER_NAME)
|
14
|
+
@client = ConfigCatClient.get(sdk_key, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
|
18
|
+
user = ctx_to_user(evaluation_context)
|
19
|
+
evaluation_detail = @client.get_value_details(flag_key, default_value, user)
|
20
|
+
|
21
|
+
unless [true, false].include?(evaluation_detail.value)
|
22
|
+
return type_mismatch(default_value)
|
23
|
+
end
|
24
|
+
|
25
|
+
produce_result(evaluation_detail, default_value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
|
29
|
+
user = ctx_to_user(evaluation_context)
|
30
|
+
evaluation_detail = @client.get_value_details(flag_key, default_value, user)
|
31
|
+
|
32
|
+
unless evaluation_detail.value.is_a?(String)
|
33
|
+
return type_mismatch(default_value)
|
34
|
+
end
|
35
|
+
|
36
|
+
produce_result(evaluation_detail, default_value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
|
40
|
+
user = ctx_to_user(evaluation_context)
|
41
|
+
evaluation_detail = @client.get_value_details(flag_key, default_value, user)
|
42
|
+
|
43
|
+
unless evaluation_detail.value.is_a?(Numeric)
|
44
|
+
return type_mismatch(default_value)
|
45
|
+
end
|
46
|
+
|
47
|
+
produce_numeric_result(evaluation_detail, default_value, Numeric)
|
48
|
+
end
|
49
|
+
|
50
|
+
def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
|
51
|
+
user = ctx_to_user(evaluation_context)
|
52
|
+
evaluation_detail = @client.get_value_details(flag_key, default_value, user)
|
53
|
+
|
54
|
+
unless evaluation_detail.value.is_a?(Numeric)
|
55
|
+
return type_mismatch(default_value)
|
56
|
+
end
|
57
|
+
|
58
|
+
produce_numeric_result(evaluation_detail, default_value, Integer)
|
59
|
+
end
|
60
|
+
|
61
|
+
def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
|
62
|
+
user = ctx_to_user(evaluation_context)
|
63
|
+
evaluation_detail = @client.get_value_details(flag_key, default_value, user)
|
64
|
+
|
65
|
+
unless evaluation_detail.value.is_a?(Numeric)
|
66
|
+
return type_mismatch(default_value)
|
67
|
+
end
|
68
|
+
|
69
|
+
produce_numeric_result(evaluation_detail, default_value, Float)
|
70
|
+
end
|
71
|
+
|
72
|
+
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
|
73
|
+
user = ctx_to_user(evaluation_context)
|
74
|
+
evaluation_detail = @client.get_value_details(flag_key, "", user)
|
75
|
+
|
76
|
+
unless evaluation_detail.value.is_a?(String)
|
77
|
+
return type_mismatch(default_value)
|
78
|
+
end
|
79
|
+
|
80
|
+
result = produce_result(evaluation_detail, default_value)
|
81
|
+
begin
|
82
|
+
result.value = JSON.parse(result.value)
|
83
|
+
rescue JSON::ParserError, TypeError
|
84
|
+
return ::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
85
|
+
value: default_value,
|
86
|
+
error_code: ::OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH,
|
87
|
+
error_message: "Could not parse '#{result.value}' as JSON",
|
88
|
+
reason: ::OpenFeature::SDK::Provider::Reason::ERROR
|
89
|
+
)
|
90
|
+
end
|
91
|
+
result
|
92
|
+
end
|
93
|
+
|
94
|
+
# @param evaluation_context [::OpenFeature::SDK::EvaluationContext, nil]
|
95
|
+
#
|
96
|
+
# @return [ConfigCat::User, nil]
|
97
|
+
private def ctx_to_user(evaluation_context)
|
98
|
+
if evaluation_context.nil? || evaluation_context.fields.nil? || evaluation_context.fields.empty?
|
99
|
+
return nil
|
100
|
+
end
|
101
|
+
|
102
|
+
email = evaluation_context.field("Email")
|
103
|
+
country = evaluation_context.field("Country")
|
104
|
+
|
105
|
+
ConfigCat::User.new(evaluation_context.targeting_key, email: email, country: country, custom: evaluation_context.fields)
|
106
|
+
end
|
107
|
+
|
108
|
+
private def type_mismatch(default_value)
|
109
|
+
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
110
|
+
value: default_value,
|
111
|
+
reason: ::OpenFeature::SDK::Provider::Reason::ERROR,
|
112
|
+
error_code: ::OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
# @param evaluation_detail [ConfigCat::EvaluationDetails]
|
117
|
+
# @param default_value [any]
|
118
|
+
#
|
119
|
+
# @return [::OpenFeature::SDK::ResolutionDetails]
|
120
|
+
private def produce_result(evaluation_detail, default_value)
|
121
|
+
unless evaluation_detail.error.nil?
|
122
|
+
error_code = evaluation_detail.error.include?("key was not found in config JSON") ? ::OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND : ::OpenFeature::SDK::Provider::ErrorCode::GENERAL
|
123
|
+
return ::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
124
|
+
value: default_value,
|
125
|
+
reason: ::OpenFeature::SDK::Provider::Reason::ERROR,
|
126
|
+
error_code: error_code,
|
127
|
+
error_message: evaluation_detail.error
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
132
|
+
value: evaluation_detail.value,
|
133
|
+
variant: evaluation_detail.variation_id,
|
134
|
+
reason: produce_reason(evaluation_detail)
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param evaluation_detail [ConfigCat::EvaluationDetails]
|
139
|
+
# @param default_value [any]
|
140
|
+
#
|
141
|
+
# @return [::OpenFeature::SDK::ResolutionDetails]
|
142
|
+
private def produce_numeric_result(evaluation_detail, default_value, type)
|
143
|
+
result = produce_result(evaluation_detail, default_value)
|
144
|
+
unless result.error_code.nil?
|
145
|
+
return result
|
146
|
+
end
|
147
|
+
|
148
|
+
if type == Integer
|
149
|
+
result.value = result.value.to_i
|
150
|
+
elsif type == Float
|
151
|
+
result.value = result.value.to_f
|
152
|
+
end
|
153
|
+
|
154
|
+
result
|
155
|
+
end
|
156
|
+
|
157
|
+
# @param evaluation_detail [ConfigCat::EvaluationDetails]
|
158
|
+
#
|
159
|
+
# @return [String]
|
160
|
+
private def produce_reason(evaluation_detail)
|
161
|
+
unless evaluation_detail.error.nil?
|
162
|
+
return ::OpenFeature::SDK::Provider::Reason::ERROR
|
163
|
+
end
|
164
|
+
|
165
|
+
if !evaluation_detail.matched_targeting_rule.nil? || !evaluation_detail.matched_percentage_option.nil?
|
166
|
+
return ::OpenFeature::SDK::Provider::Reason::TARGETING_MATCH
|
167
|
+
end
|
168
|
+
|
169
|
+
::OpenFeature::SDK::Provider::Reason::DEFAULT
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../..
|
3
|
+
specs:
|
4
|
+
configcat (8.0.1)
|
5
|
+
concurrent-ruby (~> 1.1)
|
6
|
+
semantic (~> 1.6)
|
7
|
+
configcat-openfeature-provider (0.1.0)
|
8
|
+
configcat (~> 8.0.1)
|
9
|
+
openfeature-sdk (~> 0.4.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
concurrent-ruby (1.3.5)
|
15
|
+
openfeature-sdk (0.4.0)
|
16
|
+
semantic (1.6.1)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
x64-mingw-ucrt
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
configcat-openfeature-provider!
|
23
|
+
|
24
|
+
BUNDLED WITH
|
25
|
+
2.6.9
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "configcat-openfeature-provider"
|
2
|
+
require "date"
|
3
|
+
|
4
|
+
# Info level logging helps to inspect the feature flag evaluation process.
|
5
|
+
# Use the default Warning level to avoid too detailed logging in your application.
|
6
|
+
ConfigCat.logger.level = Logger::INFO
|
7
|
+
|
8
|
+
# Configure the OpenFeature API with the ConfigCat provider.
|
9
|
+
OpenFeature::SDK.configure do |config|
|
10
|
+
config.set_provider(ConfigCat::OpenFeature::Provider.new(
|
11
|
+
sdk_key: "PKDVCLf-Hq-h-kCzMp-L7Q/HhOWfwVtZ0mb30i9wi17GQ",
|
12
|
+
# Configure the ConfigCat SDK.
|
13
|
+
options: ConfigCat::ConfigCatOptions.new(
|
14
|
+
polling_mode: ConfigCat::PollingMode.auto_poll,
|
15
|
+
offline: false
|
16
|
+
)
|
17
|
+
))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Create a client.
|
21
|
+
client = OpenFeature::SDK.build_client
|
22
|
+
|
23
|
+
# Create evaluation context.
|
24
|
+
evaluation_context = OpenFeature::SDK::EvaluationContext.new(
|
25
|
+
OpenFeature::SDK::EvaluationContext::TARGETING_KEY => "<SOME USERID>",
|
26
|
+
"Email" => "configcat@example.com",
|
27
|
+
"Country" => "CountryID",
|
28
|
+
"Version" => "1.0.0"
|
29
|
+
)
|
30
|
+
|
31
|
+
# Evaluate feature flag.
|
32
|
+
flag_details = client.fetch_boolean_details(
|
33
|
+
flag_key: "isPOCFeatureEnabled",
|
34
|
+
default_value: false,
|
35
|
+
evaluation_context: evaluation_context
|
36
|
+
)
|
37
|
+
|
38
|
+
puts(JSON.dump(flag_details))
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: configcat-openfeature-provider
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ConfigCat
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-06-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: configcat
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 8.0.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 8.0.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: openfeature-sdk
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.4.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: standard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: standard-performance
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: OpenFeature Provider that allows ConfigCat to be used with the OpenFeature
|
98
|
+
Ruby SDK.
|
99
|
+
email:
|
100
|
+
- developer@configcat.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".github/CODEOWNERS"
|
106
|
+
- ".github/dependabot.yml"
|
107
|
+
- ".github/workflows/ci.yml"
|
108
|
+
- ".github/workflows/publish.yml"
|
109
|
+
- ".github/workflows/stale.yml"
|
110
|
+
- ".gitignore"
|
111
|
+
- ".rspec"
|
112
|
+
- ".standard.yml"
|
113
|
+
- CHANGELOG.md
|
114
|
+
- CONTRIBUTING.md
|
115
|
+
- Gemfile
|
116
|
+
- Gemfile.lock
|
117
|
+
- LICENSE
|
118
|
+
- README.md
|
119
|
+
- Rakefile
|
120
|
+
- configcat-openfeature-provider.gemspec
|
121
|
+
- lib/configcat-openfeature-provider.rb
|
122
|
+
- lib/configcat-openfeature-provider/provider.rb
|
123
|
+
- lib/configcat-openfeature-provider/version.rb
|
124
|
+
- samples/provider-sample/Gemfile
|
125
|
+
- samples/provider-sample/Gemfile.lock
|
126
|
+
- samples/provider-sample/main.rb
|
127
|
+
homepage: https://configcat.com
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata:
|
131
|
+
homepage_uri: https://configcat.com
|
132
|
+
source_code_uri: https://github.com/configcat/openfeature-ruby
|
133
|
+
changelog_uri: https://github.com/configcat/openfeature-ruby/blob/main/CHANGELOG.md
|
134
|
+
bug_tracker_uri: https://github.com/configcat/openfeature-ruby/issues
|
135
|
+
documentation_uri: https://configcat.com/docs/sdk-reference/openfeature/ruby
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '3.1'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.4.19
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: ConfigCat OpenFeature Provider for Ruby.
|
155
|
+
test_files: []
|