pnpm-catalog-updates 1.0.3 → 1.1.2
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
|
@@ -5,10 +5,26 @@
|
|
|
5
5
|
* Provides detailed information about available updates.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
import type {
|
|
9
|
+
CatalogUpdateInfo,
|
|
10
|
+
CatalogUpdateService,
|
|
11
|
+
CheckOptions,
|
|
12
|
+
OutdatedDependencyInfo,
|
|
13
|
+
OutdatedReport,
|
|
14
|
+
} from '@pcu/core'
|
|
15
|
+
import { countUpdateTypesFromCatalogs } from '@pcu/core'
|
|
16
|
+
import { CommandExitError, t } from '@pcu/utils'
|
|
17
|
+
import type { OutputFormat } from '../formatters/outputFormatter.js'
|
|
11
18
|
import { StyledText, ThemeManager } from '../themes/colorTheme.js'
|
|
19
|
+
import { cliOutput } from '../utils/cliOutput.js'
|
|
20
|
+
import {
|
|
21
|
+
getEffectivePatterns,
|
|
22
|
+
getEffectiveTarget,
|
|
23
|
+
handleCommandError,
|
|
24
|
+
initializeCommand,
|
|
25
|
+
mergeWithConfig,
|
|
26
|
+
} from '../utils/commandHelpers.js'
|
|
27
|
+
import { errorsOnly, validateCheckOptions } from '../validators/index.js'
|
|
12
28
|
|
|
13
29
|
export interface CheckCommandOptions {
|
|
14
30
|
workspace?: string
|
|
@@ -20,6 +36,9 @@ export interface CheckCommandOptions {
|
|
|
20
36
|
exclude?: string[]
|
|
21
37
|
verbose?: boolean
|
|
22
38
|
color?: boolean
|
|
39
|
+
exitCode?: boolean
|
|
40
|
+
/** Skip security vulnerability checks */
|
|
41
|
+
noSecurity?: boolean
|
|
23
42
|
}
|
|
24
43
|
|
|
25
44
|
export class CheckCommand {
|
|
@@ -30,45 +49,30 @@ export class CheckCommand {
|
|
|
30
49
|
*/
|
|
31
50
|
async execute(options: CheckCommandOptions = {}): Promise<void> {
|
|
32
51
|
try {
|
|
33
|
-
// Initialize theme
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
console.log(StyledText.muted(`Target: ${options.target}`))
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
console.log('')
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Load configuration file first
|
|
52
|
-
const config = ConfigLoader.loadConfig(options.workspace || process.cwd())
|
|
53
|
-
|
|
54
|
-
// Use format from CLI options first, then config file, then default
|
|
55
|
-
const effectiveFormat = options.format || config.defaults?.format || 'table'
|
|
56
|
-
|
|
57
|
-
// Create output formatter with effective format
|
|
58
|
-
const formatter = new OutputFormatter(
|
|
59
|
-
effectiveFormat as OutputFormat,
|
|
60
|
-
options.color !== false
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
// Merge CLI options with configuration file settings
|
|
52
|
+
// Initialize command with shared helper (theme, config, formatter)
|
|
53
|
+
const { config, formatter } = await initializeCommand(options, {
|
|
54
|
+
showVerboseInfo: true,
|
|
55
|
+
verboseInfo: {
|
|
56
|
+
[t('command.check.catalogLabel', { catalog: '' }).replace(': ', '')]:
|
|
57
|
+
options.catalog || undefined,
|
|
58
|
+
[t('command.check.targetLabel', { target: '' }).replace(': ', '')]:
|
|
59
|
+
options.target && options.target !== 'latest' ? options.target : undefined,
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// Build check options using shared helpers
|
|
64
64
|
const checkOptions: CheckOptions = {
|
|
65
65
|
workspacePath: options.workspace,
|
|
66
66
|
catalogName: options.catalog,
|
|
67
|
-
target: options.target
|
|
68
|
-
includePrerelease:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
target: getEffectiveTarget(options.target, config.defaults?.target),
|
|
68
|
+
includePrerelease: mergeWithConfig(
|
|
69
|
+
options.prerelease,
|
|
70
|
+
config.defaults?.includePrerelease,
|
|
71
|
+
false
|
|
72
|
+
),
|
|
73
|
+
include: getEffectivePatterns(options.include, config.include),
|
|
74
|
+
exclude: getEffectivePatterns(options.exclude, config.exclude),
|
|
75
|
+
noSecurity: options.noSecurity,
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
// Execute check
|
|
@@ -76,117 +80,106 @@ export class CheckCommand {
|
|
|
76
80
|
|
|
77
81
|
// Format and display results
|
|
78
82
|
const formattedOutput = formatter.formatOutdatedReport(report)
|
|
79
|
-
|
|
83
|
+
cliOutput.print(formattedOutput)
|
|
80
84
|
|
|
81
85
|
// Show summary
|
|
82
86
|
if (options.verbose || options.format === 'table') {
|
|
83
87
|
this.showSummary(report, options)
|
|
84
88
|
}
|
|
85
89
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.error(StyledText.iconError('Error checking dependencies:'))
|
|
91
|
-
console.error(StyledText.error(String(error)))
|
|
90
|
+
// Exit with code 1 if --exit-code is set and updates are available (for CI/CD)
|
|
91
|
+
if (options.exitCode && report.hasUpdates) {
|
|
92
|
+
throw CommandExitError.failure('Updates available')
|
|
93
|
+
}
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
// Otherwise exit with 0 since this is just a check command
|
|
96
|
+
throw CommandExitError.success()
|
|
97
|
+
} catch (error) {
|
|
98
|
+
// Re-throw CommandExitError as-is (success or controlled exit)
|
|
99
|
+
if (error instanceof CommandExitError) {
|
|
100
|
+
throw error
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
|
|
103
|
+
// QUAL-007: Use unified error handling
|
|
104
|
+
handleCommandError(error, {
|
|
105
|
+
verbose: options.verbose,
|
|
106
|
+
errorMessage: 'Check dependencies failed',
|
|
107
|
+
context: { options },
|
|
108
|
+
errorDisplayKey: 'command.check.errorChecking',
|
|
109
|
+
})
|
|
110
|
+
throw CommandExitError.failure('Check command failed')
|
|
99
111
|
}
|
|
100
112
|
}
|
|
101
113
|
|
|
102
114
|
/**
|
|
103
115
|
* Show command summary
|
|
104
116
|
*/
|
|
105
|
-
private showSummary(report:
|
|
117
|
+
private showSummary(report: OutdatedReport, _options: CheckCommandOptions): void {
|
|
106
118
|
const lines: string[] = []
|
|
107
119
|
const theme = ThemeManager.getTheme()
|
|
108
120
|
|
|
109
121
|
if (!report.hasUpdates) {
|
|
110
|
-
lines.push(StyledText.iconSuccess('
|
|
122
|
+
lines.push(StyledText.iconSuccess(t('info.noUpdatesFound')))
|
|
111
123
|
} else {
|
|
112
|
-
lines.push(StyledText.iconInfo('
|
|
113
|
-
lines.push(` • ${report.totalOutdated}
|
|
114
|
-
lines.push(` • ${report.catalogs.length}
|
|
124
|
+
lines.push(StyledText.iconInfo(`${t('command.check.summary')}:`))
|
|
125
|
+
lines.push(` • ${t('info.foundOutdated', { count: report.totalOutdated })}`)
|
|
126
|
+
lines.push(` • ${t('command.check.catalogsChecked', { count: report.catalogs.length })}`)
|
|
115
127
|
|
|
116
128
|
const totalPackages = report.catalogs.reduce(
|
|
117
|
-
(sum: number, cat:
|
|
129
|
+
(sum: number, cat: CatalogUpdateInfo) => sum + cat.totalPackages,
|
|
118
130
|
0
|
|
119
131
|
)
|
|
120
|
-
lines.push(` • ${
|
|
132
|
+
lines.push(` • ${t('command.check.totalCatalogEntries', { count: totalPackages })}`)
|
|
121
133
|
|
|
122
134
|
// Show breakdown by update type
|
|
123
|
-
const updateTypes =
|
|
124
|
-
|
|
125
|
-
for (const catalog of report.catalogs) {
|
|
126
|
-
for (const dep of catalog.outdatedDependencies) {
|
|
127
|
-
updateTypes[dep.updateType as keyof typeof updateTypes]++
|
|
128
|
-
}
|
|
129
|
-
}
|
|
135
|
+
const updateTypes = countUpdateTypesFromCatalogs(report.catalogs)
|
|
130
136
|
|
|
131
137
|
if (updateTypes.major > 0) {
|
|
132
|
-
lines.push(
|
|
138
|
+
lines.push(
|
|
139
|
+
theme.major(` • ${t('command.check.majorUpdates', { count: updateTypes.major })}`)
|
|
140
|
+
)
|
|
133
141
|
}
|
|
134
142
|
if (updateTypes.minor > 0) {
|
|
135
|
-
lines.push(
|
|
143
|
+
lines.push(
|
|
144
|
+
theme.minor(` • ${t('command.check.minorUpdates', { count: updateTypes.minor })}`)
|
|
145
|
+
)
|
|
136
146
|
}
|
|
137
147
|
if (updateTypes.patch > 0) {
|
|
138
|
-
lines.push(
|
|
148
|
+
lines.push(
|
|
149
|
+
theme.patch(` • ${t('command.check.patchUpdates', { count: updateTypes.patch })}`)
|
|
150
|
+
)
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
// Security updates
|
|
142
|
-
const securityUpdates = report.catalogs.reduce((sum: number, cat:
|
|
143
|
-
return
|
|
154
|
+
const securityUpdates = report.catalogs.reduce((sum: number, cat: CatalogUpdateInfo) => {
|
|
155
|
+
return (
|
|
156
|
+
sum +
|
|
157
|
+
cat.outdatedDependencies.filter((dep: OutdatedDependencyInfo) => dep.isSecurityUpdate)
|
|
158
|
+
.length
|
|
159
|
+
)
|
|
144
160
|
}, 0)
|
|
145
161
|
|
|
146
162
|
if (securityUpdates > 0) {
|
|
147
|
-
lines.push(StyledText.iconSecurity(
|
|
163
|
+
lines.push(StyledText.iconSecurity(t('info.securityUpdates', { count: securityUpdates })))
|
|
148
164
|
}
|
|
149
165
|
|
|
150
166
|
lines.push('')
|
|
151
|
-
lines.push(StyledText.iconUpdate('
|
|
167
|
+
lines.push(StyledText.iconUpdate(t('info.runWithUpdate')))
|
|
152
168
|
|
|
153
169
|
if (updateTypes.major > 0) {
|
|
154
|
-
lines.push(StyledText.iconWarning('
|
|
170
|
+
lines.push(StyledText.iconWarning(t('info.majorWarning')))
|
|
155
171
|
}
|
|
156
172
|
}
|
|
157
173
|
|
|
158
|
-
|
|
174
|
+
cliOutput.print(lines.join('\n'))
|
|
159
175
|
}
|
|
160
176
|
|
|
161
177
|
/**
|
|
162
178
|
* Validate command options
|
|
179
|
+
* QUAL-002: Uses unified validator from validators/
|
|
163
180
|
*/
|
|
164
181
|
static validateOptions(options: CheckCommandOptions): string[] {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
// Validate format
|
|
168
|
-
if (options.format && !['table', 'json', 'yaml', 'minimal'].includes(options.format)) {
|
|
169
|
-
errors.push('Invalid format. Must be one of: table, json, yaml, minimal')
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Validate target
|
|
173
|
-
if (
|
|
174
|
-
options.target &&
|
|
175
|
-
!['latest', 'greatest', 'minor', 'patch', 'newest'].includes(options.target)
|
|
176
|
-
) {
|
|
177
|
-
errors.push('Invalid target. Must be one of: latest, greatest, minor, patch, newest')
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Validate include/exclude patterns
|
|
181
|
-
if (options.include?.some((pattern) => !pattern.trim())) {
|
|
182
|
-
errors.push('Include patterns cannot be empty')
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (options.exclude?.some((pattern) => !pattern.trim())) {
|
|
186
|
-
errors.push('Exclude patterns cannot be empty')
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return errors
|
|
182
|
+
return errorsOnly(validateCheckOptions)(options)
|
|
190
183
|
}
|
|
191
184
|
|
|
192
185
|
/**
|