@contentstack/cli-utilities 1.17.4 → 2.0.0-beta
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/lib/auth-handler.js +1 -0
- package/lib/constants/logging.d.ts +1 -0
- package/lib/constants/logging.js +4 -3
- package/lib/fs-utility/core.js +1 -2
- package/lib/helpers.d.ts +1 -0
- package/lib/helpers.js +11 -3
- package/lib/index.d.ts +2 -2
- package/lib/index.js +9 -3
- package/lib/interfaces/index.d.ts +50 -1
- package/lib/logger/cli-error-handler.js +1 -2
- package/lib/logger/log.js +1 -1
- package/lib/logger/logger.js +37 -17
- package/lib/progress-summary/cli-progress-manager.d.ts +125 -0
- package/lib/progress-summary/cli-progress-manager.js +544 -0
- package/lib/progress-summary/index.d.ts +4 -0
- package/lib/progress-summary/index.js +13 -0
- package/lib/progress-summary/progress-strategy.d.ts +25 -0
- package/lib/progress-summary/progress-strategy.js +54 -0
- package/lib/progress-summary/summary-manager.d.ts +28 -0
- package/lib/progress-summary/summary-manager.js +188 -0
- package/package.json +1 -1
- package/lib/flag-deprecation-check.d.ts +0 -7
- package/lib/flag-deprecation-check.js +0 -40
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
|
+
class SummaryManager {
|
|
6
|
+
constructor({ operationName, context }) {
|
|
7
|
+
this.modules = new Map();
|
|
8
|
+
this.operationName = operationName;
|
|
9
|
+
this.context = context;
|
|
10
|
+
this.operationStartTime = Date.now();
|
|
11
|
+
this.branchName = (context === null || context === void 0 ? void 0 : context.branchName) || '';
|
|
12
|
+
}
|
|
13
|
+
getModules() {
|
|
14
|
+
return this.modules;
|
|
15
|
+
}
|
|
16
|
+
registerModule(moduleName, totalItems = 0) {
|
|
17
|
+
this.modules.set(moduleName, {
|
|
18
|
+
name: moduleName,
|
|
19
|
+
status: 'pending',
|
|
20
|
+
totalItems,
|
|
21
|
+
successCount: 0,
|
|
22
|
+
failureCount: 0,
|
|
23
|
+
failures: [],
|
|
24
|
+
processes: [],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
startModule(moduleName) {
|
|
28
|
+
const module = this.modules.get(moduleName);
|
|
29
|
+
if (module) {
|
|
30
|
+
module.status = 'running';
|
|
31
|
+
module.startTime = Date.now();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
completeModule(moduleName, success = true, error) {
|
|
35
|
+
const module = this.modules.get(moduleName);
|
|
36
|
+
if (module) {
|
|
37
|
+
module.status = success ? 'completed' : 'failed';
|
|
38
|
+
module.endTime = Date.now();
|
|
39
|
+
if (!success && error) {
|
|
40
|
+
module.failures.push({ item: 'module', error });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Register process data for strategy calculations
|
|
46
|
+
*/
|
|
47
|
+
registerProcessData(moduleName, processName, processData) {
|
|
48
|
+
const module = this.modules.get(moduleName);
|
|
49
|
+
if (module) {
|
|
50
|
+
if (!module.processes) {
|
|
51
|
+
module.processes = [];
|
|
52
|
+
}
|
|
53
|
+
const existingIndex = module.processes.findIndex((p) => p.processName === processName);
|
|
54
|
+
if (existingIndex >= 0) {
|
|
55
|
+
module.processes[existingIndex] = Object.assign({ processName }, processData);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
module.processes.push(Object.assign({ processName }, processData));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
updateModuleProgress(moduleName, success, itemName, error) {
|
|
63
|
+
const module = this.modules.get(moduleName);
|
|
64
|
+
if (module) {
|
|
65
|
+
if (success) {
|
|
66
|
+
module.successCount++;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
module.failureCount++;
|
|
70
|
+
if (error) {
|
|
71
|
+
module.failures.push({ item: itemName, error });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
printFinalSummary() {
|
|
77
|
+
const operationEndTime = Date.now();
|
|
78
|
+
const totalDuration = operationEndTime - this.operationStartTime;
|
|
79
|
+
// Overall Statistics
|
|
80
|
+
const totalModules = this.modules.size;
|
|
81
|
+
const completedModules = Array.from(this.modules.values()).filter((m) => m.status === 'completed').length;
|
|
82
|
+
const failedModules = Array.from(this.modules.values()).filter((m) => m.status === 'failed').length;
|
|
83
|
+
const totalItems = Array.from(this.modules.values()).reduce((sum, m) => sum + m.successCount + m.failureCount, 0);
|
|
84
|
+
const totalSuccess = Array.from(this.modules.values()).reduce((sum, m) => sum + m.successCount, 0);
|
|
85
|
+
const totalFailures = Array.from(this.modules.values()).reduce((sum, m) => sum + m.failureCount, 0);
|
|
86
|
+
console.log('\n' + chalk_1.default.bold('='.repeat(80)));
|
|
87
|
+
console.log(chalk_1.default.bold(`${this.operationName} SUMMARY`));
|
|
88
|
+
console.log('\n' + chalk_1.default.bold('Overall Statistics:'));
|
|
89
|
+
console.log(` Total ${this.operationName} Time: ${chalk_1.default.cyan(this.formatDuration(totalDuration))}`);
|
|
90
|
+
console.log(` Modules Processed: ${chalk_1.default.cyan(completedModules)}/${chalk_1.default.cyan(totalModules)}`);
|
|
91
|
+
console.log(` Items Processed: ${chalk_1.default.green(totalSuccess)} success, ${chalk_1.default.red(totalFailures)} failed of ${chalk_1.default.cyan(totalItems)} total`);
|
|
92
|
+
console.log(` Success Rate: ${chalk_1.default.cyan(this.calculateSuccessRate(totalSuccess, totalItems))}%`);
|
|
93
|
+
// Module Details
|
|
94
|
+
console.log('\n' + chalk_1.default.bold('Module Details:'));
|
|
95
|
+
console.log(chalk_1.default.gray('-'.repeat(80)));
|
|
96
|
+
Array.from(this.modules.values()).forEach((module) => {
|
|
97
|
+
const status = this.getStatusIcon(module.status);
|
|
98
|
+
const totalCount = module.successCount + module.failureCount;
|
|
99
|
+
const duration = module.endTime && module.startTime ? this.formatDuration(module.endTime - module.startTime) : 'N/A';
|
|
100
|
+
const successRate = this.calculateSuccessRate(module.successCount, totalCount);
|
|
101
|
+
console.log(`${status} ${module.name.padEnd(20)} | ` +
|
|
102
|
+
`${String(module.successCount).padStart(4)}/${String(totalCount).padStart(4)} items | ` +
|
|
103
|
+
`${this.formatSuccessRate(successRate).padStart(6)} | ` +
|
|
104
|
+
`${duration.padStart(8)}`);
|
|
105
|
+
});
|
|
106
|
+
// Final Status
|
|
107
|
+
console.log('\n' + chalk_1.default.bold('Final Status:'));
|
|
108
|
+
if (!this.hasFailures() && failedModules === 0) {
|
|
109
|
+
console.log(chalk_1.default.bold.green(`✅ ${this.operationName} completed successfully!`));
|
|
110
|
+
}
|
|
111
|
+
else if (this.hasFailures() || failedModules > 0) {
|
|
112
|
+
console.log(chalk_1.default.bold.yellow(`⚠️ ${this.operationName} completed with failures, see the logs for more details.`));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.log(chalk_1.default.bold.red(`❌ ${this.operationName} failed`));
|
|
116
|
+
}
|
|
117
|
+
console.log(chalk_1.default.bold('='.repeat(80)));
|
|
118
|
+
console.log(chalk_1.default.bold('='.repeat(80)));
|
|
119
|
+
// Simple failure summary with log reference
|
|
120
|
+
this.printFailureSummaryWithLogReference();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Check if there are any failures across all modules
|
|
124
|
+
*/
|
|
125
|
+
hasFailures() {
|
|
126
|
+
return Array.from(this.modules.values()).some((m) => m.failures.length > 0 || m.failureCount > 0);
|
|
127
|
+
}
|
|
128
|
+
printFailureSummaryWithLogReference() {
|
|
129
|
+
const modulesWithFailures = Array.from(this.modules.values()).filter((m) => m.failures.length > 0);
|
|
130
|
+
if (modulesWithFailures.length === 0)
|
|
131
|
+
return;
|
|
132
|
+
const totalFailures = modulesWithFailures.reduce((sum, m) => sum + m.failures.length, 0);
|
|
133
|
+
console.log('\n' + chalk_1.default.bold.red('Failure Summary:'));
|
|
134
|
+
console.log(chalk_1.default.red('-'.repeat(50)));
|
|
135
|
+
modulesWithFailures.forEach((module) => {
|
|
136
|
+
console.log(`${chalk_1.default.bold.red('✗')} ${chalk_1.default.bold(module.name)}: ${chalk_1.default.red(module.failures.length)} failures`);
|
|
137
|
+
// Show just first 2-3 failures briefly
|
|
138
|
+
const preview = module.failures.slice(0, 2);
|
|
139
|
+
preview.forEach((failure) => {
|
|
140
|
+
console.log(` • ${chalk_1.default.gray(failure.item)}`);
|
|
141
|
+
});
|
|
142
|
+
if (module.failures.length > 2) {
|
|
143
|
+
console.log(` ${chalk_1.default.gray(`... and ${module.failures.length - 2} more`)}`);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
console.log(chalk_1.default.blue('\n📋 For detailed error information, check the log files:'));
|
|
147
|
+
//console.log(chalk.blue(` ${getSessionLogPath()}`));
|
|
148
|
+
console.log(chalk_1.default.gray(' Recent errors are logged with full context and stack traces.'));
|
|
149
|
+
}
|
|
150
|
+
getStatusIcon(status) {
|
|
151
|
+
switch (status) {
|
|
152
|
+
case 'completed':
|
|
153
|
+
return chalk_1.default.green('✓');
|
|
154
|
+
case 'failed':
|
|
155
|
+
return chalk_1.default.red('✗');
|
|
156
|
+
case 'running':
|
|
157
|
+
return chalk_1.default.yellow('●');
|
|
158
|
+
case 'pending':
|
|
159
|
+
return chalk_1.default.gray('○');
|
|
160
|
+
default:
|
|
161
|
+
return chalk_1.default.gray('?');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
formatDuration(ms) {
|
|
165
|
+
if (ms < 1000)
|
|
166
|
+
return `${ms}ms`;
|
|
167
|
+
if (ms < 60000)
|
|
168
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
169
|
+
return `${(ms / 60000).toFixed(1)}m`;
|
|
170
|
+
}
|
|
171
|
+
calculateSuccessRate(success, total) {
|
|
172
|
+
if (total === 0)
|
|
173
|
+
return '0';
|
|
174
|
+
return ((success / total) * 100).toFixed(1);
|
|
175
|
+
}
|
|
176
|
+
formatSuccessRate(rate) {
|
|
177
|
+
if (rate === '100.0') {
|
|
178
|
+
return '100%';
|
|
179
|
+
}
|
|
180
|
+
else if (parseFloat(rate) >= 10) {
|
|
181
|
+
return `${rate}%`;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
return ` ${rate}%`;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.default = SummaryManager;
|
package/package.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* checks the deprecation and prints it
|
|
3
|
-
* @param {Array} deprecatedFlags flags to be deprecated
|
|
4
|
-
* @param {String} customMessage [optional] a custom message
|
|
5
|
-
* @returns flag parser
|
|
6
|
-
*/
|
|
7
|
-
export default function (deprecatedFlags?: any[], suggestions?: any[], customMessage?: string): (input: any, command: any) => any;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const cli_ux_1 = tslib_1.__importDefault(require("./cli-ux"));
|
|
5
|
-
/**
|
|
6
|
-
* checks the deprecation and prints it
|
|
7
|
-
* @param {Array} deprecatedFlags flags to be deprecated
|
|
8
|
-
* @param {String} customMessage [optional] a custom message
|
|
9
|
-
* @returns flag parser
|
|
10
|
-
*/
|
|
11
|
-
function default_1(deprecatedFlags = [], suggestions = [], customMessage) {
|
|
12
|
-
return (input, command) => {
|
|
13
|
-
const { context: { flagWarningPrintState = {} } = {} } = command;
|
|
14
|
-
let isCommandHasDeprecationFlag = false;
|
|
15
|
-
deprecatedFlags.forEach((item) => {
|
|
16
|
-
if (command.argv.indexOf(item) !== -1) {
|
|
17
|
-
if (flagWarningPrintState[command.id + item]) {
|
|
18
|
-
return input;
|
|
19
|
-
}
|
|
20
|
-
flagWarningPrintState[command.id + item] = true;
|
|
21
|
-
isCommandHasDeprecationFlag = true;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
if (isCommandHasDeprecationFlag) {
|
|
25
|
-
let deprecationMessage = '';
|
|
26
|
-
if (customMessage) {
|
|
27
|
-
deprecationMessage = customMessage;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
deprecationMessage = `WARNING!!! You're using the old (soon to be deprecated) Contentstack CLI flags (${deprecatedFlags.join(', ')}).`;
|
|
31
|
-
if (suggestions.length > 0) {
|
|
32
|
-
deprecationMessage += ` We recommend you to use the updated flags (${suggestions.join(', ')}).`;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
cli_ux_1.default.print(deprecationMessage, { color: 'yellow' });
|
|
36
|
-
}
|
|
37
|
-
return input;
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
exports.default = default_1;
|