@reporting-bi/cli 0.1.14 → 0.1.15

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/index.js +86 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9315,6 +9315,7 @@ var require_dist = __commonJS({
9315
9315
  // src/commands/login.ts
9316
9316
  var http = __toESM(require("node:http"));
9317
9317
  var import_node_child_process2 = require("node:child_process");
9318
+ var readline = __toESM(require("node:readline"));
9318
9319
 
9319
9320
  // src/config.ts
9320
9321
  var fs2 = __toESM(require("node:fs"));
@@ -10397,17 +10398,37 @@ var callback_default = `<!DOCTYPE html>
10397
10398
  function renderCallback(status6, title, message) {
10398
10399
  return callback_default.replace("{{status}}", status6).replace("{{title}}", title).replace("{{message}}", message);
10399
10400
  }
10400
- function openBrowser(url2) {
10401
+ function canOpenBrowser() {
10402
+ const env = process.env;
10403
+ if (process.platform === "linux" || process.platform === "freebsd" || process.platform === "openbsd") {
10404
+ return !!(env.DISPLAY || env.WAYLAND_DISPLAY);
10405
+ }
10406
+ return !(env.SSH_CONNECTION || env.SSH_TTY);
10407
+ }
10408
+ function openBrowser(url2, onError) {
10401
10409
  const platform = process.platform;
10402
10410
  const cmd = platform === "darwin" ? "open" : platform === "win32" ? 'start ""' : "xdg-open";
10403
- (0, import_node_child_process2.exec)(`${cmd} ${JSON.stringify(url2)}`);
10411
+ (0, import_node_child_process2.exec)(`${cmd} ${JSON.stringify(url2)}`, (err) => {
10412
+ if (err) onError();
10413
+ });
10414
+ }
10415
+ function parsePastedCode(input) {
10416
+ const text2 = input.trim();
10417
+ if (!text2) return {};
10418
+ if (/[?&](code|error)=/.test(text2)) {
10419
+ const params3 = new URL(text2, "http://localhost").searchParams;
10420
+ return { code: params3.get("code") || void 0, error: params3.get("error") || void 0 };
10421
+ }
10422
+ return { code: text2 };
10404
10423
  }
10405
10424
  async function login(args) {
10406
10425
  const { positional, flags } = parseArgs(args);
10407
10426
  const domain2 = positional[0] || "https://reporting.bi";
10408
10427
  const accounting2 = flags.accounting ? parseInt(flags.accounting) : void 0;
10428
+ const port = flags.port ? parseInt(flags.port) : 0;
10429
+ const browser = flags["no-browser"] !== "true" && canOpenBrowser();
10409
10430
  console.log(`Logging in to ${domain2}...`);
10410
- const code = await getAuthorizationCode(domain2);
10431
+ const code = await getAuthorizationCode(domain2, port, browser);
10411
10432
  if (!code) {
10412
10433
  console.error("Login cancelled or timed out.");
10413
10434
  process.exit(1);
@@ -10440,12 +10461,17 @@ async function login(args) {
10440
10461
  console.log('No accounting set. Use "rpbi use <domain> --accounting <id>" to set one.');
10441
10462
  }
10442
10463
  }
10443
- function getAuthorizationCode(domain2) {
10464
+ function getAuthorizationCode(domain2, port, browser) {
10444
10465
  return new Promise((resolve8) => {
10445
10466
  let timeout;
10467
+ let rl;
10468
+ let finished = false;
10446
10469
  const done = (result) => {
10470
+ if (finished) return;
10471
+ finished = true;
10447
10472
  clearTimeout(timeout);
10448
10473
  server.close();
10474
+ rl?.close();
10449
10475
  resolve8(result);
10450
10476
  };
10451
10477
  const server = http.createServer((req, res) => {
@@ -10463,17 +10489,57 @@ function getAuthorizationCode(domain2) {
10463
10489
  res.end("Waiting for authentication...");
10464
10490
  }
10465
10491
  });
10466
- server.listen(0, "localhost", () => {
10492
+ server.on("error", (err) => {
10493
+ console.error(`Cannot listen for the login callback: ${err.message}`);
10494
+ done(null);
10495
+ });
10496
+ server.listen(port, "localhost", () => {
10467
10497
  const address = server.address();
10468
10498
  if (!address || typeof address === "string") {
10469
10499
  done(null);
10470
10500
  return;
10471
10501
  }
10472
- const port = address.port;
10473
- const redirectUri = `http://localhost:${port}`;
10502
+ const redirectUri = `http://localhost:${address.port}`;
10474
10503
  const authUrl = `${domain2}/auth?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}`;
10475
- console.log(`Opening browser for authentication...`);
10476
- openBrowser(authUrl);
10504
+ const printManual = () => {
10505
+ console.log("Open this URL in a browser and sign in:");
10506
+ console.log("");
10507
+ console.log(` ${authUrl}`);
10508
+ console.log("");
10509
+ if (process.stdin.isTTY) {
10510
+ console.log(`The browser then goes to ${redirectUri}/?code=... - if that page does not load`);
10511
+ console.log("(the browser runs on another machine), copy its whole address from the address bar");
10512
+ console.log("and paste it here.");
10513
+ }
10514
+ };
10515
+ if (browser) {
10516
+ console.log("Opening browser for authentication...");
10517
+ console.log(`If it does not open, visit: ${authUrl}`);
10518
+ openBrowser(authUrl, () => {
10519
+ console.log("Could not open a browser.");
10520
+ printManual();
10521
+ });
10522
+ } else {
10523
+ printManual();
10524
+ }
10525
+ if (process.stdin.isTTY) {
10526
+ rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false });
10527
+ rl.on("line", (line) => {
10528
+ let pasted;
10529
+ try {
10530
+ pasted = parsePastedCode(line);
10531
+ } catch {
10532
+ console.error("Not a valid address, paste the whole URL from the address bar.");
10533
+ return;
10534
+ }
10535
+ if (pasted.error) {
10536
+ console.error(`Login failed: ${pasted.error}`);
10537
+ done(null);
10538
+ } else if (pasted.code) {
10539
+ done(pasted.code);
10540
+ }
10541
+ });
10542
+ }
10477
10543
  });
