@vizzly-testing/cli 0.26.1 → 0.27.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 +250 -5
- package/dist/commands/api.js +190 -0
- package/dist/commands/baselines.js +265 -0
- package/dist/commands/builds.js +274 -0
- package/dist/commands/comparisons.js +345 -0
- package/dist/commands/config-cmd.js +184 -0
- package/dist/commands/init.js +54 -12
- package/dist/commands/orgs.js +79 -0
- package/dist/commands/preview.js +13 -3
- package/dist/commands/project.js +69 -15
- package/dist/commands/projects.js +96 -0
- package/dist/commands/review.js +319 -0
- package/dist/commands/run.js +142 -2
- package/dist/commands/tdd-daemon.js +78 -12
- package/dist/commands/tdd.js +61 -2
- package/dist/commands/upload.js +94 -2
- package/dist/server/handlers/tdd-handler.js +23 -2
- package/dist/utils/config-loader.js +13 -1
- package/dist/utils/output.js +107 -4
- package/package.json +2 -1
package/dist/utils/output.js
CHANGED
|
@@ -28,6 +28,8 @@ const VALID_LOG_LEVELS = Object.keys(LOG_LEVELS);
|
|
|
28
28
|
// Module state
|
|
29
29
|
const config = {
|
|
30
30
|
json: false,
|
|
31
|
+
jsonFields: null,
|
|
32
|
+
// null = all fields, array = selected fields
|
|
31
33
|
logLevel: null,
|
|
32
34
|
// null = not yet initialized, will check env var on first configure
|
|
33
35
|
color: undefined,
|
|
@@ -74,12 +76,96 @@ function normalizeLogLevel(level) {
|
|
|
74
76
|
return VALID_LOG_LEVELS.includes(normalized) ? normalized : 'info';
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Parse --json flag value into field list
|
|
81
|
+
* Supports: true (all fields), "field1,field2" (selected fields)
|
|
82
|
+
* @param {boolean|string} jsonArg - The --json flag value
|
|
83
|
+
* @returns {string[]|null} Array of field names, or null for all fields
|
|
84
|
+
*/
|
|
85
|
+
export function parseJsonFields(jsonArg) {
|
|
86
|
+
if (jsonArg === true || jsonArg === 'true') return null; // All fields
|
|
87
|
+
if (typeof jsonArg === 'string' && jsonArg.length > 0) {
|
|
88
|
+
return jsonArg.split(',').map(f => f.trim()).filter(f => f.length > 0);
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get a nested value from an object using dot notation
|
|
95
|
+
* @param {Object} obj - Source object
|
|
96
|
+
* @param {string} path - Dot-separated path (e.g., "comparisons.total")
|
|
97
|
+
* @returns {*} The value at the path, or undefined if not found
|
|
98
|
+
*/
|
|
99
|
+
function getNestedValue(obj, path) {
|
|
100
|
+
let parts = path.split('.');
|
|
101
|
+
let current = obj;
|
|
102
|
+
for (let part of parts) {
|
|
103
|
+
if (current === null || current === undefined) return undefined;
|
|
104
|
+
current = current[part];
|
|
105
|
+
}
|
|
106
|
+
return current;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Set a nested value in an object using dot notation
|
|
111
|
+
* Creates intermediate objects as needed
|
|
112
|
+
* @param {Object} obj - Target object
|
|
113
|
+
* @param {string} path - Dot-separated path (e.g., "comparisons.total")
|
|
114
|
+
* @param {*} value - Value to set
|
|
115
|
+
*/
|
|
116
|
+
function setNestedValue(obj, path, value) {
|
|
117
|
+
let parts = path.split('.');
|
|
118
|
+
let current = obj;
|
|
119
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
120
|
+
let part = parts[i];
|
|
121
|
+
if (!(part in current)) {
|
|
122
|
+
current[part] = {};
|
|
123
|
+
}
|
|
124
|
+
current = current[part];
|
|
125
|
+
}
|
|
126
|
+
current[parts[parts.length - 1]] = value;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Select specific fields from an object
|
|
131
|
+
* Supports dot notation for nested fields (e.g., "comparisons.total")
|
|
132
|
+
* Warns in debug mode when requested fields aren't found
|
|
133
|
+
* @param {Object|Array} obj - Source object or array
|
|
134
|
+
* @param {string[]} fields - Fields to select
|
|
135
|
+
* @returns {Object|Array} Object with only selected fields
|
|
136
|
+
*/
|
|
137
|
+
function selectFields(obj, fields) {
|
|
138
|
+
if (Array.isArray(obj)) {
|
|
139
|
+
return obj.map(item => selectFields(item, fields));
|
|
140
|
+
}
|
|
141
|
+
if (obj === null || typeof obj !== 'object') {
|
|
142
|
+
return obj;
|
|
143
|
+
}
|
|
144
|
+
let result = {};
|
|
145
|
+
let missingFields = [];
|
|
146
|
+
for (let field of fields) {
|
|
147
|
+
let value = getNestedValue(obj, field);
|
|
148
|
+
if (value !== undefined) {
|
|
149
|
+
setNestedValue(result, field, value);
|
|
150
|
+
} else {
|
|
151
|
+
missingFields.push(field);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Warn about missing fields in verbose mode
|
|
156
|
+
if (missingFields.length > 0 && shouldLog('debug')) {
|
|
157
|
+
console.error(colors.dim(`Note: Requested field(s) not found: ${missingFields.join(', ')}`));
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
|
|
77
162
|
/**
|
|
78
163
|
* Configure output settings
|
|
79
164
|
* Call this once at CLI startup with global options
|
|
80
165
|
*
|
|
81
166
|
* @param {Object} options - Configuration options
|
|
82
|
-
* @param {boolean} [options.json] - Enable JSON output mode
|
|
167
|
+
* @param {boolean|string} [options.json] - Enable JSON output mode, optionally with field selection
|
|
168
|
+
* @param {string[]} [options.jsonFields] - Fields to include in JSON output (null = all)
|
|
83
169
|
* @param {string} [options.logLevel] - Log level (debug, info, warn, error)
|
|
84
170
|
* @param {boolean} [options.verbose] - Shorthand for logLevel='debug' (backwards compatible)
|
|
85
171
|
* @param {boolean} [options.color] - Enable colored output
|
|
@@ -88,7 +174,12 @@ function normalizeLogLevel(level) {
|
|
|
88
174
|
* @param {boolean} [options.resetTimer] - Reset the start timer (default: true)
|
|
89
175
|
*/
|
|
90
176
|
export function configure(options = {}) {
|
|
91
|
-
|
|
177
|
+
// Handle --json flag: can be boolean or string of fields
|
|
178
|
+
if (options.json !== undefined) {
|
|
179
|
+
config.json = !!options.json; // Truthy check for JSON mode
|
|
180
|
+
config.jsonFields = parseJsonFields(options.json);
|
|
181
|
+
}
|
|
182
|
+
if (options.jsonFields !== undefined) config.jsonFields = options.jsonFields;
|
|
92
183
|
if (options.color !== undefined) config.color = options.color;
|
|
93
184
|
if (options.silent !== undefined) config.silent = options.silent;
|
|
94
185
|
if (options.logFile !== undefined) config.logFile = options.logFile;
|
|
@@ -336,18 +427,29 @@ export function printErr(text) {
|
|
|
336
427
|
|
|
337
428
|
/**
|
|
338
429
|
* Output structured data
|
|
430
|
+
* When field selection is active, only specified fields are included
|
|
431
|
+
* @param {Object|Array} obj - Data to output
|
|
339
432
|
*/
|
|
340
433
|
export function data(obj) {
|
|
434
|
+
let output = config.jsonFields ? selectFields(obj, config.jsonFields) : obj;
|
|
341
435
|
if (config.json) {
|
|
342
436
|
console.log(JSON.stringify({
|
|
343
437
|
status: 'data',
|
|
344
|
-
data:
|
|
438
|
+
data: output
|
|
345
439
|
}));
|
|
346
440
|
} else {
|
|
347
|
-
console.log(JSON.stringify(
|
|
441
|
+
console.log(JSON.stringify(output, null, 2));
|
|
348
442
|
}
|
|
349
443
|
}
|
|
350
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Get configured JSON fields (for commands that need direct access)
|
|
447
|
+
* @returns {string[]|null} Array of field names, or null for all fields
|
|
448
|
+
*/
|
|
449
|
+
export function getJsonFields() {
|
|
450
|
+
return config.jsonFields;
|
|
451
|
+
}
|
|
452
|
+
|
|
351
453
|
// ============================================================================
|
|
352
454
|
// Spinner / Progress (stderr so it doesn't pollute piped output)
|
|
353
455
|
// ============================================================================
|
|
@@ -982,6 +1084,7 @@ export function cleanup() {
|
|
|
982
1084
|
export function reset() {
|
|
983
1085
|
stopSpinner();
|
|
984
1086
|
config.json = false;
|
|
1087
|
+
config.jsonFields = null;
|
|
985
1088
|
config.logLevel = null;
|
|
986
1089
|
config.color = undefined; // Reset to auto-detect
|
|
987
1090
|
config.silent = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizzly-testing/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Visual review platform for UI developers and designers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visual-testing",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"LICENSE"
|
|
57
57
|
],
|
|
58
58
|
"scripts": {
|
|
59
|
+
"cli": "source .envrc && node bin/vizzly.js",
|
|
59
60
|
"start": "node src/index.js",
|
|
60
61
|
"build": "npm run clean && npm run compile && npm run build:reporter && npm run build:reporter-ssr && npm run copy-types",
|
|
61
62
|
"clean": "rimraf dist",
|