@contentstack/cli-utilities 1.17.4 → 2.0.0-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.
@@ -0,0 +1,550 @@
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
+ const ora_1 = tslib_1.__importDefault(require("ora"));
6
+ const cli_progress_1 = tslib_1.__importDefault(require("cli-progress"));
7
+ const summary_manager_1 = tslib_1.__importDefault(require("./summary-manager"));
8
+ const __1 = require("..");
9
+ const progress_strategy_1 = require("./progress-strategy");
10
+ class CLIProgressManager {
11
+ constructor({ showConsoleLogs = false, total = 0, moduleName = 'Module', enableNestedProgress = false, } = {}) {
12
+ this.showConsoleLogs = showConsoleLogs;
13
+ this.total = total;
14
+ this.moduleName = moduleName;
15
+ this.enableNestedProgress = enableNestedProgress;
16
+ this.successCount = 0;
17
+ this.failureCount = 0;
18
+ this.failures = [];
19
+ this.spinner = null;
20
+ this.progressBar = null;
21
+ this.processes = new Map();
22
+ this.multiBar = null;
23
+ this.currentProcess = null;
24
+ this.callbacks = {};
25
+ this.branchName = '';
26
+ this.initializeProgress();
27
+ this.setupGlobalSummaryIntegration();
28
+ }
29
+ /**
30
+ * Initialize global summary manager for the entire operation
31
+ */
32
+ static initializeGlobalSummary(operationName, branchName, headerTitle) {
33
+ var _a;
34
+ CLIProgressManager.globalSummary = new summary_manager_1.default({ operationName, context: { branchName } });
35
+ // Only show header if console logs are disabled (progress UI mode)
36
+ if (!((_a = __1.configHandler.get('log')) === null || _a === void 0 ? void 0 : _a.showConsoleLogs)) {
37
+ CLIProgressManager.displayOperationHeader(branchName, headerTitle);
38
+ }
39
+ return CLIProgressManager.globalSummary;
40
+ }
41
+ /**
42
+ * Display operation header with branch information
43
+ */
44
+ static displayOperationHeader(branchName, headerTitle) {
45
+ if (!headerTitle)
46
+ return;
47
+ const safeBranchName = branchName || 'main';
48
+ const branchInfo = headerTitle || `${safeBranchName === null || safeBranchName === void 0 ? void 0 : safeBranchName.toUpperCase()} CONTENT`;
49
+ console.log('\n' + chalk_1.default.bold('='.repeat(80)));
50
+ if (branchInfo) {
51
+ console.log(chalk_1.default.bold.white(` ${branchInfo}`));
52
+ }
53
+ console.log(chalk_1.default.bold('='.repeat(80)) + '\n');
54
+ }
55
+ /**
56
+ * Print the final summary for all modules using strategies.
57
+ * When showConsoleLogs is enabled, skip the Progress Manager summary block
58
+ * so output is pure timestamped log lines (per documentation).
59
+ */
60
+ static printGlobalSummary() {
61
+ if (!CLIProgressManager.globalSummary) {
62
+ return;
63
+ }
64
+ // Apply strategy-based corrections before printing
65
+ CLIProgressManager.applyStrategyCorrections();
66
+ // Print the final summary
67
+ CLIProgressManager.globalSummary.printFinalSummary();
68
+ }
69
+ /**
70
+ * Check if there are any failures in the global summary
71
+ */
72
+ static hasFailures() {
73
+ if (!CLIProgressManager.globalSummary) {
74
+ return false;
75
+ }
76
+ return CLIProgressManager.globalSummary.hasFailures();
77
+ }
78
+ /**
79
+ * Apply strategy-based corrections to module data
80
+ */
81
+ static applyStrategyCorrections() {
82
+ if (!CLIProgressManager.globalSummary)
83
+ return;
84
+ const modules = Array.from(CLIProgressManager.globalSummary.getModules().values());
85
+ modules.forEach((module) => {
86
+ // Check if this module has a registered strategy
87
+ if (progress_strategy_1.ProgressStrategyRegistry.has(module.name)) {
88
+ const strategy = progress_strategy_1.ProgressStrategyRegistry.get(module.name);
89
+ // Create a processes map from module data if available
90
+ const processesMap = new Map();
91
+ // If module has process data, populate the map
92
+ if (module.processes && Array.isArray(module.processes)) {
93
+ module.processes.forEach((processData) => {
94
+ if (processData.processName) {
95
+ processesMap.set(processData.processName, processData);
96
+ }
97
+ });
98
+ }
99
+ // Calculate corrected progress using strategy
100
+ const correctedResult = strategy.calculate(processesMap);
101
+ if (correctedResult) {
102
+ // Update module with corrected counts
103
+ module.totalItems = correctedResult.total;
104
+ module.successCount = correctedResult.success;
105
+ module.failureCount = correctedResult.failures;
106
+ }
107
+ }
108
+ });
109
+ }
110
+ /**
111
+ * Clear global summary (for cleanup)
112
+ */
113
+ static clearGlobalSummary() {
114
+ CLIProgressManager.globalSummary = null;
115
+ }
116
+ /**
117
+ * Create a simple progress manager (no nested processes)
118
+ */
119
+ static createSimple(moduleName, total, showConsoleLogs = false) {
120
+ return new CLIProgressManager({
121
+ moduleName: moduleName.toUpperCase(),
122
+ total: total || 0,
123
+ showConsoleLogs,
124
+ enableNestedProgress: false,
125
+ });
126
+ }
127
+ /**
128
+ * Create a nested progress manager (with sub-processes)
129
+ */
130
+ static createNested(moduleName, showConsoleLogs = false) {
131
+ return new CLIProgressManager({
132
+ moduleName: moduleName.toUpperCase(),
133
+ total: 0,
134
+ showConsoleLogs,
135
+ enableNestedProgress: true,
136
+ });
137
+ }
138
+ /**
139
+ * Show a loading spinner before initializing progress
140
+ */
141
+ static async withLoadingSpinner(message, asyncOperation) {
142
+ const spinner = (0, ora_1.default)(message).start();
143
+ try {
144
+ const result = await asyncOperation();
145
+ spinner.stop();
146
+ return result;
147
+ }
148
+ catch (error) {
149
+ spinner.stop();
150
+ throw error;
151
+ }
152
+ }
153
+ setupGlobalSummaryIntegration() {
154
+ var _a, _b;
155
+ // Auto-register with global summary if it exists
156
+ if (CLIProgressManager.globalSummary) {
157
+ this.setCallbacks({
158
+ onModuleStart: (name) => {
159
+ var _a, _b;
160
+ (_a = CLIProgressManager.globalSummary) === null || _a === void 0 ? void 0 : _a.registerModule(name, this.total);
161
+ (_b = CLIProgressManager.globalSummary) === null || _b === void 0 ? void 0 : _b.startModule(name);
162
+ },
163
+ onModuleComplete: (name, success, error) => {
164
+ var _a;
165
+ // Register process data with summary manager before completing
166
+ this.registerProcessDataWithSummary(name);
167
+ (_a = CLIProgressManager.globalSummary) === null || _a === void 0 ? void 0 : _a.completeModule(name, success, error);
168
+ },
169
+ onProgress: (name, success, itemName, error) => {
170
+ var _a;
171
+ (_a = CLIProgressManager.globalSummary) === null || _a === void 0 ? void 0 : _a.updateModuleProgress(name, success, itemName, error);
172
+ },
173
+ });
174
+ // Trigger module start
175
+ (_b = (_a = this.callbacks).onModuleStart) === null || _b === void 0 ? void 0 : _b.call(_a, this.moduleName);
176
+ }
177
+ }
178
+ /**
179
+ * Register process data with summary manager for strategy calculations
180
+ */
181
+ registerProcessDataWithSummary(moduleName) {
182
+ if (!CLIProgressManager.globalSummary)
183
+ return;
184
+ // Register each process with the summary manager
185
+ this.processes.forEach((processData, processName) => {
186
+ var _a;
187
+ (_a = CLIProgressManager.globalSummary) === null || _a === void 0 ? void 0 : _a.registerProcessData(moduleName, processName, {
188
+ processName,
189
+ total: processData.total,
190
+ current: processData.current,
191
+ successCount: processData.successCount,
192
+ failureCount: processData.failureCount,
193
+ status: processData.status,
194
+ failures: processData.failures,
195
+ });
196
+ });
197
+ }
198
+ /**
199
+ * Set callbacks for external integration
200
+ */
201
+ setCallbacks(callbacks) {
202
+ this.callbacks = Object.assign(Object.assign({}, this.callbacks), callbacks);
203
+ }
204
+ /**
205
+ * Convert module name from UPPERCASE to PascalCase
206
+ */
207
+ formatModuleName(name) {
208
+ return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
209
+ }
210
+ /**
211
+ * Format process name with smart truncation (modules should use short names)
212
+ */
213
+ formatProcessName(processName) {
214
+ const cleaned = processName.trim();
215
+ if (cleaned.length <= 20) {
216
+ return cleaned;
217
+ }
218
+ return cleaned.length <= 20 ? cleaned : cleaned.substring(0, 20) + '...';
219
+ }
220
+ /**
221
+ * Format percentage for consistent alignment (always 3 characters)
222
+ */
223
+ formatPercentage(percentage) {
224
+ if (percentage === 100) {
225
+ return '100';
226
+ }
227
+ else if (percentage >= 10) {
228
+ return ` ${percentage}`;
229
+ }
230
+ else {
231
+ return ` ${percentage}`;
232
+ }
233
+ }
234
+ initializeProgress() {
235
+ if (this.showConsoleLogs) {
236
+ return;
237
+ }
238
+ if (this.enableNestedProgress) {
239
+ // Initialize multi-bar for nested progress tracking
240
+ this.multiBar = new cli_progress_1.default.MultiBar({
241
+ clearOnComplete: false,
242
+ hideCursor: true,
243
+ format: ' {label} |' + chalk_1.default.cyan('{bar}') + '| {percentage}% | {value}/{total} | {status}',
244
+ barCompleteChar: '\u2588',
245
+ barIncompleteChar: '\u2591',
246
+ }, cli_progress_1.default.Presets.shades_classic);
247
+ if (!this.showConsoleLogs) {
248
+ console.log(chalk_1.default.bold.cyan(`\n${this.moduleName}:`));
249
+ }
250
+ }
251
+ else if (this.total > 0) {
252
+ if (!this.showConsoleLogs) {
253
+ console.log(chalk_1.default.bold.cyan(`\n${this.moduleName}:`));
254
+ }
255
+ this.progressBar = new cli_progress_1.default.SingleBar({
256
+ format: ' {label} |' + chalk_1.default.cyan('{bar}') + '| {percentage}% | {value}/{total} | {status}',
257
+ barCompleteChar: '\u2588',
258
+ barIncompleteChar: '\u2591',
259
+ hideCursor: true,
260
+ });
261
+ const formattedName = this.formatModuleName(this.moduleName);
262
+ const displayName = formattedName.length > 20 ? formattedName.substring(0, 17) + '...' : formattedName;
263
+ this.progressBar.start(this.total, 0, {
264
+ label: chalk_1.default.gray(` └─ ${displayName}`.padEnd(25)),
265
+ status: chalk_1.default.gray('Starting...'),
266
+ percentage: ' 0',
267
+ });
268
+ }
269
+ else {
270
+ this.spinner = (0, ora_1.default)(`${chalk_1.default.bold(this.moduleName)}: Processing...`).start();
271
+ }
272
+ }
273
+ /**
274
+ * Add a new process to track (for nested progress)
275
+ */
276
+ addProcess(processName, total) {
277
+ if (!this.enableNestedProgress)
278
+ return this;
279
+ const process = {
280
+ name: processName,
281
+ total,
282
+ current: 0,
283
+ status: 'pending',
284
+ successCount: 0,
285
+ failureCount: 0,
286
+ failures: [],
287
+ };
288
+ if (!this.showConsoleLogs && this.multiBar) {
289
+ const displayName = this.formatProcessName(processName);
290
+ const indentedLabel = ` ├─ ${displayName}`.padEnd(25);
291
+ process.progressBar = this.multiBar.create(total, 0, {
292
+ label: chalk_1.default.gray(indentedLabel),
293
+ status: chalk_1.default.gray('Pending'),
294
+ percentage: ' 0',
295
+ });
296
+ }
297
+ this.processes.set(processName, process);
298
+ return this;
299
+ }
300
+ /**
301
+ * Update the total for a specific process (for dynamic totals after API calls)
302
+ */
303
+ updateProcessTotal(processName, newTotal) {
304
+ if (!this.enableNestedProgress)
305
+ return this;
306
+ const process = this.processes.get(processName);
307
+ if (process) {
308
+ process.total = newTotal;
309
+ if (process.progressBar && !this.showConsoleLogs) {
310
+ // Update the progress bar with the new total
311
+ process.progressBar.setTotal(newTotal);
312
+ }
313
+ }
314
+ return this;
315
+ }
316
+ /**
317
+ * Start a specific process
318
+ */
319
+ startProcess(processName) {
320
+ if (!this.enableNestedProgress)
321
+ return this;
322
+ const process = this.processes.get(processName);
323
+ if (process) {
324
+ process.status = 'active';
325
+ if (!this.showConsoleLogs && process.progressBar) {
326
+ const displayName = this.formatProcessName(processName);
327
+ const indentedLabel = ` ├─ ${displayName}`.padEnd(25);
328
+ process.progressBar.update(0, {
329
+ label: chalk_1.default.yellow(indentedLabel),
330
+ status: chalk_1.default.yellow('Processing'),
331
+ percentage: ' 0',
332
+ });
333
+ }
334
+ this.currentProcess = processName;
335
+ }
336
+ return this;
337
+ }
338
+ /**
339
+ * Complete a specific process
340
+ */
341
+ completeProcess(processName, success = true) {
342
+ if (!this.enableNestedProgress)
343
+ return this;
344
+ const process = this.processes.get(processName);
345
+ if (process) {
346
+ process.status = success ? 'completed' : 'failed';
347
+ // If process completed without ticks, update current to reflect completion
348
+ if (process.current === 0 && process.total > 0) {
349
+ process.current = process.total;
350
+ if (process.status === 'completed') {
351
+ process.successCount = process.total;
352
+ }
353
+ }
354
+ if (!this.showConsoleLogs && process.progressBar) {
355
+ const totalProcessed = process.current;
356
+ const percentage = Math.round((totalProcessed / process.total) * 100);
357
+ const formattedPercentage = this.formatPercentage(percentage);
358
+ const statusText = success
359
+ ? chalk_1.default.green(`✓ Complete (${process.successCount}/${process.current})`)
360
+ : chalk_1.default.red(`✗ Failed (${process.successCount}/${process.current})`);
361
+ const displayName = this.formatProcessName(processName);
362
+ const indentedLabel = ` ├─ ${displayName}`.padEnd(25);
363
+ process.progressBar.update(process.total, {
364
+ label: success ? chalk_1.default.green(indentedLabel) : chalk_1.default.red(indentedLabel),
365
+ status: statusText,
366
+ percentage: formattedPercentage,
367
+ });
368
+ }
369
+ }
370
+ return this;
371
+ }
372
+ /**
373
+ * Update status message
374
+ */
375
+ updateStatus(message, processName) {
376
+ if (!this.showConsoleLogs) {
377
+ if (this.enableNestedProgress && processName) {
378
+ const process = this.processes.get(processName);
379
+ if (process && process.progressBar) {
380
+ const percentage = Math.round((process.current / process.total) * 100);
381
+ const formattedPercentage = this.formatPercentage(percentage);
382
+ const displayName = this.formatProcessName(processName);
383
+ const indentedLabel = ` ├─ ${displayName}`.padEnd(25);
384
+ process.progressBar.update(process.current, {
385
+ label: chalk_1.default.yellow(indentedLabel),
386
+ status: chalk_1.default.yellow(message),
387
+ percentage: formattedPercentage,
388
+ });
389
+ }
390
+ }
391
+ else if (this.progressBar) {
392
+ const percentage = Math.round(this.progressBar.getProgress() * 100);
393
+ const formattedPercentage = this.formatPercentage(percentage);
394
+ const formattedName = this.formatModuleName(this.moduleName);
395
+ const displayName = formattedName.length > 20 ? formattedName.substring(0, 17) + '...' : formattedName;
396
+ this.progressBar.update(this.progressBar.getProgress() * this.total, {
397
+ label: chalk_1.default.yellow(` └─ ${displayName}`.padEnd(25)),
398
+ status: chalk_1.default.yellow(message),
399
+ percentage: formattedPercentage,
400
+ });
401
+ }
402
+ else if (this.spinner) {
403
+ this.spinner.text = `${chalk_1.default.bold(this.moduleName)}: ${message}`;
404
+ }
405
+ }
406
+ return this;
407
+ }
408
+ /**
409
+ * Update progress
410
+ */
411
+ tick(success = true, itemName = '', errorMessage = null, processName) {
412
+ var _a, _b;
413
+ const targetProcess = processName || this.currentProcess;
414
+ if (success) {
415
+ this.successCount++;
416
+ }
417
+ else {
418
+ this.failureCount++;
419
+ this.failures.push({
420
+ item: itemName,
421
+ error: errorMessage,
422
+ process: targetProcess || undefined,
423
+ });
424
+ }
425
+ // Trigger callback
426
+ (_b = (_a = this.callbacks).onProgress) === null || _b === void 0 ? void 0 : _b.call(_a, this.moduleName, success, itemName, errorMessage || undefined);
427
+ // Update nested progress if enabled and console logs are disabled
428
+ if (this.enableNestedProgress && targetProcess) {
429
+ const process = this.processes.get(targetProcess);
430
+ if (process) {
431
+ process.current++;
432
+ if (success) {
433
+ process.successCount++;
434
+ }
435
+ else {
436
+ process.failureCount++;
437
+ process.failures.push({ item: itemName, error: errorMessage });
438
+ }
439
+ // Only update progress bar if console logs are disabled
440
+ if (!this.showConsoleLogs && process.progressBar) {
441
+ const percentage = Math.round((process.current / process.total) * 100);
442
+ const formattedPercentage = this.formatPercentage(percentage);
443
+ const statusText = `${process.successCount}✓ ${process.failureCount}✗`;
444
+ const displayName = this.formatProcessName(targetProcess);
445
+ const indentedLabel = ` ├─ ${displayName}`.padEnd(25);
446
+ process.progressBar.increment(1, {
447
+ label: chalk_1.default.cyan(indentedLabel),
448
+ status: chalk_1.default.cyan(statusText),
449
+ percentage: formattedPercentage,
450
+ });
451
+ }
452
+ }
453
+ }
454
+ else {
455
+ // Update single progress bar or spinner only if console logs are disabled
456
+ if (!this.showConsoleLogs) {
457
+ if (this.progressBar) {
458
+ const percentage = Math.round(((this.successCount + this.failureCount) / this.total) * 100);
459
+ const formattedPercentage = this.formatPercentage(percentage);
460
+ const totalProcessed = this.successCount + this.failureCount;
461
+ // Show completion status when finished, otherwise show running count
462
+ const statusText = totalProcessed >= this.total
463
+ ? this.failureCount === 0
464
+ ? chalk_1.default.green(`✓ Complete (${this.successCount}/${totalProcessed})`)
465
+ : chalk_1.default.yellow(`✓ Complete (${this.successCount}/${totalProcessed})`)
466
+ : chalk_1.default.cyan(`${this.successCount}✓ ${this.failureCount}✗`);
467
+ const labelColor = totalProcessed >= this.total ? (this.failureCount === 0 ? chalk_1.default.green : chalk_1.default.yellow) : chalk_1.default.cyan;
468
+ const formattedName = this.formatModuleName(this.moduleName);
469
+ const displayName = formattedName.length > 20 ? formattedName.substring(0, 17) + '...' : formattedName;
470
+ this.progressBar.increment(1, {
471
+ label: labelColor(` └─ ${displayName}`.padEnd(25)),
472
+ status: statusText,
473
+ percentage: formattedPercentage,
474
+ });
475
+ }
476
+ else if (this.spinner) {
477
+ const total = this.successCount + this.failureCount;
478
+ this.spinner.text = `${chalk_1.default.bold(this.moduleName)}: ${total} items (${this.successCount}✓ ${this.failureCount}✗)`;
479
+ }
480
+ }
481
+ }
482
+ return this;
483
+ }
484
+ /**
485
+ * Complete the entire module
486
+ */
487
+ complete(success = true, error) {
488
+ var _a, _b;
489
+ this.stop();
490
+ (_b = (_a = this.callbacks).onModuleComplete) === null || _b === void 0 ? void 0 : _b.call(_a, this.moduleName, success, error);
491
+ return this;
492
+ }
493
+ /**
494
+ * Log message (respects showConsoleLogs mode)
495
+ */
496
+ log(msg) {
497
+ if (this.showConsoleLogs) {
498
+ console.log(msg);
499
+ }
500
+ }
501
+ /**
502
+ * Stop all progress indicators
503
+ */
504
+ stop() {
505
+ // Stop progress bars if they were initialized
506
+ if (this.multiBar) {
507
+ this.multiBar.stop();
508
+ }
509
+ if (this.progressBar) {
510
+ this.progressBar.stop();
511
+ }
512
+ if (this.spinner) {
513
+ this.spinner.stop();
514
+ }
515
+ }
516
+ printSummary() {
517
+ // In console logs mode, use only timestamped log lines (no Progress Manager blocks)
518
+ if (this.showConsoleLogs) {
519
+ return;
520
+ }
521
+ if (!this.enableNestedProgress) {
522
+ // Simple summary for single progress
523
+ this.log('\n' + chalk_1.default.bold(`${this.moduleName} Summary:`));
524
+ this.log(`✓ Success: ${chalk_1.default.green(this.successCount)}`);
525
+ this.log(`✗ Failures: ${chalk_1.default.red(this.failureCount)}`);
526
+ return;
527
+ }
528
+ // Detailed summary for nested progress
529
+ this.log('\n' + chalk_1.default.bold(`${this.moduleName} Detailed Summary:`));
530
+ for (const [processName, process] of this.processes) {
531
+ const status = process.status === 'completed'
532
+ ? '✓'
533
+ : process.status === 'failed'
534
+ ? '✗'
535
+ : process.status === 'active'
536
+ ? '●'
537
+ : '○';
538
+ this.log(` ${status} ${processName}: ${process.successCount}✓ ${process.failureCount}✗ (${process.current}/${process.total})`);
539
+ }
540
+ this.log(`\nOverall: ${this.successCount}✓ ${this.failureCount}✗`);
541
+ }
542
+ /**
543
+ * Get the current failure count
544
+ */
545
+ getFailureCount() {
546
+ return this.failureCount;
547
+ }
548
+ }
549
+ exports.default = CLIProgressManager;
550
+ CLIProgressManager.globalSummary = null;
@@ -0,0 +1,4 @@
1
+ import SummaryManager from './summary-manager';
2
+ import CLIProgressManager from './cli-progress-manager';
3
+ import { PrimaryProcessStrategy, CustomProgressStrategy, ProgressStrategyRegistry, DefaultProgressStrategy } from './progress-strategy';
4
+ export { SummaryManager, CLIProgressManager, PrimaryProcessStrategy, CustomProgressStrategy, ProgressStrategyRegistry, DefaultProgressStrategy, };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultProgressStrategy = exports.ProgressStrategyRegistry = exports.CustomProgressStrategy = exports.PrimaryProcessStrategy = exports.CLIProgressManager = exports.SummaryManager = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const summary_manager_1 = tslib_1.__importDefault(require("./summary-manager"));
6
+ exports.SummaryManager = summary_manager_1.default;
7
+ const cli_progress_manager_1 = tslib_1.__importDefault(require("./cli-progress-manager"));
8
+ exports.CLIProgressManager = cli_progress_manager_1.default;
9
+ const progress_strategy_1 = require("./progress-strategy");
10
+ Object.defineProperty(exports, "PrimaryProcessStrategy", { enumerable: true, get: function () { return progress_strategy_1.PrimaryProcessStrategy; } });
11
+ Object.defineProperty(exports, "CustomProgressStrategy", { enumerable: true, get: function () { return progress_strategy_1.CustomProgressStrategy; } });
12
+ Object.defineProperty(exports, "ProgressStrategyRegistry", { enumerable: true, get: function () { return progress_strategy_1.ProgressStrategyRegistry; } });
13
+ Object.defineProperty(exports, "DefaultProgressStrategy", { enumerable: true, get: function () { return progress_strategy_1.DefaultProgressStrategy; } });
@@ -0,0 +1,25 @@
1
+ import { ProcessProgress, ProgressResult } from '../interfaces';
2
+ export interface ProgressCalculationStrategy {
3
+ calculate(processes: Map<string, ProcessProgress>): ProgressResult | null;
4
+ }
5
+ export declare class DefaultProgressStrategy implements ProgressCalculationStrategy {
6
+ calculate(): ProgressResult | null;
7
+ }
8
+ export declare class PrimaryProcessStrategy implements ProgressCalculationStrategy {
9
+ private primaryProcessName;
10
+ constructor(primaryProcessName: string);
11
+ calculate(processes: Map<string, ProcessProgress>): ProgressResult | null;
12
+ }
13
+ export declare class CustomProgressStrategy implements ProgressCalculationStrategy {
14
+ private calculator;
15
+ constructor(calculator: (processes: Map<string, ProcessProgress>) => ProgressResult | null);
16
+ calculate(processes: Map<string, ProcessProgress>): ProgressResult | null;
17
+ }
18
+ export declare class ProgressStrategyRegistry {
19
+ private static strategies;
20
+ static register(moduleName: string, strategy: ProgressCalculationStrategy): void;
21
+ static get(moduleName: string): ProgressCalculationStrategy;
22
+ static clear(): void;
23
+ static has(moduleName: string): boolean;
24
+ static getAllRegistered(): string[];
25
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressStrategyRegistry = exports.CustomProgressStrategy = exports.PrimaryProcessStrategy = exports.DefaultProgressStrategy = void 0;
4
+ class DefaultProgressStrategy {
5
+ calculate() {
6
+ return null; // Use default aggregated counting
7
+ }
8
+ }
9
+ exports.DefaultProgressStrategy = DefaultProgressStrategy;
10
+ class PrimaryProcessStrategy {
11
+ constructor(primaryProcessName) {
12
+ this.primaryProcessName = primaryProcessName;
13
+ }
14
+ calculate(processes) {
15
+ const primaryProcess = processes.get(this.primaryProcessName);
16
+ if (!primaryProcess)
17
+ return null;
18
+ return {
19
+ total: primaryProcess.total,
20
+ success: primaryProcess.successCount,
21
+ failures: primaryProcess.failureCount
22
+ };
23
+ }
24
+ }
25
+ exports.PrimaryProcessStrategy = PrimaryProcessStrategy;
26
+ class CustomProgressStrategy {
27
+ constructor(calculator) {
28
+ this.calculator = calculator;
29
+ }
30
+ calculate(processes) {
31
+ return this.calculator(processes);
32
+ }
33
+ }
34
+ exports.CustomProgressStrategy = CustomProgressStrategy;
35
+ // Registry
36
+ class ProgressStrategyRegistry {
37
+ static register(moduleName, strategy) {
38
+ this.strategies.set(moduleName.toUpperCase(), strategy);
39
+ }
40
+ static get(moduleName) {
41
+ return this.strategies.get(moduleName.toUpperCase()) || new DefaultProgressStrategy();
42
+ }
43
+ static clear() {
44
+ this.strategies.clear();
45
+ }
46
+ static has(moduleName) {
47
+ return this.strategies.has(moduleName.toUpperCase());
48
+ }
49
+ static getAllRegistered() {
50
+ return Array.from(this.strategies.keys());
51
+ }
52
+ }
53
+ exports.ProgressStrategyRegistry = ProgressStrategyRegistry;
54
+ ProgressStrategyRegistry.strategies = new Map();
@@ -0,0 +1,28 @@
1
+ import { ModuleResult, SummaryOptions } from '../interfaces/index';
2
+ export default class SummaryManager {
3
+ private modules;
4
+ private operationName;
5
+ private context;
6
+ private operationStartTime;
7
+ private branchName;
8
+ constructor({ operationName, context }: SummaryOptions);
9
+ getModules(): Map<string, ModuleResult>;
10
+ registerModule(moduleName: string, totalItems?: number): void;
11
+ startModule(moduleName: string): void;
12
+ completeModule(moduleName: string, success?: boolean, error?: string): void;
13
+ /**
14
+ * Register process data for strategy calculations
15
+ */
16
+ registerProcessData(moduleName: string, processName: string, processData: any): void;
17
+ updateModuleProgress(moduleName: string, success: boolean, itemName: string, error?: string): void;
18
+ printFinalSummary(): void;
19
+ /**
20
+ * Check if there are any failures across all modules
21
+ */
22
+ hasFailures(): boolean;
23
+ private printFailureSummaryWithLogReference;
24
+ private getStatusIcon;
25
+ private formatDuration;
26
+ private calculateSuccessRate;
27
+ private formatSuccessRate;
28
+ }