prefab-cloud-ruby 0 → 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.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/Gemfile +9 -22
  4. data/Gemfile.lock +88 -160
  5. data/LICENSE.txt +1 -1
  6. data/Rakefile +14 -14
  7. data/VERSION +1 -1
  8. data/lib/prefab/auth_interceptor.rb +25 -0
  9. data/lib/prefab/client.rb +34 -139
  10. data/lib/prefab/config_client.rb +23 -275
  11. data/lib/prefab/config_loader.rb +27 -60
  12. data/lib/prefab/config_resolver.rb +40 -53
  13. data/lib/prefab/noop_cache.rb +13 -0
  14. data/lib/prefab/noop_stats.rb +8 -0
  15. data/lib/prefab/prefab_pb.rb +39 -0
  16. data/lib/prefab/prefab_services_pb.rb +37 -0
  17. data/lib/prefab/ratelimit_client.rb +58 -0
  18. data/lib/prefab/ratelimit_pb.rb +125 -0
  19. data/lib/prefab/store.rb +29 -0
  20. data/lib/prefab_client.rb +35 -0
  21. metadata +36 -198
  22. data/.envrc.sample +0 -3
  23. data/.github/workflows/ruby.yml +0 -46
  24. data/.gitmodules +0 -3
  25. data/.rubocop.yml +0 -13
  26. data/.tool-versions +0 -1
  27. data/CHANGELOG.md +0 -169
  28. data/CODEOWNERS +0 -1
  29. data/README.md +0 -94
  30. data/bin/console +0 -21
  31. data/compile_protos.sh +0 -18
  32. data/lib/prefab/config_client_presenter.rb +0 -18
  33. data/lib/prefab/config_value_unwrapper.rb +0 -115
  34. data/lib/prefab/config_value_wrapper.rb +0 -18
  35. data/lib/prefab/context.rb +0 -179
  36. data/lib/prefab/context_shape.rb +0 -20
  37. data/lib/prefab/context_shape_aggregator.rb +0 -65
  38. data/lib/prefab/criteria_evaluator.rb +0 -136
  39. data/lib/prefab/encryption.rb +0 -65
  40. data/lib/prefab/error.rb +0 -6
  41. data/lib/prefab/errors/env_var_parse_error.rb +0 -11
  42. data/lib/prefab/errors/initialization_timeout_error.rb +0 -13
  43. data/lib/prefab/errors/invalid_api_key_error.rb +0 -19
  44. data/lib/prefab/errors/missing_default_error.rb +0 -13
  45. data/lib/prefab/errors/missing_env_var_error.rb +0 -11
  46. data/lib/prefab/errors/uninitialized_error.rb +0 -13
  47. data/lib/prefab/evaluation.rb +0 -52
  48. data/lib/prefab/evaluation_summary_aggregator.rb +0 -87
  49. data/lib/prefab/example_contexts_aggregator.rb +0 -78
  50. data/lib/prefab/exponential_backoff.rb +0 -21
  51. data/lib/prefab/feature_flag_client.rb +0 -42
  52. data/lib/prefab/http_connection.rb +0 -41
  53. data/lib/prefab/internal_logger.rb +0 -16
  54. data/lib/prefab/local_config_parser.rb +0 -151
  55. data/lib/prefab/log_path_aggregator.rb +0 -69
  56. data/lib/prefab/logger_client.rb +0 -264
  57. data/lib/prefab/murmer3.rb +0 -50
  58. data/lib/prefab/options.rb +0 -208
  59. data/lib/prefab/periodic_sync.rb +0 -69
  60. data/lib/prefab/prefab.rb +0 -56
  61. data/lib/prefab/rate_limit_cache.rb +0 -41
  62. data/lib/prefab/resolved_config_presenter.rb +0 -86
  63. data/lib/prefab/time_helpers.rb +0 -7
  64. data/lib/prefab/weighted_value_resolver.rb +0 -42
  65. data/lib/prefab/yaml_config_parser.rb +0 -34
  66. data/lib/prefab-cloud-ruby.rb +0 -57
  67. data/lib/prefab_pb.rb +0 -93
  68. data/prefab-cloud-ruby.gemspec +0 -155
  69. data/test/.prefab.default.config.yaml +0 -2
  70. data/test/.prefab.unit_tests.config.yaml +0 -28
  71. data/test/integration_test.rb +0 -150
  72. data/test/integration_test_helpers.rb +0 -151
  73. data/test/support/common_helpers.rb +0 -180
  74. data/test/support/mock_base_client.rb +0 -42
  75. data/test/support/mock_config_client.rb +0 -19
  76. data/test/support/mock_config_loader.rb +0 -1
  77. data/test/test_client.rb +0 -444
  78. data/test/test_config_client.rb +0 -109
  79. data/test/test_config_loader.rb +0 -117
  80. data/test/test_config_resolver.rb +0 -430
  81. data/test/test_config_value_unwrapper.rb +0 -224
  82. data/test/test_config_value_wrapper.rb +0 -42
  83. data/test/test_context.rb +0 -203
  84. data/test/test_context_shape.rb +0 -50
  85. data/test/test_context_shape_aggregator.rb +0 -147
  86. data/test/test_criteria_evaluator.rb +0 -726
  87. data/test/test_encryption.rb +0 -16
  88. data/test/test_evaluation_summary_aggregator.rb +0 -162
  89. data/test/test_example_contexts_aggregator.rb +0 -238
  90. data/test/test_exponential_backoff.rb +0 -18
  91. data/test/test_feature_flag_client.rb +0 -48
  92. data/test/test_helper.rb +0 -17
  93. data/test/test_integration.rb +0 -58
  94. data/test/test_local_config_parser.rb +0 -147
  95. data/test/test_log_path_aggregator.rb +0 -62
  96. data/test/test_logger.rb +0 -621
  97. data/test/test_logger_initialization.rb +0 -12
  98. data/test/test_options.rb +0 -75
  99. data/test/test_prefab.rb +0 -12
  100. data/test/test_rate_limit_cache.rb +0 -44
  101. data/test/test_weighted_value_resolver.rb +0 -71
