@hardfin/cli 0.0.2-dev.17 → 0.0.2-dev.18

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.
Files changed (2) hide show
  1. package/dist/cli.js +26 -20
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -136,7 +136,7 @@ function writeData(value) {
136
136
  process.stdout.write(value.endsWith("\n") ? value : `${value}\n`);
137
137
  return;
138
138
  }
139
- process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
139
+ process.stdout.write(`${JSON.stringify(value ?? null, null, 2)}\n`);
140
140
  }
141
141
  /** writeFailure prints why a command failed on stderr, as text or as JSON. */
142
142
  function writeFailure(message, isJSON, errors, requestId) {
@@ -1101,8 +1101,8 @@ function toOpeners(url) {
1101
1101
  return [["xdg-open", [url]]];
1102
1102
  }
1103
1103
  /** openBrowser asks the desktop to show a URL, and reports whether anything took it. */
1104
- function openBrowser(url) {
1105
- for (const [command, args] of toOpeners(url)) if (spawnSync(command, args, {
1104
+ function openBrowser(url, launch = spawnSync) {
1105
+ for (const [command, args] of toOpeners(url)) if (launch(command, args, {
1106
1106
  stdio: "ignore",
1107
1107
  cwd: command.endsWith(".exe") ? "/mnt/c" : void 0,
1108
1108
  timeout: 1e4
@@ -1272,11 +1272,11 @@ function toClipboardCommand() {
1272
1272
  return ["xclip", ["-selection", "clipboard"]];
1273
1273
  }
1274
1274
  /** copyToClipboard puts text on the clipboard, and reports whether anything took it. */
1275
- function copyToClipboard(text) {
1275
+ function copyToClipboard(text, copy = spawnSync) {
1276
1276
  const command = toClipboardCommand();
1277
1277
  if (!command) return false;
1278
1278
  const [name, args] = command;
1279
- const result = spawnSync(name, args, { input: text });
1279
+ const result = copy(name, args, { input: text });
1280
1280
  return result.error === void 0 && result.status === 0;
1281
1281
  }
1282
1282
  //#endregion
@@ -1312,14 +1312,13 @@ function toPastedCallback(pasted) {
1312
1312
  * toPrompt watches the keyboard while the browser is away. Pressing c copies the URL, and
1313
1313
  * pasting a code finishes the sign in on a machine whose browser cannot reach this listener.
1314
1314
  */
1315
- function toPrompt(url) {
1315
+ function toPrompt(url, input = process.stdin, copy = copyToClipboard) {
1316
1316
  let settle = () => {};
1317
1317
  let fail = () => {};
1318
1318
  const pasted = new Promise((resolve, reject) => {
1319
1319
  settle = resolve;
1320
1320
  fail = reject;
1321
1321
  });
1322
- const input = process.stdin;
1323
1322
  pasted.catch(() => {});
1324
1323
  if (!input.isTTY) return {
1325
1324
  pasted,
@@ -1327,6 +1326,7 @@ function toPrompt(url) {
1327
1326
  };
1328
1327
  let typed = "";
1329
1328
  const onData = (chunk) => {
1329
+ const isKeystroke = chunk.length === 1;
1330
1330
  for (const character of chunk) {
1331
1331
  if (character === CTRL_C) {
1332
1332
  fail(/* @__PURE__ */ new Error("sign in was cancelled"));
@@ -1343,8 +1343,8 @@ function toPrompt(url) {
1343
1343
  process.stderr.write("\b \b");
1344
1344
  continue;
1345
1345
  }
1346
- if ((character === "c" || character === "C") && typed === "") {
1347
- process.stderr.write(copyToClipboard(url) ? "Copied the URL to your clipboard\n" : "Nothing on this host takes a clipboard\n");
1346
+ if (isKeystroke && (character === "c" || character === "C") && typed === "") {
1347
+ process.stderr.write(copy(url) ? "Copied the URL to your clipboard\n" : "Nothing on this host takes a clipboard\n");
1348
1348
  continue;
1349
1349
  }
1350
1350
  typed += character;
@@ -4963,13 +4963,16 @@ function toRejectedFlag(command, flags) {
4963
4963
  }
4964
4964
  }
4965
4965
  //#endregion
4966
- //#region src/cli.ts
4967
- const program = new Command();
4968
- program.name("hardfin").description("Call the Hardfin API from a terminal or an agent").version(version$1, "-v, --version").option("--api-url <url>", "The API to call, whose host also holds the authorization server").option("--issuer-url <url>", "The authorization server, when it does not sit at the API's host").showHelpAfterError().enablePositionalOptions();
4969
- for (const command of commands) program.addCommand(toProgram(command), { hidden: command.hidden });
4970
- await program.parseAsync(process.argv);
4966
+ //#region src/cli/program.ts
4967
+ /** toCli builds the parser from the registry, which is what every surface reads. */
4968
+ function toCli(entries = commands) {
4969
+ const program = new Command();
4970
+ program.name("hardfin").description("Call the Hardfin API from a terminal or an agent").version(version$1, "-v, --version").option("--api-url <url>", "The API to call, whose host also holds the authorization server").option("--issuer-url <url>", "The authorization server, when it does not sit at the API's host").showHelpAfterError().enablePositionalOptions();
4971
+ for (const command of entries) program.addCommand(toProgram(program, command), { hidden: command.hidden });
4972
+ return program;
4973
+ }
4971
4974
  /** toProgram wires one registry command into the parser. */
4972
- function toProgram(command) {
4975
+ function toProgram(root, command) {
4973
4976
  const program = new Command(command.name).summary(command.summary).description(command.description ?? command.summary);
4974
4977
  for (const argument of command.arguments) {
4975
4978
  const name = argument.variadic ? `${argument.name}...` : argument.name;
@@ -4985,16 +4988,16 @@ function toProgram(command) {
4985
4988
  program.addOption(option);
4986
4989
  }
4987
4990
  for (const example of command.examples) program.addHelpText("after", `\n${example.description}:\n $ ${example.command}`);
4988
- for (const subcommand of command.subcommands ?? []) program.addCommand(toProgram(subcommand), { hidden: subcommand.hidden });
4991
+ for (const subcommand of command.subcommands ?? []) program.addCommand(toProgram(root, subcommand), { hidden: subcommand.hidden });
4989
4992
  if (!command.run) return program;
4990
4993
  program.action(async (...parsed) => {
4991
4994
  const flags = parsed[parsed.length - 2] ?? {};
4992
4995
  const args = parsed.slice(0, parsed.length - 2).flatMap(toArgumentList);
4993
- process.exitCode = await toExitCode(command, args, flags);
4996
+ process.exitCode = await toExitCode(root, command, args, flags);
4994
4997
  });
4995
4998
  return program;
4996
4999
  }
4997
- async function toExitCode(command, args, flags) {
5000
+ async function toExitCode(root, command, args, flags) {
4998
5001
  const isJSON = isJSONOutput(flags);
4999
5002
  const rejected = toRejectedFlag(command, flags);
5000
5003
  if (rejected) {
@@ -5003,8 +5006,8 @@ async function toExitCode(command, args, flags) {
5003
5006
  }
5004
5007
  try {
5005
5008
  const resolved = toSettings({
5006
- apiUrl: program.opts()["apiUrl"],
5007
- issuerUrl: program.opts()["issuerUrl"]
5009
+ apiUrl: root.opts()["apiUrl"],
5010
+ issuerUrl: root.opts()["issuerUrl"]
5008
5011
  });
5009
5012
  return await command.run?.({
5010
5013
  args,
@@ -5026,4 +5029,7 @@ function collect(value, previous) {
5026
5029
  return [...previous ?? [], value];
5027
5030
  }
5028
5031
  //#endregion
5032
+ //#region src/cli.ts
5033
+ await toCli().parseAsync(process.argv);
5034
+ //#endregion
5029
5035
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardfin/cli",
3
- "version": "0.0.2-dev.17",
3
+ "version": "0.0.2-dev.18",
4
4
  "description": "Command line interface for the Hardfin API",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hardfin, Inc.",