@burdenoff/bigconsole-cli 2026.802.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.
Files changed (53) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +235 -0
  3. package/dist/auth/device-code.d.ts +66 -0
  4. package/dist/auth/device-code.js +239 -0
  5. package/dist/auth/store.d.ts +46 -0
  6. package/dist/auth/store.js +90 -0
  7. package/dist/cli.d.ts +5 -0
  8. package/dist/cli.js +126 -0
  9. package/dist/commands/auth.d.ts +5 -0
  10. package/dist/commands/auth.js +352 -0
  11. package/dist/commands/base.d.ts +47 -0
  12. package/dist/commands/base.js +100 -0
  13. package/dist/commands/cli-config.d.ts +6 -0
  14. package/dist/commands/cli-config.js +79 -0
  15. package/dist/commands/dashboard.d.ts +5 -0
  16. package/dist/commands/dashboard.js +220 -0
  17. package/dist/commands/datasink.d.ts +5 -0
  18. package/dist/commands/datasink.js +175 -0
  19. package/dist/commands/drilldown.d.ts +9 -0
  20. package/dist/commands/drilldown.js +47 -0
  21. package/dist/commands/index.d.ts +13 -0
  22. package/dist/commands/index.js +13 -0
  23. package/dist/commands/parser.d.ts +5 -0
  24. package/dist/commands/parser.js +181 -0
  25. package/dist/commands/pipeline.d.ts +5 -0
  26. package/dist/commands/pipeline.js +142 -0
  27. package/dist/commands/prompt.d.ts +5 -0
  28. package/dist/commands/prompt.js +84 -0
  29. package/dist/commands/share.d.ts +8 -0
  30. package/dist/commands/share.js +50 -0
  31. package/dist/commands/template.d.ts +5 -0
  32. package/dist/commands/template.js +62 -0
  33. package/dist/commands/widget.d.ts +5 -0
  34. package/dist/commands/widget.js +164 -0
  35. package/dist/commands/workflow.d.ts +9 -0
  36. package/dist/commands/workflow.js +54 -0
  37. package/dist/commands/workspace.d.ts +9 -0
  38. package/dist/commands/workspace.js +95 -0
  39. package/dist/config/index.d.ts +72 -0
  40. package/dist/config/index.js +151 -0
  41. package/dist/graphql/client.d.ts +26 -0
  42. package/dist/graphql/client.js +274 -0
  43. package/dist/graphql/operations.d.ts +48 -0
  44. package/dist/graphql/operations.js +654 -0
  45. package/dist/index.d.ts +6 -0
  46. package/dist/index.js +6 -0
  47. package/dist/types/index.d.ts +30 -0
  48. package/dist/types/index.js +7 -0
  49. package/dist/utils/index.d.ts +1 -0
  50. package/dist/utils/index.js +1 -0
  51. package/dist/utils/output.d.ts +62 -0
  52. package/dist/utils/output.js +186 -0
  53. package/package.json +116 -0
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ Copyright (c) 2025 Burdenoff Consultancy Services Private Limited, Algoshred Technologies Private Limited and all sister companies.
2
+
3
+ All rights reserved.
4
+
5
+ This software is proprietary and confidential. Unauthorized copying, modification, distribution, or use of this software, via any medium, is strictly prohibited without the express written permission of the copyright holders.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
9
+ For licensing inquiries, please contact: legal@algoshred.com
package/README.md ADDED
@@ -0,0 +1,235 @@
1
+ # Bigconsole Cli
2
+
3
+ A powerful command-line interface for managing bigconsole operations with GraphQL backend integration.
4
+
5
+ ## Features
6
+
7
+ - 🔐 **Authentication Management** - Login, logout, and status checking
8
+ - 👥 **User Management** - CRUD operations for user accounts
9
+ - ⚙️ **Configuration Management** - Easy setup and configuration
10
+ - 📊 **Multiple Output Formats** - JSON, table, and YAML output
11
+ - 🛡️ **Type Safety** - Built with TypeScript for reliability
12
+ - 🎨 **Rich CLI Experience** - Colorful output and interactive prompts
13
+
14
+ ## Installation
15
+
16
+ ### Global Installation (Production)
17
+
18
+ ```bash
19
+ npm install -g @burdenoff/bigconsole-cli
20
+ ```
21
+
22
+ ### Global Installation (Alpha/Pre-release)
23
+
24
+ ```bash
25
+ npm install -g @burdenoff/alpha-bigconsole-cli
26
+ ```
27
+
28
+ ### Local Installation
29
+
30
+ ```bash
31
+ npm install @burdenoff/bigconsole-cli
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ Configure the API endpoint:
37
+
38
+ ```bash
39
+ bigconsole config set apiEndpoint http://localhost:8000/graphql
40
+ ```
41
+
42
+ ## Authentication
43
+
44
+ ### Login with credentials
45
+ ```bash
46
+ bigconsole auth login
47
+ ```
48
+
49
+ ### Login with token
50
+ ```bash
51
+ bigconsole auth login --token <your-access-token>
52
+ ```
53
+
54
+ ### Check authentication status
55
+ ```bash
56
+ bigconsole auth status
57
+ ```
58
+
59
+ ### Logout
60
+ ```bash
61
+ bigconsole auth logout
62
+ ```
63
+
64
+ ### Change password
65
+ ```bash
66
+ bigconsole auth change-password
67
+ ```
68
+
69
+ ## User Management
70
+
71
+ ### List users
72
+ ```bash
73
+ bigconsole users list
74
+ bigconsole users list --page 2 --limit 20
75
+ ```
76
+
77
+ ### Get user details
78
+ ```bash
79
+ bigconsole users get <user-id>
80
+ ```
81
+
82
+ ### Create a user
83
+ ```bash
84
+ bigconsole users create
85
+ bigconsole users create --email user@example.com --password password123 --fullName "John Doe"
86
+ ```
87
+
88
+ ### Update a user
89
+ ```bash
90
+ bigconsole users update <user-id> --email newemail@example.com
91
+ bigconsole users update <user-id> --active
92
+ bigconsole users update <user-id> --superuser
93
+ ```
94
+
95
+ ### Delete a user
96
+ ```bash
97
+ bigconsole users delete <user-id>
98
+ bigconsole users delete <user-id> --force
99
+ ```
100
+
101
+ ## Configuration Management
102
+
103
+ ### View all configuration
104
+ ```bash
105
+ bigconsole config get
106
+ ```
107
+
108
+ ### Get specific configuration
109
+ ```bash
110
+ bigconsole config get apiEndpoint
111
+ ```
112
+
113
+ ### Set configuration
114
+ ```bash
115
+ bigconsole config set apiEndpoint http://localhost:8000/graphql
116
+ bigconsole config set outputFormat table
117
+ ```
118
+
119
+ ### Delete configuration
120
+ ```bash
121
+ bigconsole config delete accessToken
122
+ ```
123
+
124
+ ### Clear all configuration
125
+ ```bash
126
+ bigconsole config clear
127
+ ```
128
+
129
+ ### Show config file path
130
+ ```bash
131
+ bigconsole config path
132
+ ```
133
+
134
+ ## Output Formats
135
+
136
+ All commands support different output formats:
137
+
138
+ ```bash
139
+ bigconsole users list --format json
140
+ bigconsole users list --format table
141
+ bigconsole users list --format yaml
142
+ ```
143
+
144
+ ## Global Options
145
+
146
+ - `--endpoint <endpoint>`: Override the API endpoint for a single command
147
+ - `--token <token>`: Override the access token for a single command
148
+ - `--format <format>`: Set output format (json, table, yaml)
149
+ - `--verbose`: Enable verbose logging
150
+
151
+ ## Examples
152
+
153
+ ```bash
154
+ # Set up the CLI
155
+ bigconsole config set apiEndpoint http://localhost:8000/graphql
156
+
157
+ # Login
158
+ bigconsole auth login
159
+
160
+ # List all users in table format
161
+ bigconsole users list --format table
162
+
163
+ # Create a new user
164
+ bigconsole users create --email admin@example.com --password admin123 --superuser
165
+
166
+ # Check authentication status
167
+ bigconsole auth status
168
+
169
+ # Get help for any command
170
+ bigconsole auth --help
171
+ bigconsole users --help
172
+ ```
173
+
174
+ ## Development
175
+
176
+ ```bash
177
+ # Install dependencies
178
+ npm install
179
+
180
+ # Build the project
181
+ npm run build
182
+
183
+ # Run in development mode
184
+ npm run dev
185
+
186
+ # Run tests
187
+ npm test
188
+
189
+ # Lint code
190
+ npm run lint
191
+ ```
192
+
193
+ ## Configuration File
194
+
195
+ The CLI stores configuration in `~/.config/bigconsole-cli/config.json`. This includes:
196
+
197
+ - `apiEndpoint`: The GraphQL API endpoint
198
+ - `outputFormat`: Default output format (json, table, yaml)
199
+ - `accessToken`: Authentication token
200
+ - `refreshToken`: Refresh token for authentication
201
+
202
+ ## CI/CD
203
+
204
+ The project includes automated CI/CD pipelines:
205
+
206
+ - **Alpha builds** - Published to `@burdenoff/alpha-bigconsole-cli` from `alpha` branch
207
+ - **Production builds** - Published to `@burdenoff/bigconsole-cli` from `main` branch
208
+
209
+ ## Testing
210
+
211
+ See [TESTING.md](./TESTING.md) for comprehensive testing instructions before publishing.
212
+
213
+ ## Security
214
+
215
+ - Tokens are stored securely in user configuration directory
216
+ - No sensitive information is logged in verbose mode
217
+ - All API communication uses HTTPS
218
+ - Input validation prevents injection attacks
219
+
220
+ ## Contributing
221
+
222
+ 1. Fork the repository
223
+ 2. Create a feature branch
224
+ 3. Make your changes
225
+ 4. Add tests for new functionality
226
+ 5. Ensure all tests pass
227
+ 6. Submit a pull request
228
+
229
+ ## License
230
+
231
+ UNLICENSED - Private package for internal use
232
+
233
+ ---
234
+
235
+ Built with ❤️ by [Vignesh T.V](https://github.com/tvvignesh)
@@ -0,0 +1,66 @@
1
+ /**
2
+ * OAuth2 Device Code flow implementation.
3
+ * Used for CLI authentication (similar to `gh auth login`).
4
+ */
5
+ import type { CLIConfig } from '../config/index.js';
6
+ export interface DeviceCodeResponse {
7
+ deviceCode: string;
8
+ userCode: string;
9
+ verificationUri: string;
10
+ verificationUriComplete: string | null;
11
+ expiresIn: number;
12
+ interval: number;
13
+ }
14
+ export interface DeviceCodeTokenResult {
15
+ accessToken: string;
16
+ refreshToken: string;
17
+ expiresIn: number;
18
+ }
19
+ /**
20
+ * Start the device code flow by requesting a device code from the OIDC issuer.
21
+ */
22
+ export declare function startDeviceCodeFlow(config: CLIConfig & {
23
+ oidcIssuer: string;
24
+ clientId: string;
25
+ }): Promise<DeviceCodeResponse>;
26
+ /**
27
+ * Poll the token endpoint until the user approves or the code expires.
28
+ */
29
+ export declare function pollForToken(deviceCode: string, interval: number, config: CLIConfig & {
30
+ oidcIssuer: string;
31
+ clientId: string;
32
+ }): Promise<DeviceCodeTokenResult>;
33
+ export interface ClientCredentialsResult {
34
+ accessToken: string;
35
+ expiresIn: number;
36
+ scopes: string[];
37
+ }
38
+ /**
39
+ * Authenticate using client credentials (app authentication).
40
+ * Calls the AuthenticateApp mutation on the global gateway.
41
+ */
42
+ export declare function clientCredentialsFlow(globalEndpoint: string, clientId: string, clientSecret: string, scopes?: string[]): Promise<ClientCredentialsResult>;
43
+ /**
44
+ * Issue a workspace token by calling the workspace gateway with an auth token.
45
+ * Only sends Authorization header (no X-Workspace-Authorization).
46
+ */
47
+ export declare function issueWorkspaceToken(workspaceEndpoint: string, authToken: string, workspaceId: string, organizationId: string): Promise<{
48
+ token: string;
49
+ expiresAt: string;
50
+ scopes: string[];
51
+ }>;
52
+ /**
53
+ * Fetch user's workspaces from the global gateway.
54
+ */
55
+ export declare function fetchWorkspaces(globalEndpoint: string, authToken: string): Promise<Array<{
56
+ id: string;
57
+ name: string;
58
+ slug: string;
59
+ tenantId: string;
60
+ organizationId: string;
61
+ }>>;
62
+ /**
63
+ * Attempt to open a URL in the user's default browser.
64
+ * Uses execFile instead of exec to avoid shell interpretation and command injection.
65
+ */
66
+ export declare function openBrowser(url: string): Promise<boolean>;
@@ -0,0 +1,239 @@
1
+ /**
2
+ * OAuth2 Device Code flow implementation.
3
+ * Used for CLI authentication (similar to `gh auth login`).
4
+ */
5
+ import fetch from 'cross-fetch';
6
+ /**
7
+ * Start the device code flow by requesting a device code from the OIDC issuer.
8
+ */
9
+ export async function startDeviceCodeFlow(config) {
10
+ const url = `${config.oidcIssuer}/oidc/device/code`;
11
+ const body = new URLSearchParams({
12
+ client_id: config.clientId,
13
+ scope: 'openid profile email offline_access',
14
+ });
15
+ const response = await fetch(url, {
16
+ method: 'POST',
17
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
18
+ body: body.toString(),
19
+ });
20
+ if (!response.ok) {
21
+ const text = await response.text().catch(() => 'Unknown error');
22
+ throw new Error(`Device code request failed (${response.status}): ${text}`);
23
+ }
24
+ const data = (await response.json());
25
+ return {
26
+ deviceCode: data['device_code'],
27
+ userCode: data['user_code'],
28
+ verificationUri: data['verification_uri'],
29
+ verificationUriComplete: data['verification_uri_complete'] ?? null,
30
+ expiresIn: data['expires_in'],
31
+ interval: data['interval'] ?? 5,
32
+ };
33
+ }
34
+ /**
35
+ * Poll the token endpoint until the user approves or the code expires.
36
+ */
37
+ export async function pollForToken(deviceCode, interval, config) {
38
+ const url = `${config.oidcIssuer}/oauth/device/token`;
39
+ let pollInterval = interval;
40
+ while (true) {
41
+ await new Promise((resolve) => setTimeout(resolve, pollInterval * 1000));
42
+ const response = await fetch(url, {
43
+ method: 'POST',
44
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
45
+ body: new URLSearchParams({
46
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
47
+ device_code: deviceCode,
48
+ client_id: config.clientId,
49
+ }).toString(),
50
+ });
51
+ // Guard against non-JSON responses (e.g. a 502 HTML error page from a
52
+ // gateway during a restart). Parsing those as JSON throws SyntaxError,
53
+ // aborts the whole poll loop, and forces the user to re-run
54
+ // `bigconsole auth login` from scratch even though the transient error
55
+ // would have cleared on the next tick.
56
+ const raw = await response.text();
57
+ let data;
58
+ try {
59
+ data = JSON.parse(raw);
60
+ }
61
+ catch {
62
+ if (response.status >= 500) {
63
+ // Treat it like authorization_pending — keep polling.
64
+ continue;
65
+ }
66
+ throw new Error(`Token endpoint returned non-JSON response (status ${response.status}): ${raw.slice(0, 200)}`);
67
+ }
68
+ if (response.ok && data['access_token']) {
69
+ return {
70
+ accessToken: data['access_token'],
71
+ refreshToken: data['refresh_token'] ?? '',
72
+ expiresIn: data['expires_in'] ?? 3600,
73
+ };
74
+ }
75
+ const errorCode = data['error'];
76
+ switch (errorCode) {
77
+ case 'authorization_pending':
78
+ continue;
79
+ case 'slow_down':
80
+ pollInterval += 5;
81
+ continue;
82
+ case 'expired_token':
83
+ throw new Error('Device code has expired. Please try again.');
84
+ case 'access_denied':
85
+ throw new Error('Authorization was denied by the user.');
86
+ default:
87
+ throw new Error(`Device code polling failed: ${data['error_description'] ?? errorCode ?? 'Unknown error'}`);
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * Authenticate using client credentials (app authentication).
93
+ * Calls the AuthenticateApp mutation on the global gateway.
94
+ */
95
+ export async function clientCredentialsFlow(globalEndpoint, clientId, clientSecret, scopes) {
96
+ const query = `
97
+ mutation AuthenticateApp($input: AuthenticateAppInput!) {
98
+ authenticateApp(input: $input) {
99
+ accessToken tokenType expiresIn scopes
100
+ }
101
+ }
102
+ `;
103
+ const response = await fetch(globalEndpoint, {
104
+ method: 'POST',
105
+ headers: { 'Content-Type': 'application/json' },
106
+ body: JSON.stringify({
107
+ query,
108
+ variables: { input: { clientId, clientSecret, scopes } },
109
+ }),
110
+ });
111
+ if (!response.ok) {
112
+ const text = await response.text().catch(() => 'Unknown error');
113
+ throw new Error(`App authentication failed (${response.status}): ${text}`);
114
+ }
115
+ const data = (await response.json());
116
+ if (data.errors?.length) {
117
+ throw new Error(`App authentication failed: ${data.errors[0].message}`);
118
+ }
119
+ if (!data.data?.authenticateApp?.accessToken) {
120
+ throw new Error('App authentication failed: no access token returned');
121
+ }
122
+ return data.data.authenticateApp;
123
+ }
124
+ /**
125
+ * Issue a workspace token by calling the workspace gateway with an auth token.
126
+ * Only sends Authorization header (no X-Workspace-Authorization).
127
+ */
128
+ export async function issueWorkspaceToken(workspaceEndpoint, authToken, workspaceId, organizationId) {
129
+ const query = `
130
+ mutation IssueWorkspaceToken($input: IssueWorkspaceTokenInput!) {
131
+ issueWorkspaceToken(input: $input) {
132
+ success token expiresAt scopes
133
+ error { code message }
134
+ }
135
+ }
136
+ `;
137
+ const response = await fetch(workspaceEndpoint, {
138
+ method: 'POST',
139
+ headers: {
140
+ 'Content-Type': 'application/json',
141
+ Authorization: `Bearer ${authToken}`,
142
+ },
143
+ body: JSON.stringify({
144
+ query,
145
+ variables: { input: { workspaceId, organizationId } },
146
+ }),
147
+ });
148
+ if (!response.ok) {
149
+ const text = await response.text().catch(() => 'Unknown error');
150
+ throw new Error(`Workspace token request failed (${response.status}): ${text}`);
151
+ }
152
+ const data = (await response.json());
153
+ if (data.errors?.length) {
154
+ throw new Error(`Workspace token failed: ${data.errors[0].message}`);
155
+ }
156
+ const result = data.data?.issueWorkspaceToken;
157
+ if (!result?.success || !result.token) {
158
+ const errMsg = result?.error?.message ?? 'Unknown error';
159
+ throw new Error(`Workspace token failed: ${errMsg}`);
160
+ }
161
+ return { token: result.token, expiresAt: result.expiresAt, scopes: result.scopes ?? [] };
162
+ }
163
+ /**
164
+ * Fetch user's workspaces from the global gateway.
165
+ */
166
+ export async function fetchWorkspaces(globalEndpoint, authToken) {
167
+ const query = `
168
+ query MyWorkspaces($limit: Int) {
169
+ myWorkspaces(limit: $limit) {
170
+ items { id name slug tenantId organizationId }
171
+ }
172
+ }
173
+ `;
174
+ const response = await fetch(globalEndpoint, {
175
+ method: 'POST',
176
+ headers: {
177
+ 'Content-Type': 'application/json',
178
+ Authorization: `Bearer ${authToken}`,
179
+ },
180
+ body: JSON.stringify({ query, variables: { limit: 50 } }),
181
+ });
182
+ if (!response.ok) {
183
+ const text = await response.text().catch(() => 'Unknown error');
184
+ throw new Error(`Failed to fetch workspaces (${response.status}): ${text}`);
185
+ }
186
+ const data = (await response.json());
187
+ if (data.errors?.length) {
188
+ throw new Error(`Failed to fetch workspaces: ${data.errors[0].message}`);
189
+ }
190
+ return data.data?.myWorkspaces?.items ?? [];
191
+ }
192
+ /**
193
+ * Validate that a string is a well-formed HTTP(S) URL.
194
+ * Prevents command injection by rejecting anything that isn't a valid URL.
195
+ */
196
+ function isValidHttpUrl(urlString) {
197
+ try {
198
+ const parsed = new URL(urlString);
199
+ return parsed.protocol === 'http:' || parsed.protocol === 'https:';
200
+ }
201
+ catch {
202
+ return false;
203
+ }
204
+ }
205
+ /**
206
+ * Attempt to open a URL in the user's default browser.
207
+ * Uses execFile instead of exec to avoid shell interpretation and command injection.
208
+ */
209
+ export async function openBrowser(url) {
210
+ try {
211
+ if (!isValidHttpUrl(url)) {
212
+ return false;
213
+ }
214
+ const { execFile } = await import('child_process');
215
+ const platform = process.platform;
216
+ let command;
217
+ let args;
218
+ if (platform === 'darwin') {
219
+ command = 'open';
220
+ args = [url];
221
+ }
222
+ else if (platform === 'win32') {
223
+ command = 'cmd';
224
+ args = ['/c', 'start', '', url];
225
+ }
226
+ else {
227
+ command = 'xdg-open';
228
+ args = [url];
229
+ }
230
+ return new Promise((resolve) => {
231
+ execFile(command, args, (error) => {
232
+ resolve(!error);
233
+ });
234
+ });
235
+ }
236
+ catch {
237
+ return false;
238
+ }
239
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Auth token persistence.
3
+ * Stores tokens in ~/.config/bigconsole-cli/auth.json with restrictive permissions.
4
+ */
5
+ export interface StoredAuth {
6
+ accessToken: string;
7
+ refreshToken: string;
8
+ expiresAt?: number;
9
+ workspaceToken?: string;
10
+ workspaceTokenExpiresAt?: number;
11
+ workspaceId?: string;
12
+ organizationId?: string;
13
+ authMethod?: 'device_code' | 'client_credentials';
14
+ clientId?: string;
15
+ clientSecret?: string;
16
+ }
17
+ /**
18
+ * Read stored authentication data.
19
+ * Returns null if no auth data exists.
20
+ */
21
+ export declare function readAuth(): StoredAuth | null;
22
+ /**
23
+ * Write authentication data to the store.
24
+ * File permissions are set to 0o600 (owner read/write only).
25
+ */
26
+ export declare function writeAuth(auth: StoredAuth): void;
27
+ /**
28
+ * Clear stored authentication data.
29
+ */
30
+ export declare function clearAuth(): void;
31
+ /**
32
+ * Check if the stored token has expired.
33
+ */
34
+ export declare function isTokenExpired(auth: StoredAuth): boolean;
35
+ /**
36
+ * Check if the stored token is expiring within the next 5 minutes.
37
+ */
38
+ export declare function isTokenExpiringSoon(auth: StoredAuth): boolean;
39
+ /**
40
+ * Check if the workspace token has expired.
41
+ */
42
+ export declare function isWorkspaceTokenExpired(auth: StoredAuth): boolean;
43
+ /**
44
+ * Check if the workspace token is expiring within the next 5 minutes.
45
+ */
46
+ export declare function isWorkspaceTokenExpiringSoon(auth: StoredAuth): boolean;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Auth token persistence.
3
+ * Stores tokens in ~/.config/bigconsole-cli/auth.json with restrictive permissions.
4
+ */
5
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, unlinkSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ const CONFIG_DIR = join(homedir(), '.config', 'bigconsole-cli');
9
+ const AUTH_FILE = join(CONFIG_DIR, 'auth.json');
10
+ function ensureConfigDir() {
11
+ if (!existsSync(CONFIG_DIR)) {
12
+ mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
13
+ }
14
+ }
15
+ /**
16
+ * Read stored authentication data.
17
+ * Returns null if no auth data exists.
18
+ */
19
+ export function readAuth() {
20
+ try {
21
+ if (!existsSync(AUTH_FILE))
22
+ return null;
23
+ const raw = readFileSync(AUTH_FILE, 'utf8');
24
+ return JSON.parse(raw);
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ /**
31
+ * Write authentication data to the store.
32
+ * File permissions are set to 0o600 (owner read/write only).
33
+ */
34
+ export function writeAuth(auth) {
35
+ ensureConfigDir();
36
+ writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), { encoding: 'utf8', mode: 0o600 });
37
+ try {
38
+ chmodSync(AUTH_FILE, 0o600);
39
+ }
40
+ catch {
41
+ // chmod may fail on some platforms (Windows), that's acceptable
42
+ }
43
+ }
44
+ /**
45
+ * Clear stored authentication data.
46
+ */
47
+ export function clearAuth() {
48
+ try {
49
+ if (existsSync(AUTH_FILE)) {
50
+ unlinkSync(AUTH_FILE);
51
+ }
52
+ }
53
+ catch {
54
+ // Ignore errors on cleanup
55
+ }
56
+ }
57
+ /**
58
+ * Check if the stored token has expired.
59
+ */
60
+ export function isTokenExpired(auth) {
61
+ if (!auth.expiresAt)
62
+ return false;
63
+ return Date.now() >= auth.expiresAt;
64
+ }
65
+ /**
66
+ * Check if the stored token is expiring within the next 5 minutes.
67
+ */
68
+ export function isTokenExpiringSoon(auth) {
69
+ if (!auth.expiresAt)
70
+ return false;
71
+ const BUFFER_MS = 5 * 60 * 1000;
72
+ return Date.now() + BUFFER_MS >= auth.expiresAt;
73
+ }
74
+ /**
75
+ * Check if the workspace token has expired.
76
+ */
77
+ export function isWorkspaceTokenExpired(auth) {
78
+ if (!auth.workspaceTokenExpiresAt)
79
+ return false;
80
+ return Date.now() >= auth.workspaceTokenExpiresAt;
81
+ }
82
+ /**
83
+ * Check if the workspace token is expiring within the next 5 minutes.
84
+ */
85
+ export function isWorkspaceTokenExpiringSoon(auth) {
86
+ if (!auth.workspaceTokenExpiresAt)
87
+ return false;
88
+ const BUFFER_MS = 5 * 60 * 1000;
89
+ return Date.now() + BUFFER_MS >= auth.workspaceTokenExpiresAt;
90
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * BigConsole CLI — dashboard, widget, parser, and workflow management from the terminal.
4
+ */
5
+ export {};