@vizzly-testing/cli 0.20.1-beta.1 → 0.21.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/README.md +16 -18
- package/dist/commands/run.js +2 -0
- package/dist/commands/tdd.js +18 -1
- package/dist/reporter/reporter-bundle.css +1 -1
- package/dist/reporter/reporter-bundle.iife.js +204 -22
- package/dist/server/http-server.js +4 -1
- package/dist/server/routers/dashboard.js +21 -36
- package/dist/server/routers/events.js +134 -0
- package/dist/services/auth-service.js +117 -0
- package/dist/services/config-service.js +306 -0
- package/dist/services/project-service.js +136 -0
- package/package.json +2 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Service
|
|
3
|
+
* Wraps project operations for use by the HTTP server
|
|
4
|
+
*
|
|
5
|
+
* Provides the interface expected by src/server/routers/projects.js:
|
|
6
|
+
* - listProjects() - Returns [] if not authenticated
|
|
7
|
+
* - listMappings() - Returns [] if no mappings
|
|
8
|
+
* - getMapping(directory) - Returns null if not found
|
|
9
|
+
* - createMapping(directory, projectData) - Throws on invalid input
|
|
10
|
+
* - removeMapping(directory) - Throws on invalid directory
|
|
11
|
+
* - getRecentBuilds(projectSlug, organizationSlug, options) - Returns [] if not authenticated
|
|
12
|
+
*
|
|
13
|
+
* Error handling:
|
|
14
|
+
* - API methods (listProjects, getRecentBuilds) return empty arrays when not authenticated
|
|
15
|
+
* - Local methods (listMappings, getMapping) never require authentication
|
|
16
|
+
* - Validation errors (createMapping, removeMapping) throw with descriptive messages
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { createAuthClient } from '../auth/client.js';
|
|
20
|
+
import * as projectOps from '../project/operations.js';
|
|
21
|
+
import { getApiUrl } from '../utils/environment-config.js';
|
|
22
|
+
import { deleteProjectMapping, getAuthTokens, getProjectMapping, getProjectMappings, saveProjectMapping } from '../utils/global-config.js';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a project service instance
|
|
26
|
+
* @param {Object} [options]
|
|
27
|
+
* @param {string} [options.apiUrl] - API base URL (defaults to VIZZLY_API_URL or https://app.vizzly.dev)
|
|
28
|
+
* @param {Object} [options.httpClient] - Injectable HTTP client (for testing)
|
|
29
|
+
* @param {Object} [options.mappingStore] - Injectable mapping store (for testing)
|
|
30
|
+
* @param {Function} [options.getAuthTokens] - Injectable token getter (for testing)
|
|
31
|
+
* @returns {Object} Project service
|
|
32
|
+
*/
|
|
33
|
+
export function createProjectService(options = {}) {
|
|
34
|
+
let apiUrl = options.apiUrl || getApiUrl();
|
|
35
|
+
|
|
36
|
+
// Create HTTP client once at service creation (not per-request)
|
|
37
|
+
// Allow injection for testing
|
|
38
|
+
let httpClient = options.httpClient || createAuthClient({
|
|
39
|
+
baseUrl: apiUrl
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Create mapping store adapter for global config
|
|
43
|
+
// Allow injection for testing
|
|
44
|
+
let mappingStore = options.mappingStore || {
|
|
45
|
+
getMappings: getProjectMappings,
|
|
46
|
+
getMapping: getProjectMapping,
|
|
47
|
+
saveMapping: saveProjectMapping,
|
|
48
|
+
deleteMapping: deleteProjectMapping
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Allow injection of getAuthTokens for testing
|
|
52
|
+
let tokenGetter = options.getAuthTokens || getAuthTokens;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create an OAuth client with current access token
|
|
56
|
+
* @returns {Promise<Object|null>} OAuth client or null if not authenticated
|
|
57
|
+
*/
|
|
58
|
+
async function createOAuthClient() {
|
|
59
|
+
let auth = await tokenGetter();
|
|
60
|
+
if (!auth?.accessToken) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Wrap authenticatedRequest to auto-inject the access token
|
|
65
|
+
return {
|
|
66
|
+
authenticatedRequest: (endpoint, fetchOptions = {}) => httpClient.authenticatedRequest(endpoint, auth.accessToken, fetchOptions)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
/**
|
|
71
|
+
* List all projects from API
|
|
72
|
+
* Returns empty array if not authenticated (projectOps handles null oauthClient)
|
|
73
|
+
* @returns {Promise<Array>} Array of projects, empty if not authenticated
|
|
74
|
+
*/
|
|
75
|
+
async listProjects() {
|
|
76
|
+
let oauthClient = await createOAuthClient();
|
|
77
|
+
// projectOps.listProjects handles null oauthClient by returning []
|
|
78
|
+
return projectOps.listProjects({
|
|
79
|
+
oauthClient,
|
|
80
|
+
apiClient: null
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* List all project mappings
|
|
85
|
+
* @returns {Promise<Array>} Array of project mappings
|
|
86
|
+
*/
|
|
87
|
+
async listMappings() {
|
|
88
|
+
return projectOps.listMappings(mappingStore);
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* Get project mapping for a specific directory
|
|
92
|
+
* @param {string} directory - Directory path
|
|
93
|
+
* @returns {Promise<Object|null>} Project mapping or null
|
|
94
|
+
*/
|
|
95
|
+
async getMapping(directory) {
|
|
96
|
+
return projectOps.getMapping(mappingStore, directory);
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Create or update project mapping
|
|
100
|
+
* @param {string} directory - Directory path
|
|
101
|
+
* @param {Object} projectData - Project data
|
|
102
|
+
* @returns {Promise<Object>} Created mapping
|
|
103
|
+
*/
|
|
104
|
+
async createMapping(directory, projectData) {
|
|
105
|
+
return projectOps.createMapping(mappingStore, directory, projectData);
|
|
106
|
+
},
|
|
107
|
+
/**
|
|
108
|
+
* Remove project mapping
|
|
109
|
+
* @param {string} directory - Directory path
|
|
110
|
+
* @returns {Promise<void>}
|
|
111
|
+
*/
|
|
112
|
+
async removeMapping(directory) {
|
|
113
|
+
return projectOps.removeMapping(mappingStore, directory);
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* Get recent builds for a project
|
|
117
|
+
* Returns empty array if not authenticated (projectOps handles null oauthClient)
|
|
118
|
+
* @param {string} projectSlug - Project slug
|
|
119
|
+
* @param {string} organizationSlug - Organization slug
|
|
120
|
+
* @param {Object} options - Query options
|
|
121
|
+
* @returns {Promise<Array>} Array of builds, empty if not authenticated
|
|
122
|
+
*/
|
|
123
|
+
async getRecentBuilds(projectSlug, organizationSlug, options = {}) {
|
|
124
|
+
let oauthClient = await createOAuthClient();
|
|
125
|
+
// projectOps.getRecentBuilds handles null oauthClient by returning []
|
|
126
|
+
return projectOps.getRecentBuilds({
|
|
127
|
+
oauthClient,
|
|
128
|
+
apiClient: null,
|
|
129
|
+
projectSlug,
|
|
130
|
+
organizationSlug,
|
|
131
|
+
limit: options.limit,
|
|
132
|
+
branch: options.branch
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizzly-testing/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Visual review platform for UI developers and designers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visual-testing",
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
"@tanstack/react-query": "^5.90.11",
|
|
120
120
|
"@types/node": "^25.0.2",
|
|
121
121
|
"@vitejs/plugin-react": "^5.0.3",
|
|
122
|
+
"@vizzly-testing/observatory": "^0.2.1",
|
|
122
123
|
"autoprefixer": "^10.4.21",
|
|
123
124
|
"babel-plugin-transform-remove-console": "^6.9.4",
|
|
124
125
|
"postcss": "^8.5.6",
|