@reporting-bi/cli 0.1.14 → 0.1.16
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/dist/index.js +116 -23
- 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,23 +10398,67 @@ 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
|
|
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 };
|
|
10423
|
+
}
|
|
10424
|
+
async function resolveDomain(domain2) {
|
|
10425
|
+
let origin = new URL(domain2).origin;
|
|
10426
|
+
for (let i = 0; i < 5; i++) {
|
|
10427
|
+
let res;
|
|
10428
|
+
try {
|
|
10429
|
+
res = await fetch(`${origin}/auth/info`, { method: "HEAD", redirect: "manual" });
|
|
10430
|
+
} catch {
|
|
10431
|
+
return origin;
|
|
10432
|
+
}
|
|
10433
|
+
const location = res.headers.get("location");
|
|
10434
|
+
if (res.status < 300 || res.status >= 400 || !location) return origin;
|
|
10435
|
+
const next = new URL(location, origin).origin;
|
|
10436
|
+
if (next === origin) return origin;
|
|
10437
|
+
origin = next;
|
|
10438
|
+
}
|
|
10439
|
+
return origin;
|
|
10404
10440
|
}
|
|
10405
10441
|
async function login(args) {
|
|
10406
10442
|
const { positional, flags } = parseArgs(args);
|
|
10407
|
-
const
|
|
10443
|
+
const requested = positional[0] || "https://bi.reporting.eu";
|
|
10444
|
+
const domain2 = await resolveDomain(requested);
|
|
10408
10445
|
const accounting2 = flags.accounting ? parseInt(flags.accounting) : void 0;
|
|
10409
|
-
|
|
10410
|
-
const
|
|
10446
|
+
const port = flags.port ? parseInt(flags.port) : 0;
|
|
10447
|
+
const browser = flags["no-browser"] !== "true" && canOpenBrowser();
|
|
10448
|
+
console.log(`Logging in to ${domain2}${domain2 !== requested.replace(/\/+$/, "") ? ` (redirected from ${requested})` : ""}...`);
|
|
10449
|
+
const code = await getAuthorizationCode(domain2, port, browser);
|
|
10411
10450
|
if (!code) {
|
|
10412
10451
|
console.error("Login cancelled or timed out.");
|
|
10413
10452
|
process.exit(1);
|
|
10414
10453
|
}
|
|
10415
10454
|
const client = createAuthClient(domain2);
|
|
10416
|
-
|
|
10455
|
+
try {
|
|
10456
|
+
await client.authorize(code);
|
|
10457
|
+
} catch (e) {
|
|
10458
|
+
const data = e.data;
|
|
10459
|
+
console.error(`Login failed: ${data?.error_description || data?.error || e.message}${data?.status ? ` (HTTP ${data.status})` : ""}`);
|
|
10460
|
+
process.exit(1);
|
|
10461
|
+
}
|
|
10417
10462
|
const credentials = await client.readCredentials();
|
|
10418
10463
|
if (!credentials?.access_token) {
|
|
10419
10464
|
console.error("Failed to obtain tokens.");
|
|
@@ -10440,12 +10485,17 @@ async function login(args) {
|
|
|
10440
10485
|
console.log('No accounting set. Use "rpbi use <domain> --accounting <id>" to set one.');
|
|
10441
10486
|
}
|
|
10442
10487
|
}
|
|
10443
|
-
function getAuthorizationCode(domain2) {
|
|
10488
|
+
function getAuthorizationCode(domain2, port, browser) {
|
|
10444
10489
|
return new Promise((resolve8) => {
|
|
10445
10490
|
let timeout;
|
|
10491
|
+
let rl;
|
|
10492
|
+
let finished = false;
|
|
10446
10493
|
const done = (result) => {
|
|
10494
|
+
if (finished) return;
|
|
10495
|
+
finished = true;
|
|
10447
10496
|
clearTimeout(timeout);
|
|
10448
10497
|
server.close();
|
|
10498
|
+
rl?.close();
|
|
10449
10499
|
resolve8(result);
|
|
10450
10500
|
};
|
|
10451
10501
|
const server = http.createServer((req, res) => {
|
|
@@ -10463,17 +10513,57 @@ function getAuthorizationCode(domain2) {
|
|
|
10463
10513
|
res.end("Waiting for authentication...");
|
|
10464
10514
|
}
|
|
10465
10515
|
});
|
|
10466
|
-
server.
|
|
10516
|
+
server.on("error", (err) => {
|
|
10517
|
+
console.error(`Cannot listen for the login callback: ${err.message}`);
|
|
10518
|
+
done(null);
|
|
10519
|
+
});
|
|
10520
|
+
server.listen(port, "localhost", () => {
|
|
10467
10521
|
const address = server.address();
|
|
10468
10522
|
if (!address || typeof address === "string") {
|
|
10469
10523
|
done(null);
|
|
10470
10524
|
return;
|
|
10471
10525
|
}
|
|
10472
|
-
const
|
|
10473
|
-
const redirectUri = `http://localhost:${port}`;
|
|
10526
|
+
const redirectUri = `http://localhost:${address.port}`;
|
|
10474
10527
|
const authUrl = `${domain2}/auth?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
10475
|
-
|
|
10476
|
-
|
|
10528
|
+
const printManual = () => {
|
|
10529
|
+
console.log("Open this URL in a browser and sign in:");
|
|
10530
|
+
console.log("");
|
|
10531
|
+
console.log(` ${authUrl}`);
|
|
10532
|
+
console.log("");
|
|
10533
|
+
if (process.stdin.isTTY) {
|
|
10534
|
+
console.log(`The browser then goes to ${redirectUri}/?code=... - if that page does not load`);
|
|
10535
|
+
console.log("(the browser runs on another machine), copy its whole address from the address bar");
|
|
10536
|
+
console.log("and paste it here.");
|
|
10537
|
+
}
|
|
10538
|
+
};
|
|
10539
|
+
if (browser) {
|
|
10540
|
+
console.log("Opening browser for authentication...");
|
|
10541
|
+
console.log(`If it does not open, visit: ${authUrl}`);
|
|
10542
|
+
openBrowser(authUrl, () => {
|
|
10543
|
+
console.log("Could not open a browser.");
|
|
10544
|
+
printManual();
|
|
10545
|
+
});
|
|
10546
|
+
} else {
|
|
10547
|
+
printManual();
|
|
10548
|
+
}
|
|
10549
|
+
if (process.stdin.isTTY) {
|
|
10550
|
+
rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false });
|
|
10551
|
+
rl.on("line", (line) => {
|
|
10552
|
+
let pasted;
|
|
10553
|
+
try {
|
|
10554
|
+
pasted = parsePastedCode(line);
|
|
10555
|
+
} catch {
|
|
10556
|
+
console.error("Not a valid address, paste the whole URL from the address bar.");
|
|
10557
|
+
return;
|
|
10558
|
+
}
|
|
10559
|
+
if (pasted.error) {
|
|
10560
|
+
console.error(`Login failed: ${pasted.error}`);
|
|
10561
|
+
done(null);
|
|
10562
|
+
} else if (pasted.code) {
|
|
10563
|
+
done(pasted.code);
|
|
10564
|
+
}
|
|
10565
|
+
});
|
|
10566
|
+
}
|
|
10477
10567
|
});
|
|
10478
10568
|
timeout = setTimeout(() => done(null), 5 * 60 * 1e3);
|
|
10479
10569
|
});
|
|
@@ -36588,7 +36678,7 @@ async function mcp() {
|
|
|
36588
36678
|
setMcpMode();
|
|
36589
36679
|
const server = new McpServer({
|
|
36590
36680
|
name: "reporting-bi",
|
|
36591
|
-
version: "0.1.
|
|
36681
|
+
version: "0.1.16"
|
|
36592
36682
|
});
|
|
36593
36683
|
server.tool(
|
|
36594
36684
|
"status",
|
|
@@ -37129,8 +37219,8 @@ async function checkForUpdate() {
|
|
|
37129
37219
|
saveUpdateCheck({ lastCheck: now });
|
|
37130
37220
|
const latest = await fetchLatestVersion();
|
|
37131
37221
|
if (!latest) return;
|
|
37132
|
-
if (!isNewer(latest, "0.1.
|
|
37133
|
-
console.error(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.1.
|
|
37222
|
+
if (!isNewer(latest, "0.1.16")) return;
|
|
37223
|
+
console.error(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.1.16"} \u2192 ${latest}...\x1B[0m`);
|
|
37134
37224
|
(0, import_node_child_process3.execSync)(npmInstallCmd(latest), { stdio: ["ignore", 2, 2] });
|
|
37135
37225
|
console.error(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
|
|
37136
37226
|
} catch {
|
|
@@ -37142,11 +37232,11 @@ async function forceUpdate() {
|
|
|
37142
37232
|
console.error("Could not fetch latest version from npm.");
|
|
37143
37233
|
process.exit(1);
|
|
37144
37234
|
}
|
|
37145
|
-
if (!isNewer(latest, "0.1.
|
|
37146
|
-
console.log(`Already up to date (${"0.1.
|
|
37235
|
+
if (!isNewer(latest, "0.1.16")) {
|
|
37236
|
+
console.log(`Already up to date (${"0.1.16"}).`);
|
|
37147
37237
|
return;
|
|
37148
37238
|
}
|
|
37149
|
-
console.log(`Updating ${PACKAGE_NAME} ${"0.1.
|
|
37239
|
+
console.log(`Updating ${PACKAGE_NAME} ${"0.1.16"} \u2192 ${latest}...`);
|
|
37150
37240
|
(0, import_node_child_process3.execSync)(npmInstallCmd(latest), { stdio: "inherit" });
|
|
37151
37241
|
console.log(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
|
|
37152
37242
|
saveUpdateCheck({ lastCheck: Date.now() });
|
|
@@ -37167,7 +37257,10 @@ pull removes local files deleted on the server (a locally modified file is kept)
|
|
|
37167
37257
|
deletes on the server what was deleted locally \u2014 single files or whole folders.
|
|
37168
37258
|
|
|
37169
37259
|
Commands:
|
|
37170
|
-
login [domain] [--accounting <id>]
|
|
37260
|
+
login [domain] [--accounting <id>] [--no-browser] [--port <n>]
|
|
37261
|
+
Login to a Reporting.bi instance (opens browser; without a
|
|
37262
|
+
display prints the URL - paste back the address the browser
|
|
37263
|
+
ends at, or forward --port over SSH)
|
|
37171
37264
|
logout [domain] Logout and revoke tokens (default: active connection)
|
|
37172
37265
|
use <domain> [--accounting <id>] Switch active connection and/or set accounting
|
|
37173
37266
|
status [--json] Show all connections, token and session expiry
|
|
@@ -37284,12 +37377,12 @@ Global options:
|
|
|
37284
37377
|
--filter <expression> Filter results (server-side where clause)
|
|
37285
37378
|
--verbose Show API request URLs for debugging
|
|
37286
37379
|
|
|
37287
|
-
Default domain: https://reporting.
|
|
37380
|
+
Default domain: https://bi.reporting.eu
|
|
37288
37381
|
Default language: cs
|
|
37289
37382
|
|
|
37290
37383
|
Examples:
|
|
37291
|
-
rpbi login https://reporting.
|
|
37292
|
-
rpbi use https://reporting.
|
|
37384
|
+
rpbi login https://bi.reporting.eu --accounting 100000
|
|
37385
|
+
rpbi use https://bi.reporting.eu --accounting 100000
|
|
37293
37386
|
rpbi status
|
|
37294
37387
|
|
|
37295
37388
|
rpbi etl list
|
|
@@ -37337,7 +37430,7 @@ Examples:
|
|
|
37337
37430
|
(async () => {
|
|
37338
37431
|
const [command, ...args] = process.argv.slice(2);
|
|
37339
37432
|
if (command === "--version" || command === "-v") {
|
|
37340
|
-
console.log("0.1.
|
|
37433
|
+
console.log("0.1.16");
|
|
37341
37434
|
return;
|
|
37342
37435
|
}
|
|
37343
37436
|
await checkForUpdate();
|