devcycle-ruby-server-sdk 2.1.1 → 2.2.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 +4 -4
- data/Gemfile +1 -0
- data/devcycle-ruby-server-sdk.gemspec +1 -0
- data/lib/devcycle-ruby-server-sdk/api/devcycle_api.rb +37 -5
- data/lib/devcycle-ruby-server-sdk/localbucketing/bucketing-lib.release.wasm +0 -0
- data/lib/devcycle-ruby-server-sdk/localbucketing/local_bucketing.rb +102 -20
- data/lib/devcycle-ruby-server-sdk/localbucketing/platform_data.rb +16 -1
- data/lib/devcycle-ruby-server-sdk/localbucketing/proto/helpers.rb +51 -0
- data/lib/devcycle-ruby-server-sdk/localbucketing/proto/variableForUser.proto +70 -0
- data/lib/devcycle-ruby-server-sdk/localbucketing/proto/variableForUser_pb.rb +80 -0
- data/lib/devcycle-ruby-server-sdk/models/user_data.rb +15 -0
- data/lib/devcycle-ruby-server-sdk/version.rb +1 -1
- data/lib/devcycle-ruby-server-sdk.rb +2 -2
- metadata +19 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cc9dd1b991a3647be626b38da7398efb99d89752f3f277225d5655490c4c9f5
|
|
4
|
+
data.tar.gz: 9aea4ae493717583a41a7bfa4c837d333a7d956fdc1d08fbb45e876be1412707
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: edb164bbfba2dc76e50947a70f19b79e28dbb18652e50873f7164f73d477bb44c3576525db2fe75873c627f0618b5e71de424316890296f8db5174af6e287523
|
|
7
|
+
data.tar.gz: 50b1254b7c4cb4fdc69a2d632e3aded8d7f7db94c13e72e29aa2042cb1e7057c9a83aed9a69200260d9ce10764938786dc961598b2d9c017d01e9f5c04249c03
|
data/Gemfile
CHANGED
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
|
28
28
|
s.add_runtime_dependency 'concurrent-ruby', '~> 1.2.0'
|
|
29
29
|
s.add_runtime_dependency 'sorbet-runtime', '~> 0.5'
|
|
30
30
|
s.add_runtime_dependency 'oj', '3.13.2'
|
|
31
|
+
s.add_runtime_dependency 'google-protobuf', '~> 3.22'
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0'
|
|
@@ -59,13 +59,13 @@ module DevCycle
|
|
|
59
59
|
nil
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def set_client_custom_data(
|
|
62
|
+
def set_client_custom_data(custom_data)
|
|
63
63
|
if @dvc_options.enable_cloud_bucketing
|
|
64
64
|
raise StandardError.new("Client Custom Data is only available in Local bucketing mode.")
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
if local_bucketing_initialized?
|
|
68
|
-
@local_bucketing.set_client_custom_data(
|
|
68
|
+
@local_bucketing.set_client_custom_data(custom_data)
|
|
69
69
|
else
|
|
70
70
|
@logger.warn("Local bucketing not initialized. Unable to set client custom data.")
|
|
71
71
|
end
|
|
@@ -181,11 +181,11 @@ module DevCycle
|
|
|
181
181
|
defaulted = true
|
|
182
182
|
if local_bucketing_initialized? && @local_bucketing.has_config
|
|
183
183
|
type_code = variable_type_code_from_type(type)
|
|
184
|
-
|
|
185
|
-
if
|
|
184
|
+
variable_pb = variable_for_user_pb(user_data, key, type_code)
|
|
185
|
+
if variable_pb == nil
|
|
186
186
|
@logger.warn("No variable found or type mismatch for key #{key}, returning default value")
|
|
187
187
|
else
|
|
188
|
-
value =
|
|
188
|
+
value = get_variable_value(variable_pb)
|
|
189
189
|
defaulted = false
|
|
190
190
|
end
|
|
191
191
|
else
|
|
@@ -210,6 +210,23 @@ module DevCycle
|
|
|
210
210
|
JSON.parse(json_str)
|
|
211
211
|
end
|
|
212
212
|
|
|
213
|
+
def variable_for_user_pb(user, key, variable_type_code)
|
|
214
|
+
user_data_pb = user.to_pb_user_data
|
|
215
|
+
params_pb = Proto::VariableForUserParams_PB.new(
|
|
216
|
+
sdkKey: @sdkKey,
|
|
217
|
+
variableKey: key,
|
|
218
|
+
variableType: variable_type_pb_code_from_type_code(variable_type_code),
|
|
219
|
+
user: user_data_pb,
|
|
220
|
+
shouldTrackEvent: true
|
|
221
|
+
)
|
|
222
|
+
param_bin_string = Proto::VariableForUserParams_PB.encode(params_pb)
|
|
223
|
+
var_bin_string = @local_bucketing.variable_for_user_pb(param_bin_string)
|
|
224
|
+
if var_bin_string.nil?
|
|
225
|
+
return nil
|
|
226
|
+
end
|
|
227
|
+
Proto::SDKVariable_PB.decode(var_bin_string)
|
|
228
|
+
end
|
|
229
|
+
|
|
213
230
|
# Get variable by key for user data
|
|
214
231
|
# @param key [String] Variable key
|
|
215
232
|
# @param user_data [UserData]
|
|
@@ -495,5 +512,20 @@ module DevCycle
|
|
|
495
512
|
raise ArgumentError.new("Invalid type for variable: #{type}")
|
|
496
513
|
end
|
|
497
514
|
end
|
|
515
|
+
|
|
516
|
+
def variable_type_pb_code_from_type_code(type_code)
|
|
517
|
+
case type_code
|
|
518
|
+
when @local_bucketing.variable_type_codes[:string]
|
|
519
|
+
Proto::VariableType_PB::String
|
|
520
|
+
when @local_bucketing.variable_type_codes[:boolean]
|
|
521
|
+
Proto::VariableType_PB::Boolean
|
|
522
|
+
when @local_bucketing.variable_type_codes[:number]
|
|
523
|
+
Proto::VariableType_PB::Number
|
|
524
|
+
when @local_bucketing.variable_type_codes[:json]
|
|
525
|
+
Proto::VariableType_PB::JSON
|
|
526
|
+
else
|
|
527
|
+
raise ArgumentError.new("Invalid type code for variable: #{type_code}")
|
|
528
|
+
end
|
|
529
|
+
end
|
|
498
530
|
end
|
|
499
531
|
end
|
|
Binary file
|
|
@@ -17,6 +17,11 @@ module DevCycle
|
|
|
17
17
|
attr_accessor :initialized
|
|
18
18
|
attr_accessor :has_config
|
|
19
19
|
|
|
20
|
+
BUFFER_HEADER_SIZE = 12
|
|
21
|
+
ARRAY_BUFFER_CLASS_ID = 1
|
|
22
|
+
STRING_CLASS_ID = 2
|
|
23
|
+
HEADER_ID = 9
|
|
24
|
+
|
|
20
25
|
@@rand = Random.new(seed = Random.new_seed)
|
|
21
26
|
@@engine = Wasmtime::Engine.new
|
|
22
27
|
|
|
@@ -77,7 +82,6 @@ module DevCycle
|
|
|
77
82
|
|
|
78
83
|
@@linker.func_new("env", "seed", [], [:f64]) do |_caller|
|
|
79
84
|
@@rand.rand(1.0) * DateTime.now.strftime("%Q").to_i
|
|
80
|
-
|
|
81
85
|
end
|
|
82
86
|
|
|
83
87
|
@@instance = @@linker.instantiate(@@store, @@wasmmodule)
|
|
@@ -101,6 +105,8 @@ module DevCycle
|
|
|
101
105
|
number: @@instance.export("VariableType.Number").to_global.get.to_i,
|
|
102
106
|
json: @@instance.export("VariableType.JSON").to_global.get.to_i
|
|
103
107
|
}
|
|
108
|
+
@buffer_header_addr = @@instance.export("__new").to_func.call(BUFFER_HEADER_SIZE, HEADER_ID)
|
|
109
|
+
asc_pin(@buffer_header_addr)
|
|
104
110
|
set_sdk_key_internal(sdkkey)
|
|
105
111
|
platform_data = PlatformData.new('server', VERSION, RUBY_VERSION, nil, 'Ruby', Socket.gethostname)
|
|
106
112
|
set_platform_data(platform_data)
|
|
@@ -142,6 +148,16 @@ module DevCycle
|
|
|
142
148
|
end
|
|
143
149
|
end
|
|
144
150
|
|
|
151
|
+
sig { params(bin_str: String).returns(T.nilable(String)) }
|
|
152
|
+
def variable_for_user_pb(bin_str)
|
|
153
|
+
@wasm_mutex.synchronize do
|
|
154
|
+
@@stack_tracer = @@stack_tracer_raise
|
|
155
|
+
params_addr = malloc_asc_byte_array(bin_str)
|
|
156
|
+
var_addr = @@instance.invoke("variableForUser_PB", params_addr)
|
|
157
|
+
read_asc_byte_array(var_addr)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
145
161
|
sig { returns(T::Array[EventsPayload]) }
|
|
146
162
|
def flush_event_queue
|
|
147
163
|
@wasm_mutex.synchronize do
|
|
@@ -222,9 +238,9 @@ module DevCycle
|
|
|
222
238
|
sig { params(config: String).returns(NilClass) }
|
|
223
239
|
def store_config(config)
|
|
224
240
|
@wasm_mutex.synchronize do
|
|
225
|
-
config_addr =
|
|
241
|
+
config_addr = malloc_asc_byte_array(config)
|
|
226
242
|
@@stack_tracer = @@stack_tracer_raise
|
|
227
|
-
@@instance.invoke("
|
|
243
|
+
@@instance.invoke("setConfigDataUTF8", @sdkKeyAddr, config_addr)
|
|
228
244
|
end
|
|
229
245
|
end
|
|
230
246
|
|
|
@@ -238,25 +254,25 @@ module DevCycle
|
|
|
238
254
|
end
|
|
239
255
|
end
|
|
240
256
|
|
|
241
|
-
sig { params(
|
|
242
|
-
def set_client_custom_data(
|
|
257
|
+
sig { params(custom_data: Hash).returns(NilClass) }
|
|
258
|
+
def set_client_custom_data(custom_data)
|
|
243
259
|
@wasm_mutex.synchronize do
|
|
244
|
-
|
|
245
|
-
|
|
260
|
+
custom_data_json = Oj.dump(custom_data, mode: :json)
|
|
261
|
+
custom_data_addr = malloc_asc_byte_array(custom_data_json)
|
|
246
262
|
@@stack_tracer = @@stack_tracer_raise
|
|
247
|
-
@@instance.invoke("
|
|
263
|
+
@@instance.invoke("setClientCustomDataUTF8", @sdkKeyAddr, custom_data_addr)
|
|
248
264
|
end
|
|
249
265
|
end
|
|
250
266
|
|
|
251
267
|
private
|
|
252
268
|
|
|
253
|
-
sig { params(
|
|
254
|
-
def set_platform_data(
|
|
269
|
+
sig { params(platform_data: PlatformData).returns(NilClass) }
|
|
270
|
+
def set_platform_data(platform_data)
|
|
255
271
|
@wasm_mutex.synchronize do
|
|
256
|
-
|
|
257
|
-
|
|
272
|
+
platform_data_json = platform_data.to_json
|
|
273
|
+
platform_data_addr = malloc_asc_byte_array(platform_data_json)
|
|
258
274
|
@@stack_tracer = @@stack_tracer_raise
|
|
259
|
-
@@instance.invoke("
|
|
275
|
+
@@instance.invoke("setPlatformDataUTF8", platform_data_addr)
|
|
260
276
|
end
|
|
261
277
|
end
|
|
262
278
|
|
|
@@ -280,13 +296,12 @@ module DevCycle
|
|
|
280
296
|
# @return [Integer] address to WASM String
|
|
281
297
|
sig { params(string: String).returns(Integer) }
|
|
282
298
|
def malloc_asc_string(string)
|
|
283
|
-
wasm_object_id = 1
|
|
284
299
|
@@stack_tracer = @@stack_tracer_raise
|
|
285
300
|
wasm_new = @@instance.export("__new").to_func
|
|
286
301
|
utf8_bytes = string.bytes
|
|
287
302
|
byte_len = utf8_bytes.length
|
|
288
303
|
|
|
289
|
-
start_addr = wasm_new.call(byte_len * 2,
|
|
304
|
+
start_addr = wasm_new.call(byte_len * 2, STRING_CLASS_ID)
|
|
290
305
|
i = 0
|
|
291
306
|
while i < byte_len
|
|
292
307
|
@@stack_tracer = @@stack_tracer_raise
|
|
@@ -306,15 +321,82 @@ module DevCycle
|
|
|
306
321
|
end
|
|
307
322
|
|
|
308
323
|
@@stack_tracer = @@stack_tracer_raise
|
|
309
|
-
raw_bytes = @@memory.read(address - 4, 4).bytes
|
|
310
|
-
len =
|
|
311
|
-
raw_bytes.each { |j|
|
|
312
|
-
len = (len << 8) + (j & 0xFF)
|
|
313
|
-
}
|
|
324
|
+
raw_bytes = @@memory.read(address - 4, 4).bytes
|
|
325
|
+
len = asc_bytes_to_int(raw_bytes)
|
|
314
326
|
|
|
315
327
|
@@stack_tracer = @@stack_tracer_raise
|
|
316
328
|
result = @@memory.read(address, len).bytes
|
|
317
329
|
result.select.with_index { |_, i| i.even? }.pack('c*')
|
|
318
330
|
end
|
|
331
|
+
|
|
332
|
+
# @param [String] string utf8 string to allocate
|
|
333
|
+
# @return [Integer] address to WASM String
|
|
334
|
+
sig { params(raw_str: String).returns(Integer) }
|
|
335
|
+
def malloc_asc_byte_array(raw_str)
|
|
336
|
+
align = 0
|
|
337
|
+
@@stack_tracer = @@stack_tracer_raise
|
|
338
|
+
wasm_new = @@instance.export("__new").to_func
|
|
339
|
+
|
|
340
|
+
# break up the UTF-8 characters in raw_str into bytes and pack them into a binary sequence
|
|
341
|
+
# example: "Ϗ" -> "\xCF\x8F"
|
|
342
|
+
bin_string = raw_str.bytes.pack('C*')
|
|
343
|
+
length = bin_string.length
|
|
344
|
+
|
|
345
|
+
# allocate buffer of size length - returned address is in Big Endian order
|
|
346
|
+
buffer_addr = wasm_new.call(length << align, ARRAY_BUFFER_CLASS_ID)
|
|
347
|
+
|
|
348
|
+
# convert to array of bytes in Little Endian order
|
|
349
|
+
# - pack('L<') packs the address into a binary sequence in Little Endian order
|
|
350
|
+
# - unpack('C*') converts each byte in the string to it's decimal representation
|
|
351
|
+
buffer_addr_little_endian_bytes = [buffer_addr].pack('L<').unpack('C*')
|
|
352
|
+
|
|
353
|
+
# write address byte values in Little Endian order to header
|
|
354
|
+
buffer_addr_little_endian_bytes.each_with_index { |byte, i|
|
|
355
|
+
@@memory.write(@buffer_header_addr + i, [byte].pack('C'))
|
|
356
|
+
@@memory.write(@buffer_header_addr + i + 4, [byte].pack('C'))
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
# convert length to an array of bytes in Little Endian order
|
|
360
|
+
byte_len_little_endian_bytes = [length].pack('L<').unpack('C*')
|
|
361
|
+
|
|
362
|
+
# write length to header
|
|
363
|
+
byte_len_little_endian_bytes.each_with_index { |byte, i|
|
|
364
|
+
@@memory.write(@buffer_header_addr + i + 8, [byte].pack('C'))
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
# write data bytes to buffer
|
|
368
|
+
bin_string.each_char.with_index { |char, i|
|
|
369
|
+
@@memory.write(buffer_addr + i, char)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
@buffer_header_addr
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
sig { params(address: Integer).returns(T.nilable(String)) }
|
|
376
|
+
def read_asc_byte_array(address)
|
|
377
|
+
if address == 0
|
|
378
|
+
@logger.debug("null address passed to read_asc_byte_array")
|
|
379
|
+
return nil
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
length_bytes = @@memory.read(address + 8, 4).bytes
|
|
383
|
+
length = asc_bytes_to_int(length_bytes)
|
|
384
|
+
|
|
385
|
+
buffer_addr_bytes = @@memory.read(address, 4).bytes
|
|
386
|
+
buffer_addr = asc_bytes_to_int(buffer_addr_bytes)
|
|
387
|
+
|
|
388
|
+
@@memory.read(buffer_addr, length)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# @param [Array<Integer>] bytes: array of bytes in Little Endian order
|
|
392
|
+
# @return [Integer] integer value
|
|
393
|
+
# @example
|
|
394
|
+
# asc_bytes_to_int([0, 4, 0, 0]) # => 1024 = (0 << 0) + (4 << 8) + (0 << 16) + (0 << 24)
|
|
395
|
+
sig { params(bytes: T::Array[Integer]).returns(Integer) }
|
|
396
|
+
def asc_bytes_to_int(bytes)
|
|
397
|
+
bytes.each_with_index.reduce(0) { |acc, (byte, i)|
|
|
398
|
+
acc + (byte << (i * 8))
|
|
399
|
+
}
|
|
400
|
+
end
|
|
319
401
|
end
|
|
320
402
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'socket'
|
|
4
|
-
require '
|
|
4
|
+
require 'oj'
|
|
5
5
|
|
|
6
6
|
module DevCycle
|
|
7
7
|
class PlatformData
|
|
@@ -25,5 +25,20 @@ module DevCycle
|
|
|
25
25
|
@hostname = Socket.gethostname
|
|
26
26
|
self
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
def to_hash
|
|
30
|
+
{
|
|
31
|
+
sdkType: @sdkType,
|
|
32
|
+
sdkVersion: @sdkVersion,
|
|
33
|
+
platformVersion: @platformVersion,
|
|
34
|
+
deviceModel: @deviceModel,
|
|
35
|
+
platform: @platform,
|
|
36
|
+
hostname: @hostname
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_json
|
|
41
|
+
Oj.dump(to_hash, mode: :json)
|
|
42
|
+
end
|
|
28
43
|
end
|
|
29
44
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
def create_nullable_string(val)
|
|
2
|
+
if val.nil? || val.empty?
|
|
3
|
+
Proto::NullableString.new(value: "", isNull: true)
|
|
4
|
+
else
|
|
5
|
+
Proto::NullableString.new(value: val, isNull: false)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def create_nullable_double(val)
|
|
10
|
+
if val.nil?
|
|
11
|
+
Proto::NullableDouble.new(value: 0, isNull: true)
|
|
12
|
+
else
|
|
13
|
+
Proto::NullableDouble.new(value: val, isNull: false)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_nullable_custom_data(data)
|
|
18
|
+
data_map = {}
|
|
19
|
+
if data.nil? || data.length == 0
|
|
20
|
+
return Proto::NullableCustomData.new(value: data_map, isNull: true)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
data.each do |key, value|
|
|
24
|
+
if value.nil?
|
|
25
|
+
data_map[key] = Proto::CustomDataValue.new(type: Proto::CustomDataType::Null)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if value.is_a? String
|
|
29
|
+
data_map[key] = Proto::CustomDataValue.new(type: Proto::CustomDataType::Str, stringValue: value)
|
|
30
|
+
elsif value.is_a?(Float) || value.is_a?(Integer)
|
|
31
|
+
data_map[key] = Proto::CustomDataValue.new(type: Proto::CustomDataType::Num, doubleValue: value)
|
|
32
|
+
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
|
33
|
+
data_map[key] = Proto::CustomDataValue.new(type: Proto::CustomDataType::Bool, boolValue: value)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Proto::NullableCustomData.new(value: data_map, isNull: false)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def get_variable_value(variable_pb)
|
|
41
|
+
case variable_pb.type
|
|
42
|
+
when :Boolean
|
|
43
|
+
variable_pb.boolValue
|
|
44
|
+
when :Number
|
|
45
|
+
variable_pb.doubleValue
|
|
46
|
+
when :String
|
|
47
|
+
variable_pb.stringValue
|
|
48
|
+
when :JSON
|
|
49
|
+
JSON.parse variable_pb.stringValue
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
package proto;
|
|
3
|
+
|
|
4
|
+
enum VariableType_PB {
|
|
5
|
+
Boolean = 0;
|
|
6
|
+
Number = 1;
|
|
7
|
+
String = 2;
|
|
8
|
+
JSON = 3;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
message NullableString {
|
|
12
|
+
string value = 1;
|
|
13
|
+
bool isNull = 2;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
message NullableDouble {
|
|
17
|
+
double value = 1;
|
|
18
|
+
bool isNull = 2;
|
|
19
|
+
string dummy = 3;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
enum CustomDataType {
|
|
23
|
+
Bool = 0;
|
|
24
|
+
Num = 1;
|
|
25
|
+
Str = 2;
|
|
26
|
+
Null = 3;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
message CustomDataValue {
|
|
30
|
+
CustomDataType type = 1;
|
|
31
|
+
bool boolValue = 2;
|
|
32
|
+
double doubleValue = 3;
|
|
33
|
+
string stringValue = 4;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
message NullableCustomData {
|
|
37
|
+
map<string, CustomDataValue> value = 1;
|
|
38
|
+
bool isNull = 2;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
message VariableForUserParams_PB {
|
|
42
|
+
string sdkKey = 1;
|
|
43
|
+
string variableKey = 2;
|
|
44
|
+
VariableType_PB variableType = 3;
|
|
45
|
+
DVCUser_PB user = 4;
|
|
46
|
+
bool shouldTrackEvent = 5;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
message DVCUser_PB {
|
|
50
|
+
string user_id = 1;
|
|
51
|
+
NullableString email = 2;
|
|
52
|
+
NullableString name = 3;
|
|
53
|
+
NullableString language = 4;
|
|
54
|
+
NullableString country = 5;
|
|
55
|
+
NullableDouble appBuild = 6;
|
|
56
|
+
NullableString appVersion = 7;
|
|
57
|
+
NullableString deviceModel = 8;
|
|
58
|
+
NullableCustomData customData = 9;
|
|
59
|
+
NullableCustomData privateCustomData = 10;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
message SDKVariable_PB {
|
|
63
|
+
string _id = 1;
|
|
64
|
+
VariableType_PB type = 2;
|
|
65
|
+
string key = 3;
|
|
66
|
+
bool boolValue = 4;
|
|
67
|
+
double doubleValue = 5;
|
|
68
|
+
string stringValue = 6;
|
|
69
|
+
NullableString evalReason = 7;
|
|
70
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
2
|
+
# source: variableForUser.proto
|
|
3
|
+
|
|
4
|
+
require 'google/protobuf'
|
|
5
|
+
|
|
6
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
7
|
+
add_file("variableForUser.proto", :syntax => :proto3) do
|
|
8
|
+
add_message "proto.NullableString" do
|
|
9
|
+
optional :value, :string, 1
|
|
10
|
+
optional :isNull, :bool, 2
|
|
11
|
+
end
|
|
12
|
+
add_message "proto.NullableDouble" do
|
|
13
|
+
optional :value, :double, 1
|
|
14
|
+
optional :isNull, :bool, 2
|
|
15
|
+
optional :dummy, :string, 3
|
|
16
|
+
end
|
|
17
|
+
add_message "proto.CustomDataValue" do
|
|
18
|
+
optional :type, :enum, 1, "proto.CustomDataType"
|
|
19
|
+
optional :boolValue, :bool, 2
|
|
20
|
+
optional :doubleValue, :double, 3
|
|
21
|
+
optional :stringValue, :string, 4
|
|
22
|
+
end
|
|
23
|
+
add_message "proto.NullableCustomData" do
|
|
24
|
+
map :value, :string, :message, 1, "proto.CustomDataValue"
|
|
25
|
+
optional :isNull, :bool, 2
|
|
26
|
+
end
|
|
27
|
+
add_message "proto.VariableForUserParams_PB" do
|
|
28
|
+
optional :sdkKey, :string, 1
|
|
29
|
+
optional :variableKey, :string, 2
|
|
30
|
+
optional :variableType, :enum, 3, "proto.VariableType_PB"
|
|
31
|
+
optional :user, :message, 4, "proto.DVCUser_PB"
|
|
32
|
+
optional :shouldTrackEvent, :bool, 5
|
|
33
|
+
end
|
|
34
|
+
add_message "proto.DVCUser_PB" do
|
|
35
|
+
optional :user_id, :string, 1
|
|
36
|
+
optional :email, :message, 2, "proto.NullableString"
|
|
37
|
+
optional :name, :message, 3, "proto.NullableString"
|
|
38
|
+
optional :language, :message, 4, "proto.NullableString"
|
|
39
|
+
optional :country, :message, 5, "proto.NullableString"
|
|
40
|
+
optional :appBuild, :message, 6, "proto.NullableDouble"
|
|
41
|
+
optional :appVersion, :message, 7, "proto.NullableString"
|
|
42
|
+
optional :deviceModel, :message, 8, "proto.NullableString"
|
|
43
|
+
optional :customData, :message, 9, "proto.NullableCustomData"
|
|
44
|
+
optional :privateCustomData, :message, 10, "proto.NullableCustomData"
|
|
45
|
+
end
|
|
46
|
+
add_message "proto.SDKVariable_PB" do
|
|
47
|
+
optional :_id, :string, 1
|
|
48
|
+
optional :type, :enum, 2, "proto.VariableType_PB"
|
|
49
|
+
optional :key, :string, 3
|
|
50
|
+
optional :boolValue, :bool, 4
|
|
51
|
+
optional :doubleValue, :double, 5
|
|
52
|
+
optional :stringValue, :string, 6
|
|
53
|
+
optional :evalReason, :message, 7, "proto.NullableString"
|
|
54
|
+
end
|
|
55
|
+
add_enum "proto.VariableType_PB" do
|
|
56
|
+
value :Boolean, 0
|
|
57
|
+
value :Number, 1
|
|
58
|
+
value :String, 2
|
|
59
|
+
value :JSON, 3
|
|
60
|
+
end
|
|
61
|
+
add_enum "proto.CustomDataType" do
|
|
62
|
+
value :Bool, 0
|
|
63
|
+
value :Num, 1
|
|
64
|
+
value :Str, 2
|
|
65
|
+
value :Null, 3
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
module Proto
|
|
71
|
+
NullableString = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.NullableString").msgclass
|
|
72
|
+
NullableDouble = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.NullableDouble").msgclass
|
|
73
|
+
CustomDataValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.CustomDataValue").msgclass
|
|
74
|
+
NullableCustomData = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.NullableCustomData").msgclass
|
|
75
|
+
VariableForUserParams_PB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.VariableForUserParams_PB").msgclass
|
|
76
|
+
DVCUser_PB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.DVCUser_PB").msgclass
|
|
77
|
+
SDKVariable_PB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.SDKVariable_PB").msgclass
|
|
78
|
+
VariableType_PB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.VariableType_PB").enummodule
|
|
79
|
+
CustomDataType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("proto.CustomDataType").enummodule
|
|
80
|
+
end
|
|
@@ -415,5 +415,20 @@ module DevCycle
|
|
|
415
415
|
def to_json
|
|
416
416
|
Oj.dump(to_hash, mode: :json)
|
|
417
417
|
end
|
|
418
|
+
|
|
419
|
+
def to_pb_user_data
|
|
420
|
+
pb_user = Proto::DVCUser_PB.new
|
|
421
|
+
pb_user.user_id = @user_id
|
|
422
|
+
pb_user.email = create_nullable_string(@email)
|
|
423
|
+
pb_user.name = create_nullable_string(@name)
|
|
424
|
+
pb_user.language = create_nullable_string(@language)
|
|
425
|
+
pb_user.country = create_nullable_string(@country)
|
|
426
|
+
pb_user.appVersion = create_nullable_string(@appVersion)
|
|
427
|
+
pb_user.appBuild = create_nullable_double(@appBuild)
|
|
428
|
+
pb_user.customData = create_nullable_custom_data(@customData)
|
|
429
|
+
pb_user.privateCustomData = create_nullable_custom_data(@privateCustomData)
|
|
430
|
+
|
|
431
|
+
pb_user
|
|
432
|
+
end
|
|
418
433
|
end
|
|
419
434
|
end
|
|
@@ -15,8 +15,6 @@ require 'devcycle-ruby-server-sdk/api_client'
|
|
|
15
15
|
require 'devcycle-ruby-server-sdk/api_error'
|
|
16
16
|
require 'devcycle-ruby-server-sdk/version'
|
|
17
17
|
require 'devcycle-ruby-server-sdk/configuration'
|
|
18
|
-
require 'devcycle-ruby-server-sdk/localbucketing/event_queue'
|
|
19
|
-
require 'devcycle-ruby-server-sdk/localbucketing/event_types'
|
|
20
18
|
|
|
21
19
|
# Models
|
|
22
20
|
require 'devcycle-ruby-server-sdk/models/error_response'
|
|
@@ -36,6 +34,8 @@ require 'devcycle-ruby-server-sdk/localbucketing/platform_data'
|
|
|
36
34
|
require 'devcycle-ruby-server-sdk/localbucketing/bucketed_user_config'
|
|
37
35
|
require 'devcycle-ruby-server-sdk/localbucketing/event_queue'
|
|
38
36
|
require 'devcycle-ruby-server-sdk/localbucketing/event_types'
|
|
37
|
+
require 'devcycle-ruby-server-sdk/localbucketing/proto/variableForUser_pb'
|
|
38
|
+
require 'devcycle-ruby-server-sdk/localbucketing/proto/helpers'
|
|
39
39
|
|
|
40
40
|
module DevCycle
|
|
41
41
|
class << self
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: devcycle-ruby-server-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- DevCycleHQ
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-03-
|
|
11
|
+
date: 2023-03-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: typhoeus
|
|
@@ -86,6 +86,20 @@ dependencies:
|
|
|
86
86
|
- - '='
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
88
|
version: 3.13.2
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: google-protobuf
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '3.22'
|
|
96
|
+
type: :runtime
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.22'
|
|
89
103
|
- !ruby/object:Gem::Dependency
|
|
90
104
|
name: rspec
|
|
91
105
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -132,6 +146,9 @@ files:
|
|
|
132
146
|
- lib/devcycle-ruby-server-sdk/localbucketing/events_payload.rb
|
|
133
147
|
- lib/devcycle-ruby-server-sdk/localbucketing/local_bucketing.rb
|
|
134
148
|
- lib/devcycle-ruby-server-sdk/localbucketing/platform_data.rb
|
|
149
|
+
- lib/devcycle-ruby-server-sdk/localbucketing/proto/helpers.rb
|
|
150
|
+
- lib/devcycle-ruby-server-sdk/localbucketing/proto/variableForUser.proto
|
|
151
|
+
- lib/devcycle-ruby-server-sdk/localbucketing/proto/variableForUser_pb.rb
|
|
135
152
|
- lib/devcycle-ruby-server-sdk/models/error_response.rb
|
|
136
153
|
- lib/devcycle-ruby-server-sdk/models/event.rb
|
|
137
154
|
- lib/devcycle-ruby-server-sdk/models/feature.rb
|