@hardfin/cli 0.1.0-dev.31 → 0.1.0-dev.33
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 +24 -0
- package/dist/cli.js +4 -4
- package/dist/completion-tree.json +115 -0
- package/dist/{program-B0vISolG.js → program-ByvcKNri.js} +88 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,15 @@ hardfin file get file_7hq2mx9pkr4stz8w --output photo.jpg
|
|
|
77
77
|
hardfin file get file_7hq2mx9pkr4stz8w --output - | wc -c
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
Send a whole body as JSON with `--input`, from a file or from standard input. A flag given as
|
|
81
|
+
well replaces its field, and a required field the body carries needs no flag. A value with a
|
|
82
|
+
comma in it, which a `key=value` flag cannot carry, goes through `--input`.
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
hardfin location create --input location.json
|
|
86
|
+
echo '{"name": "Dock 4, north side"}' | hardfin location create --input -
|
|
87
|
+
```
|
|
88
|
+
|
|
80
89
|
Clear a field with `--unset`, naming the flag:
|
|
81
90
|
|
|
82
91
|
```sh
|
|
@@ -199,6 +208,21 @@ On WSL the browser is opened through Windows, by `wslview`, then PowerShell, the
|
|
|
199
208
|
The port changes every time, so Hardfin matches a loopback redirect by everything except its
|
|
200
209
|
port, which is what RFC 8252 asks of an authorization server.
|
|
201
210
|
|
|
211
|
+
### When an agent signs you in
|
|
212
|
+
|
|
213
|
+
An agent that runs `hardfin login` reads its stderr, and you only see what the agent passes
|
|
214
|
+
on. So when output is JSON, which it is whenever stdout is not a terminal, the command writes
|
|
215
|
+
one line of JSON on stderr before it starts waiting.
|
|
216
|
+
|
|
217
|
+
| `event` | Also carries | The agent should |
|
|
218
|
+
| ------------- | -------------------------------------------------------------------- | --------------------------------------------------- |
|
|
219
|
+
| `sign_in_url` | `url`, `browserOpened`, `waitSeconds` | Show you `url`, saying whether a browser tab opened |
|
|
220
|
+
| `device_code` | `userCode`, `verificationUri`, `url`, `browserOpened`, `waitSeconds` | Show you the code and where to enter it |
|
|
221
|
+
|
|
222
|
+
The command then waits up to `waitSeconds` for you to approve, so the agent has to let it run
|
|
223
|
+
that long. An agent with no way to open your browser, such as one in a cloud sandbox, signs
|
|
224
|
+
in with `--device`.
|
|
225
|
+
|
|
202
226
|
### Signing in from a machine with no browser
|
|
203
227
|
|
|
204
228
|
`hardfin login --device` prints a short code and a page to enter it on, and waits. Approve
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3f5ddeb4-6ae9-5ded-b447-15c8483fc583")}catch(e){}}();
|
|
4
4
|
import module from "node:module";
|
|
5
5
|
//#region src/cli.ts
|
|
6
6
|
module.enableCompileCache?.();
|
|
@@ -14,7 +14,7 @@ process.on("unhandledRejection", (error) => void toCrash(error));
|
|
|
14
14
|
try {
|
|
15
15
|
const answer = await toQuickAnswer(process.argv.slice(2));
|
|
16
16
|
if (answer === void 0) {
|
|
17
|
-
const { toCli, toParseExitCode, wasReportAttempted } = await import("./program-
|
|
17
|
+
const { toCli, toParseExitCode, wasReportAttempted } = await import("./program-ByvcKNri.js");
|
|
18
18
|
try {
|
|
19
19
|
await toCli().parseAsync(process.argv);
|
|
20
20
|
} catch (error) {
|
|
@@ -33,7 +33,7 @@ async function toCrash(error) {
|
|
|
33
33
|
isCrashing = true;
|
|
34
34
|
process.stderr.write(`error: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
35
35
|
try {
|
|
36
|
-
const { toReported } = await import("./program-
|
|
36
|
+
const { toReported } = await import("./program-ByvcKNri.js");
|
|
37
37
|
await toReported(error, false, void 0, "fatal");
|
|
38
38
|
} finally {
|
|
39
39
|
process.exit(1);
|
|
@@ -51,4 +51,4 @@ async function toQuickAnswer(args) {
|
|
|
51
51
|
export {};
|
|
52
52
|
|
|
53
53
|
//# sourceMappingURL=cli.js.map
|
|
54
|
-
//# debugId=
|
|
54
|
+
//# debugId=3f5ddeb4-6ae9-5ded-b447-15c8483fc583
|
|
@@ -351,6 +351,11 @@
|
|
|
351
351
|
"valueName": "field",
|
|
352
352
|
"repeatable": true
|
|
353
353
|
},
|
|
354
|
+
{
|
|
355
|
+
"name": "input",
|
|
356
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
357
|
+
"valueName": "path"
|
|
358
|
+
},
|
|
354
359
|
{
|
|
355
360
|
"name": "json",
|
|
356
361
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -384,6 +389,11 @@
|
|
|
384
389
|
"valueName": "assetId=,deliverAt=,deliverAtTimezone=,destinationId=,originId=,shipAt=,shipAtTimezone=",
|
|
385
390
|
"repeatable": true
|
|
386
391
|
},
|
|
392
|
+
{
|
|
393
|
+
"name": "input",
|
|
394
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
395
|
+
"valueName": "path"
|
|
396
|
+
},
|
|
387
397
|
{
|
|
388
398
|
"name": "json",
|
|
389
399
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -412,6 +422,11 @@
|
|
|
412
422
|
"valueName": "assetId=,deliverAt=,id=,shipAt=",
|
|
413
423
|
"repeatable": true
|
|
414
424
|
},
|
|
425
|
+
{
|
|
426
|
+
"name": "input",
|
|
427
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
428
|
+
"valueName": "path"
|
|
429
|
+
},
|
|
415
430
|
{
|
|
416
431
|
"name": "json",
|
|
417
432
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -487,6 +502,11 @@
|
|
|
487
502
|
"valueName": "field",
|
|
488
503
|
"repeatable": true
|
|
489
504
|
},
|
|
505
|
+
{
|
|
506
|
+
"name": "input",
|
|
507
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
508
|
+
"valueName": "path"
|
|
509
|
+
},
|
|
490
510
|
{
|
|
491
511
|
"name": "json",
|
|
492
512
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -596,6 +616,11 @@
|
|
|
596
616
|
"valueName": "field",
|
|
597
617
|
"repeatable": true
|
|
598
618
|
},
|
|
619
|
+
{
|
|
620
|
+
"name": "input",
|
|
621
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
622
|
+
"valueName": "path"
|
|
623
|
+
},
|
|
599
624
|
{
|
|
600
625
|
"name": "json",
|
|
601
626
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -623,6 +648,11 @@
|
|
|
623
648
|
"description": "Whether Hardfin sets the asset's in-service date itself",
|
|
624
649
|
"negatable": true
|
|
625
650
|
},
|
|
651
|
+
{
|
|
652
|
+
"name": "input",
|
|
653
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
654
|
+
"valueName": "path"
|
|
655
|
+
},
|
|
626
656
|
{
|
|
627
657
|
"name": "json",
|
|
628
658
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -695,6 +725,11 @@
|
|
|
695
725
|
"valueName": "field",
|
|
696
726
|
"repeatable": true
|
|
697
727
|
},
|
|
728
|
+
{
|
|
729
|
+
"name": "input",
|
|
730
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
731
|
+
"valueName": "path"
|
|
732
|
+
},
|
|
698
733
|
{
|
|
699
734
|
"name": "json",
|
|
700
735
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -893,6 +928,11 @@
|
|
|
893
928
|
"valueName": "field",
|
|
894
929
|
"repeatable": true
|
|
895
930
|
},
|
|
931
|
+
{
|
|
932
|
+
"name": "input",
|
|
933
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
934
|
+
"valueName": "path"
|
|
935
|
+
},
|
|
896
936
|
{
|
|
897
937
|
"name": "json",
|
|
898
938
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -913,6 +953,11 @@
|
|
|
913
953
|
"description": "The day your organization takes the asset back, which cannot be in the future",
|
|
914
954
|
"valueName": "value"
|
|
915
955
|
},
|
|
956
|
+
{
|
|
957
|
+
"name": "input",
|
|
958
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
959
|
+
"valueName": "path"
|
|
960
|
+
},
|
|
916
961
|
{
|
|
917
962
|
"name": "json",
|
|
918
963
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -965,6 +1010,11 @@
|
|
|
965
1010
|
"valueName": "field",
|
|
966
1011
|
"repeatable": true
|
|
967
1012
|
},
|
|
1013
|
+
{
|
|
1014
|
+
"name": "input",
|
|
1015
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1016
|
+
"valueName": "path"
|
|
1017
|
+
},
|
|
968
1018
|
{
|
|
969
1019
|
"name": "json",
|
|
970
1020
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1027,6 +1077,11 @@
|
|
|
1027
1077
|
"valueName": "field",
|
|
1028
1078
|
"repeatable": true
|
|
1029
1079
|
},
|
|
1080
|
+
{
|
|
1081
|
+
"name": "input",
|
|
1082
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1083
|
+
"valueName": "path"
|
|
1084
|
+
},
|
|
1030
1085
|
{
|
|
1031
1086
|
"name": "json",
|
|
1032
1087
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1106,6 +1161,11 @@
|
|
|
1106
1161
|
"valueName": "field",
|
|
1107
1162
|
"repeatable": true
|
|
1108
1163
|
},
|
|
1164
|
+
{
|
|
1165
|
+
"name": "input",
|
|
1166
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1167
|
+
"valueName": "path"
|
|
1168
|
+
},
|
|
1109
1169
|
{
|
|
1110
1170
|
"name": "json",
|
|
1111
1171
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1165,6 +1225,11 @@
|
|
|
1165
1225
|
"valueName": "field",
|
|
1166
1226
|
"repeatable": true
|
|
1167
1227
|
},
|
|
1228
|
+
{
|
|
1229
|
+
"name": "input",
|
|
1230
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1231
|
+
"valueName": "path"
|
|
1232
|
+
},
|
|
1168
1233
|
{
|
|
1169
1234
|
"name": "json",
|
|
1170
1235
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1313,6 +1378,11 @@
|
|
|
1313
1378
|
"valueName": "field",
|
|
1314
1379
|
"repeatable": true
|
|
1315
1380
|
},
|
|
1381
|
+
{
|
|
1382
|
+
"name": "input",
|
|
1383
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1384
|
+
"valueName": "path"
|
|
1385
|
+
},
|
|
1316
1386
|
{
|
|
1317
1387
|
"name": "json",
|
|
1318
1388
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1402,6 +1472,11 @@
|
|
|
1402
1472
|
"valueName": "field",
|
|
1403
1473
|
"repeatable": true
|
|
1404
1474
|
},
|
|
1475
|
+
{
|
|
1476
|
+
"name": "input",
|
|
1477
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1478
|
+
"valueName": "path"
|
|
1479
|
+
},
|
|
1405
1480
|
{
|
|
1406
1481
|
"name": "json",
|
|
1407
1482
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1664,6 +1739,11 @@
|
|
|
1664
1739
|
"valueName": "field",
|
|
1665
1740
|
"repeatable": true
|
|
1666
1741
|
},
|
|
1742
|
+
{
|
|
1743
|
+
"name": "input",
|
|
1744
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1745
|
+
"valueName": "path"
|
|
1746
|
+
},
|
|
1667
1747
|
{
|
|
1668
1748
|
"name": "json",
|
|
1669
1749
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1739,6 +1819,11 @@
|
|
|
1739
1819
|
"valueName": "field",
|
|
1740
1820
|
"repeatable": true
|
|
1741
1821
|
},
|
|
1822
|
+
{
|
|
1823
|
+
"name": "input",
|
|
1824
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1825
|
+
"valueName": "path"
|
|
1826
|
+
},
|
|
1742
1827
|
{
|
|
1743
1828
|
"name": "json",
|
|
1744
1829
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1838,6 +1923,11 @@
|
|
|
1838
1923
|
"valueName": "field",
|
|
1839
1924
|
"repeatable": true
|
|
1840
1925
|
},
|
|
1926
|
+
{
|
|
1927
|
+
"name": "input",
|
|
1928
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1929
|
+
"valueName": "path"
|
|
1930
|
+
},
|
|
1841
1931
|
{
|
|
1842
1932
|
"name": "json",
|
|
1843
1933
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1898,6 +1988,11 @@
|
|
|
1898
1988
|
"valueName": "field",
|
|
1899
1989
|
"repeatable": true
|
|
1900
1990
|
},
|
|
1991
|
+
{
|
|
1992
|
+
"name": "input",
|
|
1993
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
1994
|
+
"valueName": "path"
|
|
1995
|
+
},
|
|
1901
1996
|
{
|
|
1902
1997
|
"name": "json",
|
|
1903
1998
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1924,6 +2019,11 @@
|
|
|
1924
2019
|
"valueName": "field",
|
|
1925
2020
|
"repeatable": true
|
|
1926
2021
|
},
|
|
2022
|
+
{
|
|
2023
|
+
"name": "input",
|
|
2024
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
2025
|
+
"valueName": "path"
|
|
2026
|
+
},
|
|
1927
2027
|
{
|
|
1928
2028
|
"name": "json",
|
|
1929
2029
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -2141,6 +2241,11 @@
|
|
|
2141
2241
|
"valueName": "field",
|
|
2142
2242
|
"repeatable": true
|
|
2143
2243
|
},
|
|
2244
|
+
{
|
|
2245
|
+
"name": "input",
|
|
2246
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
2247
|
+
"valueName": "path"
|
|
2248
|
+
},
|
|
2144
2249
|
{
|
|
2145
2250
|
"name": "json",
|
|
2146
2251
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -2260,6 +2365,11 @@
|
|
|
2260
2365
|
"valueName": "field",
|
|
2261
2366
|
"repeatable": true
|
|
2262
2367
|
},
|
|
2368
|
+
{
|
|
2369
|
+
"name": "input",
|
|
2370
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
2371
|
+
"valueName": "path"
|
|
2372
|
+
},
|
|
2263
2373
|
{
|
|
2264
2374
|
"name": "json",
|
|
2265
2375
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -2371,6 +2481,11 @@
|
|
|
2371
2481
|
"valueName": "field",
|
|
2372
2482
|
"repeatable": true
|
|
2373
2483
|
},
|
|
2484
|
+
{
|
|
2485
|
+
"name": "input",
|
|
2486
|
+
"description": "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
2487
|
+
"valueName": "path"
|
|
2488
|
+
},
|
|
2374
2489
|
{
|
|
2375
2490
|
"name": "json",
|
|
2376
2491
|
"description": "Print machine-readable output, which is the default when stdout is not a terminal"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="93b4bc8d-ebeb-59ca-967b-9fd10484e4a5")}catch(e){}}();
|
|
4
4
|
import { a as defineCommand, i as GLOBAL_FLAGS, r as ExitCode, t as toInvocation } from "./scrub-BN3gyBpR.js";
|
|
5
5
|
import { n as toCompletion, t as toAnswer$1 } from "./completion-tree-rR_Rmeij.js";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
@@ -987,6 +987,7 @@ function toGuide(commands, version) {
|
|
|
987
987
|
"## Before calling",
|
|
988
988
|
"",
|
|
989
989
|
"- Authenticate with `--api-key`, by setting `HARDFIN_API_KEY`, or by running `hardfin login`",
|
|
990
|
+
"- `hardfin login` writes one JSON line on stderr before it waits. Show the person its `url`, or its `userCode` and `verificationUri`, and let the command run for `waitSeconds`",
|
|
990
991
|
"- Every command prints JSON on stdout and diagnostics on stderr",
|
|
991
992
|
"- Output is JSON whenever stdout is not a terminal, so no flag is needed when calling from code",
|
|
992
993
|
"",
|
|
@@ -1065,6 +1066,31 @@ function toSummary(command) {
|
|
|
1065
1066
|
subcommands: command.subcommands?.filter((entry) => !entry.hidden).map(toSummary)
|
|
1066
1067
|
};
|
|
1067
1068
|
}
|
|
1069
|
+
//#endregion
|
|
1070
|
+
//#region src/command/input.ts
|
|
1071
|
+
/** InputFailure is a body given with --input that cannot be used, and says why. */
|
|
1072
|
+
var InputFailure = class extends Error {
|
|
1073
|
+
constructor(message) {
|
|
1074
|
+
super(message);
|
|
1075
|
+
this.name = "InputFailure";
|
|
1076
|
+
}
|
|
1077
|
+
};
|
|
1078
|
+
/** toJSONInput reads the JSON a command was given with --input, from a file or from standard input. */
|
|
1079
|
+
function toJSONInput(source) {
|
|
1080
|
+
const name = source === "-" ? "standard input" : source;
|
|
1081
|
+
let text;
|
|
1082
|
+
try {
|
|
1083
|
+
text = readFileSync(source === "-" ? 0 : source, "utf8");
|
|
1084
|
+
} catch {
|
|
1085
|
+
return new InputFailure(`${name} cannot be read`);
|
|
1086
|
+
}
|
|
1087
|
+
if (text.trim() === "") return new InputFailure(`${name} is empty, and a body needs JSON`);
|
|
1088
|
+
try {
|
|
1089
|
+
return JSON.parse(text);
|
|
1090
|
+
} catch {
|
|
1091
|
+
return new InputFailure(`${name} does not hold JSON`);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1068
1094
|
const apiCommand = defineCommand({
|
|
1069
1095
|
name: "api",
|
|
1070
1096
|
summary: "Call a Hardfin API endpoint and print what it answers",
|
|
@@ -1142,9 +1168,9 @@ async function runApi(input) {
|
|
|
1142
1168
|
}
|
|
1143
1169
|
let body;
|
|
1144
1170
|
if (typeof input.flags["input"] === "string") {
|
|
1145
|
-
body =
|
|
1146
|
-
if (body
|
|
1147
|
-
writeFailure("invalid_input",
|
|
1171
|
+
body = toJSONInput(input.flags["input"]);
|
|
1172
|
+
if (body instanceof InputFailure) {
|
|
1173
|
+
writeFailure("invalid_input", body.message, input.isJSON);
|
|
1148
1174
|
return ExitCode.USAGE;
|
|
1149
1175
|
}
|
|
1150
1176
|
}
|
|
@@ -1180,14 +1206,6 @@ function toQuery$1(fields) {
|
|
|
1180
1206
|
}
|
|
1181
1207
|
return query;
|
|
1182
1208
|
}
|
|
1183
|
-
function toBody$1(source) {
|
|
1184
|
-
const text = source === "-" ? readFileSync(0, "utf8") : readFileSync(source, "utf8");
|
|
1185
|
-
try {
|
|
1186
|
-
return JSON.parse(text);
|
|
1187
|
-
} catch {
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
1209
|
//#endregion
|
|
1192
1210
|
//#region src/auth/browser.ts
|
|
1193
1211
|
/** isWSL reports whether this Linux is running under Windows. */
|
|
@@ -2137,7 +2155,13 @@ async function runLogin(input) {
|
|
|
2137
2155
|
challenge: pkce.challenge
|
|
2138
2156
|
});
|
|
2139
2157
|
const opened = input.flags["noBrowser"] !== true && !process.env["HARDFIN_NO_BROWSER"] && openBrowser(url);
|
|
2140
|
-
|
|
2158
|
+
if (input.isJSON) writeEvent({
|
|
2159
|
+
event: "sign_in_url",
|
|
2160
|
+
url,
|
|
2161
|
+
browserOpened: opened,
|
|
2162
|
+
waitSeconds: WAIT_MS / 1e3
|
|
2163
|
+
});
|
|
2164
|
+
else process.stderr.write(opened ? `Opening your browser to sign in. If it did not open:\n\n${url}\n\n` : `Open this URL to sign in:\n\n${url}\n\n`);
|
|
2141
2165
|
const prompt = toPrompt(url);
|
|
2142
2166
|
if (process.stdin.isTTY) process.stderr.write("Press c to copy the URL, or paste the code or redirect URL here: ");
|
|
2143
2167
|
let callback;
|
|
@@ -2147,7 +2171,7 @@ async function runLogin(input) {
|
|
|
2147
2171
|
listener.close();
|
|
2148
2172
|
prompt.close();
|
|
2149
2173
|
}
|
|
2150
|
-
process.stderr.write(callback.error ? "\n" : "\nApproved, finishing the sign in\n");
|
|
2174
|
+
if (!input.isJSON) process.stderr.write(callback.error ? "\n" : "\nApproved, finishing the sign in\n");
|
|
2151
2175
|
if (callback.error) {
|
|
2152
2176
|
writeFailure("sign_in_failed", `sign in was refused: ${callback.error}${callback.errorDescription ? `, ${callback.errorDescription}` : ""}`, input.isJSON);
|
|
2153
2177
|
return ExitCode.ERROR;
|
|
@@ -2183,7 +2207,15 @@ async function runDeviceLogin(input, metadata, scope) {
|
|
|
2183
2207
|
const device = await toDeviceAuthorization(metadata.device_authorization_endpoint, settings.clientId, scope);
|
|
2184
2208
|
const url = device.verificationUriComplete ?? device.verificationUri;
|
|
2185
2209
|
const opened = input.flags["noBrowser"] !== true && !process.env["HARDFIN_NO_BROWSER"] && openBrowser(url);
|
|
2186
|
-
|
|
2210
|
+
if (input.isJSON) writeEvent({
|
|
2211
|
+
event: "device_code",
|
|
2212
|
+
userCode: device.userCode,
|
|
2213
|
+
verificationUri: device.verificationUri,
|
|
2214
|
+
url,
|
|
2215
|
+
browserOpened: opened,
|
|
2216
|
+
waitSeconds: Math.max(0, Math.round((device.expiresAt - Date.now()) / 1e3))
|
|
2217
|
+
});
|
|
2218
|
+
else process.stderr.write([
|
|
2187
2219
|
"",
|
|
2188
2220
|
` Code ${device.userCode}`,
|
|
2189
2221
|
` At ${device.verificationUri}`,
|
|
@@ -2235,6 +2267,10 @@ async function toSignedIn(input, metadata, tokens) {
|
|
|
2235
2267
|
].join("\n"));
|
|
2236
2268
|
return ExitCode.OK;
|
|
2237
2269
|
}
|
|
2270
|
+
/** writeEvent tells a program what a sign in is waiting on, as one line of JSON on stderr. */
|
|
2271
|
+
function writeEvent(event) {
|
|
2272
|
+
process.stderr.write(`${JSON.stringify(event)}\n`);
|
|
2273
|
+
}
|
|
2238
2274
|
/** toAuthorizationUrl builds the URL the person approves this CLI at. */
|
|
2239
2275
|
function toAuthorizationUrl(endpoint, request) {
|
|
2240
2276
|
const url = new URL(endpoint);
|
|
@@ -3097,6 +3133,12 @@ const UNSET_FLAG = {
|
|
|
3097
3133
|
repeatable: true,
|
|
3098
3134
|
schema: z.array(z.string())
|
|
3099
3135
|
};
|
|
3136
|
+
const INPUT_FLAG = {
|
|
3137
|
+
name: "input",
|
|
3138
|
+
description: "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
|
|
3139
|
+
valueName: "path",
|
|
3140
|
+
schema: z.string()
|
|
3141
|
+
};
|
|
3100
3142
|
const FILE_FLAG = {
|
|
3101
3143
|
name: "file",
|
|
3102
3144
|
description: "The file to upload",
|
|
@@ -3120,6 +3162,7 @@ function defineOperation(operation) {
|
|
|
3120
3162
|
...operation.queryFlags,
|
|
3121
3163
|
...operation.bodyFlags,
|
|
3122
3164
|
...operation.bodyFlags.some((flag) => flag.nullable) ? [UNSET_FLAG] : [],
|
|
3165
|
+
...operation.bodyFlags.length > 0 ? [INPUT_FLAG] : [],
|
|
3123
3166
|
...operation.upload ? [...operation.upload.fields, FILE_FLAG] : [],
|
|
3124
3167
|
...operation.downloads ? [OUTPUT_FLAG] : [],
|
|
3125
3168
|
JSON_FLAG
|
|
@@ -3147,12 +3190,17 @@ async function runOperation(operation, input) {
|
|
|
3147
3190
|
writeFailure("invalid_arguments", `this command takes ${operation.pathParameters.length} argument(s)`, input.isJSON);
|
|
3148
3191
|
return ExitCode.USAGE;
|
|
3149
3192
|
}
|
|
3150
|
-
const
|
|
3193
|
+
const given = toGivenBody(input.flags["input"]);
|
|
3194
|
+
if (given instanceof InputFailure) {
|
|
3195
|
+
writeFailure("invalid_input", given.message, input.isJSON);
|
|
3196
|
+
return ExitCode.USAGE;
|
|
3197
|
+
}
|
|
3198
|
+
const missing = operation.bodyFlags.concat(operation.upload?.fields ?? []).filter((flag) => flag.required && input.flags[toOptionKey(flag.name)] === void 0 && !hasPath(given, flag.jsonPath));
|
|
3151
3199
|
if (missing.length > 0) {
|
|
3152
3200
|
writeFailure("missing_flag", `this command needs ${missing.map((flag) => `--${flag.name}`).join(", ")}`, input.isJSON);
|
|
3153
3201
|
return ExitCode.USAGE;
|
|
3154
3202
|
}
|
|
3155
|
-
const body = toBody(operation, input.flags);
|
|
3203
|
+
const body = toBody(operation, input.flags, given);
|
|
3156
3204
|
if (body instanceof Error) {
|
|
3157
3205
|
writeFailure("invalid_flag", body.message, input.isJSON);
|
|
3158
3206
|
return ExitCode.USAGE;
|
|
@@ -3261,10 +3309,27 @@ async function toForm(upload, flags) {
|
|
|
3261
3309
|
}
|
|
3262
3310
|
return form;
|
|
3263
3311
|
}
|
|
3264
|
-
/**
|
|
3265
|
-
function
|
|
3266
|
-
|
|
3267
|
-
|
|
3312
|
+
/** toGivenBody reads the --input body, which a generated command takes only as a JSON object. */
|
|
3313
|
+
function toGivenBody(source) {
|
|
3314
|
+
if (typeof source !== "string") return;
|
|
3315
|
+
const read = toJSONInput(source);
|
|
3316
|
+
if (read instanceof InputFailure) return read;
|
|
3317
|
+
if (typeof read !== "object" || read === null || Array.isArray(read)) return new InputFailure(`the body in ${source === "-" ? "standard input" : source} must be a JSON object, such as {"name": "Acme"}`);
|
|
3318
|
+
return read;
|
|
3319
|
+
}
|
|
3320
|
+
/** hasPath reports whether a body already holds a value at a field's path. */
|
|
3321
|
+
function hasPath(body, path) {
|
|
3322
|
+
let holder = body;
|
|
3323
|
+
for (const name of path) {
|
|
3324
|
+
if (typeof holder !== "object" || holder === null || !(name in holder)) return false;
|
|
3325
|
+
holder = holder[name];
|
|
3326
|
+
}
|
|
3327
|
+
return true;
|
|
3328
|
+
}
|
|
3329
|
+
/** toBody builds the request body from the --input body and the flags, a flag winning over its field. */
|
|
3330
|
+
function toBody(operation, flags, given) {
|
|
3331
|
+
const body = given ? structuredClone(given) : {};
|
|
3332
|
+
let hasField = given !== void 0;
|
|
3268
3333
|
for (const flag of operation.bodyFlags) {
|
|
3269
3334
|
const value = flags[toOptionKey(flag.name)];
|
|
3270
3335
|
if (value === void 0) continue;
|
|
@@ -6122,5 +6187,5 @@ async function toReported(error, isJSON, resolved, level = "error") {
|
|
|
6122
6187
|
//#endregion
|
|
6123
6188
|
export { toCli, toParseExitCode, toReported, wasReportAttempted };
|
|
6124
6189
|
|
|
6125
|
-
//# sourceMappingURL=program-
|
|
6126
|
-
//# debugId=
|
|
6190
|
+
//# sourceMappingURL=program-ByvcKNri.js.map
|
|
6191
|
+
//# debugId=93b4bc8d-ebeb-59ca-967b-9fd10484e4a5
|