@burdenoff/bigconsole-cli 2026.802.1 → 2026.1029.1

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.
@@ -38,10 +38,10 @@ export const LIST_DASHBOARDS = `
38
38
  $first: Int
39
39
  $after: String
40
40
  $search: String
41
- $visibility: DashboardVisibility
42
- $category: DashboardCategory
41
+ $visibility: BigConsoleDashboardVisibility
42
+ $category: BigConsoleDashboardCategory
43
43
  $includeArchived: Boolean
44
- $sortBy: DashboardSortField
44
+ $sortBy: BigConsoleDashboardSortField
45
45
  $sortOrder: SortOrder
46
46
  ) {
47
47
  listDashboards(
@@ -106,7 +106,7 @@ export const DELETE_DASHBOARD = `
106
106
  // Widgets (workspace gateway)
107
107
  // ---------------------------------------------------------------------------
108
108
  export const LIST_WIDGETS = `
109
- query ListWidgets($pageId: ID!, $first: Int, $after: String, $type: WidgetType) {
109
+ query ListWidgets($pageId: ID!, $first: Int, $after: String, $type: BigConsoleWidgetType) {
110
110
  listWidgets(pageId: $pageId, first: $first, after: $after, type: $type) {
111
111
  edges {
112
112
  node {
@@ -204,12 +204,25 @@ export const GET_DATASINK = `
204
204
  `;
205
205
  export const GET_DATASINK_DATA = `
206
206
  query GetDataSinkData($id: ID, $key: String, $dataPath: String, $forceRefresh: Boolean) {
207
- getDataSinkData(id: $id, key: $key, dataPath: $dataPath, forceRefresh: $forceRefresh)
207
+ getDataSinkData(id: $id, key: $key, dataPath: $dataPath, forceRefresh: $forceRefresh) {
208
+ raw
209
+ extracted
210
+ cached
211
+ fetchedAt
212
+ version
213
+ totalCount
214
+ hasMore
215
+ limit
216
+ offset
217
+ }
208
218
  }
209
219
  `;
210
220
  export const DELETE_DATASINK = `
211
221
  mutation DeleteDataSink($id: ID!) {
212
- deleteDataSink(id: $id)
222
+ deleteDataSink(id: $id) {
223
+ id
224
+ name
225
+ }
213
226
  }
214
227
  `;
215
228
  // ---------------------------------------------------------------------------
@@ -342,7 +355,7 @@ export const UPDATE_DASHBOARD = `
342
355
  }
343
356
  `;
344
357
  export const IMPORT_DASHBOARD = `
