@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/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.72",
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.4",
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-30T11:21:03.379Z";
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, text) {
581
+ function parseScopeDenial(status2, text2) {
581
582
  if (status2 !== 403) return void 0;
582
583
  let body;
583
584
  try {
584
- body = JSON.parse(text);
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(text, label) {
702
+ function parseTokenBody(text2, label) {
702
703
  let raw;
703
704
  try {
704
- raw = JSON.parse(text);
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 text = await res.text();
731
+ const text2 = await res.text();
731
732
  if (!res.ok) {
732
- throw new Error(`jwt mint: HTTP ${res.status}: ${truncate(text, TRUNCATE)}`);
733
+ throw new Error(`jwt mint: HTTP ${res.status}: ${truncate(text2, TRUNCATE)}`);
733
734
  }
734
- const out = parseTokenBody(text, "mint");
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 text = await res.text();
758
+ const text2 = await res.text();
758
759
  if (!res.ok) {
759
- throw new Error(`jwt refresh: HTTP ${res.status}: ${truncate(text, TRUNCATE)}`);
760
+ throw new Error(`jwt refresh: HTTP ${res.status}: ${truncate(text2, TRUNCATE)}`);
760
761
  }
761
- const out = parseTokenBody(text, "refresh");
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 text = await res.text();
782
+ const text2 = await res.text();
782
783
  if (!res.ok) {
783
- throw new Error(`jwt external refresh: HTTP ${res.status}: ${truncate(text, TRUNCATE)}`);
784
+ throw new Error(`jwt external refresh: HTTP ${res.status}: ${truncate(text2, TRUNCATE)}`);
784
785
  }
785
- const out = parseTokenBody(text, "refresh");
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 text = await res.text();
814
+ const text2 = await res.text();
814
815
  if (!res.ok) {
815
816
  let code;
816
817
  try {
817
- const value = JSON.parse(text)["error"];
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(text);
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 text = await res.text();
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(text);
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(text, 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(text);
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 text = await res.text();
2249
- _AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status, text);
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(text, 200)}`);
2255
+ throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
2255
2256
  }
2256
- if (text === "" || text === '""') return null;
2257
+ if (text2 === "" || text2 === '""') return null;
2257
2258
  try {
2258
- return JSON.parse(text);
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 text = await res.text();
2300
- _AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status, text);
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(text, 200)}`);
2306
+ throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
2306
2307
  }
2307
- if (text === "" || text === '""') return null;
2308
+ if (text2 === "" || text2 === '""') return null;
2308
2309
  try {
2309
- return JSON.parse(text);
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 text = await res.text();
2359
- _AuthorizedClient.throwIfScopeDeniedBody("POST", path11, res.status, text);
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(text, 200)}`);
2365
+ throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate2(text2, 200)}`);
2365
2366
  }
2366
- if (text === "" || text === '""') return null;
2367
+ if (text2 === "" || text2 === '""') return null;
2367
2368
  try {
2368
- return JSON.parse(text);
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 text2 = await res.text();
2430
- _AuthorizedClient.throwIfScopeDeniedBody(method, path11, res.status, text2);
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(text2, 200)}`
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 text = await res.text();
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(text, 200)}`);
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 (text === "" || text === '""') return null;
2452
+ if (text2 === "" || text2 === '""') return null;
2452
2453
  try {
2453
- return JSON.parse(text);
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 text;
2526
+ let text2;
2526
2527
  try {
2527
- text = await res.clone().text();
2528
+ text2 = await res.clone().text();
2528
2529
  } catch {
2529
2530
  return;
2530
2531
  }
2531
- _AuthorizedClient.throwIfScopeDeniedBody(method, path11, res.status, text);
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, text) {
2536
- const denial = parseScopeDenial(status2, text);
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 child = spawn(probe, [cmd], { stdio: "ignore" });
3428
- child.on("error", () => resolve3(false));
3429
- child.on("close", (code) => resolve3(code === 0));
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 child = spawn(cmd, args, {
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
- child.stdout.on("data", (c) => {
3456
+ child2.stdout.on("data", (c) => {
3456
3457
  stdout += c.toString("utf8");
3457
3458
  });
3458
- child.stderr.on("data", (c) => {
3459
+ child2.stderr.on("data", (c) => {
3459
3460
  stderr += c.toString("utf8");
3460
3461
  });
3461
- child.on("error", reject);
3462
- child.on("close", (code) => resolve3({ code: code ?? 0, stdout, stderr }));
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(text) {
4600
+ function parseScopesMap(text2) {
4593
4601
  let raw;
4594
4602
  try {
4595
- raw = JSON.parse(text);
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 text;
4637
+ let text2;
4630
4638
  try {
4631
- text = readFileSync(path3.join(here, "scopes-map.json"), "utf8");
4639
+ text2 = readFileSync(path3.join(here, "scopes-map.json"), "utf8");
4632
4640
  } catch {
4633
4641
  return void 0;
4634
4642
  }
4635
- return parseScopesMap(text);
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 child = childNamed(cmd, token);
4656
- if (child === void 0) break;
4657
- names.push(child.name());
4658
- cmd = child;
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 child of cmd.commands) {
4676
- for (const opt of child.options) {
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, child)) return true;
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 text = await res.text();
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} ${text.trim()}${hint}`);
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(text);
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(text) {
5060
+ function parseObject(text2) {
5053
5061
  let raw;
5054
5062
  try {
5055
- raw = JSON.parse(text);
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(text) {
5066
- const obj = parseObject(text);
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(text) {
5084
+ function tryParseErrorCode(text2) {
5077
5085
  let raw;
5078
5086
  try {
5079
- raw = JSON.parse(text);
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, (text) => {
5089
- const tok = parseTokenResponse(text);
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, (text) => {
5098
- const obj = parseObject(text);
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 text = await res.text();
5141
+ const text2 = await res.text();
5134
5142
  if (res.ok) {
5135
- return onSuccess(text);
5143
+ return onSuccess(text2);
5136
5144
  }
5137
- const errCode = tryParseErrorCode(text);
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}: ${text.trim()}`);
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 text = await res.text();
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(text);
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(text);
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(text, 200)}`);
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 text = await res.text();
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(text);
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(text, 200)}`
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(text);
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(text, 200)}`);
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 text = await res.text();
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(text, 200)}`);
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 text = await res.text();
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(text, 200)}`);
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 text = await res.text();
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(text, 200)}`);
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 text = await res.text();
5762
+ const text2 = await res.text();
5755
5763
  if (res.status === 400) {
5756
5764
  let parsed2;
5757
5765
  try {
5758
- parsed2 = JSON.parse(text);
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(text, 200)}`);
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 text = await res.text();
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(text)) {
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(text, 200)}`);
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 text = await res.text();
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(text)) {
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(text, 200)}`);
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 text = await res.text();
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(text, 200)}`);
7076
+ throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
7069
7077
  }
7070
- return parsePermissionGroup("POST", path11, text);
7078
+ return parsePermissionGroup("POST", path11, text2);
7071
7079
  }
