@vizzly-testing/cli 0.20.0 → 0.20.1-beta.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/dist/api/client.js +134 -0
- package/dist/api/core.js +341 -0
- package/dist/api/endpoints.js +314 -0
- package/dist/api/index.js +19 -0
- package/dist/auth/client.js +91 -0
- package/dist/auth/core.js +176 -0
- package/dist/auth/index.js +30 -0
- package/dist/auth/operations.js +148 -0
- package/dist/cli.js +178 -3
- package/dist/client/index.js +144 -77
- package/dist/commands/doctor.js +121 -36
- package/dist/commands/finalize.js +49 -18
- package/dist/commands/init.js +13 -18
- package/dist/commands/login.js +49 -55
- package/dist/commands/logout.js +17 -9
- package/dist/commands/project.js +100 -71
- package/dist/commands/run.js +189 -95
- package/dist/commands/status.js +101 -66
- package/dist/commands/tdd-daemon.js +61 -32
- package/dist/commands/tdd.js +104 -98
- package/dist/commands/upload.js +78 -34
- package/dist/commands/whoami.js +44 -42
- package/dist/config/core.js +438 -0
- package/dist/config/index.js +13 -0
- package/dist/config/operations.js +327 -0
- package/dist/index.js +1 -1
- package/dist/project/core.js +295 -0
- package/dist/project/index.js +13 -0
- package/dist/project/operations.js +393 -0
- package/dist/reporter/reporter-bundle.css +1 -1
- package/dist/reporter/reporter-bundle.iife.js +16 -16
- package/dist/screenshot-server/core.js +157 -0
- package/dist/screenshot-server/index.js +11 -0
- package/dist/screenshot-server/operations.js +183 -0
- package/dist/sdk/index.js +3 -2
- package/dist/server/handlers/api-handler.js +14 -5
- package/dist/server/handlers/tdd-handler.js +191 -53
- package/dist/server/http-server.js +9 -3
- package/dist/server/routers/baseline.js +58 -0
- package/dist/server/routers/dashboard.js +10 -6
- package/dist/server/routers/screenshot.js +32 -0
- package/dist/server-manager/core.js +186 -0
- package/dist/server-manager/index.js +81 -0
- package/dist/server-manager/operations.js +209 -0
- package/dist/services/build-manager.js +2 -69
- package/dist/services/index.js +21 -48
- package/dist/services/screenshot-server.js +40 -74
- package/dist/services/server-manager.js +45 -80
- package/dist/services/test-runner.js +90 -250
- package/dist/services/uploader.js +56 -358
- package/dist/tdd/core/hotspot-coverage.js +112 -0
- package/dist/tdd/core/signature.js +101 -0
- package/dist/tdd/index.js +19 -0
- package/dist/tdd/metadata/baseline-metadata.js +103 -0
- package/dist/tdd/metadata/hotspot-metadata.js +93 -0
- package/dist/tdd/services/baseline-downloader.js +151 -0
- package/dist/tdd/services/baseline-manager.js +166 -0
- package/dist/tdd/services/comparison-service.js +230 -0
- package/dist/tdd/services/hotspot-service.js +71 -0
- package/dist/tdd/services/result-service.js +123 -0
- package/dist/tdd/tdd-service.js +1145 -0
- package/dist/test-runner/core.js +255 -0
- package/dist/test-runner/index.js +13 -0
- package/dist/test-runner/operations.js +483 -0
- package/dist/types/client.d.ts +25 -2
- package/dist/uploader/core.js +396 -0
- package/dist/uploader/index.js +11 -0
- package/dist/uploader/operations.js +412 -0
- package/dist/utils/colors.js +187 -39
- package/dist/utils/config-loader.js +3 -6
- package/dist/utils/context.js +228 -0
- package/dist/utils/output.js +449 -14
- package/docs/api-reference.md +173 -8
- package/docs/tui-elements.md +560 -0
- package/package.json +13 -13
- package/dist/services/api-service.js +0 -412
- package/dist/services/auth-service.js +0 -226
- package/dist/services/config-service.js +0 -369
- package/dist/services/html-report-generator.js +0 -455
- package/dist/services/project-service.js +0 -326
- package/dist/services/report-generator/report.css +0 -411
- package/dist/services/report-generator/viewer.js +0 -102
- package/dist/services/static-report-generator.js +0 -207
- package/dist/services/tdd-service.js +0 -1437
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Server Core - Pure functions for screenshot server logic
|
|
3
|
+
*
|
|
4
|
+
* No I/O, no side effects - just data transformations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Request Validation
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validate screenshot request body
|
|
13
|
+
* @param {Object} body - Request body
|
|
14
|
+
* @returns {{ valid: boolean, error: string|null }}
|
|
15
|
+
*/
|
|
16
|
+
export function validateScreenshotRequest(body) {
|
|
17
|
+
if (!body?.name || !body?.image) {
|
|
18
|
+
return {
|
|
19
|
+
valid: false,
|
|
20
|
+
error: 'name and image are required'
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
valid: true,
|
|
25
|
+
error: null
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if request is for the screenshot endpoint
|
|
31
|
+
* @param {string} method - HTTP method
|
|
32
|
+
* @param {string} url - Request URL
|
|
33
|
+
* @returns {boolean}
|
|
34
|
+
*/
|
|
35
|
+
export function isScreenshotEndpoint(method, url) {
|
|
36
|
+
return method === 'POST' && url === '/screenshot';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Build ID Handling
|
|
41
|
+
// ============================================================================
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get effective build ID (falls back to 'default')
|
|
45
|
+
* @param {string|null|undefined} buildId - Build ID from request
|
|
46
|
+
* @returns {string}
|
|
47
|
+
*/
|
|
48
|
+
export function getEffectiveBuildId(buildId) {
|
|
49
|
+
return buildId || 'default';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Response Building
|
|
54
|
+
// ============================================================================
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Build success response object
|
|
58
|
+
* @returns {{ status: number, body: Object }}
|
|
59
|
+
*/
|
|
60
|
+
export function buildSuccessResponse() {
|
|
61
|
+
return {
|
|
62
|
+
status: 200,
|
|
63
|
+
body: {
|
|
64
|
+
success: true
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Build error response object
|
|
71
|
+
* @param {number} status - HTTP status code
|
|
72
|
+
* @param {string} message - Error message
|
|
73
|
+
* @returns {{ status: number, body: Object }}
|
|
74
|
+
*/
|
|
75
|
+
export function buildErrorResponse(status, message) {
|
|
76
|
+
return {
|
|
77
|
+
status,
|
|
78
|
+
body: {
|
|
79
|
+
error: message
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Build not found response
|
|
86
|
+
* @returns {{ status: number, body: Object }}
|
|
87
|
+
*/
|
|
88
|
+
export function buildNotFoundResponse() {
|
|
89
|
+
return buildErrorResponse(404, 'Not found');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build bad request response
|
|
94
|
+
* @param {string} message - Error message
|
|
95
|
+
* @returns {{ status: number, body: Object }}
|
|
96
|
+
*/
|
|
97
|
+
export function buildBadRequestResponse(message) {
|
|
98
|
+
return buildErrorResponse(400, message);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Build internal error response
|
|
103
|
+
* @returns {{ status: number, body: Object }}
|
|
104
|
+
*/
|
|
105
|
+
export function buildInternalErrorResponse() {
|
|
106
|
+
return buildErrorResponse(500, 'Internal server error');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Server Configuration
|
|
111
|
+
// ============================================================================
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Build server listen options
|
|
115
|
+
* @param {Object} config - Server configuration
|
|
116
|
+
* @returns {{ port: number, host: string }}
|
|
117
|
+
*/
|
|
118
|
+
export function buildServerListenOptions(config) {
|
|
119
|
+
return {
|
|
120
|
+
port: config?.server?.port || 3000,
|
|
121
|
+
host: '127.0.0.1'
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Build server started message
|
|
127
|
+
* @param {number} port - Server port
|
|
128
|
+
* @returns {string}
|
|
129
|
+
*/
|
|
130
|
+
export function buildServerStartedMessage(port) {
|
|
131
|
+
return `Screenshot server listening on http://127.0.0.1:${port}`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Build server stopped message
|
|
136
|
+
* @returns {string}
|
|
137
|
+
*/
|
|
138
|
+
export function buildServerStoppedMessage() {
|
|
139
|
+
return 'Screenshot server stopped';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ============================================================================
|
|
143
|
+
// Screenshot Data Extraction
|
|
144
|
+
// ============================================================================
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Extract screenshot data from request body
|
|
148
|
+
* @param {Object} body - Request body
|
|
149
|
+
* @returns {{ name: string, image: string, properties?: Object }}
|
|
150
|
+
*/
|
|
151
|
+
export function extractScreenshotData(body) {
|
|
152
|
+
return {
|
|
153
|
+
name: body.name,
|
|
154
|
+
image: body.image,
|
|
155
|
+
properties: body.properties
|
|
156
|
+
};
|
|
157
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Server Module
|
|
3
|
+
*
|
|
4
|
+
* Exports pure functions (core) and I/O operations for screenshot server functionality.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Core - pure functions
|
|
8
|
+
export { buildBadRequestResponse, buildErrorResponse, buildInternalErrorResponse, buildNotFoundResponse, buildServerListenOptions, buildServerStartedMessage, buildServerStoppedMessage, buildSuccessResponse, extractScreenshotData, getEffectiveBuildId, isScreenshotEndpoint, validateScreenshotRequest } from './core.js';
|
|
9
|
+
|
|
10
|
+
// Operations - I/O with dependency injection
|
|
11
|
+
export { handleRequest, parseRequestBody, startServer, stopServer } from './operations.js';
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Server Operations - I/O operations with dependency injection
|
|
3
|
+
*
|
|
4
|
+
* Each operation takes its dependencies as parameters for testability.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { buildBadRequestResponse, buildInternalErrorResponse, buildNotFoundResponse, buildServerListenOptions, buildServerStartedMessage, buildServerStoppedMessage, buildSuccessResponse, extractScreenshotData, getEffectiveBuildId, isScreenshotEndpoint, validateScreenshotRequest } from './core.js';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Request Body Parsing
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse request body as JSON
|
|
15
|
+
* @param {Object} options - Options
|
|
16
|
+
* @param {Object} options.req - HTTP request
|
|
17
|
+
* @param {Object} options.deps - Dependencies
|
|
18
|
+
* @param {Function} options.deps.createError - Error factory
|
|
19
|
+
* @returns {Promise<Object>} Parsed body
|
|
20
|
+
*/
|
|
21
|
+
export function parseRequestBody({
|
|
22
|
+
req,
|
|
23
|
+
deps
|
|
24
|
+
}) {
|
|
25
|
+
let {
|
|
26
|
+
createError
|
|
27
|
+
} = deps;
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
let body = '';
|
|
30
|
+
req.on('data', chunk => {
|
|
31
|
+
body += chunk.toString();
|
|
32
|
+
});
|
|
33
|
+
req.on('end', () => {
|
|
34
|
+
try {
|
|
35
|
+
resolve(JSON.parse(body));
|
|
36
|
+
} catch {
|
|
37
|
+
reject(createError('Invalid JSON in request body', 'INVALID_JSON'));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
req.on('error', error => {
|
|
41
|
+
reject(createError(`Request error: ${error.message}`, 'REQUEST_ERROR'));
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Request Handling
|
|
48
|
+
// ============================================================================
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handle incoming HTTP request
|
|
52
|
+
* @param {Object} options - Options
|
|
53
|
+
* @param {Object} options.req - HTTP request
|
|
54
|
+
* @param {Object} options.res - HTTP response
|
|
55
|
+
* @param {Object} options.deps - Dependencies
|
|
56
|
+
* @param {Object} options.deps.buildManager - Build manager for screenshot storage
|
|
57
|
+
* @param {Function} options.deps.createError - Error factory
|
|
58
|
+
* @param {Object} options.deps.output - Output utilities
|
|
59
|
+
*/
|
|
60
|
+
export async function handleRequest({
|
|
61
|
+
req,
|
|
62
|
+
res,
|
|
63
|
+
deps
|
|
64
|
+
}) {
|
|
65
|
+
let {
|
|
66
|
+
buildManager,
|
|
67
|
+
createError,
|
|
68
|
+
output
|
|
69
|
+
} = deps;
|
|
70
|
+
|
|
71
|
+
// Check if this is a screenshot endpoint
|
|
72
|
+
if (!isScreenshotEndpoint(req.method, req.url)) {
|
|
73
|
+
let response = buildNotFoundResponse();
|
|
74
|
+
sendResponse(res, response);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
// Parse request body
|
|
79
|
+
let body = await parseRequestBody({
|
|
80
|
+
req,
|
|
81
|
+
deps: {
|
|
82
|
+
createError
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Validate required fields
|
|
87
|
+
let validation = validateScreenshotRequest(body);
|
|
88
|
+
if (!validation.valid) {
|
|
89
|
+
let response = buildBadRequestResponse(validation.error);
|
|
90
|
+
sendResponse(res, response);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Process screenshot
|
|
95
|
+
let effectiveBuildId = getEffectiveBuildId(body.buildId);
|
|
96
|
+
let screenshotData = extractScreenshotData(body);
|
|
97
|
+
await buildManager.addScreenshot(effectiveBuildId, screenshotData);
|
|
98
|
+
let response = buildSuccessResponse();
|
|
99
|
+
sendResponse(res, response);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
output.error('Failed to process screenshot:', error);
|
|
102
|
+
let response = buildInternalErrorResponse();
|
|
103
|
+
sendResponse(res, response);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Send response to client
|
|
109
|
+
* @param {Object} res - HTTP response
|
|
110
|
+
* @param {{ status: number, body: Object }} response - Response data
|
|
111
|
+
*/
|
|
112
|
+
function sendResponse(res, response) {
|
|
113
|
+
res.statusCode = response.status;
|
|
114
|
+
res.end(JSON.stringify(response.body));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// Server Lifecycle
|
|
119
|
+
// ============================================================================
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Start the HTTP server
|
|
123
|
+
* @param {Object} options - Options
|
|
124
|
+
* @param {Object} options.config - Server configuration
|
|
125
|
+
* @param {Function} options.requestHandler - Request handler function
|
|
126
|
+
* @param {Object} options.deps - Dependencies
|
|
127
|
+
* @param {Function} options.deps.createHttpServer - HTTP server factory (http.createServer)
|
|
128
|
+
* @param {Function} options.deps.createError - Error factory
|
|
129
|
+
* @param {Object} options.deps.output - Output utilities
|
|
130
|
+
* @returns {Promise<Object>} HTTP server instance
|
|
131
|
+
*/
|
|
132
|
+
export function startServer({
|
|
133
|
+
config,
|
|
134
|
+
requestHandler,
|
|
135
|
+
deps
|
|
136
|
+
}) {
|
|
137
|
+
let {
|
|
138
|
+
createHttpServer,
|
|
139
|
+
createError,
|
|
140
|
+
output
|
|
141
|
+
} = deps;
|
|
142
|
+
return new Promise((resolve, reject) => {
|
|
143
|
+
let server = createHttpServer(requestHandler);
|
|
144
|
+
let {
|
|
145
|
+
port,
|
|
146
|
+
host
|
|
147
|
+
} = buildServerListenOptions(config);
|
|
148
|
+
server.listen(port, host, error => {
|
|
149
|
+
if (error) {
|
|
150
|
+
reject(createError(`Failed to start screenshot server: ${error.message}`, 'SERVER_ERROR'));
|
|
151
|
+
} else {
|
|
152
|
+
output.info(buildServerStartedMessage(port));
|
|
153
|
+
resolve(server);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Stop the HTTP server
|
|
161
|
+
* @param {Object} options - Options
|
|
162
|
+
* @param {Object|null} options.server - HTTP server instance
|
|
163
|
+
* @param {Object} options.deps - Dependencies
|
|
164
|
+
* @param {Object} options.deps.output - Output utilities
|
|
165
|
+
* @returns {Promise<void>}
|
|
166
|
+
*/
|
|
167
|
+
export function stopServer({
|
|
168
|
+
server,
|
|
169
|
+
deps
|
|
170
|
+
}) {
|
|
171
|
+
let {
|
|
172
|
+
output
|
|
173
|
+
} = deps;
|
|
174
|
+
if (!server) {
|
|
175
|
+
return Promise.resolve();
|
|
176
|
+
}
|
|
177
|
+
return new Promise(resolve => {
|
|
178
|
+
server.close(() => {
|
|
179
|
+
output.info(buildServerStoppedMessage());
|
|
180
|
+
resolve();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
package/dist/sdk/index.js
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
import { EventEmitter } from 'node:events';
|
|
14
14
|
import { VizzlyError } from '../errors/vizzly-error.js';
|
|
15
15
|
import { ScreenshotServer } from '../services/screenshot-server.js';
|
|
16
|
-
import { createTDDService } from '../services/tdd-service.js';
|
|
17
16
|
import { createUploader } from '../services/uploader.js';
|
|
17
|
+
import { createTDDService } from '../tdd/tdd-service.js';
|
|
18
18
|
import { loadConfig } from '../utils/config-loader.js';
|
|
19
19
|
import { resolveImageBuffer } from '../utils/file-helpers.js';
|
|
20
20
|
import * as output from '../utils/output.js';
|
|
@@ -357,9 +357,10 @@ export class VizzlySDK extends EventEmitter {
|
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
|
-
|
|
360
|
+
|
|
361
361
|
// Export service creators for advanced usage
|
|
362
362
|
export { createUploader } from '../services/uploader.js';
|
|
363
|
+
export { createTDDService } from '../tdd/tdd-service.js';
|
|
363
364
|
// Re-export key utilities and errors
|
|
364
365
|
export { loadConfig } from '../utils/config-loader.js';
|
|
365
366
|
export * as output from '../utils/output.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
+
import { uploadScreenshot as defaultUploadScreenshot } from '../../api/index.js';
|
|
4
5
|
import { detectImageInputType } from '../../utils/image-input-detector.js';
|
|
5
6
|
import * as output from '../../utils/output.js';
|
|
6
7
|
|
|
@@ -34,7 +35,15 @@ import * as output from '../../utils/output.js';
|
|
|
34
35
|
* └─────────────────────────────────────────────────────────────┘
|
|
35
36
|
*/
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Create an API handler for screenshot uploads.
|
|
40
|
+
* @param {Object} client - API client with request method
|
|
41
|
+
* @param {Object} options - Optional dependencies for testing
|
|
42
|
+
* @param {Function} options.uploadScreenshot - Upload function (defaults to API uploadScreenshot)
|
|
43
|
+
*/
|
|
44
|
+
export const createApiHandler = (client, {
|
|
45
|
+
uploadScreenshot = defaultUploadScreenshot
|
|
46
|
+
} = {}) => {
|
|
38
47
|
let vizzlyDisabled = false;
|
|
39
48
|
let screenshotCount = 0;
|
|
40
49
|
let uploadPromises = [];
|
|
@@ -52,13 +61,13 @@ export const createApiHandler = apiService => {
|
|
|
52
61
|
};
|
|
53
62
|
}
|
|
54
63
|
|
|
55
|
-
// buildId is optional - API
|
|
64
|
+
// buildId is optional - API will handle it appropriately
|
|
56
65
|
|
|
57
|
-
if (!
|
|
66
|
+
if (!client) {
|
|
58
67
|
return {
|
|
59
68
|
statusCode: 500,
|
|
60
69
|
body: {
|
|
61
|
-
error: 'API
|
|
70
|
+
error: 'API client not available'
|
|
62
71
|
}
|
|
63
72
|
};
|
|
64
73
|
}
|
|
@@ -114,7 +123,7 @@ export const createApiHandler = apiService => {
|
|
|
114
123
|
screenshotCount++;
|
|
115
124
|
|
|
116
125
|
// Fire upload in background - DON'T AWAIT!
|
|
117
|
-
|
|
126
|
+
let uploadPromise = uploadScreenshot(client, buildId, name, imageBuffer, properties ?? {}).then(result => {
|
|
118
127
|
if (!result.skipped) {
|
|
119
128
|
output.debug('upload', name);
|
|
120
129
|
}
|