data/CHANGELOG.md DELETED
@@ -1,169 +0,0 @@
1
- # Changelog
2
-
3
- ## 1.5.0 - 2024-02-12
4
-
5
- - Fix potential inconsistent Context behavior (#172)
6
-
7
- ## 1.4.5 - 2024-01-31
8
-
9
- - Refactor out a `should_log?` method (#170)
10
-
11
- ## 1.4.4 - 2024-01-26
12
-
13
- - Raise when ENV var is missing
14
-
15
- ## 1.4.3 - 2024-01-17
16
-
17
- - Updated proto definition file
18
-
19
- ## 1.4.2 - 2023-12-14
20
-
21
- - Use reportable value even for invalid data (#166)
22
-
23
- ## 1.4.1 - 2023-12-08
24
-
25
- - Include version in `get` request (#165)
26
-
27
- ## 1.4.0 - 2023-11-28
28
-
29
- - ActiveJob tagged logger issue (#164)
30
- - Compact Log Format (#163)
31
- - Tagged Logging (#161)
32
- - ContextKey logging thread safety (#162)
33
-
34
- ## 1.3.2 - 2023-11-15
35
-
36
- - Send back cloud.prefab logging telemetry (#160)
37
-
38
- ## 1.3.1 - 2023-11-14
39
-
40
- - Improve path of rails.controller logging & fix strong param include (#159)
41
-
42
- ## 1.3.0 - 2023-11-13
43
-
44
- - Less logging when wifi is off and we load from cache (#157)
45
- - Alpha: Add Provided & Secret Support (#152)
46
- - Alpha: x_datafile (#156)
47
- - Add single line action-controller output under rails.controller (#158)
48
-
49
- ## 1.2.1 - 2023-11-01
50
-
51
- - Update protobuf definitions (#154)
52
-
53
- ## 1.2.0 - 2023-10-30
54
-
55
- - Add `Prefab.get('key')` style usage after a `Prefab.init()` call (#151)
56
- - Add `add_context_keys` and `with_context_keys` method for LoggerClient (#145)
57
-
58
- ## 1.1.2 - 2023-10-13
59
-
60
- - Add `cloud.prefab.client.criteria_evaluator` `debug` logging of evaluations (#150)
61
- - Add `x_use_local_cache` for local caching (#148)
62
- - Tests run in RubyMine (#147)
63
-
64
- ## 1.1.1 - 2023-10-11
65
-
66
- - Migrate happy-path client-initialization logging to `DEBUG` level rather than `INFO` (#144)
67
- - Add `ConfigClientPresenter` for logging out stats upon successful client initialization (#144)
68
- - Add support for default context (#146)
69
-
70
- ## 1.1.0 - 2023-09-18
71
-
72
- - Add support for structured logging (#143)
73
- - Ability to pass a hash of key/value context pairs to any of the user-facing log methods
74
-
75
- ## 1.0.1 - 2023-08-17
76
-
77
- - Bug fix for StringList w/ ExampleContextsAggregator (#141)
78
-
79
- ## 1.0.0 - 2023-08-10
80
-
81
- - Removed EvaluatedKeysAggregator (#137)
82
- - Change `collect_evaluation_summaries` default to true (#136)
83
- - Removed some backwards compatibility shims (#133)
84
- - Standardizing options (#132)
85
- - Note that the default value for `context_upload_mode` is `:periodic_example` which means example contexts will be collected.
86
- This enables easy variant override assignment in our UI. More at https://prefab.cloud/blog/feature-flag-variant-assignment/
87
-
88
- ## 0.24.6 - 2023-07-31
89
-
90
- - Logger Client compatibility (#129)
91
- - Replace EvaluatedConfigs with ExampleContexts (#128)
92
- - Add ConfigEvaluationSummaries (opt-in for now) (#123)
93
-
94
- ## 0.24.5 - 2023-07-10
95
-
96
- - Report Client Version (#121)
97
-
98
- ## [0.24.4] - 2023-07-06
99
-
100
- - Support Timed Loggers (#119)
101
- - Added EvaluatedConfigsAggregator (disabled by default) (#118)
102
- - Added EvaluatedKeysAggregator (disabled by default) (#117)
103
- - Dropped Ruby 2.6 support (#116)
104
- - Capture/report context shapes (#115)
105
- - Added bin/console (#114)
106
-
107
- ## [0.24.3] - 2023-05-15
108
-
109
- - Add JSON log formatter (#106)
110
-
111
- # [0.24.2] - 2023-05-12
112
-
113
- - Fix bug in FF rollout eval consistency (#108)
114
- - Simplify forking (#107)
115
-
116
- # [0.24.1] - 2023-04-26
117
-
118
- - Fix misleading deprecation warning (#105)
119
-
120
- # [0.24.0] - 2023-04-26
121
-
122
- - Backwards compatibility for JIT context (#104)
123
- - Remove upsert (#103)
124
- - Add resolver presenter and `on_update` callback (#102)
125
- - Deprecate `lookup_key` and introduce Context (#99)
126
-
127
- # [0.23.8] - 2023-04-21
128
-
129
- - Update protobuf (#101)
130
-
131
- # [0.23.7] - 2023-04-21
132
-
133
- - Guard against ActiveJob not being loaded (#100)
134
-
135
- # [0.23.6] - 2023-04-17
136
-
137
- - Fix bug in FF rollout eval consistency (#98)
138
- - Add tests for block-form of logging (#96)
139
-
140
- # [0.23.5] - 2023-04-13
141
-
142
- - Cast the value to string when checking presence in string list (#95)
143
-
144
- # [0.23.4] - 2023-04-12
145
-
146
- - Remove GRPC (#93)
147
-
148
- # [0.23.3] - 2023-04-07
149
-
150
- - Use exponential backoff for log level uploading (#92)
151
-
152
- # [0.23.2] - 2023-04-04
153
-
154
- - Move log collection logs from INFO to DEBUG (#91)
155
- - Fix: Handle trailing slash in PREFAB_API_URL (#90)
156
-
157
- # [0.23.1] - 2023-03-30
158
-
159
- - ActiveStorage not defined in Rails < 5.2 (#87)
160
-
161
- # [0.23.0] - 2023-03-28
162
-
163
- - Convenience for setting Rails.logger (#85)
164
- - Log evaluation according to rules (#81)
165
-
166
- # [0.22.0] - 2023-03-15
167
-
168
- - Report log paths and usages (#79)
169
- - Accept hash or keyword args in `initialize` (#78)
data/CODEOWNERS DELETED
@@ -1 +0,0 @@
1
- * @prefab-cloud/prefabdevs @prefab-cloud/prefabmaintainers @prefab-cloud/prefabadmins
data/README.md DELETED
@@ -1,94 +0,0 @@
1
- # prefab-cloud-ruby
2
-
3
- Ruby Client for Prefab Feature Flags, Dynamic log levels, and Config as a Service: https://www.prefab.cloud
4
-
5
- ```ruby
6
- client = Prefab::Client.new
7
-
8
- context = {
9
- user: {
10
- team_id: 432,
11
- id: 123,
12
- subscription_level: 'pro',
13
- email: "alice@example.com"
14
- }
15
- }
16
-
17
- result = client.enabled? "my-first-feature-flag", context
18
-
19
- puts "my-first-feature-flag is: #{result}"
20
- ```
21
-
22
- See full documentation https://docs.prefab.cloud/docs/ruby-sdk/ruby
23
-
24
- ## Supports
25
-
26
- - Feature Flags
27
- - Dynamic log levels
28
- - Live Config
29
- - WebUI for tweaking config, log levels, and feature flags
30
-
31
- ## Important note about Forking and realtime updates
32
-
33
- Many ruby web servers fork. When the process is forked, the current realtime update stream is disconnected. If you're using Puma or Unicorn, do the following.
34
-
35
- ```ruby
36
- #config/initializers/prefab.rb
37
- $prefab = Prefab::Client.new
38
- $prefab.set_rails_loggers
39
- ```
40
-
41
- ```ruby
42
- #puma.rb
43
- on_worker_boot do
44
- $prefab = $prefab.fork
45
- $prefab.set_rails_loggers
46
- end
47
- ```
48
-
49
- ```ruby
50
- # unicorn.rb
51
- after_fork do |server, worker|
52
- $prefab = $prefab.fork
53
- $prefab.set_rails_loggers
54
- end
55
- ```
56
-
57
- ## Logging & Debugging
58
-
59
- In classpath or ~/.prefab.default.config.yaml set
60
-
61
- ```
62
- log-level:
63
- cloud.prefab: debug
64
- ```
65
-
66
- To debug issues before this config file has been read, set env var
67
-
68
- ```
69
- PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL=debug
70
- ```
71
-
72
- ## Contributing to prefab-cloud-ruby
73
-
74
- - Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
75
- - Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
76
- - Fork the project.
77
- - Start a feature/bugfix branch.
78
- - Commit and push until you are happy with your contribution.
79
- - Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
80
- - Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
81
-
82
- ## Release
83
-
84
- ```shell
85
- update the changelog
86
- update VERSION
87
- bundle exec rake gemspec:generate
88
- git commit & push
89
- REMOTE_BRANCH=main LOCAL_BRANCH=main bundle exec rake release
90
- ```
91
-
92
- ## Copyright
93
-
94
- Copyright (c) 2023 Jeff Dwyer. See LICENSE.txt for further details.
data/bin/console DELETED
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'irb'
5
- require 'bundler/setup'
6
-
7
- gemspec = Dir.glob(File.expand_path("../../*.gemspec", __FILE__)).first
8
- spec = Gem::Specification.load(gemspec)
9
-
10
- # Add the require paths to the $LOAD_PATH
11
- spec.require_paths.each do |path|
12
- full_path = File.expand_path("../" + path, __dir__)
13
- $LOAD_PATH.unshift(full_path) unless $LOAD_PATH.include?(full_path)
14
- end
15
-
16
- spec.require_paths.each do |path|
17
- require "./lib/prefab-cloud-ruby"
18
- end
19
-
20
- # Start an IRB session
21
- IRB.start(__FILE__)
data/compile_protos.sh DELETED
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- set -e
4
-
5
- gem install grpc-tools
6
-
7
- (
8
- cd ../prefab-cloud
9
- git pull --rebase
10
- )
11
-
12
- grpc_tools_ruby_protoc -I ../prefab-cloud/ --ruby_out=lib --grpc_out=lib prefab.proto
13
-
14
- gsed -i 's/^module Prefab$/module PrefabProto/g' lib/prefab_pb.rb
15
-
16
- # on M1 you need to
17
- # 1. run in rosetta
18
- # 2. mv gems/2.6.0/gems/grpc-tools-1.43.1/bin/x86_64-macos x86-macos
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class ConfigClientPresenter
5
- def initialize(size:, source:, project_id:, project_env_id:, api_key_id:)
6
- @size = size
7
- @source = source
8
- @project_id = project_id
9
- @project_env_id = project_env_id
10
- @api_key_id = api_key_id
11
- end
12
-
13
- def to_s
14
- "Configuration Loaded count=#{@size} source=#{@source} project=#{@project_id} project-env=#{@project_env_id} prefab.api-key-id=#{@api_key_id}"
15
- end
16
- end
17
- end
18
-
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class ConfigValueUnwrapper
5
- LOG = Prefab::InternalLogger.new(ConfigValueUnwrapper)
6
- CONFIDENTIAL_PREFIX = "*****"
7
- attr_reader :weighted_value_index
8
-
9
- def initialize(config_value, resolver, weighted_value_index = nil)
10
- @config_value = config_value
11
- @resolver = resolver
12
- @weighted_value_index = weighted_value_index
13
- end
14
-
15
- def reportable_wrapped_value
16
- if @config_value.confidential || @config_value.decrypt_with&.length&.positive?
17
- # Unique hash for differentiation
18
- Prefab::ConfigValueWrapper.wrap("#{CONFIDENTIAL_PREFIX}#{Digest::MD5.hexdigest(unwrap)[0, 5]}")
19
- else
20
- @config_value
21
- end
22
- end
23
-
24
- def reportable_value
25
- Prefab::ConfigValueUnwrapper.new(reportable_wrapped_value, @resolver, @weighted_value_index).unwrap
26
- end
27
-
28
- def raw_config_value
29
- @config_value
30
- end
31
-
32
- # this will return the actual value of confidential, use reportable_value unless you need it
33
- def unwrap
34
- raw = case @config_value.type
35
- when :int, :string, :double, :bool, :log_level
36
- @config_value.public_send(@config_value.type)
37
- when :string_list
38
- @config_value.string_list.values
39
- else
40
- LOG.error "Unknown type: #{@config_value.type}"
41
- raise "Unknown type: #{@config_value.type}"
42
- end
43
- if @config_value.has_decrypt_with?
44
- decryption_key = @resolver.get(@config_value.decrypt_with)&.unwrapped_value
45
- if decryption_key.nil?
46
- LOG.warn "No value for decryption key #{@config_value.decrypt_with} found."
47
- return ""
48
- else
49
- unencrypted = Prefab::Encryption.new(decryption_key).decrypt(raw)
50
- return unencrypted
51
- end
52
- end
53
-
54
- raw
55
- end
56
-
57
- def self.deepest_value(config_value, config, context, resolver)
58
- if config_value&.type == :weighted_values
59
- value, index = Prefab::WeightedValueResolver.new(
60
- config_value.weighted_values.weighted_values,
61
- config.key,
62
- context.get(config_value.weighted_values.hash_by_property_name)
63
- ).resolve
64
-
65
- new(deepest_value(value.value, config, context, resolver).raw_config_value, resolver, index)
66
-
67
- elsif config_value&.type == :provided
68
- if :ENV_VAR == config_value.provided.source
69
- raw = ENV[config_value.provided.lookup]
70
- if raw.nil?
71
- raise Prefab::Errors::MissingEnvVarError.new("Missing environment variable #{config_value.provided.lookup}")
72
- else
73
- coerced = coerce_into_type(raw, config, config_value.provided.lookup)
74
- new(Prefab::ConfigValueWrapper.wrap(coerced, confidential: config_value.confidential), resolver)
75
- end
76
- else
77
- raise "Unknown Provided Source #{config_value.provided.source}"
78
- end
79
- else
80
- new(config_value, resolver)
81
- end
82
- end
83
-
84
- # Don't allow env vars to resolve to a value_type other than the config's value_type
85
- def self.coerce_into_type(value_string, config, env_var_name)
86
- case config.value_type
87
- when :INT then Integer(value_string)
88
- when :DOUBLE then Float(value_string)
89
- when :STRING then String(value_string)
90
- when :STRING_LIST then
91
- maybe_string_list = YAML.load(value_string)
92
- case maybe_string_list
93
- when Array
94
- maybe_string_list
95
- else
96
- raise raise Prefab::Errors::EnvVarParseError.new(value_string, config, env_var_name)
97
- end
98
- when :BOOL then
99
- maybe_bool = YAML.load(value_string)
100
- case maybe_bool
101
- when TrueClass, FalseClass
102
- maybe_bool
103
- else
104
- raise Prefab::Errors::EnvVarParseError.new(value_string, config, env_var_name)
105
- end
106
- when :NOT_SET_VALUE_TYPE
107
- YAML.load(value_string)
108
- else
109
- raise Prefab::Errors::EnvVarParseError.new(value_string, config, env_var_name)
110
- end
111
- rescue ArgumentError
112
- raise Prefab::Errors::EnvVarParseError.new(value_string, config, env_var_name)
113
- end
114
- end
115
- end
@@ -1,18 +0,0 @@
1
- module Prefab
2
- class ConfigValueWrapper
3
- def self.wrap(value, confidential: nil)
4
- case value
5
- when Integer
6
- PrefabProto::ConfigValue.new(int: value, confidential: confidential)
7
- when Float
8
- PrefabProto::ConfigValue.new(double: value, confidential: confidential)
9
- when TrueClass, FalseClass
10
- PrefabProto::ConfigValue.new(bool: value, confidential: confidential)
11
- when Array
12
- PrefabProto::ConfigValue.new(string_list: PrefabProto::StringList.new(values: value.map(&:to_s)), confidential: confidential)
13
- else
14
- PrefabProto::ConfigValue.new(string: value.to_s, confidential: confidential)
15
- end
16
- end
17
- end
18
- end
@@ -1,179 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class Context
5
- BLANK_CONTEXT_NAME = ''
6
-
7
- class NamedContext
8
- attr_reader :name
9
-
10
- def initialize(name, hash)
11
- @hash = {}
12
- @name = name.to_s
13
-
14
- merge!(hash)
15
- end
16
-
17
- def get(parts)
18
- @hash[parts]
19
- end
20
-
21
- def merge!(other)
22
- @hash = @hash.merge(other.transform_keys(&:to_s))
23
- end
24
-
25
- def to_h
26
- @hash
27
- end
28
-
29
- def key
30
- "#{@name}:#{get('key')}"
31
- end
32
-
33
- def to_proto
34
- PrefabProto::Context.new(
35
- type: name,
36
- values: to_h.transform_values do |value|
37
- ConfigValueWrapper.wrap(value)
38
- end
39
- )
40
- end
41
- end
42
-
43
- THREAD_KEY = :prefab_context
44
- attr_reader :contexts, :seen_at
45
-
46
- class << self
47
- def current=(context)
48
- Thread.current[THREAD_KEY] = context
49
- end
50
-
51
- def current
52
- Thread.current[THREAD_KEY] ||= new
53
- end
54
-
55
- def with_context(context)
56
- old_context = Thread.current[THREAD_KEY]
57
- Thread.current[THREAD_KEY] = new(context)
58
- yield
59
- ensure
60
- Thread.current[THREAD_KEY] = old_context
61
- end
62
-
63
- def with_merged_context(context)
64
- old_context = Thread.current[THREAD_KEY]
65
- Thread.current[THREAD_KEY] = merge_with_current(context)
66
- yield
67
- ensure
68
- Thread.current[THREAD_KEY] = old_context
69
- end
70
-
71
- def clear_current
72
- Thread.current[THREAD_KEY] = nil
73
- end
74
-
75
- def merge_with_current(new_context_properties = {})
76
- new(current.to_h.merge(new_context_properties.to_h))
77
- end
78
- end
79
-
80
- def initialize(context = {})
81
- @contexts = {}
82
- @seen_at = Time.now.utc.to_i
83
-
84
- if context.is_a?(NamedContext)
85
- @contexts[context.name] = context
86
- elsif context.is_a?(Hash)
87
- context.map do |name, values|
88
- if values.is_a?(Hash)
89
- @contexts[name.to_s] = NamedContext.new(name, values)
90
- else
91
- warn '[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash.'
92
-
93
- @contexts[BLANK_CONTEXT_NAME] ||= NamedContext.new(BLANK_CONTEXT_NAME, {})
94
- @contexts[BLANK_CONTEXT_NAME].merge!({ name => values })
95
- end
96
- end
97
- else
98
- raise ArgumentError, 'must be a Hash or a NamedContext'
99
- end
100
- end
101
-
102
- def blank?
103
- contexts.empty?
104
- end
105
-
106
- def set(name, hash)
107
- @contexts[name.to_s] = NamedContext.new(name, hash)
108
- end
109
-
110
- def get(property_key)
111
- name, key = property_key.split('.', 2)
112
-
113
- if key.nil?
114
- name = BLANK_CONTEXT_NAME
115
- key = property_key
116
- end
117
-
118
- contexts[name]&.get(key)
119
- end
120
-
121
- def to_h
122
- contexts.transform_values(&:to_h)
123
- end
124
-
125
- def clear
126
- @contexts = {}
127
- end
128
-
129
- def context(name)
130
- contexts[name.to_s] || NamedContext.new(name, {})
131
- end
132
-
133
- def merge_default(defaults)
134
- defaults.keys.each do |name|
135
- set(name, context(name).merge!(defaults[name]))
136
- end
137
-
138
- self
139
- end
140
-
141
- def to_proto(namespace)
142
- prefab_context = {
143
- 'current-time' => ConfigValueWrapper.wrap(Prefab::TimeHelpers.now_in_ms)
144
- }
145
-
146
- prefab_context['namespace'] = ConfigValueWrapper.wrap(namespace) if namespace&.length&.positive?
147
-
148
- PrefabProto::ContextSet.new(
149
- contexts: contexts.map do |name, context|
150
- context.to_proto
151
- end.concat([PrefabProto::Context.new(type: 'prefab',
152
- values: prefab_context)])
153
- )
154
- end
155
-
156
- def slim_proto
157
- PrefabProto::ContextSet.new(
158
- contexts: contexts.map do |_, context|
159
- context.to_proto
160
- end
161
- )
162
- end
163
-
164
- def grouped_key
165
- contexts.map do |_, context|
166
- context.key
167
- end.sort.join('|')
168
- end
169
-
170
- include Comparable
171
- def <=>(other)
172
- if other.is_a?(Prefab::Context)
173
- to_h <=> other.to_h
174
- else
175
- super
176
- end
177
- end
178
- end
179
- end
@@ -1,20 +0,0 @@
1
- module Prefab
2
- class ContextShape
3
- MAPPING = {
4
- Integer => 1,
5
- String => 2,
6
- Float => 4,
7
- TrueClass => 5,
8
- FalseClass => 5,
9
- Array => 10,
10
- }.freeze
11
-
12
- # We default to String if the type isn't a primitive we support.
13
- # This is because we do a `to_s` in the CriteriaEvaluator.
14
- DEFAULT = MAPPING[String]
15
-
16
- def self.field_type_number(value)
17
- MAPPING.fetch(value.class, DEFAULT)
18
- end
19
- end
20
- end