7072
- function parsePermissionGroup(method, path11, text) {
7080
+ function parsePermissionGroup(method, path11, text2) {
7073
7081
  try {
7074
- return JSON.parse(text);
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(text, 200)})`);
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 text = await res.text();
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(text, 200)}`);
7093
+ throw new Error(`GET ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
7086
7094
  }
7087
- return parsePermissionGroup("GET", path11, text);
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 text = await res.text();
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(text, 200)}`);
7102
+ throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate4(text2, 200)}`);
7095
7103
  }
7096
- return parsePermissionGroup("PUT", path11, text);
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 text = await res.text();
7103
- throw new Error(`DELETE ${path11}: HTTP ${res.status}: ${truncate4(text, 200)}`);
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, text) {
7114
+ function decodeJsonBody(method, path11, text2) {
7107
7115
  try {
7108
- return JSON.parse(text);
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(text, 200)})`);
7119
+ throw new Error(`${method} ${path11}: decode: ${msg} (body: ${truncate4(text2, 200)})`);
7112
7120
  }
7113
7121
  }
7114
- function redactPasswordsInBodyText(text) {
7115
- return text.replace(/"password"\s*:\s*"(?:[^"\\]|\\.)*"/g, '"password":"[redacted]"');
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 text = await res.text();
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(text), 600)}`
7130
+ `${method} ${path11}: HTTP ${res.status}: ${truncate4(redactPasswordsInBodyText(text2), 600)}`
7123
7131
  );
7124
7132
  }
7125
- return decodeJsonBody(method, path11, text);
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(text) {
7169
- const normalized = text.replace(/\r\n/g, "\n").replace(/\n$/, "");
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(text) {
7249
- const withoutBom = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
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 text = await res.text();
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(text, 200)}`);
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 text = await res.text();
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(text, 200)}`);
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(text) {
8159
- const withoutBom = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
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(text) {
8593
- const withoutBom = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
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(text) {
10227
- const withoutBom = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
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(text) {
11893
- const trimmed = text.trim();
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 text = await res.text();
11968
+ const text2 = await res.text();
11958
11969
  throw new Error(
11959
- `${label} POST: expected 202, got ${res.status}: ${describeFinanceOsFailure(text)}`
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 text2 = await res.text();
12014
+ const text3 = await res.text();
12004
12015
  let parsed2;
12005
12016
  try {
12006
- parsed2 = text2 === "" ? null : JSON.parse(text2);
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 text = await res.text();
12028
+ const text2 = await res.text();
12018
12029
  throw new Error(
12019
- `poll ${label}: unexpected status ${res.status}: ${describeFinanceOsFailure(text)}`
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 child of node.children ?? []) walk(child, depth + 1);
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 text = await res.text();
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(text)}`);
16919
+ throw new Error(`POST ${path11}: HTTP ${res.status}: ${truncateBody(text2)}`);
16412
16920
  }