345
- mutation ImportDashboard($input: ImportDashboardInput!) {
358
+ mutation ImportDashboard($input: BigConsoleImportDashboardInput!) {
346
359
  importDashboard(input: $input) {
347
360
  id
348
361
  name
@@ -354,8 +367,8 @@ export const IMPORT_DASHBOARD = `
354
367
  }
355
368
  `;
356
369
  export const EXPORT_DASHBOARD = `
357
- query ExportDashboard($id: ID!, $includeComments: Boolean, $options: ExportDashboardOptions) {
358
- exportDashboard(id: $id, includeComments: $includeComments, options: $options)
370
+ query ExportDashboard($id: ID!, $options: BigConsoleExportDashboardOptions) {
371
+ exportDashboard(id: $id, options: $options)
359
372
  }
360
373
  `;
361
374
  // ---------------------------------------------------------------------------
@@ -474,15 +487,28 @@ export const GET_WIDGET_ACTIONS = `
474
487
  id
475
488
  widgetId
476
489
  type
490
+ name
477
491
  label
478
- config
492
+ order
493
+ disabled
494
+ hidden
479
495
  createdAt
480
496
  }
481
497
  }
482
498
  `;
483
499
  export const DELETE_WIDGET_DRILLDOWN = `
484
- mutation DeleteWidgetDrilldown($widgetId: ID!) {
485
- deleteWidgetDrilldown(widgetId: $widgetId)
500
+ mutation DeleteWidgetDrilldown($id: ID!) {
501
+ deleteWidgetDrilldown(id: $id)
502
+ }
503
+ `;
504
+ export const GET_WIDGET_DRILLDOWN = `
505
+ query GetWidgetDrilldown($id: ID!) {
506
+ getWidget(id: $id) {
507
+ id
508
+ drilldown {
509
+ id
510
+ }
511
+ }
486
512
  }
487
513
  `;
488
514
  // ---------------------------------------------------------------------------
@@ -494,8 +520,8 @@ export const LIST_DASHBOARD_SHARES = `
494
520
  $first: Int
495
521
  $after: String
496
522
  $isActive: Boolean
497
- $permission: SharePermission
498
- $recipientType: ShareRecipientType
523
+ $permission: BigConsoleDashboardSharePermission
524
+ $recipientType: BigConsoleDashboardShareRecipientType
499
525
  ) {
500
526
  listDashboardShares(
501
527
  dashboardId: $dashboardId
@@ -527,7 +553,7 @@ export const LIST_TEMPLATES = `
527
553
  query ListTemplates(
528
554
  $first: Int
529
555
  $after: String
530
- $category: DashboardCategory
556
+ $category: BigConsoleDashboardCategory
531
557
  $search: String
532
558
  $isFeatured: Boolean
533
559
  ) {
@@ -571,7 +597,7 @@ export const GET_TEMPLATE = `
571
597
  // Prompt (AI) — generate, list, get, cancel
572
598
  // ---------------------------------------------------------------------------
573
599
  export const GENERATE_DASHBOARD_FROM_PROMPT = `
574
- mutation GenerateDashboardFromPrompt($input: GenerateDashboardFromPromptInput!) {
600
+ mutation GenerateDashboardFromPrompt($input: BigConsoleGenerateDashboardFromPromptInput!) {
575
601
  generateDashboardFromPrompt(input: $input) {
576
602
  id
577
603
  status
@@ -607,8 +633,8 @@ export const GET_PROMPT_GENERATION = `
607
633
  }
608
634
  `;
609
635
  export const CANCEL_PROMPT_GENERATION = `
610
- mutation CancelPromptGeneration($id: ID!) {
611
- cancelPromptGeneration(id: $id) {
636
+ mutation CancelPromptGeneration($generationId: ID!) {
637
+ cancelPromptGeneration(generationId: $generationId) {
612
638
  id
613
639
  status
614
640
  }
package/dist/index.d.ts CHANGED
@@ -2,5 +2,5 @@
2
2
  * @burdenoff/bigconsole-cli — public API exports.
3
3
  */
4
4
  export * from './config/index.js';
5
- export { workspaceRequest, globalRequest, resetClients } from './graphql/client.js';
5
+ export { workspaceRequest, globalRequest, resetClients, BigConsoleRequestError, } from './graphql/client.js';
6
6
  export * from './commands/index.js';
package/dist/index.js CHANGED
@@ -2,5 +2,5 @@
2
2
  * @burdenoff/bigconsole-cli — public API exports.
3
3
  */
4
4
  export * from './config/index.js';
5
- export { workspaceRequest, globalRequest, resetClients } from './graphql/client.js';
5
+ export { workspaceRequest, globalRequest, resetClients, BigConsoleRequestError, } from './graphql/client.js';
6
6
  export * from './commands/index.js';
@@ -1 +1,2 @@
1
1
  export * from './output.js';
2
+ export * from './sanitize.js';
@@ -1 +1,2 @@
1
1
  export * from './output.js';
2
+ export * from './sanitize.js';
@@ -1,6 +1,12 @@
1
1
  /**
2
2
  * Output utilities for CLI display.
3
3
  * Provides consistent formatting for both interactive and non-interactive modes.
4
+ *
5
+ * stdout carries only command data (JSON, YAML, tables); status lines
6
+ * (success, info, warning, error) go to stderr so piping stays clean. Remote
7
+ * strings are made inert before they reach the terminal: tables and status
8
+ * lines pass through `sanitizeForTerminal`, while JSON and YAML stay exact
9
+ * data and only use escape forms their own syntax defines.
4
10
  */
5
11
  export type OutputFormat = 'json' | 'table' | 'yaml';
6
12
  /**
@@ -13,32 +19,47 @@ export declare function isInteractive(): boolean;
13
19
  export declare function getFormat(options: {
14
20
  format?: string;
15
21
  }): OutputFormat;
22
+ /**
23
+ * Serialize data as pretty-printed JSON. Characters in
24
+ * {@link JSON_DISPLAY_ESCAPES} can only occur inside JSON strings, so writing
25
+ * them as `\uXXXX` escapes leaves the parsed value unchanged.
26
+ */
27
+ export declare function toJson(data: unknown): string;
16
28
  /**
17
29
  * Print data as formatted JSON.
18
30
  */
19
31
  export declare function printJson(data: unknown): void;
20
32
  /**
21
- * Print data as a simple ASCII table.
33
+ * Print data as a simple ASCII table. Headers and cells are sanitized for the
34
+ * terminal (single line, no control sequences) before widths are measured;
35
+ * columns are padded to at most {@link MAX_COLUMN_WIDTH} characters.
22
36
  */
23
37
  export declare function printTable(headers: string[], rows: string[][]): void;
24
38
  /**
25
- * Print data as YAML-like output (simple key-value).
39
+ * Serialize data as YAML with js-yaml, restricted to the JSON schema (no
40
+ * custom tags) and without anchors/aliases. Control characters are escaped by
41
+ * the dumper; bidirectional controls, which YAML treats as printable, are
42
+ * written as `\uXXXX` inside double-quoted scalars.
43
+ */
44
+ export declare function toYaml(data: unknown): string;
45
+ /**
46
+ * Print data as YAML.
26
47
  */
27
48
  export declare function printYaml(data: unknown): void;
28
49
  /**
29
- * Print a success message.
50
+ * Print a success message (stderr).
30
51
  */
31
52
  export declare function printSuccess(message: string): void;
32
53
  /**
33
- * Print an error message to stderr.
54
+ * Print an error message to stderr. Credential-shaped values are masked.
34
55
  */
35
56
  export declare function printError(message: string): void;
36
57
  /**
37
- * Print a warning message.
58
+ * Print a warning message to stderr. Credential-shaped values are masked.
38
59
  */
39
60
  export declare function printWarning(message: string): void;
40
61
  /**
41
- * Print an info message.
62
+ * Print an info message (stderr).
42
63
  */
43
64
  export declare function printInfo(message: string): void;
44
65
  /**
@@ -57,6 +78,7 @@ export declare function outputData(format: OutputFormat, data: unknown, tableCon
57
78
  rows: string[][];
58
79
  }): void;
59
80
  /**
60
- * Truncate a string to a maximum length, appending ellipsis if needed.
81
+ * Sanitize a string for the terminal, then truncate it to a maximum length,
82
+ * appending an ellipsis if needed.
61
83
  */
62
84
  export declare function truncate(str: string | null | undefined, maxLen: number): string;
@@ -1,7 +1,17 @@
1
1
  /**
2
2
  * Output utilities for CLI display.
3
3
  * Provides consistent formatting for both interactive and non-interactive modes.
4
+ *
5
+ * stdout carries only command data (JSON, YAML, tables); status lines
6
+ * (success, info, warning, error) go to stderr so piping stays clean. Remote
7
+ * strings are made inert before they reach the terminal: tables and status
8
+ * lines pass through `sanitizeForTerminal`, while JSON and YAML stay exact
9
+ * data and only use escape forms their own syntax defines.
4
10
  */
11
+ import { DEFAULT_SCALAR_STYLE_RULES, JSON_SCHEMA, SCALAR_STYLE, dump, strTag, } from 'js-yaml';
12
+ import { escapeBidiControls, redactSecrets, sanitizeForTerminal, toUnicodeEscape, } from './sanitize.js';
13
+ /** Widest a table column is padded to; longer cells extend past it. */
14
+ const MAX_COLUMN_WIDTH = 50;
5
15
  /**
6
16
  * Check if the current terminal session is interactive (TTY).
7
17
  */
@@ -16,101 +26,140 @@ export function getFormat(options) {
16
26
  const f = options.format.toLowerCase();
17
27
  if (f === 'json' || f === 'table' || f === 'yaml')
18
28
  return f;
29
+ if (f === 'yml')
30
+ return 'yaml';
19
31
  }
20
32
  return isInteractive() ? 'table' : 'json';
21
33
  }
34
+ /**
35
+ * Characters that are valid raw inside JSON strings but act on, or are
36
+ * invisible in, a terminal: DEL, C1 controls, line/paragraph separators and
37
+ * bidirectional formatting controls.
38
+ */
39
+ const JSON_DISPLAY_ESCAPES = /[\u007f-\u009f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g;
40
+ /**
41
+ * Serialize data as pretty-printed JSON. Characters in
42
+ * {@link JSON_DISPLAY_ESCAPES} can only occur inside JSON strings, so writing
43
+ * them as `\uXXXX` escapes leaves the parsed value unchanged.
44
+ */
45
+ export function toJson(data) {
46
+ const json = JSON.stringify(data, null, 2) ?? 'null';
47
+ return json.replace(JSON_DISPLAY_ESCAPES, toUnicodeEscape);
48
+ }
22
49
  /**
23
50
  * Print data as formatted JSON.
24
51
  */
25
52
  export function printJson(data) {
26
- console.log(JSON.stringify(data, null, 2));
53
+ console.log(toJson(data));
27
54
  }
28
55
  /**
29
- * Print data as a simple ASCII table.
56
+ * Print data as a simple ASCII table. Headers and cells are sanitized for the
57
+ * terminal (single line, no control sequences) before widths are measured;
58
+ * columns are padded to at most {@link MAX_COLUMN_WIDTH} characters.
30
59
  */
31
60
  export function printTable(headers, rows) {
32
61
  if (headers.length === 0)
33
62
  return;
34
- const colWidths = headers.map((h, i) => {
35
- let max = h.length;
36
- for (const row of rows) {
37
- const cell = row[i] ?? '';
38
- if (cell.length > max)
39
- max = cell.length;
40
- }
41
- return Math.min(max, 50);
42
- });
63
+ const header = headers.map((h) => sanitizeForTerminal(h));
64
+ const body = rows.map((row) => headers.map((_, i) => sanitizeForTerminal(row[i])));
65
+ const colWidths = header.map((h, i) => Math.min(body.reduce((max, row) => Math.max(max, (row[i] ?? '').length), h.length), MAX_COLUMN_WIDTH));
43
66
  const separator = colWidths.map((w) => '-'.repeat(w + 2)).join('+');
44
- const formatRow = (cells) => cells.map((cell, i) => ` ${(cell ?? '').padEnd(colWidths[i] ?? 0)} `).join('|');
45
- console.log(formatRow(headers));
67
+ const formatRow = (cells) => cells.map((cell, i) => ` ${cell.padEnd(colWidths[i] ?? 0)} `).join('|');
68
+ console.log(formatRow(header));
46
69
  console.log(separator);
47
- for (const row of rows) {
70
+ for (const row of body) {
48
71
  console.log(formatRow(row));
49
72
  }
50
73
  }
74
+ function allowsStyle(mask, style) {
75
+ return (mask & (1 << style)) !== 0;
76
+ }
77
+ /** Bidirectional formatting controls (see `escapeBidiControls`). */
78
+ const BIDI_CONTROL = /[\u202a-\u202e\u2066-\u2069]/;
51
79
  /**
52
- * Print data as YAML-like output (simple key-value).
80
+ * Strings that read back as the same string under the YAML 1.2 JSON and core
81
+ * schemas and under YAML 1.1: a letter first, then only letters, digits,
82
+ * spaces and `_ . / @ + -`, and not one of the words those schemas map to
83
+ * booleans or null.
53
84
  */
54
- export function printYaml(data) {
55
- if (typeof data !== 'object' || data === null) {
56
- console.log(String(data));
85
+ const UNAMBIGUOUS_PLAIN = /^\p{L}[\p{L}\p{N} _./@+-]*$/u;
86
+ const NON_STRING_WORDS = /^(?:y|n|yes|no|on|off|true|false|null)$/i;
87
+ /**
88
+ * Double-quote any scalar containing a bidirectional formatting control.
89
+ * Double-quoted YAML supports `\uXXXX` escapes, so `toYaml` can then write
90
+ * those characters visibly without changing the parsed value.
91
+ */
92
+ const doubleQuoteBidiControls = (layout) => {
93
+ if (BIDI_CONTROL.test(layout.node.value))
94
+ layout.style = SCALAR_STYLE.DOUBLE_QUOTED;
95
+ };
96
+ /**
97
+ * Quote string scalars (keys and values) that another YAML parser could read
98
+ * as a number, boolean, null, date or merge key. The JSON schema alone leaves
99
+ * values such as `yes`, `~`, `0x1F`, `2026-01-01` or the empty string plain.
100
+ * Runs after the default rules, so strings with invisible characters are
101
+ * already double-quoted and multi-line strings already use block scalars.
102
+ */
103
+ const quoteAmbiguousStrings = (layout) => {
104
+ if (layout.style !== SCALAR_STYLE.PLAIN || layout.node.tag !== strTag.tagName)
57
105
  return;
58
- }
59
- const lines = yamlSerialize(data, 0);
60
- console.log(lines);
61
- }
62
- function yamlSerialize(obj, indent) {
63
- const prefix = ' '.repeat(indent);
64
- const lines = [];
65
- for (const [key, value] of Object.entries(obj)) {
66
- if (value === null || value === undefined) {
67
- lines.push(`${prefix}${key}: null`);
68
- }
69
- else if (Array.isArray(value)) {
70
- lines.push(`${prefix}${key}:`);
71
- for (const item of value) {
72
- if (typeof item === 'object' && item !== null) {
73
- lines.push(`${prefix} -`);
74
- lines.push(yamlSerialize(item, indent + 2));
75
- }
76
- else {
77
- lines.push(`${prefix} - ${String(item)}`);
78
- }
79
- }
80
- }
81
- else if (typeof value === 'object') {
82
- lines.push(`${prefix}${key}:`);
83
- lines.push(yamlSerialize(value, indent + 1));
84
- }
85
- else {
86
- lines.push(`${prefix}${key}: ${String(value)}`);
87
- }
88
- }
89
- return lines.join('\n');
106
+ const value = layout.node.value;
107
+ if (UNAMBIGUOUS_PLAIN.test(value) && !NON_STRING_WORDS.test(value))
108
+ return;
109
+ layout.style = allowsStyle(layout.allowedStylesMask, SCALAR_STYLE.SINGLE_QUOTED)
110
+ ? SCALAR_STYLE.SINGLE_QUOTED
111
+ : SCALAR_STYLE.DOUBLE_QUOTED;
112
+ };
113
+ const YAML_STYLE_RULES = [
114
+ doubleQuoteBidiControls,
115
+ ...Object.values(DEFAULT_SCALAR_STYLE_RULES),
116
+ quoteAmbiguousStrings,
117
+ ];
118
+ /**
119
+ * Serialize data as YAML with js-yaml, restricted to the JSON schema (no
120
+ * custom tags) and without anchors/aliases. Control characters are escaped by
121
+ * the dumper; bidirectional controls, which YAML treats as printable, are
122
+ * written as `\uXXXX` inside double-quoted scalars.
123
+ */
124
+ export function toYaml(data) {
125
+ const yaml = dump(data ?? null, {
126
+ schema: JSON_SCHEMA,
127
+ noRefs: true,
128
+ skipInvalid: true,
129
+ lineWidth: -1,
130
+ scalarStyleRules: YAML_STYLE_RULES,
131
+ });
132
+ return escapeBidiControls(yaml).trimEnd();
133
+ }
134
+ /**
135
+ * Print data as YAML.
136
+ */
137
+ export function printYaml(data) {
138
+ console.log(toYaml(data));
90
139
  }
91
140
  /**
92
- * Print a success message.
141
+ * Print a success message (stderr).
93
142
  */
94
143
  export function printSuccess(message) {
95
- console.log(`\u2713 ${message}`);
144
+ console.error(`\u2713 ${sanitizeForTerminal(message)}`);
96
145
  }
97
146
  /**
98
- * Print an error message to stderr.
147
+ * Print an error message to stderr. Credential-shaped values are masked.
99
148
  */
100
149
  export function printError(message) {
101
- console.error(`\u2717 ${message}`);
150
+ console.error(`\u2717 ${redactSecrets(sanitizeForTerminal(message))}`);
102
151
  }
103
152
  /**
104
- * Print a warning message.
153
+ * Print a warning message to stderr. Credential-shaped values are masked.
105
154
  */
106
155
  export function printWarning(message) {
107
- console.warn(`! ${message}`);
156
+ console.warn(`! ${redactSecrets(sanitizeForTerminal(message))}`);
108
157
  }
109
158
  /**
110
- * Print an info message.
159
+ * Print an info message (stderr).
111
160
  */
112
161
  export function printInfo(message) {
113
- console.log(`\u2139 ${message}`);
162
+ console.error(`\u2139 ${sanitizeForTerminal(message)}`);
114
163
  }
115
164
  /**
116
165
  * Format an ISO date string for display.
@@ -175,12 +224,14 @@ export function outputData(format, data, tableConfig) {
175
224
  }
176
225
  }
177
226
  /**
178
- * Truncate a string to a maximum length, appending ellipsis if needed.
227
+ * Sanitize a string for the terminal, then truncate it to a maximum length,
228
+ * appending an ellipsis if needed.
179
229
  */
180
230
  export function truncate(str, maxLen) {
181
231
  if (!str)
182
232
  return '-';
183
- if (str.length <= maxLen)
184
- return str;
185
- return str.substring(0, maxLen - 3) + '...';
233
+ const clean = sanitizeForTerminal(str);
234
+ if (clean.length <= maxLen)
235
+ return clean;
236
+ return clean.substring(0, maxLen - 3) + '...';
186
237
  }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Text hygiene for everything the CLI prints.
3
+ *
4
+ * Remote data (resource names, server error messages, HTTP response bodies)
5
+ * ends up in terminals, CI logs and support captures. The helpers here:
6
+ * - keep terminal output inert: escape sequences and control characters are
7
+ * removed, and bidirectional formatting characters are made visible;
8
+ * - mask credential-shaped values (bearer tokens, JWTs, URL credentials and
9
+ * values stored under secret-like keys);
10
+ * - turn any thrown value into a short, single-line message that is built
11
+ * from an allowlist of fields and never includes request variables,
12
+ * request headers or raw response bodies.
13
+ *
14
+ * The module is side-effect free and imports nothing from the rest of the CLI,
15
+ * so every layer can use it (and unit-test module mocks never replace it).
16
+ */
17
+ /** Longest error message shown to the user. */
18
+ export declare const MAX_ERROR_MESSAGE_LENGTH = 500;
19
+ /** Longest excerpt of an HTTP response body or server message kept in an error. */
20
+ export declare const MAX_HTTP_BODY_EXCERPT_LENGTH = 200;
21
+ export interface TerminalSanitizeOptions {
22
+ /**
23
+ * Keep line structure: CRLF and CR become LF, LF and TAB are kept, and
24
+ * NEL/LS/PS are shown as `\uXXXX`. By default (single-line mode) every line
25
+ * break and TAB becomes a single space.
26
+ */
27
+ preserveNewlines?: boolean;
28
+ }
29
+ /** `\uXXXX` spelling of a single UTF-16 code unit (valid in JSON and YAML). */
30
+ export declare function toUnicodeEscape(char: string): string;
31
+ /** Make bidirectional formatting controls visible as `\uXXXX` text. */
32
+ export declare function escapeBidiControls(text: string): string;
33
+ /**
34
+ * Make a value safe to print on a terminal.
35
+ *
36
+ * - ANSI/VT escape sequences (CSI, OSC, DCS, SOS, PM, APC and two-character
37
+ * ESC sequences, in 7-bit and 8-bit form) are removed entirely.
38
+ * - Other C0 controls, DEL and C1 controls are removed.
39
+ * - Line breaks and TAB become a space (see {@link TerminalSanitizeOptions}).
40
+ * - Bidirectional formatting controls are shown as `\uXXXX` text so the
41
+ * printed text reads in its stored order.
42
+ *
43
+ * `null`/`undefined` become an empty string. The function is idempotent.
44
+ */
45
+ export declare function sanitizeForTerminal(value: unknown, options?: TerminalSanitizeOptions): string;
46
+ /**
47
+ * Mask credential-shaped values in free text: values under secret-like keys
48
+ * (`password`, `token`, `refreshToken`, `clientSecret`, `Authorization`, ...),
49
+ * `Bearer` credentials, JWT-shaped strings and credentials embedded in URLs.
50
+ */
51
+ export declare function redactSecrets(text: string): string;
52
+ /**
53
+ * Reduce untrusted text to one printable, credential-masked line of at most
54
+ * `maxLength` characters. Returns an empty string when nothing is left.
55
+ */
56
+ export declare function toDisplayLine(value: unknown, maxLength?: number): string;
57
+ /** Short, printable excerpt of an HTTP response body for an error message. */
58
+ export declare function summarizeHttpBody(body: unknown): string;
59
+ /** Safe, user-facing description of a failed request. */
60
+ export interface SafeErrorDescription {
61
+ message: string;
62
+ /** HTTP status of the response, when there was one. */
63
+ status?: number;
64
+ /** Stable GraphQL error code (`extensions.code`), when the server sent one. */
65
+ code?: string;
66
+ }
67
+ /**
68
+ * Describe a failure of a GraphQL request for display. Network-level
69
+ * `TypeError`s (fetch failures) are reported as network errors; aborted
70
+ * requests as timeouts.
71
+ */
72
+ export declare function describeRequestError(error: unknown): SafeErrorDescription;
73
+ /**
74
+ * Convert any thrown value into a message that is safe to print: a single
75
+ * line, at most {@link MAX_ERROR_MESSAGE_LENGTH} characters, free of terminal
76
+ * control sequences and with credential-shaped values masked. Response-bearing
77
+ * errors are described from an allowlist of fields only.
78
+ */
79
+ export declare function toSafeErrorMessage(error: unknown): string;