@burdenoff/bigconsole-cli 2026.1029.1 → 2026.1110.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 +96 -212
- package/dist/auth/store.d.ts +0 -4
- package/dist/cli.js +2959 -103
- package/dist/commands/base.d.ts +0 -4
- package/dist/graphql/operations.d.ts +1 -1
- package/dist/index.js +2895 -6
- package/dist/utils/parse.d.ts +5 -0
- package/package.json +42 -41
- package/dist/auth/device-code.js +0 -244
- package/dist/auth/store.js +0 -90
- package/dist/commands/auth.js +0 -353
- package/dist/commands/base.js +0 -120
- package/dist/commands/cli-config.js +0 -79
- package/dist/commands/dashboard.js +0 -223
- package/dist/commands/datasink.js +0 -175
- package/dist/commands/drilldown.js +0 -55
- package/dist/commands/index.js +0 -13
- package/dist/commands/parser.js +0 -181
- package/dist/commands/pipeline.js +0 -142
- package/dist/commands/prompt.js +0 -84
- package/dist/commands/share.js +0 -50
- package/dist/commands/template.js +0 -62
- package/dist/commands/widget.js +0 -164
- package/dist/commands/workflow.js +0 -54
- package/dist/commands/workspace.js +0 -95
- package/dist/config/index.js +0 -151
- package/dist/graphql/client.js +0 -254
- package/dist/graphql/operations.js +0 -680
- package/dist/types/index.d.ts +0 -30
- package/dist/types/index.js +0 -7
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -2
- package/dist/utils/output.js +0 -237
- package/dist/utils/sanitize.js +0 -347
package/dist/config/index.js
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI configuration management.
|
|
3
|
-
* Persists CLI-level settings to ~/.config/bigconsole-cli/config.json
|
|
4
|
-
*/
|
|
5
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from 'fs';
|
|
6
|
-
import { join } from 'path';
|
|
7
|
-
import { homedir } from 'os';
|
|
8
|
-
const CONFIG_DIR = join(homedir(), '.config', 'bigconsole-cli');
|
|
9
|
-
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
10
|
-
/**
|
|
11
|
-
* Well-known client ID for the BigConsole CLI.
|
|
12
|
-
* This is a system app auto-created by global-auth-svc on startup.
|
|
13
|
-
* Same pattern as GitHub CLI (gh), Claude Code, Stripe CLI.
|
|
14
|
-
*/
|
|
15
|
-
export const DEFAULT_CLIENT_ID = 'burdenoff_cli_bigconsole';
|
|
16
|
-
/** Production OIDC issuer (global gateway) */
|
|
17
|
-
const PROD_OIDC_ISSUER = 'https://graphql.burdenoff.com/global';
|
|
18
|
-
/** Production workspace gateway endpoint */
|
|
19
|
-
export const PROD_WORKSPACE_ENDPOINT = 'https://graphqlworkspaces.burdenoff.com/workspaces/graphql';
|
|
20
|
-
/** Production global gateway endpoint */
|
|
21
|
-
export const PROD_GLOBAL_ENDPOINT = 'https://graphql.burdenoff.com/global/graphql';
|
|
22
|
-
export const DEFAULT_CONFIG = {
|
|
23
|
-
workspaceEndpoint: PROD_WORKSPACE_ENDPOINT,
|
|
24
|
-
globalEndpoint: PROD_GLOBAL_ENDPOINT,
|
|
25
|
-
};
|
|
26
|
-
function ensureConfigDir() {
|
|
27
|
-
if (!existsSync(CONFIG_DIR)) {
|
|
28
|
-
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function getEnvOverrides() {
|
|
32
|
-
const overrides = {};
|
|
33
|
-
if (process.env.BIGCONSOLE_WORKSPACE_ENDPOINT) {
|
|
34
|
-
overrides.workspaceEndpoint = process.env.BIGCONSOLE_WORKSPACE_ENDPOINT;
|
|
35
|
-
}
|
|
36
|
-
if (process.env.BIGCONSOLE_GLOBAL_ENDPOINT) {
|
|
37
|
-
overrides.globalEndpoint = process.env.BIGCONSOLE_GLOBAL_ENDPOINT;
|
|
38
|
-
}
|
|
39
|
-
if (process.env.BIGCONSOLE_OIDC_ISSUER) {
|
|
40
|
-
overrides.oidcIssuer = process.env.BIGCONSOLE_OIDC_ISSUER;
|
|
41
|
-
}
|
|
42
|
-
if (process.env.BIGCONSOLE_CLIENT_ID) {
|
|
43
|
-
overrides.clientId = process.env.BIGCONSOLE_CLIENT_ID;
|
|
44
|
-
}
|
|
45
|
-
return overrides;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Read the CLI configuration, merging with defaults.
|
|
49
|
-
*
|
|
50
|
-
* Resolution order (later wins):
|
|
51
|
-
* 1. Built-in production defaults
|
|
52
|
-
* 2. Environment variables BIGCONSOLE_WORKSPACE_ENDPOINT, BIGCONSOLE_GLOBAL_ENDPOINT,
|
|
53
|
-
* BIGCONSOLE_OIDC_ISSUER, BIGCONSOLE_CLIENT_ID
|
|
54
|
-
* 3. Values stored in ~/.config/bigconsole-cli/config.json
|
|
55
|
-
*/
|
|
56
|
-
export function readConfig() {
|
|
57
|
-
try {
|
|
58
|
-
const envOverrides = getEnvOverrides();
|
|
59
|
-
if (!existsSync(CONFIG_FILE))
|
|
60
|
-
return { ...DEFAULT_CONFIG, ...envOverrides };
|
|
61
|
-
const raw = readFileSync(CONFIG_FILE, 'utf8');
|
|
62
|
-
const stored = JSON.parse(raw);
|
|
63
|
-
return { ...DEFAULT_CONFIG, ...envOverrides, ...stored };
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
return { ...DEFAULT_CONFIG };
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Write the CLI configuration to disk.
|
|
71
|
-
*/
|
|
72
|
-
export function writeConfig(config) {
|
|
73
|
-
ensureConfigDir();
|
|
74
|
-
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { encoding: 'utf8' });
|
|
75
|
-
try {
|
|
76
|
-
chmodSync(CONFIG_FILE, 0o600);
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
// chmodSync may fail on Windows, non-critical
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Get a single config value by key.
|
|
84
|
-
*/
|
|
85
|
-
export function getConfigValue(key) {
|
|
86
|
-
const config = readConfig();
|
|
87
|
-
return config[key];
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Set a single config value by key.
|
|
91
|
-
*/
|
|
92
|
-
export function setConfigValue(key, value) {
|
|
93
|
-
const config = readConfig();
|
|
94
|
-
config[key] = value;
|
|
95
|
-
writeConfig(config);
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Get the path to the config file.
|
|
99
|
-
*/
|
|
100
|
-
export function getConfigPath() {
|
|
101
|
-
return CONFIG_FILE;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Get the config directory path.
|
|
105
|
-
*/
|
|
106
|
-
export function getConfigDir() {
|
|
107
|
-
return CONFIG_DIR;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Resolve OIDC configuration with smart defaults.
|
|
111
|
-
* - clientId defaults to the built-in BigConsole CLI system app
|
|
112
|
-
* - oidcIssuer derives from the configured globalEndpoint
|
|
113
|
-
* Users can override both via cli-config if they have a custom OIDC provider.
|
|
114
|
-
*/
|
|
115
|
-
export function resolveOIDCConfig() {
|
|
116
|
-
const config = readConfig();
|
|
117
|
-
// Client ID: user override > built-in default
|
|
118
|
-
const clientId = config.clientId || DEFAULT_CLIENT_ID;
|
|
119
|
-
// OIDC issuer: user override > derive from any non-prod endpoint > prod default.
|
|
120
|
-
//
|
|
121
|
-
// Strip the trailing `/graphql` from the endpoint so OIDC routes (device-code,
|
|
122
|
-
// token, etc.) are mounted at the parent path. The second `.replace()` that
|
|
123
|
-
// used to target `/global/graphql$` was dead code — the first replace always
|
|
124
|
-
// strips the trailing `/graphql` first.
|
|
125
|
-
//
|
|
126
|
-
// Deriving from the endpoint also covers staging / self-hosted global
|
|
127
|
-
// gateways, not just localhost: if the user has explicitly pointed
|
|
128
|
-
// `globalEndpoint` somewhere non-prod the issuer should follow, and only the
|
|
129
|
-
// implicit prod endpoint falls back to `PROD_OIDC_ISSUER`.
|
|
130
|
-
let oidcIssuer = config.oidcIssuer;
|
|
131
|
-
if (!oidcIssuer) {
|
|
132
|
-
const globalEndpoint = config.globalEndpoint;
|
|
133
|
-
const isProdEndpoint = globalEndpoint.includes('graphql.burdenoff.com');
|
|
134
|
-
if (isProdEndpoint) {
|
|
135
|
-
oidcIssuer = PROD_OIDC_ISSUER;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
oidcIssuer = globalEndpoint.replace(/\/graphql$/, '');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return { oidcIssuer, clientId };
|
|
142
|
-
}
|
|
143
|
-
export const KNOWN_CONFIG_KEYS = [
|
|
144
|
-
'workspaceEndpoint',
|
|
145
|
-
'globalEndpoint',
|
|
146
|
-
'oidcIssuer',
|
|
147
|
-
'clientId',
|
|
148
|
-
'defaultFormat',
|
|
149
|
-
'verbose',
|
|
150
|
-
'authServiceEndpoint',
|
|
151
|
-
];
|
package/dist/graphql/client.js
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GraphQL client for CLI operations.
|
|
3
|
-
* Dual-endpoint: workspace gateway (bigconsole ops) + global gateway (auth ops).
|
|
4
|
-
* Auto-injects auth headers, auto-refreshes both platform and workspace tokens.
|
|
5
|
-
*/
|
|
6
|
-
import { GraphQLClient } from 'graphql-request';
|
|
7
|
-
import { readConfig } from '../config/index.js';
|
|
8
|
-
import { readAuth, writeAuth, isTokenExpiringSoon, isWorkspaceTokenExpiringSoon, } from '../auth/store.js';
|
|
9
|
-
import { issueWorkspaceToken, clientCredentialsFlow } from '../auth/device-code.js';
|
|
10
|
-
import { printError } from '../utils/output.js';
|
|
11
|
-
import { describeRequestError, toSafeErrorMessage, } from '../utils/sanitize.js';
|
|
12
|
-
const DEFAULT_TIMEOUT = 30000;
|
|
13
|
-
const MAX_RETRIES = 3;
|
|
14
|
-
const INITIAL_RETRY_DELAY_MS = 1000;
|
|
15
|
-
function sleep(ms) {
|
|
16
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
-
}
|
|
18
|
-
function isNetworkOrServerError(error) {
|
|
19
|
-
if (error instanceof TypeError)
|
|
20
|
-
return true;
|
|
21
|
-
if (error && typeof error === 'object' && 'response' in error) {
|
|
22
|
-
const resp = error.response;
|
|
23
|
-
if (resp && typeof resp.status === 'number' && resp.status >= 500)
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Error thrown for a failed GraphQL request. Its message is built only from
|
|
30
|
-
* the HTTP status, the server's first GraphQL error and its error code, so it
|
|
31
|
-
* is safe to print. The underlying client error is deliberately not attached
|
|
32
|
-
* (no `cause`): it carries the request variables and the raw response body.
|
|
33
|
-
*/
|
|
34
|
-
export class BigConsoleRequestError extends Error {
|
|
35
|
-
constructor(description) {
|
|
36
|
-
super(description.message);
|
|
37
|
-
this.name = 'BigConsoleRequestError';
|
|
38
|
-
this.status = description.status;
|
|
39
|
-
this.code = description.code;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
let workspaceClient = null;
|
|
43
|
-
let globalClient = null;
|
|
44
|
-
function getHeaders(auth) {
|
|
45
|
-
const headers = {};
|
|
46
|
-
if (auth?.accessToken) {
|
|
47
|
-
headers['Authorization'] = `Bearer ${auth.accessToken}`;
|
|
48
|
-
}
|
|
49
|
-
return headers;
|
|
50
|
-
}
|
|
51
|
-
function getWorkspaceHeaders(auth) {
|
|
52
|
-
const headers = getHeaders(auth);
|
|
53
|
-
if (auth?.workspaceToken) {
|
|
54
|
-
headers['X-Workspace-Authorization'] = `Bearer ${auth.workspaceToken}`;
|
|
55
|
-
}
|
|
56
|
-
if (auth?.organizationId) {
|
|
57
|
-
headers['x-org-id'] = auth.organizationId;
|
|
58
|
-
}
|
|
59
|
-
return headers;
|
|
60
|
-
}
|
|
61
|
-
function initClients() {
|
|
62
|
-
const config = readConfig();
|
|
63
|
-
const auth = readAuth();
|
|
64
|
-
workspaceClient = new GraphQLClient(config.workspaceEndpoint);
|
|
65
|
-
workspaceClient.setHeaders(getWorkspaceHeaders(auth));
|
|
66
|
-
globalClient = new GraphQLClient(config.globalEndpoint);
|
|
67
|
-
globalClient.setHeaders(getHeaders(auth));
|
|
68
|
-
return { workspace: workspaceClient, global: globalClient };
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Refresh the platform access token.
|
|
72
|
-
* For client_credentials: re-authenticate with stored credentials.
|
|
73
|
-
* For device_code/api_key: use the stored refresh token.
|
|
74
|
-
*/
|
|
75
|
-
async function refreshPlatformToken() {
|
|
76
|
-
const auth = readAuth();
|
|
77
|
-
if (!auth)
|
|
78
|
-
return;
|
|
79
|
-
if (auth.authMethod === 'client_credentials' && auth.clientId && auth.clientSecret) {
|
|
80
|
-
const config = readConfig();
|
|
81
|
-
try {
|
|
82
|
-
const result = await clientCredentialsFlow(config.globalEndpoint, auth.clientId, auth.clientSecret);
|
|
83
|
-
writeAuth({
|
|
84
|
-
...auth,
|
|
85
|
-
accessToken: result.accessToken,
|
|
86
|
-
expiresAt: Date.now() + result.expiresIn * 1000,
|
|
87
|
-
});
|
|
88
|
-
workspaceClient = null;
|
|
89
|
-
globalClient = null;
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
printError(`App token refresh failed: ${toSafeErrorMessage(error)}`);
|
|
93
|
-
}
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (!auth.refreshToken)
|
|
97
|
-
return;
|
|
98
|
-
const config = readConfig();
|
|
99
|
-
const client = new GraphQLClient(config.globalEndpoint);
|
|
100
|
-
client.setHeaders({ Authorization: `Bearer ${auth.accessToken}` });
|
|
101
|
-
const REFRESH_MUTATION = `
|
|
102
|
-
mutation RefreshToken($token: String!) {
|
|
103
|
-
refreshToken(token: $token) {
|
|
104
|
-
accessToken
|
|
105
|
-
refreshToken
|
|
106
|
-
expiresIn
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
`;
|
|
110
|
-
try {
|
|
111
|
-
const data = await client.request(REFRESH_MUTATION, {
|
|
112
|
-
token: auth.refreshToken,
|
|
113
|
-
});
|
|
114
|
-
const result = data.refreshToken;
|
|
115
|
-
const expiresAt = Date.now() + result.expiresIn * 1000;
|
|
116
|
-
writeAuth({
|
|
117
|
-
...auth,
|
|
118
|
-
accessToken: result.accessToken,
|
|
119
|
-
refreshToken: result.refreshToken,
|
|
120
|
-
expiresAt,
|
|
121
|
-
});
|
|
122
|
-
workspaceClient = null;
|
|
123
|
-
globalClient = null;
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
printError(`Token refresh failed: ${toSafeErrorMessage(error)}`);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Refresh the workspace token using the current platform token.
|
|
131
|
-
*/
|
|
132
|
-
async function refreshWorkspaceToken() {
|
|
133
|
-
const auth = readAuth();
|
|
134
|
-
if (!auth?.accessToken || !auth.workspaceId || !auth.organizationId)
|
|
135
|
-
return;
|
|
136
|
-
const config = readConfig();
|
|
137
|
-
try {
|
|
138
|
-
const result = await issueWorkspaceToken(config.workspaceEndpoint, auth.accessToken, auth.workspaceId, auth.organizationId);
|
|
139
|
-
writeAuth({
|
|
140
|
-
...auth,
|
|
141
|
-
workspaceToken: result.token,
|
|
142
|
-
workspaceTokenExpiresAt: new Date(result.expiresAt).getTime(),
|
|
143
|
-
});
|
|
144
|
-
workspaceClient = null;
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
printError(`Workspace token refresh failed: ${toSafeErrorMessage(error)}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
export async function ensureFreshTokens() {
|
|
151
|
-
const auth = readAuth();
|
|
152
|
-
if (!auth)
|
|
153
|
-
return;
|
|
154
|
-
if (isTokenExpiringSoon(auth)) {
|
|
155
|
-
await refreshPlatformToken();
|
|
156
|
-
}
|
|
157
|
-
const freshAuth = readAuth();
|
|
158
|
-
if (freshAuth && freshAuth.workspaceToken && isWorkspaceTokenExpiringSoon(freshAuth)) {
|
|
159
|
-
await refreshWorkspaceToken();
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Inspect a GraphQL document to decide whether it is safe to retry.
|
|
164
|
-
* Mutations are NOT retried — a transient error may land the write
|
|
165
|
-
* server-side even if the client observed a timeout, so blindly
|
|
166
|
-
* retrying create/update/delete could create duplicates. Queries are
|
|
167
|
-
* always retryable.
|
|
168
|
-
*/
|
|
169
|
-
function isRetryableDocument(document) {
|
|
170
|
-
const text = typeof document === 'string'
|
|
171
|
-
? document
|
|
172
|
-
: typeof document?.loc?.source?.body ===
|
|
173
|
-
'string'
|
|
174
|
-
? document.loc.source.body
|
|
175
|
-
: '';
|
|
176
|
-
const m = text.match(/\b(query|mutation|subscription)\b/i);
|
|
177
|
-
return !m || m[1].toLowerCase() === 'query';
|
|
178
|
-
}
|
|
179
|
-
async function executeWithRetry(client, document, variables) {
|
|
180
|
-
const retryable = isRetryableDocument(document);
|
|
181
|
-
const maxAttempts = retryable ? MAX_RETRIES : 1;
|
|
182
|
-
let lastError;
|
|
183
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
184
|
-
try {
|
|
185
|
-
const controller = new AbortController();
|
|
186
|
-
const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
|
|
187
|
-
try {
|
|
188
|
-
return await client.request({
|
|
189
|
-
document,
|
|
190
|
-
variables,
|
|
191
|
-
signal: controller.signal,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
finally {
|
|
195
|
-
clearTimeout(timer);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
lastError = error;
|
|
200
|
-
if (error && typeof error === 'object' && 'response' in error) {
|
|
201
|
-
const resp = error.response;
|
|
202
|
-
if (resp && typeof resp.status === 'number' && resp.status >= 400 && resp.status < 500) {
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
if (retryable && isNetworkOrServerError(error) && attempt < maxAttempts - 1) {
|
|
207
|
-
const delay = INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt);
|
|
208
|
-
await sleep(delay);
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
throw new BigConsoleRequestError(describeRequestError(lastError));
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Execute a GraphQL request against the workspace gateway.
|
|
218
|
-
* Auto-refreshes both platform and workspace tokens when they are about to expire.
|
|
219
|
-
*/
|
|
220
|
-
export async function workspaceRequest(document, variables) {
|
|
221
|
-
await ensureFreshTokens();
|
|
222
|
-
const { workspace } = workspaceClient ? { workspace: workspaceClient } : initClients();
|
|
223
|
-
const auth = readAuth();
|
|
224
|
-
workspace.setHeaders(getWorkspaceHeaders(auth));
|
|
225
|
-
return executeWithRetry(workspace, document, variables);
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Execute a GraphQL request against the global gateway (auth operations).
|
|
229
|
-
* Does NOT auto-refresh tokens (to prevent loops during refresh itself).
|
|
230
|
-
*/
|
|
231
|
-
export async function globalRequest(document, variables) {
|
|
232
|
-
const { global: client } = globalClient ? { global: globalClient } : initClients();
|
|
233
|
-
const auth = readAuth();
|
|
234
|
-
client.setHeaders(getHeaders(auth));
|
|
235
|
-
return executeWithRetry(client, document, variables);
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Execute a request against the workspace gateway with ONLY the platform auth token.
|
|
239
|
-
* Used for IssueWorkspaceToken which does not require an existing workspace token.
|
|
240
|
-
*/
|
|
241
|
-
export async function workspaceAuthOnlyRequest(document, variables) {
|
|
242
|
-
const config = readConfig();
|
|
243
|
-
const auth = readAuth();
|
|
244
|
-
const client = new GraphQLClient(config.workspaceEndpoint);
|
|
245
|
-
client.setHeaders(getHeaders(auth));
|
|
246
|
-
return executeWithRetry(client, document, variables);
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Reset cached clients (useful after auth changes).
|
|
250
|
-
*/
|
|
251
|
-
export function resetClients() {
|
|
252
|
-
workspaceClient = null;
|
|
253
|
-
globalClient = null;
|
|
254
|
-
}
|