pnpm-catalog-updates 0.5.6 → 0.6.5
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/bin/pcu.js +1 -1
- package/dist/index.js +9559 -32
- package/dist/index.js.map +1 -1
- package/package.json +61 -103
- package/src/cli/commands/checkCommand.ts +227 -0
- package/src/cli/commands/initCommand.ts +394 -0
- package/src/cli/commands/securityCommand.ts +569 -0
- package/src/cli/commands/updateCommand.ts +245 -0
- package/src/cli/formatters/outputFormatter.ts +830 -0
- package/src/cli/formatters/progressBar.ts +700 -0
- package/src/cli/index.ts +565 -0
- package/src/cli/interactive/interactivePrompts.ts +517 -0
- package/src/cli/options/globalOptions.ts +380 -0
- package/src/cli/options/index.ts +5 -0
- package/src/cli/themes/colorTheme.ts +379 -0
- package/src/cli/validators/commandValidator.ts +395 -0
- package/src/cli/validators/index.ts +5 -0
- package/src/index.ts +4 -0
- package/LICENSE +0 -21
- package/README.ja.md +0 -582
- package/README.md +0 -690
- package/README.zh-CN.md +0 -630
- package/dist/application/services/CatalogUpdateService.d.ts +0 -209
- package/dist/application/services/CatalogUpdateService.d.ts.map +0 -1
- package/dist/application/services/CatalogUpdateService.js +0 -836
- package/dist/application/services/CatalogUpdateService.js.map +0 -1
- package/dist/application/services/WorkspaceService.d.ts +0 -139
- package/dist/application/services/WorkspaceService.d.ts.map +0 -1
- package/dist/application/services/WorkspaceService.js +0 -340
- package/dist/application/services/WorkspaceService.js.map +0 -1
- package/dist/cli/commands/CheckCommand.d.ts +0 -40
- package/dist/cli/commands/CheckCommand.d.ts.map +0 -1
- package/dist/cli/commands/CheckCommand.js +0 -177
- package/dist/cli/commands/CheckCommand.js.map +0 -1
- package/dist/cli/commands/InitCommand.d.ts +0 -53
- package/dist/cli/commands/InitCommand.d.ts.map +0 -1
- package/dist/cli/commands/InitCommand.js +0 -338
- package/dist/cli/commands/InitCommand.js.map +0 -1
- package/dist/cli/commands/SecurityCommand.d.ts +0 -113
- package/dist/cli/commands/SecurityCommand.d.ts.map +0 -1
- package/dist/cli/commands/SecurityCommand.js +0 -410
- package/dist/cli/commands/SecurityCommand.js.map +0 -1
- package/dist/cli/commands/UpdateCommand.d.ts +0 -44
- package/dist/cli/commands/UpdateCommand.d.ts.map +0 -1
- package/dist/cli/commands/UpdateCommand.js +0 -189
- package/dist/cli/commands/UpdateCommand.js.map +0 -1
- package/dist/cli/formatters/OutputFormatter.d.ts +0 -116
- package/dist/cli/formatters/OutputFormatter.d.ts.map +0 -1
- package/dist/cli/formatters/OutputFormatter.js +0 -664
- package/dist/cli/formatters/OutputFormatter.js.map +0 -1
- package/dist/cli/formatters/ProgressBar.d.ts +0 -195
- package/dist/cli/formatters/ProgressBar.d.ts.map +0 -1
- package/dist/cli/formatters/ProgressBar.js +0 -622
- package/dist/cli/formatters/ProgressBar.js.map +0 -1
- package/dist/cli/index.d.ts +0 -12
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -492
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/interactive/InteractivePrompts.d.ts +0 -85
- package/dist/cli/interactive/InteractivePrompts.d.ts.map +0 -1
- package/dist/cli/interactive/InteractivePrompts.js +0 -434
- package/dist/cli/interactive/InteractivePrompts.js.map +0 -1
- package/dist/cli/options/GlobalOptions.d.ts +0 -117
- package/dist/cli/options/GlobalOptions.d.ts.map +0 -1
- package/dist/cli/options/GlobalOptions.js +0 -278
- package/dist/cli/options/GlobalOptions.js.map +0 -1
- package/dist/cli/options/index.d.ts +0 -5
- package/dist/cli/options/index.d.ts.map +0 -1
- package/dist/cli/options/index.js +0 -5
- package/dist/cli/options/index.js.map +0 -1
- package/dist/cli/themes/ColorTheme.d.ts +0 -211
- package/dist/cli/themes/ColorTheme.d.ts.map +0 -1
- package/dist/cli/themes/ColorTheme.js +0 -267
- package/dist/cli/themes/ColorTheme.js.map +0 -1
- package/dist/cli/validators/CommandValidator.d.ts +0 -60
- package/dist/cli/validators/CommandValidator.d.ts.map +0 -1
- package/dist/cli/validators/CommandValidator.js +0 -319
- package/dist/cli/validators/CommandValidator.js.map +0 -1
- package/dist/cli/validators/index.d.ts +0 -5
- package/dist/cli/validators/index.d.ts.map +0 -1
- package/dist/cli/validators/index.js +0 -5
- package/dist/cli/validators/index.js.map +0 -1
- package/dist/common/config/Config.d.ts +0 -142
- package/dist/common/config/Config.d.ts.map +0 -1
- package/dist/common/config/Config.js +0 -382
- package/dist/common/config/Config.js.map +0 -1
- package/dist/common/config/ConfigLoader.d.ts +0 -49
- package/dist/common/config/ConfigLoader.d.ts.map +0 -1
- package/dist/common/config/ConfigLoader.js +0 -180
- package/dist/common/config/ConfigLoader.js.map +0 -1
- package/dist/common/config/PackageFilterConfig.d.ts +0 -56
- package/dist/common/config/PackageFilterConfig.d.ts.map +0 -1
- package/dist/common/config/PackageFilterConfig.js +0 -94
- package/dist/common/config/PackageFilterConfig.js.map +0 -1
- package/dist/common/config/index.d.ts +0 -8
- package/dist/common/config/index.d.ts.map +0 -1
- package/dist/common/config/index.js +0 -8
- package/dist/common/config/index.js.map +0 -1
- package/dist/common/error-handling/ErrorTracker.d.ts +0 -48
- package/dist/common/error-handling/ErrorTracker.d.ts.map +0 -1
- package/dist/common/error-handling/ErrorTracker.js +0 -93
- package/dist/common/error-handling/ErrorTracker.js.map +0 -1
- package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts +0 -74
- package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts.map +0 -1
- package/dist/common/error-handling/UserFriendlyErrorHandler.js +0 -703
- package/dist/common/error-handling/UserFriendlyErrorHandler.js.map +0 -1
- package/dist/common/error-handling/index.d.ts +0 -11
- package/dist/common/error-handling/index.d.ts.map +0 -1
- package/dist/common/error-handling/index.js +0 -9
- package/dist/common/error-handling/index.js.map +0 -1
- package/dist/common/logger/Logger.d.ts +0 -110
- package/dist/common/logger/Logger.d.ts.map +0 -1
- package/dist/common/logger/Logger.js +0 -289
- package/dist/common/logger/Logger.js.map +0 -1
- package/dist/common/logger/index.d.ts +0 -6
- package/dist/common/logger/index.d.ts.map +0 -1
- package/dist/common/logger/index.js +0 -6
- package/dist/common/logger/index.js.map +0 -1
- package/dist/common/types/cli.d.ts +0 -265
- package/dist/common/types/cli.d.ts.map +0 -1
- package/dist/common/types/cli.js +0 -5
- package/dist/common/types/cli.js.map +0 -1
- package/dist/common/types/core.d.ts +0 -270
- package/dist/common/types/core.d.ts.map +0 -1
- package/dist/common/types/core.js +0 -32
- package/dist/common/types/core.js.map +0 -1
- package/dist/common/types/index.d.ts +0 -8
- package/dist/common/types/index.d.ts.map +0 -1
- package/dist/common/types/index.js +0 -8
- package/dist/common/types/index.js.map +0 -1
- package/dist/common/utils/VersionChecker.d.ts +0 -54
- package/dist/common/utils/VersionChecker.d.ts.map +0 -1
- package/dist/common/utils/VersionChecker.js +0 -180
- package/dist/common/utils/VersionChecker.js.map +0 -1
- package/dist/common/utils/async.d.ts +0 -74
- package/dist/common/utils/async.d.ts.map +0 -1
- package/dist/common/utils/async.js +0 -228
- package/dist/common/utils/async.js.map +0 -1
- package/dist/common/utils/format.d.ts +0 -32
- package/dist/common/utils/format.d.ts.map +0 -1
- package/dist/common/utils/format.js +0 -121
- package/dist/common/utils/format.js.map +0 -1
- package/dist/common/utils/git.d.ts +0 -44
- package/dist/common/utils/git.d.ts.map +0 -1
- package/dist/common/utils/git.js +0 -147
- package/dist/common/utils/git.js.map +0 -1
- package/dist/common/utils/index.d.ts +0 -12
- package/dist/common/utils/index.d.ts.map +0 -1
- package/dist/common/utils/index.js +0 -12
- package/dist/common/utils/index.js.map +0 -1
- package/dist/common/utils/string.d.ts +0 -56
- package/dist/common/utils/string.d.ts.map +0 -1
- package/dist/common/utils/string.js +0 -134
- package/dist/common/utils/string.js.map +0 -1
- package/dist/common/utils/validation.d.ts +0 -88
- package/dist/common/utils/validation.d.ts.map +0 -1
- package/dist/common/utils/validation.js +0 -308
- package/dist/common/utils/validation.js.map +0 -1
- package/dist/domain/entities/Catalog.d.ts +0 -117
- package/dist/domain/entities/Catalog.d.ts.map +0 -1
- package/dist/domain/entities/Catalog.js +0 -240
- package/dist/domain/entities/Catalog.js.map +0 -1
- package/dist/domain/entities/Package.d.ts +0 -143
- package/dist/domain/entities/Package.d.ts.map +0 -1
- package/dist/domain/entities/Package.js +0 -272
- package/dist/domain/entities/Package.js.map +0 -1
- package/dist/domain/entities/Workspace.d.ts +0 -95
- package/dist/domain/entities/Workspace.d.ts.map +0 -1
- package/dist/domain/entities/Workspace.js +0 -173
- package/dist/domain/entities/Workspace.js.map +0 -1
- package/dist/domain/repositories/WorkspaceRepository.d.ts +0 -41
- package/dist/domain/repositories/WorkspaceRepository.d.ts.map +0 -1
- package/dist/domain/repositories/WorkspaceRepository.js +0 -8
- package/dist/domain/repositories/WorkspaceRepository.js.map +0 -1
- package/dist/domain/value-objects/CatalogCollection.d.ts +0 -106
- package/dist/domain/value-objects/CatalogCollection.d.ts.map +0 -1
- package/dist/domain/value-objects/CatalogCollection.js +0 -230
- package/dist/domain/value-objects/CatalogCollection.js.map +0 -1
- package/dist/domain/value-objects/PackageCollection.d.ts +0 -122
- package/dist/domain/value-objects/PackageCollection.d.ts.map +0 -1
- package/dist/domain/value-objects/PackageCollection.js +0 -263
- package/dist/domain/value-objects/PackageCollection.js.map +0 -1
- package/dist/domain/value-objects/Version.d.ts +0 -141
- package/dist/domain/value-objects/Version.d.ts.map +0 -1
- package/dist/domain/value-objects/Version.js +0 -268
- package/dist/domain/value-objects/Version.js.map +0 -1
- package/dist/domain/value-objects/WorkspaceConfig.d.ts +0 -144
- package/dist/domain/value-objects/WorkspaceConfig.d.ts.map +0 -1
- package/dist/domain/value-objects/WorkspaceConfig.js +0 -357
- package/dist/domain/value-objects/WorkspaceConfig.js.map +0 -1
- package/dist/domain/value-objects/WorkspaceId.d.ts +0 -51
- package/dist/domain/value-objects/WorkspaceId.d.ts.map +0 -1
- package/dist/domain/value-objects/WorkspaceId.js +0 -104
- package/dist/domain/value-objects/WorkspaceId.js.map +0 -1
- package/dist/domain/value-objects/WorkspacePath.d.ts +0 -75
- package/dist/domain/value-objects/WorkspacePath.d.ts.map +0 -1
- package/dist/domain/value-objects/WorkspacePath.js +0 -128
- package/dist/domain/value-objects/WorkspacePath.js.map +0 -1
- package/dist/index.d.ts +0 -25
- package/dist/index.d.ts.map +0 -1
- package/dist/infrastructure/cache/Cache.d.ts +0 -161
- package/dist/infrastructure/cache/Cache.d.ts.map +0 -1
- package/dist/infrastructure/cache/Cache.js +0 -398
- package/dist/infrastructure/cache/Cache.js.map +0 -1
- package/dist/infrastructure/cache/index.d.ts +0 -6
- package/dist/infrastructure/cache/index.d.ts.map +0 -1
- package/dist/infrastructure/cache/index.js +0 -6
- package/dist/infrastructure/cache/index.js.map +0 -1
- package/dist/infrastructure/external-services/NpmRegistryService.d.ts +0 -145
- package/dist/infrastructure/external-services/NpmRegistryService.d.ts.map +0 -1
- package/dist/infrastructure/external-services/NpmRegistryService.js +0 -466
- package/dist/infrastructure/external-services/NpmRegistryService.js.map +0 -1
- package/dist/infrastructure/file-system/FileSystemService.d.ts +0 -120
- package/dist/infrastructure/file-system/FileSystemService.d.ts.map +0 -1
- package/dist/infrastructure/file-system/FileSystemService.js +0 -663
- package/dist/infrastructure/file-system/FileSystemService.js.map +0 -1
- package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts +0 -57
- package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts.map +0 -1
- package/dist/infrastructure/repositories/FileWorkspaceRepository.js +0 -179
- package/dist/infrastructure/repositories/FileWorkspaceRepository.js.map +0 -1
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* pnpm-catalog-updates CLI Entry Point
|
|
5
|
+
*
|
|
6
|
+
* A CLI tool for checking and updating pnpm workspace catalog dependencies.
|
|
7
|
+
* This is the main entry point that handles command parsing and execution.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { dirname, join } from 'path';
|
|
11
|
+
import { OutputFormat, OutputFormatter } from './formatters/outputFormatter.js';
|
|
12
|
+
|
|
13
|
+
// Services and Dependencies
|
|
14
|
+
import {
|
|
15
|
+
CatalogUpdateService,
|
|
16
|
+
WorkspaceService,
|
|
17
|
+
NpmRegistryService,
|
|
18
|
+
FileSystemService,
|
|
19
|
+
FileWorkspaceRepository,
|
|
20
|
+
} from '@pcu/core';
|
|
21
|
+
// CLI Commands
|
|
22
|
+
import chalk from 'chalk';
|
|
23
|
+
import { Command } from 'commander';
|
|
24
|
+
import { readFileSync } from 'fs';
|
|
25
|
+
import { fileURLToPath } from 'url';
|
|
26
|
+
import { CheckCommand } from './commands/checkCommand.js';
|
|
27
|
+
import { UpdateCommand } from './commands/updateCommand.js';
|
|
28
|
+
import { SecurityCommand } from './commands/securityCommand.js';
|
|
29
|
+
import { InitCommand } from './commands/initCommand.js';
|
|
30
|
+
import { InteractivePrompts } from './interactive/interactivePrompts.js';
|
|
31
|
+
import { ThemeManager, StyledText } from './themes/colorTheme.js';
|
|
32
|
+
import { VersionChecker, ConfigLoader } from '@pcu/utils';
|
|
33
|
+
|
|
34
|
+
// Get package.json for version info
|
|
35
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
36
|
+
const __dirname = dirname(__filename);
|
|
37
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create service dependencies with configuration support
|
|
41
|
+
*/
|
|
42
|
+
function createServices(workspacePath?: string) {
|
|
43
|
+
const fileSystemService = new FileSystemService();
|
|
44
|
+
const workspaceRepository = new FileWorkspaceRepository(fileSystemService);
|
|
45
|
+
// Use factory method to create CatalogUpdateService with configuration
|
|
46
|
+
const catalogUpdateService = CatalogUpdateService.createWithConfig(
|
|
47
|
+
workspaceRepository,
|
|
48
|
+
workspacePath
|
|
49
|
+
);
|
|
50
|
+
const workspaceService = new WorkspaceService(workspaceRepository);
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
fileSystemService,
|
|
54
|
+
workspaceRepository,
|
|
55
|
+
catalogUpdateService,
|
|
56
|
+
workspaceService,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Main CLI function
|
|
62
|
+
*/
|
|
63
|
+
export async function main(): Promise<void> {
|
|
64
|
+
const program = new Command();
|
|
65
|
+
|
|
66
|
+
// Parse arguments first to get workspace path
|
|
67
|
+
let workspacePath: string | undefined;
|
|
68
|
+
|
|
69
|
+
// Extract workspace path from arguments for service creation
|
|
70
|
+
const workspaceIndex = process.argv.findIndex((arg) => arg === '-w' || arg === '--workspace');
|
|
71
|
+
if (workspaceIndex !== -1 && workspaceIndex + 1 < process.argv.length) {
|
|
72
|
+
workspacePath = process.argv[workspaceIndex + 1];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Load configuration to check if version updates are enabled
|
|
76
|
+
const config = ConfigLoader.loadConfig(workspacePath || process.cwd());
|
|
77
|
+
|
|
78
|
+
// Check for version updates (skip in CI environments or if disabled)
|
|
79
|
+
if (VersionChecker.shouldCheckForUpdates() && config.advanced?.checkForUpdates !== false) {
|
|
80
|
+
try {
|
|
81
|
+
const versionResult = await VersionChecker.checkVersion(packageJson.version, {
|
|
82
|
+
skipPrompt: false,
|
|
83
|
+
timeout: 3000, // Short timeout to not delay CLI startup
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (versionResult.shouldPrompt) {
|
|
87
|
+
const didUpdate = await VersionChecker.promptAndUpdate(versionResult);
|
|
88
|
+
if (didUpdate) {
|
|
89
|
+
// Exit after successful update to allow user to restart with new version
|
|
90
|
+
console.log(chalk.blue('Please run your command again to use the updated version.'));
|
|
91
|
+
process.exit(0);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
// Silently fail version check to not interrupt CLI usage (only show warning in verbose mode)
|
|
96
|
+
if (process.argv.includes('-v') || process.argv.includes('--verbose')) {
|
|
97
|
+
console.warn(chalk.yellow('⚠️ Could not check for updates:'), error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Create services with workspace path for configuration loading
|
|
103
|
+
const services = createServices(workspacePath);
|
|
104
|
+
|
|
105
|
+
// Configure the main command
|
|
106
|
+
program
|
|
107
|
+
.name('pcu')
|
|
108
|
+
.description('A CLI tool to check and update pnpm workspace catalog dependencies')
|
|
109
|
+
.option('--version', 'show version information')
|
|
110
|
+
.option('-v, --verbose', 'enable verbose logging')
|
|
111
|
+
.option('-w, --workspace <path>', 'workspace directory path')
|
|
112
|
+
.option('--no-color', 'disable colored output')
|
|
113
|
+
.option('-u, --update', 'shorthand for update command')
|
|
114
|
+
.option('-c, --check', 'shorthand for check command')
|
|
115
|
+
.option('-a, --analyze', 'shorthand for analyze command')
|
|
116
|
+
.option('-s, --workspace-info', 'shorthand for workspace command')
|
|
117
|
+
.option('-t, --theme', 'shorthand for theme command')
|
|
118
|
+
.option('--security-audit', 'shorthand for security command')
|
|
119
|
+
.option('--security-fix', 'shorthand for security --fix-vulns command');
|
|
120
|
+
|
|
121
|
+
// Check command
|
|
122
|
+
program
|
|
123
|
+
.command('check')
|
|
124
|
+
.alias('chk')
|
|
125
|
+
.description('check for outdated catalog dependencies')
|
|
126
|
+
.option('--catalog <name>', 'check specific catalog only')
|
|
127
|
+
.option('-f, --format <type>', 'output format: table, json, yaml, minimal', 'table')
|
|
128
|
+
.option(
|
|
129
|
+
'-t, --target <type>',
|
|
130
|
+
'update target: latest, greatest, minor, patch, newest',
|
|
131
|
+
'latest'
|
|
132
|
+
)
|
|
133
|
+
.option('--prerelease', 'include prerelease versions')
|
|
134
|
+
.option('--include <pattern>', 'include packages matching pattern', [])
|
|
135
|
+
.option('--exclude <pattern>', 'exclude packages matching pattern', [])
|
|
136
|
+
.action(async (options, command) => {
|
|
137
|
+
try {
|
|
138
|
+
const globalOptions = command.parent.opts();
|
|
139
|
+
const checkCommand = new CheckCommand(services.catalogUpdateService);
|
|
140
|
+
|
|
141
|
+
await checkCommand.execute({
|
|
142
|
+
workspace: globalOptions.workspace,
|
|
143
|
+
catalog: options.catalog,
|
|
144
|
+
format: options.format,
|
|
145
|
+
target: options.target,
|
|
146
|
+
prerelease: options.prerelease,
|
|
147
|
+
include: Array.isArray(options.include)
|
|
148
|
+
? options.include
|
|
149
|
+
: [options.include].filter(Boolean),
|
|
150
|
+
exclude: Array.isArray(options.exclude)
|
|
151
|
+
? options.exclude
|
|
152
|
+
: [options.exclude].filter(Boolean),
|
|
153
|
+
verbose: globalOptions.verbose,
|
|
154
|
+
color: !globalOptions.noColor,
|
|
155
|
+
});
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error(chalk.red('❌ Error:'), error);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Update command
|
|
163
|
+
program
|
|
164
|
+
.command('update')
|
|
165
|
+
.alias('u')
|
|
166
|
+
.description('update catalog dependencies')
|
|
167
|
+
.option('-i, --interactive', 'interactive mode to choose updates')
|
|
168
|
+
.option('-d, --dry-run', 'preview changes without writing files')
|
|
169
|
+
.option(
|
|
170
|
+
'-t, --target <type>',
|
|
171
|
+
'update target: latest, greatest, minor, patch, newest',
|
|
172
|
+
'latest'
|
|
173
|
+
)
|
|
174
|
+
.option('--catalog <name>', 'update specific catalog only')
|
|
175
|
+
.option('--include <pattern>', 'include packages matching pattern', [])
|
|
176
|
+
.option('--exclude <pattern>', 'exclude packages matching pattern', [])
|
|
177
|
+
.option('--force', 'force updates even if risky')
|
|
178
|
+
.option('--prerelease', 'include prerelease versions')
|
|
179
|
+
.option('-b, --create-backup', 'create backup files before updating')
|
|
180
|
+
.option('-f, --format <type>', 'output format: table, json, yaml, minimal', 'table')
|
|
181
|
+
.action(async (options, command) => {
|
|
182
|
+
try {
|
|
183
|
+
const globalOptions = command.parent.opts();
|
|
184
|
+
const updateCommand = new UpdateCommand(services.catalogUpdateService);
|
|
185
|
+
|
|
186
|
+
await updateCommand.execute({
|
|
187
|
+
workspace: globalOptions.workspace,
|
|
188
|
+
catalog: options.catalog,
|
|
189
|
+
format: options.format,
|
|
190
|
+
target: options.target,
|
|
191
|
+
interactive: options.interactive,
|
|
192
|
+
dryRun: options.dryRun,
|
|
193
|
+
force: options.force,
|
|
194
|
+
prerelease: options.prerelease,
|
|
195
|
+
include: Array.isArray(options.include)
|
|
196
|
+
? options.include
|
|
197
|
+
: [options.include].filter(Boolean),
|
|
198
|
+
exclude: Array.isArray(options.exclude)
|
|
199
|
+
? options.exclude
|
|
200
|
+
: [options.exclude].filter(Boolean),
|
|
201
|
+
createBackup: options.createBackup,
|
|
202
|
+
verbose: globalOptions.verbose,
|
|
203
|
+
color: !globalOptions.noColor,
|
|
204
|
+
});
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error(chalk.red('❌ Error:'), error);
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Analyze command
|
|
212
|
+
program
|
|
213
|
+
.command('analyze')
|
|
214
|
+
.alias('a')
|
|
215
|
+
.description('analyze the impact of updating a specific dependency')
|
|
216
|
+
.argument('<catalog>', 'catalog name')
|
|
217
|
+
.argument('<package>', 'package name')
|
|
218
|
+
.argument('[version]', 'new version (default: latest)')
|
|
219
|
+
.option('-f, --format <type>', 'output format: table, json, yaml, minimal', 'table')
|
|
220
|
+
.action(async (catalog, packageName, version, options, command) => {
|
|
221
|
+
try {
|
|
222
|
+
const globalOptions = command.parent.opts();
|
|
223
|
+
const formatter = new OutputFormatter(
|
|
224
|
+
options.format as OutputFormat,
|
|
225
|
+
!globalOptions.noColor
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
// Get latest version if not specified
|
|
229
|
+
let targetVersion = version;
|
|
230
|
+
if (!targetVersion) {
|
|
231
|
+
// Create a temporary registry service for version fetching
|
|
232
|
+
const tempRegistryService = new NpmRegistryService();
|
|
233
|
+
targetVersion = (await tempRegistryService.getLatestVersion(packageName)).toString();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const analysis = await services.catalogUpdateService.analyzeImpact(
|
|
237
|
+
catalog,
|
|
238
|
+
packageName,
|
|
239
|
+
targetVersion,
|
|
240
|
+
globalOptions.workspace
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const formattedOutput = formatter.formatImpactAnalysis(analysis);
|
|
244
|
+
console.log(formattedOutput);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error(chalk.red('❌ Error:'), error);
|
|
247
|
+
process.exit(1);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Workspace command
|
|
252
|
+
program
|
|
253
|
+
.command('workspace')
|
|
254
|
+
.alias('w')
|
|
255
|
+
.description('workspace information and validation')
|
|
256
|
+
.option('--validate', 'validate workspace configuration')
|
|
257
|
+
.option('-s, --stats', 'show workspace statistics')
|
|
258
|
+
.option('-f, --format <type>', 'output format: table, json, yaml, minimal', 'table')
|
|
259
|
+
.action(async (options, command) => {
|
|
260
|
+
try {
|
|
261
|
+
const globalOptions = command.parent.opts();
|
|
262
|
+
const formatter = new OutputFormatter(
|
|
263
|
+
options.format as OutputFormat,
|
|
264
|
+
!globalOptions.noColor
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
if (options.validate) {
|
|
268
|
+
const report = await services.workspaceService.validateWorkspace(globalOptions.workspace);
|
|
269
|
+
const formattedOutput = formatter.formatValidationReport(report);
|
|
270
|
+
console.log(formattedOutput);
|
|
271
|
+
process.exit(report.isValid ? 0 : 1);
|
|
272
|
+
} else if (options.stats) {
|
|
273
|
+
const stats = await services.workspaceService.getWorkspaceStats(globalOptions.workspace);
|
|
274
|
+
const formattedOutput = formatter.formatWorkspaceStats(stats);
|
|
275
|
+
console.log(formattedOutput);
|
|
276
|
+
} else {
|
|
277
|
+
const info = await services.workspaceService.getWorkspaceInfo(globalOptions.workspace);
|
|
278
|
+
console.log(formatter.formatMessage(`Workspace: ${info.name}`, 'info'));
|
|
279
|
+
console.log(formatter.formatMessage(`Path: ${info.path}`, 'info'));
|
|
280
|
+
console.log(formatter.formatMessage(`Packages: ${info.packageCount}`, 'info'));
|
|
281
|
+
console.log(formatter.formatMessage(`Catalogs: ${info.catalogCount}`, 'info'));
|
|
282
|
+
|
|
283
|
+
if (info.catalogNames.length > 0) {
|
|
284
|
+
console.log(
|
|
285
|
+
formatter.formatMessage(`Catalog names: ${info.catalogNames.join(', ')}`, 'info')
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
} catch (error) {
|
|
290
|
+
console.error(chalk.red('❌ Error:'), error);
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Theme command
|
|
296
|
+
program
|
|
297
|
+
.command('theme')
|
|
298
|
+
.alias('t')
|
|
299
|
+
.description('configure color theme')
|
|
300
|
+
.option('-s, --set <theme>', 'set theme: default, modern, minimal, neon')
|
|
301
|
+
.option('-l, --list', 'list available themes')
|
|
302
|
+
.option('-i, --interactive', 'interactive theme selection')
|
|
303
|
+
.action(async (options, _command) => {
|
|
304
|
+
try {
|
|
305
|
+
if (options.list) {
|
|
306
|
+
const themes = ThemeManager.listThemes();
|
|
307
|
+
console.log(StyledText.iconInfo('Available themes:'));
|
|
308
|
+
themes.forEach((theme) => {
|
|
309
|
+
console.log(` • ${theme}`);
|
|
310
|
+
});
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (options.set) {
|
|
315
|
+
const themes = ThemeManager.listThemes();
|
|
316
|
+
if (!themes.includes(options.set)) {
|
|
317
|
+
console.error(StyledText.iconError(`Invalid theme: ${options.set}`));
|
|
318
|
+
console.log(StyledText.muted(`Available themes: ${themes.join(', ')}`));
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
ThemeManager.setTheme(options.set);
|
|
323
|
+
console.log(StyledText.iconSuccess(`Theme set to: ${options.set}`));
|
|
324
|
+
|
|
325
|
+
// Show a preview
|
|
326
|
+
console.log('\nTheme preview:');
|
|
327
|
+
const theme = ThemeManager.getTheme();
|
|
328
|
+
console.log(` ${theme.success('✓ Success message')}`);
|
|
329
|
+
console.log(` ${theme.warning('⚠ Warning message')}`);
|
|
330
|
+
console.log(` ${theme.error('✗ Error message')}`);
|
|
331
|
+
console.log(` ${theme.info('ℹ Info message')}`);
|
|
332
|
+
console.log(
|
|
333
|
+
` ${theme.major('Major update')} | ${theme.minor('Minor update')} | ${theme.patch('Patch update')}`
|
|
334
|
+
);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (options.interactive) {
|
|
339
|
+
const interactivePrompts = new InteractivePrompts();
|
|
340
|
+
const config = await interactivePrompts.configurationWizard();
|
|
341
|
+
|
|
342
|
+
if (config.theme) {
|
|
343
|
+
ThemeManager.setTheme(config.theme);
|
|
344
|
+
console.log(StyledText.iconSuccess(`Theme configured: ${config.theme}`));
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Default: show current theme and list
|
|
350
|
+
const currentTheme = ThemeManager.getTheme();
|
|
351
|
+
console.log(StyledText.iconInfo('Current theme settings:'));
|
|
352
|
+
console.log(` Theme: ${currentTheme ? 'custom' : 'default'}`);
|
|
353
|
+
console.log('\nAvailable themes:');
|
|
354
|
+
ThemeManager.listThemes().forEach((theme) => {
|
|
355
|
+
console.log(` • ${theme}`);
|
|
356
|
+
});
|
|
357
|
+
console.log(
|
|
358
|
+
StyledText.muted('\nUse --set <theme> to change theme or --interactive for guided setup')
|
|
359
|
+
);
|
|
360
|
+
} catch (error) {
|
|
361
|
+
console.error(StyledText.iconError('Error configuring theme:'), error);
|
|
362
|
+
process.exit(1);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Security command
|
|
367
|
+
program
|
|
368
|
+
.command('security')
|
|
369
|
+
.alias('sec')
|
|
370
|
+
.description('security vulnerability scanning and automated fixes')
|
|
371
|
+
.option('-f, --format <type>', 'output format: table, json, yaml, minimal', 'table')
|
|
372
|
+
.option('--audit', 'perform npm audit scan (default: true)', true)
|
|
373
|
+
.option('--fix-vulns', 'automatically fix vulnerabilities')
|
|
374
|
+
.option('--severity <level>', 'filter by severity: low, moderate, high, critical')
|
|
375
|
+
.option('--include-dev', 'include dev dependencies in scan')
|
|
376
|
+
.option('--snyk', 'include Snyk scan (requires snyk CLI)')
|
|
377
|
+
.action(async (options, command) => {
|
|
378
|
+
try {
|
|
379
|
+
const globalOptions = command.parent.opts();
|
|
380
|
+
const formatter = new OutputFormatter(
|
|
381
|
+
options.format as OutputFormat,
|
|
382
|
+
!globalOptions.noColor
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
const securityCommand = new SecurityCommand(formatter);
|
|
386
|
+
|
|
387
|
+
await securityCommand.execute({
|
|
388
|
+
workspace: globalOptions.workspace,
|
|
389
|
+
format: options.format,
|
|
390
|
+
audit: options.audit,
|
|
391
|
+
fixVulns: options.fixVulns,
|
|
392
|
+
severity: options.severity,
|
|
393
|
+
includeDev: options.includeDev,
|
|
394
|
+
snyk: options.snyk,
|
|
395
|
+
verbose: globalOptions.verbose,
|
|
396
|
+
color: !globalOptions.noColor,
|
|
397
|
+
});
|
|
398
|
+
} catch (error) {
|
|
399
|
+
console.error(chalk.red('❌ Error:'), error);
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// Init command
|
|
405
|
+
program
|
|
406
|
+
.command('init')
|
|
407
|
+
.alias('i')
|
|
408
|
+
.description('initialize PCU configuration and PNPM workspace')
|
|
409
|
+
.option('--force', 'overwrite existing configuration file')
|
|
410
|
+
.option('--full', 'generate full configuration with all options')
|
|
411
|
+
.option(
|
|
412
|
+
'--create-workspace',
|
|
413
|
+
'create PNPM workspace structure if missing (default: true)',
|
|
414
|
+
true
|
|
415
|
+
)
|
|
416
|
+
.option('--no-create-workspace', 'skip creating PNPM workspace structure')
|
|
417
|
+
.option('-f, --format <type>', 'output format: table, json, yaml, minimal', 'table')
|
|
418
|
+
.action(async (options, command) => {
|
|
419
|
+
try {
|
|
420
|
+
const globalOptions = command.parent.opts();
|
|
421
|
+
const initCommand = new InitCommand();
|
|
422
|
+
|
|
423
|
+
await initCommand.execute({
|
|
424
|
+
workspace: globalOptions.workspace,
|
|
425
|
+
force: options.force,
|
|
426
|
+
full: options.full,
|
|
427
|
+
createWorkspace: options.createWorkspace,
|
|
428
|
+
verbose: globalOptions.verbose,
|
|
429
|
+
color: !globalOptions.noColor,
|
|
430
|
+
});
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.error(chalk.red('❌ Error:'), error);
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// Add help command
|
|
438
|
+
program
|
|
439
|
+
.command('help')
|
|
440
|
+
.alias('h')
|
|
441
|
+
.argument('[command]', 'command to get help for')
|
|
442
|
+
.description('display help for command')
|
|
443
|
+
.action((command) => {
|
|
444
|
+
if (command) {
|
|
445
|
+
const cmd = program.commands.find((c) => c.name() === command);
|
|
446
|
+
if (cmd) {
|
|
447
|
+
cmd.help();
|
|
448
|
+
} else {
|
|
449
|
+
console.log(chalk.red(`Unknown command: ${command}`));
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
program.help();
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Let commander handle help and version normally
|
|
457
|
+
// program.exitOverride() removed to fix help/version output
|
|
458
|
+
|
|
459
|
+
// Handle shorthand options and single-letter commands by rewriting arguments
|
|
460
|
+
const args = [...process.argv];
|
|
461
|
+
// Map single-letter command 'i' -> init (changed from interactive mode)
|
|
462
|
+
if (
|
|
463
|
+
args.includes('i') &&
|
|
464
|
+
!args.some(
|
|
465
|
+
(a) =>
|
|
466
|
+
a === 'init' ||
|
|
467
|
+
a === 'update' ||
|
|
468
|
+
a === '-u' ||
|
|
469
|
+
a === '--update' ||
|
|
470
|
+
a === '-i' ||
|
|
471
|
+
a === '--interactive'
|
|
472
|
+
)
|
|
473
|
+
) {
|
|
474
|
+
const index = args.findIndex((arg) => arg === 'i');
|
|
475
|
+
args.splice(index, 1, 'init');
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (args.includes('-u') || args.includes('--update')) {
|
|
479
|
+
const index = args.findIndex((arg) => arg === '-u' || arg === '--update');
|
|
480
|
+
args.splice(index, 1, 'update');
|
|
481
|
+
} else if (
|
|
482
|
+
(args.includes('-i') || args.includes('--interactive')) &&
|
|
483
|
+
!args.some((a) => a === 'update' || a === '-u' || a === '--update')
|
|
484
|
+
) {
|
|
485
|
+
// Map standalone -i to `update -i`
|
|
486
|
+
const index = args.findIndex((arg) => arg === '-i' || arg === '--interactive');
|
|
487
|
+
// Replace the flag position with 'update' and keep the flag after it
|
|
488
|
+
args.splice(index, 1, 'update', '-i');
|
|
489
|
+
} else if (args.includes('-c') || args.includes('--check')) {
|
|
490
|
+
const index = args.findIndex((arg) => arg === '-c' || arg === '--check');
|
|
491
|
+
args.splice(index, 1, 'check');
|
|
492
|
+
} else if (args.includes('-a') || args.includes('--analyze')) {
|
|
493
|
+
const index = args.findIndex((arg) => arg === '-a' || arg === '--analyze');
|
|
494
|
+
args.splice(index, 1, 'analyze');
|
|
495
|
+
} else if (args.includes('-s') || args.includes('--workspace-info')) {
|
|
496
|
+
const index = args.findIndex((arg) => arg === '-s' || arg === '--workspace-info');
|
|
497
|
+
args.splice(index, 1, 'workspace');
|
|
498
|
+
} else if (args.includes('-t') || args.includes('--theme')) {
|
|
499
|
+
const index = args.findIndex((arg) => arg === '-t' || arg === '--theme');
|
|
500
|
+
args.splice(index, 1, 'theme');
|
|
501
|
+
} else if (args.includes('--security-audit')) {
|
|
502
|
+
const index = args.findIndex((arg) => arg === '--security-audit');
|
|
503
|
+
args.splice(index, 1, 'security');
|
|
504
|
+
} else if (args.includes('--security-fix')) {
|
|
505
|
+
const index = args.findIndex((arg) => arg === '--security-fix');
|
|
506
|
+
args.splice(index, 1, 'security', '--fix-vulns');
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Show help if no arguments provided
|
|
510
|
+
if (args.length <= 2) {
|
|
511
|
+
program.help();
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Handle custom --version with update checking
|
|
515
|
+
if (args.includes('--version')) {
|
|
516
|
+
console.log(packageJson.version);
|
|
517
|
+
|
|
518
|
+
// Check for updates if not in CI and enabled in config
|
|
519
|
+
if (VersionChecker.shouldCheckForUpdates() && config.advanced?.checkForUpdates !== false) {
|
|
520
|
+
try {
|
|
521
|
+
console.log(chalk.gray('Checking for updates...'));
|
|
522
|
+
const versionResult = await VersionChecker.checkVersion(packageJson.version, {
|
|
523
|
+
skipPrompt: false,
|
|
524
|
+
timeout: 5000, // Longer timeout for explicit version check
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
if (versionResult.shouldPrompt) {
|
|
528
|
+
const didUpdate = await VersionChecker.promptAndUpdate(versionResult);
|
|
529
|
+
if (didUpdate) {
|
|
530
|
+
console.log(chalk.blue('Please run your command again to use the updated version.'));
|
|
531
|
+
process.exit(0);
|
|
532
|
+
}
|
|
533
|
+
} else if (versionResult.isLatest) {
|
|
534
|
+
console.log(chalk.green('You are using the latest version!'));
|
|
535
|
+
}
|
|
536
|
+
} catch (error) {
|
|
537
|
+
// Silently fail update check for version command
|
|
538
|
+
if (args.includes('-v') || args.includes('--verbose')) {
|
|
539
|
+
console.warn(chalk.yellow('⚠️ Could not check for updates:'), error);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
process.exit(0);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Parse command line arguments
|
|
548
|
+
try {
|
|
549
|
+
await program.parseAsync(args);
|
|
550
|
+
} catch (error) {
|
|
551
|
+
console.error(chalk.red('❌ Unexpected error:'), error);
|
|
552
|
+
if (error instanceof Error && error.stack) {
|
|
553
|
+
console.error(chalk.gray(error.stack));
|
|
554
|
+
}
|
|
555
|
+
process.exit(1);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Run the CLI if this file is executed directly
|
|
560
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
561
|
+
main().catch((error) => {
|
|
562
|
+
console.error(chalk.red('❌ Fatal error:'), error);
|
|
563
|
+
process.exit(1);
|
|
564
|
+
});
|
|
565
|
+
}
|