pnpm-catalog-updates 0.7.18 → 1.0.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 +1 -1
- package/bin/pcu.js +3 -1
- package/dist/index.js +10212 -6761
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
- package/src/cli/commands/checkCommand.ts +62 -62
- package/src/cli/commands/initCommand.ts +90 -90
- package/src/cli/commands/securityCommand.ts +172 -172
- package/src/cli/commands/updateCommand.ts +227 -68
- package/src/cli/formatters/outputFormatter.ts +500 -280
- package/src/cli/formatters/progressBar.ts +228 -228
- package/src/cli/index.ts +407 -167
- package/src/cli/interactive/interactivePrompts.ts +100 -98
- package/src/cli/options/globalOptions.ts +143 -86
- package/src/cli/options/index.ts +1 -1
- package/src/cli/themes/colorTheme.ts +70 -70
- package/src/cli/validators/commandValidator.ts +118 -122
- package/src/cli/validators/index.ts +1 -1
- package/src/index.ts +1 -1
|
@@ -5,64 +5,64 @@
|
|
|
5
5
|
* with multiple styles and themes.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import chalk from 'chalk'
|
|
8
|
+
import chalk from 'chalk'
|
|
9
9
|
|
|
10
10
|
export interface ProgressBarOptions {
|
|
11
|
-
text?: string
|
|
12
|
-
total?: number
|
|
13
|
-
style?: 'default' | 'gradient' | 'fancy' | 'minimal' | 'rainbow' | 'neon'
|
|
14
|
-
showSpeed?: boolean
|
|
11
|
+
text?: string
|
|
12
|
+
total?: number
|
|
13
|
+
style?: 'default' | 'gradient' | 'fancy' | 'minimal' | 'rainbow' | 'neon'
|
|
14
|
+
showSpeed?: boolean
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export class ProgressBar {
|
|
18
|
-
private percentageBar: PercentageProgressBar | null = null
|
|
19
|
-
private current = 0
|
|
20
|
-
private total = 0
|
|
21
|
-
private text = ''
|
|
22
|
-
private startTime: number = 0
|
|
23
|
-
private style: string
|
|
24
|
-
private showSpeed: boolean
|
|
18
|
+
private percentageBar: PercentageProgressBar | null = null
|
|
19
|
+
private current = 0
|
|
20
|
+
private total = 0
|
|
21
|
+
private text = ''
|
|
22
|
+
private startTime: number = 0
|
|
23
|
+
private style: string
|
|
24
|
+
private showSpeed: boolean
|
|
25
25
|
|
|
26
26
|
constructor(options: ProgressBarOptions = {}) {
|
|
27
|
-
this.text = options.text || 'Processing...'
|
|
28
|
-
this.total = options.total || 0
|
|
29
|
-
this.style = options.style || 'default'
|
|
30
|
-
this.showSpeed = options.showSpeed ?? true
|
|
27
|
+
this.text = options.text || 'Processing...'
|
|
28
|
+
this.total = options.total || 0
|
|
29
|
+
this.style = options.style || 'default'
|
|
30
|
+
this.showSpeed = options.showSpeed ?? true
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Start the progress bar
|
|
35
35
|
*/
|
|
36
36
|
start(text?: string): void {
|
|
37
|
-
this.text = text || this.text
|
|
38
|
-
this.startTime = Date.now()
|
|
37
|
+
this.text = text || this.text
|
|
38
|
+
this.startTime = Date.now()
|
|
39
39
|
|
|
40
40
|
// 在开始新进度条前,彻底清理可能的残留内容
|
|
41
|
-
this.clearPreviousOutput()
|
|
41
|
+
this.clearPreviousOutput()
|
|
42
42
|
|
|
43
43
|
// 强制使用percentageBar,即使没有total也要创建
|
|
44
44
|
// 这样可以避免spinner导致的冲突问题
|
|
45
|
-
const effectiveTotal = this.total > 0 ? this.total : 1
|
|
45
|
+
const effectiveTotal = this.total > 0 ? this.total : 1 // 如果没有total,设为1避免除零错误
|
|
46
46
|
|
|
47
47
|
this.percentageBar = new PercentageProgressBar(40, {
|
|
48
48
|
style: this.style,
|
|
49
49
|
showStats: this.showSpeed,
|
|
50
50
|
multiLine: true, // 使用多行模式减少闪烁
|
|
51
|
-
})
|
|
52
|
-
this.percentageBar.start(effectiveTotal, this.text)
|
|
51
|
+
})
|
|
52
|
+
this.percentageBar.start(effectiveTotal, this.text)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Update progress with text
|
|
57
57
|
*/
|
|
58
58
|
update(text: string, current?: number, total?: number): void {
|
|
59
|
-
this.text = text
|
|
60
|
-
if (current !== undefined) this.current = current
|
|
61
|
-
if (total !== undefined) this.total = total
|
|
59
|
+
this.text = text
|
|
60
|
+
if (current !== undefined) this.current = current
|
|
61
|
+
if (total !== undefined) this.total = total
|
|
62
62
|
|
|
63
63
|
// 只使用percentageBar,不使用spinner
|
|
64
64
|
if (this.percentageBar) {
|
|
65
|
-
this.percentageBar.update(this.current, text)
|
|
65
|
+
this.percentageBar.update(this.current, text)
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -70,12 +70,12 @@ export class ProgressBar {
|
|
|
70
70
|
* Increment progress
|
|
71
71
|
*/
|
|
72
72
|
increment(amount = 1, text?: string): void {
|
|
73
|
-
this.current += amount
|
|
74
|
-
if (text) this.text = text
|
|
73
|
+
this.current += amount
|
|
74
|
+
if (text) this.text = text
|
|
75
75
|
|
|
76
76
|
// 只使用percentageBar,不使用spinner
|
|
77
77
|
if (this.percentageBar) {
|
|
78
|
-
this.percentageBar.update(this.current, text)
|
|
78
|
+
this.percentageBar.update(this.current, text)
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -85,10 +85,10 @@ export class ProgressBar {
|
|
|
85
85
|
succeed(text?: string): void {
|
|
86
86
|
// 只使用percentageBar,不使用spinner
|
|
87
87
|
if (this.percentageBar) {
|
|
88
|
-
const successText = text || this.getCompletionText()
|
|
89
|
-
this.percentageBar.complete(successText)
|
|
90
|
-
console.log(this.getSuccessMessage(successText))
|
|
91
|
-
this.percentageBar = null
|
|
88
|
+
const successText = text || this.getCompletionText()
|
|
89
|
+
this.percentageBar.complete(successText)
|
|
90
|
+
console.log(this.getSuccessMessage(successText))
|
|
91
|
+
this.percentageBar = null
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -98,9 +98,9 @@ export class ProgressBar {
|
|
|
98
98
|
fail(text?: string): void {
|
|
99
99
|
// 只使用percentageBar,不使用spinner
|
|
100
100
|
if (this.percentageBar) {
|
|
101
|
-
const failText = text || this.getFailureText()
|
|
102
|
-
console.log(this.getFailureMessage(failText))
|
|
103
|
-
this.percentageBar = null
|
|
101
|
+
const failText = text || this.getFailureText()
|
|
102
|
+
console.log(this.getFailureMessage(failText))
|
|
103
|
+
this.percentageBar = null
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -108,20 +108,20 @@ export class ProgressBar {
|
|
|
108
108
|
* Get styled success message
|
|
109
109
|
*/
|
|
110
110
|
private getSuccessMessage(text: string): string {
|
|
111
|
-
const elapsed = this.getElapsedTime()
|
|
111
|
+
const elapsed = this.getElapsedTime()
|
|
112
112
|
switch (this.style) {
|
|
113
113
|
case 'gradient':
|
|
114
|
-
return `${chalk.magenta.bold('✨')} ${chalk.green(text)} ${chalk.gray(elapsed)}
|
|
114
|
+
return `${chalk.magenta.bold('✨')} ${chalk.green(text)} ${chalk.gray(elapsed)}`
|
|
115
115
|
case 'fancy':
|
|
116
|
-
return `${chalk.cyan('🎉')} ${chalk.green.bold(text)} ${chalk.cyan('🎉')} ${chalk.gray(elapsed)}
|
|
116
|
+
return `${chalk.cyan('🎉')} ${chalk.green.bold(text)} ${chalk.cyan('🎉')} ${chalk.gray(elapsed)}`
|
|
117
117
|
case 'minimal':
|
|
118
|
-
return chalk.green(text)
|
|
118
|
+
return chalk.green(text)
|
|
119
119
|
case 'rainbow':
|
|
120
|
-
return `${chalk.magenta('🌈')} ${chalk.green(text)} ${chalk.gray(elapsed)}
|
|
120
|
+
return `${chalk.magenta('🌈')} ${chalk.green(text)} ${chalk.gray(elapsed)}`
|
|
121
121
|
case 'neon':
|
|
122
|
-
return `${chalk.green.bold('⚡ SUCCESS')} ${chalk.green(text)} ${chalk.gray(elapsed)}
|
|
122
|
+
return `${chalk.green.bold('⚡ SUCCESS')} ${chalk.green(text)} ${chalk.gray(elapsed)}`
|
|
123
123
|
default:
|
|
124
|
-
return `${chalk.green('✅')} ${chalk.green(text)} ${chalk.gray(elapsed)}
|
|
124
|
+
return `${chalk.green('✅')} ${chalk.green(text)} ${chalk.gray(elapsed)}`
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -129,20 +129,20 @@ export class ProgressBar {
|
|
|
129
129
|
* Get styled failure message
|
|
130
130
|
*/
|
|
131
131
|
private getFailureMessage(text: string): string {
|
|
132
|
-
const elapsed = this.getElapsedTime()
|
|
132
|
+
const elapsed = this.getElapsedTime()
|
|
133
133
|
switch (this.style) {
|
|
134
134
|
case 'gradient':
|
|
135
|
-
return `${chalk.red.bold('💥')} ${chalk.red(text)} ${chalk.gray(elapsed)}
|
|
135
|
+
return `${chalk.red.bold('💥')} ${chalk.red(text)} ${chalk.gray(elapsed)}`
|
|
136
136
|
case 'fancy':
|
|
137
|
-
return `${chalk.red('💔')} ${chalk.red.bold(text)} ${chalk.red('💔')} ${chalk.gray(elapsed)}
|
|
137
|
+
return `${chalk.red('💔')} ${chalk.red.bold(text)} ${chalk.red('💔')} ${chalk.gray(elapsed)}`
|
|
138
138
|
case 'minimal':
|
|
139
|
-
return chalk.red(text)
|
|
139
|
+
return chalk.red(text)
|
|
140
140
|
case 'rainbow':
|
|
141
|
-
return `${chalk.red('⚠️')} ${chalk.red(text)} ${chalk.gray(elapsed)}
|
|
141
|
+
return `${chalk.red('⚠️')} ${chalk.red(text)} ${chalk.gray(elapsed)}`
|
|
142
142
|
case 'neon':
|
|
143
|
-
return `${chalk.red.bold('⚡ ERROR')} ${chalk.red(text)} ${chalk.gray(elapsed)}
|
|
143
|
+
return `${chalk.red.bold('⚡ ERROR')} ${chalk.red(text)} ${chalk.gray(elapsed)}`
|
|
144
144
|
default:
|
|
145
|
-
return `${chalk.red('❌')} ${chalk.red(text)} ${chalk.gray(elapsed)}
|
|
145
|
+
return `${chalk.red('❌')} ${chalk.red(text)} ${chalk.gray(elapsed)}`
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -150,36 +150,36 @@ export class ProgressBar {
|
|
|
150
150
|
* Get completion text with stats
|
|
151
151
|
*/
|
|
152
152
|
private getCompletionText(): string {
|
|
153
|
-
const elapsed = this.getElapsedTime()
|
|
154
|
-
const speed = this.getAverageSpeed()
|
|
155
|
-
return `${this.text} completed ${speed} ${elapsed}
|
|
153
|
+
const elapsed = this.getElapsedTime()
|
|
154
|
+
const speed = this.getAverageSpeed()
|
|
155
|
+
return `${this.text} completed ${speed} ${elapsed}`
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
159
|
* Get failure text
|
|
160
160
|
*/
|
|
161
161
|
private getFailureText(): string {
|
|
162
|
-
return `${this.text} failed
|
|
162
|
+
return `${this.text} failed`
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
166
|
* Get elapsed time formatted
|
|
167
167
|
*/
|
|
168
168
|
private getElapsedTime(): string {
|
|
169
|
-
const elapsed = Date.now() - this.startTime
|
|
170
|
-
if (elapsed < 1000) return `(${elapsed}ms)
|
|
171
|
-
if (elapsed < 60000) return `(${(elapsed / 1000).toFixed(1)}s)
|
|
172
|
-
return `(${Math.floor(elapsed / 60000)}m ${Math.floor((elapsed % 60000) / 1000)}s)
|
|
169
|
+
const elapsed = Date.now() - this.startTime
|
|
170
|
+
if (elapsed < 1000) return `(${elapsed}ms)`
|
|
171
|
+
if (elapsed < 60000) return `(${(elapsed / 1000).toFixed(1)}s)`
|
|
172
|
+
return `(${Math.floor(elapsed / 60000)}m ${Math.floor((elapsed % 60000) / 1000)}s)`
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
/**
|
|
176
176
|
* Get average processing speed
|
|
177
177
|
*/
|
|
178
178
|
private getAverageSpeed(): string {
|
|
179
|
-
const elapsed = Date.now() - this.startTime
|
|
180
|
-
if (elapsed === 0 || this.current === 0) return ''
|
|
181
|
-
const speed = Math.round((this.current / elapsed) * 1000)
|
|
182
|
-
return speed > 0 ? `(${speed}/s)` : ''
|
|
179
|
+
const elapsed = Date.now() - this.startTime
|
|
180
|
+
if (elapsed === 0 || this.current === 0) return ''
|
|
181
|
+
const speed = Math.round((this.current / elapsed) * 1000)
|
|
182
|
+
return speed > 0 ? `(${speed}/s)` : ''
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
/**
|
|
@@ -188,9 +188,9 @@ export class ProgressBar {
|
|
|
188
188
|
warn(text?: string): void {
|
|
189
189
|
// 只使用percentageBar,不使用spinner
|
|
190
190
|
if (this.percentageBar) {
|
|
191
|
-
const warnText = text || this.text
|
|
192
|
-
console.log(this.getWarningMessage(warnText))
|
|
193
|
-
this.percentageBar = null
|
|
191
|
+
const warnText = text || this.text
|
|
192
|
+
console.log(this.getWarningMessage(warnText))
|
|
193
|
+
this.percentageBar = null
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
@@ -200,9 +200,9 @@ export class ProgressBar {
|
|
|
200
200
|
info(text?: string): void {
|
|
201
201
|
// 只使用percentageBar,不使用spinner
|
|
202
202
|
if (this.percentageBar) {
|
|
203
|
-
const infoText = text || this.text
|
|
204
|
-
console.log(this.getInfoMessage(infoText))
|
|
205
|
-
this.percentageBar = null
|
|
203
|
+
const infoText = text || this.text
|
|
204
|
+
console.log(this.getInfoMessage(infoText))
|
|
205
|
+
this.percentageBar = null
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
@@ -210,20 +210,20 @@ export class ProgressBar {
|
|
|
210
210
|
* Get styled warning message
|
|
211
211
|
*/
|
|
212
212
|
private getWarningMessage(text: string): string {
|
|
213
|
-
const elapsed = this.getElapsedTime()
|
|
213
|
+
const elapsed = this.getElapsedTime()
|
|
214
214
|
switch (this.style) {
|
|
215
215
|
case 'gradient':
|
|
216
|
-
return `${chalk.yellow.bold('⚡')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}
|
|
216
|
+
return `${chalk.yellow.bold('⚡')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}`
|
|
217
217
|
case 'fancy':
|
|
218
|
-
return `${chalk.yellow('⚠️')} ${chalk.yellow.bold(text)} ${chalk.yellow('⚠️')} ${chalk.gray(elapsed)}
|
|
218
|
+
return `${chalk.yellow('⚠️')} ${chalk.yellow.bold(text)} ${chalk.yellow('⚠️')} ${chalk.gray(elapsed)}`
|
|
219
219
|
case 'minimal':
|
|
220
|
-
return chalk.yellow(text)
|
|
220
|
+
return chalk.yellow(text)
|
|
221
221
|
case 'rainbow':
|
|
222
|
-
return `${chalk.yellow('⚠️')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}
|
|
222
|
+
return `${chalk.yellow('⚠️')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}`
|
|
223
223
|
case 'neon':
|
|
224
|
-
return `${chalk.yellow.bold('⚡ WARNING')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}
|
|
224
|
+
return `${chalk.yellow.bold('⚡ WARNING')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}`
|
|
225
225
|
default:
|
|
226
|
-
return `${chalk.yellow('⚠️')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}
|
|
226
|
+
return `${chalk.yellow('⚠️')} ${chalk.yellow(text)} ${chalk.gray(elapsed)}`
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
@@ -231,20 +231,20 @@ export class ProgressBar {
|
|
|
231
231
|
* Get styled info message
|
|
232
232
|
*/
|
|
233
233
|
private getInfoMessage(text: string): string {
|
|
234
|
-
const elapsed = this.getElapsedTime()
|
|
234
|
+
const elapsed = this.getElapsedTime()
|
|
235
235
|
switch (this.style) {
|
|
236
236
|
case 'gradient':
|
|
237
|
-
return `${chalk.blue.bold('ℹ️')} ${chalk.blue(text)} ${chalk.gray(elapsed)}
|
|
237
|
+
return `${chalk.blue.bold('ℹ️')} ${chalk.blue(text)} ${chalk.gray(elapsed)}`
|
|
238
238
|
case 'fancy':
|
|
239
|
-
return `${chalk.blue('💡')} ${chalk.blue.bold(text)} ${chalk.blue('💡')} ${chalk.gray(elapsed)}
|
|
239
|
+
return `${chalk.blue('💡')} ${chalk.blue.bold(text)} ${chalk.blue('💡')} ${chalk.gray(elapsed)}`
|
|
240
240
|
case 'minimal':
|
|
241
|
-
return chalk.blue(text)
|
|
241
|
+
return chalk.blue(text)
|
|
242
242
|
case 'rainbow':
|
|
243
|
-
return `${chalk.blue('ℹ️')} ${chalk.blue(text)} ${chalk.gray(elapsed)}
|
|
243
|
+
return `${chalk.blue('ℹ️')} ${chalk.blue(text)} ${chalk.gray(elapsed)}`
|
|
244
244
|
case 'neon':
|
|
245
|
-
return `${chalk.blue.bold('⚡ INFO')} ${chalk.blue(text)} ${chalk.gray(elapsed)}
|
|
245
|
+
return `${chalk.blue.bold('⚡ INFO')} ${chalk.blue(text)} ${chalk.gray(elapsed)}`
|
|
246
246
|
default:
|
|
247
|
-
return `${chalk.blue('ℹ️')} ${chalk.blue(text)} ${chalk.gray(elapsed)}
|
|
247
|
+
return `${chalk.blue('ℹ️')} ${chalk.blue(text)} ${chalk.gray(elapsed)}`
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
|
|
@@ -254,7 +254,7 @@ export class ProgressBar {
|
|
|
254
254
|
stop(): void {
|
|
255
255
|
// 只使用percentageBar,不使用spinner
|
|
256
256
|
if (this.percentageBar) {
|
|
257
|
-
this.percentageBar = null
|
|
257
|
+
this.percentageBar = null
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
|
|
@@ -264,17 +264,17 @@ export class ProgressBar {
|
|
|
264
264
|
private clearPreviousOutput(): void {
|
|
265
265
|
// 清理可能的残留进度条显示(最多清理5行,应该足够了)
|
|
266
266
|
for (let i = 0; i < 5; i++) {
|
|
267
|
-
process.stdout.write('\x1b[1A\r\x1b[K')
|
|
267
|
+
process.stdout.write('\x1b[1A\r\x1b[K') // 上移一行并清除
|
|
268
268
|
}
|
|
269
269
|
// 确保光标在正确位置
|
|
270
|
-
process.stdout.write('\r')
|
|
270
|
+
process.stdout.write('\r')
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
/**
|
|
274
274
|
* Create a multi-step progress indicator
|
|
275
275
|
*/
|
|
276
276
|
static createMultiStep(steps: string[]): MultiStepProgress {
|
|
277
|
-
return new MultiStepProgress(steps)
|
|
277
|
+
return new MultiStepProgress(steps)
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
/**
|
|
@@ -285,7 +285,7 @@ export class ProgressBar {
|
|
|
285
285
|
style: 'gradient',
|
|
286
286
|
showSpeed: true,
|
|
287
287
|
...options,
|
|
288
|
-
})
|
|
288
|
+
})
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
/**
|
|
@@ -296,7 +296,7 @@ export class ProgressBar {
|
|
|
296
296
|
style: 'fancy',
|
|
297
297
|
showSpeed: true,
|
|
298
298
|
...options,
|
|
299
|
-
})
|
|
299
|
+
})
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
/**
|
|
@@ -307,7 +307,7 @@ export class ProgressBar {
|
|
|
307
307
|
style: 'minimal',
|
|
308
308
|
showSpeed: false,
|
|
309
309
|
...options,
|
|
310
|
-
})
|
|
310
|
+
})
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
/**
|
|
@@ -318,7 +318,7 @@ export class ProgressBar {
|
|
|
318
318
|
style: 'rainbow',
|
|
319
319
|
showSpeed: true,
|
|
320
320
|
...options,
|
|
321
|
-
})
|
|
321
|
+
})
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
/**
|
|
@@ -329,7 +329,7 @@ export class ProgressBar {
|
|
|
329
329
|
style: 'neon',
|
|
330
330
|
showSpeed: true,
|
|
331
331
|
...options,
|
|
332
|
-
})
|
|
332
|
+
})
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
335
|
|
|
@@ -337,41 +337,41 @@ export class ProgressBar {
|
|
|
337
337
|
* Multi-step progress indicator
|
|
338
338
|
*/
|
|
339
339
|
export class MultiStepProgress {
|
|
340
|
-
private currentStep = 0
|
|
341
|
-
private steps: string[] = []
|
|
340
|
+
private currentStep = 0
|
|
341
|
+
private steps: string[] = []
|
|
342
342
|
|
|
343
343
|
constructor(steps: string[]) {
|
|
344
|
-
this.steps = steps
|
|
344
|
+
this.steps = steps
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
start(): void {
|
|
348
|
-
console.log(chalk.bold('\n📋 Progress Steps:\n'))
|
|
349
|
-
this.renderSteps()
|
|
348
|
+
console.log(chalk.bold('\n📋 Progress Steps:\n'))
|
|
349
|
+
this.renderSteps()
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
next(text?: string): void {
|
|
353
353
|
if (this.currentStep < this.steps.length) {
|
|
354
|
-
const stepText = text || this.steps[this.currentStep]
|
|
355
|
-
console.log(` ${chalk.green('✓')} ${stepText}`)
|
|
356
|
-
this.currentStep
|
|
354
|
+
const stepText = text || this.steps[this.currentStep]
|
|
355
|
+
console.log(` ${chalk.green('✓')} ${stepText}`)
|
|
356
|
+
this.currentStep++
|
|
357
357
|
|
|
358
358
|
if (this.currentStep < this.steps.length) {
|
|
359
|
-
console.log(` ${chalk.cyan('→')} ${this.steps[this.currentStep]}`)
|
|
359
|
+
console.log(` ${chalk.cyan('→')} ${this.steps[this.currentStep]}`)
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
complete(): void {
|
|
365
|
-
console.log(chalk.green('\n🎉 All steps completed!\n'))
|
|
365
|
+
console.log(chalk.green('\n🎉 All steps completed!\n'))
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
private renderSteps(): void {
|
|
369
369
|
this.steps.forEach((step, index) => {
|
|
370
|
-
const prefix = index === 0 ? chalk.cyan('→') : ' '
|
|
371
|
-
const style = index < this.currentStep ? chalk.green : chalk.gray
|
|
372
|
-
console.log(` ${prefix} ${style(step)}`)
|
|
373
|
-
})
|
|
374
|
-
console.log('')
|
|
370
|
+
const prefix = index === 0 ? chalk.cyan('→') : ' '
|
|
371
|
+
const style = index < this.currentStep ? chalk.green : chalk.gray
|
|
372
|
+
console.log(` ${prefix} ${style(step)}`)
|
|
373
|
+
})
|
|
374
|
+
console.log('')
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
|
|
@@ -379,34 +379,34 @@ export class MultiStepProgress {
|
|
|
379
379
|
* Progress bar with percentage and beautiful visual effects
|
|
380
380
|
*/
|
|
381
381
|
export class PercentageProgressBar {
|
|
382
|
-
private current = 0
|
|
383
|
-
private total = 0
|
|
384
|
-
private text = ''
|
|
385
|
-
private lastRender = ''
|
|
386
|
-
private startTime = 0
|
|
387
|
-
private style: string
|
|
388
|
-
private useMultiLine = true
|
|
389
|
-
private isFirstRender = true
|
|
382
|
+
private current = 0
|
|
383
|
+
private total = 0
|
|
384
|
+
private text = ''
|
|
385
|
+
private lastRender = ''
|
|
386
|
+
private startTime = 0
|
|
387
|
+
private style: string
|
|
388
|
+
private useMultiLine = true
|
|
389
|
+
private isFirstRender = true
|
|
390
390
|
|
|
391
391
|
constructor(
|
|
392
392
|
private readonly width = 40,
|
|
393
393
|
private readonly options: { style?: string; showStats?: boolean; multiLine?: boolean } = {}
|
|
394
394
|
) {
|
|
395
|
-
this.style = options.style || 'gradient'
|
|
396
|
-
this.useMultiLine = options.multiLine ?? true
|
|
395
|
+
this.style = options.style || 'gradient'
|
|
396
|
+
this.useMultiLine = options.multiLine ?? true // 默认使用多行模式来减少闪烁
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
start(total: number, text: string): void {
|
|
400
|
-
this.total = total
|
|
401
|
-
this.current = 0
|
|
402
|
-
this.text = text
|
|
403
|
-
this.startTime = Date.now()
|
|
404
|
-
this.isFirstRender = true
|
|
400
|
+
this.total = total
|
|
401
|
+
this.current = 0
|
|
402
|
+
this.text = text
|
|
403
|
+
this.startTime = Date.now()
|
|
404
|
+
this.isFirstRender = true // 重置首次渲染标记
|
|
405
405
|
|
|
406
406
|
// 清理可能的残留输出
|
|
407
|
-
this.clearPreviousLines()
|
|
407
|
+
this.clearPreviousLines()
|
|
408
408
|
|
|
409
|
-
this.render()
|
|
409
|
+
this.render()
|
|
410
410
|
}
|
|
411
411
|
|
|
412
412
|
/**
|
|
@@ -415,200 +415,200 @@ export class PercentageProgressBar {
|
|
|
415
415
|
private clearPreviousLines(): void {
|
|
416
416
|
// 更强力的清理:清理多行可能的残留内容
|
|
417
417
|
for (let i = 0; i < 6; i++) {
|
|
418
|
-
process.stdout.write('\x1b[1A\r\x1b[2K')
|
|
418
|
+
process.stdout.write('\x1b[1A\r\x1b[2K') // 上移一行并完全清除该行
|
|
419
419
|
}
|
|
420
420
|
// 回到起始位置
|
|
421
|
-
process.stdout.write('\r')
|
|
421
|
+
process.stdout.write('\r')
|
|
422
422
|
}
|
|
423
423
|
|
|
424
424
|
update(current: number, text?: string): void {
|
|
425
|
-
this.current = current
|
|
426
|
-
if (text) this.text = text
|
|
427
|
-
this.render()
|
|
425
|
+
this.current = current
|
|
426
|
+
if (text) this.text = text
|
|
427
|
+
this.render()
|
|
428
428
|
}
|
|
429
429
|
|
|
430
430
|
increment(amount = 1, text?: string): void {
|
|
431
|
-
this.current += amount
|
|
432
|
-
if (text) this.text = text
|
|
433
|
-
this.render()
|
|
431
|
+
this.current += amount
|
|
432
|
+
if (text) this.text = text
|
|
433
|
+
this.render()
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
complete(text?: string): void {
|
|
437
|
-
this.current = this.total
|
|
438
|
-
if (text) this.text = text
|
|
439
|
-
this.render()
|
|
440
|
-
console.log('')
|
|
437
|
+
this.current = this.total
|
|
438
|
+
if (text) this.text = text
|
|
439
|
+
this.render()
|
|
440
|
+
console.log('') // New line after completion
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
private render(): void {
|
|
444
|
-
const percentage = Math.round((this.current / this.total) * 100)
|
|
445
|
-
const filledWidth = Math.round((this.current / this.total) * this.width)
|
|
446
|
-
const emptyWidth = this.width - filledWidth
|
|
444
|
+
const percentage = Math.round((this.current / this.total) * 100)
|
|
445
|
+
const filledWidth = Math.round((this.current / this.total) * this.width)
|
|
446
|
+
const emptyWidth = this.width - filledWidth
|
|
447
447
|
|
|
448
448
|
if (this.useMultiLine) {
|
|
449
|
-
this.renderMultiLine(percentage, filledWidth, emptyWidth)
|
|
449
|
+
this.renderMultiLine(percentage, filledWidth, emptyWidth)
|
|
450
450
|
} else {
|
|
451
|
-
this.renderSingleLine(percentage, filledWidth, emptyWidth)
|
|
451
|
+
this.renderSingleLine(percentage, filledWidth, emptyWidth)
|
|
452
452
|
}
|
|
453
453
|
}
|
|
454
454
|
|
|
455
455
|
private renderMultiLine(percentage: number, filledWidth: number, emptyWidth: number): void {
|
|
456
|
-
const currentText = `${this.getStyledPrefix()} ${this.text}
|
|
456
|
+
const currentText = `${this.getStyledPrefix()} ${this.text}`
|
|
457
457
|
|
|
458
458
|
// 构建进度条
|
|
459
|
-
let bar: string
|
|
459
|
+
let bar: string
|
|
460
460
|
switch (this.style) {
|
|
461
461
|
case 'gradient':
|
|
462
|
-
bar = this.renderGradientBar(filledWidth, emptyWidth)
|
|
463
|
-
break
|
|
462
|
+
bar = this.renderGradientBar(filledWidth, emptyWidth)
|
|
463
|
+
break
|
|
464
464
|
case 'fancy':
|
|
465
|
-
bar = this.renderFancyBar(filledWidth, emptyWidth)
|
|
466
|
-
break
|
|
465
|
+
bar = this.renderFancyBar(filledWidth, emptyWidth)
|
|
466
|
+
break
|
|
467
467
|
case 'minimal':
|
|
468
|
-
bar = this.renderMinimalBar(filledWidth, emptyWidth)
|
|
469
|
-
break
|
|
468
|
+
bar = this.renderMinimalBar(filledWidth, emptyWidth)
|
|
469
|
+
break
|
|
470
470
|
case 'blocks':
|
|
471
|
-
bar = this.renderBlockBar(filledWidth, emptyWidth)
|
|
472
|
-
break
|
|
471
|
+
bar = this.renderBlockBar(filledWidth, emptyWidth)
|
|
472
|
+
break
|
|
473
473
|
default:
|
|
474
|
-
bar = this.renderDefaultBar(filledWidth, emptyWidth)
|
|
474
|
+
bar = this.renderDefaultBar(filledWidth, emptyWidth)
|
|
475
475
|
}
|
|
476
476
|
|
|
477
|
-
let progressLine = `(${this.current}/${this.total}) [${bar}] ${this.getStyledPercentage(percentage)}
|
|
477
|
+
let progressLine = `(${this.current}/${this.total}) [${bar}] ${this.getStyledPercentage(percentage)}`
|
|
478
478
|
|
|
479
479
|
// Add stats if enabled
|
|
480
480
|
if (this.options.showStats && this.startTime > 0) {
|
|
481
|
-
const elapsed = Date.now() - this.startTime
|
|
482
|
-
const speed = elapsed > 0 ? Math.round((this.current / elapsed) * 1000) : 0
|
|
481
|
+
const elapsed = Date.now() - this.startTime
|
|
482
|
+
const speed = elapsed > 0 ? Math.round((this.current / elapsed) * 1000) : 0
|
|
483
483
|
if (speed > 0) {
|
|
484
|
-
progressLine += ` ${chalk.gray(`${speed}/s`)}
|
|
484
|
+
progressLine += ` ${chalk.gray(`${speed}/s`)}`
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
|
|
488
488
|
if (this.isFirstRender) {
|
|
489
489
|
// 第一次渲染:输出两行
|
|
490
|
-
console.log(currentText)
|
|
491
|
-
console.log(progressLine)
|
|
492
|
-
this.isFirstRender = false
|
|
490
|
+
console.log(currentText)
|
|
491
|
+
console.log(progressLine)
|
|
492
|
+
this.isFirstRender = false
|
|
493
493
|
} else {
|
|
494
494
|
// 后续更新:回到两行前的位置,分别更新这两行
|
|
495
495
|
// 光标上移两行,清除文字行,输出新文字行
|
|
496
|
-
process.stdout.write(
|
|
496
|
+
process.stdout.write(`\x1b[2A\r\x1b[2K${currentText}\n`)
|
|
497
497
|
// 清除进度条行,输出新进度条行
|
|
498
|
-
process.stdout.write(
|
|
498
|
+
process.stdout.write(`\r\x1b[2K${progressLine}`)
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
-
this.lastRender = progressLine
|
|
501
|
+
this.lastRender = progressLine
|
|
502
502
|
|
|
503
503
|
if (this.current >= this.total) {
|
|
504
|
-
process.stdout.write('\n')
|
|
504
|
+
process.stdout.write('\n')
|
|
505
505
|
}
|
|
506
506
|
}
|
|
507
507
|
|
|
508
508
|
private renderSingleLine(percentage: number, filledWidth: number, emptyWidth: number): void {
|
|
509
|
-
let bar: string
|
|
509
|
+
let bar: string
|
|
510
510
|
switch (this.style) {
|
|
511
511
|
case 'gradient':
|
|
512
|
-
bar = this.renderGradientBar(filledWidth, emptyWidth)
|
|
513
|
-
break
|
|
512
|
+
bar = this.renderGradientBar(filledWidth, emptyWidth)
|
|
513
|
+
break
|
|
514
514
|
case 'fancy':
|
|
515
|
-
bar = this.renderFancyBar(filledWidth, emptyWidth)
|
|
516
|
-
break
|
|
515
|
+
bar = this.renderFancyBar(filledWidth, emptyWidth)
|
|
516
|
+
break
|
|
517
517
|
case 'minimal':
|
|
518
|
-
bar = this.renderMinimalBar(filledWidth, emptyWidth)
|
|
519
|
-
break
|
|
518
|
+
bar = this.renderMinimalBar(filledWidth, emptyWidth)
|
|
519
|
+
break
|
|
520
520
|
case 'blocks':
|
|
521
|
-
bar = this.renderBlockBar(filledWidth, emptyWidth)
|
|
522
|
-
break
|
|
521
|
+
bar = this.renderBlockBar(filledWidth, emptyWidth)
|
|
522
|
+
break
|
|
523
523
|
default:
|
|
524
|
-
bar = this.renderDefaultBar(filledWidth, emptyWidth)
|
|
524
|
+
bar = this.renderDefaultBar(filledWidth, emptyWidth)
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
-
let progressText = `${this.getStyledPrefix()} ${this.text} (${this.current}/${this.total}) [${bar}] ${this.getStyledPercentage(percentage)}
|
|
527
|
+
let progressText = `${this.getStyledPrefix()} ${this.text} (${this.current}/${this.total}) [${bar}] ${this.getStyledPercentage(percentage)}`
|
|
528
528
|
|
|
529
529
|
// Add stats if enabled
|
|
530
530
|
if (this.options.showStats && this.startTime > 0) {
|
|
531
|
-
const elapsed = Date.now() - this.startTime
|
|
532
|
-
const speed = elapsed > 0 ? Math.round((this.current / elapsed) * 1000) : 0
|
|
531
|
+
const elapsed = Date.now() - this.startTime
|
|
532
|
+
const speed = elapsed > 0 ? Math.round((this.current / elapsed) * 1000) : 0
|
|
533
533
|
if (speed > 0) {
|
|
534
|
-
progressText += ` ${chalk.gray(`${speed}/s`)}
|
|
534
|
+
progressText += ` ${chalk.gray(`${speed}/s`)}`
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
537
|
|
|
538
538
|
// Clear previous line and render new one
|
|
539
539
|
if (this.lastRender) {
|
|
540
|
-
process.stdout.write('\r\x1b[K')
|
|
540
|
+
process.stdout.write('\r\x1b[K')
|
|
541
541
|
}
|
|
542
542
|
|
|
543
|
-
process.stdout.write(progressText)
|
|
544
|
-
this.lastRender = progressText
|
|
543
|
+
process.stdout.write(progressText)
|
|
544
|
+
this.lastRender = progressText
|
|
545
545
|
|
|
546
546
|
if (this.current >= this.total) {
|
|
547
|
-
process.stdout.write('\n')
|
|
547
|
+
process.stdout.write('\n')
|
|
548
548
|
}
|
|
549
549
|
}
|
|
550
550
|
|
|
551
551
|
private renderGradientBar(filledWidth: number, emptyWidth: number): string {
|
|
552
|
-
const colors = [chalk.red, chalk.yellow, chalk.green, chalk.cyan, chalk.blue, chalk.magenta]
|
|
552
|
+
const colors = [chalk.red, chalk.yellow, chalk.green, chalk.cyan, chalk.blue, chalk.magenta]
|
|
553
553
|
|
|
554
|
-
let filledBar = ''
|
|
554
|
+
let filledBar = ''
|
|
555
555
|
for (let i = 0; i < filledWidth; i++) {
|
|
556
|
-
const colorIndex = Math.floor((i / this.width) * colors.length)
|
|
557
|
-
const colorFn = colors[Math.min(colorIndex, colors.length - 1)]
|
|
556
|
+
const colorIndex = Math.floor((i / this.width) * colors.length)
|
|
557
|
+
const colorFn = colors[Math.min(colorIndex, colors.length - 1)]
|
|
558
558
|
if (colorFn) {
|
|
559
|
-
filledBar += colorFn('█')
|
|
559
|
+
filledBar += colorFn('█')
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
|
|
563
|
-
const emptyBar = chalk.gray('░'.repeat(emptyWidth))
|
|
564
|
-
return filledBar + emptyBar
|
|
563
|
+
const emptyBar = chalk.gray('░'.repeat(emptyWidth))
|
|
564
|
+
return filledBar + emptyBar
|
|
565
565
|
}
|
|
566
566
|
|
|
567
567
|
private renderFancyBar(filledWidth: number, emptyWidth: number): string {
|
|
568
|
-
const filledBar = chalk.cyan('▓'.repeat(filledWidth))
|
|
569
|
-
const emptyBar = chalk.gray('░'.repeat(emptyWidth))
|
|
570
|
-
return filledBar + emptyBar
|
|
568
|
+
const filledBar = chalk.cyan('▓'.repeat(filledWidth))
|
|
569
|
+
const emptyBar = chalk.gray('░'.repeat(emptyWidth))
|
|
570
|
+
return filledBar + emptyBar
|
|
571
571
|
}
|
|
572
572
|
|
|
573
573
|
private renderMinimalBar(filledWidth: number, emptyWidth: number): string {
|
|
574
|
-
const filledBar = chalk.white('━'.repeat(filledWidth))
|
|
575
|
-
const emptyBar = chalk.gray('─'.repeat(emptyWidth))
|
|
576
|
-
return filledBar + emptyBar
|
|
574
|
+
const filledBar = chalk.white('━'.repeat(filledWidth))
|
|
575
|
+
const emptyBar = chalk.gray('─'.repeat(emptyWidth))
|
|
576
|
+
return filledBar + emptyBar
|
|
577
577
|
}
|
|
578
578
|
|
|
579
579
|
private renderBlockBar(filledWidth: number, emptyWidth: number): string {
|
|
580
|
-
const filledBar = chalk.green('■'.repeat(filledWidth))
|
|
581
|
-
const emptyBar = chalk.gray('□'.repeat(emptyWidth))
|
|
582
|
-
return filledBar + emptyBar
|
|
580
|
+
const filledBar = chalk.green('■'.repeat(filledWidth))
|
|
581
|
+
const emptyBar = chalk.gray('□'.repeat(emptyWidth))
|
|
582
|
+
return filledBar + emptyBar
|
|
583
583
|
}
|
|
584
584
|
|
|
585
585
|
private renderDefaultBar(filledWidth: number, emptyWidth: number): string {
|
|
586
|
-
const filledBar = chalk.green('█'.repeat(filledWidth))
|
|
587
|
-
const emptyBar = chalk.gray('░'.repeat(emptyWidth))
|
|
588
|
-
return filledBar + emptyBar
|
|
586
|
+
const filledBar = chalk.green('█'.repeat(filledWidth))
|
|
587
|
+
const emptyBar = chalk.gray('░'.repeat(emptyWidth))
|
|
588
|
+
return filledBar + emptyBar
|
|
589
589
|
}
|
|
590
590
|
|
|
591
591
|
private getStyledPrefix(): string {
|
|
592
592
|
switch (this.style) {
|
|
593
593
|
case 'gradient':
|
|
594
|
-
return chalk.magenta('▶')
|
|
594
|
+
return chalk.magenta('▶')
|
|
595
595
|
case 'fancy':
|
|
596
|
-
return chalk.cyan('★')
|
|
596
|
+
return chalk.cyan('★')
|
|
597
597
|
case 'minimal':
|
|
598
|
-
return chalk.gray('•')
|
|
598
|
+
return chalk.gray('•')
|
|
599
599
|
case 'blocks':
|
|
600
|
-
return chalk.green('◆')
|
|
600
|
+
return chalk.green('◆')
|
|
601
601
|
default:
|
|
602
|
-
return chalk.cyan('●')
|
|
602
|
+
return chalk.cyan('●')
|
|
603
603
|
}
|
|
604
604
|
}
|
|
605
605
|
|
|
606
606
|
private getStyledPercentage(percentage: number): string {
|
|
607
|
-
if (percentage < 25) return chalk.red.bold(`${percentage}%`)
|
|
608
|
-
if (percentage < 50) return chalk.yellow.bold(`${percentage}%`)
|
|
609
|
-
if (percentage < 75) return chalk.blue.bold(`${percentage}%`)
|
|
610
|
-
if (percentage < 100) return chalk.cyan.bold(`${percentage}%`)
|
|
611
|
-
return chalk.green.bold(`${percentage}%`)
|
|
607
|
+
if (percentage < 25) return chalk.red.bold(`${percentage}%`)
|
|
608
|
+
if (percentage < 50) return chalk.yellow.bold(`${percentage}%`)
|
|
609
|
+
if (percentage < 75) return chalk.blue.bold(`${percentage}%`)
|
|
610
|
+
if (percentage < 100) return chalk.cyan.bold(`${percentage}%`)
|
|
611
|
+
return chalk.green.bold(`${percentage}%`)
|
|
612
612
|
}
|
|
613
613
|
|
|
614
614
|
/**
|
|
@@ -619,14 +619,14 @@ export class PercentageProgressBar {
|
|
|
619
619
|
style: 'gradient',
|
|
620
620
|
showStats: true,
|
|
621
621
|
multiLine: true,
|
|
622
|
-
})
|
|
622
|
+
})
|
|
623
623
|
}
|
|
624
624
|
|
|
625
625
|
/**
|
|
626
626
|
* Create a fancy percentage progress bar
|
|
627
627
|
*/
|
|
628
628
|
static createFancy(width = 40): PercentageProgressBar {
|
|
629
|
-
return new PercentageProgressBar(width, { style: 'fancy', showStats: true, multiLine: true })
|
|
629
|
+
return new PercentageProgressBar(width, { style: 'fancy', showStats: true, multiLine: true })
|
|
630
630
|
}
|
|
631
631
|
|
|
632
632
|
/**
|
|
@@ -637,14 +637,14 @@ export class PercentageProgressBar {
|
|
|
637
637
|
style: 'minimal',
|
|
638
638
|
showStats: false,
|
|
639
639
|
multiLine: true,
|
|
640
|
-
})
|
|
640
|
+
})
|
|
641
641
|
}
|
|
642
642
|
|
|
643
643
|
/**
|
|
644
644
|
* Create a block-style percentage progress bar
|
|
645
645
|
*/
|
|
646
646
|
static createBlocks(width = 40): PercentageProgressBar {
|
|
647
|
-
return new PercentageProgressBar(width, { style: 'blocks', showStats: true, multiLine: true })
|
|
647
|
+
return new PercentageProgressBar(width, { style: 'blocks', showStats: true, multiLine: true })
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
|
|
@@ -652,49 +652,49 @@ export class PercentageProgressBar {
|
|
|
652
652
|
* Progress manager for batch operations
|
|
653
653
|
*/
|
|
654
654
|
export class BatchProgressManager {
|
|
655
|
-
private bars: Map<string, ProgressBar> = new Map()
|
|
656
|
-
private totalOperations = 0
|
|
657
|
-
private completedOperations = 0
|
|
655
|
+
private bars: Map<string, ProgressBar> = new Map()
|
|
656
|
+
private totalOperations = 0
|
|
657
|
+
private completedOperations = 0
|
|
658
658
|
|
|
659
659
|
createBar(id: string, options?: ProgressBarOptions): ProgressBar {
|
|
660
|
-
const bar = new ProgressBar(options)
|
|
661
|
-
this.bars.set(id, bar)
|
|
662
|
-
return bar
|
|
660
|
+
const bar = new ProgressBar(options)
|
|
661
|
+
this.bars.set(id, bar)
|
|
662
|
+
return bar
|
|
663
663
|
}
|
|
664
664
|
|
|
665
665
|
getBar(id: string): ProgressBar | undefined {
|
|
666
|
-
return this.bars.get(id)
|
|
666
|
+
return this.bars.get(id)
|
|
667
667
|
}
|
|
668
668
|
|
|
669
669
|
setTotal(total: number): void {
|
|
670
|
-
this.totalOperations = total
|
|
670
|
+
this.totalOperations = total
|
|
671
671
|
}
|
|
672
672
|
|
|
673
673
|
updateOverall(text: string): void {
|
|
674
674
|
const percentage =
|
|
675
675
|
this.totalOperations > 0
|
|
676
676
|
? Math.round((this.completedOperations / this.totalOperations) * 100)
|
|
677
|
-
: 0
|
|
677
|
+
: 0
|
|
678
678
|
|
|
679
679
|
console.log(
|
|
680
680
|
chalk.cyan(
|
|
681
681
|
`📊 Overall Progress: ${percentage}% (${this.completedOperations}/${this.totalOperations})`
|
|
682
682
|
)
|
|
683
|
-
)
|
|
683
|
+
)
|
|
684
684
|
if (text) {
|
|
685
|
-
console.log(chalk.gray(` → ${text}`))
|
|
685
|
+
console.log(chalk.gray(` → ${text}`))
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
688
|
|
|
689
689
|
completeOperation(text?: string): void {
|
|
690
|
-
this.completedOperations
|
|
690
|
+
this.completedOperations++
|
|
691
691
|
if (text) {
|
|
692
|
-
this.updateOverall(text)
|
|
692
|
+
this.updateOverall(text)
|
|
693
693
|
}
|
|
694
694
|
}
|
|
695
695
|
|
|
696
696
|
cleanup(): void {
|
|
697
|
-
this.bars.forEach((bar) => bar.stop())
|
|
698
|
-
this.bars.clear()
|
|
697
|
+
this.bars.forEach((bar) => bar.stop())
|
|
698
|
+
this.bars.clear()
|
|
699
699
|
}
|
|
700
700
|
}
|