@quonfig/cli 0.0.52 → 0.0.53
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 +102 -44
- package/dist/commands/run.js +0 -1
- package/dist/commands/serve.d.ts +23 -0
- package/dist/commands/serve.js +136 -0
- package/dist/quonfig.js +0 -1
- package/dist/serve/datadir-discovery.d.ts +33 -0
- package/dist/serve/datadir-discovery.js +38 -0
- package/dist/serve/handlers/evalContext.d.ts +66 -0
- package/dist/serve/handlers/evalContext.js +170 -0
- package/dist/serve/server.d.ts +53 -0
- package/dist/serve/server.js +355 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/oclif.manifest.json +271 -156
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ $ npm install -g @quonfig/cli
|
|
|
17
17
|
$ qfg COMMAND
|
|
18
18
|
running command...
|
|
19
19
|
$ qfg (--version)
|
|
20
|
-
@quonfig/cli/0.0.
|
|
20
|
+
@quonfig/cli/0.0.53 linux-x64 node-v24.4.1
|
|
21
21
|
$ qfg --help [COMMAND]
|
|
22
22
|
USAGE
|
|
23
23
|
$ qfg COMMAND
|
|
@@ -157,6 +157,7 @@ script doesn't need to know which env it's running in.
|
|
|
157
157
|
* [`qfg sdk-key create`](#qfg-sdk-key-create)
|
|
158
158
|
* [`qfg sdk-key list`](#qfg-sdk-key-list)
|
|
159
159
|
* [`qfg sdk-key revoke KEYID`](#qfg-sdk-key-revoke-keyid)
|
|
160
|
+
* [`qfg serve`](#qfg-serve)
|
|
160
161
|
* [`qfg set-default [NAME]`](#qfg-set-default-name)
|
|
161
162
|
* [`qfg set-rollout [NAME]`](#qfg-set-rollout-name)
|
|
162
163
|
* [`qfg sync`](#qfg-sync)
|
|
@@ -195,7 +196,7 @@ EXAMPLES
|
|
|
195
196
|
$ qfg activity restore my.flag --yes
|
|
196
197
|
```
|
|
197
198
|
|
|
198
|
-
_See code: [src/commands/activity.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
199
|
+
_See code: [src/commands/activity.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity.ts)_
|
|
199
200
|
|
|
200
201
|
## `qfg activity deleted`
|
|
201
202
|
|
|
@@ -224,7 +225,7 @@ EXAMPLES
|
|
|
224
225
|
$ qfg activity deleted --json
|
|
225
226
|
```
|
|
226
227
|
|
|
227
|
-
_See code: [src/commands/activity/deleted.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
228
|
+
_See code: [src/commands/activity/deleted.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/deleted.ts)_
|
|
228
229
|
|
|
229
230
|
## `qfg activity feed`
|
|
230
231
|
|
|
@@ -259,7 +260,7 @@ EXAMPLES
|
|
|
259
260
|
$ qfg activity feed --json
|
|
260
261
|
```
|
|
261
262
|
|
|
262
|
-
_See code: [src/commands/activity/feed.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
263
|
+
_See code: [src/commands/activity/feed.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/feed.ts)_
|
|
263
264
|
|
|
264
265
|
## `qfg activity history [NAME]`
|
|
265
266
|
|
|
@@ -293,7 +294,7 @@ EXAMPLES
|
|
|
293
294
|
$ qfg activity history request.timeout --json
|
|
294
295
|
```
|
|
295
296
|
|
|
296
|
-
_See code: [src/commands/activity/history.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
297
|
+
_See code: [src/commands/activity/history.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/history.ts)_
|
|
297
298
|
|
|
298
299
|
## `qfg activity restore [NAME]`
|
|
299
300
|
|
|
@@ -332,7 +333,7 @@ EXAMPLES
|
|
|
332
333
|
$ qfg activity restore request.timeout --type config --yes
|
|
333
334
|
```
|
|
334
335
|
|
|
335
|
-
_See code: [src/commands/activity/restore.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
336
|
+
_See code: [src/commands/activity/restore.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/activity/restore.ts)_
|
|
336
337
|
|
|
337
338
|
## `qfg audit-log [NAME]`
|
|
338
339
|
|
|
@@ -360,7 +361,7 @@ EXAMPLES
|
|
|
360
361
|
$ qfg audit-log my.flag
|
|
361
362
|
```
|
|
362
363
|
|
|
363
|
-
_See code: [src/commands/audit-log.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
364
|
+
_See code: [src/commands/audit-log.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/audit-log.ts)_
|
|
364
365
|
|
|
365
366
|
## `qfg config-schema`
|
|
366
367
|
|
|
@@ -389,7 +390,7 @@ EXAMPLES
|
|
|
389
390
|
$ qfg config-schema --json-schema # full JSON Schema document (copy into your editor)
|
|
390
391
|
```
|
|
391
392
|
|
|
392
|
-
_See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
393
|
+
_See code: [src/commands/config-schema.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/config-schema.ts)_
|
|
393
394
|
|
|
394
395
|
## `qfg create NAME`
|
|
395
396
|
|
|
@@ -474,7 +475,7 @@ EXAMPLES
|
|
|
474
475
|
$ qfg set-rollout my.new.flag --environment production --true-percent 20
|
|
475
476
|
```
|
|
476
477
|
|
|
477
|
-
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
478
|
+
_See code: [src/commands/create.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/create.ts)_
|
|
478
479
|
|
|
479
480
|
## `qfg delete NAME`
|
|
480
481
|
|
|
@@ -520,7 +521,7 @@ EXAMPLES
|
|
|
520
521
|
$ qfg delete my.config --yes
|
|
521
522
|
```
|
|
522
523
|
|
|
523
|
-
_See code: [src/commands/delete.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
524
|
+
_See code: [src/commands/delete.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/delete.ts)_
|
|
524
525
|
|
|
525
526
|
## `qfg flag info [NAME]`
|
|
526
527
|
|
|
@@ -724,7 +725,7 @@ EXAMPLES
|
|
|
724
725
|
$ qfg generate --targets node-ts -o ./dist # combine with targets
|
|
725
726
|
```
|
|
726
727
|
|
|
727
|
-
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
728
|
+
_See code: [src/commands/generate.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/generate.ts)_
|
|
728
729
|
|
|
729
730
|
## `qfg generate-new-hex-key`
|
|
730
731
|
|
|
@@ -747,7 +748,7 @@ EXAMPLES
|
|
|
747
748
|
$ qfg generate-new-hex-key
|
|
748
749
|
```
|
|
749
750
|
|
|
750
|
-
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
751
|
+
_See code: [src/commands/generate-new-hex-key.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/generate-new-hex-key.ts)_
|
|
751
752
|
|
|
752
753
|
## `qfg get [NAME]`
|
|
753
754
|
|
|
@@ -779,7 +780,7 @@ EXAMPLES
|
|
|
779
780
|
$ qfg get my.config.name --environment=production
|
|
780
781
|
```
|
|
781
782
|
|
|
782
|
-
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
783
|
+
_See code: [src/commands/get.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/get.ts)_
|
|
783
784
|
|
|
784
785
|
## `qfg history NAME`
|
|
785
786
|
|
|
@@ -805,7 +806,7 @@ EXAMPLES
|
|
|
805
806
|
$ qfg history my.flag
|
|
806
807
|
```
|
|
807
808
|
|
|
808
|
-
_See code: [src/commands/history.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
809
|
+
_See code: [src/commands/history.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/history.ts)_
|
|
809
810
|
|
|
810
811
|
## `qfg info [NAME]`
|
|
811
812
|
|
|
@@ -853,7 +854,7 @@ EXAMPLES
|
|
|
853
854
|
$ qfg info my.config.name --exclude-evaluations # skip 24h stats
|
|
854
855
|
```
|
|
855
856
|
|
|
856
|
-
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
857
|
+
_See code: [src/commands/info.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/info.ts)_
|
|
857
858
|
|
|
858
859
|
## `qfg init [DIRECTORY]`
|
|
859
860
|
|
|
@@ -893,7 +894,7 @@ EXAMPLES
|
|
|
893
894
|
$ qfg init --dry-run
|
|
894
895
|
```
|
|
895
896
|
|
|
896
|
-
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
897
|
+
_See code: [src/commands/init.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/init.ts)_
|
|
897
898
|
|
|
898
899
|
## `qfg interactive`
|
|
899
900
|
|
|
@@ -923,7 +924,7 @@ EXAMPLES
|
|
|
923
924
|
$ qfg
|
|
924
925
|
```
|
|
925
926
|
|
|
926
|
-
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
927
|
+
_See code: [src/commands/interactive.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/interactive.ts)_
|
|
927
928
|
|
|
928
929
|
## `qfg list`
|
|
929
930
|
|
|
@@ -963,7 +964,7 @@ EXAMPLES
|
|
|
963
964
|
$ qfg list --feature-flags
|
|
964
965
|
```
|
|
965
966
|
|
|
966
|
-
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
967
|
+
_See code: [src/commands/list.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/list.ts)_
|
|
967
968
|
|
|
968
969
|
## `qfg log`
|
|
969
970
|
|
|
@@ -988,7 +989,7 @@ EXAMPLES
|
|
|
988
989
|
$ qfg log --limit 5
|
|
989
990
|
```
|
|
990
991
|
|
|
991
|
-
_See code: [src/commands/log.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
992
|
+
_See code: [src/commands/log.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/log.ts)_
|
|
992
993
|
|
|
993
994
|
## `qfg log-level NAME`
|
|
994
995
|
|
|
@@ -1053,7 +1054,7 @@ EXAMPLES
|
|
|
1053
1054
|
$ qfg log-level log-level.my-app --target=Chatty --value=INFO --environment=production
|
|
1054
1055
|
```
|
|
1055
1056
|
|
|
1056
|
-
_See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1057
|
+
_See code: [src/commands/log-level.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/log-level.ts)_
|
|
1057
1058
|
|
|
1058
1059
|
## `qfg login`
|
|
1059
1060
|
|
|
@@ -1078,7 +1079,7 @@ EXAMPLES
|
|
|
1078
1079
|
$ qfg login --profile myprofile
|
|
1079
1080
|
```
|
|
1080
1081
|
|
|
1081
|
-
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1082
|
+
_See code: [src/commands/login.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/login.ts)_
|
|
1082
1083
|
|
|
1083
1084
|
## `qfg logout`
|
|
1084
1085
|
|
|
@@ -1101,7 +1102,7 @@ EXAMPLES
|
|
|
1101
1102
|
$ qfg logout
|
|
1102
1103
|
```
|
|
1103
1104
|
|
|
1104
|
-
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1105
|
+
_See code: [src/commands/logout.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/logout.ts)_
|
|
1105
1106
|
|
|
1106
1107
|
## `qfg migrate`
|
|
1107
1108
|
|
|
@@ -1164,7 +1165,7 @@ EXAMPLES
|
|
|
1164
1165
|
$ qfg migrate --from launch --source-api-key $LAUNCH_API_KEY --dir ./quonfig-repo --staging
|
|
1165
1166
|
```
|
|
1166
1167
|
|
|
1167
|
-
_See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1168
|
+
_See code: [src/commands/migrate.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate.ts)_
|
|
1168
1169
|
|
|
1169
1170
|
## `qfg migrate doctor`
|
|
1170
1171
|
|
|
@@ -1202,7 +1203,7 @@ EXAMPLES
|
|
|
1202
1203
|
$ qfg migrate doctor --json
|
|
1203
1204
|
```
|
|
1204
1205
|
|
|
1205
|
-
_See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1206
|
+
_See code: [src/commands/migrate/doctor.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate/doctor.ts)_
|
|
1206
1207
|
|
|
1207
1208
|
## `qfg migrate my-code`
|
|
1208
1209
|
|
|
@@ -1234,7 +1235,7 @@ EXAMPLES
|
|
|
1234
1235
|
$ qfg migrate my-code --dry-run
|
|
1235
1236
|
```
|
|
1236
1237
|
|
|
1237
|
-
_See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1238
|
+
_See code: [src/commands/migrate/my-code.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate/my-code.ts)_
|
|
1238
1239
|
|
|
1239
1240
|
## `qfg migrate status`
|
|
1240
1241
|
|
|
@@ -1265,7 +1266,7 @@ EXAMPLES
|
|
|
1265
1266
|
$ qfg migrate status --json
|
|
1266
1267
|
```
|
|
1267
1268
|
|
|
1268
|
-
_See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1269
|
+
_See code: [src/commands/migrate/status.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/migrate/status.ts)_
|
|
1269
1270
|
|
|
1270
1271
|
## `qfg override [NAME] [VALUE]`
|
|
1271
1272
|
|
|
@@ -1320,7 +1321,7 @@ EXAMPLES
|
|
|
1320
1321
|
$ qfg override my.flag true --env=staging
|
|
1321
1322
|
```
|
|
1322
1323
|
|
|
1323
|
-
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1324
|
+
_See code: [src/commands/override.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/override.ts)_
|
|
1324
1325
|
|
|
1325
1326
|
## `qfg pull`
|
|
1326
1327
|
|
|
@@ -1368,7 +1369,7 @@ EXAMPLES
|
|
|
1368
1369
|
$ qfg pull # uses QUONFIG_DIR env var
|
|
1369
1370
|
```
|
|
1370
1371
|
|
|
1371
|
-
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1372
|
+
_See code: [src/commands/pull.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/pull.ts)_
|
|
1372
1373
|
|
|
1373
1374
|
## `qfg push`
|
|
1374
1375
|
|
|
@@ -1417,7 +1418,7 @@ EXAMPLES
|
|
|
1417
1418
|
$ qfg push --dir ./our-config --yes
|
|
1418
1419
|
```
|
|
1419
1420
|
|
|
1420
|
-
_See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1421
|
+
_See code: [src/commands/push.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/push.ts)_
|
|
1421
1422
|
|
|
1422
1423
|
## `qfg run [COMMAND]`
|
|
1423
1424
|
|
|
@@ -1468,7 +1469,7 @@ EXAMPLES
|
|
|
1468
1469
|
$ qfg run --env DATABASE_URL=db.url --preserve-env --environment=staging -- npm test
|
|
1469
1470
|
```
|
|
1470
1471
|
|
|
1471
|
-
_See code: [src/commands/run.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1472
|
+
_See code: [src/commands/run.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/run.ts)_
|
|
1472
1473
|
|
|
1473
1474
|
## `qfg schema NAME`
|
|
1474
1475
|
|
|
@@ -1506,7 +1507,7 @@ EXAMPLES
|
|
|
1506
1507
|
$ qfg schema my-schema --set-json-schema=@schemas/my-schema.json --protected
|
|
1507
1508
|
```
|
|
1508
1509
|
|
|
1509
|
-
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1510
|
+
_See code: [src/commands/schema.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/schema.ts)_
|
|
1510
1511
|
|
|
1511
1512
|
## `qfg sdk-key`
|
|
1512
1513
|
|
|
@@ -1533,7 +1534,7 @@ EXAMPLES
|
|
|
1533
1534
|
$ qfg sdk-key revoke <key-id>
|
|
1534
1535
|
```
|
|
1535
1536
|
|
|
1536
|
-
_See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1537
|
+
_See code: [src/commands/sdk-key.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key.ts)_
|
|
1537
1538
|
|
|
1538
1539
|
## `qfg sdk-key create`
|
|
1539
1540
|
|
|
@@ -1565,7 +1566,7 @@ EXAMPLES
|
|
|
1565
1566
|
$ qfg sdk-key create --environment staging --type browser
|
|
1566
1567
|
```
|
|
1567
1568
|
|
|
1568
|
-
_See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1569
|
+
_See code: [src/commands/sdk-key/create.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key/create.ts)_
|
|
1569
1570
|
|
|
1570
1571
|
## `qfg sdk-key list`
|
|
1571
1572
|
|
|
@@ -1594,7 +1595,7 @@ EXAMPLES
|
|
|
1594
1595
|
$ qfg sdk-key list --environment production
|
|
1595
1596
|
```
|
|
1596
1597
|
|
|
1597
|
-
_See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1598
|
+
_See code: [src/commands/sdk-key/list.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key/list.ts)_
|
|
1598
1599
|
|
|
1599
1600
|
## `qfg sdk-key revoke KEYID`
|
|
1600
1601
|
|
|
@@ -1621,7 +1622,64 @@ EXAMPLES
|
|
|
1621
1622
|
$ qfg sdk-key revoke a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
1622
1623
|
```
|
|
1623
1624
|
|
|
1624
|
-
_See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1625
|
+
_See code: [src/commands/sdk-key/revoke.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sdk-key/revoke.ts)_
|
|
1626
|
+
|
|
1627
|
+
## `qfg serve`
|
|
1628
|
+
|
|
1629
|
+
Serve a local datadir over HTTP to browser/RN SDKs.
|
|
1630
|
+
|
|
1631
|
+
```
|
|
1632
|
+
USAGE
|
|
1633
|
+
$ qfg serve [--json] [--interactive] [--no-color] [--verbose] [--datadir <value>] [--environment <value>]
|
|
1634
|
+
[--port <value>] [--host <value>] [--frontend-sdk-key <value>] [--cors-origin <value>...] [--watch]
|
|
1635
|
+
[--allow-non-loopback]
|
|
1636
|
+
|
|
1637
|
+
FLAGS
|
|
1638
|
+
--allow-non-loopback Confirm a LAN-reachable bind. Required when --host is not loopback.
|
|
1639
|
+
--cors-origin=<value>... [default: *] Allowed CORS origin (repeatable). Default is *; required when binding to a
|
|
1640
|
+
non-loopback host.
|
|
1641
|
+
--datadir=<value> Datadir to serve (defaults to ./our-config, then ./.quonfig, then errors). Honors
|
|
1642
|
+
QUONFIG_DIR.
|
|
1643
|
+
--environment=<value> [default: development] Which environment slug to evaluate. Honors QUONFIG_ENVIRONMENT.
|
|
1644
|
+
--frontend-sdk-key=<value> If set, every request must present Authorization: Basic 1:<key>. If unset, the server is
|
|
1645
|
+
open (matches the "datadir is the source of truth" mental model).
|
|
1646
|
+
--host=<value> [default: 127.0.0.1] Bind address. Loopback by default; non-loopback requires
|
|
1647
|
+
--allow-non-loopback.
|
|
1648
|
+
--port=<value> [default: 6580] TCP port to listen on. Errors on collision; pass --port <n> to retry.
|
|
1649
|
+
--[no-]watch Reload the envelope when the datadir changes. --no-watch disables.
|
|
1650
|
+
|
|
1651
|
+
GLOBAL FLAGS
|
|
1652
|
+
--[no-]interactive Force interactive mode
|
|
1653
|
+
--json Format output as json.
|
|
1654
|
+
--no-color Do not colorize output
|
|
1655
|
+
--verbose Verbose output
|
|
1656
|
+
|
|
1657
|
+
DESCRIPTION
|
|
1658
|
+
Serve a local datadir over HTTP to browser/RN SDKs.
|
|
1659
|
+
|
|
1660
|
+
Reads configs from a local datadir and exposes them at
|
|
1661
|
+
`GET /api/v2/configs/eval-with-context/{base64url(ctx)}`. Point your
|
|
1662
|
+
browser SDK at the resulting URL (`http://localhost:6580` by default)
|
|
1663
|
+
and the same client code that talks to api-delivery in production will
|
|
1664
|
+
work unmodified.
|
|
1665
|
+
|
|
1666
|
+
Telemetry is intentionally not served — qfg serve has no Quonfig backend
|
|
1667
|
+
behind it. Disable client-side telemetry with
|
|
1668
|
+
`collectEvaluationSummaries: false` (and `contextUploadMode: "none"`),
|
|
1669
|
+
or point the SDK's `telemetryUrl` at a real endpoint.
|
|
1670
|
+
|
|
1671
|
+
The server is bound to 127.0.0.1 by default; pass --allow-non-loopback
|
|
1672
|
+
to confirm a LAN-reachable bind.
|
|
1673
|
+
|
|
1674
|
+
EXAMPLES
|
|
1675
|
+
$ qfg serve
|
|
1676
|
+
|
|
1677
|
+
$ qfg serve --datadir ./our-config --environment production
|
|
1678
|
+
|
|
1679
|
+
$ qfg serve --port 6581 --frontend-sdk-key PUBLIC_KEY
|
|
1680
|
+
```
|
|
1681
|
+
|
|
1682
|
+
_See code: [src/commands/serve.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/serve.ts)_
|
|
1625
1683
|
|
|
1626
1684
|
## `qfg set-default [NAME]`
|
|
1627
1685
|
|
|
@@ -1692,7 +1750,7 @@ EXAMPLES
|
|
|
1692
1750
|
$ qfg pull && qfg config-schema
|
|
1693
1751
|
```
|
|
1694
1752
|
|
|
1695
|
-
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1753
|
+
_See code: [src/commands/set-default.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/set-default.ts)_
|
|
1696
1754
|
|
|
1697
1755
|
## `qfg set-rollout [NAME]`
|
|
1698
1756
|
|
|
@@ -1769,7 +1827,7 @@ EXAMPLES
|
|
|
1769
1827
|
$ qfg set-rollout my.variant.flag --environment production --weights "a:33,b:33,c:34" --hash-by user.id
|
|
1770
1828
|
```
|
|
1771
1829
|
|
|
1772
|
-
_See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1830
|
+
_See code: [src/commands/set-rollout.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/set-rollout.ts)_
|
|
1773
1831
|
|
|
1774
1832
|
## `qfg sync`
|
|
1775
1833
|
|
|
@@ -1801,7 +1859,7 @@ EXAMPLES
|
|
|
1801
1859
|
$ qfg sync --watch --dir ./our-config --interval 30
|
|
1802
1860
|
```
|
|
1803
1861
|
|
|
1804
|
-
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1862
|
+
_See code: [src/commands/sync.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/sync.ts)_
|
|
1805
1863
|
|
|
1806
1864
|
## `qfg toggle [NAME]`
|
|
1807
1865
|
|
|
@@ -1903,7 +1961,7 @@ EXAMPLES
|
|
|
1903
1961
|
$ qfg verify --json
|
|
1904
1962
|
```
|
|
1905
1963
|
|
|
1906
|
-
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1964
|
+
_See code: [src/commands/verify.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/verify.ts)_
|
|
1907
1965
|
|
|
1908
1966
|
## `qfg whoami`
|
|
1909
1967
|
|
|
@@ -1926,7 +1984,7 @@ EXAMPLES
|
|
|
1926
1984
|
$ qfg whoami
|
|
1927
1985
|
```
|
|
1928
1986
|
|
|
1929
|
-
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
1987
|
+
_See code: [src/commands/whoami.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/whoami.ts)_
|
|
1930
1988
|
|
|
1931
1989
|
## `qfg workspace`
|
|
1932
1990
|
|
|
@@ -1949,7 +2007,7 @@ EXAMPLES
|
|
|
1949
2007
|
$ qfg workspace
|
|
1950
2008
|
```
|
|
1951
2009
|
|
|
1952
|
-
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
2010
|
+
_See code: [src/commands/workspace.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace.ts)_
|
|
1953
2011
|
|
|
1954
2012
|
## `qfg workspace bootstrap`
|
|
1955
2013
|
|
|
@@ -1982,7 +2040,7 @@ EXAMPLES
|
|
|
1982
2040
|
$ qfg workspace bootstrap --dir ./our-config --skip-validate
|
|
1983
2041
|
```
|
|
1984
2042
|
|
|
1985
|
-
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
2043
|
+
_See code: [src/commands/workspace/bootstrap.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace/bootstrap.ts)_
|
|
1986
2044
|
|
|
1987
2045
|
## `qfg workspace create SLUG`
|
|
1988
2046
|
|
|
@@ -2016,7 +2074,7 @@ EXAMPLES
|
|
|
2016
2074
|
$ qfg workspace create my-team --org 11111111-1111-1111-1111-111111111111
|
|
2017
2075
|
```
|
|
2018
2076
|
|
|
2019
|
-
_See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
2077
|
+
_See code: [src/commands/workspace/create.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace/create.ts)_
|
|
2020
2078
|
|
|
2021
2079
|
## `qfg workspace switch [SLUG]`
|
|
2022
2080
|
|
|
@@ -2044,7 +2102,7 @@ EXAMPLES
|
|
|
2044
2102
|
$ qfg workspace switch acme/production
|
|
2045
2103
|
```
|
|
2046
2104
|
|
|
2047
|
-
_See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.
|
|
2105
|
+
_See code: [src/commands/workspace/switch.ts](https://github.com/quonfig/cli/blob/v0.0.53/src/commands/workspace/switch.ts)_
|
|
2048
2106
|
<!-- commandsstop -->
|
|
2049
2107
|
|
|
2050
2108
|
## Local Development
|
package/dist/commands/run.js
CHANGED
|
@@ -241,7 +241,6 @@ The flag separator '--' is REQUIRED between qfg flags and the child command.`;
|
|
|
241
241
|
const quonfig = new Quonfig({
|
|
242
242
|
sdkKey,
|
|
243
243
|
collectEvaluationSummaries: false,
|
|
244
|
-
collectLoggerCounts: false,
|
|
245
244
|
contextUploadMode: 'none',
|
|
246
245
|
enableSSE: false,
|
|
247
246
|
apiUrls: [getDeliveryUrl()],
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `qfg serve` — Node-native local server that exposes a datadir over the
|
|
3
|
+
* same HTTP protocol the browser SDKs already speak. Designed to close the
|
|
4
|
+
* "browser SDKs can't read a local datadir" gap (epic qfg-38sf, plan
|
|
5
|
+
* project/plans/qfg-serve.md, Option A).
|
|
6
|
+
*/
|
|
7
|
+
import type { JsonObj } from '../result.js';
|
|
8
|
+
import { BaseCommand } from '../index.js';
|
|
9
|
+
export default class Serve extends BaseCommand {
|
|
10
|
+
static description: string;
|
|
11
|
+
static examples: string[];
|
|
12
|
+
static flags: {
|
|
13
|
+
datadir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
14
|
+
environment: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
15
|
+
port: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
16
|
+
host: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
17
|
+
'frontend-sdk-key': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
18
|
+
'cors-origin': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
19
|
+
watch: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
20
|
+
'allow-non-loopback': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
21
|
+
};
|
|
22
|
+
run(): Promise<JsonObj | void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `qfg serve` — Node-native local server that exposes a datadir over the
|
|
3
|
+
* same HTTP protocol the browser SDKs already speak. Designed to close the
|
|
4
|
+
* "browser SDKs can't read a local datadir" gap (epic qfg-38sf, plan
|
|
5
|
+
* project/plans/qfg-serve.md, Option A).
|
|
6
|
+
*/
|
|
7
|
+
import { Flags } from '@oclif/core';
|
|
8
|
+
import { BaseCommand } from '../index.js';
|
|
9
|
+
import { resolveDatadirForServe } from '../serve/datadir-discovery.js';
|
|
10
|
+
import { startServer } from '../serve/server.js';
|
|
11
|
+
export default class Serve extends BaseCommand {
|
|
12
|
+
static description = `Serve a local datadir over HTTP to browser/RN SDKs.
|
|
13
|
+
|
|
14
|
+
Reads configs from a local datadir and exposes them at
|
|
15
|
+
\`GET /api/v2/configs/eval-with-context/{base64url(ctx)}\`. Point your
|
|
16
|
+
browser SDK at the resulting URL (\`http://localhost:6580\` by default)
|
|
17
|
+
and the same client code that talks to api-delivery in production will
|
|
18
|
+
work unmodified.
|
|
19
|
+
|
|
20
|
+
Telemetry is intentionally not served — qfg serve has no Quonfig backend
|
|
21
|
+
behind it. Disable client-side telemetry with
|
|
22
|
+
\`collectEvaluationSummaries: false\` (and \`contextUploadMode: "none"\`),
|
|
23
|
+
or point the SDK's \`telemetryUrl\` at a real endpoint.
|
|
24
|
+
|
|
25
|
+
The server is bound to 127.0.0.1 by default; pass --allow-non-loopback
|
|
26
|
+
to confirm a LAN-reachable bind.`;
|
|
27
|
+
static examples = [
|
|
28
|
+
'<%= config.bin %> serve',
|
|
29
|
+
'<%= config.bin %> serve --datadir ./our-config --environment production',
|
|
30
|
+
'<%= config.bin %> serve --port 6581 --frontend-sdk-key PUBLIC_KEY',
|
|
31
|
+
];
|
|
32
|
+
static flags = {
|
|
33
|
+
datadir: Flags.string({
|
|
34
|
+
description: 'Datadir to serve (defaults to ./our-config, then ./.quonfig, then errors). Honors QUONFIG_DIR.',
|
|
35
|
+
}),
|
|
36
|
+
environment: Flags.string({
|
|
37
|
+
default: 'development',
|
|
38
|
+
description: 'Which environment slug to evaluate. Honors QUONFIG_ENVIRONMENT.',
|
|
39
|
+
}),
|
|
40
|
+
port: Flags.integer({
|
|
41
|
+
default: 6580,
|
|
42
|
+
description: 'TCP port to listen on. Errors on collision; pass --port <n> to retry.',
|
|
43
|
+
}),
|
|
44
|
+
host: Flags.string({
|
|
45
|
+
default: '127.0.0.1',
|
|
46
|
+
description: 'Bind address. Loopback by default; non-loopback requires --allow-non-loopback.',
|
|
47
|
+
}),
|
|
48
|
+
'frontend-sdk-key': Flags.string({
|
|
49
|
+
description: 'If set, every request must present Authorization: Basic 1:<key>. ' +
|
|
50
|
+
'If unset, the server is open (matches the "datadir is the source of truth" mental model).',
|
|
51
|
+
}),
|
|
52
|
+
'cors-origin': Flags.string({
|
|
53
|
+
default: ['*'],
|
|
54
|
+
description: 'Allowed CORS origin (repeatable). Default is *; required when binding to a non-loopback host.',
|
|
55
|
+
multiple: true,
|
|
56
|
+
}),
|
|
57
|
+
watch: Flags.boolean({
|
|
58
|
+
allowNo: true,
|
|
59
|
+
default: true,
|
|
60
|
+
description: 'Reload the envelope when the datadir changes. --no-watch disables.',
|
|
61
|
+
}),
|
|
62
|
+
'allow-non-loopback': Flags.boolean({
|
|
63
|
+
default: false,
|
|
64
|
+
description: 'Confirm a LAN-reachable bind. Required when --host is not loopback.',
|
|
65
|
+
}),
|
|
66
|
+
};
|
|
67
|
+
async run() {
|
|
68
|
+
const { flags } = await this.parse(Serve);
|
|
69
|
+
const envEnvironment = process.env.QUONFIG_ENVIRONMENT;
|
|
70
|
+
const environment = flags.environment ?? envEnvironment ?? 'development';
|
|
71
|
+
const resolved = resolveDatadirForServe({
|
|
72
|
+
flagDatadir: flags.datadir,
|
|
73
|
+
envDatadir: process.env.QUONFIG_DIR,
|
|
74
|
+
cwd: process.cwd(),
|
|
75
|
+
});
|
|
76
|
+
if (resolved.kind === 'error') {
|
|
77
|
+
return this.err(resolved.message);
|
|
78
|
+
}
|
|
79
|
+
const datadir = resolved.dir;
|
|
80
|
+
if (this.isVerbose) {
|
|
81
|
+
this.verboseLog('Serve', { datadir, environment, port: flags.port, host: flags.host });
|
|
82
|
+
}
|
|
83
|
+
const logger = {
|
|
84
|
+
log: (msg) => this.log(msg),
|
|
85
|
+
warn: (msg) => this.logToStderr(msg),
|
|
86
|
+
};
|
|
87
|
+
let handle;
|
|
88
|
+
try {
|
|
89
|
+
handle = await startServer({
|
|
90
|
+
datadir,
|
|
91
|
+
environment,
|
|
92
|
+
port: flags.port,
|
|
93
|
+
host: flags.host,
|
|
94
|
+
frontendSdkKey: flags['frontend-sdk-key'],
|
|
95
|
+
corsOrigins: flags['cors-origin'],
|
|
96
|
+
watch: flags.watch,
|
|
97
|
+
allowNonLoopback: flags['allow-non-loopback'],
|
|
98
|
+
verbose: this.isVerbose,
|
|
99
|
+
logger,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return this.err(error.message);
|
|
104
|
+
}
|
|
105
|
+
const url = `http://${flags.host}:${handle.port}`;
|
|
106
|
+
this.log(`qfg serve listening on ${url}`);
|
|
107
|
+
this.log(` datadir: ${datadir}`);
|
|
108
|
+
this.log(` environment: ${environment}`);
|
|
109
|
+
if (flags['frontend-sdk-key']) {
|
|
110
|
+
this.log(` auth: required (Authorization: Basic 1:<key>)`);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.log(` auth: none (datadir served openly)`);
|
|
114
|
+
}
|
|
115
|
+
this.log('');
|
|
116
|
+
this.log('Point your browser SDK at the URL above:');
|
|
117
|
+
this.log(` init({ apiUrls: ["${url}"] })`);
|
|
118
|
+
this.log('Press Ctrl-C to stop.');
|
|
119
|
+
// Block until the process is killed. The server is already accepting
|
|
120
|
+
// connections; we just need to keep the event loop alive.
|
|
121
|
+
await new Promise((resolve) => {
|
|
122
|
+
const shutdown = async () => {
|
|
123
|
+
this.log('\nqfg serve shutting down...');
|
|
124
|
+
try {
|
|
125
|
+
await handle.close();
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
resolve();
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
process.once('SIGINT', shutdown);
|
|
132
|
+
process.once('SIGTERM', shutdown);
|
|
133
|
+
});
|
|
134
|
+
return { datadir, environment, url };
|
|
135
|
+
}
|
|
136
|
+
}
|
package/dist/quonfig.js
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadir discovery for `qfg serve`.
|
|
3
|
+
*
|
|
4
|
+
* Resolution order (plan §4):
|
|
5
|
+
* 1. --datadir flag
|
|
6
|
+
* 2. QUONFIG_DIR env var
|
|
7
|
+
* 3. ./our-config if present
|
|
8
|
+
* 4. ./.quonfig if present
|
|
9
|
+
* 5. error
|
|
10
|
+
*
|
|
11
|
+
* Kept narrow on purpose: `qfg pull`/`qfg push` use a richer
|
|
12
|
+
* `resolveWorkspaceDir` helper that walks up looking for `quonfig.json` — but
|
|
13
|
+
* `qfg serve` is intentionally cwd-relative (the user said "serve THIS dir")
|
|
14
|
+
* and the walk would surface a confusing path on a misconfigured repo. The
|
|
15
|
+
* default-pair lookup mirrors `qfg pull --dir` defaults documented in the
|
|
16
|
+
* plan.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_DATADIR_CANDIDATES: readonly ["our-config", ".quonfig"];
|
|
19
|
+
export declare const NO_DATADIR_ERROR: string;
|
|
20
|
+
export interface ResolveDatadirInput {
|
|
21
|
+
cwd: string;
|
|
22
|
+
envDatadir: string | undefined;
|
|
23
|
+
flagDatadir: string | undefined;
|
|
24
|
+
}
|
|
25
|
+
export type ResolveDatadirResult = {
|
|
26
|
+
kind: 'ok';
|
|
27
|
+
dir: string;
|
|
28
|
+
source: 'flag' | 'env' | 'cwd-default';
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'error';
|
|
31
|
+
message: string;
|
|
32
|
+
};
|
|
33
|
+
export declare const resolveDatadirForServe: (input: ResolveDatadirInput) => ResolveDatadirResult;
|