pnpm-catalog-updates 1.0.2 → 1.1.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 +15 -0
- package/dist/index.js +22031 -10684
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
- package/src/cli/__tests__/commandRegistrar.test.ts +248 -0
- package/src/cli/commandRegistrar.ts +785 -0
- package/src/cli/commands/__tests__/aiCommand.test.ts +161 -0
- package/src/cli/commands/__tests__/analyzeCommand.test.ts +283 -0
- package/src/cli/commands/__tests__/checkCommand.test.ts +435 -0
- package/src/cli/commands/__tests__/graphCommand.test.ts +312 -0
- package/src/cli/commands/__tests__/initCommand.test.ts +317 -0
- package/src/cli/commands/__tests__/rollbackCommand.test.ts +400 -0
- package/src/cli/commands/__tests__/securityCommand.test.ts +467 -0
- package/src/cli/commands/__tests__/themeCommand.test.ts +166 -0
- package/src/cli/commands/__tests__/updateCommand.test.ts +720 -0
- package/src/cli/commands/__tests__/workspaceCommand.test.ts +286 -0
- package/src/cli/commands/aiCommand.ts +163 -0
- package/src/cli/commands/analyzeCommand.ts +219 -0
- package/src/cli/commands/checkCommand.ts +91 -98
- package/src/cli/commands/graphCommand.ts +475 -0
- package/src/cli/commands/initCommand.ts +64 -54
- package/src/cli/commands/rollbackCommand.ts +334 -0
- package/src/cli/commands/securityCommand.ts +165 -100
- package/src/cli/commands/themeCommand.ts +148 -0
- package/src/cli/commands/updateCommand.ts +215 -263
- package/src/cli/commands/workspaceCommand.ts +73 -0
- package/src/cli/constants/cliChoices.ts +93 -0
- package/src/cli/formatters/__tests__/__snapshots__/outputFormatter.test.ts.snap +557 -0
- package/src/cli/formatters/__tests__/ciFormatter.test.ts +526 -0
- package/src/cli/formatters/__tests__/outputFormatter.test.ts +448 -0
- package/src/cli/formatters/__tests__/progressBar.test.ts +709 -0
- package/src/cli/formatters/ciFormatter.ts +964 -0
- package/src/cli/formatters/colorUtils.ts +145 -0
- package/src/cli/formatters/outputFormatter.ts +615 -332
- package/src/cli/formatters/progressBar.ts +43 -52
- package/src/cli/formatters/versionFormatter.ts +132 -0
- package/src/cli/handlers/aiAnalysisHandler.ts +205 -0
- package/src/cli/handlers/changelogHandler.ts +113 -0
- package/src/cli/handlers/index.ts +9 -0
- package/src/cli/handlers/installHandler.ts +130 -0
- package/src/cli/index.ts +175 -726
- package/src/cli/interactive/InteractiveOptionsCollector.ts +387 -0
- package/src/cli/interactive/interactivePrompts.ts +189 -83
- package/src/cli/interactive/optionUtils.ts +89 -0
- package/src/cli/themes/colorTheme.ts +43 -16
- package/src/cli/utils/cliOutput.ts +118 -0
- package/src/cli/utils/commandHelpers.ts +249 -0
- package/src/cli/validators/commandValidator.ts +321 -336
- package/src/cli/validators/index.ts +37 -2
- package/src/cli/options/globalOptions.ts +0 -437
- package/src/cli/options/index.ts +0 -5
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides consistent color schemes and styling across the CLI
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { t } from '@pcu/utils'
|
|
7
8
|
import chalk from 'chalk'
|
|
8
9
|
|
|
9
10
|
export interface ColorTheme {
|
|
@@ -289,27 +290,27 @@ export class StyledText {
|
|
|
289
290
|
}
|
|
290
291
|
|
|
291
292
|
static iconInfo(text?: string): string {
|
|
292
|
-
return StyledText.icon('
|
|
293
|
+
return StyledText.icon('[i]', text)
|
|
293
294
|
}
|
|
294
295
|
|
|
295
296
|
static iconPackage(text?: string): string {
|
|
296
|
-
return StyledText.icon('
|
|
297
|
+
return StyledText.icon('[PKG]', text)
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
static iconCatalog(text?: string): string {
|
|
300
|
-
return StyledText.icon('
|
|
301
|
+
return StyledText.icon('[CAT]', text)
|
|
301
302
|
}
|
|
302
303
|
|
|
303
304
|
static iconUpdate(text?: string): string {
|
|
304
|
-
return StyledText.icon('
|
|
305
|
+
return StyledText.icon('[UPD]', text)
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
static iconSecurity(text?: string): string {
|
|
308
|
-
return StyledText.icon('
|
|
309
|
+
return StyledText.icon('[SEC]', text)
|
|
309
310
|
}
|
|
310
311
|
|
|
311
312
|
static iconAnalysis(text?: string): string {
|
|
312
|
-
return StyledText.icon('
|
|
313
|
+
return StyledText.icon('[*]', text)
|
|
313
314
|
}
|
|
314
315
|
|
|
315
316
|
static iconCheck(text?: string): string {
|
|
@@ -317,27 +318,53 @@ export class StyledText {
|
|
|
317
318
|
}
|
|
318
319
|
|
|
319
320
|
static iconProgress(text?: string): string {
|
|
320
|
-
return StyledText.icon('
|
|
321
|
+
return StyledText.icon('[...]', text)
|
|
321
322
|
}
|
|
322
323
|
|
|
323
324
|
static iconComplete(text?: string): string {
|
|
324
|
-
return StyledText.icon('
|
|
325
|
+
return StyledText.icon('[OK]', text)
|
|
325
326
|
}
|
|
327
|
+
|
|
328
|
+
// Text formatting
|
|
329
|
+
static bold(text: string): string {
|
|
330
|
+
return chalk.bold(text)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
static dim(text: string): string {
|
|
334
|
+
return chalk.dim(text)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
static italic(text: string): string {
|
|
338
|
+
return chalk.italic(text)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static underline(text: string): string {
|
|
342
|
+
return chalk.underline(text)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Chalk-like color function type
|
|
348
|
+
*/
|
|
349
|
+
type ColorFunction = {
|
|
350
|
+
(text: string): string
|
|
351
|
+
bold: (text: string) => string
|
|
352
|
+
dim: (text: string) => string
|
|
326
353
|
}
|
|
327
354
|
|
|
328
355
|
/**
|
|
329
356
|
* Table styling utilities
|
|
330
357
|
*/
|
|
331
358
|
export class TableStyles {
|
|
332
|
-
static createHeaderStyle(color:
|
|
359
|
+
static createHeaderStyle(color: ColorFunction) {
|
|
333
360
|
return (text: string) => color.bold(text)
|
|
334
361
|
}
|
|
335
362
|
|
|
336
|
-
static createBorderStyle(color:
|
|
363
|
+
static createBorderStyle(color: ColorFunction) {
|
|
337
364
|
return (text: string) => color.dim(text)
|
|
338
365
|
}
|
|
339
366
|
|
|
340
|
-
static createCellStyle(color:
|
|
367
|
+
static createCellStyle(color: (text: string) => string) {
|
|
341
368
|
return (text: string) => color(text)
|
|
342
369
|
}
|
|
343
370
|
}
|
|
@@ -349,7 +376,7 @@ export interface ThemeConfig {
|
|
|
349
376
|
name: string
|
|
350
377
|
colors: Partial<ColorTheme>
|
|
351
378
|
icons: Record<string, string>
|
|
352
|
-
styles: Record<string,
|
|
379
|
+
styles: Record<string, string | number | boolean>
|
|
353
380
|
}
|
|
354
381
|
|
|
355
382
|
/**
|
|
@@ -358,22 +385,22 @@ export interface ThemeConfig {
|
|
|
358
385
|
export const themePresets = {
|
|
359
386
|
development: {
|
|
360
387
|
name: 'development',
|
|
361
|
-
description: '
|
|
388
|
+
description: t('theme.preset.development'),
|
|
362
389
|
theme: 'modern',
|
|
363
390
|
},
|
|
364
391
|
production: {
|
|
365
392
|
name: 'production',
|
|
366
|
-
description: '
|
|
393
|
+
description: t('theme.preset.production'),
|
|
367
394
|
theme: 'minimal',
|
|
368
395
|
},
|
|
369
396
|
presentation: {
|
|
370
397
|
name: 'presentation',
|
|
371
|
-
description: '
|
|
398
|
+
description: t('theme.preset.presentation'),
|
|
372
399
|
theme: 'neon',
|
|
373
400
|
},
|
|
374
401
|
default: {
|
|
375
402
|
name: 'default',
|
|
376
|
-
description: '
|
|
403
|
+
description: t('theme.preset.default'),
|
|
377
404
|
theme: 'default',
|
|
378
405
|
},
|
|
379
406
|
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Output Service
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified interface for CLI output, making it easier to test
|
|
5
|
+
* and control output behavior. This separates user-facing output from
|
|
6
|
+
* internal logging (which should use the logger from @pcu/utils).
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* - Use cliOutput for user-facing messages (formatted, styled)
|
|
10
|
+
* - Use logger from @pcu/utils for internal logging (debug, errors)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Interface for CLI output operations
|
|
15
|
+
* Allows mocking in tests without console hijacking
|
|
16
|
+
*/
|
|
17
|
+
export interface ICliOutput {
|
|
18
|
+
/** Print standard output (user-facing messages) */
|
|
19
|
+
print(...args: unknown[]): void
|
|
20
|
+
/** Print error output (user-facing errors) */
|
|
21
|
+
error(...args: unknown[]): void
|
|
22
|
+
/** Print warning output (user-facing warnings) */
|
|
23
|
+
warn(...args: unknown[]): void
|
|
24
|
+
/** Print info output (alias for print) */
|
|
25
|
+
info(...args: unknown[]): void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Default CLI output implementation using console
|
|
30
|
+
*/
|
|
31
|
+
class CliOutputImpl implements ICliOutput {
|
|
32
|
+
print(...args: unknown[]): void {
|
|
33
|
+
console.log(...args)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
error(...args: unknown[]): void {
|
|
37
|
+
console.error(...args)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
warn(...args: unknown[]): void {
|
|
41
|
+
console.warn(...args)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
info(...args: unknown[]): void {
|
|
45
|
+
console.log(...args)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Singleton instance for CLI output
|
|
51
|
+
* Can be replaced in tests via setCliOutput()
|
|
52
|
+
*/
|
|
53
|
+
let cliOutputInstance: ICliOutput = new CliOutputImpl()
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the current CLI output instance
|
|
57
|
+
*/
|
|
58
|
+
export function getCliOutput(): ICliOutput {
|
|
59
|
+
return cliOutputInstance
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Set a custom CLI output instance (useful for testing)
|
|
64
|
+
*/
|
|
65
|
+
export function setCliOutput(output: ICliOutput): void {
|
|
66
|
+
cliOutputInstance = output
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Reset CLI output to the default implementation
|
|
71
|
+
*/
|
|
72
|
+
export function resetCliOutput(): void {
|
|
73
|
+
cliOutputInstance = new CliOutputImpl()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Default CLI output instance for convenience
|
|
78
|
+
*/
|
|
79
|
+
export const cliOutput: ICliOutput = {
|
|
80
|
+
print: (...args: unknown[]) => cliOutputInstance.print(...args),
|
|
81
|
+
error: (...args: unknown[]) => cliOutputInstance.error(...args),
|
|
82
|
+
warn: (...args: unknown[]) => cliOutputInstance.warn(...args),
|
|
83
|
+
info: (...args: unknown[]) => cliOutputInstance.info(...args),
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Create a mock CLI output for testing
|
|
88
|
+
* Returns the mock and arrays of captured output
|
|
89
|
+
*/
|
|
90
|
+
export function createMockCliOutput(): {
|
|
91
|
+
mock: ICliOutput
|
|
92
|
+
prints: unknown[][]
|
|
93
|
+
errors: unknown[][]
|
|
94
|
+
warns: unknown[][]
|
|
95
|
+
infos: unknown[][]
|
|
96
|
+
clear: () => void
|
|
97
|
+
} {
|
|
98
|
+
const prints: unknown[][] = []
|
|
99
|
+
const errors: unknown[][] = []
|
|
100
|
+
const warns: unknown[][] = []
|
|
101
|
+
const infos: unknown[][] = []
|
|
102
|
+
|
|
103
|
+
const mock: ICliOutput = {
|
|
104
|
+
print: (...args: unknown[]) => prints.push(args),
|
|
105
|
+
error: (...args: unknown[]) => errors.push(args),
|
|
106
|
+
warn: (...args: unknown[]) => warns.push(args),
|
|
107
|
+
info: (...args: unknown[]) => infos.push(args),
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const clear = () => {
|
|
111
|
+
prints.length = 0
|
|
112
|
+
errors.length = 0
|
|
113
|
+
warns.length = 0
|
|
114
|
+
infos.length = 0
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return { mock, prints, errors, warns, infos, clear }
|
|
118
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Helpers
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for CLI command initialization and common patterns.
|
|
5
|
+
* Reduces code duplication across check, update, and other commands.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { PackageFilterConfig, TranslationKey } from '@pcu/utils'
|
|
9
|
+
import { ConfigLoader, Logger, logger, t } from '@pcu/utils'
|
|
10
|
+
import { type OutputFormat, OutputFormatter } from '../formatters/outputFormatter.js'
|
|
11
|
+
import { StyledText, ThemeManager } from '../themes/colorTheme.js'
|
|
12
|
+
import { cliOutput } from './cliOutput.js'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Common command options shared across multiple commands
|
|
16
|
+
*/
|
|
17
|
+
export interface CommonCommandOptions {
|
|
18
|
+
workspace?: string
|
|
19
|
+
format?: OutputFormat
|
|
20
|
+
color?: boolean
|
|
21
|
+
verbose?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Command context created during initialization
|
|
26
|
+
*/
|
|
27
|
+
export interface CommandContext {
|
|
28
|
+
config: PackageFilterConfig
|
|
29
|
+
formatter: OutputFormatter
|
|
30
|
+
workspacePath: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Command initialization options
|
|
35
|
+
*/
|
|
36
|
+
export interface InitOptions {
|
|
37
|
+
/** Theme to use (default: 'default') */
|
|
38
|
+
theme?: 'default' | 'minimal' | 'neon' | 'modern'
|
|
39
|
+
/** Whether to show verbose initialization info */
|
|
40
|
+
showVerboseInfo?: boolean
|
|
41
|
+
/** Additional info to show in verbose mode */
|
|
42
|
+
verboseInfo?: Record<string, string | undefined>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Initialize theme for a command
|
|
47
|
+
* Common pattern used in: checkCommand, updateCommand, securityCommand, etc.
|
|
48
|
+
*/
|
|
49
|
+
export function initializeTheme(
|
|
50
|
+
theme: 'default' | 'minimal' | 'neon' | 'modern' = 'default'
|
|
51
|
+
): void {
|
|
52
|
+
ThemeManager.setTheme(theme)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Load and merge configuration with CLI options
|
|
57
|
+
* Common pattern used in: checkCommand, updateCommand, watchCommand
|
|
58
|
+
*/
|
|
59
|
+
export async function loadConfiguration(workspacePath?: string): Promise<PackageFilterConfig> {
|
|
60
|
+
const effectivePath = workspacePath || process.cwd()
|
|
61
|
+
return ConfigLoader.loadConfig(effectivePath)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Create an output formatter with common configuration
|
|
66
|
+
* Common pattern used in: checkCommand, updateCommand, analyzeCommand, workspaceCommand
|
|
67
|
+
*/
|
|
68
|
+
export function createFormatter(
|
|
69
|
+
format: OutputFormat | undefined,
|
|
70
|
+
config: PackageFilterConfig,
|
|
71
|
+
colorEnabled: boolean = true
|
|
72
|
+
): OutputFormatter {
|
|
73
|
+
const effectiveFormat = format || config.defaults?.format || 'table'
|
|
74
|
+
return new OutputFormatter(effectiveFormat as OutputFormat, colorEnabled)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Initialize a command with common setup
|
|
79
|
+
* Combines theme initialization, config loading, and formatter creation
|
|
80
|
+
*/
|
|
81
|
+
export async function initializeCommand(
|
|
82
|
+
options: CommonCommandOptions,
|
|
83
|
+
initOptions: InitOptions = {}
|
|
84
|
+
): Promise<CommandContext> {
|
|
85
|
+
// Initialize theme
|
|
86
|
+
initializeTheme(initOptions.theme)
|
|
87
|
+
|
|
88
|
+
// Set logger to debug level when verbose mode is enabled
|
|
89
|
+
if (options.verbose) {
|
|
90
|
+
Logger.setGlobalLevel('debug')
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Show verbose initialization info
|
|
94
|
+
if (initOptions.showVerboseInfo && options.verbose) {
|
|
95
|
+
showVerboseInfo(options, initOptions.verboseInfo)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Load configuration
|
|
99
|
+
const workspacePath = options.workspace || process.cwd()
|
|
100
|
+
const config = await loadConfiguration(workspacePath)
|
|
101
|
+
|
|
102
|
+
// Create formatter
|
|
103
|
+
const formatter = createFormatter(options.format, config, options.color !== false)
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
config,
|
|
107
|
+
formatter,
|
|
108
|
+
workspacePath,
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Show verbose initialization information
|
|
114
|
+
* QUAL-012: Use unified output helpers (cliOutput, StyledText)
|
|
115
|
+
*/
|
|
116
|
+
function showVerboseInfo(
|
|
117
|
+
options: CommonCommandOptions,
|
|
118
|
+
additionalInfo?: Record<string, string | undefined>
|
|
119
|
+
): void {
|
|
120
|
+
cliOutput.print(StyledText.iconAnalysis(t('info.checkingUpdates')))
|
|
121
|
+
cliOutput.print(
|
|
122
|
+
StyledText.muted(`${t('command.workspace.title')}: ${options.workspace || process.cwd()}`)
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if (additionalInfo) {
|
|
126
|
+
for (const [key, value] of Object.entries(additionalInfo)) {
|
|
127
|
+
if (value !== undefined) {
|
|
128
|
+
cliOutput.print(StyledText.muted(`${key}: ${value}`))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
cliOutput.print('')
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Error handling options for commands
|
|
138
|
+
* QUAL-007: Unified error handling configuration
|
|
139
|
+
*/
|
|
140
|
+
export interface ErrorHandlingOptions {
|
|
141
|
+
/** Whether to show verbose information (stack trace) */
|
|
142
|
+
verbose?: boolean
|
|
143
|
+
/** Progress bar to stop/fail on error */
|
|
144
|
+
progressBar?: { stop: () => void; fail: (msg: string) => void }
|
|
145
|
+
/** Custom error message for logging */
|
|
146
|
+
errorMessage?: string
|
|
147
|
+
/** Additional context for logging */
|
|
148
|
+
context?: Record<string, unknown>
|
|
149
|
+
/** Custom i18n key for failed progress message */
|
|
150
|
+
failedProgressKey?: string
|
|
151
|
+
/** Custom i18n key for error display */
|
|
152
|
+
errorDisplayKey?: string
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check if error is a user cancellation (e.g., Ctrl+C)
|
|
157
|
+
*/
|
|
158
|
+
export function isUserCancellation(error: unknown): boolean {
|
|
159
|
+
return (
|
|
160
|
+
error instanceof Error &&
|
|
161
|
+
(error.name === 'ExitPromptError' || error.message.includes('force closed'))
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Handle command error with consistent logging
|
|
167
|
+
* QUAL-007: Unified error handling pattern for all commands
|
|
168
|
+
*
|
|
169
|
+
* @returns true if error was handled as user cancellation (command should return gracefully)
|
|
170
|
+
*/
|
|
171
|
+
export function handleCommandError(
|
|
172
|
+
error: Error | unknown,
|
|
173
|
+
options: ErrorHandlingOptions = {}
|
|
174
|
+
): boolean {
|
|
175
|
+
const {
|
|
176
|
+
verbose = false,
|
|
177
|
+
progressBar,
|
|
178
|
+
errorMessage = 'Command failed',
|
|
179
|
+
context,
|
|
180
|
+
failedProgressKey = 'progress.operationFailed',
|
|
181
|
+
errorDisplayKey,
|
|
182
|
+
} = options
|
|
183
|
+
|
|
184
|
+
// Handle user cancellation gracefully (Ctrl+C)
|
|
185
|
+
if (isUserCancellation(error)) {
|
|
186
|
+
progressBar?.stop()
|
|
187
|
+
cliOutput.print(StyledText.iconWarning(t('cli.cancelled')))
|
|
188
|
+
return true
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Log error with context
|
|
192
|
+
logger.error(errorMessage, error instanceof Error ? error : undefined, context)
|
|
193
|
+
|
|
194
|
+
// Fail progress bar if provided
|
|
195
|
+
if (progressBar) {
|
|
196
|
+
progressBar.fail(t(failedProgressKey as TranslationKey))
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Display error to user
|
|
200
|
+
const displayKey = errorDisplayKey || 'cli.error'
|
|
201
|
+
cliOutput.error(StyledText.iconError(t(displayKey as TranslationKey)))
|
|
202
|
+
cliOutput.error(StyledText.error(String(error)))
|
|
203
|
+
|
|
204
|
+
// Show stack trace in verbose mode
|
|
205
|
+
if (verbose && error instanceof Error) {
|
|
206
|
+
cliOutput.error(StyledText.muted(t('common.stackTrace')))
|
|
207
|
+
cliOutput.error(StyledText.muted(error.stack || t('common.noStackTrace')))
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return false
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Merge CLI options with config defaults
|
|
215
|
+
* Returns the effective value prioritizing CLI > config > fallback
|
|
216
|
+
*/
|
|
217
|
+
export function mergeWithConfig<T>(
|
|
218
|
+
cliValue: T | undefined,
|
|
219
|
+
configValue: T | undefined,
|
|
220
|
+
fallback: T
|
|
221
|
+
): T {
|
|
222
|
+
return cliValue ?? configValue ?? fallback
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Get effective target from options and config
|
|
227
|
+
*/
|
|
228
|
+
export function getEffectiveTarget(
|
|
229
|
+
optionTarget: string | undefined,
|
|
230
|
+
configTarget: string | undefined
|
|
231
|
+
): 'latest' | 'greatest' | 'minor' | 'patch' | 'newest' {
|
|
232
|
+
return (optionTarget || configTarget || 'latest') as
|
|
233
|
+
| 'latest'
|
|
234
|
+
| 'greatest'
|
|
235
|
+
| 'minor'
|
|
236
|
+
| 'patch'
|
|
237
|
+
| 'newest'
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get effective include/exclude patterns
|
|
242
|
+
* CLI options take priority over config file
|
|
243
|
+
*/
|
|
244
|
+
export function getEffectivePatterns(
|
|
245
|
+
cliPatterns: string[] | undefined,
|
|
246
|
+
configPatterns: string[] | undefined
|
|
247
|
+
): string[] | undefined {
|
|
248
|
+
return cliPatterns?.length ? cliPatterns : configPatterns
|
|
249
|
+
}
|