@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.
- package/README.md +39 -11
- package/dist/auth/device-code.js +20 -15
- package/dist/cli.js +5 -2
- package/dist/commands/auth.js +6 -5
- package/dist/commands/base.d.ts +11 -0
- package/dist/commands/base.js +22 -2
- package/dist/commands/dashboard.js +7 -4
- package/dist/commands/drilldown.js +9 -1
- package/dist/commands/prompt.js +1 -1
- package/dist/graphql/client.d.ts +12 -0
- package/dist/graphql/client.js +15 -35
- package/dist/graphql/operations.d.ts +13 -12
- package/dist/graphql/operations.js +44 -18
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/output.d.ts +29 -7
- package/dist/utils/output.js +113 -62
- package/dist/utils/sanitize.d.ts +79 -0
- package/dist/utils/sanitize.js +347 -0
- package/package.json +39 -32
|
@@ -0,0 +1,347 @@
|
|
|
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 const MAX_ERROR_MESSAGE_LENGTH = 500;
|
|
19
|
+
/** Longest excerpt of an HTTP response body or server message kept in an error. */
|
|
20
|
+
export const MAX_HTTP_BODY_EXCERPT_LENGTH = 200;
|
|
21
|
+
/** Text is cut to this length before the redaction patterns scan it. */
|
|
22
|
+
const MAX_SCAN_LENGTH = 4000;
|
|
23
|
+
const REDACTED = '[REDACTED]';
|
|
24
|
+
const ELLIPSIS = '\u2026';
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Terminal output
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
const ESC = 0x1b;
|
|
29
|
+
const BEL = 0x07;
|
|
30
|
+
const TAB = 0x09;
|
|
31
|
+
const LF = 0x0a;
|
|
32
|
+
const CR = 0x0d;
|
|
33
|
+
const DEL = 0x7f;
|
|
34
|
+
const NEL = 0x85;
|
|
35
|
+
const C1_CSI = 0x9b;
|
|
36
|
+
const C1_ST = 0x9c;
|
|
37
|
+
const LINE_SEPARATOR = 0x2028;
|
|
38
|
+
const PARAGRAPH_SEPARATOR = 0x2029;
|
|
39
|
+
/** 8-bit introducers of DCS, SOS, OSC, PM and APC control strings. */
|
|
40
|
+
const C1_STRING_INTRODUCERS = new Set([0x90, 0x98, 0x9d, 0x9e, 0x9f]);
|
|
41
|
+
/** Final bytes after ESC that open DCS, SOS, OSC, PM and APC control strings. */
|
|
42
|
+
const ESC_STRING_INTRODUCERS = new Set(['P', 'X', ']', '^', '_'].map((c) => c.charCodeAt(0)));
|
|
43
|
+
/** Bidirectional embedding, override and isolate controls. */
|
|
44
|
+
const BIDI_CONTROLS = /[\u202a-\u202e\u2066-\u2069]/g;
|
|
45
|
+
/** `\uXXXX` spelling of a single UTF-16 code unit (valid in JSON and YAML). */
|
|
46
|
+
export function toUnicodeEscape(char) {
|
|
47
|
+
return `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}`;
|
|
48
|
+
}
|
|
49
|
+
/** Make bidirectional formatting controls visible as `\uXXXX` text. */
|
|
50
|
+
export function escapeBidiControls(text) {
|
|
51
|
+
return text.replace(BIDI_CONTROLS, toUnicodeEscape);
|
|
52
|
+
}
|
|
53
|
+
function isInRange(code, low, high) {
|
|
54
|
+
return code >= low && code <= high;
|
|
55
|
+
}
|
|
56
|
+
/** Index just past a CSI sequence whose parameters start at `index`. */
|
|
57
|
+
function skipControlSequence(text, index) {
|
|
58
|
+
let i = index;
|
|
59
|
+
while (i < text.length && isInRange(text.charCodeAt(i), 0x30, 0x3f))
|
|
60
|
+
i++;
|
|
61
|
+
while (i < text.length && isInRange(text.charCodeAt(i), 0x20, 0x2f))
|
|
62
|
+
i++;
|
|
63
|
+
if (i < text.length && isInRange(text.charCodeAt(i), 0x40, 0x7e))
|
|
64
|
+
i++;
|
|
65
|
+
return i;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Index just past a control string (OSC, DCS, ...) whose payload starts at
|
|
69
|
+
* `index`. Terminated by BEL, 8-bit ST or ESC \; an unterminated string runs
|
|
70
|
+
* to the end of the text, exactly as a terminal would consume it.
|
|
71
|
+
*/
|
|
72
|
+
function skipControlString(text, index) {
|
|
73
|
+
let i = index;
|
|
74
|
+
while (i < text.length) {
|
|
75
|
+
const code = text.charCodeAt(i);
|
|
76
|
+
if (code === BEL || code === C1_ST)
|
|
77
|
+
return i + 1;
|
|
78
|
+
if (code === ESC)
|
|
79
|
+
return text.charCodeAt(i + 1) === 0x5c ? i + 2 : i;
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
82
|
+
return i;
|
|
83
|
+
}
|
|
84
|
+
/** Index just past an ESC-introduced sequence; `index` points at the ESC. */
|
|
85
|
+
function skipEscapeSequence(text, index) {
|
|
86
|
+
const next = text.charCodeAt(index + 1);
|
|
87
|
+
if (Number.isNaN(next))
|
|
88
|
+
return index + 1;
|
|
89
|
+
if (next === 0x5b)
|
|
90
|
+
return skipControlSequence(text, index + 2);
|
|
91
|
+
if (ESC_STRING_INTRODUCERS.has(next))
|
|
92
|
+
return skipControlString(text, index + 2);
|
|
93
|
+
let i = index + 1;
|
|
94
|
+
while (i < text.length && isInRange(text.charCodeAt(i), 0x20, 0x2f))
|
|
95
|
+
i++;
|
|
96
|
+
if (i < text.length && isInRange(text.charCodeAt(i), 0x30, 0x7e))
|
|
97
|
+
i++;
|
|
98
|
+
return i;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Make a value safe to print on a terminal.
|
|
102
|
+
*
|
|
103
|
+
* - ANSI/VT escape sequences (CSI, OSC, DCS, SOS, PM, APC and two-character
|
|
104
|
+
* ESC sequences, in 7-bit and 8-bit form) are removed entirely.
|
|
105
|
+
* - Other C0 controls, DEL and C1 controls are removed.
|
|
106
|
+
* - Line breaks and TAB become a space (see {@link TerminalSanitizeOptions}).
|
|
107
|
+
* - Bidirectional formatting controls are shown as `\uXXXX` text so the
|
|
108
|
+
* printed text reads in its stored order.
|
|
109
|
+
*
|
|
110
|
+
* `null`/`undefined` become an empty string. The function is idempotent.
|
|
111
|
+
*/
|
|
112
|
+
export function sanitizeForTerminal(value, options = {}) {
|
|
113
|
+
const text = value === null || value === undefined ? '' : String(value);
|
|
114
|
+
const multiline = options.preserveNewlines === true;
|
|
115
|
+
let out = '';
|
|
116
|
+
let i = 0;
|
|
117
|
+
while (i < text.length) {
|
|
118
|
+
const code = text.charCodeAt(i);
|
|
119
|
+
if (code === ESC) {
|
|
120
|
+
i = skipEscapeSequence(text, i);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (code === C1_CSI) {
|
|
124
|
+
i = skipControlSequence(text, i + 1);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (C1_STRING_INTRODUCERS.has(code)) {
|
|
128
|
+
i = skipControlString(text, i + 1);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (code === CR || code === LF) {
|
|
132
|
+
const crlf = code === CR && text.charCodeAt(i + 1) === LF;
|
|
133
|
+
out += multiline ? '\n' : ' ';
|
|
134
|
+
i += crlf ? 2 : 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (code === NEL || code === LINE_SEPARATOR || code === PARAGRAPH_SEPARATOR) {
|
|
138
|
+
out += multiline ? toUnicodeEscape(text.charAt(i)) : ' ';
|
|
139
|
+
i++;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (code === TAB) {
|
|
143
|
+
out += multiline ? '\t' : ' ';
|
|
144
|
+
i++;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (code < 0x20 || isInRange(code, DEL, 0x9f)) {
|
|
148
|
+
i++;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
out += text.charAt(i);
|
|
152
|
+
i++;
|
|
153
|
+
}
|
|
154
|
+
return escapeBidiControls(out);
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Credential masking
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
/** A key whose value is treated as a credential when it contains one of these. */
|
|
160
|
+
const SECRET_KEY_HINT = /pass(?:word|wd|phrase)?|secret|token|api[-_]?key|private[-_]?key|access[-_]?key|credential|authori[sz]ation|cookie|session[-_]?id/i;
|
|
161
|
+
/**
|
|
162
|
+
* `key: value` / `key=value` / `"key": value` openings. Keys may be quoted,
|
|
163
|
+
* including with backslash-escaped quotes (JSON serialised inside a string).
|
|
164
|
+
*/
|
|
165
|
+
const KEY_VALUE_OPENING = /\b([A-Za-z_$][\w$-]{0,127})\\*["']?\s*[:=]\s*/g;
|
|
166
|
+
/** Opening quote of a value, optionally backslash-escaped. */
|
|
167
|
+
const QUOTE_OPENING = /^(\\*)(["'])/;
|
|
168
|
+
/** Unquoted value: runs to whitespace, a quote, a backslash or a delimiter. */
|
|
169
|
+
const UNQUOTED_VALUE = /^[^\s"'\\,;&)}\]]*/;
|
|
170
|
+
/** An auth scheme word that precedes the credential in header values. */
|
|
171
|
+
const AUTH_SCHEME = /^(?:Bearer|Basic|Digest|Token)\s+/i;
|
|
172
|
+
const BEARER_CREDENTIAL = /\bBearer\s+[A-Za-z0-9\-._~+/]+=*/g;
|
|
173
|
+
const JWT_LIKE = /\beyJ[\w-]{4,}\.[\w-]{4,}\.[\w-]*/g;
|
|
174
|
+
const URL_USERINFO = /\b([a-z][a-z0-9+.-]{1,31}:\/\/)[^\s/?#@"'\\]+@/gi;
|
|
175
|
+
/** Number of consecutive backslashes immediately before `index`, not before `floor`. */
|
|
176
|
+
function backslashRun(text, index, floor) {
|
|
177
|
+
let run = 0;
|
|
178
|
+
while (index - run - 1 >= floor && text.charAt(index - run - 1) === '\\')
|
|
179
|
+
run++;
|
|
180
|
+
return run;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Masked replacement for the value starting at `start`, and the index just
|
|
184
|
+
* past that value. A quoted value ends at the matching quote (same escaping
|
|
185
|
+
* depth) or, when unterminated, at the end of the text.
|
|
186
|
+
*/
|
|
187
|
+
function maskValue(text, start) {
|
|
188
|
+
if (text.startsWith(REDACTED, start)) {
|
|
189
|
+
return { replacement: REDACTED, end: start + REDACTED.length };
|
|
190
|
+
}
|
|
191
|
+
const quote = QUOTE_OPENING.exec(text.slice(start, start + 64));
|
|
192
|
+
if (quote) {
|
|
193
|
+
const opener = quote[0];
|
|
194
|
+
const depth = (quote[1] ?? '').length;
|
|
195
|
+
const quoteChar = quote[2] ?? '"';
|
|
196
|
+
let search = start + opener.length;
|
|
197
|
+
while (search < text.length) {
|
|
198
|
+
const candidate = text.indexOf(quoteChar, search);
|
|
199
|
+
if (candidate === -1)
|
|
200
|
+
break;
|
|
201
|
+
if (backslashRun(text, candidate, start + opener.length) === depth) {
|
|
202
|
+
return { replacement: `${opener}${REDACTED}${opener}`, end: candidate + 1 };
|
|
203
|
+
}
|
|
204
|
+
search = candidate + 1;
|
|
205
|
+
}
|
|
206
|
+
return { replacement: `${opener}${REDACTED}`, end: text.length };
|
|
207
|
+
}
|
|
208
|
+
const rest = text.slice(start);
|
|
209
|
+
const scheme = AUTH_SCHEME.exec(rest);
|
|
210
|
+
const offset = scheme ? scheme[0].length : 0;
|
|
211
|
+
const run = UNQUOTED_VALUE.exec(rest.slice(offset));
|
|
212
|
+
const length = offset + (run ? run[0].length : 0);
|
|
213
|
+
return { replacement: length > 0 ? REDACTED : '', end: start + length };
|
|
214
|
+
}
|
|
215
|
+
function redactKeyValues(text) {
|
|
216
|
+
let out = '';
|
|
217
|
+
let copiedUpTo = 0;
|
|
218
|
+
KEY_VALUE_OPENING.lastIndex = 0;
|
|
219
|
+
let match;
|
|
220
|
+
while ((match = KEY_VALUE_OPENING.exec(text)) !== null) {
|
|
221
|
+
if (!SECRET_KEY_HINT.test(match[1] ?? ''))
|
|
222
|
+
continue;
|
|
223
|
+
const start = match.index + match[0].length;
|
|
224
|
+
const { replacement, end } = maskValue(text, start);
|
|
225
|
+
if (end === start)
|
|
226
|
+
continue;
|
|
227
|
+
out += text.slice(copiedUpTo, start) + replacement;
|
|
228
|
+
copiedUpTo = end;
|
|
229
|
+
KEY_VALUE_OPENING.lastIndex = end;
|
|
230
|
+
}
|
|
231
|
+
return out + text.slice(copiedUpTo);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Mask credential-shaped values in free text: values under secret-like keys
|
|
235
|
+
* (`password`, `token`, `refreshToken`, `clientSecret`, `Authorization`, ...),
|
|
236
|
+
* `Bearer` credentials, JWT-shaped strings and credentials embedded in URLs.
|
|
237
|
+
*/
|
|
238
|
+
export function redactSecrets(text) {
|
|
239
|
+
return redactKeyValues(text)
|
|
240
|
+
.replace(BEARER_CREDENTIAL, `Bearer ${REDACTED}`)
|
|
241
|
+
.replace(JWT_LIKE, REDACTED)
|
|
242
|
+
.replace(URL_USERINFO, `$1${REDACTED}@`);
|
|
243
|
+
}
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
// Display lines and error messages
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
const LINE_BREAK = /\r\n|[\r\n\u0085\u2028\u2029]/;
|
|
248
|
+
/**
|
|
249
|
+
* Reduce untrusted text to one printable, credential-masked line of at most
|
|
250
|
+
* `maxLength` characters. Returns an empty string when nothing is left.
|
|
251
|
+
*/
|
|
252
|
+
export function toDisplayLine(value, maxLength = MAX_ERROR_MESSAGE_LENGTH) {
|
|
253
|
+
if (value === null || value === undefined)
|
|
254
|
+
return '';
|
|
255
|
+
const firstLine = String(value).split(LINE_BREAK, 1)[0] ?? '';
|
|
256
|
+
const scanned = firstLine.slice(0, MAX_SCAN_LENGTH);
|
|
257
|
+
const line = redactSecrets(sanitizeForTerminal(scanned)).trim();
|
|
258
|
+
return line.length > maxLength ? `${line.slice(0, maxLength)}${ELLIPSIS}` : line;
|
|
259
|
+
}
|
|
260
|
+
/** Short, printable excerpt of an HTTP response body for an error message. */
|
|
261
|
+
export function summarizeHttpBody(body) {
|
|
262
|
+
return toDisplayLine(body, MAX_HTTP_BODY_EXCERPT_LENGTH) || 'empty response body';
|
|
263
|
+
}
|
|
264
|
+
const ERROR_CODE = /^[A-Z][A-Z0-9_]{1,63}$/;
|
|
265
|
+
function asRecord(value) {
|
|
266
|
+
// Narrowing an arbitrary thrown value; every field read below is type-checked.
|
|
267
|
+
return typeof value === 'object' && value !== null
|
|
268
|
+
? value
|
|
269
|
+
: undefined;
|
|
270
|
+
}
|
|
271
|
+
function stringField(record, key) {
|
|
272
|
+
const value = record?.[key];
|
|
273
|
+
return typeof value === 'string' ? value : undefined;
|
|
274
|
+
}
|
|
275
|
+
function isAbortError(error) {
|
|
276
|
+
const name = stringField(asRecord(error), 'name');
|
|
277
|
+
return name === 'AbortError' || name === 'TimeoutError';
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Describe an error that carries an HTTP/GraphQL `response` (graphql-request's
|
|
281
|
+
* ClientError). The library-composed `message` of such errors embeds the full
|
|
282
|
+
* request (query and variables) and the raw response body, so it is never
|
|
283
|
+
* read: the description is built only from the status, the first GraphQL
|
|
284
|
+
* error's message and its `extensions.code`.
|
|
285
|
+
*/
|
|
286
|
+
function describeResponseError(response) {
|
|
287
|
+
const status = typeof response.status === 'number' ? response.status : undefined;
|
|
288
|
+
const errors = Array.isArray(response.errors) ? response.errors : [];
|
|
289
|
+
const first = asRecord(errors[0]);
|
|
290
|
+
const extensions = asRecord(first?.extensions);
|
|
291
|
+
// Federated subgraph errors carry the useful text under
|
|
292
|
+
// extensions.originalError.message; the top-level message is often generic.
|
|
293
|
+
const original = toDisplayLine(stringField(asRecord(extensions?.originalError), 'message'));
|
|
294
|
+
const wrapper = toDisplayLine(stringField(first, 'message'));
|
|
295
|
+
const rawCode = stringField(extensions, 'code');
|
|
296
|
+
const code = rawCode !== undefined && ERROR_CODE.test(rawCode) ? rawCode : undefined;
|
|
297
|
+
const base = original ||
|
|
298
|
+
wrapper ||
|
|
299
|
+
(status !== undefined ? `Request failed (HTTP ${status})` : 'Request failed');
|
|
300
|
+
return {
|
|
301
|
+
message: code ? `${base} [${code}]` : base,
|
|
302
|
+
...(status !== undefined ? { status } : {}),
|
|
303
|
+
...(code ? { code } : {}),
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function networkErrorCode(error) {
|
|
307
|
+
const code = stringField(asRecord(asRecord(error)?.cause), 'code');
|
|
308
|
+
return code !== undefined && ERROR_CODE.test(code) ? code : undefined;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Describe a failure of a GraphQL request for display. Network-level
|
|
312
|
+
* `TypeError`s (fetch failures) are reported as network errors; aborted
|
|
313
|
+
* requests as timeouts.
|
|
314
|
+
*/
|
|
315
|
+
export function describeRequestError(error) {
|
|
316
|
+
const response = asRecord(asRecord(error)?.response);
|
|
317
|
+
if (response)
|
|
318
|
+
return describeResponseError(response);
|
|
319
|
+
if (isAbortError(error))
|
|
320
|
+
return { message: 'Request timed out' };
|
|
321
|
+
if (error instanceof TypeError) {
|
|
322
|
+
const detail = toDisplayLine(error.message, MAX_HTTP_BODY_EXCERPT_LENGTH);
|
|
323
|
+
const code = networkErrorCode(error);
|
|
324
|
+
return {
|
|
325
|
+
message: `Network error${detail ? `: ${detail}` : ''}${code ? ` (${code})` : ''}`,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
return { message: toSafeErrorMessage(error) };
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Convert any thrown value into a message that is safe to print: a single
|
|
332
|
+
* line, at most {@link MAX_ERROR_MESSAGE_LENGTH} characters, free of terminal
|
|
333
|
+
* control sequences and with credential-shaped values masked. Response-bearing
|
|
334
|
+
* errors are described from an allowlist of fields only.
|
|
335
|
+
*/
|
|
336
|
+
export function toSafeErrorMessage(error) {
|
|
337
|
+
const response = asRecord(asRecord(error)?.response);
|
|
338
|
+
if (response)
|
|
339
|
+
return describeResponseError(response).message;
|
|
340
|
+
if (isAbortError(error))
|
|
341
|
+
return 'Request timed out';
|
|
342
|
+
if (error instanceof Error || typeof error === 'string') {
|
|
343
|
+
const text = typeof error === 'string' ? error : error.message;
|
|
344
|
+
return toDisplayLine(text) || 'Unexpected error';
|
|
345
|
+
}
|
|
346
|
+
return 'Unexpected error';
|
|
347
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/bigconsole-cli",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.1029.1",
|
|
4
4
|
"description": "Command-line interface for BigConsole platform operations and management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"audit": "bunx better-npm-audit audit",
|
|
34
34
|
"start": "bun dist/cli.js",
|
|
35
35
|
"publish:alpha": "bun run build && bunx npm@latest publish --tag alpha",
|
|
36
|
-
"publish:prod": "bun run build && bunx npm@latest publish"
|
|
36
|
+
"publish:prod": "bun run build && bunx npm@latest publish",
|
|
37
|
+
"schema:pull": "bash scripts/schema-pull.sh"
|
|
37
38
|
},
|
|
38
39
|
"keywords": [
|
|
39
40
|
"algoshred",
|
|
@@ -56,41 +57,42 @@
|
|
|
56
57
|
},
|
|
57
58
|
"homepage": "https://github.com/Algoshred/bigconsole-cli#readme",
|
|
58
59
|
"publishConfig": {
|
|
59
|
-
"access": "
|
|
60
|
+
"access": "public"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
63
|
"boxen": "^8.0.1",
|
|
63
|
-
"chalk": "^
|
|
64
|
-
"commander": "^
|
|
64
|
+
"chalk": "^6.0.0",
|
|
65
|
+
"commander": "^15.0.0",
|
|
65
66
|
"cross-fetch": "^4.1.0",
|
|
66
|
-
"graphql": "^
|
|
67
|
-
"graphql-request": "^7.
|
|
68
|
-
"inquirer": "^
|
|
69
|
-
"js-yaml": "^4.1
|
|
70
|
-
"ora": "^
|
|
67
|
+
"graphql": "^17.0.2",
|
|
68
|
+
"graphql-request": "^7.4.0",
|
|
69
|
+
"inquirer": "^14.1.0",
|
|
70
|
+
"js-yaml": "^5.4.1",
|
|
71
|
+
"ora": "^9.4.1",
|
|
71
72
|
"table": "^6.9.0",
|
|
72
73
|
"update-notifier": "^7.3.1"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
|
-
"@
|
|
76
|
-
"@
|
|
77
|
-
"@types/
|
|
78
|
-
"@types/node": "^
|
|
76
|
+
"@eslint/js": "^10.0.1",
|
|
77
|
+
"@playwright/test": "^1.62.1",
|
|
78
|
+
"@types/inquirer": "^9.0.10",
|
|
79
|
+
"@types/node": "^26.3.0",
|
|
79
80
|
"@types/update-notifier": "^6.0.8",
|
|
80
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
81
|
-
"@typescript-eslint/parser": "^8.
|
|
82
|
-
"@vitest/coverage-v8": "^
|
|
83
|
-
"@vitest/ui": "^
|
|
84
|
-
"eslint": "^9.
|
|
81
|
+
"@typescript-eslint/eslint-plugin": "^8.68.0",
|
|
82
|
+
"@typescript-eslint/parser": "^8.68.0",
|
|
83
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
84
|
+
"@vitest/ui": "^4.1.11",
|
|
85
|
+
"eslint": "^10.9.1",
|
|
85
86
|
"eslint-config-prettier": "^10.1.8",
|
|
86
|
-
"eslint-plugin-prettier": "^5.5.
|
|
87
|
-
"globals": "^
|
|
88
|
-
"prettier": "^3.6
|
|
89
|
-
"rimraf": "^6.
|
|
90
|
-
"tsc-alias": "^1.
|
|
91
|
-
"tsx": "^4.
|
|
92
|
-
"typescript": "^5.9.
|
|
93
|
-
"vitest": "^
|
|
87
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
88
|
+
"globals": "^17.11.0",
|
|
89
|
+
"prettier": "^3.9.6",
|
|
90
|
+
"rimraf": "^6.1.3",
|
|
91
|
+
"tsc-alias": "^1.9.2",
|
|
92
|
+
"tsx": "^4.23.12",
|
|
93
|
+
"typescript": "^5.9.3",
|
|
94
|
+
"vitest": "^4.1.11",
|
|
95
|
+
"yaml": "^2.8.3"
|
|
94
96
|
},
|
|
95
97
|
"engines": {
|
|
96
98
|
"node": ">=24.11.0",
|
|
@@ -103,14 +105,19 @@
|
|
|
103
105
|
"fast-xml-parser": ">=4.5.5",
|
|
104
106
|
"@xmldom/xmldom": ">=0.8.12",
|
|
105
107
|
"swiper": ">=12.1.2",
|
|
106
|
-
"brace-expansion": "
|
|
108
|
+
"brace-expansion": "5.0.9",
|
|
107
109
|
"follow-redirects": ">=1.15.12",
|
|
108
110
|
"smol-toml": ">=1.6.1",
|
|
109
111
|
"axios": ">=1.15.0",
|
|
110
|
-
"flatted": "
|
|
111
|
-
"yaml": "
|
|
112
|
-
"picomatch": "
|
|
112
|
+
"flatted": "3.4.4",
|
|
113
|
+
"yaml": "$yaml",
|
|
114
|
+
"picomatch": "4.0.7",
|
|
113
115
|
"immutable": ">=3.8.3",
|
|
114
|
-
"minimatch": ">=3.1.3"
|
|
116
|
+
"minimatch": ">=3.1.3",
|
|
117
|
+
"nanoid": "6.0.1",
|
|
118
|
+
"postcss": "8.5.26",
|
|
119
|
+
"vite": "8.2.2",
|
|
120
|
+
"fast-uri": "4.1.3",
|
|
121
|
+
"esbuild": "0.28.2"
|
|
115
122
|
}
|
|
116
123
|
}
|