prefab-cloud-ruby 1.8.4 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
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