@hardfin/cli 0.1.0-dev.31 → 0.1.0-dev.32

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 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
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]="bb3026cb-ab06-5af0-9743-290b61ec91a3")}catch(e){}}();
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]="62437fed-ab84-53c5-9984-9bbadc0f2e15")}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-B0vISolG.js");
17
+ const { toCli, toParseExitCode, wasReportAttempted } = await import("./program-B02z-kNH.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-B0vISolG.js");
36
+ const { toReported } = await import("./program-B02z-kNH.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=bb3026cb-ab06-5af0-9743-290b61ec91a3
54
+ //# debugId=62437fed-ab84-53c5-9984-9bbadc0f2e15
@@ -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]="ab584cf3-443f-569e-8167-fa0cbab9ab68")}catch(e){}}();
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]="b1928379-e7e3-5a7e-9ade-d45695e05814")}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";
@@ -1065,6 +1065,31 @@ function toSummary(command) {
1065
1065
  subcommands: command.subcommands?.filter((entry) => !entry.hidden).map(toSummary)
1066
1066
  };
1067
1067
  }
1068
+ //#endregion
1069
+ //#region src/command/input.ts
1070
+ /** InputFailure is a body given with --input that cannot be used, and says why. */
1071
+ var InputFailure = class extends Error {
1072
+ constructor(message) {
1073
+ super(message);
1074
+ this.name = "InputFailure";
1075
+ }
1076
+ };
1077
+ /** toJSONInput reads the JSON a command was given with --input, from a file or from standard input. */
1078
+ function toJSONInput(source) {
1079
+ const name = source === "-" ? "standard input" : source;
1080
+ let text;
1081
+ try {
1082
+ text = readFileSync(source === "-" ? 0 : source, "utf8");
1083
+ } catch {
1084
+ return new InputFailure(`${name} cannot be read`);
1085
+ }
1086
+ if (text.trim() === "") return new InputFailure(`${name} is empty, and a body needs JSON`);
1087
+ try {
1088
+ return JSON.parse(text);
1089
+ } catch {
1090
+ return new InputFailure(`${name} does not hold JSON`);
1091
+ }
1092
+ }
1068
1093
  const apiCommand = defineCommand({
1069
1094
  name: "api",
1070
1095
  summary: "Call a Hardfin API endpoint and print what it answers",
@@ -1142,9 +1167,9 @@ async function runApi(input) {
1142
1167
  }
1143
1168
  let body;
1144
1169
  if (typeof input.flags["input"] === "string") {
1145
- body = toBody$1(input.flags["input"]);
1146
- if (body === void 0) {
1147
- writeFailure("invalid_input", `${input.flags["input"]} does not hold JSON`, input.isJSON);
1170
+ body = toJSONInput(input.flags["input"]);
1171
+ if (body instanceof InputFailure) {
1172
+ writeFailure("invalid_input", body.message, input.isJSON);
1148
1173
  return ExitCode.USAGE;
1149
1174
  }
1150
1175
  }
@@ -1180,14 +1205,6 @@ function toQuery$1(fields) {
1180
1205
  }
1181
1206
  return query;
1182
1207
  }
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
1208
  //#endregion
1192
1209
  //#region src/auth/browser.ts
1193
1210
  /** isWSL reports whether this Linux is running under Windows. */
@@ -3097,6 +3114,12 @@ const UNSET_FLAG = {
3097
3114
  repeatable: true,
3098
3115
  schema: z.array(z.string())
3099
3116
  };
3117
+ const INPUT_FLAG = {
3118
+ name: "input",
3119
+ description: "A file holding the JSON request body, or - for standard input. A flag given as well replaces its field",
3120
+ valueName: "path",
3121
+ schema: z.string()
3122
+ };
3100
3123
  const FILE_FLAG = {
3101
3124
  name: "file",
3102
3125
  description: "The file to upload",
@@ -3120,6 +3143,7 @@ function defineOperation(operation) {
3120
3143
  ...operation.queryFlags,
3121
3144
  ...operation.bodyFlags,
3122
3145
  ...operation.bodyFlags.some((flag) => flag.nullable) ? [UNSET_FLAG] : [],
3146
+ ...operation.bodyFlags.length > 0 ? [INPUT_FLAG] : [],
3123
3147
  ...operation.upload ? [...operation.upload.fields, FILE_FLAG] : [],
3124
3148
  ...operation.downloads ? [OUTPUT_FLAG] : [],
3125
3149
  JSON_FLAG
@@ -3147,12 +3171,17 @@ async function runOperation(operation, input) {
3147
3171
  writeFailure("invalid_arguments", `this command takes ${operation.pathParameters.length} argument(s)`, input.isJSON);
3148
3172
  return ExitCode.USAGE;
3149
3173
  }
3150
- const missing = operation.bodyFlags.concat(operation.upload?.fields ?? []).filter((flag) => flag.required && input.flags[toOptionKey(flag.name)] === void 0);
3174
+ const given = toGivenBody(input.flags["input"]);
3175
+ if (given instanceof InputFailure) {
3176
+ writeFailure("invalid_input", given.message, input.isJSON);
3177
+ return ExitCode.USAGE;
3178
+ }
3179
+ const missing = operation.bodyFlags.concat(operation.upload?.fields ?? []).filter((flag) => flag.required && input.flags[toOptionKey(flag.name)] === void 0 && !hasPath(given, flag.jsonPath));
3151
3180
  if (missing.length > 0) {
3152
3181
  writeFailure("missing_flag", `this command needs ${missing.map((flag) => `--${flag.name}`).join(", ")}`, input.isJSON);
3153
3182
  return ExitCode.USAGE;
3154
3183
  }
3155
- const body = toBody(operation, input.flags);
3184
+ const body = toBody(operation, input.flags, given);
3156
3185
  if (body instanceof Error) {
3157
3186
  writeFailure("invalid_flag", body.message, input.isJSON);
3158
3187
  return ExitCode.USAGE;
@@ -3261,10 +3290,27 @@ async function toForm(upload, flags) {
3261
3290
  }
3262
3291
  return form;
3263
3292
  }
3264
- /** toBody builds the request body from the flags, one field at a time. */
3265
- function toBody(operation, flags) {
3266
- const body = {};
3267
- let hasField = false;
3293
+ /** toGivenBody reads the --input body, which a generated command takes only as a JSON object. */
3294
+ function toGivenBody(source) {
3295
+ if (typeof source !== "string") return;
3296
+ const read = toJSONInput(source);
3297
+ if (read instanceof InputFailure) return read;
3298
+ 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"}`);
3299
+ return read;
3300
+ }
3301
+ /** hasPath reports whether a body already holds a value at a field's path. */
3302
+ function hasPath(body, path) {
3303
+ let holder = body;
3304
+ for (const name of path) {
3305
+ if (typeof holder !== "object" || holder === null || !(name in holder)) return false;
3306
+ holder = holder[name];
3307
+ }
3308
+ return true;
3309
+ }
3310
+ /** toBody builds the request body from the --input body and the flags, a flag winning over its field. */
3311
+ function toBody(operation, flags, given) {
3312
+ const body = given ? structuredClone(given) : {};
3313
+ let hasField = given !== void 0;
3268
3314
  for (const flag of operation.bodyFlags) {
3269
3315
  const value = flags[toOptionKey(flag.name)];
3270
3316
  if (value === void 0) continue;
@@ -6122,5 +6168,5 @@ async function toReported(error, isJSON, resolved, level = "error") {
6122
6168
  //#endregion
6123
6169
  export { toCli, toParseExitCode, toReported, wasReportAttempted };
6124
6170
 
6125
- //# sourceMappingURL=program-B0vISolG.js.map
6126
- //# debugId=ab584cf3-443f-569e-8167-fa0cbab9ab68
6171
+ //# sourceMappingURL=program-B02z-kNH.js.map
6172
+ //# debugId=b1928379-e7e3-5a7e-9ade-d45695e05814
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardfin/cli",
3
- "version": "0.1.0-dev.31",
3
+ "version": "0.1.0-dev.32",
4
4
  "description": "Command line interface for the Hardfin API",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hardfin, Inc.",