tggl 0.2.0 → 1.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 +4 -4
- data/README.md +51 -32
- data/lib/tggl/client.rb +23 -19
- data/lib/tggl/local_client.rb +7 -7
- data/lib/tggl/version.rb +1 -1
- data/sig/tggl/response.rbs +1 -1
- data/tggl.gemspec +3 -2
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc176934b429ebb7ba025c8e0b91702443edef4d470f72c2cb315ff52b41a6fa
|
4
|
+
data.tar.gz: af39ab816611de04c1e85e6d81711428249c713e2464dc0a45b76ccbc147b490
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e50c639a4ac523900a07f488102760f56cb81946678f23301016d6a6ecf7cd9742ab3d2254c22809de1be207d20b6dc0f640258e763c72d6a5a3ad5c522e0742
|
7
|
+
data.tar.gz: 91ec02dca2c10894638bece25229a667157dc15761fbdc3812875168b937d2601df2239509aee87b64608a480fb3d968b8ec57a31573f4f891f7779f5da0c00c
|
data/README.md
CHANGED
@@ -1,35 +1,54 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
1
|
+
<p align="center">
|
2
|
+
<picture>
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tggl.io/tggl-io-logo-white.svg">
|
4
|
+
<img align="center" alt="Tggl Logo" src="https://tggl.io/tggl-io-logo-black.svg" width="200rem" />
|
5
|
+
</picture>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<h1 align="center">Tggl Ruby SDK</h1>
|
9
|
+
|
10
|
+
<p align="center">
|
11
|
+
The Ruby SDK can be used to evaluate flags and report usage to the Tggl API or a <a href="https://tggl.io/developers/evaluating-flags/tggl-proxy">proxy</a>.
|
12
|
+
</p>
|
13
|
+
|
14
|
+
<p align="center">
|
15
|
+
<a href="https://tggl.io/">🔗 Website</a>
|
16
|
+
•
|
17
|
+
<a href="https://tggl.io/developers/sdks/ruby">📚 Documentation</a>
|
18
|
+
•
|
19
|
+
<a href="https://rubygems.org/gems/tggl">📦 RubyGem</a>
|
20
|
+
•
|
21
|
+
<a href="https://www.youtube.com/@Tggl-io">🎥 Videos</a>
|
22
|
+
</p>
|
18
23
|
|
19
24
|
## Usage
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
Install the dependency:
|
27
|
+
|
28
|
+
```bash
|
29
|
+
gem install tggl
|
30
|
+
```
|
31
|
+
|
32
|
+
Start evaluating flags:
|
33
|
+
|
34
|
+
```rb
|
35
|
+
require "tggl"
|
36
|
+
|
37
|
+
$client = Tggl::Client.new("YOUR_API_KEY")
|
38
|
+
|
39
|
+
# An API call to Tggl is performed here
|
40
|
+
$flags = $client.eval_context({
|
41
|
+
userId: "abc",
|
42
|
+
email: "foo@gmail.com",
|
43
|
+
country: "FR",
|
44
|
+
# ...
|
45
|
+
})
|
46
|
+
|
47
|
+
if $flags.is_active? "my-feature"
|
48
|
+
# ...
|
49
|
+
end
|
50
|
+
|
51
|
+
if $flags.get "my-feature" == "Variation A"
|
52
|
+
# ...
|
53
|
+
end
|
54
|
+
```
|
data/lib/tggl/client.rb
CHANGED
@@ -24,27 +24,31 @@ module Tggl
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def eval_contexts(contexts)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
if
|
42
|
-
|
27
|
+
begin
|
28
|
+
uri = URI(@url)
|
29
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
30
|
+
http.use_ssl = true
|
31
|
+
|
32
|
+
request = Net::HTTP::Post.new(uri.path, {
|
33
|
+
'X-Tggl-Api-Key' => @api_key,
|
34
|
+
'Content-Type' => 'application/json'
|
35
|
+
})
|
36
|
+
request.body = contexts.to_json
|
37
|
+
|
38
|
+
response = http.request(request)
|
39
|
+
result = JSON.parse(response.body, symbolize_names: true)
|
40
|
+
|
41
|
+
if response.code.to_i > 200
|
42
|
+
if result.nil?
|
43
|
+
raise StandardError.new "Invalid response from Tggl: #{response.code}"
|
44
|
+
end
|
45
|
+
raise StandardError.new result['error']
|
43
46
|
end
|
44
|
-
raise StandardError.new result['error']
|
45
|
-
end
|
46
47
|
|
47
|
-
|
48
|
+
result.map { |flags| Response.new(flags, reporter: @reporter) }
|
49
|
+
rescue
|
50
|
+
contexts.map { || Response.new({}, reporter: @reporter) }
|
51
|
+
end
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
data/lib/tggl/local_client.rb
CHANGED
@@ -139,12 +139,12 @@ module Tggl
|
|
139
139
|
|
140
140
|
if rule[:operator] === "STR_AFTER"
|
141
141
|
return false unless value.is_a?(String)
|
142
|
-
return value >= rule[:value]
|
142
|
+
return (value >= rule[:value]) != (rule[:negate].nil? ? false : rule[:negate])
|
143
143
|
end
|
144
144
|
|
145
145
|
if rule[:operator] === "STR_BEFORE"
|
146
146
|
return false unless value.is_a?(String)
|
147
|
-
return value <= rule[:value]
|
147
|
+
return (value <= rule[:value]) != (rule[:negate].nil? ? false : rule[:negate])
|
148
148
|
end
|
149
149
|
|
150
150
|
if rule[:operator] === "REGEXP"
|
@@ -179,9 +179,9 @@ module Tggl
|
|
179
179
|
if rule[:operator] === "DATE_AFTER"
|
180
180
|
if value.is_a?(String)
|
181
181
|
val = value[0, '2000-01-01T23:59:59'.length] + ('2000-01-01T23:59:59'[value.length..] || "")
|
182
|
-
return rule[:iso] <= val
|
182
|
+
return (rule[:iso] <= val) != (rule[:negate].nil? ? false : rule[:negate])
|
183
183
|
elsif value.is_a?(Integer) || value.is_a?(Float)
|
184
|
-
return value < 631_152_000_000 ? (value * 1000 >= rule[:timestamp]) : (value >= rule[:timestamp])
|
184
|
+
return (value < 631_152_000_000 ? (value * 1000 >= rule[:timestamp]) : (value >= rule[:timestamp])) != (rule[:negate].nil? ? false : rule[:negate])
|
185
185
|
end
|
186
186
|
return false
|
187
187
|
end
|
@@ -189,9 +189,9 @@ module Tggl
|
|
189
189
|
if rule[:operator] === "DATE_BEFORE"
|
190
190
|
if value.is_a?(String)
|
191
191
|
val = value[0, '2000-01-01T00:00:00'.length] + ('2000-01-01T00:00:00'[value.length..] || "")
|
192
|
-
return rule[:iso] >= val
|
192
|
+
return (rule[:iso] >= val) != (rule[:negate].nil? ? false : rule[:negate])
|
193
193
|
elsif value.is_a?(Integer) || value.is_a?(Float)
|
194
|
-
return value < 631_152_000_000 ? (value * 1000 <= rule[:timestamp]) : (value <= rule[:timestamp])
|
194
|
+
return (value < 631_152_000_000 ? (value * 1000 <= rule[:timestamp]) : (value <= rule[:timestamp])) != (rule[:negate].nil? ? false : rule[:negate])
|
195
195
|
end
|
196
196
|
return false
|
197
197
|
end
|
@@ -248,7 +248,7 @@ module Tggl
|
|
248
248
|
return false unless value.is_a?(String) || value.is_a?(Integer) || value.is_a?(Float)
|
249
249
|
probability = XXhash.xxh32(value.to_s, rule[:seed]) / 0xFFFFFFFF.to_f
|
250
250
|
probability -= 1.0e-8 if probability == 1
|
251
|
-
return probability >= rule[:rangeStart] && probability < rule[:rangeEnd]
|
251
|
+
return (probability >= rule[:rangeStart] && probability < rule[:rangeEnd]) != (rule[:negate].nil? ? false : rule[:negate])
|
252
252
|
end
|
253
253
|
|
254
254
|
raise StandardError.new "Unsupported operator #{rule[:operator]}"
|
data/lib/tggl/version.rb
CHANGED
data/sig/tggl/response.rbs
CHANGED
@@ -3,7 +3,7 @@ module Tggl
|
|
3
3
|
@flags: Hash[Symbol, any]
|
4
4
|
@reporter: Reporting | nil
|
5
5
|
|
6
|
-
def initialize: (Hash[Symbol, untyped] flags, Reporting | nil
|
6
|
+
def initialize: (Hash[Symbol, untyped] flags, { reporter: Reporting | nil, error?: Exception | nil } options) -> void
|
7
7
|
|
8
8
|
def is_active?: (String slug) -> bool
|
9
9
|
def get: (String slug, untyped default_value) -> untyped
|
data/tggl.gemspec
CHANGED
@@ -8,7 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["nick-keller"]
|
9
9
|
spec.email = ["hello@tggl.io"]
|
10
10
|
|
11
|
-
spec.summary = "Tggl
|
11
|
+
spec.summary = "Tggl Ruby SDK"
|
12
|
+
spec.description = "The Ruby SDK can be used to evaluate flags and report usage to the Tggl API or a Proxy."
|
12
13
|
spec.homepage = "https://tggl.io/developers/sdks/ruby"
|
13
14
|
spec.license = "MIT"
|
14
15
|
spec.required_ruby_version = ">= 2.6.0"
|
@@ -23,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
23
24
|
`git ls-files -z`.split("\x0").reject do |f|
|
24
25
|
(File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
|
25
26
|
end
|
26
|
-
end
|
27
|
+
end + ["README.md"]
|
27
28
|
spec.bindir = "exe"
|
28
29
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
30
|
spec.require_paths = ["lib"]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tggl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nick-keller
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xxhash
|
@@ -66,7 +66,8 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.23'
|
69
|
-
description:
|
69
|
+
description: The Ruby SDK can be used to evaluate flags and report usage to the Tggl
|
70
|
+
API or a Proxy.
|
70
71
|
email:
|
71
72
|
- hello@tggl.io
|
72
73
|
executables: []
|
@@ -120,5 +121,5 @@ requirements: []
|
|
120
121
|
rubygems_version: 3.4.10
|
121
122
|
signing_key:
|
122
123
|
specification_version: 4
|
123
|
-
summary: Tggl
|
124
|
+
summary: Tggl Ruby SDK
|
124
125
|
test_files: []
|