@vizzly-testing/cli 0.27.0 → 0.27.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.
@@ -2,17 +2,27 @@
2
2
  * Organizations command - List organizations the user has access to
3
3
  */
4
4
 
5
- import { createApiClient } from '../api/client.js';
6
- import { loadConfig } from '../utils/config-loader.js';
7
- import { getApiUrl } from '../utils/environment-config.js';
8
- import * as output from '../utils/output.js';
5
+ import { createApiClient as defaultCreateApiClient } from '../api/client.js';
6
+ import { loadConfig as defaultLoadConfig } from '../utils/config-loader.js';
7
+ import { getApiUrl as defaultGetApiUrl } from '../utils/environment-config.js';
8
+ import { getAccessToken as defaultGetAccessToken } from '../utils/global-config.js';
9
+ import * as defaultOutput from '../utils/output.js';
9
10
 
10
11
  /**
11
12
  * Organizations command implementation
12
13
  * @param {Object} options - Command options
13
14
  * @param {Object} globalOptions - Global CLI options
15
+ * @param {Object} deps - Dependencies for testing
14
16
  */
15
- export async function orgsCommand(_options = {}, globalOptions = {}) {
17
+ export async function orgsCommand(_options = {}, globalOptions = {}, deps = {}) {
18
+ let {
19
+ loadConfig = defaultLoadConfig,
20
+ createApiClient = defaultCreateApiClient,
21
+ getApiUrl = defaultGetApiUrl,
22
+ getAccessToken = defaultGetAccessToken,
23
+ output = defaultOutput,
24
+ exit = code => process.exit(code)
25
+ } = deps;
16
26
  output.configure({
17
27
  json: globalOptions.json,
18
28
  verbose: globalOptions.verbose,
@@ -20,14 +30,19 @@ export async function orgsCommand(_options = {}, globalOptions = {}) {
20
30
  });
21
31
  try {
22
32
  let config = await loadConfig(globalOptions.config, globalOptions);
23
- if (!config.apiKey) {
33
+
34
+ // Prefer user auth token for listing orgs (project tokens are org-scoped).
35
+ // Falls back to config.apiKey which may be: VIZZLY_TOKEN, --token flag, or project token.
36
+ let token = (await getAccessToken()) || config.apiKey;
37
+ if (!token) {
24
38
  output.error('API token required. Use --token, set VIZZLY_TOKEN, or run "vizzly login"');
25
39
  output.cleanup();
26
- process.exit(1);
40
+ exit(1);
41
+ return;
27
42
  }
28
43
  let client = createApiClient({
29
44
  baseUrl: config.apiUrl || getApiUrl(),
30
- token: config.apiKey
45
+ token
31
46
  });
32
47
  output.startSpinner('Fetching organizations...');
33
48
  let response = await client.request('/api/sdk/organizations');
@@ -65,7 +80,7 @@ export async function orgsCommand(_options = {}, globalOptions = {}) {
65
80
  output.stopSpinner();
66
81
  output.error('Failed to fetch organizations', error);
67
82
  output.cleanup();
68
- process.exit(1);
83
+ exit(1);
69
84
  }
70
85
  }
71
86
 
@@ -2,17 +2,27 @@
2
2
  * Projects command - List projects the user has access to
3
3
  */
4
4
 
5
- import { createApiClient } from '../api/client.js';
6
- import { loadConfig } from '../utils/config-loader.js';
7
- import { getApiUrl } from '../utils/environment-config.js';
8
- import * as output from '../utils/output.js';
5
+ import { createApiClient as defaultCreateApiClient } from '../api/client.js';
6
+ import { loadConfig as defaultLoadConfig } from '../utils/config-loader.js';
7
+ import { getApiUrl as defaultGetApiUrl } from '../utils/environment-config.js';
8
+ import { getAccessToken as defaultGetAccessToken } from '../utils/global-config.js';
9
+ import * as defaultOutput from '../utils/output.js';
9
10
 
10
11
  /**
11
12
  * Projects command implementation
12
13
  * @param {Object} options - Command options
13
14
  * @param {Object} globalOptions - Global CLI options
15
+ * @param {Object} deps - Dependencies for testing
14
16
  */
15
- export async function projectsCommand(options = {}, globalOptions = {}) {
17
+ export async function projectsCommand(options = {}, globalOptions = {}, deps = {}) {
18
+ let {
19
+ loadConfig = defaultLoadConfig,
20
+ createApiClient = defaultCreateApiClient,
21
+ getApiUrl = defaultGetApiUrl,
22
+ getAccessToken = defaultGetAccessToken,
23
+ output = defaultOutput,
24
+ exit = code => process.exit(code)
25
+ } = deps;
16
26
  output.configure({
17
27
  json: globalOptions.json,
18
28
  verbose: globalOptions.verbose,
@@ -20,14 +30,19 @@ export async function projectsCommand(options = {}, globalOptions = {}) {
20
30
  });
21
31
  try {
22
32
  let config = await loadConfig(globalOptions.config, globalOptions);
23
- if (!config.apiKey) {
33
+
34
+ // Prefer user auth token for listing projects (project tokens are org-scoped).
35
+ // Falls back to config.apiKey which may be: VIZZLY_TOKEN, --token flag, or project token.
36
+ let token = (await getAccessToken()) || config.apiKey;
37
+ if (!token) {
24
38
  output.error('API token required. Use --token, set VIZZLY_TOKEN, or run "vizzly login"');
25
39
  output.cleanup();
26
- process.exit(1);
40
+ exit(1);
41
+ return;
27
42
  }
28
43
  let client = createApiClient({
29
44
  baseUrl: config.apiUrl || getApiUrl(),
30
- token: config.apiKey
45
+ token
31
46
  });
32
47
 
33
48
  // Build query params
@@ -82,7 +97,7 @@ export async function projectsCommand(options = {}, globalOptions = {}) {
82
97
  output.stopSpinner();
83
98
  output.error('Failed to fetch projects', error);
84
99
  output.cleanup();
85
- process.exit(1);
100
+ exit(1);
86
101
  }
87
102
  }
88
103
 
@@ -189,11 +189,13 @@ export async function hasValidTokens() {
189
189
  }
190
190
 
191
191
  /**
192
- * Get the access token from global config if available
192
+ * Get the access token from global config if valid and not expired
193
193
  * @returns {Promise<string|null>} Access token or null
194
194
  */
195
195
  export async function getAccessToken() {
196
- const auth = await getAuthTokens();
196
+ let valid = await hasValidTokens();
197
+ if (!valid) return null;
198
+ let auth = await getAuthTokens();
197
199
  return auth?.accessToken || null;
198
200
  }
199
201
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizzly-testing/cli",
3
- "version": "0.27.0",
3
+ "version": "0.27.1",
4
4
  "description": "Visual review platform for UI developers and designers",
5
5
  "keywords": [
6
6
  "visual-testing",