From fa0cb3339d4228114911954e9f0f6c28b9b8a400 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Mon, 24 Mar 2025 20:05:07 +0100 Subject: [PATCH 1/3] fix: handle buffer scan more graciously and print to terminal Signed-off-by: Simon Schrottner --- launchpad/pkg/flagd.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/launchpad/pkg/flagd.go b/launchpad/pkg/flagd.go index 37929fd..03d768b 100644 --- a/launchpad/pkg/flagd.go +++ b/launchpad/pkg/flagd.go @@ -110,8 +110,8 @@ func StartFlagd(config string) error { flagdLock.Unlock() ready := make(chan bool) - go monitorOutput(stdout, ready) - go monitorOutput(stderr, ready) + go monitorOutput(stdout, ready, "stdout") + go monitorOutput(stderr, ready, "stderr") select { case success := <-ready: @@ -154,19 +154,27 @@ func stopFlagDWithoutLock() error { return fmt.Errorf("failed to stop flagd: %v", err) } flagdCmd = nil + fmt.Println("flagd stopped") } return nil } -func monitorOutput(pipe io.ReadCloser, ready chan bool) { +func monitorOutput(pipe io.ReadCloser, ready chan bool, info string) { scanner := bufio.NewScanner(pipe) + //adjust the capacity to your need (max characters in line) + const maxCapacity = 512 * 1024 + buf := make([]byte, maxCapacity) + scanner.Buffer(buf, maxCapacity) + started := false + for scanner.Scan() { line := scanner.Text() - fmt.Println("[flagd]:", line) - if ready != nil && strings.Contains(line, "listening at") { + fmt.Println("[flagd ", info, "]:", line) + if ready != nil && !started && strings.Contains(line, "listening at") { ready <- true close(ready) - return + fmt.Println("flagd started properly found logline with 'listening at'") + started = true } } } From b410d7fe1f52db1b1fbdf364e9789044a586973d Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 25 Mar 2025 07:07:34 +0100 Subject: [PATCH 2/3] fixup: renaming Signed-off-by: Simon Schrottner --- flags/allFlags.json | 727 +++++++++++++++++++++++++++++++++++++++++ launchpad/pkg/flagd.go | 4 +- 2 files changed, 729 insertions(+), 2 deletions(-) create mode 100644 flags/allFlags.json diff --git a/flags/allFlags.json b/flags/allFlags.json new file mode 100644 index 0000000..0321f6e --- /dev/null +++ b/flags/allFlags.json @@ -0,0 +1,727 @@ +{ + "$evaluators": { + "is_ballmer": { + "==": [ + "ballmer@macrosoft.com", + { + "var": [ + "email" + ] + } + ] + } + }, + "flags": { + "boolean-flag": { + "defaultVariant": "on", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "boolean-targeted-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "targeting": { + "if": [ + { + "$ref": "is_ballmer" + }, + "zero" + ] + }, + "variants": { + "non-zero": true, + "zero": false + } + }, + "boolean-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "variants": { + "non-zero": true, + "zero": false + } + }, + "changing-flag": { + "defaultVariant": "foo", + "state": "ENABLED", + "variants": { + "bar": "bar", + "foo": "foo" + } + }, + "context-aware": { + "defaultVariant": "external", + "state": "ENABLED", + "targeting": { + "if": [ + { + "and": [ + { + "==": [ + { + "var": [ + "fn" + ] + }, + "Sulisław" + ] + }, + { + "==": [ + { + "var": [ + "ln" + ] + }, + "Świętopełk" + ] + }, + { + "==": [ + { + "var": [ + "age" + ] + }, + 29 + ] + }, + { + "==": [ + { + "var": [ + "customer" + ] + }, + false + ] + } + ] + }, + "internal", + "external" + ] + }, + "variants": { + "external": "EXTERNAL", + "internal": "INTERNAL" + } + }, + "empty-targeting-flag": { + "defaultVariant": "false", + "state": "ENABLED", + "targeting": {}, + "variants": { + "false": 1, + "true": 2 + } + }, + "equal-greater-lesser-version-flag": { + "defaultVariant": "none", + "state": "ENABLED", + "targeting": { + "if": [ + { + "sem_ver": [ + { + "var": "version" + }, + "=", + "2.0.0" + ] + }, + "equal", + { + "if": [ + { + "sem_ver": [ + { + "var": "version" + }, + "\u003e", + "2.0.0" + ] + }, + "greater", + { + "if": [ + { + "sem_ver": [ + { + "var": "version" + }, + "\u003c", + "2.0.0" + ] + }, + "lesser", + { + "if": [ + { + "sem_ver": [ + { + "var": "version" + }, + "=", + "2.0.0.0" + ] + }, + "fail", + "none" + ] + } + ] + } + ] + } + ] + }, + "variants": { + "equal": "equal", + "greater": "greater", + "lesser": "lesser", + "none": "none" + } + }, + "error-targeting-flag": { + "defaultVariant": "two", + "state": "ENABLED", + "targeting": { + "invalid": [ + "this is not valid targeting" + ] + }, + "variants": { + "one": 1, + "two": 2 + } + }, + "flagd-context-aware": { + "defaultVariant": "external", + "state": "ENABLED", + "targeting": { + "if": [ + { + "==": [ + { + "var": [ + "injectedmetadata" + ] + }, + "set" + ] + }, + "internal", + "external" + ] + }, + "variants": { + "external": "EXTERNAL", + "internal": "INTERNAL" + } + }, + "float-flag": { + "defaultVariant": "half", + "state": "ENABLED", + "variants": { + "half": 0.5, + "tenth": 0.1 + } + }, + "float-targeted-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "targeting": { + "if": [ + { + "$ref": "is_ballmer" + }, + "zero" + ] + }, + "variants": { + "non-zero": 1, + "zero": 0 + } + }, + "float-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "variants": { + "non-zero": 1, + "zero": 0 + } + }, + "fractional-flag": { + "defaultVariant": "wild", + "state": "ENABLED", + "targeting": { + "fractional": [ + { + "cat": [ + { + "var": "$flagd.flagKey" + }, + { + "var": "user.name" + } + ] + }, + [ + "clubs", + 25 + ], + [ + "diamonds", + 25 + ], + [ + "hearts", + 25 + ], + [ + "spades", + 25 + ] + ] + }, + "variants": { + "clubs": "clubs", + "diamonds": "diamonds", + "hearts": "hearts", + "spades": "spades", + "wild": "wild" + } + }, + "fractional-flag-A-shared-seed": { + "defaultVariant": "wild", + "state": "ENABLED", + "targeting": { + "fractional": [ + { + "cat": [ + "shared-seed", + { + "var": "user.name" + } + ] + }, + [ + "clubs", + 25 + ], + [ + "diamonds", + 25 + ], + [ + "hearts", + 25 + ], + [ + "spades", + 25 + ] + ] + }, + "variants": { + "clubs": "clubs", + "diamonds": "diamonds", + "hearts": "hearts", + "spades": "spades", + "wild": "wild" + } + }, + "fractional-flag-B-shared-seed": { + "defaultVariant": "wild", + "state": "ENABLED", + "targeting": { + "fractional": [ + { + "cat": [ + "shared-seed", + { + "var": "user.name" + } + ] + }, + [ + "clubs", + 25 + ], + [ + "diamonds", + 25 + ], + [ + "hearts", + 25 + ], + [ + "spades", + 25 + ] + ] + }, + "variants": { + "clubs": "ace-of-clubs", + "diamonds": "ace-of-diamonds", + "hearts": "ace-of-hearts", + "spades": "ace-of-spades", + "wild": "wild" + } + }, + "fractional-flag-shorthand": { + "defaultVariant": "draw", + "state": "ENABLED", + "targeting": { + "fractional": [ + [ + "heads" + ], + [ + "tails", + 1 + ] + ] + }, + "variants": { + "draw": "draw", + "heads": "heads", + "tails": "tails" + } + }, + "integer-flag": { + "defaultVariant": "ten", + "state": "ENABLED", + "variants": { + "one": 1, + "ten": 10 + } + }, + "integer-targeted-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "targeting": { + "if": [ + { + "$ref": "is_ballmer" + }, + "zero" + ] + }, + "variants": { + "non-zero": 1, + "zero": 0 + } + }, + "integer-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "variants": { + "non-zero": 1, + "zero": 0 + } + }, + "major-minor-version-flag": { + "defaultVariant": "none", + "state": "ENABLED", + "targeting": { + "if": [ + { + "sem_ver": [ + { + "var": "version" + }, + "~", + "3.0.0" + ] + }, + "minor", + { + "if": [ + { + "sem_ver": [ + { + "var": "version" + }, + "^", + "3.0.0" + ] + }, + "major", + "none" + ] + } + ] + }, + "variants": { + "major": "major", + "minor": "minor", + "none": "none" + } + }, + "metadata-flag": { + "defaultVariant": "false", + "metadata": { + "boolean": true, + "float": 1.2, + "integer": 1, + "string": "a" + }, + "state": "ENABLED", + "targeting": {}, + "variants": { + "false": false, + "true": true + } + }, + "missing-variant-targeting-flag": { + "defaultVariant": "two", + "state": "ENABLED", + "targeting": { + "if": [ + true, + "three", + "one" + ] + }, + "variants": { + "one": 1, + "two": 2 + } + }, + "non-string-variant-targeting-flag": { + "defaultVariant": "false", + "state": "ENABLED", + "targeting": { + "if": [ + true, + true, + false + ] + }, + "variants": { + "false": 1, + "true": 2 + } + }, + "object-flag": { + "defaultVariant": "template", + "state": "ENABLED", + "variants": { + "empty": {}, + "template": { + "imagesPerPage": 100, + "showImages": true, + "title": "Check out these pics!" + } + } + }, + "some-email-targeted-flag": { + "defaultVariant": "none", + "state": "ENABLED", + "targeting": { + "if": [ + { + "$ref": "is_ballmer" + }, + "hi", + "bye" + ] + }, + "variants": { + "bye": "bye", + "hi": "hi", + "none": "none" + } + }, + "some-other-email-targeted-flag": { + "defaultVariant": "none", + "state": "ENABLED", + "targeting": { + "if": [ + { + "$ref": "is_ballmer" + }, + "yes", + "no" + ] + }, + "variants": { + "no": "no", + "none": "none", + "yes": "yes" + } + }, + "starts-ends-flag": { + "defaultVariant": "none", + "state": "ENABLED", + "targeting": { + "if": [ + { + "starts_with": [ + { + "var": "id" + }, + "abc" + ] + }, + "prefix", + { + "if": [ + { + "ends_with": [ + { + "var": "id" + }, + "xyz" + ] + }, + "postfix", + { + "if": [ + { + "ends_with": [ + { + "var": "id" + }, + 3 + ] + }, + "fail", + "none" + ] + } + ] + } + ] + }, + "variants": { + "none": "none", + "postfix": "postfix", + "prefix": "prefix" + } + }, + "string-flag": { + "defaultVariant": "greeting", + "state": "ENABLED", + "variants": { + "greeting": "hi", + "parting": "bye" + } + }, + "string-targeted-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "targeting": { + "if": [ + { + "$ref": "is_ballmer" + }, + "zero" + ] + }, + "variants": { + "non-zero": "str", + "zero": "" + } + }, + "string-zero-flag": { + "defaultVariant": "zero", + "state": "ENABLED", + "variants": { + "non-zero": "str", + "zero": "" + } + }, + "targeting-key-flag": { + "defaultVariant": "miss", + "state": "ENABLED", + "targeting": { + "if": [ + { + "==": [ + { + "var": "targetingKey" + }, + "5c3d8535-f81a-4478-a6d3-afaa4d51199e" + ] + }, + "hit", + null + ] + }, + "variants": { + "hit": "hit", + "miss": "miss" + } + }, + "targeting-null-variant-flag": { + "defaultVariant": "two", + "state": "ENABLED", + "targeting": { + "if": [ + true, + null, + "one" + ] + }, + "variants": { + "one": 1, + "two": 2 + } + }, + "timestamp-flag": { + "defaultVariant": "none", + "state": "ENABLED", + "targeting": { + "if": [ + { + "\u003e": [ + { + "var": "$flagd.timestamp" + }, + { + "var": "time" + } + ] + }, + "past", + { + "if": [ + { + "\u003c": [ + { + "var": "$flagd.timestamp" + }, + { + "var": "time" + } + ] + }, + "future", + "none" + ] + } + ] + }, + "variants": { + "future": 1, + "none": 0, + "past": -1 + } + }, + "wrong-flag": { + "defaultVariant": "one", + "state": "ENABLED", + "variants": { + "one": "uno", + "two": "dos" + } + } + } +} \ No newline at end of file diff --git a/launchpad/pkg/flagd.go b/launchpad/pkg/flagd.go index 03d768b..ec84f7c 100644 --- a/launchpad/pkg/flagd.go +++ b/launchpad/pkg/flagd.go @@ -159,7 +159,7 @@ func stopFlagDWithoutLock() error { return nil } -func monitorOutput(pipe io.ReadCloser, ready chan bool, info string) { +func monitorOutput(pipe io.ReadCloser, ready chan bool, stream string) { scanner := bufio.NewScanner(pipe) //adjust the capacity to your need (max characters in line) const maxCapacity = 512 * 1024 @@ -169,7 +169,7 @@ func monitorOutput(pipe io.ReadCloser, ready chan bool, info string) { for scanner.Scan() { line := scanner.Text() - fmt.Println("[flagd ", info, "]:", line) + fmt.Println("[flagd ", stream, "]:", line) if ready != nil && !started && strings.Contains(line, "listening at") { ready <- true close(ready) From 2214ba38bf7255f7cd7352b690da438b5bbebb8a Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 25 Mar 2025 08:46:49 +0100 Subject: [PATCH 3/3] chore: delete accidentally added file Signed-off-by: Simon Schrottner --- flags/allFlags.json | 727 -------------------------------------------- 1 file changed, 727 deletions(-) delete mode 100644 flags/allFlags.json diff --git a/flags/allFlags.json b/flags/allFlags.json deleted file mode 100644 index 0321f6e..0000000 --- a/flags/allFlags.json +++ /dev/null @@ -1,727 +0,0 @@ -{ - "$evaluators": { - "is_ballmer": { - "==": [ - "ballmer@macrosoft.com", - { - "var": [ - "email" - ] - } - ] - } - }, - "flags": { - "boolean-flag": { - "defaultVariant": "on", - "state": "ENABLED", - "variants": { - "off": false, - "on": true - } - }, - "boolean-targeted-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "targeting": { - "if": [ - { - "$ref": "is_ballmer" - }, - "zero" - ] - }, - "variants": { - "non-zero": true, - "zero": false - } - }, - "boolean-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "variants": { - "non-zero": true, - "zero": false - } - }, - "changing-flag": { - "defaultVariant": "foo", - "state": "ENABLED", - "variants": { - "bar": "bar", - "foo": "foo" - } - }, - "context-aware": { - "defaultVariant": "external", - "state": "ENABLED", - "targeting": { - "if": [ - { - "and": [ - { - "==": [ - { - "var": [ - "fn" - ] - }, - "Sulisław" - ] - }, - { - "==": [ - { - "var": [ - "ln" - ] - }, - "Świętopełk" - ] - }, - { - "==": [ - { - "var": [ - "age" - ] - }, - 29 - ] - }, - { - "==": [ - { - "var": [ - "customer" - ] - }, - false - ] - } - ] - }, - "internal", - "external" - ] - }, - "variants": { - "external": "EXTERNAL", - "internal": "INTERNAL" - } - }, - "empty-targeting-flag": { - "defaultVariant": "false", - "state": "ENABLED", - "targeting": {}, - "variants": { - "false": 1, - "true": 2 - } - }, - "equal-greater-lesser-version-flag": { - "defaultVariant": "none", - "state": "ENABLED", - "targeting": { - "if": [ - { - "sem_ver": [ - { - "var": "version" - }, - "=", - "2.0.0" - ] - }, - "equal", - { - "if": [ - { - "sem_ver": [ - { - "var": "version" - }, - "\u003e", - "2.0.0" - ] - }, - "greater", - { - "if": [ - { - "sem_ver": [ - { - "var": "version" - }, - "\u003c", - "2.0.0" - ] - }, - "lesser", - { - "if": [ - { - "sem_ver": [ - { - "var": "version" - }, - "=", - "2.0.0.0" - ] - }, - "fail", - "none" - ] - } - ] - } - ] - } - ] - }, - "variants": { - "equal": "equal", - "greater": "greater", - "lesser": "lesser", - "none": "none" - } - }, - "error-targeting-flag": { - "defaultVariant": "two", - "state": "ENABLED", - "targeting": { - "invalid": [ - "this is not valid targeting" - ] - }, - "variants": { - "one": 1, - "two": 2 - } - }, - "flagd-context-aware": { - "defaultVariant": "external", - "state": "ENABLED", - "targeting": { - "if": [ - { - "==": [ - { - "var": [ - "injectedmetadata" - ] - }, - "set" - ] - }, - "internal", - "external" - ] - }, - "variants": { - "external": "EXTERNAL", - "internal": "INTERNAL" - } - }, - "float-flag": { - "defaultVariant": "half", - "state": "ENABLED", - "variants": { - "half": 0.5, - "tenth": 0.1 - } - }, - "float-targeted-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "targeting": { - "if": [ - { - "$ref": "is_ballmer" - }, - "zero" - ] - }, - "variants": { - "non-zero": 1, - "zero": 0 - } - }, - "float-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "variants": { - "non-zero": 1, - "zero": 0 - } - }, - "fractional-flag": { - "defaultVariant": "wild", - "state": "ENABLED", - "targeting": { - "fractional": [ - { - "cat": [ - { - "var": "$flagd.flagKey" - }, - { - "var": "user.name" - } - ] - }, - [ - "clubs", - 25 - ], - [ - "diamonds", - 25 - ], - [ - "hearts", - 25 - ], - [ - "spades", - 25 - ] - ] - }, - "variants": { - "clubs": "clubs", - "diamonds": "diamonds", - "hearts": "hearts", - "spades": "spades", - "wild": "wild" - } - }, - "fractional-flag-A-shared-seed": { - "defaultVariant": "wild", - "state": "ENABLED", - "targeting": { - "fractional": [ - { - "cat": [ - "shared-seed", - { - "var": "user.name" - } - ] - }, - [ - "clubs", - 25 - ], - [ - "diamonds", - 25 - ], - [ - "hearts", - 25 - ], - [ - "spades", - 25 - ] - ] - }, - "variants": { - "clubs": "clubs", - "diamonds": "diamonds", - "hearts": "hearts", - "spades": "spades", - "wild": "wild" - } - }, - "fractional-flag-B-shared-seed": { - "defaultVariant": "wild", - "state": "ENABLED", - "targeting": { - "fractional": [ - { - "cat": [ - "shared-seed", - { - "var": "user.name" - } - ] - }, - [ - "clubs", - 25 - ], - [ - "diamonds", - 25 - ], - [ - "hearts", - 25 - ], - [ - "spades", - 25 - ] - ] - }, - "variants": { - "clubs": "ace-of-clubs", - "diamonds": "ace-of-diamonds", - "hearts": "ace-of-hearts", - "spades": "ace-of-spades", - "wild": "wild" - } - }, - "fractional-flag-shorthand": { - "defaultVariant": "draw", - "state": "ENABLED", - "targeting": { - "fractional": [ - [ - "heads" - ], - [ - "tails", - 1 - ] - ] - }, - "variants": { - "draw": "draw", - "heads": "heads", - "tails": "tails" - } - }, - "integer-flag": { - "defaultVariant": "ten", - "state": "ENABLED", - "variants": { - "one": 1, - "ten": 10 - } - }, - "integer-targeted-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "targeting": { - "if": [ - { - "$ref": "is_ballmer" - }, - "zero" - ] - }, - "variants": { - "non-zero": 1, - "zero": 0 - } - }, - "integer-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "variants": { - "non-zero": 1, - "zero": 0 - } - }, - "major-minor-version-flag": { - "defaultVariant": "none", - "state": "ENABLED", - "targeting": { - "if": [ - { - "sem_ver": [ - { - "var": "version" - }, - "~", - "3.0.0" - ] - }, - "minor", - { - "if": [ - { - "sem_ver": [ - { - "var": "version" - }, - "^", - "3.0.0" - ] - }, - "major", - "none" - ] - } - ] - }, - "variants": { - "major": "major", - "minor": "minor", - "none": "none" - } - }, - "metadata-flag": { - "defaultVariant": "false", - "metadata": { - "boolean": true, - "float": 1.2, - "integer": 1, - "string": "a" - }, - "state": "ENABLED", - "targeting": {}, - "variants": { - "false": false, - "true": true - } - }, - "missing-variant-targeting-flag": { - "defaultVariant": "two", - "state": "ENABLED", - "targeting": { - "if": [ - true, - "three", - "one" - ] - }, - "variants": { - "one": 1, - "two": 2 - } - }, - "non-string-variant-targeting-flag": { - "defaultVariant": "false", - "state": "ENABLED", - "targeting": { - "if": [ - true, - true, - false - ] - }, - "variants": { - "false": 1, - "true": 2 - } - }, - "object-flag": { - "defaultVariant": "template", - "state": "ENABLED", - "variants": { - "empty": {}, - "template": { - "imagesPerPage": 100, - "showImages": true, - "title": "Check out these pics!" - } - } - }, - "some-email-targeted-flag": { - "defaultVariant": "none", - "state": "ENABLED", - "targeting": { - "if": [ - { - "$ref": "is_ballmer" - }, - "hi", - "bye" - ] - }, - "variants": { - "bye": "bye", - "hi": "hi", - "none": "none" - } - }, - "some-other-email-targeted-flag": { - "defaultVariant": "none", - "state": "ENABLED", - "targeting": { - "if": [ - { - "$ref": "is_ballmer" - }, - "yes", - "no" - ] - }, - "variants": { - "no": "no", - "none": "none", - "yes": "yes" - } - }, - "starts-ends-flag": { - "defaultVariant": "none", - "state": "ENABLED", - "targeting": { - "if": [ - { - "starts_with": [ - { - "var": "id" - }, - "abc" - ] - }, - "prefix", - { - "if": [ - { - "ends_with": [ - { - "var": "id" - }, - "xyz" - ] - }, - "postfix", - { - "if": [ - { - "ends_with": [ - { - "var": "id" - }, - 3 - ] - }, - "fail", - "none" - ] - } - ] - } - ] - }, - "variants": { - "none": "none", - "postfix": "postfix", - "prefix": "prefix" - } - }, - "string-flag": { - "defaultVariant": "greeting", - "state": "ENABLED", - "variants": { - "greeting": "hi", - "parting": "bye" - } - }, - "string-targeted-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "targeting": { - "if": [ - { - "$ref": "is_ballmer" - }, - "zero" - ] - }, - "variants": { - "non-zero": "str", - "zero": "" - } - }, - "string-zero-flag": { - "defaultVariant": "zero", - "state": "ENABLED", - "variants": { - "non-zero": "str", - "zero": "" - } - }, - "targeting-key-flag": { - "defaultVariant": "miss", - "state": "ENABLED", - "targeting": { - "if": [ - { - "==": [ - { - "var": "targetingKey" - }, - "5c3d8535-f81a-4478-a6d3-afaa4d51199e" - ] - }, - "hit", - null - ] - }, - "variants": { - "hit": "hit", - "miss": "miss" - } - }, - "targeting-null-variant-flag": { - "defaultVariant": "two", - "state": "ENABLED", - "targeting": { - "if": [ - true, - null, - "one" - ] - }, - "variants": { - "one": 1, - "two": 2 - } - }, - "timestamp-flag": { - "defaultVariant": "none", - "state": "ENABLED", - "targeting": { - "if": [ - { - "\u003e": [ - { - "var": "$flagd.timestamp" - }, - { - "var": "time" - } - ] - }, - "past", - { - "if": [ - { - "\u003c": [ - { - "var": "$flagd.timestamp" - }, - { - "var": "time" - } - ] - }, - "future", - "none" - ] - } - ] - }, - "variants": { - "future": 1, - "none": 0, - "past": -1 - } - }, - "wrong-flag": { - "defaultVariant": "one", - "state": "ENABLED", - "variants": { - "one": "uno", - "two": "dos" - } - } - } -} \ No newline at end of file