@quonfig/cli 0.0.18 → 0.0.20
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.
- package/README.md +148 -37
- package/dist/codegen/code-generators/node-typescript-generator.js +2 -2
- package/dist/codegen/code-generators/react-typescript-generator.js +2 -2
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +103 -20
- package/dist/commands/log-level.d.ts +27 -0
- package/dist/commands/log-level.js +197 -0
- package/dist/commands/pull.js +5 -15
- package/dist/commands/push.js +5 -15
- package/dist/commands/set-default.js +1 -1
- package/dist/commands/workspace/create.d.ts +20 -0
- package/dist/commands/workspace/create.js +156 -0
- package/dist/util/encryption.d.ts +5 -2
- package/dist/util/encryption.js +11 -6
- package/dist/util/log-levels.d.ts +4 -0
- package/dist/util/log-levels.js +5 -0
- package/dist/util/resolve-workspace.d.ts +14 -0
- package/dist/util/resolve-workspace.js +75 -0
- package/dist/verify/validate.js +2 -1
- package/oclif.manifest.json +196 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @quonfig/cli
|
|
|
14
14
|
$ qfg COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ qfg (--version)
|
|
17
|
-
@quonfig/cli/0.0.
|
|
17
|
+
@quonfig/cli/0.0.20 linux-x64 node-v24.4.1
|
|
18
18
|
$ qfg --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ qfg COMMAND
|
|
@@ -37,6 +37,7 @@ USAGE
|
|
|
37
37
|
* [`qfg init [DIRECTORY]`](#qfg-init-directory)
|
|
38
38
|
* [`qfg interactive`](#qfg-interactive)
|
|
39
39
|
* [`qfg list`](#qfg-list)
|
|
40
|
+
* [`qfg log-level NAME`](#qfg-log-level-name)
|
|
40
41
|
* [`qfg login`](#qfg-login)
|
|
41
42
|
* [`qfg logout`](#qfg-logout)
|
|
42
43
|
* [`qfg mcp`](#qfg-mcp)
|
|
@@ -60,6 +61,7 @@ USAGE
|
|
|
60
61
|
* [`qfg whoami`](#qfg-whoami)
|
|
61
62
|
* [`qfg workspace`](#qfg-workspace)
|
|
62
63
|
* [`qfg workspace bootstrap`](#qfg-workspace-bootstrap)
|
|
64
|
+
* [`qfg workspace create SLUG`](#qfg-workspace-create-slug)
|
|
63
65
|
* [`qfg workspace switch [SLUG]`](#qfg-workspace-switch-slug)
|
|
64
66
|
|
|
65
67
|
## `qfg config-schema`
|
|
@@ -89,7 +91,7 @@ EXAMPLES
|
|
|
89
91
|
$ qfg config-schema --json-schema # full JSON Schema document (copy into your editor)
|
|
90
92
|
```
|
|
91
93
|
|
|
92
|
-
_See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
94
|
+
_See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/config-schema.ts)_
|
|
93
95
|
|
|
94
96
|
## `qfg create NAME`
|
|
95
97
|
|
|
@@ -97,9 +99,9 @@ Create a new feature flag, config value, or other item.
|
|
|
97
99
|
|
|
98
100
|
```
|
|
99
101
|
USAGE
|
|
100
|
-
$ qfg create NAME --type boolean-flag|boolean|string|double|int|string-list|json [--json]
|
|
101
|
-
[--no-color] [--verbose] [-w <value>] [--confidential] [--env-var <value>] [--value <value>]
|
|
102
|
-
[--secret-key-name <value>]
|
|
102
|
+
$ qfg create NAME --type boolean-flag|boolean|string|double|int|string-list|json|log_level [--json]
|
|
103
|
+
[--interactive] [--no-color] [--verbose] [-w <value>] [--confidential] [--env-var <value>] [--value <value>]
|
|
104
|
+
[--secret] [--secret-key-name <value>]
|
|
103
105
|
|
|
104
106
|
ARGUMENTS
|
|
105
107
|
NAME name for your new item (e.g. my.new.flag)
|
|
@@ -111,7 +113,7 @@ FLAGS
|
|
|
111
113
|
--secret-key-name=<value> [default: quonfig.secrets.encryption.key] name of the secret key to use for
|
|
112
114
|
encryption/decryption
|
|
113
115
|
--type=<option> (required)
|
|
114
|
-
<options: boolean-flag|boolean|string|double|int|string-list|json>
|
|
116
|
+
<options: boolean-flag|boolean|string|double|int|string-list|json|log_level>
|
|
115
117
|
--value=<value> default value for your new item
|
|
116
118
|
|
|
117
119
|
GLOBAL FLAGS
|
|
@@ -132,6 +134,7 @@ DESCRIPTION
|
|
|
132
134
|
string-list A comma-separated list of strings
|
|
133
135
|
json An arbitrary JSON blob
|
|
134
136
|
boolean A plain boolean (not a feature flag)
|
|
137
|
+
log_level A dynamic log level (value must be one of TRACE/DEBUG/INFO/WARN/ERROR/FATAL)
|
|
135
138
|
|
|
136
139
|
This sets the global default value. Override per-environment with:
|
|
137
140
|
qfg set-default my.flag --environment production --value true
|
|
@@ -143,6 +146,13 @@ DESCRIPTION
|
|
|
143
146
|
qfg config-schema # full operator reference + examples
|
|
144
147
|
qfg pull --dir ./config # clone workspace, then edit JSON and git push
|
|
145
148
|
|
|
149
|
+
Log levels:
|
|
150
|
+
qfg create log-level.my-app --type log_level --value WARN
|
|
151
|
+
# Log-level keys must start with "log-level.".
|
|
152
|
+
# For per-logger targeting, create ONE log-level config per service and add
|
|
153
|
+
# rules on the "quonfig-sdk-logging.key" context property (e.g.
|
|
154
|
+
# PROP_STARTS_WITH_ONE_OF MyPackage.) rather than one config per logger.
|
|
155
|
+
|
|
146
156
|
EXAMPLES
|
|
147
157
|
$ qfg create my.new.flag --type boolean-flag
|
|
148
158
|
|
|
@@ -156,12 +166,14 @@ EXAMPLES
|
|
|
156
166
|
|
|
157
167
|
$ qfg create my.new.string --type json --value="{\"key\": \"value\"}"
|
|
158
168
|
|
|
169
|
+
$ qfg create log-level.my-app --type log_level --value WARN
|
|
170
|
+
|
|
159
171
|
# After creating a flag, set a 20% rollout in production:
|
|
160
172
|
|
|
161
173
|
$ qfg set-rollout my.new.flag --environment production --true-percent 20
|
|
162
174
|
```
|
|
163
175
|
|
|
164
|
-
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
176
|
+
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/create.ts)_
|
|
165
177
|
|
|
166
178
|
## `qfg flag info [NAME]`
|
|
167
179
|
|
|
@@ -361,7 +373,7 @@ EXAMPLES
|
|
|
361
373
|
$ qfg generate --targets node-ts -o ./dist # combine with targets
|
|
362
374
|
```
|
|
363
375
|
|
|
364
|
-
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
376
|
+
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/generate.ts)_
|
|
365
377
|
|
|
366
378
|
## `qfg generate-new-hex-key`
|
|
367
379
|
|
|
@@ -384,7 +396,7 @@ EXAMPLES
|
|
|
384
396
|
$ qfg generate-new-hex-key
|
|
385
397
|
```
|
|
386
398
|
|
|
387
|
-
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
399
|
+
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/generate-new-hex-key.ts)_
|
|
388
400
|
|
|
389
401
|
## `qfg get [NAME]`
|
|
390
402
|
|
|
@@ -416,7 +428,7 @@ EXAMPLES
|
|
|
416
428
|
$ qfg get my.config.name --environment=production
|
|
417
429
|
```
|
|
418
430
|
|
|
419
|
-
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
431
|
+
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/get.ts)_
|
|
420
432
|
|
|
421
433
|
## `qfg info [NAME]`
|
|
422
434
|
|
|
@@ -464,7 +476,7 @@ EXAMPLES
|
|
|
464
476
|
$ qfg info my.config.name --exclude-evaluations # skip 24h stats
|
|
465
477
|
```
|
|
466
478
|
|
|
467
|
-
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
479
|
+
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/info.ts)_
|
|
468
480
|
|
|
469
481
|
## `qfg init [DIRECTORY]`
|
|
470
482
|
|
|
@@ -504,7 +516,7 @@ EXAMPLES
|
|
|
504
516
|
$ qfg init --dry-run
|
|
505
517
|
```
|
|
506
518
|
|
|
507
|
-
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
519
|
+
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/init.ts)_
|
|
508
520
|
|
|
509
521
|
## `qfg interactive`
|
|
510
522
|
|
|
@@ -534,7 +546,7 @@ EXAMPLES
|
|
|
534
546
|
$ qfg
|
|
535
547
|
```
|
|
536
548
|
|
|
537
|
-
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
549
|
+
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/interactive.ts)_
|
|
538
550
|
|
|
539
551
|
## `qfg list`
|
|
540
552
|
|
|
@@ -574,7 +586,72 @@ EXAMPLES
|
|
|
574
586
|
$ qfg list --feature-flags
|
|
575
587
|
```
|
|
576
588
|
|
|
577
|
-
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
589
|
+
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/list.ts)_
|
|
590
|
+
|
|
591
|
+
## `qfg log-level NAME`
|
|
592
|
+
|
|
593
|
+
Create or add targeting rules to a log-level config.
|
|
594
|
+
|
|
595
|
+
```
|
|
596
|
+
USAGE
|
|
597
|
+
$ qfg log-level NAME [--json] [--interactive] [--no-color] [--verbose] [-w <value>] [--environment <value>]
|
|
598
|
+
[--target <value>...] [--value TRACE|DEBUG|INFO|WARN|ERROR|FATAL]
|
|
599
|
+
|
|
600
|
+
ARGUMENTS
|
|
601
|
+
NAME log-level key (must start with "log-level.", e.g. log-level.my-app)
|
|
602
|
+
|
|
603
|
+
FLAGS
|
|
604
|
+
--environment=<value> when used with --target, scope the rule to this environment instead of the default
|
|
605
|
+
--target=<value>... logger path prefix (matched via PROP_STARTS_WITH_ONE_OF on "quonfig-sdk-logging.key");
|
|
606
|
+
repeatable
|
|
607
|
+
--value=<option> log level — either the new default (create mode) or the level for the targeted loggers
|
|
608
|
+
<options: TRACE|DEBUG|INFO|WARN|ERROR|FATAL>
|
|
609
|
+
|
|
610
|
+
GLOBAL FLAGS
|
|
611
|
+
-w, --workspace=<value> Workspace slug to use (overrides QUONFIG_WORKSPACE env var and saved default)
|
|
612
|
+
--[no-]interactive Force interactive mode
|
|
613
|
+
--json Format output as json.
|
|
614
|
+
--no-color Do not colorize output
|
|
615
|
+
--verbose Verbose output
|
|
616
|
+
|
|
617
|
+
DESCRIPTION
|
|
618
|
+
Create or add targeting rules to a log-level config.
|
|
619
|
+
|
|
620
|
+
Log-level keys must start with "log-level." (e.g. log-level.my-app). The
|
|
621
|
+
default value applies to every logger in that service unless a targeting
|
|
622
|
+
rule matches first.
|
|
623
|
+
|
|
624
|
+
Two modes:
|
|
625
|
+
|
|
626
|
+
1. Create a new log-level config with a default value:
|
|
627
|
+
qfg log-level log-level.my-app --value=WARN
|
|
628
|
+
|
|
629
|
+
2. Add a per-logger targeting rule to an existing config. SDKs populate
|
|
630
|
+
the "quonfig-sdk-logging.key" context automatically from the logger path,
|
|
631
|
+
so this rule fires for any logger whose name starts with --target:
|
|
632
|
+
qfg log-level log-level.my-app --target=MyPackage.Noisy --value=ERROR
|
|
633
|
+
|
|
634
|
+
Pass --target multiple times to match any of several prefixes (OR).
|
|
635
|
+
Pass --environment=<env> to scope the rule to a single environment.
|
|
636
|
+
|
|
637
|
+
To update the catch-all default for an existing log level, use set-default:
|
|
638
|
+
qfg set-default log-level.my-app --value=DEBUG --environment=production
|
|
639
|
+
|
|
640
|
+
For more complex rules (regex, multi-criterion, exact match) edit the JSON:
|
|
641
|
+
qfg pull && $EDITOR log-levels/log-level.my-app.json
|
|
642
|
+
qfg config-schema # full operator reference
|
|
643
|
+
|
|
644
|
+
EXAMPLES
|
|
645
|
+
$ qfg log-level log-level.my-app --value=WARN
|
|
646
|
+
|
|
647
|
+
$ qfg log-level log-level.my-app --target=MyPackage.Noisy --value=ERROR
|
|
648
|
+
|
|
649
|
+
$ qfg log-level log-level.my-app --target=A --target=B --value=DEBUG
|
|
650
|
+
|
|
651
|
+
$ qfg log-level log-level.my-app --target=Chatty --value=INFO --environment=production
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
_See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/log-level.ts)_
|
|
578
655
|
|
|
579
656
|
## `qfg login`
|
|
580
657
|
|
|
@@ -599,7 +676,7 @@ EXAMPLES
|
|
|
599
676
|
$ qfg login --profile myprofile
|
|
600
677
|
```
|
|
601
678
|
|
|
602
|
-
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
679
|
+
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/login.ts)_
|
|
603
680
|
|
|
604
681
|
## `qfg logout`
|
|
605
682
|
|
|
@@ -622,7 +699,7 @@ EXAMPLES
|
|
|
622
699
|
$ qfg logout
|
|
623
700
|
```
|
|
624
701
|
|
|
625
|
-
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
702
|
+
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/logout.ts)_
|
|
626
703
|
|
|
627
704
|
## `qfg mcp`
|
|
628
705
|
|
|
@@ -655,7 +732,7 @@ EXAMPLES
|
|
|
655
732
|
$ qfg mcp --url http://local-app.quonfig-staging.com:3003/api/v1/mcp
|
|
656
733
|
```
|
|
657
734
|
|
|
658
|
-
_See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
735
|
+
_See code: [src/commands/mcp.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/mcp.ts)_
|
|
659
736
|
|
|
660
737
|
## `qfg migrate`
|
|
661
738
|
|
|
@@ -709,7 +786,7 @@ EXAMPLES
|
|
|
709
786
|
$ qfg migrate --from launch --api-key $LAUNCH_API_KEY --dir ./quonfig-config --staging
|
|
710
787
|
```
|
|
711
788
|
|
|
712
|
-
_See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
789
|
+
_See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/migrate.ts)_
|
|
713
790
|
|
|
714
791
|
## `qfg migrate doctor`
|
|
715
792
|
|
|
@@ -747,7 +824,7 @@ EXAMPLES
|
|
|
747
824
|
$ qfg migrate doctor --json
|
|
748
825
|
```
|
|
749
826
|
|
|
750
|
-
_See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
827
|
+
_See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/migrate/doctor.ts)_
|
|
751
828
|
|
|
752
829
|
## `qfg migrate my-code`
|
|
753
830
|
|
|
@@ -779,7 +856,7 @@ EXAMPLES
|
|
|
779
856
|
$ qfg migrate my-code --dry-run
|
|
780
857
|
```
|
|
781
858
|
|
|
782
|
-
_See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
859
|
+
_See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/migrate/my-code.ts)_
|
|
783
860
|
|
|
784
861
|
## `qfg migrate status`
|
|
785
862
|
|
|
@@ -810,7 +887,7 @@ EXAMPLES
|
|
|
810
887
|
$ qfg migrate status --json
|
|
811
888
|
```
|
|
812
889
|
|
|
813
|
-
_See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
890
|
+
_See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/migrate/status.ts)_
|
|
814
891
|
|
|
815
892
|
## `qfg override [NAME]`
|
|
816
893
|
|
|
@@ -854,7 +931,7 @@ EXAMPLES
|
|
|
854
931
|
$ qfg override my.double.config --value=3.14159
|
|
855
932
|
```
|
|
856
933
|
|
|
857
|
-
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
934
|
+
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/override.ts)_
|
|
858
935
|
|
|
859
936
|
## `qfg pull`
|
|
860
937
|
|
|
@@ -898,7 +975,7 @@ EXAMPLES
|
|
|
898
975
|
$ qfg pull # uses QUONFIG_DIR env var
|
|
899
976
|
```
|
|
900
977
|
|
|
901
|
-
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
978
|
+
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/pull.ts)_
|
|
902
979
|
|
|
903
980
|
## `qfg push`
|
|
904
981
|
|
|
@@ -946,7 +1023,7 @@ EXAMPLES
|
|
|
946
1023
|
$ qfg push --dir ./our-config --yes
|
|
947
1024
|
```
|
|
948
1025
|
|
|
949
|
-
_See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1026
|
+
_See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/push.ts)_
|
|
950
1027
|
|
|
951
1028
|
## `qfg schema NAME`
|
|
952
1029
|
|
|
@@ -984,7 +1061,7 @@ EXAMPLES
|
|
|
984
1061
|
$ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
|
|
985
1062
|
```
|
|
986
1063
|
|
|
987
|
-
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1064
|
+
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/schema.ts)_
|
|
988
1065
|
|
|
989
1066
|
## `qfg sdk-key`
|
|
990
1067
|
|
|
@@ -1011,7 +1088,7 @@ EXAMPLES
|
|
|
1011
1088
|
$ qfg sdk-key revoke <key-id>
|
|
1012
1089
|
```
|
|
1013
1090
|
|
|
1014
|
-
_See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1091
|
+
_See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/sdk-key.ts)_
|
|
1015
1092
|
|
|
1016
1093
|
## `qfg sdk-key create`
|
|
1017
1094
|
|
|
@@ -1043,7 +1120,7 @@ EXAMPLES
|
|
|
1043
1120
|
$ qfg sdk-key create --environment staging --type browser
|
|
1044
1121
|
```
|
|
1045
1122
|
|
|
1046
|
-
_See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1123
|
+
_See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/sdk-key/create.ts)_
|
|
1047
1124
|
|
|
1048
1125
|
## `qfg sdk-key list`
|
|
1049
1126
|
|
|
@@ -1072,7 +1149,7 @@ EXAMPLES
|
|
|
1072
1149
|
$ qfg sdk-key list --environment production
|
|
1073
1150
|
```
|
|
1074
1151
|
|
|
1075
|
-
_See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1152
|
+
_See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/sdk-key/list.ts)_
|
|
1076
1153
|
|
|
1077
1154
|
## `qfg sdk-key revoke KEYID`
|
|
1078
1155
|
|
|
@@ -1099,7 +1176,7 @@ EXAMPLES
|
|
|
1099
1176
|
$ qfg sdk-key revoke a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
1100
1177
|
```
|
|
1101
1178
|
|
|
1102
|
-
_See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1179
|
+
_See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/sdk-key/revoke.ts)_
|
|
1103
1180
|
|
|
1104
1181
|
## `qfg set-default [NAME]`
|
|
1105
1182
|
|
|
@@ -1170,7 +1247,7 @@ EXAMPLES
|
|
|
1170
1247
|
$ qfg pull && qfg config-schema
|
|
1171
1248
|
```
|
|
1172
1249
|
|
|
1173
|
-
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1250
|
+
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/set-default.ts)_
|
|
1174
1251
|
|
|
1175
1252
|
## `qfg set-rollout [NAME]`
|
|
1176
1253
|
|
|
@@ -1247,7 +1324,7 @@ EXAMPLES
|
|
|
1247
1324
|
$ qfg set-rollout my.variant.flag --environment production --weights "a:33,b:33,c:34" --hash-by user.id
|
|
1248
1325
|
```
|
|
1249
1326
|
|
|
1250
|
-
_See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1327
|
+
_See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/set-rollout.ts)_
|
|
1251
1328
|
|
|
1252
1329
|
## `qfg sync`
|
|
1253
1330
|
|
|
@@ -1279,7 +1356,7 @@ EXAMPLES
|
|
|
1279
1356
|
$ qfg sync --watch --dir ./our-config --interval 30
|
|
1280
1357
|
```
|
|
1281
1358
|
|
|
1282
|
-
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1359
|
+
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/sync.ts)_
|
|
1283
1360
|
|
|
1284
1361
|
## `qfg toggle [NAME]`
|
|
1285
1362
|
|
|
@@ -1381,7 +1458,7 @@ EXAMPLES
|
|
|
1381
1458
|
$ qfg verify --json
|
|
1382
1459
|
```
|
|
1383
1460
|
|
|
1384
|
-
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1461
|
+
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/verify.ts)_
|
|
1385
1462
|
|
|
1386
1463
|
## `qfg whoami`
|
|
1387
1464
|
|
|
@@ -1404,7 +1481,7 @@ EXAMPLES
|
|
|
1404
1481
|
$ qfg whoami
|
|
1405
1482
|
```
|
|
1406
1483
|
|
|
1407
|
-
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1484
|
+
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/whoami.ts)_
|
|
1408
1485
|
|
|
1409
1486
|
## `qfg workspace`
|
|
1410
1487
|
|
|
@@ -1427,7 +1504,7 @@ EXAMPLES
|
|
|
1427
1504
|
$ qfg workspace
|
|
1428
1505
|
```
|
|
1429
1506
|
|
|
1430
|
-
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1507
|
+
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/workspace.ts)_
|
|
1431
1508
|
|
|
1432
1509
|
## `qfg workspace bootstrap`
|
|
1433
1510
|
|
|
@@ -1460,7 +1537,41 @@ EXAMPLES
|
|
|
1460
1537
|
$ qfg workspace bootstrap --dir ./our-config --skip-validate
|
|
1461
1538
|
```
|
|
1462
1539
|
|
|
1463
|
-
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1540
|
+
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/workspace/bootstrap.ts)_
|
|
1541
|
+
|
|
1542
|
+
## `qfg workspace create SLUG`
|
|
1543
|
+
|
|
1544
|
+
Create a new workspace. Provisions the Gitea repo and default environments, identical to the app's New Workspace UI.
|
|
1545
|
+
|
|
1546
|
+
```
|
|
1547
|
+
USAGE
|
|
1548
|
+
$ qfg workspace create SLUG [--json] [--interactive] [--no-color] [--verbose] [--name <value>] [--org <value>]
|
|
1549
|
+
|
|
1550
|
+
ARGUMENTS
|
|
1551
|
+
SLUG Workspace slug (lowercase letters, numbers, hyphens)
|
|
1552
|
+
|
|
1553
|
+
FLAGS
|
|
1554
|
+
--name=<value> Human-readable display name (defaults to the slug)
|
|
1555
|
+
--org=<value> Organization UUID or slug. Required when you belong to more than one organization; inferred otherwise.
|
|
1556
|
+
|
|
1557
|
+
GLOBAL FLAGS
|
|
1558
|
+
--[no-]interactive Force interactive mode
|
|
1559
|
+
--json Format output as json.
|
|
1560
|
+
--no-color Do not colorize output
|
|
1561
|
+
--verbose Verbose output
|
|
1562
|
+
|
|
1563
|
+
DESCRIPTION
|
|
1564
|
+
Create a new workspace. Provisions the Gitea repo and default environments, identical to the app's New Workspace UI.
|
|
1565
|
+
|
|
1566
|
+
EXAMPLES
|
|
1567
|
+
$ qfg workspace create my-team
|
|
1568
|
+
|
|
1569
|
+
$ qfg workspace create lt-21-smoke --name "Load Test 21"
|
|
1570
|
+
|
|
1571
|
+
$ qfg workspace create my-team --org 11111111-1111-1111-1111-111111111111
|
|
1572
|
+
```
|
|
1573
|
+
|
|
1574
|
+
_See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/workspace/create.ts)_
|
|
1464
1575
|
|
|
1465
1576
|
## `qfg workspace switch [SLUG]`
|
|
1466
1577
|
|
|
@@ -1488,7 +1599,7 @@ EXAMPLES
|
|
|
1488
1599
|
$ qfg workspace switch my-workspace-slug
|
|
1489
1600
|
```
|
|
1490
1601
|
|
|
1491
|
-
_See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1602
|
+
_See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.20/src/commands/workspace/switch.ts)_
|
|
1492
1603
|
<!-- commandsstop -->
|
|
1493
1604
|
|
|
1494
1605
|
## Local Development
|
|
@@ -7,7 +7,7 @@ export class NodeTypeScriptGenerator extends BaseTypescriptGenerator {
|
|
|
7
7
|
declarationGenerate() {
|
|
8
8
|
return (stripIndent `
|
|
9
9
|
/* eslint-disable */
|
|
10
|
-
// AUTOGENERATED by quonfig-cli's '
|
|
10
|
+
// AUTOGENERATED by quonfig-cli's 'generate' command
|
|
11
11
|
// prettier-ignore
|
|
12
12
|
import "@quonfig/node";
|
|
13
13
|
|
|
@@ -27,7 +27,7 @@ export class NodeTypeScriptGenerator extends BaseTypescriptGenerator {
|
|
|
27
27
|
generate() {
|
|
28
28
|
return (stripIndent `
|
|
29
29
|
/* eslint-disable */
|
|
30
|
-
// AUTOGENERATED by quonfig-cli's '
|
|
30
|
+
// AUTOGENERATED by quonfig-cli's 'generate' command
|
|
31
31
|
// prettier-ignore
|
|
32
32
|
import { Quonfig, Contexts, TypedNodeServerConfigurationRaw, TypedNodeServerConfigurationAccessor } from '@quonfig/node'
|
|
33
33
|
// prettier-ignore
|
|
@@ -8,7 +8,7 @@ export class ReactTypeScriptGenerator extends BaseTypescriptGenerator {
|
|
|
8
8
|
declarationGenerate() {
|
|
9
9
|
return (stripIndent `
|
|
10
10
|
/* eslint-disable */
|
|
11
|
-
// AUTOGENERATED by quonfig-cli's '
|
|
11
|
+
// AUTOGENERATED by quonfig-cli's 'generate' command
|
|
12
12
|
// prettier-ignore
|
|
13
13
|
import "@quonfig/javascript";
|
|
14
14
|
// prettier-ignore
|
|
@@ -42,7 +42,7 @@ export class ReactTypeScriptGenerator extends BaseTypescriptGenerator {
|
|
|
42
42
|
generate() {
|
|
43
43
|
return (stripIndent `
|
|
44
44
|
/* eslint-disable */
|
|
45
|
-
// AUTOGENERATED by quonfig-cli's '
|
|
45
|
+
// AUTOGENERATED by quonfig-cli's 'generate' command
|
|
46
46
|
// prettier-ignore
|
|
47
47
|
import { Quonfig, TypedFrontEndConfigurationRaw } from "@quonfig/javascript"
|
|
48
48
|
// prettier-ignore
|
package/dist/commands/create.js
CHANGED
|
@@ -6,6 +6,7 @@ import { TYPE_MAPPING, coerceBool, coerceIntoType } from '../util/coerce.js';
|
|
|
6
6
|
import { checkmark } from '../util/color.js';
|
|
7
7
|
import { mapConfigValueToDto, mapValueTypeToString } from '../util/config-value-dto.js';
|
|
8
8
|
import { makeConfidentialValue } from '../util/encryption.js';
|
|
9
|
+
import { LOG_LEVELS, LOG_LEVEL_KEY_PREFIX, isLogLevel } from '../util/log-levels.js';
|
|
9
10
|
import secretFlags, { parsedSecretFlags } from '../util/secret-flags.js';
|
|
10
11
|
export default class Create extends APICommand {
|
|
11
12
|
static args = {
|
|
@@ -21,6 +22,7 @@ Use --type to specify the kind of item:
|
|
|
21
22
|
string-list A comma-separated list of strings
|
|
22
23
|
json An arbitrary JSON blob
|
|
23
24
|
boolean A plain boolean (not a feature flag)
|
|
25
|
+
log_level A dynamic log level (value must be one of ${LOG_LEVELS.join('/')})
|
|
24
26
|
|
|
25
27
|
This sets the global default value. Override per-environment with:
|
|
26
28
|
qfg set-default my.flag --environment production --value true
|
|
@@ -30,7 +32,14 @@ For a percentage rollout (gradual rollout / A/B test / canary deploy), use:
|
|
|
30
32
|
|
|
31
33
|
Or edit the JSON config file directly for complex targeting rules:
|
|
32
34
|
qfg config-schema # full operator reference + examples
|
|
33
|
-
qfg pull --dir ./config # clone workspace, then edit JSON and git push
|
|
35
|
+
qfg pull --dir ./config # clone workspace, then edit JSON and git push
|
|
36
|
+
|
|
37
|
+
Log levels:
|
|
38
|
+
qfg create log-level.my-app --type log_level --value WARN
|
|
39
|
+
# Log-level keys must start with "${LOG_LEVEL_KEY_PREFIX}".
|
|
40
|
+
# For per-logger targeting, create ONE log-level config per service and add
|
|
41
|
+
# rules on the "quonfig-sdk-logging.key" context property (e.g.
|
|
42
|
+
# PROP_STARTS_WITH_ONE_OF MyPackage.) rather than one config per logger.`;
|
|
34
43
|
static examples = [
|
|
35
44
|
'<%= config.bin %> <%= command.id %> my.new.flag --type boolean-flag',
|
|
36
45
|
'<%= config.bin %> <%= command.id %> my.new.flag --type boolean-flag --value=true',
|
|
@@ -38,6 +47,7 @@ Or edit the JSON config file directly for complex targeting rules:
|
|
|
38
47
|
'<%= config.bin %> <%= command.id %> my.new.string --type string --value="hello world" --secret',
|
|
39
48
|
'<%= config.bin %> <%= command.id %> my.new.string --type string --env-var=MY_ENV_VAR_NAME',
|
|
40
49
|
'<%= config.bin %> <%= command.id %> my.new.string --type json --value="{\\"key\\": \\"value\\"}"',
|
|
50
|
+
'<%= config.bin %> <%= command.id %> log-level.my-app --type log_level --value WARN',
|
|
41
51
|
'# After creating a flag, set a 20% rollout in production:',
|
|
42
52
|
'<%= config.bin %> set-rollout my.new.flag --environment production --true-percent 20',
|
|
43
53
|
];
|
|
@@ -45,7 +55,7 @@ Or edit the JSON config file directly for complex targeting rules:
|
|
|
45
55
|
confidential: Flags.boolean({ default: false, description: 'mark the value as confidential' }),
|
|
46
56
|
'env-var': Flags.string({ description: 'environment variable to get value from' }),
|
|
47
57
|
type: Flags.string({
|
|
48
|
-
options: ['boolean-flag', 'boolean', 'string', 'double', 'int', 'string-list', 'json'],
|
|
58
|
+
options: ['boolean-flag', 'boolean', 'string', 'double', 'int', 'string-list', 'json', 'log_level'],
|
|
49
59
|
required: true,
|
|
50
60
|
}),
|
|
51
61
|
value: Flags.string({ description: 'default value for your new item', required: false }),
|
|
@@ -56,6 +66,9 @@ Or edit the JSON config file directly for complex targeting rules:
|
|
|
56
66
|
if (flags.type === 'boolean-flag') {
|
|
57
67
|
return this.createBooleanFlag(args, flags.value);
|
|
58
68
|
}
|
|
69
|
+
if (flags.type === 'log_level') {
|
|
70
|
+
return this.createLogLevel(args, flags);
|
|
71
|
+
}
|
|
59
72
|
const key = args.name;
|
|
60
73
|
const secret = parsedSecretFlags(flags);
|
|
61
74
|
if (flags['env-var'] && flags.value) {
|
|
@@ -122,14 +135,7 @@ Or edit the JSON config file directly for complex targeting rules:
|
|
|
122
135
|
key: args.name,
|
|
123
136
|
valueType: mapValueTypeToString(valueType),
|
|
124
137
|
sendToClientSdk: false,
|
|
125
|
-
|
|
126
|
-
rules: [
|
|
127
|
-
{
|
|
128
|
-
criteria: [],
|
|
129
|
-
value: mapConfigValueToDto(configValue, valueType),
|
|
130
|
-
},
|
|
131
|
-
],
|
|
132
|
-
},
|
|
138
|
+
defaultValue: mapConfigValueToDto(configValue, valueType),
|
|
133
139
|
},
|
|
134
140
|
};
|
|
135
141
|
this.verboseLog('RPC configs/create', createInput);
|
|
@@ -172,16 +178,9 @@ Or edit the JSON config file directly for complex targeting rules:
|
|
|
172
178
|
description: 'Disabled',
|
|
173
179
|
},
|
|
174
180
|
],
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
criteria: [],
|
|
179
|
-
value: {
|
|
180
|
-
type: 'bool',
|
|
181
|
-
value: defaultValue,
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
],
|
|
181
|
+
defaultValue: {
|
|
182
|
+
type: 'bool',
|
|
183
|
+
value: defaultValue,
|
|
185
184
|
},
|
|
186
185
|
},
|
|
187
186
|
};
|
|
@@ -196,4 +195,88 @@ Or edit the JSON config file directly for complex targeting rules:
|
|
|
196
195
|
const response = request.json;
|
|
197
196
|
return this.ok(`${checkmark} Created boolean flag: ${key}`, { key, ...response });
|
|
198
197
|
}
|
|
198
|
+
async createLogLevel(args, flags) {
|
|
199
|
+
const key = args.name;
|
|
200
|
+
if (!key.startsWith(LOG_LEVEL_KEY_PREFIX)) {
|
|
201
|
+
return this.err(`Log level key "${key}" must start with "${LOG_LEVEL_KEY_PREFIX}". Try: ${LOG_LEVEL_KEY_PREFIX}${key}`, { key, phase: 'validation' });
|
|
202
|
+
}
|
|
203
|
+
const secret = parsedSecretFlags(flags);
|
|
204
|
+
if (secret.selected) {
|
|
205
|
+
return this.err('--secret is not supported for log_level (values are enum, not free-form strings)');
|
|
206
|
+
}
|
|
207
|
+
if (flags['env-var']) {
|
|
208
|
+
return this.err('--env-var is not supported for log_level (values must be one of the enum constants)');
|
|
209
|
+
}
|
|
210
|
+
if (flags.confidential) {
|
|
211
|
+
return this.err('--confidential is not supported for log_level');
|
|
212
|
+
}
|
|
213
|
+
const valueInput = await getValue({
|
|
214
|
+
desiredValue: flags.value,
|
|
215
|
+
flags,
|
|
216
|
+
message: `Default log level (${LOG_LEVELS.join('/')})`,
|
|
217
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
218
|
+
quonfig: undefined,
|
|
219
|
+
});
|
|
220
|
+
if (!valueInput.ok) {
|
|
221
|
+
if (valueInput.error) {
|
|
222
|
+
return this.err(valueInput.message, valueInput.json);
|
|
223
|
+
}
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const rawValue = valueInput.value.toUpperCase();
|
|
227
|
+
if (!isLogLevel(rawValue)) {
|
|
228
|
+
return this.err(`Invalid log level "${valueInput.value}". Must be one of: ${LOG_LEVELS.join(', ')}`, {
|
|
229
|
+
key,
|
|
230
|
+
phase: 'validation',
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// Step 1: create the log-level config. The server always writes INFO as the
|
|
234
|
+
// initial default, so we patch it to the requested value below if needed.
|
|
235
|
+
const createInput = {
|
|
236
|
+
workspaceId: this.workspaceId,
|
|
237
|
+
logLevel: { key },
|
|
238
|
+
};
|
|
239
|
+
this.verboseLog('RPC logLevels/create', createInput);
|
|
240
|
+
const createRequest = await this.apiClient.post('/api/v1/logLevels/create', createInput);
|
|
241
|
+
if (!createRequest.ok) {
|
|
242
|
+
const errMsg = createRequest.status === 409
|
|
243
|
+
? `Failed to create log level: ${key} already exists`
|
|
244
|
+
: `Failed to create log level: ${createRequest.status} | ${JSON.stringify(createRequest.error)}`;
|
|
245
|
+
return this.err(errMsg, { key, phase: 'creation', serverError: createRequest.error });
|
|
246
|
+
}
|
|
247
|
+
const createResponse = createRequest.json;
|
|
248
|
+
// Step 2: if the requested value isn't the server's default (INFO), update.
|
|
249
|
+
if (rawValue !== 'INFO') {
|
|
250
|
+
if (!createResponse.commitSha) {
|
|
251
|
+
return this.err('Server did not return commitSha after create; cannot patch default value', {
|
|
252
|
+
key,
|
|
253
|
+
phase: 'update',
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
const updateInput = {
|
|
257
|
+
workspaceId: this.workspaceId,
|
|
258
|
+
logLevelKey: key,
|
|
259
|
+
logLevel: {
|
|
260
|
+
default: {
|
|
261
|
+
rules: [
|
|
262
|
+
{
|
|
263
|
+
criteria: [{ operator: 'ALWAYS_TRUE' }],
|
|
264
|
+
value: { type: 'log_level', value: rawValue },
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
expectedCommitSha: createResponse.commitSha,
|
|
270
|
+
};
|
|
271
|
+
this.verboseLog('RPC logLevels/update', updateInput);
|
|
272
|
+
const updateRequest = await this.apiClient.post('/api/v1/logLevels/update', updateInput);
|
|
273
|
+
if (!updateRequest.ok) {
|
|
274
|
+
return this.err(`Log level created with default INFO, but failed to set value to ${rawValue}: ${updateRequest.status}. Run \`qfg set-default ${key} --value=${rawValue}\` to retry.`, { key, phase: 'update', serverError: updateRequest.error });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return this.ok(`${checkmark} Created log level: ${key} (default: ${rawValue})`, {
|
|
278
|
+
key,
|
|
279
|
+
value: rawValue,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
199
282
|
}
|