prefab-cloud-ruby 1.8.4 → 1.8.5

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: ec8c47fb2fe1945e2d189198fbb2ecb8b2eee9d77537ac6569196659931badf4
4
- data.tar.gz: 58afaf18e4541429db3e4204f7bc2c19340028d894b84a75d7195aac39fd6b37
3
+ metadata.gz: 221fd3505c561f550efb45c86fcdf1ea79a7afd442ef6d2c351d9f0ce433c391
4
+ data.tar.gz: e85a75665a06ed8350e9fe6d44bc5c7462eb1d5d698f2b58a8ae2890472740e2
5
5
  SHA512:
6
- metadata.gz: 7ed0b65787d13a25a301a75481cff40db9b7dc1b036aea75c5e241b0bdddfd26577317b013830c7533ad0da51b7d087c3e59df5d8c38c07382509cfbc8d9eeb1
7
- data.tar.gz: c57bb8881f6a61b252013c118240bc64b8ffaa248caafd234747f1897dd3d67aab6b02b72a3c1e8b164feb689590587475fe5d605f13c1ac4b5c0b426e45f137
6
+ metadata.gz: 34a83eabd765201e831bc00d6b4472f1b67f6eb9271f5cd77f33de7a55571acbd323f2c6ee2c8df8a3df0602f577a3a30daebe983403d0e61870a14f6bcd7b74
7
+ data.tar.gz: fc6f2e0616a62dee54415d1290d163a055391afee5ba62f158aad5d19192ebd129507305dd6cda9735bf8b184e9c7e94657f1005384907150a0049c14cc8c6fe
@@ -25,7 +25,7 @@ jobs:
25
25
  ruby-version: ['2.7', '3.0', '3.3']
26
26
 
27
27
  steps:
28
- - uses: actions/checkout@v3
28
+ - uses: actions/checkout@v4
29
29
  with:
30
30
  submodules: recursive