16413
- function extractCacheKey(text) {
16921
+ function extractCacheKey(text2) {
16414
16922
  try {
16415
- const parsed2 = JSON.parse(text);
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(text) {
16422
- let message = text.trim();
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 text = await res.text();
16458
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = await res.text();
16497
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = await res.text();
16624
- throw new Error(`document-job status: unexpected HTTP ${res.status}: ${text.trim()}`);
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 text = await res.text();
17135
+ const text2 = await res.text();
16628
17136
  try {
16629
- const parsed2 = JSON.parse(text);
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 text.trim();
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 text = await res.text();
17384
+ const text2 = await res.text();
16877
17385
  if (res.status < 200 || res.status >= 300) {
16878
- throw new Error(`GET ${path11}: HTTP ${res.status}: ${text.slice(0, 200)}`);
17386
+ throw new Error(`GET ${path11}: HTTP ${res.status}: ${text2.slice(0, 200)}`);
16879
17387
  }
16880
- if (text === "" || text === '""') return null;
17388
+ if (text2 === "" || text2 === '""') return null;
16881
17389
  try {
16882
- return JSON.parse(text);
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 text;
21481
+ let text2;
20974
21482
  try {
20975
- text = await readFile2(path11, "utf8");
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(text);
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 text = await res.text();
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(text, 200)}`);
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(text, 200)}`);
25294
+ throw new Error(`PUT ${path11}: HTTP ${res.status}: ${truncate5(text2, 200)}`);
24787
25295
  }
24788
- if (text === "" || text === '""') {
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(text) };
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 text = await res.text();
26700
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = Buffer.from(routerBytes(s)).toString("utf8");
28489
- const trailingNl = text.endsWith("\n") ? "" : "\n";
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
- ${text}${trailingNl}${pointer}`;
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 children = Array.isArray(result.split_documents) ? result.split_documents : [];
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}): ${children.length} child file(s) under parent ${JSON.stringify(parentName)}.
31068
+ `Split created (id=${result.id}): ${children2.length} child file(s) under parent ${JSON.stringify(parentName)}.
30561
31069
  `
30562
31070
  );
30563
- for (const child of children) {
30564
- const name = typeof child.name === "string" ? child.name : "(unnamed)";
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 children = Array.isArray(s.split_documents) ? String(s.split_documents.length) : "0";
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
- children,
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 text = await res.text();
32230
+ const text2 = await res.text();
31723
32231
  if (res.status === 200) {
31724
32232
  let parsed2;
31725
32233
  try {
31726
- parsed2 = JSON.parse(text);
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: text };
32239
+ return { status: 200, body: parsed2, rawText: text2 };
31732
32240
  }
31733
32241
  if (res.status === 404) {
31734
- return { status: 404, body: null, rawText: text };
32242
+ return { status: 404, body: null, rawText: text2 };
31735
32243
  }
31736
- throw new Error(`error explanation: unexpected status ${res.status}: ${text.trim()}`);
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 text = await res.text();
31755
- return { status: res.status, rawText: text };
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 text = await res.text();
31776
- return { status: res.status, rawText: text };
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 text = await res.text();
31856
- return { status: res.status, rawText: text };
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 text = await res.text();
32368
+ const text2 = await res.text();
31861
32369
  if (res.status < 200 || res.status >= 300) {
31862
- throw new Error(`resync: HTTP ${res.status}: ${text.trim()}`);
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 text = await res.text();
40850
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = await res.text();
41416
+ const text2 = await res.text();
40909
41417
  if (res.status === 200 || res.status === 409) {
40910
- if (text === "" || text === '""') {
41418
+ if (text2 === "" || text2 === '""') {
40911
41419
  return { status: "", remaining_files: 0, message: "" };
40912
41420
  }
40913
41421
  try {
40914
- return JSON.parse(text);
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 = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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(text) {
41078
- const withoutBom = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
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 text = await res.text();
44455
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text2 = await res.text();
44904
- const lower = text2.toLowerCase();
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 = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
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 text = await res.text();
44912
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text2 = await res.text();
44986
- const lower = text2.toLowerCase();
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 = text2.length > 200 ? `${text2.slice(0, 200)}\u2026` : text2;
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 text = await res.text();
44994
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = await res.text();
51543
- let body = text;
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 text = await res.text();
51620
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = await res.text();
51647
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text = await res.text();
51656
- let body = text;
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(text) {
51967
- const rows = parseCsvRows(text);
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(text, lineNo, clauseIdx) {
52580
+ function parseQuotedValueList(text2, lineNo, clauseIdx) {
52073
52581
  const out = [];
52074
52582
  let i = 0;
52075
- while (i < text.length) {
52076
- while (i < text.length && (text[i] === " " || text[i] === ",")) i++;
52077
- if (i >= text.length) break;
52078
- if (text[i] !== "'") {
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(text, 80)}"`
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 < text.length) {
52087
- const ch = text[i];
52594
+ while (i < text2.length) {
52595
+ const ch = text2[i];
52088
52596
  if (ch === "'") {
52089
- if (i + 1 < text.length && text[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(text, 80)}"`
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(text, 80)}"`
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(text, sep) {
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 < text.length) {
52121
- const ch = text[i];
52628
+ while (i < text2.length) {
52629
+ const ch = text2[i];
52122
52630
  if (ch === "'") {
52123
- if (inQuote && i + 1 < text.length && text[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 && text.startsWith(sep, i)) {
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 child = spawn2(command, args, {
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
- child.on("close", (code) => {
54150
+ child2.on("close", (code) => {
53643
54151
  resolve3(code ?? 1);
53644
54152
  });
53645
- child.on("error", () => {
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 child = spawn2("dr", ["--version"], { shell: true });
54160
+ const child2 = spawn2("dr", ["--version"], { shell: true });
53653
54161
  let out = "";
53654
- child.stdout.on("data", (chunk) => {
54162
+ child2.stdout.on("data", (chunk) => {
53655
54163
  out += chunk.toString();
53656
54164
  });
53657
- child.on("close", (code) => {
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
- child.on("error", () => resolve3(null));
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 text = await res.text();
53737
- const truncated = text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;
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 text2 = JSON.stringify(allResults, null, 2);
60223
+ const text3 = JSON.stringify(allResults, null, 2);
59716
60224
  if (cfg.outputPath !== void 0) {
59717
- await fsPromises3.writeFile(cfg.outputPath, text2 + "\n", "utf8");
60225
+ await fsPromises3.writeFile(cfg.outputPath, text3 + "\n", "utf8");
59718
60226
  } else {
59719
- cfg.out.write(text2 + "\n");
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 text = JSON.stringify(draft, null, 2);
60239
+ const text2 = JSON.stringify(draft, null, 2);
59732
60240
  if (cfg.outputPath !== void 0) {
59733
- await fsPromises3.writeFile(cfg.outputPath, text + "\n", "utf8");
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(text + "\n");
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 text;
60734
+ let text2;
60227
60735
  try {
60228
- text = await fsPromises3.readFile(fromPath, "utf8");
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 text.split(/\r?\n/)) {
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 child of node.commands) {
63820
- if (child.commands.length > 0) {
63821
- const below = filterBelow(child, scopes, map, armed);
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(child, below.answer);
63828
- hide(child);
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(child, scopes, map);
64341
+ const answer = leafAnswer(child2, scopes, map);
63834
64342
  if (answer === void 0) {
63835
64343
  allAnswered = false;
63836
64344
  continue;
63837
64345
  }
63838
- intercept(child, answer.err, armed);
63839
- hide(child);
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((child) => isServerBound(child));
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(text) {
64420
- return text.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");
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;