@datarails-ai/dr-cli 1.6.72 → 1.6.74
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 +10 -9
- package/dist/cli.js +793 -284
- package/dist/scopes-map.json +25 -1
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@datarails-ai/dr-cli",
|
|
11
|
-
version: "1.6.
|
|
11
|
+
version: "1.6.74",
|
|
12
12
|
description: "Datarails CLI",
|
|
13
13
|
type: "module",
|
|
14
14
|
engines: {
|
|
@@ -38,10 +38,11 @@ var package_default = {
|
|
|
38
38
|
postinstall: "node scripts/postinstall.mjs"
|
|
39
39
|
},
|
|
40
40
|
dependencies: {
|
|
41
|
-
"@datarails-ai/dr-appspace-cli": "0.9.
|
|
41
|
+
"@datarails-ai/dr-appspace-cli": "0.9.5",
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
43
43
|
"@napi-rs/keyring": "^1.3.0",
|
|
44
44
|
commander: "^12.1.0",
|
|
45
|
+
"fast-xml-parser": "^5.11.2",
|
|
45
46
|
jszip: "^3.10.1",
|
|
46
47
|
"node-html-parser": "^6.1.13",
|
|
47
48
|
open: "^10.1.0",
|
|
@@ -66,7 +67,7 @@ var package_default = {
|
|
|
66
67
|
};
|
|
67
68
|
|
|
68
69
|
// src/buildInfo.ts
|
|
69
|
-
var BUILD_TIME = "2026-09-
|
|
70
|
+
var BUILD_TIME = "2026-09-30T12:03:03.518Z";
|
|
70
71
|
function formatBuildTime(iso) {
|
|
71
72
|
if (iso === "") return "";
|
|
72
73
|
const d = new Date(iso);
|
|
@@ -577,11 +578,11 @@ var ScopeDeniedError = class extends Error {
|
|
|
577
578
|
return `${this.method} ${this.path}: this identity's credential scope does not allow it${needs}; run 'dr whoami' to see the scopes this identity carries`;
|
|
578
579
|
}
|
|
579
580
|
};
|
|
580
|
-
function parseScopeDenial(status2,
|
|
581
|
+
function parseScopeDenial(status2, text2) {
|
|
581
582
|
if (status2 !== 403) return void 0;
|
|
582
583
|
let body;
|
|
583
584
|
try {
|
|
584
|
-
body = JSON.parse(
|
|
585
|
+
body = JSON.parse(text2);
|
|
585
586
|
} catch {
|
|
586
587
|
return void 0;
|
|
587
588
|
}
|
|
@@ -698,10 +699,10 @@ function decodeJwtExpiration(token) {
|
|
|
698
699
|
}
|
|
699
700
|
return at;
|
|
700
701
|
}
|
|
701
|
-
function parseTokenBody(
|
|
702
|
+
function parseTokenBody(text2, label) {
|
|
702
703
|
let raw;
|
|
703
704
|
try {
|
|
704
|
-
raw = JSON.parse(
|
|
705
|
+
raw = JSON.parse(text2);
|
|
705
706
|
} catch (err) {
|
|
706
707
|
throw new Error(`jwt ${label} parse: ${msgOf3(err)}`);
|
|
707
708
|
}
|
|
@@ -727,11 +728,11 @@ async function mintJwt(host, sessionId, csrfToken, options) {
|
|
|
727
728
|
body: "{}",
|
|
728
729
|
signal: options?.signal
|
|
729
730
|
});
|
|
730
|
-
const
|
|
731
|
+
const text2 = await res.text();
|
|
731
732
|
if (!res.ok) {
|
|
732
|
-
throw new Error(`jwt mint: HTTP ${res.status}: ${truncate(
|
|
733
|
+
throw new Error(`jwt mint: HTTP ${res.status}: ${truncate(text2, TRUNCATE)}`);
|
|
733
734
|
}
|
|
734
|
-
const out = parseTokenBody(
|
|
735
|
+
const out = parseTokenBody(text2, "mint");
|
|
735
736
|
if (out.access === "") {
|
|
736
737
|
throw new Error("jwt mint: empty access token");
|
|
737
738
|
}
|
|
@@ -754,11 +755,11 @@ async function refreshJwt(host, refreshToken, options) {
|
|
|
754
755
|
body: JSON.stringify({ refresh: refreshToken }),
|
|
755
756
|
signal: options?.signal
|
|
756
757
|
});
|
|
757
|
-
const
|
|
758
|
+
const text2 = await res.text();
|
|
758
759
|
if (!res.ok) {
|
|
759
|
-
throw new Error(`jwt refresh: HTTP ${res.status}: ${truncate(
|
|
760
|
+
throw new Error(`jwt refresh: HTTP ${res.status}: ${truncate(text2, TRUNCATE)}`);
|
|
760
761
|
}
|
|
761
|
-
const out = parseTokenBody(
|
|
762
|
+
const out = parseTokenBody(text2, "refresh");
|
|
762
763
|
if (out.access === "") {
|
|
763
764
|
throw new Error("jwt refresh: empty access token");
|
|
764
765
|
}
|
|
@@ -778,11 +779,11 @@ async function refreshExternalJwt(host, refreshToken, options) {
|
|
|
778
779
|
body: JSON.stringify({ refresh: refreshToken }),
|
|
779
780
|
signal: options?.signal
|
|
780
781
|
});
|
|
781
|
-
const
|
|
782
|
+
const text2 = await res.text();
|
|
782
783
|
if (!res.ok) {
|
|
783
|
-
throw new Error(`jwt external refresh: HTTP ${res.status}: ${truncate(
|
|
784
|
+
throw new Error(`jwt external refresh: HTTP ${res.status}: ${truncate(text2, TRUNCATE)}`);
|
|
784
785
|
}
|
|
785
|
-
const out = parseTokenBody(
|
|
786
|
+
const out = parseTokenBody(text2, "refresh");
|
|
786
787
|
if (out.access === "") {
|
|
787
788
|
throw new Error("jwt external refresh: empty access token");
|
|
788
789
|
}
|
|
@@ -810,11 +811,11 @@ async function exchangeApiKey(host, apiKey, options) {
|
|
|
810
811
|
headers: { Authorization: `Bearer ${key}`, Accept: "application/json" },
|
|
811
812
|
signal: options?.signal
|
|
812
813
|
});
|
|
813
|
-
const
|
|
814
|
+
const text2 = await res.text();
|
|
814
815
|
if (!res.ok) {
|
|
815
816
|
let code;
|
|
816
817
|
try {
|
|
817
|
-
const value = JSON.parse(
|
|
818
|
+
const value = JSON.parse(text2)["error"];
|
|
818
819
|
if (value === "invalid_key" || value === "exchange_unavailable") code = value;
|
|
819
820
|
} catch {
|
|
820
821
|
}
|
|
@@ -822,7 +823,7 @@ async function exchangeApiKey(host, apiKey, options) {
|
|
|
822
823
|
}
|
|
823
824
|
let raw;
|
|
824
825
|
try {
|
|
825
|
-
raw = JSON.parse(
|
|
826
|
+
raw = JSON.parse(text2);
|
|
826
827
|
} catch {
|
|
827
828
|
throw new Error("api-key exchange parse: the response is not JSON");
|
|
828
829
|
}
|
|
@@ -871,21 +872,21 @@ async function loginAs(host, operatorAccessToken, userId, options) {
|
|
|
871
872
|
body: JSON.stringify(body),
|
|
872
873
|
signal: options?.signal
|
|
873
874
|
});
|
|
874
|
-
const
|
|
875
|
+
const text2 = await res.text();
|
|
875
876
|
if (!res.ok) {
|
|
876
877
|
let code;
|
|
877
878
|
let detail;
|
|
878
879
|
try {
|
|
879
|
-
const parsed2 = JSON.parse(
|
|
880
|
+
const parsed2 = JSON.parse(text2);
|
|
880
881
|
if (typeof parsed2["code"] === "string") code = parsed2["code"];
|
|
881
882
|
if (typeof parsed2["detail"] === "string") detail = parsed2["detail"];
|
|
882
883
|
} catch {
|
|
883
884
|
}
|
|
884
|
-
throw new LoginAsError(res.status, { code, detail, body: truncate(
|
|
885
|
+
throw new LoginAsError(res.status, { code, detail, body: truncate(text2, TRUNCATE) });
|
|
885
886
|
}
|
|
886
887
|
let raw;
|
|
887
888
|
try {
|
|
888
|
-
raw = JSON.parse(
|
|
889
|
+
raw = JSON.parse(text2);
|
|
889
890
|
} catch (err) {
|
|
890
891
|
throw new Error(`jwt loginas parse: ${msgOf3(err)}`);
|
|
891
892
|
}
|
|
@@ -2245,17 +2246,17 @@ var AuthorizedClient = class _AuthorizedClient {
|
|
|
2245
2246
|
body: fd,
|
|
2246
2247
|
signal: options?.signal
|
|
2247
2248
|
});
|
|
2248
|
-
const
|
|
2249
|
-
_AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status,
|
|
2249
|
+
const text2 = await res.text();
|
|
2250
|
+
_AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status, text2);
|
|
2250
2251
|
if (res.status === 401 || res.status === 403) {
|
|
2251
2252
|
throw new SessionExpiredError(`POST ${path11} (HTTP ${res.status})`);
|
|
2252
2253
|
}
|
|
2253
2254
|
if (res.status < 200 || res.status >= 300) {
|
|
2254
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(
|
|
2255
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
|
|
2255
2256
|
}
|
|
2256
|
-
if (
|
|
2257
|
+
if (text2 === "" || text2 === '""') return null;
|
|
2257
2258
|
try {
|
|
2258
|
-
return JSON.parse(
|
|
2259
|
+
return JSON.parse(text2);
|
|
2259
2260
|
} catch (err) {
|
|
2260
2261
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2261
2262
|
throw new Error(`POST ${path11}: decode: ${msg}`);
|
|
@@ -2296,17 +2297,17 @@ var AuthorizedClient = class _AuthorizedClient {
|
|
|
2296
2297
|
body: fd,
|
|
2297
2298
|
signal: options?.signal
|
|
2298
2299
|
});
|
|
2299
|
-
const
|
|
2300
|
-
_AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status,
|
|
2300
|
+
const text2 = await res.text();
|
|
2301
|
+
_AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status, text2);
|
|
2301
2302
|
if (res.status === 401 || res.status === 403) {
|
|
2302
2303
|
throw new SessionExpiredError(`POST ${path11} (HTTP ${res.status})`);
|
|
2303
2304
|
}
|
|
2304
2305
|
if (res.status < 200 || res.status >= 300) {
|
|
2305
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(
|
|
2306
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
|
|
2306
2307
|
}
|
|
2307
|
-
if (
|
|
2308
|
+
if (text2 === "" || text2 === '""') return null;
|
|
2308
2309
|
try {
|
|
2309
|
-
return JSON.parse(
|
|
2310
|
+
return JSON.parse(text2);
|
|
2310
2311
|
} catch (err) {
|
|
2311
2312
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2312
2313
|
throw new Error(`POST ${path11}: decode: ${msg}`);
|
|
@@ -2355,17 +2356,17 @@ var AuthorizedClient = class _AuthorizedClient {
|
|
|
2355
2356
|
body: fd,
|
|
2356
2357
|
signal: options?.signal
|
|
2357
2358
|
});
|
|
2358
|
-
const
|
|
2359
|
-
_AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status,
|
|
2359
|
+
const text2 = await res.text();
|
|
2360
|
+
_AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status, text2);
|
|
2360
2361
|
if (res.status === 401 || res.status === 403) {
|
|
2361
2362
|
throw new SessionExpiredError(`POST ${path11} (HTTP ${res.status})`);
|
|
2362
2363
|
}
|
|
2363
2364
|
if (res.status < 200 || res.status >= 300) {
|
|
2364
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(
|
|
2365
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
|
|
2365
2366
|
}
|
|
2366
|
-
if (
|
|
2367
|
+
if (text2 === "" || text2 === '""') return null;
|
|
2367
2368
|
try {
|
|
2368
|
-
return JSON.parse(
|
|
2369
|
+
return JSON.parse(text2);
|
|
2369
2370
|
} catch (err) {
|
|
2370
2371
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2371
2372
|
throw new Error(`POST ${path11}: decode: ${msg}`);
|
|
@@ -2426,12 +2427,12 @@ var AuthorizedClient = class _AuthorizedClient {
|
|
|
2426
2427
|
}
|
|
2427
2428
|
}
|
|
2428
2429
|
if (this.isAuthRejected(res)) {
|
|
2429
|
-
const
|
|
2430
|
-
_AuthorizedClient.throwIfScopeDeniedBody(method, path11, res.status,
|
|
2430
|
+
const text3 = await res.text();
|
|
2431
|
+
_AuthorizedClient.throwIfScopeDeniedBody(method, path11, res.status, text3);
|
|
2431
2432
|
if (refreshed || triedSessionOnly) {
|
|
2432
2433
|
const attempted = refreshed ? "session-only retry and JWT refresh" : "session-only retry";
|
|
2433
2434
|
throw new Error(
|
|
2434
|
-
`${method} ${path11}: HTTP ${res.status} after ${attempted} (authenticated, but endpoint rejected \u2014 check permissions, tenant/org context, or body): ${truncate2(
|
|
2435
|
+
`${method} ${path11}: HTTP ${res.status} after ${attempted} (authenticated, but endpoint rejected \u2014 check permissions, tenant/org context, or body): ${truncate2(text3, 200)}`
|
|
2435
2436
|
);
|
|
2436
2437
|
}
|
|
2437
2438
|
if (refreshErr !== void 0) {
|
|
@@ -2440,17 +2441,17 @@ var AuthorizedClient = class _AuthorizedClient {
|
|
|
2440
2441
|
}
|
|
2441
2442
|
throw new SessionExpiredError(`${method} ${path11} (HTTP ${res.status})`);
|
|
2442
2443
|
}
|
|
2443
|
-
const
|
|
2444
|
+
const text2 = await res.text();
|
|
2444
2445
|
if (res.status < 200 || res.status >= 300) {
|
|
2445
|
-
throw new Error(`${method} ${path11}: HTTP ${res.status}: ${truncate2(
|
|
2446
|
+
throw new Error(`${method} ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
|
|
2446
2447
|
}
|
|
2447
2448
|
try {
|
|
2448
2449
|
await this._store.touch(this._serverKey, this._email);
|
|
2449
2450
|
} catch {
|
|
2450
2451
|
}
|
|
2451
|
-
if (
|
|
2452
|
+
if (text2 === "" || text2 === '""') return null;
|
|
2452
2453
|
try {
|
|
2453
|
-
return JSON.parse(
|
|
2454
|
+
return JSON.parse(text2);
|
|
2454
2455
|
} catch (err) {
|
|
2455
2456
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2456
2457
|
throw new Error(`${method} ${path11}: decode: ${msg}`);
|
|
@@ -2522,18 +2523,18 @@ var AuthorizedClient = class _AuthorizedClient {
|
|
|
2522
2523
|
*/
|
|
2523
2524
|
static async throwIfScopeDenied(method, path11, res) {
|
|
2524
2525
|
if (res.status !== 403) return;
|
|
2525
|
-
let
|
|
2526
|
+
let text2;
|
|
2526
2527
|
try {
|
|
2527
|
-
|
|
2528
|
+
text2 = await res.clone().text();
|
|
2528
2529
|
} catch {
|
|
2529
2530
|
return;
|
|
2530
2531
|
}
|
|
2531
|
-
_AuthorizedClient.throwIfScopeDeniedBody(method, path11, res.status,
|
|
2532
|
+
_AuthorizedClient.throwIfScopeDeniedBody(method, path11, res.status, text2);
|
|
2532
2533
|
}
|
|
2533
2534
|
/** {@link AuthorizedClient.throwIfScopeDenied} for a body already in hand — the multipart
|
|
2534
2535
|
* methods and `requestJson`'s final branch have read theirs and must not read it twice. */
|
|
2535
|
-
static throwIfScopeDeniedBody(method, path11, status2,
|
|
2536
|
-
const denial = parseScopeDenial(status2,
|
|
2536
|
+
static throwIfScopeDeniedBody(method, path11, status2, text2) {
|
|
2537
|
+
const denial = parseScopeDenial(status2, text2);
|
|
2537
2538
|
if (denial !== void 0) throw new ScopeDeniedError(method, path11, denial.code);
|
|
2538
2539
|
}
|
|
2539
2540
|
/** True iff `res` is the auth-rejection signal (401 or 403). */
|
|
@@ -3424,9 +3425,9 @@ async function commandExists(cmd) {
|
|
|
3424
3425
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
3425
3426
|
return new Promise((resolve3) => {
|
|
3426
3427
|
try {
|
|
3427
|
-
const
|
|
3428
|
-
|
|
3429
|
-
|
|
3428
|
+
const child2 = spawn(probe, [cmd], { stdio: "ignore" });
|
|
3429
|
+
child2.on("error", () => resolve3(false));
|
|
3430
|
+
child2.on("close", (code) => resolve3(code === 0));
|
|
3430
3431
|
} catch {
|
|
3431
3432
|
resolve3(false);
|
|
3432
3433
|
}
|
|
@@ -3446,20 +3447,20 @@ async function realEnv() {
|
|
|
3446
3447
|
}
|
|
3447
3448
|
function spawnCapture(cmd, args) {
|
|
3448
3449
|
return new Promise((resolve3, reject) => {
|
|
3449
|
-
const
|
|
3450
|
+
const child2 = spawn(cmd, args, {
|
|
3450
3451
|
stdio: ["ignore", "pipe", "pipe"],
|
|
3451
3452
|
windowsHide: false
|
|
3452
3453
|
});
|
|
3453
3454
|
let stdout = "";
|
|
3454
3455
|
let stderr = "";
|
|
3455
|
-
|
|
3456
|
+
child2.stdout.on("data", (c) => {
|
|
3456
3457
|
stdout += c.toString("utf8");
|
|
3457
3458
|
});
|
|
3458
|
-
|
|
3459
|
+
child2.stderr.on("data", (c) => {
|
|
3459
3460
|
stderr += c.toString("utf8");
|
|
3460
3461
|
});
|
|
3461
|
-
|
|
3462
|
-
|
|
3462
|
+
child2.on("error", reject);
|
|
3463
|
+
child2.on("close", (code) => resolve3({ code: code ?? 0, stdout, stderr }));
|
|
3463
3464
|
});
|
|
3464
3465
|
}
|
|
3465
3466
|
function ttyPrompt(spec, io = { input: process.stdin, output: process.stderr }) {
|
|
@@ -4362,6 +4363,7 @@ async function setupCall(serverFlag, accountFlag, options = {}) {
|
|
|
4362
4363
|
let deadline = Date.now() + timeoutMs;
|
|
4363
4364
|
let timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
4364
4365
|
let cleared = false;
|
|
4366
|
+
let paused = false;
|
|
4365
4367
|
let client;
|
|
4366
4368
|
try {
|
|
4367
4369
|
client = await AuthorizedClient.create(store, key, email, {
|
|
@@ -4388,11 +4390,17 @@ async function setupCall(serverFlag, accountFlag, options = {}) {
|
|
|
4388
4390
|
if (cleared || controller.signal.aborted) return;
|
|
4389
4391
|
if (!Number.isFinite(ms) || ms <= 0) return;
|
|
4390
4392
|
const next = Date.now() + ms;
|
|
4391
|
-
if (next <= deadline) return;
|
|
4393
|
+
if (!paused && next <= deadline) return;
|
|
4394
|
+
paused = false;
|
|
4392
4395
|
clearTimeout(timer);
|
|
4393
4396
|
deadline = next;
|
|
4394
4397
|
timer = setTimeout(() => controller.abort(), ms);
|
|
4395
4398
|
},
|
|
4399
|
+
pauseTimeout: () => {
|
|
4400
|
+
if (cleared || controller.signal.aborted) return;
|
|
4401
|
+
paused = true;
|
|
4402
|
+
clearTimeout(timer);
|
|
4403
|
+
},
|
|
4396
4404
|
cleanup: () => {
|
|
4397
4405
|
if (cleared) return;
|
|
4398
4406
|
cleared = true;
|
|
@@ -4589,10 +4597,10 @@ function parsePendingCommands(v, pending) {
|
|
|
4589
4597
|
}
|
|
4590
4598
|
return out;
|
|
4591
4599
|
}
|
|
4592
|
-
function parseScopesMap(
|
|
4600
|
+
function parseScopesMap(text2) {
|
|
4593
4601
|
let raw;
|
|
4594
4602
|
try {
|
|
4595
|
-
raw = JSON.parse(
|
|
4603
|
+
raw = JSON.parse(text2);
|
|
4596
4604
|
} catch {
|
|
4597
4605
|
return void 0;
|
|
4598
4606
|
}
|
|
@@ -4626,13 +4634,13 @@ function parseScopesMap(text) {
|
|
|
4626
4634
|
return map;
|
|
4627
4635
|
}
|
|
4628
4636
|
function loadScopesMap(here = path3.dirname(fileURLToPath(import.meta.url))) {
|
|
4629
|
-
let
|
|
4637
|
+
let text2;
|
|
4630
4638
|
try {
|
|
4631
|
-
|
|
4639
|
+
text2 = readFileSync(path3.join(here, "scopes-map.json"), "utf8");
|
|
4632
4640
|
} catch {
|
|
4633
4641
|
return void 0;
|
|
4634
4642
|
}
|
|
4635
|
-
return parseScopesMap(
|
|
4643
|
+
return parseScopesMap(text2);
|
|
4636
4644
|
}
|
|
4637
4645
|
function scopesMapKey(cmd) {
|
|
4638
4646
|
const names = [];
|
|
@@ -4652,10 +4660,10 @@ function commandPathOf(argv, root) {
|
|
|
4652
4660
|
if (takesValue(token, cmd)) i += 1;
|
|
4653
4661
|
continue;
|
|
4654
4662
|
}
|
|
4655
|
-
const
|
|
4656
|
-
if (
|
|
4657
|
-
names.push(
|
|
4658
|
-
cmd =
|
|
4663
|
+
const child2 = childNamed(cmd, token);
|
|
4664
|
+
if (child2 === void 0) break;
|
|
4665
|
+
names.push(child2.name());
|
|
4666
|
+
cmd = child2;
|
|
4659
4667
|
}
|
|
4660
4668
|
return names.join(" ");
|
|
4661
4669
|
}
|
|
@@ -4672,11 +4680,11 @@ function takesValue(flag, cmd) {
|
|
|
4672
4680
|
return declaredWithValueBelow(flag, cmd);
|
|
4673
4681
|
}
|
|
4674
4682
|
function declaredWithValueBelow(flag, cmd) {
|
|
4675
|
-
for (const
|
|
4676
|
-
for (const opt of
|
|
4683
|
+
for (const child2 of cmd.commands) {
|
|
4684
|
+
for (const opt of child2.options) {
|
|
4677
4685
|
if ((opt.short === flag || opt.long === flag) && (opt.required || opt.optional)) return true;
|
|
4678
4686
|
}
|
|
4679
|
-
if (declaredWithValueBelow(flag,
|
|
4687
|
+
if (declaredWithValueBelow(flag, child2)) return true;
|
|
4680
4688
|
}
|
|
4681
4689
|
return false;
|
|
4682
4690
|
}
|
|
@@ -5011,14 +5019,14 @@ async function requestDeviceCode(host, options) {
|
|
|
5011
5019
|
body: body.toString(),
|
|
5012
5020
|
signal: options?.signal
|
|
5013
5021
|
});
|
|
5014
|
-
const
|
|
5022
|
+
const text2 = await res.text();
|
|
5015
5023
|
if (!res.ok) {
|
|
5016
5024
|
const hint = flow === "v2" && res.status === 429 ? " (too many logins from this address: wait a minute and run `dr login` again)" : "";
|
|
5017
|
-
throw new Error(`device/code failed: ${res.status} ${
|
|
5025
|
+
throw new Error(`device/code failed: ${res.status} ${text2.trim()}${hint}`);
|
|
5018
5026
|
}
|
|
5019
5027
|
let raw;
|
|
5020
5028
|
try {
|
|
5021
|
-
raw = JSON.parse(
|
|
5029
|
+
raw = JSON.parse(text2);
|
|
5022
5030
|
} catch (err) {
|
|
5023
5031
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5024
5032
|
throw new Error(`device/code parse: ${msg}`);
|
|
@@ -5049,10 +5057,10 @@ var defaultSleep = (ms, signal) => new Promise((resolve3, reject) => {
|
|
|
5049
5057
|
{ once: true }
|
|
5050
5058
|
);
|
|
5051
5059
|
});
|
|
5052
|
-
function parseObject(
|
|
5060
|
+
function parseObject(text2) {
|
|
5053
5061
|
let raw;
|
|
5054
5062
|
try {
|
|
5055
|
-
raw = JSON.parse(
|
|
5063
|
+
raw = JSON.parse(text2);
|
|
5056
5064
|
} catch (err) {
|
|
5057
5065
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5058
5066
|
throw new Error(`token parse: ${msg}`);
|
|
@@ -5062,8 +5070,8 @@ function parseObject(text) {
|
|
|
5062
5070
|
}
|
|
5063
5071
|
return raw;
|
|
5064
5072
|
}
|
|
5065
|
-
function parseTokenResponse(
|
|
5066
|
-
const obj = parseObject(
|
|
5073
|
+
function parseTokenResponse(text2) {
|
|
5074
|
+
const obj = parseObject(text2);
|
|
5067
5075
|
const tok = {
|
|
5068
5076
|
sessionId: typeof obj.session_id === "string" ? obj.session_id : "",
|
|
5069
5077
|
csrfToken: typeof obj.csrf_token === "string" ? obj.csrf_token : ""
|
|
@@ -5073,10 +5081,10 @@ function parseTokenResponse(text) {
|
|
|
5073
5081
|
}
|
|
5074
5082
|
return tok;
|
|
5075
5083
|
}
|
|
5076
|
-
function tryParseErrorCode(
|
|
5084
|
+
function tryParseErrorCode(text2) {
|
|
5077
5085
|
let raw;
|
|
5078
5086
|
try {
|
|
5079
|
-
raw = JSON.parse(
|
|
5087
|
+
raw = JSON.parse(text2);
|
|
5080
5088
|
} catch {
|
|
5081
5089
|
return "";
|
|
5082
5090
|
}
|
|
@@ -5085,8 +5093,8 @@ function tryParseErrorCode(text) {
|
|
|
5085
5093
|
return typeof errVal === "string" ? errVal : "";
|
|
5086
5094
|
}
|
|
5087
5095
|
async function pollForToken(host, deviceCode, options = {}) {
|
|
5088
|
-
return poll(host, PATHS.legacy.token, deviceCode, options, (
|
|
5089
|
-
const tok = parseTokenResponse(
|
|
5096
|
+
return poll(host, PATHS.legacy.token, deviceCode, options, (text2) => {
|
|
5097
|
+
const tok = parseTokenResponse(text2);
|
|
5090
5098
|
if (!tok.sessionId || !tok.csrfToken) {
|
|
5091
5099
|
throw new Error("token response missing session_id or csrf_token");
|
|
5092
5100
|
}
|
|
@@ -5094,8 +5102,8 @@ async function pollForToken(host, deviceCode, options = {}) {
|
|
|
5094
5102
|
});
|
|
5095
5103
|
}
|
|
5096
5104
|
async function pollForV2Token(host, deviceCode, options = {}) {
|
|
5097
|
-
return poll(host, PATHS.v2.token, deviceCode, options, (
|
|
5098
|
-
const obj = parseObject(
|
|
5105
|
+
return poll(host, PATHS.v2.token, deviceCode, options, (text2) => {
|
|
5106
|
+
const obj = parseObject(text2);
|
|
5099
5107
|
const access = typeof obj.access === "string" ? obj.access : "";
|
|
5100
5108
|
const refresh = typeof obj.refresh === "string" ? obj.refresh : "";
|
|
5101
5109
|
if (access === "" || refresh === "") {
|
|
@@ -5130,11 +5138,11 @@ async function poll(host, path11, deviceCode, options, onSuccess) {
|
|
|
5130
5138
|
body: body.toString(),
|
|
5131
5139
|
signal
|
|
5132
5140
|
});
|
|
5133
|
-
const
|
|
5141
|
+
const text2 = await res.text();
|
|
5134
5142
|
if (res.ok) {
|
|
5135
|
-
return onSuccess(
|
|
5143
|
+
return onSuccess(text2);
|
|
5136
5144
|
}
|
|
5137
|
-
const errCode = tryParseErrorCode(
|
|
5145
|
+
const errCode = tryParseErrorCode(text2);
|
|
5138
5146
|
if (errCode === "authorization_pending" || errCode === "slow_down") {
|
|
5139
5147
|
await sleep3(interval, signal);
|
|
5140
5148
|
continue;
|
|
@@ -5142,7 +5150,7 @@ async function poll(host, path11, deviceCode, options, onSuccess) {
|
|
|
5142
5150
|
if (errCode) {
|
|
5143
5151
|
throw new Error(`token error: ${errCode}`);
|
|
5144
5152
|
}
|
|
5145
|
-
throw new Error(`token HTTP ${res.status}: ${
|
|
5153
|
+
throw new Error(`token HTTP ${res.status}: ${text2.trim()}`);
|
|
5146
5154
|
}
|
|
5147
5155
|
}
|
|
5148
5156
|
|
|
@@ -5642,11 +5650,11 @@ var UserExistsError = class extends Error {
|
|
|
5642
5650
|
async function create(client, payload, options) {
|
|
5643
5651
|
const path11 = "/api/it/users";
|
|
5644
5652
|
const res = await client.do("POST", path11, JSON.stringify(payload), options);
|
|
5645
|
-
const
|
|
5653
|
+
const text2 = await res.text();
|
|
5646
5654
|
if (res.status >= 200 && res.status < 300) {
|
|
5647
5655
|
let parsed2;
|
|
5648
5656
|
try {
|
|
5649
|
-
parsed2 = JSON.parse(
|
|
5657
|
+
parsed2 = JSON.parse(text2);
|
|
5650
5658
|
} catch (err) {
|
|
5651
5659
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5652
5660
|
throw new Error(`POST ${path11}: decode: ${msg}`);
|
|
@@ -5664,7 +5672,7 @@ async function create(client, payload, options) {
|
|
|
5664
5672
|
if (res.status === 400) {
|
|
5665
5673
|
let details;
|
|
5666
5674
|
try {
|
|
5667
|
-
const body = JSON.parse(
|
|
5675
|
+
const body = JSON.parse(text2);
|
|
5668
5676
|
if (typeof body.details === "string") details = body.details;
|
|
5669
5677
|
} catch {
|
|
5670
5678
|
}
|
|
@@ -5672,23 +5680,23 @@ async function create(client, payload, options) {
|
|
|
5672
5680
|
throw new UserExistsError(payload.email);
|
|
5673
5681
|
}
|
|
5674
5682
|
}
|
|
5675
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5683
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5676
5684
|
}
|
|
5677
5685
|
async function registerIdentity(client, id, options) {
|
|
5678
5686
|
const path11 = `/api/it/users/${id}/register_identity`;
|
|
5679
5687
|
const res = await client.do("PUT", path11, void 0, options);
|
|
5680
|
-
const
|
|
5688
|
+
const text2 = await res.text();
|
|
5681
5689
|
if (res.status >= 200 && res.status < 300) {
|
|
5682
5690
|
let body;
|
|
5683
5691
|
try {
|
|
5684
|
-
body = JSON.parse(
|
|
5692
|
+
body = JSON.parse(text2);
|
|
5685
5693
|
} catch (err) {
|
|
5686
5694
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5687
5695
|
throw new Error(`PUT ${path11}: decode: ${msg}`);
|
|
5688
5696
|
}
|
|
5689
5697
|
if (typeof body.sent !== "boolean") {
|
|
5690
5698
|
throw new Error(
|
|
5691
|
-
`PUT ${path11}: expected a boolean "sent" in the 2xx body, got ${truncate4(
|
|
5699
|
+
`PUT ${path11}: expected a boolean "sent" in the 2xx body, got ${truncate4(text2, 200)}`
|
|
5692
5700
|
);
|
|
5693
5701
|
}
|
|
5694
5702
|
return body.sent ? { status: "registered" } : { status: "already_exists" };
|
|
@@ -5696,42 +5704,42 @@ async function registerIdentity(client, id, options) {
|
|
|
5696
5704
|
if (res.status === 502) {
|
|
5697
5705
|
let reason;
|
|
5698
5706
|
try {
|
|
5699
|
-
const body = JSON.parse(
|
|
5707
|
+
const body = JSON.parse(text2);
|
|
5700
5708
|
if (typeof body.reason === "string") reason = body.reason;
|
|
5701
5709
|
} catch {
|
|
5702
5710
|
}
|
|
5703
5711
|
return { status: "failed", ...reason !== void 0 ? { reason } : {} };
|
|
5704
5712
|
}
|
|
5705
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5713
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5706
5714
|
}
|
|
5707
5715
|
async function assignPermissionGroups(client, id, groupIds, options) {
|
|
5708
5716
|
const path11 = `/api/it/users/${id}/permission_groups`;
|
|
5709
5717
|
const body = JSON.stringify({ permission_groups: groupIds });
|
|
5710
5718
|
const res = await client.do("POST", path11, body, options);
|
|
5711
|
-
const
|
|
5719
|
+
const text2 = await res.text();
|
|
5712
5720
|
if (res.status >= 200 && res.status < 300) {
|
|
5713
5721
|
return;
|
|
5714
5722
|
}
|
|
5715
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5723
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5716
5724
|
}
|
|
5717
5725
|
async function updateUserRole(client, id, role, options) {
|
|
5718
5726
|
const path11 = `/api/it/users/${id}/permissions`;
|
|
5719
5727
|
const body = JSON.stringify({ role });
|
|
5720
5728
|
const res = await client.do("PUT", path11, body, options);
|
|
5721
|
-
const
|
|
5729
|
+
const text2 = await res.text();
|
|
5722
5730
|
if (res.status >= 200 && res.status < 300) {
|
|
5723
5731
|
return;
|
|
5724
5732
|
}
|
|
5725
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5733
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5726
5734
|
}
|
|
5727
5735
|
async function removePermissionGroup(client, id, groupId, options) {
|
|
5728
5736
|
const path11 = `/api/it/users/${id}/permission_groups/${groupId}`;
|
|
5729
5737
|
const res = await client.do("DELETE", path11, void 0, options);
|
|
5730
|
-
const
|
|
5738
|
+
const text2 = await res.text();
|
|
5731
5739
|
if (res.status >= 200 && res.status < 300) {
|
|
5732
5740
|
return;
|
|
5733
5741
|
}
|
|
5734
|
-
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5742
|
+
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5735
5743
|
}
|
|
5736
5744
|
var PasswordValidationError = class extends Error {
|
|
5737
5745
|
errors;
|
|
@@ -5751,11 +5759,11 @@ async function setPassword(client, id, password, options) {
|
|
|
5751
5759
|
await res.text();
|
|
5752
5760
|
return;
|
|
5753
5761
|
}
|
|
5754
|
-
const
|
|
5762
|
+
const text2 = await res.text();
|
|
5755
5763
|
if (res.status === 400) {
|
|
5756
5764
|
let parsed2;
|
|
5757
5765
|
try {
|
|
5758
|
-
parsed2 = JSON.parse(
|
|
5766
|
+
parsed2 = JSON.parse(text2);
|
|
5759
5767
|
} catch {
|
|
5760
5768
|
}
|
|
5761
5769
|
if (typeof parsed2 === "object" && parsed2 !== null && "password" in parsed2 && Array.isArray(parsed2.password)) {
|
|
@@ -5764,7 +5772,7 @@ async function setPassword(client, id, password, options) {
|
|
|
5764
5772
|
throw new PasswordValidationError(messages);
|
|
5765
5773
|
}
|
|
5766
5774
|
}
|
|
5767
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5775
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5768
5776
|
}
|
|
5769
5777
|
var EmailInUseError = class extends Error {
|
|
5770
5778
|
email;
|
|
@@ -5782,14 +5790,14 @@ async function updateUserEmail(client, id, newEmail, options) {
|
|
|
5782
5790
|
excel_online_email: current.profile?.excel_online_email ?? null
|
|
5783
5791
|
});
|
|
5784
5792
|
const res = await client.do("PUT", path11, body, options);
|
|
5785
|
-
const
|
|
5793
|
+
const text2 = await res.text();
|
|
5786
5794
|
if (res.status >= 200 && res.status < 300) {
|
|
5787
5795
|
return { id, email: newEmail, previousEmail: current.email };
|
|
5788
5796
|
}
|
|
5789
|
-
if (res.status === 400 && /already in use/i.test(
|
|
5797
|
+
if (res.status === 400 && /already in use/i.test(text2)) {
|
|
5790
5798
|
throw new EmailInUseError(newEmail);
|
|
5791
5799
|
}
|
|
5792
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5800
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5793
5801
|
}
|
|
5794
5802
|
var StoredEmailInvalidError = class extends Error {
|
|
5795
5803
|
id;
|
|
@@ -5813,7 +5821,7 @@ async function setEmailNotifications(client, id, enabled, options) {
|
|
|
5813
5821
|
excel_online_email: current.profile?.excel_online_email ?? null
|
|
5814
5822
|
});
|
|
5815
5823
|
const res = await client.do("PUT", path11, body, options);
|
|
5816
|
-
const
|
|
5824
|
+
const text2 = await res.text();
|
|
5817
5825
|
if (res.status >= 200 && res.status < 300) {
|
|
5818
5826
|
return {
|
|
5819
5827
|
id,
|
|
@@ -5822,10 +5830,10 @@ async function setEmailNotifications(client, id, enabled, options) {
|
|
|
5822
5830
|
blocked: current.profile?.is_blocked === true
|
|
5823
5831
|
};
|
|
5824
5832
|
}
|
|
5825
|
-
if (res.status === 400 && /valid email address/i.test(
|
|
5833
|
+
if (res.status === 400 && /valid email address/i.test(text2)) {
|
|
5826
5834
|
throw new StoredEmailInvalidError(id, current.email);
|
|
5827
5835
|
}
|
|
5828
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(
|
|
5836
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
5829
5837
|
}
|
|
5830
5838
|
async function getCanLoginAs(client, params = {}, options) {
|
|
5831
5839
|
const qs = new URLSearchParams();
|
|
@@ -7063,66 +7071,66 @@ async function listPermissionGroups(client, options) {
|
|
|
7063
7071
|
async function createPermissionGroup(client, payload, options) {
|
|
7064
7072
|
const path11 = "/api/it/permission_groups";
|
|
7065
7073
|
const res = await client.do("POST", path11, JSON.stringify(payload), options);
|
|
7066
|
-
const
|
|
7074
|
+
const text2 = await res.text();
|
|
7067
7075
|
if (res.status < 200 || res.status >= 300) {
|
|
7068
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(
|
|
7076
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
7069
7077
|
}
|
|
7070
|
-
return parsePermissionGroup("POST", path11,
|
|
7078
|
+
return parsePermissionGroup("POST", path11, text2);
|
|
7071
7079
|
}
|
|
7072
|
-
function parsePermissionGroup(method, path11,
|
|
7080
|
+
function parsePermissionGroup(method, path11, text2) {
|
|
7073
7081
|
try {
|
|
7074
|
-
return JSON.parse(
|
|
7082
|
+
return JSON.parse(text2);
|
|
7075
7083
|
} catch (err) {
|
|
7076
7084
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7077
|
-
throw new Error(`${method} ${path11}: decode: ${msg} (body: ${truncate4(
|
|
7085
|
+
throw new Error(`${method} ${path11}: decode: ${msg} (body: ${truncate4(text2, 200)})`);
|
|
7078
7086
|
}
|
|
7079
7087
|
}
|
|
7080
7088
|
async function getPermissionGroup(client, id, options) {
|
|
7081
7089
|
const path11 = `/api/it/permission_groups/${id}`;
|
|
7082
7090
|
const res = await client.do("GET", path11, void 0, options);
|
|
7083
|
-
const
|
|
7091
|
+
const text2 = await res.text();
|
|
7084
7092
|
if (res.status < 200 || res.status >= 300) {
|
|
7085
|
-
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncate4(
|
|
7093
|
+
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
7086
7094
|
}
|
|
7087
|
-
return parsePermissionGroup("GET", path11,
|
|
7095
|
+
return parsePermissionGroup("GET", path11, text2);
|
|
7088
7096
|
}
|
|
7089
7097
|
async function updatePermissionGroup(client, id, name, options) {
|
|
7090
7098
|
const path11 = `/api/it/permission_groups/${id}`;
|
|
7091
7099
|
const res = await client.do("PUT", path11, JSON.stringify({ name }), options);
|
|
7092
|
-
const
|
|
7100
|
+
const text2 = await res.text();
|
|
7093
7101
|
if (res.status < 200 || res.status >= 300) {
|
|
7094
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(
|
|
7102
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
7095
7103
|
}
|
|
7096
|
-
return parsePermissionGroup("PUT", path11,
|
|
7104
|
+
return parsePermissionGroup("PUT", path11, text2);
|
|
7097
7105
|
}
|
|
7098
7106
|
async function deletePermissionGroup(client, id, options) {
|
|
7099
7107
|
const path11 = `/api/it/permission_groups/${id}`;
|
|
7100
7108
|
const res = await client.do("DELETE", path11, void 0, options);
|
|
7101
7109
|
if (res.status < 200 || res.status >= 300) {
|
|
7102
|
-
const
|
|
7103
|
-
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncate4(
|
|
7110
|
+
const text2 = await res.text();
|
|
7111
|
+
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
7104
7112
|
}
|
|
7105
7113
|
}
|
|
7106
|
-
function decodeJsonBody(method, path11,
|
|
7114
|
+
function decodeJsonBody(method, path11, text2) {
|
|
7107
7115
|
try {
|
|
7108
|
-
return JSON.parse(
|
|
7116
|
+
return JSON.parse(text2);
|
|
7109
7117
|
} catch (err) {
|
|
7110
7118
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7111
|
-
throw new Error(`${method} ${path11}: decode: ${msg} (body: ${truncate4(
|
|
7119
|
+
throw new Error(`${method} ${path11}: decode: ${msg} (body: ${truncate4(text2, 200)})`);
|
|
7112
7120
|
}
|
|
7113
7121
|
}
|
|
7114
|
-
function redactPasswordsInBodyText(
|
|
7115
|
-
return
|
|
7122
|
+
function redactPasswordsInBodyText(text2) {
|
|
7123
|
+
return text2.replace(/"password"\s*:\s*"(?:[^"\\]|\\.)*"/g, '"password":"[redacted]"');
|
|
7116
7124
|
}
|
|
7117
7125
|
async function orgMigrationRequest(client, method, path11, payload, options) {
|
|
7118
7126
|
const res = await client.do(method, path11, JSON.stringify(payload), options);
|
|
7119
|
-
const
|
|
7127
|
+
const text2 = await res.text();
|
|
7120
7128
|
if (res.status < 200 || res.status >= 300) {
|
|
7121
7129
|
throw new Error(
|
|
7122
|
-
`${method} ${path11}: HTTP ${res.status}: ${truncate4(redactPasswordsInBodyText(
|
|
7130
|
+
`${method} ${path11}: HTTP ${res.status}: ${truncate4(redactPasswordsInBodyText(text2), 600)}`
|
|
7123
7131
|
);
|
|
7124
7132
|
}
|
|
7125
|
-
return decodeJsonBody(method, path11,
|
|
7133
|
+
return decodeJsonBody(method, path11, text2);
|
|
7126
7134
|
}
|
|
7127
7135
|
async function exportCreate(client, payload, options) {
|
|
7128
7136
|
return orgMigrationRequest(
|
|
@@ -7165,8 +7173,8 @@ async function importDeleteOrgs(client, payload, options) {
|
|
|
7165
7173
|
import { promises as fs4 } from "fs";
|
|
7166
7174
|
|
|
7167
7175
|
// src/commands/_csv.ts
|
|
7168
|
-
function parseCsvRows(
|
|
7169
|
-
const normalized =
|
|
7176
|
+
function parseCsvRows(text2) {
|
|
7177
|
+
const normalized = text2.replace(/\r\n/g, "\n").replace(/\n$/, "");
|
|
7170
7178
|
if (normalized === "") return [];
|
|
7171
7179
|
const rows = [];
|
|
7172
7180
|
let row = [];
|
|
@@ -7216,6 +7224,9 @@ function parseCsvRows(text) {
|
|
|
7216
7224
|
rows.push(row);
|
|
7217
7225
|
return rows;
|
|
7218
7226
|
}
|
|
7227
|
+
function formatCsvRow(cells) {
|
|
7228
|
+
return cells.map((c) => /[",\r\n]/.test(c) ? `"${c.replace(/"/g, '""')}"` : c).join(",");
|
|
7229
|
+
}
|
|
7219
7230
|
|
|
7220
7231
|
// src/commands/_userCsv.ts
|
|
7221
7232
|
var EXPECTED_HEADER = [
|
|
@@ -7245,8 +7256,8 @@ async function readUsersCsv(path11) {
|
|
|
7245
7256
|
}
|
|
7246
7257
|
return parseUsersCsvText(raw);
|
|
7247
7258
|
}
|
|
7248
|
-
function parseUsersCsvText(
|
|
7249
|
-
const withoutBom =
|
|
7259
|
+
function parseUsersCsvText(text2) {
|
|
7260
|
+
const withoutBom = text2.charCodeAt(0) === 65279 ? text2.slice(1) : text2;
|
|
7250
7261
|
const rows = parseCsvRows(withoutBom);
|
|
7251
7262
|
if (rows.length === 0) {
|
|
7252
7263
|
throw new Error("--file: CSV is empty");
|
|
@@ -7420,11 +7431,11 @@ async function getRoles(client, segment, options) {
|
|
|
7420
7431
|
async function grantRoleToUsers(client, appSegment, payload, options) {
|
|
7421
7432
|
const path11 = `/api/${appSegment}/users/grant_permissions_bulk`;
|
|
7422
7433
|
const res = await client.do("POST", path11, JSON.stringify(payload), options);
|
|
7423
|
-
const
|
|
7434
|
+
const text2 = await res.text();
|
|
7424
7435
|
if (res.status >= 200 && res.status < 300) {
|
|
7425
7436
|
return;
|
|
7426
7437
|
}
|
|
7427
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(
|
|
7438
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
7428
7439
|
}
|
|
7429
7440
|
async function getUserTableRoles(client, userId, options) {
|
|
7430
7441
|
const out = await client.getJSON(
|
|
@@ -7444,11 +7455,11 @@ async function setUserPermissionFilters(client, userId, newFilters, options) {
|
|
|
7444
7455
|
const path11 = `/api/it/users/${userId}/permission_filters`;
|
|
7445
7456
|
const body = JSON.stringify({ new_filters: newFilters });
|
|
7446
7457
|
const res = await client.do("POST", path11, body, options);
|
|
7447
|
-
const
|
|
7458
|
+
const text2 = await res.text();
|
|
7448
7459
|
if (res.status >= 200 && res.status < 300) {
|
|
7449
7460
|
return;
|
|
7450
7461
|
}
|
|
7451
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(
|
|
7462
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
|
|
7452
7463
|
}
|
|
7453
7464
|
async function getTableRoles(client, options) {
|
|
7454
7465
|
return getRoles(client, "table", options);
|
|
@@ -8155,8 +8166,8 @@ async function readPermissionsCsv(path11) {
|
|
|
8155
8166
|
}
|
|
8156
8167
|
return parsePermissionsCsvText(raw);
|
|
8157
8168
|
}
|
|
8158
|
-
function parsePermissionsCsvText(
|
|
8159
|
-
const withoutBom =
|
|
8169
|
+
function parsePermissionsCsvText(text2) {
|
|
8170
|
+
const withoutBom = text2.charCodeAt(0) === 65279 ? text2.slice(1) : text2;
|
|
8160
8171
|
const rows = parseCsvRows(withoutBom);
|
|
8161
8172
|
if (rows.length === 0) {
|
|
8162
8173
|
throw new Error("--file: CSV is empty");
|
|
@@ -8589,8 +8600,8 @@ async function readEmailRenameCsv(path11) {
|
|
|
8589
8600
|
}
|
|
8590
8601
|
return parseEmailRenameCsvText(raw);
|
|
8591
8602
|
}
|
|
8592
|
-
function parseEmailRenameCsvText(
|
|
8593
|
-
const withoutBom =
|
|
8603
|
+
function parseEmailRenameCsvText(text2) {
|
|
8604
|
+
const withoutBom = text2.charCodeAt(0) === 65279 ? text2.slice(1) : text2;
|
|
8594
8605
|
const rows = parseCsvRows(withoutBom);
|
|
8595
8606
|
if (rows.length === 0) {
|
|
8596
8607
|
throw new Error("--file: CSV is empty");
|
|
@@ -10223,8 +10234,8 @@ async function readGroupsCsv(path11) {
|
|
|
10223
10234
|
}
|
|
10224
10235
|
return parseGroupsCsvText(raw);
|
|
10225
10236
|
}
|
|
10226
|
-
function parseGroupsCsvText(
|
|
10227
|
-
const withoutBom =
|
|
10237
|
+
function parseGroupsCsvText(text2) {
|
|
10238
|
+
const withoutBom = text2.charCodeAt(0) === 65279 ? text2.slice(1) : text2;
|
|
10228
10239
|
const rows = parseCsvRows(withoutBom);
|
|
10229
10240
|
if (rows.length === 0) {
|
|
10230
10241
|
throw new Error("--file: CSV is empty");
|
|
@@ -11889,8 +11900,8 @@ function envelopeErr(success, error) {
|
|
|
11889
11900
|
}
|
|
11890
11901
|
throw new Error("finance-os returned success=false with no error message");
|
|
11891
11902
|
}
|
|
11892
|
-
function describeFinanceOsFailure(
|
|
11893
|
-
const trimmed =
|
|
11903
|
+
function describeFinanceOsFailure(text2) {
|
|
11904
|
+
const trimmed = text2.trim();
|
|
11894
11905
|
let parsed2;
|
|
11895
11906
|
try {
|
|
11896
11907
|
parsed2 = JSON.parse(trimmed);
|
|
@@ -11954,9 +11965,9 @@ var AGGREGATE_POLL_TIMEOUT_MS = 6e4;
|
|
|
11954
11965
|
async function startTask(client, label, path11, body, options) {
|
|
11955
11966
|
const res = await client.do("POST", path11, JSON.stringify(body), options);
|
|
11956
11967
|
if (res.status !== 202) {
|
|
11957
|
-
const
|
|
11968
|
+
const text2 = await res.text();
|
|
11958
11969
|
throw new Error(
|
|
11959
|
-
`${label} POST: expected 202, got ${res.status}: ${describeFinanceOsFailure(
|
|
11970
|
+
`${label} POST: expected 202, got ${res.status}: ${describeFinanceOsFailure(text2)}`
|
|
11960
11971
|
);
|
|
11961
11972
|
}
|
|
11962
11973
|
const location = res.headers.get("Location") ?? "";
|
|
@@ -12000,10 +12011,10 @@ async function getTaskOnce(client, label, pollPath, options) {
|
|
|
12000
12011
|
throw new Error(`poll ${label}: ${msg}`);
|
|
12001
12012
|
}
|
|
12002
12013
|
if (res.status === 200) {
|
|
12003
|
-
const
|
|
12014
|
+
const text3 = await res.text();
|
|
12004
12015
|
let parsed2;
|
|
12005
12016
|
try {
|
|
12006
|
-
parsed2 =
|
|
12017
|
+
parsed2 = text3 === "" ? null : JSON.parse(text3);
|
|
12007
12018
|
} catch (err) {
|
|
12008
12019
|
const msg = err instanceof Error ? err.message : String(err);
|
|
12009
12020
|
throw new Error(`poll ${label}: ${msg}`);
|
|
@@ -12014,9 +12025,9 @@ async function getTaskOnce(client, label, pollPath, options) {
|
|
|
12014
12025
|
await res.text();
|
|
12015
12026
|
return { env: null, status: res.status };
|
|
12016
12027
|
}
|
|
12017
|
-
const
|
|
12028
|
+
const text2 = await res.text();
|
|
12018
12029
|
throw new Error(
|
|
12019
|
-
`poll ${label}: unexpected status ${res.status}: ${describeFinanceOsFailure(
|
|
12030
|
+
`poll ${label}: unexpected status ${res.status}: ${describeFinanceOsFailure(text2)}`
|
|
12020
12031
|
);
|
|
12021
12032
|
}
|
|
12022
12033
|
var defaultSleep2 = (ms, signal) => new Promise((resolve3, reject) => {
|
|
@@ -14280,7 +14291,7 @@ function renderFolderTree(out, tree) {
|
|
|
14280
14291
|
node.parent_id !== null ? String(node.parent_id) : "(root)"
|
|
14281
14292
|
]
|
|
14282
14293
|
});
|
|
14283
|
-
for (const
|
|
14294
|
+
for (const child2 of node.children ?? []) walk(child2, depth + 1);
|
|
14284
14295
|
};
|
|
14285
14296
|
for (const root of tree) walk(root, 0);
|
|
14286
14297
|
writeTable9(out, rows);
|
|
@@ -15775,6 +15786,503 @@ function collectArray3(value, previous) {
|
|
|
15775
15786
|
return previous.concat([value]);
|
|
15776
15787
|
}
|
|
15777
15788
|
|
|
15789
|
+
// src/commands/odata.ts
|
|
15790
|
+
import { once } from "events";
|
|
15791
|
+
|
|
15792
|
+
// src/api/odata.ts
|
|
15793
|
+
import { XMLParser } from "fast-xml-parser";
|
|
15794
|
+
var ODATA_VARIANTS = ["latest", "cleared", "full", "full-cleared"];
|
|
15795
|
+
var VARIANT_BY_SUFFIX = /* @__PURE__ */ new Map([
|
|
15796
|
+
["", "latest"],
|
|
15797
|
+
[" (Cleared)", "cleared"],
|
|
15798
|
+
[" (Full)", "full"],
|
|
15799
|
+
[" (Full)(Cleared)", "full-cleared"]
|
|
15800
|
+
]);
|
|
15801
|
+
var TAG = "%";
|
|
15802
|
+
var TEXT = "#text";
|
|
15803
|
+
var ATTR = "@_";
|
|
15804
|
+
var parser = new XMLParser({
|
|
15805
|
+
ignoreAttributes: false,
|
|
15806
|
+
attributeNamePrefix: ATTR,
|
|
15807
|
+
textNodeName: TEXT,
|
|
15808
|
+
removeNSPrefix: true,
|
|
15809
|
+
parseTagValue: false,
|
|
15810
|
+
parseAttributeValue: false,
|
|
15811
|
+
trimValues: false,
|
|
15812
|
+
htmlEntities: true,
|
|
15813
|
+
transformTagName: (name) => name.startsWith(TAG) ? name : `${TAG}${name}`,
|
|
15814
|
+
isArray: (_name, _jpath, _isLeaf, isAttribute) => isAttribute !== true
|
|
15815
|
+
});
|
|
15816
|
+
function isNode(v) {
|
|
15817
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
15818
|
+
}
|
|
15819
|
+
function children(node, tag) {
|
|
15820
|
+
if (!isNode(node)) return [];
|
|
15821
|
+
const v = node[`${TAG}${tag}`];
|
|
15822
|
+
return Array.isArray(v) ? v : [];
|
|
15823
|
+
}
|
|
15824
|
+
function child(node, tag) {
|
|
15825
|
+
return children(node, tag)[0];
|
|
15826
|
+
}
|
|
15827
|
+
function attr(node, name) {
|
|
15828
|
+
if (!isNode(node)) return void 0;
|
|
15829
|
+
const v = node[`${ATTR}${name}`];
|
|
15830
|
+
return typeof v === "string" ? v : void 0;
|
|
15831
|
+
}
|
|
15832
|
+
function text(node) {
|
|
15833
|
+
if (typeof node === "string") return node;
|
|
15834
|
+
if (isNode(node) && typeof node[TEXT] === "string") return node[TEXT];
|
|
15835
|
+
return "";
|
|
15836
|
+
}
|
|
15837
|
+
function parseXml(xml, what) {
|
|
15838
|
+
let doc;
|
|
15839
|
+
try {
|
|
15840
|
+
doc = parser.parse(xml);
|
|
15841
|
+
} catch (err) {
|
|
15842
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
15843
|
+
throw new Error(`not ${what}: ${msg}`);
|
|
15844
|
+
}
|
|
15845
|
+
if (!isNode(doc)) throw new Error(`not ${what}`);
|
|
15846
|
+
return doc;
|
|
15847
|
+
}
|
|
15848
|
+
function parseServiceDocument(xml) {
|
|
15849
|
+
const doc = parseXml(xml, "an OData service document");
|
|
15850
|
+
const service = child(doc, "service");
|
|
15851
|
+
if (service === void 0) {
|
|
15852
|
+
throw new Error("not an OData service document (no <service> root)");
|
|
15853
|
+
}
|
|
15854
|
+
const out = [];
|
|
15855
|
+
for (const ws of children(service, "workspace")) {
|
|
15856
|
+
for (const c of children(ws, "collection")) {
|
|
15857
|
+
const key = attr(c, "href");
|
|
15858
|
+
if (key === void 0) continue;
|
|
15859
|
+
out.push({ key, title: text(child(c, "title")), updated: text(child(c, "updated")) });
|
|
15860
|
+
}
|
|
15861
|
+
}
|
|
15862
|
+
return out;
|
|
15863
|
+
}
|
|
15864
|
+
function parseMetadata(xml) {
|
|
15865
|
+
const doc = parseXml(xml, "an OData $metadata document");
|
|
15866
|
+
const edmx = child(doc, "Edmx");
|
|
15867
|
+
if (edmx === void 0) {
|
|
15868
|
+
throw new Error("not an OData $metadata document (no <edmx:Edmx> root)");
|
|
15869
|
+
}
|
|
15870
|
+
const out = [];
|
|
15871
|
+
for (const ds of children(edmx, "DataServices")) {
|
|
15872
|
+
for (const schema of children(ds, "Schema")) {
|
|
15873
|
+
for (const et of children(schema, "EntityType")) {
|
|
15874
|
+
const name = attr(et, "Name");
|
|
15875
|
+
if (name === void 0) continue;
|
|
15876
|
+
const columns = [];
|
|
15877
|
+
for (const p of children(et, "Property")) {
|
|
15878
|
+
const pname = attr(p, "Name");
|
|
15879
|
+
if (pname === void 0) continue;
|
|
15880
|
+
columns.push({ name: pname, type: attr(p, "Type") ?? "" });
|
|
15881
|
+
}
|
|
15882
|
+
out.push({ name, columns });
|
|
15883
|
+
}
|
|
15884
|
+
}
|
|
15885
|
+
}
|
|
15886
|
+
return out;
|
|
15887
|
+
}
|
|
15888
|
+
function parseFeed(xml) {
|
|
15889
|
+
const tooLarge = /^\s*\[\{'error': 'too_large_data'(?:, 'rows_count': (\d+))?(?:, 'cols_count': (\d+))?/.exec(
|
|
15890
|
+
xml
|
|
15891
|
+
);
|
|
15892
|
+
if (tooLarge !== null) {
|
|
15893
|
+
const dims = tooLarge[1] !== void 0 && tooLarge[2] !== void 0 ? ` (${tooLarge[1]} rows \xD7 ${tooLarge[2]} columns)` : "";
|
|
15894
|
+
throw new Error(
|
|
15895
|
+
`the server refused the page as too large${dims}: lower --page-size or narrow --select`
|
|
15896
|
+
);
|
|
15897
|
+
}
|
|
15898
|
+
if (!/<\/(?:[\w.-]+:)?feed>\s*$/.test(xml)) {
|
|
15899
|
+
throw new Error("not an OData Atom feed: the body ends before </feed> (truncated response)");
|
|
15900
|
+
}
|
|
15901
|
+
const doc = parseXml(xml, "an OData Atom feed");
|
|
15902
|
+
const feed = child(doc, "feed");
|
|
15903
|
+
if (feed === void 0) {
|
|
15904
|
+
throw new Error("not an OData Atom feed (no <feed> root)");
|
|
15905
|
+
}
|
|
15906
|
+
const out = [];
|
|
15907
|
+
for (const e of children(feed, "entry")) {
|
|
15908
|
+
const row = /* @__PURE__ */ new Map();
|
|
15909
|
+
const props = child(child(e, "content"), "properties");
|
|
15910
|
+
if (isNode(props)) {
|
|
15911
|
+
for (const [k, v] of Object.entries(props)) {
|
|
15912
|
+
if (!k.startsWith(TAG) || !Array.isArray(v)) continue;
|
|
15913
|
+
const value = v[0];
|
|
15914
|
+
row.set(k.slice(TAG.length), attr(value, "null") === "true" ? null : text(value));
|
|
15915
|
+
}
|
|
15916
|
+
}
|
|
15917
|
+
out.push(row);
|
|
15918
|
+
}
|
|
15919
|
+
return out;
|
|
15920
|
+
}
|
|
15921
|
+
function parseODataTitle(title) {
|
|
15922
|
+
const m = /^(.*)_(\d+)( \(Full\)\(Cleared\)| \(Cleared\)| \(Full\))?$/s.exec(title);
|
|
15923
|
+
if (m === null) return null;
|
|
15924
|
+
const variant = VARIANT_BY_SUFFIX.get(m[3] ?? "");
|
|
15925
|
+
if (variant === void 0) return null;
|
|
15926
|
+
return { baseTitle: m[1] ?? "", tableId: Number(m[2]), variant };
|
|
15927
|
+
}
|
|
15928
|
+
function findByTableId(items, titleOf, tableId, variant) {
|
|
15929
|
+
const hits = items.filter((it) => {
|
|
15930
|
+
const p = parseODataTitle(titleOf(it));
|
|
15931
|
+
return p !== null && p.tableId === tableId && p.variant === variant;
|
|
15932
|
+
});
|
|
15933
|
+
if (hits.length > 1) {
|
|
15934
|
+
const titles = hits.map((h) => `"${titleOf(h)}"`).join(", ");
|
|
15935
|
+
throw new Error(`table ${tableId} (${variant}) is ambiguous over OData: ${titles}`);
|
|
15936
|
+
}
|
|
15937
|
+
return hits[0];
|
|
15938
|
+
}
|
|
15939
|
+
function tablePagePath(key, q) {
|
|
15940
|
+
let path11 = `/OData.svc/${key}?$top=${q.top}&$skip=${q.skip}`;
|
|
15941
|
+
if (q.select !== void 0 && q.select.length > 0) {
|
|
15942
|
+
path11 += `&$select=${encodeURIComponent(q.select.join(","))}`;
|
|
15943
|
+
}
|
|
15944
|
+
if (q.filter !== void 0 && q.filter !== "") {
|
|
15945
|
+
path11 += `&$filter=${encodeURIComponent(q.filter)}`;
|
|
15946
|
+
}
|
|
15947
|
+
return path11;
|
|
15948
|
+
}
|
|
15949
|
+
async function getXml(client, path11, accept, options) {
|
|
15950
|
+
const res = await client.do("GET", path11, void 0, {
|
|
15951
|
+
...options,
|
|
15952
|
+
headers: { ...options?.headers, Accept: accept }
|
|
15953
|
+
});
|
|
15954
|
+
const body = await res.text();
|
|
15955
|
+
if (res.status < 200 || res.status >= 300) {
|
|
15956
|
+
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncate4(body, 200)}`);
|
|
15957
|
+
}
|
|
15958
|
+
return body;
|
|
15959
|
+
}
|
|
15960
|
+
async function getServiceDocument(client, options) {
|
|
15961
|
+
return parseServiceDocument(await getXml(client, "/OData.svc", "application/xml", options));
|
|
15962
|
+
}
|
|
15963
|
+
async function getMetadata(client, options) {
|
|
15964
|
+
return parseMetadata(await getXml(client, "/OData.svc/$metadata", "application/xml", options));
|
|
15965
|
+
}
|
|
15966
|
+
async function getTablePage(client, key, q, options) {
|
|
15967
|
+
return parseFeed(await getXml(client, tablePagePath(key, q), "application/atom+xml", options));
|
|
15968
|
+
}
|
|
15969
|
+
|
|
15970
|
+
// src/commands/odata.ts
|
|
15971
|
+
var ODATA_DEFAULT_PAGE_SIZE = 3e4;
|
|
15972
|
+
var ODATA_REQUEST_TIMEOUT_MS = 12e4;
|
|
15973
|
+
function notVisible(tableId, variant, where) {
|
|
15974
|
+
return new Error(
|
|
15975
|
+
`table ${tableId} (${variant}) is not visible to this user over OData (not in ${where})`
|
|
15976
|
+
);
|
|
15977
|
+
}
|
|
15978
|
+
async function runODataTables(cfg) {
|
|
15979
|
+
const collections = await getServiceDocument(cfg.client, { signal: cfg.signal });
|
|
15980
|
+
const byId = /* @__PURE__ */ new Map();
|
|
15981
|
+
for (const c of collections) {
|
|
15982
|
+
const parts = parseODataTitle(c.title);
|
|
15983
|
+
if (parts === null) continue;
|
|
15984
|
+
let info = byId.get(parts.tableId);
|
|
15985
|
+
if (info === void 0) {
|
|
15986
|
+
info = { id: parts.tableId, title: parts.baseTitle, variants: [] };
|
|
15987
|
+
byId.set(parts.tableId, info);
|
|
15988
|
+
}
|
|
15989
|
+
info.variants.push({ variant: parts.variant, title: c.title, key: c.key, updated: c.updated });
|
|
15990
|
+
}
|
|
15991
|
+
const order = ODATA_VARIANTS;
|
|
15992
|
+
const tables = [...byId.values()].sort((a, b) => a.id - b.id);
|
|
15993
|
+
for (const t of tables) {
|
|
15994
|
+
t.variants.sort((a, b) => order.indexOf(a.variant) - order.indexOf(b.variant));
|
|
15995
|
+
}
|
|
15996
|
+
if (cfg.asJson) {
|
|
15997
|
+
writeJSONIndented(cfg.out, tables);
|
|
15998
|
+
return;
|
|
15999
|
+
}
|
|
16000
|
+
if (tables.length === 0) {
|
|
16001
|
+
cfg.out.write("(no tables visible over OData)\n");
|
|
16002
|
+
return;
|
|
16003
|
+
}
|
|
16004
|
+
const rows = [["ID", "TITLE", "VARIANTS", "UPDATED"]];
|
|
16005
|
+
for (const t of tables) {
|
|
16006
|
+
const updated = (t.variants.find((v) => v.variant === "latest") ?? t.variants[0])?.updated;
|
|
16007
|
+
rows.push([String(t.id), t.title, t.variants.map((v) => v.variant).join(","), updated ?? ""]);
|
|
16008
|
+
}
|
|
16009
|
+
for (const line of formatTable(rows, columnWidths(rows))) cfg.out.write(`${line}
|
|
16010
|
+
`);
|
|
16011
|
+
}
|
|
16012
|
+
async function runODataMetadata(cfg) {
|
|
16013
|
+
const types = await getMetadata(cfg.client, { signal: cfg.signal });
|
|
16014
|
+
const entity = findByTableId(types, (t) => t.name, cfg.tableId, cfg.variant);
|
|
16015
|
+
if (entity === void 0) throw notVisible(cfg.tableId, cfg.variant, "$metadata");
|
|
16016
|
+
if (cfg.asJson) {
|
|
16017
|
+
writeJSONIndented(cfg.out, entity);
|
|
16018
|
+
return;
|
|
16019
|
+
}
|
|
16020
|
+
cfg.out.write(`${entity.name}
|
|
16021
|
+
`);
|
|
16022
|
+
if (entity.columns.length === 0) {
|
|
16023
|
+
cfg.out.write("(no columns)\n");
|
|
16024
|
+
return;
|
|
16025
|
+
}
|
|
16026
|
+
cfg.out.write("\n");
|
|
16027
|
+
const rows = [["COLUMN", "TYPE"], ...entity.columns.map((c) => [c.name, c.type])];
|
|
16028
|
+
for (const line of formatTable(rows, columnWidths(rows))) cfg.out.write(`${line}
|
|
16029
|
+
`);
|
|
16030
|
+
}
|
|
16031
|
+
async function runODataData(cfg) {
|
|
16032
|
+
const req = { signal: cfg.signal };
|
|
16033
|
+
const budget = () => cfg.extendTimeout?.(cfg.requestTimeoutMs ?? ODATA_REQUEST_TIMEOUT_MS);
|
|
16034
|
+
let key = cfg.key;
|
|
16035
|
+
if (key === void 0) {
|
|
16036
|
+
budget();
|
|
16037
|
+
const collections = await getServiceDocument(cfg.client, req);
|
|
16038
|
+
const hit = findByTableId(collections, (c) => c.title, cfg.tableId, cfg.variant);
|
|
16039
|
+
if (hit === void 0) throw notVisible(cfg.tableId, cfg.variant, "the service document");
|
|
16040
|
+
key = hit.key;
|
|
16041
|
+
}
|
|
16042
|
+
budget();
|
|
16043
|
+
const types = await getMetadata(cfg.client, req);
|
|
16044
|
+
const entity = findByTableId(types, (t) => t.name, cfg.tableId, cfg.variant);
|
|
16045
|
+
if (entity === void 0) throw notVisible(cfg.tableId, cfg.variant, "$metadata");
|
|
16046
|
+
const columns = selectColumns(entity.columns, cfg.select, cfg.tableId, cfg.variant);
|
|
16047
|
+
const names = columns.map((c) => c.name);
|
|
16048
|
+
const pause = () => cfg.pauseTimeout?.();
|
|
16049
|
+
const sink = createSink(cfg.format, names, cfg.out, cfg.signal, pause, budget);
|
|
16050
|
+
await sink.start();
|
|
16051
|
+
let skip = 0;
|
|
16052
|
+
let remaining = cfg.limit;
|
|
16053
|
+
for (; ; ) {
|
|
16054
|
+
const top = remaining === null ? cfg.pageSize : Math.min(cfg.pageSize, remaining);
|
|
16055
|
+
budget();
|
|
16056
|
+
const entries = await getTablePage(
|
|
16057
|
+
cfg.client,
|
|
16058
|
+
key,
|
|
16059
|
+
{ top, skip, select: cfg.select === void 0 ? void 0 : names, filter: cfg.filter },
|
|
16060
|
+
req
|
|
16061
|
+
);
|
|
16062
|
+
const page = entries.slice(0, top);
|
|
16063
|
+
await sink.page(page.map((e) => names.map((n) => e.get(n) ?? null)));
|
|
16064
|
+
skip += page.length;
|
|
16065
|
+
if (remaining !== null) remaining -= page.length;
|
|
16066
|
+
if (page.length < top || remaining === 0) break;
|
|
16067
|
+
}
|
|
16068
|
+
await sink.end();
|
|
16069
|
+
}
|
|
16070
|
+
function selectColumns(all, select, tableId, variant) {
|
|
16071
|
+
if (select === void 0) return [...all];
|
|
16072
|
+
const known = new Set(all.map((c) => c.name));
|
|
16073
|
+
for (const s of select) {
|
|
16074
|
+
if (!known.has(s)) {
|
|
16075
|
+
throw new Error(
|
|
16076
|
+
`--select: unknown column "${s}" for table ${tableId} (${variant}); names are the OData-sanitized ones from \`dr odata metadata ${tableId}\``
|
|
16077
|
+
);
|
|
16078
|
+
}
|
|
16079
|
+
}
|
|
16080
|
+
const wanted = new Set(select);
|
|
16081
|
+
return all.filter((c) => wanted.has(c.name));
|
|
16082
|
+
}
|
|
16083
|
+
async function emitTo(out, s, signal, pause, rearm) {
|
|
16084
|
+
if (!out.write(s)) {
|
|
16085
|
+
pause();
|
|
16086
|
+
await once(out, "drain", { signal });
|
|
16087
|
+
rearm();
|
|
16088
|
+
}
|
|
16089
|
+
}
|
|
16090
|
+
function createSink(format, names, out, signal, pause = () => {
|
|
16091
|
+
}, rearm = () => {
|
|
16092
|
+
}) {
|
|
16093
|
+
const emit = (s) => emitTo(out, s, signal, pause, rearm);
|
|
16094
|
+
if (format === "csv") {
|
|
16095
|
+
return {
|
|
16096
|
+
start: () => emit(`${formatCsvRow(names)}
|
|
16097
|
+
`),
|
|
16098
|
+
page: async (rows) => {
|
|
16099
|
+
for (const r of rows) await emit(`${formatCsvRow(r.map((c) => c ?? ""))}
|
|
16100
|
+
`);
|
|
16101
|
+
},
|
|
16102
|
+
end: async () => {
|
|
16103
|
+
}
|
|
16104
|
+
};
|
|
16105
|
+
}
|
|
16106
|
+
if (format === "json") {
|
|
16107
|
+
let count = 0;
|
|
16108
|
+
return {
|
|
16109
|
+
start: () => emit("["),
|
|
16110
|
+
page: async (rows) => {
|
|
16111
|
+
for (const r of rows) {
|
|
16112
|
+
const obj = Object.fromEntries(names.map((n, i) => [n, r[i] ?? null]));
|
|
16113
|
+
await emit(`${count === 0 ? "\n" : ",\n"}${JSON.stringify(obj)}`);
|
|
16114
|
+
count++;
|
|
16115
|
+
}
|
|
16116
|
+
},
|
|
16117
|
+
end: () => emit(count === 0 ? "]\n" : "\n]\n")
|
|
16118
|
+
};
|
|
16119
|
+
}
|
|
16120
|
+
let widths = null;
|
|
16121
|
+
return {
|
|
16122
|
+
start: async () => {
|
|
16123
|
+
},
|
|
16124
|
+
page: async (rows) => {
|
|
16125
|
+
const cells = rows.map((r) => r.map((c) => c ?? ""));
|
|
16126
|
+
if (widths === null) {
|
|
16127
|
+
if (cells.length === 0) return;
|
|
16128
|
+
widths = columnWidths([names, ...cells]);
|
|
16129
|
+
await emit(`${formatTable([names], widths)[0]}
|
|
16130
|
+
`);
|
|
16131
|
+
}
|
|
16132
|
+
for (const line of formatTable(cells, widths)) await emit(`${line}
|
|
16133
|
+
`);
|
|
16134
|
+
},
|
|
16135
|
+
end: async () => {
|
|
16136
|
+
if (widths === null) await emit("(no rows)\n");
|
|
16137
|
+
}
|
|
16138
|
+
};
|
|
16139
|
+
}
|
|
16140
|
+
function columnWidths(rows) {
|
|
16141
|
+
const widths = [];
|
|
16142
|
+
for (const r of rows) {
|
|
16143
|
+
r.forEach((cell, i) => {
|
|
16144
|
+
if ((widths[i] ?? 0) < cell.length) widths[i] = cell.length;
|
|
16145
|
+
});
|
|
16146
|
+
}
|
|
16147
|
+
return widths;
|
|
16148
|
+
}
|
|
16149
|
+
function formatTable(rows, widths) {
|
|
16150
|
+
return rows.map(
|
|
16151
|
+
(r) => r.map((cell, i) => i === r.length - 1 ? cell : cell.padEnd((widths[i] ?? 0) + 2)).join("")
|
|
16152
|
+
);
|
|
16153
|
+
}
|
|
16154
|
+
function parseVariant(raw) {
|
|
16155
|
+
if (raw === void 0) return "latest";
|
|
16156
|
+
const hit = ODATA_VARIANTS.find((v) => v === raw);
|
|
16157
|
+
if (hit === void 0) {
|
|
16158
|
+
throw new Error(
|
|
16159
|
+
`invalid --variant "${raw}" (expected one of: ${ODATA_VARIANTS.join(", ")})`
|
|
16160
|
+
);
|
|
16161
|
+
}
|
|
16162
|
+
return hit;
|
|
16163
|
+
}
|
|
16164
|
+
var KEY_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/;
|
|
16165
|
+
function resolveDataOptions(tableIdStr, f) {
|
|
16166
|
+
const tableId = parsePositiveIntArg(tableIdStr, "<table-id>");
|
|
16167
|
+
const variant = parseVariant(f.variant);
|
|
16168
|
+
if (f.top !== void 0 && f.all === true) {
|
|
16169
|
+
throw new Error("--top and --all cannot be combined");
|
|
16170
|
+
}
|
|
16171
|
+
if (f.csv === true && f.json === true) {
|
|
16172
|
+
throw new Error("--csv and --json cannot be combined");
|
|
16173
|
+
}
|
|
16174
|
+
const pageSize = f.pageSize === void 0 ? ODATA_DEFAULT_PAGE_SIZE : parsePositiveIntArg(f.pageSize, "--page-size");
|
|
16175
|
+
let limit = pageSize;
|
|
16176
|
+
if (f.all === true) limit = null;
|
|
16177
|
+
else if (f.top !== void 0) limit = parsePositiveIntArg(f.top, "--top");
|
|
16178
|
+
if (f.key !== void 0 && !KEY_PATTERN.test(f.key)) {
|
|
16179
|
+
throw new Error(
|
|
16180
|
+
`invalid --key "${f.key}" (expected a base64 key, see \`dr odata tables --json\`)`
|
|
16181
|
+
);
|
|
16182
|
+
}
|
|
16183
|
+
let select;
|
|
16184
|
+
if (f.select !== void 0) {
|
|
16185
|
+
select = f.select.split(",").map((s) => s.trim()).filter((s) => s !== "");
|
|
16186
|
+
if (select.length === 0) throw new Error("--select must name at least one column");
|
|
16187
|
+
}
|
|
16188
|
+
if (f.filter !== void 0 && f.filter === "") {
|
|
16189
|
+
throw new Error("--filter must not be empty");
|
|
16190
|
+
}
|
|
16191
|
+
const requestTimeoutMs = parsePositiveSecondsFlag(
|
|
16192
|
+
f.timeout,
|
|
16193
|
+
"--timeout",
|
|
16194
|
+
ODATA_REQUEST_TIMEOUT_MS
|
|
16195
|
+
);
|
|
16196
|
+
if (requestTimeoutMs > BATCH_TIMEOUT_MAX_SECONDS * 1e3) {
|
|
16197
|
+
throw new Error(`--timeout must be at most ${BATCH_TIMEOUT_MAX_SECONDS} seconds`);
|
|
16198
|
+
}
|
|
16199
|
+
return {
|
|
16200
|
+
tableId,
|
|
16201
|
+
variant,
|
|
16202
|
+
key: f.key,
|
|
16203
|
+
limit,
|
|
16204
|
+
pageSize,
|
|
16205
|
+
select,
|
|
16206
|
+
filter: f.filter,
|
|
16207
|
+
format: f.csv === true ? "csv" : f.json === true ? "json" : "table",
|
|
16208
|
+
requestTimeoutMs
|
|
16209
|
+
};
|
|
16210
|
+
}
|
|
16211
|
+
var VARIANT_HELP = "latest (default), cleared, full (all versions) or full-cleared \u2014 the four collections OData clients see";
|
|
16212
|
+
function registerODataCommand(root) {
|
|
16213
|
+
const od = root.command("odata").description(
|
|
16214
|
+
"Read tables over OData V1 exactly as Excel / Power BI / SQLConnector receive them (read-only)"
|
|
16215
|
+
);
|
|
16216
|
+
const tablesCmd = od.command("tables").description("List the tables this user can read over OData, with their variants").option("--json", "Output JSON, including each variant key", false).action(async (opts) => {
|
|
16217
|
+
const setup = await setupCall(opts.server, opts.account);
|
|
16218
|
+
try {
|
|
16219
|
+
await runODataTables({
|
|
16220
|
+
client: setup.client,
|
|
16221
|
+
asJson: opts.json === true,
|
|
16222
|
+
signal: setup.signal,
|
|
16223
|
+
out: process.stdout
|
|
16224
|
+
});
|
|
16225
|
+
} finally {
|
|
16226
|
+
setup.cleanup();
|
|
16227
|
+
}
|
|
16228
|
+
});
|
|
16229
|
+
addServerFlag(tablesCmd);
|
|
16230
|
+
addAccountFlag(tablesCmd);
|
|
16231
|
+
const metadataCmd = od.command("metadata").description("Columns and EDM types of a table, in $metadata order").argument("<table-id>", "table (template) id").option("--variant <variant>", VARIANT_HELP).option("--json", "Output JSON", false).action(async (idStr, opts) => {
|
|
16232
|
+
const tableId = parsePositiveIntArg(idStr, "<table-id>");
|
|
16233
|
+
const variant = parseVariant(opts.variant);
|
|
16234
|
+
const setup = await setupCall(opts.server, opts.account);
|
|
16235
|
+
try {
|
|
16236
|
+
await runODataMetadata({
|
|
16237
|
+
client: setup.client,
|
|
16238
|
+
tableId,
|
|
16239
|
+
variant,
|
|
16240
|
+
asJson: opts.json === true,
|
|
16241
|
+
signal: setup.signal,
|
|
16242
|
+
out: process.stdout
|
|
16243
|
+
});
|
|
16244
|
+
} finally {
|
|
16245
|
+
setup.cleanup();
|
|
16246
|
+
}
|
|
16247
|
+
});
|
|
16248
|
+
addServerFlag(metadataCmd);
|
|
16249
|
+
addAccountFlag(metadataCmd);
|
|
16250
|
+
const dataCmd = od.command("data").description(
|
|
16251
|
+
"Read table rows over OData. Without --top/--all: one page of --page-size rows. --top N: at most N rows. --all: page until the table is exhausted. Rows stream as each page arrives."
|
|
16252
|
+
).argument("<table-id>", "table (template) id").option("--variant <variant>", VARIANT_HELP).option(
|
|
16253
|
+
"--key <base64>",
|
|
16254
|
+
"Use this OData key verbatim instead of the one the service document lists"
|
|
16255
|
+
).option("--top <n>", "Return at most N rows").option("--all", "Page until the table is exhausted", false).option("--page-size <n>", `Rows per request ($top) (default ${ODATA_DEFAULT_PAGE_SIZE})`).option("--select <columns>", "Comma-separated OData column names (see `dr odata metadata`)").option("--filter <expr>", "OData $filter expression, passed through to the server").option("--csv", "Output CSV", false).option("--json", "Output a JSON array, streamed", false).option(
|
|
16256
|
+
"--timeout <seconds>",
|
|
16257
|
+
`Budget for each request in seconds (default ${ODATA_REQUEST_TIMEOUT_MS / 1e3})`
|
|
16258
|
+
).action(async (idStr, opts) => {
|
|
16259
|
+
const r = resolveDataOptions(idStr, opts);
|
|
16260
|
+
const setup = await setupCall(opts.server, opts.account, { timeoutMs: r.requestTimeoutMs });
|
|
16261
|
+
try {
|
|
16262
|
+
await runODataData({
|
|
16263
|
+
client: setup.client,
|
|
16264
|
+
tableId: r.tableId,
|
|
16265
|
+
variant: r.variant,
|
|
16266
|
+
key: r.key,
|
|
16267
|
+
limit: r.limit,
|
|
16268
|
+
pageSize: r.pageSize,
|
|
16269
|
+
select: r.select,
|
|
16270
|
+
filter: r.filter,
|
|
16271
|
+
format: r.format,
|
|
16272
|
+
signal: setup.signal,
|
|
16273
|
+
out: process.stdout,
|
|
16274
|
+
extendTimeout: setup.extendTimeout,
|
|
16275
|
+
pauseTimeout: setup.pauseTimeout,
|
|
16276
|
+
requestTimeoutMs: r.requestTimeoutMs
|
|
16277
|
+
});
|
|
16278
|
+
} finally {
|
|
16279
|
+
setup.cleanup();
|
|
16280
|
+
}
|
|
16281
|
+
});
|
|
16282
|
+
addServerFlag(dataCmd);
|
|
16283
|
+
addAccountFlag(dataCmd);
|
|
16284
|
+
}
|
|
16285
|
+
|
|
15778
16286
|
// src/api/storyboards.ts
|
|
15779
16287
|
async function list13(client, options) {
|
|
15780
16288
|
const out = await client.getJSON("/api/storytelling/", options);
|
|
@@ -16404,22 +16912,22 @@ async function saveMappings(client, documentId, body, options = {}) {
|
|
|
16404
16912
|
}
|
|
16405
16913
|
async function postOnce(client, path11, payload, signal) {
|
|
16406
16914
|
const res = await client.do("POST", path11, payload, { signal });
|
|
16407
|
-
const
|
|
16915
|
+
const text2 = await res.text();
|
|
16408
16916
|
if (res.status === 200 || res.status === 409) {
|
|
16409
|
-
return { status: res.status, text };
|
|
16917
|
+
return { status: res.status, text: text2 };
|
|
16410
16918
|
}
|
|
16411
|
-
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncateBody(
|
|
16919
|
+
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncateBody(text2)}`);
|
|
16412
16920
|
}
|
|
16413
|
-
function extractCacheKey(
|
|
16921
|
+
function extractCacheKey(text2) {
|
|
16414
16922
|
try {
|
|
16415
|
-
const parsed2 = JSON.parse(
|
|
16923
|
+
const parsed2 = JSON.parse(text2);
|
|
16416
16924
|
return typeof parsed2.cache_key === "string" ? parsed2.cache_key : "";
|
|
16417
16925
|
} catch {
|
|
16418
16926
|
return "";
|
|
16419
16927
|
}
|
|
16420
16928
|
}
|
|
16421
|
-
function toResult(
|
|
16422
|
-
let message =
|
|
16929
|
+
function toResult(text2) {
|
|
16930
|
+
let message = text2.trim();
|
|
16423
16931
|
try {
|
|
16424
16932
|
const parsed2 = JSON.parse(message);
|
|
16425
16933
|
if (typeof parsed2 === "string") message = parsed2;
|
|
@@ -16454,8 +16962,8 @@ async function getLutFile(client, documentId, options) {
|
|
|
16454
16962
|
const path11 = `/api/documents/${documentId}/lut-file`;
|
|
16455
16963
|
const res = await client.do("GET", path11, void 0, options);
|
|
16456
16964
|
if (res.status < 200 || res.status >= 300) {
|
|
16457
|
-
const
|
|
16458
|
-
const truncated =
|
|
16965
|
+
const text2 = await res.text();
|
|
16966
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
16459
16967
|
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
16460
16968
|
}
|
|
16461
16969
|
const ab = await res.arrayBuffer();
|
|
@@ -16493,8 +17001,8 @@ async function downloadDebugZip(client, docVersionId, type, reqOptions) {
|
|
|
16493
17001
|
const path11 = `/api/documents/download_debug_zip_file/${docVersionId}?type=${type}`;
|
|
16494
17002
|
const res = await client.do("GET", path11, void 0, reqOptions);
|
|
16495
17003
|
if (res.status < 200 || res.status >= 300) {
|
|
16496
|
-
const
|
|
16497
|
-
const truncated =
|
|
17004
|
+
const text2 = await res.text();
|
|
17005
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
16498
17006
|
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
16499
17007
|
}
|
|
16500
17008
|
const ab = await res.arrayBuffer();
|
|
@@ -16620,19 +17128,19 @@ async function getDocumentJobStatusOnce(client, basePath, requestId, reqOptions)
|
|
|
16620
17128
|
await res.text();
|
|
16621
17129
|
return { kind: "notFound" };
|
|
16622
17130
|
}
|
|
16623
|
-
const
|
|
16624
|
-
throw new Error(`document-job status: unexpected HTTP ${res.status}: ${
|
|
17131
|
+
const text2 = await res.text();
|
|
17132
|
+
throw new Error(`document-job status: unexpected HTTP ${res.status}: ${text2.trim()}`);
|
|
16625
17133
|
}
|
|
16626
17134
|
async function readAutoCalcError(res) {
|
|
16627
|
-
const
|
|
17135
|
+
const text2 = await res.text();
|
|
16628
17136
|
try {
|
|
16629
|
-
const parsed2 = JSON.parse(
|
|
17137
|
+
const parsed2 = JSON.parse(text2);
|
|
16630
17138
|
if (typeof parsed2.error === "string" && parsed2.error !== "") {
|
|
16631
17139
|
return parsed2.error;
|
|
16632
17140
|
}
|
|
16633
17141
|
} catch {
|
|
16634
17142
|
}
|
|
16635
|
-
return
|
|
17143
|
+
return text2.trim();
|
|
16636
17144
|
}
|
|
16637
17145
|
var defaultSleep3 = (ms, signal) => new Promise((resolve3, reject) => {
|
|
16638
17146
|
if (signal?.aborted) {
|
|
@@ -16873,13 +17381,13 @@ async function getAutoCalculateSettings(client, docId, reqOptions) {
|
|
|
16873
17381
|
await res.text().catch(() => "");
|
|
16874
17382
|
return null;
|
|
16875
17383
|
}
|
|
16876
|
-
const
|
|
17384
|
+
const text2 = await res.text();
|
|
16877
17385
|
if (res.status < 200 || res.status >= 300) {
|
|
16878
|
-
throw new Error(`GET ${path11}: HTTP ${res.status}: ${
|
|
17386
|
+
throw new Error(`GET ${path11}: HTTP ${res.status}: ${text2.slice(0, 200)}`);
|
|
16879
17387
|
}
|
|
16880
|
-
if (
|
|
17388
|
+
if (text2 === "" || text2 === '""') return null;
|
|
16881
17389
|
try {
|
|
16882
|
-
return JSON.parse(
|
|
17390
|
+
return JSON.parse(text2);
|
|
16883
17391
|
} catch (err) {
|
|
16884
17392
|
const msg = err instanceof Error ? err.message : String(err);
|
|
16885
17393
|
throw new Error(`GET ${path11}: decode: ${msg}`);
|
|
@@ -20970,15 +21478,15 @@ function parseSuppressionDimension(d, source, i) {
|
|
|
20970
21478
|
return { name, mappings };
|
|
20971
21479
|
}
|
|
20972
21480
|
async function loadSuppression(path11) {
|
|
20973
|
-
let
|
|
21481
|
+
let text2;
|
|
20974
21482
|
try {
|
|
20975
|
-
|
|
21483
|
+
text2 = await readFile2(path11, "utf8");
|
|
20976
21484
|
} catch (err) {
|
|
20977
21485
|
throw new Error(`--suppression: cannot read ${path11} (${errText(err)})`);
|
|
20978
21486
|
}
|
|
20979
21487
|
let parsed2;
|
|
20980
21488
|
try {
|
|
20981
|
-
parsed2 = JSON.parse(
|
|
21489
|
+
parsed2 = JSON.parse(text2);
|
|
20982
21490
|
} catch (err) {
|
|
20983
21491
|
throw new Error(`--suppression: ${path11} is not valid JSON (${errText(err)})`);
|
|
20984
21492
|
}
|
|
@@ -24778,18 +25286,18 @@ async function getTemplateFields(client, templateId, options) {
|
|
|
24778
25286
|
}
|
|
24779
25287
|
async function putDataOnce(client, path11, body, options) {
|
|
24780
25288
|
const res = await client.do("PUT", path11, body, options);
|
|
24781
|
-
const
|
|
25289
|
+
const text2 = await res.text();
|
|
24782
25290
|
if (res.status === 401 || res.status === 403) {
|
|
24783
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate5(
|
|
25291
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate5(text2, 200)}`);
|
|
24784
25292
|
}
|
|
24785
25293
|
if (res.status !== 200 && res.status !== 409 && (res.status < 200 || res.status >= 300)) {
|
|
24786
|
-
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate5(
|
|
25294
|
+
throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate5(text2, 200)}`);
|
|
24787
25295
|
}
|
|
24788
|
-
if (
|
|
25296
|
+
if (text2 === "" || text2 === '""') {
|
|
24789
25297
|
return { status: res.status, parsed: null };
|
|
24790
25298
|
}
|
|
24791
25299
|
try {
|
|
24792
|
-
return { status: res.status, parsed: JSON.parse(
|
|
25300
|
+
return { status: res.status, parsed: JSON.parse(text2) };
|
|
24793
25301
|
} catch (err) {
|
|
24794
25302
|
const msg = err instanceof Error ? err.message : String(err);
|
|
24795
25303
|
throw new Error(`PUT ${path11}: decode: ${msg}`);
|
|
@@ -26696,8 +27204,8 @@ async function exportCsv(client, options) {
|
|
|
26696
27204
|
const path11 = `${BASE}export-csv/`;
|
|
26697
27205
|
const res = await client.do("GET", path11, void 0, options);
|
|
26698
27206
|
if (res.status < 200 || res.status >= 300) {
|
|
26699
|
-
const
|
|
26700
|
-
const truncated =
|
|
27207
|
+
const text2 = await res.text();
|
|
27208
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
26701
27209
|
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
26702
27210
|
}
|
|
26703
27211
|
return res.text();
|
|
@@ -28485,13 +28993,13 @@ ${MARKER_END}`;
|
|
|
28485
28993
|
}
|
|
28486
28994
|
function renderInlineBlock(skills, managedBy, installRoot) {
|
|
28487
28995
|
const sections = skills.map((s) => {
|
|
28488
|
-
const
|
|
28489
|
-
const trailingNl =
|
|
28996
|
+
const text2 = Buffer.from(routerBytes(s)).toString("utf8");
|
|
28997
|
+
const trailingNl = text2.endsWith("\n") ? "" : "\n";
|
|
28490
28998
|
const refs = s.files.filter((f) => f.relPath !== ROUTER_FILE).map((f) => f.relPath);
|
|
28491
28999
|
const pointer = refs.length === 0 ? "" : `<!-- dr-cli skill ${s.name}: ${refs.length} reference file(s) installed under ${installRoot}/${s.name}/ (${refs.join(", ")}) \u2014 read on demand -->
|
|
28492
29000
|
`;
|
|
28493
29001
|
return `<!-- dr-cli skill: ${s.name} -->
|
|
28494
|
-
${
|
|
29002
|
+
${text2}${trailingNl}${pointer}`;
|
|
28495
29003
|
});
|
|
28496
29004
|
return `${MARKER_BEGIN}
|
|
28497
29005
|
<!-- dr-cli \u2014 Datarails CLI skills (auto-managed by ${managedBy}) -->
|
|
@@ -30554,14 +31062,14 @@ async function runSplitCreate(cfg) {
|
|
|
30554
31062
|
writeJSONIndented(cfg.out, result);
|
|
30555
31063
|
return;
|
|
30556
31064
|
}
|
|
30557
|
-
const
|
|
31065
|
+
const children2 = Array.isArray(result.split_documents) ? result.split_documents : [];
|
|
30558
31066
|
const parentName = result.document !== null && typeof result.document?.name === "string" ? result.document.name : "-";
|
|
30559
31067
|
cfg.out.write(
|
|
30560
|
-
`Split created (id=${result.id}): ${
|
|
31068
|
+
`Split created (id=${result.id}): ${children2.length} child file(s) under parent ${JSON.stringify(parentName)}.
|
|
30561
31069
|
`
|
|
30562
31070
|
);
|
|
30563
|
-
for (const
|
|
30564
|
-
const name = typeof
|
|
31071
|
+
for (const child2 of children2) {
|
|
31072
|
+
const name = typeof child2.name === "string" ? child2.name : "(unnamed)";
|
|
30565
31073
|
cfg.out.write(` - ${name}
|
|
30566
31074
|
`);
|
|
30567
31075
|
}
|
|
@@ -30642,11 +31150,11 @@ function renderSplitsTable(out, splits) {
|
|
|
30642
31150
|
const rows = [["ID", "PARENT", "CHILDREN", "INPUT_METHOD", "DATA_MODE"]];
|
|
30643
31151
|
for (const s of splits) {
|
|
30644
31152
|
const parent = s.document !== null && typeof s.document?.name === "string" ? s.document.name : "-";
|
|
30645
|
-
const
|
|
31153
|
+
const children2 = Array.isArray(s.split_documents) ? String(s.split_documents.length) : "0";
|
|
30646
31154
|
rows.push([
|
|
30647
31155
|
String(s.id),
|
|
30648
31156
|
parent,
|
|
30649
|
-
|
|
31157
|
+
children2,
|
|
30650
31158
|
s.input_method ?? "-",
|
|
30651
31159
|
s.export_as_values === true ? "fixed" : "live"
|
|
30652
31160
|
]);
|
|
@@ -31719,21 +32227,21 @@ async function queryCheckStatus(client, queryIds, reqOptions) {
|
|
|
31719
32227
|
}
|
|
31720
32228
|
async function getErrorExplanation(client, path11, reqOptions) {
|
|
31721
32229
|
const res = await client.do("GET", path11, void 0, reqOptions);
|
|
31722
|
-
const
|
|
32230
|
+
const text2 = await res.text();
|
|
31723
32231
|
if (res.status === 200) {
|
|
31724
32232
|
let parsed2;
|
|
31725
32233
|
try {
|
|
31726
|
-
parsed2 = JSON.parse(
|
|
32234
|
+
parsed2 = JSON.parse(text2);
|
|
31727
32235
|
} catch (err) {
|
|
31728
32236
|
const msg = err instanceof Error ? err.message : String(err);
|
|
31729
32237
|
throw new Error(`decode error-explanation: ${msg}`);
|
|
31730
32238
|
}
|
|
31731
|
-
return { status: 200, body: parsed2, rawText:
|
|
32239
|
+
return { status: 200, body: parsed2, rawText: text2 };
|
|
31732
32240
|
}
|
|
31733
32241
|
if (res.status === 404) {
|
|
31734
|
-
return { status: 404, body: null, rawText:
|
|
32242
|
+
return { status: 404, body: null, rawText: text2 };
|
|
31735
32243
|
}
|
|
31736
|
-
throw new Error(`error explanation: unexpected status ${res.status}: ${
|
|
32244
|
+
throw new Error(`error explanation: unexpected status ${res.status}: ${text2.trim()}`);
|
|
31737
32245
|
}
|
|
31738
32246
|
async function resync(client, id, reqOptions) {
|
|
31739
32247
|
const out = await client.postJSON(
|
|
@@ -31751,8 +32259,8 @@ async function testConnection(client, rawBody, reqOptions) {
|
|
|
31751
32259
|
rawBody,
|
|
31752
32260
|
reqOptions
|
|
31753
32261
|
);
|
|
31754
|
-
const
|
|
31755
|
-
return { status: res.status, rawText:
|
|
32262
|
+
const text2 = await res.text();
|
|
32263
|
+
return { status: res.status, rawText: text2 };
|
|
31756
32264
|
}
|
|
31757
32265
|
async function create15(client, body, reqOptions) {
|
|
31758
32266
|
const path11 = "/api/v3/data_integrations/";
|
|
@@ -31772,8 +32280,8 @@ async function update9(client, id, body, reqOptions) {
|
|
|
31772
32280
|
}
|
|
31773
32281
|
async function deleteById13(client, id, reqOptions) {
|
|
31774
32282
|
const res = await client.do("DELETE", `/api/v3/data_integrations/${id}/`, void 0, reqOptions);
|
|
31775
|
-
const
|
|
31776
|
-
return { status: res.status, rawText:
|
|
32283
|
+
const text2 = await res.text();
|
|
32284
|
+
return { status: res.status, rawText: text2 };
|
|
31777
32285
|
}
|
|
31778
32286
|
async function revoke(client, id, reqOptions) {
|
|
31779
32287
|
const res = await client.do(
|
|
@@ -31852,14 +32360,14 @@ async function itUpdate(client, id, body, reqOptions) {
|
|
|
31852
32360
|
}
|
|
31853
32361
|
async function itDelete(client, id, reqOptions) {
|
|
31854
32362
|
const res = await client.do("DELETE", `/api/it/integrations/${id}`, void 0, reqOptions);
|
|
31855
|
-
const
|
|
31856
|
-
return { status: res.status, rawText:
|
|
32363
|
+
const text2 = await res.text();
|
|
32364
|
+
return { status: res.status, rawText: text2 };
|
|
31857
32365
|
}
|
|
31858
32366
|
async function itResync(client, id, reqOptions) {
|
|
31859
32367
|
const res = await client.do("GET", `/api/it/integrations/${id}/resync`, void 0, reqOptions);
|
|
31860
|
-
const
|
|
32368
|
+
const text2 = await res.text();
|
|
31861
32369
|
if (res.status < 200 || res.status >= 300) {
|
|
31862
|
-
throw new Error(`resync: HTTP ${res.status}: ${
|
|
32370
|
+
throw new Error(`resync: HTTP ${res.status}: ${text2.trim()}`);
|
|
31863
32371
|
}
|
|
31864
32372
|
}
|
|
31865
32373
|
|
|
@@ -40846,8 +41354,8 @@ async function getEvidenceFile(client, params, options) {
|
|
|
40846
41354
|
const path11 = params.accountId !== void 0 && params.accountId !== "" ? `/api/reconciliation/processes/${params.processId}/account/${params.accountId}/evidences/${params.evidenceId}/file` : `/api/reconciliation/processes/${params.processId}/evidences/${params.evidenceId}/file`;
|
|
40847
41355
|
const res = await client.do("GET", path11, void 0, options);
|
|
40848
41356
|
if (res.status < 200 || res.status >= 300) {
|
|
40849
|
-
const
|
|
40850
|
-
const truncated =
|
|
41357
|
+
const text2 = await res.text();
|
|
41358
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
40851
41359
|
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
40852
41360
|
}
|
|
40853
41361
|
const ab = await res.arrayBuffer();
|
|
@@ -40905,19 +41413,19 @@ async function deleteFileboxConnection(client, connectionId, options) {
|
|
|
40905
41413
|
async function getFileboxSyncProgress(client, params, options) {
|
|
40906
41414
|
const path11 = `/api/reconciliation/filebox/connections/${params.connectionId}/sync/progress`;
|
|
40907
41415
|
const res = await client.do("GET", path11, void 0, options);
|
|
40908
|
-
const
|
|
41416
|
+
const text2 = await res.text();
|
|
40909
41417
|
if (res.status === 200 || res.status === 409) {
|
|
40910
|
-
if (
|
|
41418
|
+
if (text2 === "" || text2 === '""') {
|
|
40911
41419
|
return { status: "", remaining_files: 0, message: "" };
|
|
40912
41420
|
}
|
|
40913
41421
|
try {
|
|
40914
|
-
return JSON.parse(
|
|
41422
|
+
return JSON.parse(text2);
|
|
40915
41423
|
} catch (err) {
|
|
40916
41424
|
const msg = err instanceof Error ? err.message : String(err);
|
|
40917
41425
|
throw new Error(`GET ${path11}: decode: ${msg}`);
|
|
40918
41426
|
}
|
|
40919
41427
|
}
|
|
40920
|
-
const truncated =
|
|
41428
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
40921
41429
|
throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
40922
41430
|
}
|
|
40923
41431
|
async function getFileboxUnlinkedCount(client, params, options) {
|
|
@@ -41074,8 +41582,8 @@ async function readAssigneeCsv(path11) {
|
|
|
41074
41582
|
}
|
|
41075
41583
|
return parseAssigneeCsvText(raw);
|
|
41076
41584
|
}
|
|
41077
|
-
function parseAssigneeCsvText(
|
|
41078
|
-
const withoutBom =
|
|
41585
|
+
function parseAssigneeCsvText(text2) {
|
|
41586
|
+
const withoutBom = text2.charCodeAt(0) === 65279 ? text2.slice(1) : text2;
|
|
41079
41587
|
const rows = parseCsvRows(withoutBom);
|
|
41080
41588
|
if (rows.length === 0) {
|
|
41081
41589
|
throw new Error("--file: CSV is empty");
|
|
@@ -44451,8 +44959,8 @@ async function deleteWithBody(client, path11, body, options) {
|
|
|
44451
44959
|
const encoded = JSON.stringify(body);
|
|
44452
44960
|
const res = await client.do("DELETE", path11, encoded, options);
|
|
44453
44961
|
if (res.status < 200 || res.status >= 300) {
|
|
44454
|
-
const
|
|
44455
|
-
const truncated =
|
|
44962
|
+
const text2 = await res.text();
|
|
44963
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
44456
44964
|
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
44457
44965
|
}
|
|
44458
44966
|
await res.text();
|
|
@@ -44900,16 +45408,16 @@ async function runProbe(client, options) {
|
|
|
44900
45408
|
return;
|
|
44901
45409
|
}
|
|
44902
45410
|
if (res.status === 403 || res.status === 404) {
|
|
44903
|
-
const
|
|
44904
|
-
const lower =
|
|
45411
|
+
const text3 = await res.text();
|
|
45412
|
+
const lower = text3.toLowerCase();
|
|
44905
45413
|
if (V2_NOT_ENABLED_MARKERS.some((marker) => lower.includes(marker))) {
|
|
44906
45414
|
throw new WorkflowV2NotEnabledError();
|
|
44907
45415
|
}
|
|
44908
|
-
const truncated2 =
|
|
45416
|
+
const truncated2 = text3.length > 200 ? `${text3.slice(0, 200)}\u2026` : text3;
|
|
44909
45417
|
throw new Error(`GET ${WORKFLOW_V2_PROBE_PATH}: HTTP ${res.status}: ${truncated2}`);
|
|
44910
45418
|
}
|
|
44911
|
-
const
|
|
44912
|
-
const truncated =
|
|
45419
|
+
const text2 = await res.text();
|
|
45420
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
44913
45421
|
throw new Error(`GET ${WORKFLOW_V2_PROBE_PATH}: HTTP ${res.status}: ${truncated}`);
|
|
44914
45422
|
}
|
|
44915
45423
|
var MEC_NOT_ENABLED_MARKERS = [
|
|
@@ -44982,16 +45490,16 @@ async function runMecProbe(client, options) {
|
|
|
44982
45490
|
return;
|
|
44983
45491
|
}
|
|
44984
45492
|
if (res.status === 403 || res.status === 404) {
|
|
44985
|
-
const
|
|
44986
|
-
const lower =
|
|
45493
|
+
const text3 = await res.text();
|
|
45494
|
+
const lower = text3.toLowerCase();
|
|
44987
45495
|
if (MEC_NOT_ENABLED_MARKERS.some((marker) => lower.includes(marker))) {
|
|
44988
45496
|
throw new MecNotEnabledError();
|
|
44989
45497
|
}
|
|
44990
|
-
const truncated2 =
|
|
45498
|
+
const truncated2 = text3.length > 200 ? `${text3.slice(0, 200)}\u2026` : text3;
|
|
44991
45499
|
throw new Error(`GET ${MEC_PROBE_PATH}: HTTP ${res.status}: ${truncated2}`);
|
|
44992
45500
|
}
|
|
44993
|
-
const
|
|
44994
|
-
const truncated =
|
|
45501
|
+
const text2 = await res.text();
|
|
45502
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
44995
45503
|
throw new Error(`GET ${MEC_PROBE_PATH}: HTTP ${res.status}: ${truncated}`);
|
|
44996
45504
|
}
|
|
44997
45505
|
var SHARE_DATA_FLAG = "--yes-share-data";
|
|
@@ -51539,8 +52047,8 @@ async function putTransactions(client, params, payload, options) {
|
|
|
51539
52047
|
async function rescanTemplateRules(client, params, options) {
|
|
51540
52048
|
const path11 = `/api/templates/${params.templateId}/rules/rescan`;
|
|
51541
52049
|
const res = await client.do("POST", path11, void 0, options);
|
|
51542
|
-
const
|
|
51543
|
-
let body =
|
|
52050
|
+
const text2 = await res.text();
|
|
52051
|
+
let body = text2;
|
|
51544
52052
|
if (body.startsWith('"') && body.endsWith('"') && body.length >= 2) {
|
|
51545
52053
|
try {
|
|
51546
52054
|
body = JSON.parse(body);
|
|
@@ -51616,8 +52124,8 @@ async function exportRulesCsv(client, params, options) {
|
|
|
51616
52124
|
const path11 = `/api/templates/${params.templateId}/rules/export_to_csv${qs}`;
|
|
51617
52125
|
const res = await client.do("POST", path11, void 0, options);
|
|
51618
52126
|
if (res.status < 200 || res.status >= 300) {
|
|
51619
|
-
const
|
|
51620
|
-
const truncated =
|
|
52127
|
+
const text2 = await res.text();
|
|
52128
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
51621
52129
|
throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
51622
52130
|
}
|
|
51623
52131
|
const csv = await res.text();
|
|
@@ -51643,8 +52151,8 @@ async function deleteHiddenRules(client, params, customerTransactionIds, options
|
|
|
51643
52151
|
const body = JSON.stringify(customerTransactionIds);
|
|
51644
52152
|
const res = await client.do("DELETE", path11, body, options);
|
|
51645
52153
|
if (res.status < 200 || res.status >= 300) {
|
|
51646
|
-
const
|
|
51647
|
-
const truncated =
|
|
52154
|
+
const text2 = await res.text();
|
|
52155
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
51648
52156
|
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
51649
52157
|
}
|
|
51650
52158
|
await res.text();
|
|
@@ -51652,8 +52160,8 @@ async function deleteHiddenRules(client, params, customerTransactionIds, options
|
|
|
51652
52160
|
async function triggerAiRules(client, options) {
|
|
51653
52161
|
const path11 = `/api/templates/ai-rules`;
|
|
51654
52162
|
const res = await client.do("POST", path11, void 0, options);
|
|
51655
|
-
const
|
|
51656
|
-
let body =
|
|
52163
|
+
const text2 = await res.text();
|
|
52164
|
+
let body = text2;
|
|
51657
52165
|
if (body.startsWith('"') && body.endsWith('"') && body.length >= 2) {
|
|
51658
52166
|
try {
|
|
51659
52167
|
body = JSON.parse(body);
|
|
@@ -51963,8 +52471,8 @@ async function readCsvImportPayload(path11) {
|
|
|
51963
52471
|
}
|
|
51964
52472
|
return parseCsvImportText(raw);
|
|
51965
52473
|
}
|
|
51966
|
-
function parseCsvImportText(
|
|
51967
|
-
const rows = parseCsvRows(
|
|
52474
|
+
function parseCsvImportText(text2) {
|
|
52475
|
+
const rows = parseCsvRows(text2);
|
|
51968
52476
|
if (rows.length === 0) {
|
|
51969
52477
|
throw new Error("--file: CSV is empty");
|
|
51970
52478
|
}
|
|
@@ -52069,24 +52577,24 @@ function parseClause(clause, lineNo, clauseIdx) {
|
|
|
52069
52577
|
args: values[0]
|
|
52070
52578
|
};
|
|
52071
52579
|
}
|
|
52072
|
-
function parseQuotedValueList(
|
|
52580
|
+
function parseQuotedValueList(text2, lineNo, clauseIdx) {
|
|
52073
52581
|
const out = [];
|
|
52074
52582
|
let i = 0;
|
|
52075
|
-
while (i <
|
|
52076
|
-
while (i <
|
|
52077
|
-
if (i >=
|
|
52078
|
-
if (
|
|
52583
|
+
while (i < text2.length) {
|
|
52584
|
+
while (i < text2.length && (text2[i] === " " || text2[i] === ",")) i++;
|
|
52585
|
+
if (i >= text2.length) break;
|
|
52586
|
+
if (text2[i] !== "'") {
|
|
52079
52587
|
throw new Error(
|
|
52080
|
-
`--file: line ${lineNo} clause ${clauseIdx + 1}: expected single-quoted value at offset ${i} in "${truncate7(
|
|
52588
|
+
`--file: line ${lineNo} clause ${clauseIdx + 1}: expected single-quoted value at offset ${i} in "${truncate7(text2, 80)}"`
|
|
52081
52589
|
);
|
|
52082
52590
|
}
|
|
52083
52591
|
i++;
|
|
52084
52592
|
let v = "";
|
|
52085
52593
|
let closed = false;
|
|
52086
|
-
while (i <
|
|
52087
|
-
const ch =
|
|
52594
|
+
while (i < text2.length) {
|
|
52595
|
+
const ch = text2[i];
|
|
52088
52596
|
if (ch === "'") {
|
|
52089
|
-
if (i + 1 <
|
|
52597
|
+
if (i + 1 < text2.length && text2[i + 1] === "'") {
|
|
52090
52598
|
v += "'";
|
|
52091
52599
|
i += 2;
|
|
52092
52600
|
continue;
|
|
@@ -52100,27 +52608,27 @@ function parseQuotedValueList(text, lineNo, clauseIdx) {
|
|
|
52100
52608
|
}
|
|
52101
52609
|
if (!closed) {
|
|
52102
52610
|
throw new Error(
|
|
52103
|
-
`--file: line ${lineNo} clause ${clauseIdx + 1}: unterminated single-quoted value in "${truncate7(
|
|
52611
|
+
`--file: line ${lineNo} clause ${clauseIdx + 1}: unterminated single-quoted value in "${truncate7(text2, 80)}"`
|
|
52104
52612
|
);
|
|
52105
52613
|
}
|
|
52106
52614
|
out.push(v);
|
|
52107
52615
|
}
|
|
52108
52616
|
if (out.length === 0) {
|
|
52109
52617
|
throw new Error(
|
|
52110
|
-
`--file: line ${lineNo} clause ${clauseIdx + 1}: no quoted values found in "${truncate7(
|
|
52618
|
+
`--file: line ${lineNo} clause ${clauseIdx + 1}: no quoted values found in "${truncate7(text2, 80)}"`
|
|
52111
52619
|
);
|
|
52112
52620
|
}
|
|
52113
52621
|
return out;
|
|
52114
52622
|
}
|
|
52115
|
-
function splitOutsideQuotes(
|
|
52623
|
+
function splitOutsideQuotes(text2, sep) {
|
|
52116
52624
|
const out = [];
|
|
52117
52625
|
let buf = "";
|
|
52118
52626
|
let i = 0;
|
|
52119
52627
|
let inQuote = false;
|
|
52120
|
-
while (i <
|
|
52121
|
-
const ch =
|
|
52628
|
+
while (i < text2.length) {
|
|
52629
|
+
const ch = text2[i];
|
|
52122
52630
|
if (ch === "'") {
|
|
52123
|
-
if (inQuote && i + 1 <
|
|
52631
|
+
if (inQuote && i + 1 < text2.length && text2[i + 1] === "'") {
|
|
52124
52632
|
buf += "''";
|
|
52125
52633
|
i += 2;
|
|
52126
52634
|
continue;
|
|
@@ -52130,7 +52638,7 @@ function splitOutsideQuotes(text, sep) {
|
|
|
52130
52638
|
i++;
|
|
52131
52639
|
continue;
|
|
52132
52640
|
}
|
|
52133
|
-
if (!inQuote &&
|
|
52641
|
+
if (!inQuote && text2.startsWith(sep, i)) {
|
|
52134
52642
|
out.push(buf);
|
|
52135
52643
|
buf = "";
|
|
52136
52644
|
i += sep.length;
|
|
@@ -53633,35 +54141,35 @@ var REGISTRY = "https://datarails.jfrog.io/artifactory/api/npm/dr-cli-virtual";
|
|
|
53633
54141
|
var PACKAGE = "@datarails-ai/dr-cli";
|
|
53634
54142
|
function spawnInherit(command, args) {
|
|
53635
54143
|
return new Promise((resolve3) => {
|
|
53636
|
-
const
|
|
54144
|
+
const child2 = spawn2(command, args, {
|
|
53637
54145
|
stdio: "inherit",
|
|
53638
54146
|
// Windows resolves `npm` as `npm.cmd`; `shell: true` lets cmd.exe do
|
|
53639
54147
|
// the resolution without us having to special-case the suffix.
|
|
53640
54148
|
shell: true
|
|
53641
54149
|
});
|
|
53642
|
-
|
|
54150
|
+
child2.on("close", (code) => {
|
|
53643
54151
|
resolve3(code ?? 1);
|
|
53644
54152
|
});
|
|
53645
|
-
|
|
54153
|
+
child2.on("error", () => {
|
|
53646
54154
|
resolve3(1);
|
|
53647
54155
|
});
|
|
53648
54156
|
});
|
|
53649
54157
|
}
|
|
53650
54158
|
function captureVersion() {
|
|
53651
54159
|
return new Promise((resolve3) => {
|
|
53652
|
-
const
|
|
54160
|
+
const child2 = spawn2("dr", ["--version"], { shell: true });
|
|
53653
54161
|
let out = "";
|
|
53654
|
-
|
|
54162
|
+
child2.stdout.on("data", (chunk) => {
|
|
53655
54163
|
out += chunk.toString();
|
|
53656
54164
|
});
|
|
53657
|
-
|
|
54165
|
+
child2.on("close", (code) => {
|
|
53658
54166
|
if (code !== 0) {
|
|
53659
54167
|
resolve3(null);
|
|
53660
54168
|
return;
|
|
53661
54169
|
}
|
|
53662
54170
|
resolve3(out.trim());
|
|
53663
54171
|
});
|
|
53664
|
-
|
|
54172
|
+
child2.on("error", () => resolve3(null));
|
|
53665
54173
|
});
|
|
53666
54174
|
}
|
|
53667
54175
|
async function runUpdate() {
|
|
@@ -53733,8 +54241,8 @@ async function deleteEntity(client, body, options) {
|
|
|
53733
54241
|
const path11 = "/bo/pre_kickoff/qbo_manage_companies/v2";
|
|
53734
54242
|
const res = await client.do("DELETE", path11, JSON.stringify(body), options);
|
|
53735
54243
|
if (res.status < 200 || res.status >= 300) {
|
|
53736
|
-
const
|
|
53737
|
-
const truncated =
|
|
54244
|
+
const text2 = await res.text();
|
|
54245
|
+
const truncated = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
|
|
53738
54246
|
throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncated}`);
|
|
53739
54247
|
}
|
|
53740
54248
|
}
|
|
@@ -59712,11 +60220,11 @@ async function extractSync(cfg, parts) {
|
|
|
59712
60220
|
async function emitExtractionDraft(cfg, allResults, sourceFiles, outcomes, abortedMidRun) {
|
|
59713
60221
|
const failed = outcomes.filter((o) => !o.ok);
|
|
59714
60222
|
if (cfg.asRawJson) {
|
|
59715
|
-
const
|
|
60223
|
+
const text3 = JSON.stringify(allResults, null, 2);
|
|
59716
60224
|
if (cfg.outputPath !== void 0) {
|
|
59717
|
-
await fsPromises3.writeFile(cfg.outputPath,
|
|
60225
|
+
await fsPromises3.writeFile(cfg.outputPath, text3 + "\n", "utf8");
|
|
59718
60226
|
} else {
|
|
59719
|
-
cfg.out.write(
|
|
60227
|
+
cfg.out.write(text3 + "\n");
|
|
59720
60228
|
}
|
|
59721
60229
|
reportFileOutcomes(cfg.err, outcomes, abortedMidRun);
|
|
59722
60230
|
throwIfAnyFileFailed(failed, outcomes.length);
|
|
@@ -59728,13 +60236,13 @@ async function emitExtractionDraft(cfg, allResults, sourceFiles, outcomes, abort
|
|
|
59728
60236
|
tenantServer: cfg.serverKey,
|
|
59729
60237
|
defaults: cfg.defaults
|
|
59730
60238
|
});
|
|
59731
|
-
const
|
|
60239
|
+
const text2 = JSON.stringify(draft, null, 2);
|
|
59732
60240
|
if (cfg.outputPath !== void 0) {
|
|
59733
|
-
await fsPromises3.writeFile(cfg.outputPath,
|
|
60241
|
+
await fsPromises3.writeFile(cfg.outputPath, text2 + "\n", "utf8");
|
|
59734
60242
|
cfg.err.write(`wrote ${cfg.outputPath}
|
|
59735
60243
|
`);
|
|
59736
60244
|
} else {
|
|
59737
|
-
cfg.out.write(
|
|
60245
|
+
cfg.out.write(text2 + "\n");
|
|
59738
60246
|
}
|
|
59739
60247
|
const review = draft._meta?.review_required ?? [];
|
|
59740
60248
|
const failures = draft._meta?.ai_failures ?? [];
|
|
@@ -60223,14 +60731,14 @@ async function collectResourceIds(args, fromPath, labels = {}) {
|
|
|
60223
60731
|
raw.push(...a.split(",").map((s) => s.trim()));
|
|
60224
60732
|
}
|
|
60225
60733
|
if (fromPath !== void 0 && fromPath !== "") {
|
|
60226
|
-
let
|
|
60734
|
+
let text2;
|
|
60227
60735
|
try {
|
|
60228
|
-
|
|
60736
|
+
text2 = await fsPromises3.readFile(fromPath, "utf8");
|
|
60229
60737
|
} catch (err) {
|
|
60230
60738
|
const m = err instanceof Error ? err.message : String(err);
|
|
60231
60739
|
throw new Error(`read --from: ${m}`);
|
|
60232
60740
|
}
|
|
60233
|
-
for (const line of
|
|
60741
|
+
for (const line of text2.split(/\r?\n/)) {
|
|
60234
60742
|
const stripped = line.split("#")[0] ?? "";
|
|
60235
60743
|
raw.push(...stripped.split(",").map((s) => s.trim()));
|
|
60236
60744
|
}
|
|
@@ -63816,27 +64324,27 @@ function groupAnswer(group, below) {
|
|
|
63816
64324
|
function filterBelow(node, scopes, map, armed) {
|
|
63817
64325
|
const here = { count: 0, answer: void 0, required: [], denials: [] };
|
|
63818
64326
|
let allAnswered = node.commands.length > 0;
|
|
63819
|
-
for (const
|
|
63820
|
-
if (
|
|
63821
|
-
const below = filterBelow(
|
|
64327
|
+
for (const child2 of node.commands) {
|
|
64328
|
+
if (child2.commands.length > 0) {
|
|
64329
|
+
const below = filterBelow(child2, scopes, map, armed);
|
|
63822
64330
|
here.count += below.count;
|
|
63823
64331
|
if (below.answer === void 0) {
|
|
63824
64332
|
allAnswered = false;
|
|
63825
64333
|
continue;
|
|
63826
64334
|
}
|
|
63827
|
-
interceptGroup(
|
|
63828
|
-
hide(
|
|
64335
|
+
interceptGroup(child2, below.answer);
|
|
64336
|
+
hide(child2);
|
|
63829
64337
|
addRequired(here, below.required);
|
|
63830
64338
|
addDenials(here, below.denials);
|
|
63831
64339
|
continue;
|
|
63832
64340
|
}
|
|
63833
|
-
const answer = leafAnswer(
|
|
64341
|
+
const answer = leafAnswer(child2, scopes, map);
|
|
63834
64342
|
if (answer === void 0) {
|
|
63835
64343
|
allAnswered = false;
|
|
63836
64344
|
continue;
|
|
63837
64345
|
}
|
|
63838
|
-
intercept(
|
|
63839
|
-
hide(
|
|
64346
|
+
intercept(child2, answer.err, armed);
|
|
64347
|
+
hide(child2);
|
|
63840
64348
|
here.count += 1;
|
|
63841
64349
|
addRequired(here, answer.required);
|
|
63842
64350
|
if (answer.denial !== void 0) addDenials(here, [answer.denial]);
|
|
@@ -63959,7 +64467,7 @@ function registersServerFlag(cmd) {
|
|
|
63959
64467
|
}
|
|
63960
64468
|
function isServerBound(cmd) {
|
|
63961
64469
|
if (cmd.commands.length === 0) return registersServerFlag(cmd);
|
|
63962
|
-
return cmd.commands.every((
|
|
64470
|
+
return cmd.commands.every((child2) => isServerBound(child2));
|
|
63963
64471
|
}
|
|
63964
64472
|
function isOpenWithoutServer(cmd) {
|
|
63965
64473
|
return SERVER_OPTIONAL_COMMANDS.has(cmd.name()) || !isServerBound(cmd);
|
|
@@ -64264,6 +64772,7 @@ function buildRootCommand() {
|
|
|
64264
64772
|
registerDynamicRangesCommand(root);
|
|
64265
64773
|
registerFunctionsCommand(root);
|
|
64266
64774
|
registerSemanticTablesCommand(root);
|
|
64775
|
+
registerODataCommand(root);
|
|
64267
64776
|
registerStoryboardsCommand(root);
|
|
64268
64777
|
registerExTablesCommand(root);
|
|
64269
64778
|
registerLutCommand(root);
|
|
@@ -64416,8 +64925,8 @@ function redactUnknownOption(match, prefix, token) {
|
|
|
64416
64925
|
if (!looksLikeFlag(name)) return `${prefix}<redacted>'`;
|
|
64417
64926
|
return eq === -1 ? match : `${prefix}${name}=<redacted>'`;
|
|
64418
64927
|
}
|
|
64419
|
-
function redactCommanderValues(
|
|
64420
|
-
return
|
|
64928
|
+
function redactCommanderValues(text2) {
|
|
64929
|
+
return text2.replace(UNKNOWN_OPTION_PATTERN, redactUnknownOption).replace(UNKNOWN_COMMAND_PATTERN, "$1<redacted>'").replace(INVALID_OPTION_ARGUMENT_PATTERN, "$1<redacted>$2").replace(INVALID_ENV_VALUE_PATTERN, "$1<redacted>$2").replace(INVALID_COMMAND_ARGUMENT_PATTERN, "$1<redacted>$2");
|
|
64421
64930
|
}
|
|
64422
64931
|
async function main() {
|
|
64423
64932
|
let root;
|