@vizzly-testing/cli 0.14.0 → 0.15.0
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 +68 -68
- package/dist/commands/doctor.js +30 -34
- package/dist/commands/finalize.js +24 -23
- package/dist/commands/init.js +30 -28
- package/dist/commands/login.js +49 -55
- package/dist/commands/logout.js +14 -19
- package/dist/commands/project.js +83 -103
- package/dist/commands/run.js +77 -89
- package/dist/commands/status.js +48 -49
- package/dist/commands/tdd-daemon.js +90 -86
- package/dist/commands/tdd.js +59 -88
- package/dist/commands/upload.js +57 -57
- package/dist/commands/whoami.js +40 -45
- package/dist/index.js +2 -5
- package/dist/plugin-loader.js +15 -17
- package/dist/reporter/reporter-bundle.css +1 -1
- package/dist/reporter/reporter-bundle.iife.js +74 -41
- package/dist/sdk/index.js +36 -45
- package/dist/server/handlers/api-handler.js +14 -15
- package/dist/server/handlers/tdd-handler.js +34 -37
- package/dist/server/http-server.js +75 -869
- package/dist/server/middleware/cors.js +22 -0
- package/dist/server/middleware/json-parser.js +35 -0
- package/dist/server/middleware/response.js +79 -0
- package/dist/server/routers/assets.js +91 -0
- package/dist/server/routers/auth.js +144 -0
- package/dist/server/routers/baseline.js +163 -0
- package/dist/server/routers/cloud-proxy.js +146 -0
- package/dist/server/routers/config.js +126 -0
- package/dist/server/routers/dashboard.js +130 -0
- package/dist/server/routers/health.js +61 -0
- package/dist/server/routers/projects.js +168 -0
- package/dist/server/routers/screenshot.js +86 -0
- package/dist/services/auth-service.js +1 -1
- package/dist/services/build-manager.js +13 -40
- package/dist/services/config-service.js +2 -4
- package/dist/services/html-report-generator.js +6 -5
- package/dist/services/index.js +64 -0
- package/dist/services/project-service.js +121 -40
- package/dist/services/screenshot-server.js +9 -9
- package/dist/services/server-manager.js +11 -18
- package/dist/services/static-report-generator.js +3 -4
- package/dist/services/tdd-service.js +246 -103
- package/dist/services/test-runner.js +24 -25
- package/dist/services/uploader.js +5 -4
- package/dist/types/commands/init.d.ts +1 -2
- package/dist/types/index.d.ts +2 -3
- package/dist/types/plugin-loader.d.ts +1 -2
- package/dist/types/reporter/src/api/client.d.ts +178 -0
- package/dist/types/reporter/src/components/app-router.d.ts +1 -3
- package/dist/types/reporter/src/components/code-block.d.ts +4 -0
- package/dist/types/reporter/src/components/comparison/comparison-modes/onion-skin-mode.d.ts +10 -0
- package/dist/types/reporter/src/components/comparison/comparison-modes/overlay-mode.d.ts +11 -0
- package/dist/types/reporter/src/components/comparison/comparison-modes/shared/base-comparison-mode.d.ts +14 -0
- package/dist/types/reporter/src/components/comparison/comparison-modes/shared/image-renderer.d.ts +30 -0
- package/dist/types/reporter/src/components/comparison/comparison-modes/toggle-view.d.ts +8 -0
- package/dist/types/reporter/src/components/comparison/comparison-viewer.d.ts +4 -0
- package/dist/types/reporter/src/components/comparison/screenshot-display.d.ts +16 -0
- package/dist/types/reporter/src/components/design-system/alert.d.ts +9 -0
- package/dist/types/reporter/src/components/design-system/badge.d.ts +17 -0
- package/dist/types/reporter/src/components/design-system/button.d.ts +19 -0
- package/dist/types/reporter/src/components/design-system/card.d.ts +31 -0
- package/dist/types/reporter/src/components/design-system/empty-state.d.ts +13 -0
- package/dist/types/reporter/src/components/design-system/form-controls.d.ts +44 -0
- package/dist/types/reporter/src/components/design-system/health-ring.d.ts +7 -0
- package/dist/types/reporter/src/components/design-system/index.d.ts +11 -0
- package/dist/types/reporter/src/components/design-system/modal.d.ts +10 -0
- package/dist/types/reporter/src/components/design-system/skeleton.d.ts +19 -0
- package/dist/types/reporter/src/components/design-system/spinner.d.ts +10 -0
- package/dist/types/reporter/src/components/design-system/tabs.d.ts +13 -0
- package/dist/types/reporter/src/components/layout/header.d.ts +5 -0
- package/dist/types/reporter/src/components/layout/index.d.ts +2 -0
- package/dist/types/reporter/src/components/layout/layout.d.ts +6 -0
- package/dist/types/reporter/src/components/views/builds-view.d.ts +1 -0
- package/dist/types/reporter/src/components/views/comparison-detail-view.d.ts +1 -4
- package/dist/types/reporter/src/components/views/comparisons-view.d.ts +1 -6
- package/dist/types/reporter/src/components/views/stats-view.d.ts +1 -6
- package/dist/types/reporter/src/components/waiting-for-screenshots.d.ts +1 -0
- package/dist/types/reporter/src/hooks/queries/use-auth-queries.d.ts +15 -0
- package/dist/types/reporter/src/hooks/queries/use-cloud-queries.d.ts +6 -0
- package/dist/types/reporter/src/hooks/queries/use-config-queries.d.ts +6 -0
- package/dist/types/reporter/src/hooks/queries/use-tdd-queries.d.ts +9 -0
- package/dist/types/reporter/src/lib/query-client.d.ts +2 -0
- package/dist/types/reporter/src/lib/query-keys.d.ts +13 -0
- package/dist/types/sdk/index.d.ts +2 -4
- package/dist/types/server/handlers/tdd-handler.d.ts +2 -0
- package/dist/types/server/http-server.d.ts +1 -1
- package/dist/types/server/middleware/cors.d.ts +11 -0
- package/dist/types/server/middleware/json-parser.d.ts +10 -0
- package/dist/types/server/middleware/response.d.ts +50 -0
- package/dist/types/server/routers/assets.d.ts +6 -0
- package/dist/types/server/routers/auth.d.ts +9 -0
- package/dist/types/server/routers/baseline.d.ts +13 -0
- package/dist/types/server/routers/cloud-proxy.d.ts +11 -0
- package/dist/types/server/routers/config.d.ts +9 -0
- package/dist/types/server/routers/dashboard.d.ts +6 -0
- package/dist/types/server/routers/health.d.ts +11 -0
- package/dist/types/server/routers/projects.d.ts +9 -0
- package/dist/types/server/routers/screenshot.d.ts +11 -0
- package/dist/types/services/build-manager.d.ts +4 -3
- package/dist/types/services/config-service.d.ts +2 -3
- package/dist/types/services/index.d.ts +7 -0
- package/dist/types/services/project-service.d.ts +6 -4
- package/dist/types/services/screenshot-server.d.ts +5 -5
- package/dist/types/services/server-manager.d.ts +5 -3
- package/dist/types/services/tdd-service.d.ts +12 -1
- package/dist/types/services/test-runner.d.ts +3 -3
- package/dist/types/utils/output.d.ts +84 -0
- package/dist/utils/config-loader.js +24 -48
- package/dist/utils/global-config.js +2 -17
- package/dist/utils/output.js +445 -0
- package/dist/utils/security.js +3 -4
- package/docs/api-reference.md +0 -1
- package/docs/plugins.md +22 -22
- package/package.json +3 -2
- package/dist/container/index.js +0 -215
- package/dist/services/base-service.js +0 -154
- package/dist/types/container/index.d.ts +0 -59
- package/dist/types/reporter/src/components/comparison/viewer-modes/onion-viewer.d.ts +0 -3
- package/dist/types/reporter/src/components/comparison/viewer-modes/overlay-viewer.d.ts +0 -3
- package/dist/types/reporter/src/components/comparison/viewer-modes/side-by-side-viewer.d.ts +0 -3
- package/dist/types/reporter/src/components/comparison/viewer-modes/toggle-viewer.d.ts +0 -3
- package/dist/types/reporter/src/components/dashboard/dashboard-header.d.ts +0 -5
- package/dist/types/reporter/src/components/dashboard/dashboard-stats.d.ts +0 -4
- package/dist/types/reporter/src/components/dashboard/empty-state.d.ts +0 -8
- package/dist/types/reporter/src/components/ui/form-field.d.ts +0 -16
- package/dist/types/reporter/src/components/ui/status-badge.d.ts +0 -5
- package/dist/types/reporter/src/hooks/use-auth.d.ts +0 -10
- package/dist/types/reporter/src/hooks/use-baseline-actions.d.ts +0 -5
- package/dist/types/reporter/src/hooks/use-config.d.ts +0 -9
- package/dist/types/reporter/src/hooks/use-projects.d.ts +0 -10
- package/dist/types/reporter/src/hooks/use-report-data.d.ts +0 -7
- package/dist/types/reporter/src/hooks/use-vizzly-api.d.ts +0 -9
- package/dist/types/services/base-service.d.ts +0 -71
- package/dist/types/utils/console-ui.d.ts +0 -61
- package/dist/types/utils/logger-factory.d.ts +0 -26
- package/dist/types/utils/logger.d.ts +0 -79
- package/dist/utils/console-ui.js +0 -241
- package/dist/utils/logger-factory.js +0 -76
- package/dist/utils/logger.js +0 -231
package/dist/commands/init.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { VizzlyError } from '../errors/vizzly-error.js';
|
|
5
|
-
import
|
|
5
|
+
import * as output from '../utils/output.js';
|
|
6
6
|
import { loadPlugins } from '../plugin-loader.js';
|
|
7
7
|
import { loadConfig } from '../utils/config-loader.js';
|
|
8
8
|
import { z } from 'zod';
|
|
@@ -11,20 +11,18 @@ import { z } from 'zod';
|
|
|
11
11
|
* Simple configuration setup for Vizzly CLI
|
|
12
12
|
*/
|
|
13
13
|
export class InitCommand {
|
|
14
|
-
constructor(
|
|
15
|
-
this.logger = logger || createComponentLogger('INIT', {
|
|
16
|
-
level: 'info'
|
|
17
|
-
});
|
|
14
|
+
constructor(plugins = []) {
|
|
18
15
|
this.plugins = plugins;
|
|
19
16
|
}
|
|
20
17
|
async run(options = {}) {
|
|
21
|
-
|
|
18
|
+
output.info('🎯 Initializing Vizzly configuration...');
|
|
19
|
+
output.blank();
|
|
22
20
|
try {
|
|
23
21
|
// Check for existing config
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
let configPath = path.join(process.cwd(), 'vizzly.config.js');
|
|
23
|
+
let hasConfig = await this.fileExists(configPath);
|
|
26
24
|
if (hasConfig && !options.force) {
|
|
27
|
-
|
|
25
|
+
output.info('❌ A vizzly.config.js file already exists. Use --force to overwrite.');
|
|
28
26
|
return;
|
|
29
27
|
}
|
|
30
28
|
|
|
@@ -33,7 +31,8 @@ export class InitCommand {
|
|
|
33
31
|
|
|
34
32
|
// Show next steps
|
|
35
33
|
this.showNextSteps();
|
|
36
|
-
|
|
34
|
+
output.blank();
|
|
35
|
+
output.success('Vizzly CLI setup complete!');
|
|
37
36
|
} catch (error) {
|
|
38
37
|
throw new VizzlyError('Failed to initialize Vizzly configuration', 'INIT_FAILED', {
|
|
39
38
|
error: error.message
|
|
@@ -78,14 +77,14 @@ export class InitCommand {
|
|
|
78
77
|
}
|
|
79
78
|
coreConfig += '\n};\n';
|
|
80
79
|
await fs.writeFile(configPath, coreConfig, 'utf8');
|
|
81
|
-
|
|
80
|
+
output.info(`📄 Created vizzly.config.js`);
|
|
82
81
|
|
|
83
82
|
// Log discovered plugins
|
|
84
83
|
let pluginsWithConfig = this.plugins.filter(p => p.configSchema);
|
|
85
84
|
if (pluginsWithConfig.length > 0) {
|
|
86
|
-
|
|
85
|
+
output.info(` Added config for ${pluginsWithConfig.length} plugin(s):`);
|
|
87
86
|
pluginsWithConfig.forEach(p => {
|
|
88
|
-
|
|
87
|
+
output.info(` - ${p.name}`);
|
|
89
88
|
});
|
|
90
89
|
}
|
|
91
90
|
}
|
|
@@ -127,9 +126,9 @@ export class InitCommand {
|
|
|
127
126
|
} catch (error) {
|
|
128
127
|
if (error instanceof z.ZodError) {
|
|
129
128
|
let messages = error.errors.map(e => `${e.path.join('.')}: ${e.message}`);
|
|
130
|
-
|
|
129
|
+
output.warn(`Invalid config schema for plugin ${plugin.name}: ${messages.join(', ')}`);
|
|
131
130
|
} else {
|
|
132
|
-
|
|
131
|
+
output.warn(`Failed to format config for plugin ${plugin.name}: ${error.message}`);
|
|
133
132
|
}
|
|
134
133
|
return '';
|
|
135
134
|
}
|
|
@@ -168,13 +167,14 @@ export class InitCommand {
|
|
|
168
167
|
return String(value);
|
|
169
168
|
}
|
|
170
169
|
showNextSteps() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
170
|
+
output.blank();
|
|
171
|
+
output.info('📚 Next steps:');
|
|
172
|
+
output.info(' 1. Set your API token:');
|
|
173
|
+
output.info(' export VIZZLY_TOKEN="your-api-key"');
|
|
174
|
+
output.info(' 2. Run your tests with Vizzly:');
|
|
175
|
+
output.info(' npx vizzly run "npm test"');
|
|
176
|
+
output.info(' 3. Upload screenshots:');
|
|
177
|
+
output.info(' npx vizzly upload ./screenshots');
|
|
178
178
|
}
|
|
179
179
|
async fileExists(filePath) {
|
|
180
180
|
try {
|
|
@@ -188,28 +188,30 @@ export class InitCommand {
|
|
|
188
188
|
|
|
189
189
|
// Export factory function for CLI
|
|
190
190
|
export function createInitCommand(options) {
|
|
191
|
-
|
|
191
|
+
let command = new InitCommand(options.plugins);
|
|
192
192
|
return () => command.run(options);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
// Simple export for direct CLI usage
|
|
196
196
|
export async function init(options = {}) {
|
|
197
|
+
output.configure({
|
|
198
|
+
json: options.json || false,
|
|
199
|
+
verbose: options.verbose || false,
|
|
200
|
+
color: options.color !== false
|
|
201
|
+
});
|
|
197
202
|
let plugins = [];
|
|
198
203
|
|
|
199
204
|
// Try to load plugins if not provided
|
|
200
205
|
if (!options.plugins) {
|
|
201
206
|
try {
|
|
202
207
|
let config = await loadConfig(options.config, {});
|
|
203
|
-
|
|
204
|
-
level: 'debug'
|
|
205
|
-
});
|
|
206
|
-
plugins = await loadPlugins(options.config, config, logger);
|
|
208
|
+
plugins = await loadPlugins(options.config, config, null);
|
|
207
209
|
} catch {
|
|
208
210
|
// Silent fail - plugins are optional for init
|
|
209
211
|
}
|
|
210
212
|
} else {
|
|
211
213
|
plugins = options.plugins;
|
|
212
214
|
}
|
|
213
|
-
|
|
215
|
+
let command = new InitCommand(plugins);
|
|
214
216
|
return await command.run(options);
|
|
215
217
|
}
|
package/dist/commands/login.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Authenticates user via OAuth device flow
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import * as output from '../utils/output.js';
|
|
7
7
|
import { AuthService } from '../services/auth-service.js';
|
|
8
8
|
import { getApiUrl } from '../utils/environment-config.js';
|
|
9
9
|
import { openBrowser } from '../utils/browser.js';
|
|
@@ -14,15 +14,15 @@ import { openBrowser } from '../utils/browser.js';
|
|
|
14
14
|
* @param {Object} globalOptions - Global CLI options
|
|
15
15
|
*/
|
|
16
16
|
export async function loginCommand(options = {}, globalOptions = {}) {
|
|
17
|
-
|
|
18
|
-
let ui = new ConsoleUI({
|
|
17
|
+
output.configure({
|
|
19
18
|
json: globalOptions.json,
|
|
20
19
|
verbose: globalOptions.verbose,
|
|
21
20
|
color: !globalOptions.noColor
|
|
22
21
|
});
|
|
22
|
+
let colors = output.getColors();
|
|
23
23
|
try {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
output.info('Starting Vizzly authentication...');
|
|
25
|
+
output.blank();
|
|
26
26
|
|
|
27
27
|
// Create auth service
|
|
28
28
|
let authService = new AuthService({
|
|
@@ -30,9 +30,9 @@ export async function loginCommand(options = {}, globalOptions = {}) {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
// Initiate device flow
|
|
33
|
-
|
|
33
|
+
output.startSpinner('Connecting to Vizzly...');
|
|
34
34
|
let deviceFlow = await authService.initiateDeviceFlow();
|
|
35
|
-
|
|
35
|
+
output.stopSpinner();
|
|
36
36
|
|
|
37
37
|
// Handle both snake_case and camelCase field names
|
|
38
38
|
let verificationUri = deviceFlow.verification_uri || deviceFlow.verificationUri;
|
|
@@ -46,29 +46,29 @@ export async function loginCommand(options = {}, globalOptions = {}) {
|
|
|
46
46
|
let urlWithCode = `${verificationUri}?code=${userCode}`;
|
|
47
47
|
|
|
48
48
|
// Display user code prominently
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
output.blank();
|
|
50
|
+
output.print('='.repeat(50));
|
|
51
|
+
output.blank();
|
|
52
|
+
output.print(' Please visit the following URL to authorize this device:');
|
|
53
|
+
output.blank();
|
|
54
|
+
output.print(` ${urlWithCode}`);
|
|
55
|
+
output.blank();
|
|
56
|
+
output.print(' Your code (pre-filled):');
|
|
57
|
+
output.blank();
|
|
58
|
+
output.print(` ${colors.bold(colors.cyan(userCode))}`);
|
|
59
|
+
output.blank();
|
|
60
|
+
output.print('='.repeat(50));
|
|
61
|
+
output.blank();
|
|
62
62
|
|
|
63
63
|
// Try to open browser with pre-filled code
|
|
64
64
|
let browserOpened = await openBrowser(urlWithCode);
|
|
65
65
|
if (browserOpened) {
|
|
66
|
-
|
|
66
|
+
output.info('Opening browser...');
|
|
67
67
|
} else {
|
|
68
|
-
|
|
68
|
+
output.warn('Could not open browser automatically. Please open the URL manually.');
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
output.blank();
|
|
71
|
+
output.info('After authorizing in your browser, press Enter to continue...');
|
|
72
72
|
|
|
73
73
|
// Wait for user to press Enter
|
|
74
74
|
await new Promise(resolve => {
|
|
@@ -82,9 +82,9 @@ export async function loginCommand(options = {}, globalOptions = {}) {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
// Check authorization status
|
|
85
|
-
|
|
85
|
+
output.startSpinner('Checking authorization status...');
|
|
86
86
|
let pollResponse = await authService.pollDeviceAuthorization(deviceCode);
|
|
87
|
-
|
|
87
|
+
output.stopSpinner();
|
|
88
88
|
let tokenData = null;
|
|
89
89
|
|
|
90
90
|
// Check if authorization was successful by looking for tokens
|
|
@@ -116,66 +116,60 @@ export async function loginCommand(options = {}, globalOptions = {}) {
|
|
|
116
116
|
await authService.completeDeviceFlow(tokens);
|
|
117
117
|
|
|
118
118
|
// Display success message
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
output.success('Successfully authenticated!');
|
|
120
|
+
output.blank();
|
|
121
121
|
|
|
122
122
|
// Show user info
|
|
123
123
|
if (tokens.user) {
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
output.info(`User: ${tokens.user.name || tokens.user.username}`);
|
|
125
|
+
output.info(`Email: ${tokens.user.email}`);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// Show organization info
|
|
129
129
|
if (tokens.organizations && tokens.organizations.length > 0) {
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
output.blank();
|
|
131
|
+
output.info('Organizations:');
|
|
132
132
|
for (let org of tokens.organizations) {
|
|
133
|
-
|
|
133
|
+
output.print(` - ${org.name}${org.slug ? ` (@${org.slug})` : ''}`);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// Show token expiry info
|
|
138
138
|
if (tokens.expiresAt) {
|
|
139
|
-
|
|
139
|
+
output.blank();
|
|
140
140
|
let expiresAt = new Date(tokens.expiresAt);
|
|
141
141
|
let msUntilExpiry = expiresAt.getTime() - Date.now();
|
|
142
142
|
let daysUntilExpiry = Math.floor(msUntilExpiry / (1000 * 60 * 60 * 24));
|
|
143
143
|
let hoursUntilExpiry = Math.floor(msUntilExpiry / (1000 * 60 * 60));
|
|
144
144
|
let minutesUntilExpiry = Math.floor(msUntilExpiry / (1000 * 60));
|
|
145
145
|
if (daysUntilExpiry > 0) {
|
|
146
|
-
|
|
146
|
+
output.info(`Token expires in ${daysUntilExpiry} day${daysUntilExpiry !== 1 ? 's' : ''} (${expiresAt.toLocaleDateString()})`);
|
|
147
147
|
} else if (hoursUntilExpiry > 0) {
|
|
148
|
-
|
|
148
|
+
output.info(`Token expires in ${hoursUntilExpiry} hour${hoursUntilExpiry !== 1 ? 's' : ''}`);
|
|
149
149
|
} else if (minutesUntilExpiry > 0) {
|
|
150
|
-
|
|
150
|
+
output.info(`Token expires in ${minutesUntilExpiry} minute${minutesUntilExpiry !== 1 ? 's' : ''}`);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
output.blank();
|
|
154
|
+
output.info('You can now use Vizzly CLI commands without setting VIZZLY_TOKEN');
|
|
155
|
+
output.cleanup();
|
|
156
156
|
} catch (error) {
|
|
157
|
-
|
|
157
|
+
output.stopSpinner();
|
|
158
158
|
|
|
159
159
|
// Handle authentication errors with helpful messages
|
|
160
160
|
if (error.name === 'AuthError') {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
output.error('Authentication failed', error);
|
|
162
|
+
output.blank();
|
|
163
|
+
output.print('Please try logging in again.');
|
|
164
|
+
output.print("If you don't have an account, sign up at https://vizzly.dev");
|
|
165
165
|
process.exit(1);
|
|
166
166
|
} else if (error.code === 'RATE_LIMIT_ERROR') {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
output.error('Too many login attempts', error);
|
|
168
|
+
output.blank();
|
|
169
|
+
output.print('Please wait a few minutes before trying again.');
|
|
170
170
|
process.exit(1);
|
|
171
171
|
} else {
|
|
172
|
-
|
|
173
|
-
console.log(''); // Empty line for spacing
|
|
174
|
-
console.log('Error details:', error.message);
|
|
175
|
-
if (globalOptions.verbose && error.stack) {
|
|
176
|
-
console.error(''); // Empty line for spacing
|
|
177
|
-
console.error(error.stack);
|
|
178
|
-
}
|
|
172
|
+
output.error('Login failed', error);
|
|
179
173
|
process.exit(1);
|
|
180
174
|
}
|
|
181
175
|
}
|
package/dist/commands/logout.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Clears stored authentication tokens
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import * as output from '../utils/output.js';
|
|
7
7
|
import { AuthService } from '../services/auth-service.js';
|
|
8
8
|
import { getApiUrl } from '../utils/environment-config.js';
|
|
9
9
|
import { getAuthTokens } from '../utils/global-config.js';
|
|
@@ -14,8 +14,7 @@ import { getAuthTokens } from '../utils/global-config.js';
|
|
|
14
14
|
* @param {Object} globalOptions - Global CLI options
|
|
15
15
|
*/
|
|
16
16
|
export async function logoutCommand(options = {}, globalOptions = {}) {
|
|
17
|
-
|
|
18
|
-
let ui = new ConsoleUI({
|
|
17
|
+
output.configure({
|
|
19
18
|
json: globalOptions.json,
|
|
20
19
|
verbose: globalOptions.verbose,
|
|
21
20
|
color: !globalOptions.noColor
|
|
@@ -24,36 +23,32 @@ export async function logoutCommand(options = {}, globalOptions = {}) {
|
|
|
24
23
|
// Check if user is logged in
|
|
25
24
|
let auth = await getAuthTokens();
|
|
26
25
|
if (!auth || !auth.accessToken) {
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
output.info('You are not logged in');
|
|
27
|
+
output.cleanup();
|
|
29
28
|
return;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
// Logout
|
|
33
|
-
|
|
32
|
+
output.startSpinner('Logging out...');
|
|
34
33
|
let authService = new AuthService({
|
|
35
34
|
baseUrl: options.apiUrl || getApiUrl()
|
|
36
35
|
});
|
|
37
36
|
await authService.logout();
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
output.stopSpinner();
|
|
38
|
+
output.success('Successfully logged out');
|
|
40
39
|
if (globalOptions.json) {
|
|
41
|
-
|
|
40
|
+
output.data({
|
|
42
41
|
loggedOut: true
|
|
43
42
|
});
|
|
44
43
|
} else {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
output.blank();
|
|
45
|
+
output.info('Your authentication tokens have been cleared');
|
|
46
|
+
output.info('Run "vizzly login" to authenticate again');
|
|
48
47
|
}
|
|
49
|
-
|
|
48
|
+
output.cleanup();
|
|
50
49
|
} catch (error) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (globalOptions.verbose && error.stack) {
|
|
54
|
-
console.error(''); // Empty line for spacing
|
|
55
|
-
console.error(error.stack);
|
|
56
|
-
}
|
|
50
|
+
output.stopSpinner();
|
|
51
|
+
output.error('Logout failed', error);
|
|
57
52
|
process.exit(1);
|
|
58
53
|
}
|
|
59
54
|
}
|