kameleoon-openfeature-ruby 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: aeeddfee1813205e7afa99fe74684a056233268d96383fcb5c98a9e2d555b183
4
+ data.tar.gz: e1b9e9e7353c54e9b0c54d4481b13b9eccf19ccded1171bd51b4ac840cb3940e
5
+ SHA512:
6
+ metadata.gz: 796225f66e0bc342064a7bd647fbb4788e4208c583aa40dd7445a0e706438d7f722858acc6f2ab81df55197af811f9936d3dc84c57c83c0e2621df32d6944753
7
+ data.tar.gz: b947424769ab79c1a3fd45fffec0aa6da3e999d14baf6123a2abfdee861653d7f5db0ec65ba3ab6a458e4ce8b0465628686b81f28db954be16e386097ac6d564
data/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # Kameleoon OpenFeature provider for Ruby
2
+
3
+ The Kameleoon OpenFeature provider for Ruby allows you to connect your OpenFeature Ruby implementation to Kameleoon without installing the Ruby Kameleoon SDK.
4
+
5
+ > [!WARNING]
6
+ > This is a beta version. Breaking changes may be introduced before general release.
7
+
8
+ ## Supported Ruby versions
9
+
10
+ This version of the SDK is built for the following targets:
11
+
12
+ * Ruby 3.1.4 and above.
13
+
14
+ ## Get started
15
+
16
+ This section explains how to install, configure, and customize the Kameleoon OpenFeature provider.
17
+
18
+ ### Install dependencies
19
+
20
+ First, install the required dependencies in your application.
21
+
22
+ ```sh
23
+ gem install bundler
24
+ bundle install
25
+ ```
26
+
27
+ ### Usage
28
+
29
+ The following example shows how to use the Kameleoon provider with the OpenFeature SDK.
30
+
31
+ ```ruby
32
+ require 'kameleoon-client'
33
+ require 'open_feature/sdk'
34
+
35
+ client_config = Kameleoon::KameleoonClientConfig.new(
36
+ 'clientId',
37
+ 'clientSecret',
38
+ top_level_domain: 'topLevelDomain',
39
+ )
40
+
41
+ provider = Kameleoon::KameleoonProvider.new('siteCode', config: client_config)
42
+ OpenFeature::SDK.configure do |config|
43
+ config.set_provider(provider)
44
+ end
45
+
46
+ client = OpenFeature::SDK.build_client
47
+
48
+ data_dictionary = {
49
+ 'targeting_key' => 'visitorCode',
50
+ 'variableKey' => 'variableKey'
51
+ }
52
+ eval_context = OpenFeature::SDK::EvaluationContext.new(**data_dictionary)
53
+
54
+ resolution_details = client.fetch_integer_value(flag_key: 'featureKey', default_value: 5,
55
+ evaluation_context: eval_context)
56
+ number_of_recommended_products = resolution_details.value
57
+
58
+ puts "Number of recommended products: #{number_of_recommended_products}"
59
+ ```
60
+
61
+ #### Customize the Kameleoon provider
62
+
63
+ You can customize the Kameleoon provider by changing the `KameleoonClientConfig` object that you passed to the constructor above. For example:
64
+
65
+ ```ruby
66
+ client_config = Kameleoon::KameleoonClientConfig.new(
67
+ 'clientId',
68
+ 'clientSecret',
69
+ top_level_domain: 'topLevelDomain',
70
+ refresh_interval_minute: 1, # Optional field
71
+ session_duration_minute: 5, # Optional field
72
+ )
73
+
74
+ provider = Kameleoon::KameleoonProvider.new('siteCode', config: client_config)
75
+ ```
76
+ > [!NOTE]
77
+ > For additional configuration options, see the [Kameleoon documentation](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/ruby-sdk/#example-code).
78
+
79
+ ## EvaluationContext and Kameleoon Data
80
+
81
+ Kameleoon uses the concept of associating `Data` to users, while the OpenFeature SDK uses the concept of an `EvaluationContext`, which is a dictionary of string keys and values. The Kameleoon provider maps the `EvaluationContext` to the Kameleoon `Data`.
82
+
83
+ > [!NOTE]
84
+ > To get the evaluation for a specific visitor, set the `targeting_key` value for the `EvaluationContext` to the visitor code (user ID). If the value is not provided, then the `defaultValue` parameter will be returned.
85
+
86
+ ```ruby
87
+ values = { 'targeting_key' => 'userId' }
88
+
89
+ eval_context = OpenFeature::SDK::EvaluationContext.new(**values)
90
+ ```
91
+
92
+ The Kameleoon provider provides a few predefined parameters that you can use to target a visitor from a specific audience and track each conversion. These are:
93
+
94
+ | Parameter | Description |
95
+ |---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
96
+ | `Data::Type::CUSTOM_DATA` | The parameter is used to set [`CustomData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/ruby-sdk/#customdata) for a visitor. |
97
+ | `Data::Type::CONVERSION` | The parameter is used to track a [`Conversion`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/ruby-sdk/#conversion) for a visitor. |
98
+
99
+ ### Data::Type::CUSTOM_DATA
100
+
101
+ Use `Data::Type::CUSTOM_DATA` to set [`CustomData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/ruby-sdk/#customdata) for a visitor. The `Data::Type::CUSTOM_DATA` field has the following parameters:
102
+
103
+ | Parameter | Type | Description |
104
+ |--------------------------------|---------|-------------------------------------------------------------------|
105
+ | `Data::CustomDataType::INDEX` | Integer | Index or ID of the custom data to store. This field is mandatory. |
106
+ | `Data::CustomDataType::VALUES` | String | Value of the custom data to store. This field is mandatory. |
107
+
108
+ #### Example
109
+
110
+ ```ruby
111
+ custom_data_dictionary = {
112
+ 'targeting_key' => 'userId',
113
+ Kameleoon::Types::Data::Type::CUSTOM_DATA => {
114
+ Kameleoon::Types::Data::CustomDataType::INDEX => 1,
115
+ Kameleoon::Types::Data::CustomDataType::VALUES => '10'
116
+ }
117
+ }
118
+
119
+ eval_context = OpenFeature::SDK::EvaluationContext.new(**custom_data_dictionary)
120
+ ```
121
+
122
+ ### Data::Type::CONVERSION
123
+
124
+ Use `Data::Type::CONVERSION` to track a [`Conversion`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/ruby-sdk/#conversion) for a visitor. The `Data::Type::CONVERSION` field has the following parameters:
125
+
126
+ | Parameter | Type | Description |
127
+ |---------------------------------|---------|-----------------------------------------------------------------|
128
+ | `Data::ConversionType::GOAL_ID` | Integer | Identifier of the goal. This field is mandatory. |
129
+ | `Data::ConversionType::REVENUE` | Float | Revenue associated with the conversion. This field is optional. |
130
+
131
+ #### Example
132
+
133
+ ```ruby
134
+ conversion_dictionary = {
135
+ Kameleoon::Types::Data::ConversionType::GOAL_ID => 1,
136
+ Kameleoon::Types::Data::ConversionType::REVENUE => 200
137
+ }
138
+
139
+ eval_context = OpenFeature::SDK::EvaluationContext.new(**{
140
+ 'targeting_key' => 'userId',
141
+ Kameleoon::Types::Data::Type::CONVERSION => conversion_dictionary
142
+ })
143
+ ```
144
+
145
+ ### Use multiple Kameleoon Data types
146
+
147
+ You can provide many different kinds of Kameleoon data within a single `EvaluationContext` instance.
148
+
149
+ For example, the following code provides one `Data::Type::CONVERSION` instance and two `Data::Type::CUSTOM_DATA` instances.
150
+
151
+ ```ruby
152
+ data_dictionary = {
153
+ 'targeting_key' => 'userId',
154
+ Kameleoon::Types::Data::Type::CONVERSION => {
155
+ Kameleoon::Types::Data::ConversionType::GOAL_ID => 1,
156
+ Kameleoon::Types::Data::ConversionType::REVENUE => 200
157
+ },
158
+ Kameleoon::Types::Data::Type::CUSTOM_DATA => [
159
+ {
160
+ Kameleoon::Types::Data::CustomDataType::INDEX => 1,
161
+ Kameleoon::Types::Data::CustomDataType::VALUES => ['10', '30']
162
+ },
163
+ {
164
+ Kameleoon::Types::Data::CustomDataType::INDEX => 2,
165
+ Kameleoon::Types::Data::CustomDataType::VALUES => '20'
166
+ }
167
+ ]
168
+ }
169
+
170
+ eval_context = OpenFeature::SDK::EvaluationContext.new(**data_dictionary)
171
+ ```
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kameleoon/types'
4
+ require 'kameleoon/data/conversion'
5
+ require 'kameleoon/data/custom_data'
6
+
7
+ module Kameleoon
8
+ # DataConverter is used to convert data from OpenFeature to Kameleoon.
9
+ class DataConverter
10
+ class << self
11
+ def conversion_methods
12
+ # Dictionary which contains conversion methods by keys
13
+ @conversion_methods ||= {
14
+ Kameleoon::Types::Data::Type::CONVERSION => method(:make_conversion),
15
+ Kameleoon::Types::Data::Type::CUSTOM_DATA => method(:make_custom_data)
16
+ }
17
+ end
18
+
19
+ # ToKameleoon converts EvaluationContext to Kameleoon SDK data types.
20
+ def to_kameleoon(context)
21
+ return [] if context.nil?
22
+
23
+ data = []
24
+ context.fields.each do |key, value|
25
+ method = conversion_methods[key]
26
+ next if method.nil? || value.nil?
27
+ values = value.is_a?(Array) ? value : [value]
28
+ values.each do |val|
29
+ data << method.call(val)
30
+ end
31
+ end
32
+ data
33
+ end
34
+
35
+ private
36
+
37
+ # make_conversion creates a Conversion object from the value.
38
+ def make_conversion(value)
39
+ return nil unless value.is_a?(Hash)
40
+
41
+ goal_id = value[Kameleoon::Types::Data::ConversionType::GOAL_ID]
42
+ revenue = value[Kameleoon::Types::Data::ConversionType::REVENUE]
43
+ revenue = revenue.to_f if revenue.is_a?(Integer)
44
+ revenue ||= 0.0
45
+
46
+ Kameleoon::Conversion.new(goal_id, revenue, false)
47
+ end
48
+
49
+ # make_custom_data creates a CustomData object from the value.
50
+ def make_custom_data(value)
51
+ return nil unless value.is_a?(Hash)
52
+
53
+ index = value[Kameleoon::Types::Data::CustomDataType::INDEX]
54
+ values = value[Kameleoon::Types::Data::CustomDataType::VALUES]
55
+ values = [values] if values.is_a?(String)
56
+
57
+ Kameleoon::CustomData.new(index, *values)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kameleoon/kameleoon_client_factory'
4
+ require 'kameleoon/resolver'
5
+ require 'open_feature/sdk/provider/provider_metadata'
6
+ require 'open_feature/sdk/provider/resolution_details'
7
+
8
+ module Kameleoon
9
+ # The KameleoonProvider class integrates with the OpenFeature SDK to provide feature flag resolution.
10
+ class KameleoonProvider
11
+ Provider = OpenFeature::SDK::Provider
12
+ NAME = 'Kameleoon Provider'
13
+
14
+ attr_reader :client, :metadata, :ready_state
15
+
16
+ # Initializes a new instance of the KameleoonProvider.
17
+ #
18
+ # @param site_code [String] The site code for the Kameleoon client.
19
+ # @param config [KameleoonClientConfig, nil] Optional configuration for the Kameleoon client.
20
+ # @param config_path [String, nil] Optional path to the configuration file.
21
+ def initialize(site_code, config: nil, config_path: nil)
22
+ @ready_state = false
23
+ @site_code = site_code
24
+ make_kameleoon_client(site_code, config, config_path)
25
+ @resolver = KameleoonResolver.new(@client)
26
+ @metadata = OpenFeature::SDK::Provider::ProviderMetadata.new(name: NAME).freeze
27
+ end
28
+
29
+ # Creates a Kameleoon client with the given site code and configuration.
30
+ #
31
+ # @param site_code [String] The site code for the Kameleoon client.
32
+ # @param config [KameleoonClientConfig, nil] Optional configuration for the Kameleoon client.
33
+ # @param config_path [String, nil] Optional path to the configuration file.
34
+ # @return [void]
35
+ private def make_kameleoon_client(site_code, config, config_path)
36
+ begin
37
+ @client = KameleoonClientFactory.create(site_code, config: config, config_path: config_path)
38
+ rescue Kameleoon::Exception::KameleoonError => exception
39
+
40
+ end
41
+ end
42
+
43
+ # Fetches a boolean value for the given feature flag.
44
+ #
45
+ # @param flag_key [String] The key of the feature flag.
46
+ # @param default_value [Boolean] The default value to return if the flag is not found.
47
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
48
+ # @return [ResolutionDetails] The resolution details.
49
+ def fetch_boolean_value(flag_key: String, default_value:, evaluation_context: nil)
50
+ fetch_value(allowed_classes: [TrueClass, FalseClass], flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
51
+ end
52
+
53
+ # Fetches a string value for the given feature flag.
54
+ #
55
+ # @param flag_key [String] The key of the feature flag.
56
+ # @param default_value [String] The default value to return if the flag is not found.
57
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
58
+ # @return [ResolutionDetails] The resolution details.
59
+ def fetch_string_value(flag_key: String, default_value: String, evaluation_context: nil)
60
+ fetch_value(allowed_classes: [String], flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
61
+ end
62
+
63
+ # Fetches a numeric value for the given feature flag.
64
+ #
65
+ # @param flag_key [String] The key of the feature flag.
66
+ # @param default_value [Numeric] The default value to return if the flag is not found.
67
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
68
+ # @return [ResolutionDetails] The resolution details.
69
+ def fetch_number_value(flag_key: String, default_value: Numeric, evaluation_context: nil)
70
+ fetch_value(allowed_classes: [Numeric], flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
71
+ end
72
+
73
+ # Fetches an integer value for the given feature flag.
74
+ #
75
+ # @param flag_key [String] The key of the feature flag.
76
+ # @param default_value [Integer] The default value to return if the flag is not found.
77
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
78
+ # @return [ResolutionDetails] The resolution details.
79
+ def fetch_integer_value(flag_key: String, default_value: Integer, evaluation_context: nil)
80
+ fetch_value(allowed_classes: [Integer], flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
81
+ end
82
+
83
+ # Fetches a float value for the given feature flag.
84
+ #
85
+ # @param flag_key [String] The key of the feature flag.
86
+ # @param default_value [Float] The default value to return if the flag is not found.
87
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
88
+ # @return [ResolutionDetails] The resolution details.
89
+ def fetch_float_value(flag_key: String, default_value: Float, evaluation_context: nil)
90
+ fetch_value(allowed_classes: [Float], flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
91
+ end
92
+
93
+ # Fetches an object value for the given feature flag.
94
+ #
95
+ # @param flag_key [String] The key of the feature flag.
96
+ # @param default_value [Array, Hash] The default value to return if the flag is not found.
97
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
98
+ # @return [ResolutionDetails] The resolution details.
99
+ def fetch_object_value(flag_key: String, default_value:, evaluation_context: nil)
100
+ fetch_value(allowed_classes: [Array, Hash], flag_key: flag_key, default_value: default_value, evaluation_context: evaluation_context)
101
+ end
102
+
103
+ # Initializes the Kameleoon client and sets the ready state.
104
+ #
105
+ # @return [Boolean]
106
+ def init
107
+ begin
108
+ success = @client.nil? ? false : @client.wait_init
109
+ rescue StandardError => e
110
+ success = false
111
+ end
112
+ @ready_state = success
113
+ end
114
+
115
+ # Shuts down the Kameleoon client and resets the ready state.
116
+ #
117
+ # @return [void]
118
+ def shutdown
119
+ KameleoonClientFactory.forget(@site_code)
120
+ @ready_state = false
121
+ @client = nil
122
+ end
123
+
124
+ private
125
+
126
+ # Fetches a value for the given feature flag based on the allowed classes.
127
+ #
128
+ # @param allowed_classes [Array<Class>] The allowed classes for the value.
129
+ # @param flag_key [String] The key of the feature flag.
130
+ # @param default_value [Any] The default value to return if the flag is not found.
131
+ # @param evaluation_context [EvaluationContext, nil] The evaluation context.
132
+ # @return [ResolutionDetails] The resolution details.
133
+ def fetch_value(allowed_classes:, flag_key:, default_value:, evaluation_context:)
134
+ if @ready_state
135
+ @resolver.resolve(allowed_classes: allowed_classes, flag_key: flag_key, default_value: default_value,
136
+ evaluation_context: evaluation_context)
137
+ else
138
+ Provider::ResolutionDetails.new(
139
+ value: default_value,
140
+ error_code: @client.nil? ? Provider::ErrorCode::PROVIDER_FATAL : Provider::ErrorCode::PROVIDER_NOT_READY,
141
+ error_message: 'The provider is not ready to resolve flags.',
142
+ reason: Provider::Reason::ERROR)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open_feature/sdk/provider/error_code'
4
+ require 'open_feature/sdk/provider/resolution_details'
5
+ require 'open_feature/sdk/provider/reason'
6
+ require 'open_feature/sdk/provider'
7
+ require 'kameleoon/data_converter'
8
+
9
+ module Kameleoon
10
+ VARIABLE_KEY = 'variableKey'
11
+
12
+ # Resolver interface which contains method for evaluations based on provided data
13
+ class Resolver
14
+ def resolve(flag: String, default_value:, evaluation_context: OpenFeature::SDK::EvaluationContext)
15
+ raise NotImplementedError, 'Subclasses must implement the resolve method'
16
+ end
17
+ end
18
+
19
+ # KameleoonResolver makes evaluations based on provided data, conforms to Resolver interface
20
+ class KameleoonResolver < Resolver
21
+ Provider = OpenFeature::SDK::Provider
22
+
23
+ def initialize(client)
24
+ @client = client
25
+ end
26
+
27
+ # Main method for getting resolution details based on provided data.
28
+ def resolve(allowed_classes: Array, flag_key: String, default_value:, evaluation_context: nil)
29
+ if !evaluation_context.is_a?(OpenFeature::SDK::EvaluationContext) ||
30
+ (visitor_code = get_targeting_key(evaluation_context)).nil? || visitor_code.empty?
31
+ return make_resolution_error(
32
+ default_value,
33
+ Provider::ErrorCode::TARGETING_KEY_MISSING,
34
+ 'The TargetingKey is required in context and cannot be omitted.')
35
+ end
36
+
37
+ # Add targeting data from context to KameleoonClient by visitor code
38
+ @client.add_data(visitor_code, *DataConverter.to_kameleoon(evaluation_context))
39
+
40
+ # Get a variation (main SDK method)
41
+ variation = @client.get_variation(visitor_code, flag_key)
42
+
43
+ # Get a variant (variation key)
44
+ variant = variation.key
45
+
46
+ # Get variableKey if it's provided in context or any first in variation.
47
+ # It's the responsibility of the client to have only one variable per variation if
48
+ # variableKey is not provided.
49
+ variable_key = get_variable_key(evaluation_context, variation.variables)
50
+
51
+ # Get value by variable key
52
+ value = variation.variables[variable_key]&.value
53
+
54
+ if value.nil? || variable_key.empty?
55
+ return make_resolution_error(
56
+ default_value,
57
+ Provider::ErrorCode::FLAG_NOT_FOUND,
58
+ make_error_description(variant, variable_key),
59
+ variant: variant)
60
+ end
61
+
62
+ # Check if the variable value has a required type
63
+ if allowed_classes.any? { |klass| value.is_a?(klass) }
64
+ return Provider::ResolutionDetails.new(
65
+ value: value,
66
+ reason: Provider::Reason::STATIC,
67
+ variant: variant)
68
+ else
69
+ make_resolution_error(
70
+ default_value,
71
+ Provider::ErrorCode::TYPE_MISMATCH,
72
+ 'The type of value received is different from the requested value.',
73
+ variant: variant)
74
+ end
75
+ rescue Kameleoon::Exception::FeatureError => e
76
+ make_resolution_error(default_value, Provider::ErrorCode::FLAG_NOT_FOUND, e.message)
77
+ rescue Kameleoon::Exception::VisitorCodeInvalid => e
78
+ make_resolution_error(default_value, Provider::ErrorCode::INVALID_CONTEXT, e.message)
79
+ rescue StandardError => e
80
+ make_resolution_error(default_value, Provider::ErrorCode::GENERAL, e.message, variant: variant)
81
+ end
82
+
83
+ private
84
+
85
+ # Helper method to get the targeting key from the context.
86
+ def get_targeting_key(evaluation_context)
87
+ targeting_key = evaluation_context.targeting_key
88
+ targeting_key if targeting_key.is_a?(String)
89
+ end
90
+
91
+ # Helper method to get the variable key from the context or variables map.
92
+ def get_variable_key(context, variables)
93
+ variable_key = context.field(VARIABLE_KEY)
94
+ variable_key = variables.keys.first if variable_key.nil? || variable_key.empty?
95
+ variable_key
96
+ end
97
+
98
+ # Helper method to generate an error description based on the variant and variable key.
99
+ def make_error_description(variant, variable_key)
100
+ if variable_key.nil? || variable_key.empty?
101
+ "The variation '#{variant}' has no variables"
102
+ else
103
+ "The value for provided variable key '#{variable_key}' isn't found in variation '#{variant}'"
104
+ end
105
+ end
106
+
107
+ # Helper method to generate a resolution details with error.
108
+ def make_resolution_error(default_value, error_code, error_message, variant: nil)
109
+ Provider::ResolutionDetails.new(
110
+ value: default_value,
111
+ error_code: error_code,
112
+ error_message: error_message,
113
+ reason: Provider::Reason::ERROR,
114
+ variant: variant)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kameleoon
4
+ module Types
5
+ module Data
6
+ # Type is used to add different Kameleoon data types using
7
+ # OpenFeature::SDK::EvaluationContext.
8
+ module Type
9
+ CONVERSION = 'conversion'
10
+ CUSTOM_DATA = 'customData'
11
+ end
12
+
13
+ # CustomDataType is used to add Kameleoon::CustomData using
14
+ # OpenFeature::SDK::EvaluationContext.
15
+ module CustomDataType
16
+ INDEX = 'index'
17
+ VALUES = 'values'
18
+ end
19
+
20
+ # ConversionType is used to add Kameleoon::Conversion using
21
+ # OpenFeature::SDK::EvaluationContext.
22
+ module ConversionType
23
+ GOAL_ID = 'goalId'
24
+ REVENUE = 'revenue'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kameleoon
4
+ OPENFEATURE_SDK_VERSION = '0.0.1'
5
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kameleoon-openfeature-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kameleoon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-10-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: openfeature-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: kameleoon-client-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.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: 3.4.0
41
+ description: Kameleoon OpenFeature provider for the Ruby SDK
42
+ email:
43
+ - sdk@kameleoon.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - README.md
49
+ - lib/kameleoon/data_converter.rb
50
+ - lib/kameleoon/kameleoon_provider.rb
51
+ - lib/kameleoon/resolver.rb
52
+ - lib/kameleoon/types.rb
53
+ - lib/kameleoon/util/version.rb
54
+ homepage: https://developers.kameleoon.com/ruby-sdk.html
55
+ licenses:
56
+ - GPL-3.0
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.3.26
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Kameleoon OpenFeature Ruby
77
+ test_files: []