10478
10544
  timeout = setTimeout(() => done(null), 5 * 60 * 1e3);
10479
10545
  });
@@ -36588,7 +36654,7 @@ async function mcp() {
36588
36654
  setMcpMode();
36589
36655
  const server = new McpServer({
36590
36656
  name: "reporting-bi",
36591
- version: "0.1.14"
36657
+ version: "0.1.15"
36592
36658
  });
36593
36659
  server.tool(
36594
36660
  "status",
@@ -37129,8 +37195,8 @@ async function checkForUpdate() {
37129
37195
  saveUpdateCheck({ lastCheck: now });
37130
37196
  const latest = await fetchLatestVersion();
37131
37197
  if (!latest) return;
37132
- if (!isNewer(latest, "0.1.14")) return;
37133
- console.error(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.1.14"} \u2192 ${latest}...\x1B[0m`);
37198
+ if (!isNewer(latest, "0.1.15")) return;
37199
+ console.error(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.1.15"} \u2192 ${latest}...\x1B[0m`);
37134
37200
  (0, import_node_child_process3.execSync)(npmInstallCmd(latest), { stdio: ["ignore", 2, 2] });
37135
37201
  console.error(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
37136
37202
  } catch {
@@ -37142,11 +37208,11 @@ async function forceUpdate() {
37142
37208
  console.error("Could not fetch latest version from npm.");
37143
37209
  process.exit(1);
37144
37210
  }
37145
- if (!isNewer(latest, "0.1.14")) {
37146
- console.log(`Already up to date (${"0.1.14"}).`);
37211
+ if (!isNewer(latest, "0.1.15")) {
37212
+ console.log(`Already up to date (${"0.1.15"}).`);
37147
37213
  return;
37148
37214
  }
37149
- console.log(`Updating ${PACKAGE_NAME} ${"0.1.14"} \u2192 ${latest}...`);
37215
+ console.log(`Updating ${PACKAGE_NAME} ${"0.1.15"} \u2192 ${latest}...`);
37150
37216
  (0, import_node_child_process3.execSync)(npmInstallCmd(latest), { stdio: "inherit" });
37151
37217
  console.log(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
37152
37218
  saveUpdateCheck({ lastCheck: Date.now() });
@@ -37167,7 +37233,10 @@ pull removes local files deleted on the server (a locally modified file is kept)
37167
37233
  deletes on the server what was deleted locally \u2014 single files or whole folders.
37168
37234
 
37169
37235
  Commands:
37170
- login [domain] [--accounting <id>] Login to a Reporting.bi instance (opens browser)
37236
+ login [domain] [--accounting <id>] [--no-browser] [--port <n>]
37237
+ Login to a Reporting.bi instance (opens browser; without a
37238
+ display prints the URL - paste back the address the browser
37239
+ ends at, or forward --port over SSH)
37171
37240
  logout [domain] Logout and revoke tokens (default: active connection)
37172
37241
  use <domain> [--accounting <id>] Switch active connection and/or set accounting
37173
37242
  status [--json] Show all connections, token and session expiry
@@ -37337,7 +37406,7 @@ Examples:
37337
37406
  (async () => {
37338
37407
  const [command, ...args] = process.argv.slice(2);
37339
37408
  if (command === "--version" || command === "-v") {
37340
- console.log("0.1.14");
37409
+ console.log("0.1.15");
37341
37410
  return;
37342
37411
  }
37343
37412
  await checkForUpdate();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reporting-bi/cli",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "license": "UNLICENSED",
5
5
  "description": "Reporting.bi CLI — command-line interface for the Reporting.bi platform",
6
6
  "main": "./dist/index.js",