31
31
  - name: Set up Ruby
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.8.5 - 2024-09-27
4
+
5
+ - Fix JS bootstrapping and improve performance (#206)
6
+ - Promote `datafile` from `x_datafile` (#205)
7
+
3
8
  ## 1.8.4 - 2024-09-19
4
9
 
5
10
  - Use `stream` subdomain for SSE (#203)
data/Gemfile.lock CHANGED
@@ -62,7 +62,7 @@ GEM
62
62
  faraday (>= 0.8, < 2)
63
63
  hashie (~> 3.5, >= 3.5.2)
64
64
  oauth2 (~> 1.0)
65
- google-protobuf (3.25.3)
65
+ google-protobuf (3.25.5)
66
66
  googleapis-common-protos-types (1.14.0)
67
67
  google-protobuf (~> 3.18)
68
68
  hashie (3.6.0)
@@ -152,7 +152,7 @@ GEM
152
152
  concurrent-ruby (~> 1.0)
153
153
  uuid (2.3.9)
154
154
  macaddr (~> 1.0)
155
- webrick (1.8.1)
155
+ webrick (1.8.2)
156
156
 
157
157
  PLATFORMS
158
158
  ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.4
1
+ 1.8.5
@@ -30,7 +30,7 @@ module Prefab
30
30
  end
31
31
 
32
32
  # this will return the actual value of confidential, use reportable_value unless you need it
33
- def unwrap
33
+ def unwrap(raw_json: false)
34
34
  raw = case @config_value.type
35
35
  when :int, :string, :double, :bool, :log_level
36
36
  @config_value.public_send(@config_value.type)
@@ -39,7 +39,11 @@ module Prefab
39
39
  when :duration
40
40
  Prefab::Duration.new(@config_value.duration.definition)
41
41
  when :json
42
- JSON.parse(@config_value.json.json)
42
+ if raw_json
43
+ @config_value.json.json
44
+ else
45
+ JSON.parse(@config_value.json.json)
46
+ end
43
47
  else
44
48
  LOG.error "Unknown type: #{@config_value.type}"
45
49
  raise "Unknown type: #{@config_value.type}"
@@ -3,16 +3,17 @@
3
3
  module Prefab
4
4
  class JavaScriptStub
5
5
  LOG = Prefab::InternalLogger.new(self)
6
+ CAMELS = {}
6
7
 
7
8
  def initialize(client = nil)
8
9
  @client = client || Prefab.instance
9
10
  end
10
11
 
11
12
  def bootstrap(context)
12
- configs, warnings = data(context)
13
+ configs, warnings = data(context, :bootstrap)
13
14
  <<~JS
14
15
  window._prefabBootstrap = {
15
- configs: #{JSON.dump(configs)},
16
+ evaluations: #{JSON.dump(configs)},
16
17
  context: #{JSON.dump(context)}
17
18
  }
18
19
  #{log_warnings(warnings)}
@@ -20,7 +21,7 @@ module Prefab
20
21
  end
21
22
 
22
23
  def generate_stub(context, callback = nil)
23
- configs, warnings = data(context)
24
+ configs, warnings = data(context, :stub)
24
25
  <<~JS
25
26
  window.prefab = window.prefab || {};
26
27
  window.prefab.config = #{JSON.dump(configs)};
@@ -41,7 +42,7 @@ module Prefab
41
42
  private
42
43
 
43
44
  def underlying_value(value)
44
- v = Prefab::ConfigValueUnwrapper.new(value, @client.resolver).unwrap
45
+ v = Prefab::ConfigValueUnwrapper.new(value, @client.resolver).unwrap(raw_json: true)
45
46
  case v
46
47
  when Google::Protobuf::RepeatedField
47
48
  v.to_a
@@ -60,7 +61,7 @@ module Prefab
60
61
  JS
61
62
  end
62
63
 
63
- def data(context)
64
+ def data(context, mode)
64
65
  permitted = {}
65
66
  warnings = []
66
67
  resolver_keys = @client.resolver.keys
@@ -70,7 +71,12 @@ module Prefab
70
71
  config = @client.resolver.raw(key)
71
72
 
72
73
  if config.config_type == :FEATURE_FLAG || config.send_to_client_sdk || config.config_type == :LOG_LEVEL
73
- permitted[key] = underlying_value(@client.resolver.get(key, context).value)
74
+ value = @client.resolver.get(key, context).value
75
+ if mode == :bootstrap
76
+ permitted[key] = { value: { to_camel_case(value.type) => underlying_value(value) } }
77
+ else
78
+ permitted[key] = underlying_value(value)
79
+ end
74
80
  end
75
81
  rescue StandardError => e
76
82
  LOG.warn("Could not resolve key #{key}: #{e}")
@@ -81,5 +87,13 @@ module Prefab
81
87
 
82
88
  [permitted, warnings]
83
89
  end
90
+
91
+ def to_camel_case(str)
92
+ CAMELS[str] ||= begin
93
+ str.to_s.split('_').map.with_index { |word, index|
94
+ index == 0 ? word : word.capitalize
95
+ }.join
96
+ end
97
+ end
84
98
  end
85
99
  end
@@ -66,6 +66,7 @@ module Prefab
66
66
  collect_evaluation_summaries: true,
67
67
  collect_max_evaluation_summaries: DEFAULT_MAX_EVAL_SUMMARIES,
68
68
  allow_telemetry_in_local_mode: false,
69
+ datafile: ENV['PREFAB_DATAFILE'],
69
70
  x_datafile: ENV['PREFAB_DATAFILE'],
70
71
  x_use_local_cache: false,
71
72
  global_context: {}
@@ -76,7 +77,13 @@ module Prefab
76
77
  @initialization_timeout_sec = initialization_timeout_sec
77
78
  @on_init_failure = on_init_failure
78
79
  @prefab_datasources = prefab_datasources
79
- @datafile = x_datafile
80
+
81
+ @datafile = datafile || x_datafile
82
+
83
+ if !x_datafile.nil?
84
+ warn '[DEPRECATION] x_datafile is deprecated. Please provide `datafile` instead'
85
+ end
86
+
80
87
  @prefab_config_classpath_dir = prefab_config_classpath_dir
81
88
  @prefab_config_override_dir = prefab_config_override_dir
82
89
  @prefab_envs = Array(prefab_envs)
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: prefab-cloud-ruby 1.8.4 ruby lib
5
+ # stub: prefab-cloud-ruby 1.8.5 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "1.8.4"
9
+ s.version = "1.8.5"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Jeff Dwyer".freeze]
14
- s.date = "2024-09-19"
14
+ s.date = "2024-09-27"
15
15
  s.description = "Feature Flags, Live Config, and Dynamic Log Levels as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -84,6 +84,7 @@ Gem::Specification.new do |s|
84
84
  "prefab-cloud-ruby.gemspec",
85
85
  "test/.prefab.default.config.yaml",
86
86
  "test/.prefab.unit_tests.config.yaml",
87
+ "test/fixtures/datafile.json",
87
88
  "test/integration_test.rb",
88
89
  "test/integration_test_helpers.rb",
89
90
  "test/support/common_helpers.rb",
@@ -0,0 +1,87 @@
1
+ {
2
+ "configs": [
3
+ {
4
+ "id": "16825372746571694",
5
+ "projectId": "202",
6
+ "key": "log-level",
7
+ "changedBy": {
8
+ "email": "jeffrey.chupp@prefab.cloud"
9
+ },
10
+ "configType": "DELETED"
11
+ },
12
+ {
13
+ "id": "17271108409487302",
14
+ "projectId": "202",
15
+ "key": "flag.list.environments",
16
+ "changedBy": {
17
+ "email": "jeffrey.chupp@prefab.cloud"
18
+ },
19
+ "rows": [
20
+ {
21
+ "projectEnvId": "308",
22
+ "values": [
23
+ {
24
+ "criteria": [
25
+ {
26
+ "propertyName": "user.key",
27
+ "operator": "PROP_IS_ONE_OF",
28
+ "valueToMatch": {
29
+ "stringList": {
30
+ "values": [
31
+ "5905ecd1-9bbf-4711-a663-4f713628a78c"
32
+ ]
33
+ }
34
+ }
35
+ }
36
+ ],
37
+ "value": {
38
+ "bool": true
39
+ }
40
+ },
41
+ {
42
+ "value": {
43
+ "bool": true
44
+ }
45
+ }
46
+ ]
47
+ }
48
+ ],
49
+ "allowableValues": [
50
+ {
51
+ "bool": false
52
+ },
53
+ {
54
+ "bool": true
55
+ }
56
+ ],
57
+ "configType": "FEATURE_FLAG",
58
+ "valueType": "BOOL"
59
+ },
60
+ {
61
+ "id": "17271831941669987",
62
+ "projectId": "202",
63
+ "key": "my.test.string",
64
+ "changedBy": {
65
+ "userId": "3",
66
+ "apiKeyId": "481"
67
+ },
68
+ "rows": [
69
+ {
70
+ "values": [
71
+ {
72
+ "value": {
73
+ "string": "hello world"
74
+ }
75
+ }
76
+ ]
77
+ }
78
+ ],
79
+ "configType": "CONFIG",
80
+ "valueType": "STRING"
81
+ }
82
+ ],
83
+ "configServicePointer": {
84
+ "projectId": "202",
85
+ "projectEnvId": "308"
86
+ }
87
+ }
data/test/test_client.rb CHANGED
@@ -427,6 +427,14 @@ class TestClient < Minitest::Test
427
427
  refute client.is_ff?('does_not_exist')
428
428
  end
429
429
 
430
+ def test_with_datafile
431
+ datafile = "#{Dir.pwd}/test/fixtures/datafile.json"
432
+ client = new_client(datafile: datafile, prefab_datasources: :all)
433
+
434
+ assert client.get('flag.list.environments')
435
+ assert_equal "hello world", client.get('my.test.string')
436
+ end
437
+
430
438
  private
431
439
 
432
440
  def basic_value_config
@@ -48,6 +48,34 @@ class JavascriptStubTest < Minitest::Test
48
48
  rows: [DEFAULT_ROW]
49
49
  )
50
50
 
51
+ json_config = PrefabProto::Config.new(
52
+ id: 234,
53
+ key: 'json-config',
54
+ config_type: PrefabProto::ConfigType::CONFIG,
55
+ send_to_client_sdk: true,
56
+ rows: [
57
+ PrefabProto::ConfigRow.new(
58
+ values: [
59
+ PrefabProto::ConditionalValue.new(value: PrefabProto::ConfigValue.new(json: PrefabProto::Json.new(json: '{"key":"value"}')))
60
+ ]
61
+ )
62
+ ]
63
+ )
64
+
65
+ duration_config = PrefabProto::Config.new(
66
+ id: 236,
67
+ key: 'duration-config',
68
+ config_type: PrefabProto::ConfigType::CONFIG,
69
+ send_to_client_sdk: true,
70
+ rows: [
71
+ PrefabProto::ConfigRow.new(
72
+ values: [
73
+ PrefabProto::ConditionalValue.new(value: PrefabProto::ConfigValue.new(duration: PrefabProto::IsoDuration.new(definition: "P4DT12H30M5S")))
74
+ ]
75
+ )
76
+ ]
77
+ )
78
+
51
79
  ff = PrefabProto::Config.new(
52
80
  id: 456,
53
81
  key: 'feature-flag',
@@ -72,7 +100,7 @@ class JavascriptStubTest < Minitest::Test
72
100
  )
73
101
 
74
102
  @client = new_client(
75
- config: [log_level, config_for_sdk, config_not_for_sdk, ff],
103
+ config: [log_level, config_for_sdk, config_not_for_sdk, ff, json_config, duration_config],
76
104
  project_env_id: PROJECT_ENV_ID,
77
105
  collect_evaluation_summaries: true,
78
106
  prefab_config_override_dir: '/tmp',
@@ -85,20 +113,29 @@ class JavascriptStubTest < Minitest::Test
85
113
  def test_bootstrap
86
114
  result = Prefab::JavaScriptStub.new(@client).bootstrap({})
87
115
 
116
+
117
+ File.open('/tmp/prefab_config.json', 'w') do |f|
118
+ f.write(result)
119
+ end
88
120
  assert_equal %(
89
121
  window._prefabBootstrap = {
90
- configs: {"log-level":"INFO","basic-config":"default_value","feature-flag":false},
122
+ evaluations: {"log-level":{"value":{"logLevel":"INFO"}},"basic-config":{"value":{"string":"default_value"}},"feature-flag":{"value":{"bool":false}},"json-config":{"value":{"json":"{\\"key\\":\\"value\\"}"}},"duration-config":{"value":{"duration":{"ms":390605000.0,"seconds":390605.0}}}},
91
123
  context: {}
92
124
  }
93
125
  ).strip, result.strip
94
126
 
95
127
  result = Prefab::JavaScriptStub.new(@client).bootstrap({ user: { email: 'gmail.com' } })
96
128
 
129
+ File.open('/tmp/prefab_config.json', 'w') do |f|
130
+ f.write(result)
131
+ end
132
+
97
133
  assert_equal %(
98
134
  window._prefabBootstrap = {
99
- configs: {"log-level":"INFO","basic-config":"default_value","feature-flag":true},
135
+ evaluations: {"log-level":{"value":{"logLevel":"INFO"}},"basic-config":{"value":{"string":"default_value"}},"feature-flag":{"value":{"bool":true}},"json-config":{"value":{"json":"{\\"key\\":\\"value\\"}"}},"duration-config":{"value":{"duration":{"ms":390605000.0,"seconds":390605.0}}}},
100
136
  context: {"user":{"email":"gmail.com"}}
101
137
  }
138
+
102
139
  ).strip, result.strip
103
140
  end
104
141
 
@@ -107,7 +144,7 @@ window._prefabBootstrap = {
107
144
 
108
145
  assert_equal %(
109
146
  window.prefab = window.prefab || {};
110
- window.prefab.config = {"log-level":"INFO","basic-config":"default_value","feature-flag":false};
147
+ window.prefab.config = {"log-level":"INFO","basic-config":"default_value","feature-flag":false,"json-config":"{\\"key\\":\\"value\\"}","duration-config":{"ms":390605000.0,"seconds":390605.0}};
111
148
  window.prefab.get = function(key) {
112
149
  var value = window.prefab.config[key];
113
150
 
@@ -120,11 +157,11 @@ window.prefab.isEnabled = function(key) {
120
157
  };
121
158
  ).strip, result.strip
122
159
 
123
- result = Prefab::JavaScriptStub.new(@client).generate_stub({ user: { email: 'gmail.com' } }, "myEvalCallback")
160
+ result = Prefab::JavaScriptStub.new(@client).generate_stub({ user: { email: 'gmail.com' } }, 'myEvalCallback')
124
161
 
125
162
  assert_equal %(
126
163
  window.prefab = window.prefab || {};
127
- window.prefab.config = {"log-level":"INFO","basic-config":"default_value","feature-flag":true};
164
+ window.prefab.config = {"log-level":"INFO","basic-config":"default_value","feature-flag":true,"json-config":"{\\"key\\":\\"value\\"}","duration-config":{"ms":390605000.0,"seconds":390605.0}};
128
165
  window.prefab.get = function(key) {
129
166
  var value = window.prefab.config[key];
130
167
  myEvalCallback(key, value);
data/test/test_options.rb CHANGED
@@ -85,4 +85,9 @@ class TestOptions < Minitest::Test
85
85
  options = Prefab::Options.new(context_upload_mode: :none)
86
86
  assert_equal 0, options.collect_max_shapes
87
87
  end
88
+
89
+ def test_loading_a_datafile
90
+ options = Prefab::Options.new(datafile: "#{Dir.pwd}/test/fixtures/datafile.json")
91
+ assert_equal "#{Dir.pwd}/test/fixtures/datafile.json", options.datafile
92
+ end
88
93
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.4
4
+ version: 1.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-19 00:00:00.000000000 Z
11
+ date: 2024-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -285,6 +285,7 @@ files:
285
285
  - prefab-cloud-ruby.gemspec
286
286
  - test/.prefab.default.config.yaml
287
287
  - test/.prefab.unit_tests.config.yaml
288
+ - test/fixtures/datafile.json
288
289
  - test/integration_test.rb
289
290
  - test/integration_test_helpers.rb
290
291
  - test/support/common_helpers.rb