pcu 1.1.9 → 1.2.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 +4 -4
- package/dist/index.js +566 -67
- package/dist/index.js.map +1 -1
- package/package.json +21 -21
- package/src/cli/commandRegistrar.ts +22 -3
- package/src/cli/commands/initCommand.ts +3 -1
- package/src/cli/index.ts +28 -9
- package/src/cli/interactive/InteractiveOptionsCollector.ts +1 -1
- package/src/cli/interactive/interactivePrompts.ts +11 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pcu",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "CLI application for pnpm-catalog-updates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,24 +32,22 @@
|
|
|
32
32
|
"clean": "rimraf dist bin/*.js"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@clack/prompts": "
|
|
36
|
-
"@inquirer/core": "
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"semver": "catalog:",
|
|
52
|
-
"yaml": "catalog:"
|
|
35
|
+
"@clack/prompts": "^1.1.0",
|
|
36
|
+
"@inquirer/core": "^11.1.5",
|
|
37
|
+
"boxen": "^8.0.1",
|
|
38
|
+
"chalk": "^5.6.2",
|
|
39
|
+
"cli-table3": "^0.6.5",
|
|
40
|
+
"commander": "^14.0.3",
|
|
41
|
+
"fs-extra": "^11.3.4",
|
|
42
|
+
"glob": "^13.0.6",
|
|
43
|
+
"inquirer": "^13.3.0",
|
|
44
|
+
"lodash": "^4.17.23",
|
|
45
|
+
"npm-registry-fetch": "^19.1.1",
|
|
46
|
+
"ora": "^9.3.0",
|
|
47
|
+
"pacote": "^21.5.0",
|
|
48
|
+
"rxjs": "^7.8.2",
|
|
49
|
+
"semver": "^7.7.4",
|
|
50
|
+
"yaml": "^2.8.2"
|
|
53
51
|
},
|
|
54
52
|
"devDependencies": {
|
|
55
53
|
"@types/inquirer": "catalog:",
|
|
@@ -78,9 +76,11 @@
|
|
|
78
76
|
"homepage": "https://pcu-cli.dev",
|
|
79
77
|
"repository": {
|
|
80
78
|
"type": "git",
|
|
81
|
-
"url": "https://github.com/
|
|
79
|
+
"url": "https://github.com/yldm-tech/pnpm-catalog-updates.git",
|
|
82
80
|
"directory": "apps/cli"
|
|
83
81
|
},
|
|
84
|
-
"peerDependencies": {
|
|
82
|
+
"peerDependencies": {
|
|
83
|
+
"pnpm": ">=9"
|
|
84
|
+
},
|
|
85
85
|
"optionalDependencies": {}
|
|
86
86
|
}
|
|
@@ -61,6 +61,7 @@ export interface GlobalOptions {
|
|
|
61
61
|
workspace?: string
|
|
62
62
|
verbose?: boolean
|
|
63
63
|
noColor?: boolean
|
|
64
|
+
ci?: boolean
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
/**
|
|
@@ -235,7 +236,10 @@ function createCommandAction<TOptions>(
|
|
|
235
236
|
|
|
236
237
|
// Handle interactive mode if collector is provided
|
|
237
238
|
if (config.interactiveCollector) {
|
|
238
|
-
const
|
|
239
|
+
const isCiMode = (globalOptions as Record<string, unknown>).ci === true
|
|
240
|
+
const isInteractive = isCiMode
|
|
241
|
+
? false
|
|
242
|
+
: (options as Record<string, unknown>).interactive === true
|
|
239
243
|
const noMeaningfulOptions = !hasProvidedOptions(
|
|
240
244
|
options as Record<string, unknown>,
|
|
241
245
|
command,
|
|
@@ -277,6 +281,21 @@ export function registerCommands(
|
|
|
277
281
|
serviceFactory: LazyServiceFactory,
|
|
278
282
|
packageJson: { version: string }
|
|
279
283
|
): void {
|
|
284
|
+
// Global CI mode option - enables non-interactive mode with sensible defaults
|
|
285
|
+
program
|
|
286
|
+
.option(
|
|
287
|
+
'--ci',
|
|
288
|
+
'Enable CI mode for non-interactive execution. Skips all prompts and uses sensible defaults.',
|
|
289
|
+
false
|
|
290
|
+
)
|
|
291
|
+
.hook('preAction', (thisCommand) => {
|
|
292
|
+
const opts = thisCommand.opts()
|
|
293
|
+
if (opts.ci) {
|
|
294
|
+
// Force no color in CI mode for better compatibility
|
|
295
|
+
opts.noColor = true
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
280
299
|
// Check command
|
|
281
300
|
program
|
|
282
301
|
.command('check')
|
|
@@ -764,7 +783,7 @@ ${t('cli.help.tipLabel')} ${t('cli.help.tipContent', { locale: I18n.getLocale()
|
|
|
764
783
|
cliOutput.print(chalk.gray(t('command.selfUpdate.restartHint')))
|
|
765
784
|
} else {
|
|
766
785
|
cliOutput.error(chalk.red(t('command.selfUpdate.failed')))
|
|
767
|
-
cliOutput.print(chalk.gray('
|
|
786
|
+
cliOutput.print(chalk.gray(t('command.selfUpdate.manualHint')))
|
|
768
787
|
exitProcess(1)
|
|
769
788
|
}
|
|
770
789
|
} catch (error) {
|
|
@@ -772,7 +791,7 @@ ${t('cli.help.tipLabel')} ${t('cli.help.tipContent', { locale: I18n.getLocale()
|
|
|
772
791
|
if (globalOptions.verbose) {
|
|
773
792
|
cliOutput.error(error)
|
|
774
793
|
}
|
|
775
|
-
cliOutput.print(chalk.gray('
|
|
794
|
+
cliOutput.print(chalk.gray(t('command.selfUpdate.manualHint')))
|
|
776
795
|
exitProcess(1)
|
|
777
796
|
}
|
|
778
797
|
}
|
|
@@ -339,7 +339,9 @@ catalogs:
|
|
|
339
339
|
lines.push('')
|
|
340
340
|
lines.push(StyledText.muted(t('command.init.step5')))
|
|
341
341
|
lines.push(StyledText.muted(' https://pnpm.io/workspaces'))
|
|
342
|
-
lines.push(
|
|
342
|
+
lines.push(
|
|
343
|
+
StyledText.muted(' https://github.com/yldm-tech/pnpm-catalog-updates#configuration')
|
|
344
|
+
)
|
|
343
345
|
|
|
344
346
|
cliOutput.print(lines.join('\n'))
|
|
345
347
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -118,35 +118,54 @@ async function handleVersionFlag(
|
|
|
118
118
|
): Promise<void> {
|
|
119
119
|
if (!args.includes('--version')) return
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
const pkg = getPackageJson()
|
|
122
|
+
const version = pkg.version
|
|
122
123
|
|
|
123
124
|
// Check for updates if not in CI and enabled in config
|
|
124
125
|
if (VersionChecker.shouldCheckForUpdates() && config.advanced?.checkForUpdates !== false) {
|
|
125
126
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
// Show version with checking status on same line
|
|
128
|
+
process.stdout.write(
|
|
129
|
+
`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)} ${chalk.gray(t('cli.checkingUpdates'))}`
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
const versionResult = await VersionChecker.checkVersion(version, {
|
|
128
133
|
skipPrompt: false,
|
|
129
|
-
timeout: 5000,
|
|
134
|
+
timeout: 5000,
|
|
130
135
|
})
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
// Clear the checking message and show final result
|
|
138
|
+
process.stdout.write('\r\x1b[K') // Clear current line
|
|
139
|
+
|
|
140
|
+
if (versionResult.shouldPrompt && versionResult.latestVersion) {
|
|
141
|
+
cliOutput.print(
|
|
142
|
+
`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)} ${chalk.yellow(`-> v${versionResult.latestVersion} ${t('cli.available')}`)}`
|
|
143
|
+
)
|
|
133
144
|
const didUpdate = await VersionChecker.promptAndUpdate(versionResult)
|
|
134
145
|
if (didUpdate) {
|
|
135
146
|
cliOutput.print(chalk.blue(t('cli.runAgain')))
|
|
136
147
|
exitWithCleanup(0)
|
|
137
148
|
}
|
|
138
|
-
} else
|
|
139
|
-
cliOutput.print(
|
|
149
|
+
} else {
|
|
150
|
+
cliOutput.print(
|
|
151
|
+
`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)} ${chalk.green(t('cli.latestVersion'))}`
|
|
152
|
+
)
|
|
140
153
|
}
|
|
141
154
|
} catch (error) {
|
|
142
|
-
//
|
|
155
|
+
// Clear line and show version without update status
|
|
156
|
+
process.stdout.write('\r\x1b[K')
|
|
157
|
+
cliOutput.print(`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)}`)
|
|
158
|
+
|
|
143
159
|
logger.debug('Version flag update check failed', {
|
|
144
160
|
error: error instanceof Error ? error.message : error,
|
|
145
161
|
})
|
|
146
162
|
if (args.includes('-v') || args.includes('--verbose')) {
|
|
147
|
-
cliOutput.warn(chalk.yellow(
|
|
163
|
+
cliOutput.warn(chalk.yellow(` ${t('cli.couldNotCheckUpdates')}`), error)
|
|
148
164
|
}
|
|
149
165
|
}
|
|
166
|
+
} else {
|
|
167
|
+
// No update check, just show version
|
|
168
|
+
cliOutput.print(`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)}`)
|
|
150
169
|
}
|
|
151
170
|
|
|
152
171
|
exitWithCleanup(0)
|
|
@@ -272,7 +272,7 @@ export class InteractiveOptionsCollector {
|
|
|
272
272
|
message: t('interactive.analyze.packageName'),
|
|
273
273
|
placeholder: 'lodash, react, ...',
|
|
274
274
|
validate: (value) => {
|
|
275
|
-
if (!value
|
|
275
|
+
if (!value?.trim()) return t('interactive.analyze.packageNameRequired')
|
|
276
276
|
return undefined
|
|
277
277
|
},
|
|
278
278
|
})
|
|
@@ -103,7 +103,7 @@ export class InteractivePrompts {
|
|
|
103
103
|
|
|
104
104
|
const answers = await inquirer.prompt([
|
|
105
105
|
{
|
|
106
|
-
type: '
|
|
106
|
+
type: 'select',
|
|
107
107
|
name: 'catalog',
|
|
108
108
|
message: StyledText.iconCatalog(t('prompt.selectCatalog')),
|
|
109
109
|
choices,
|
|
@@ -128,7 +128,7 @@ export class InteractivePrompts {
|
|
|
128
128
|
|
|
129
129
|
const answers = await inquirer.prompt([
|
|
130
130
|
{
|
|
131
|
-
type: '
|
|
131
|
+
type: 'select',
|
|
132
132
|
name: 'strategy',
|
|
133
133
|
message: StyledText.iconUpdate(t('prompt.selectUpdateStrategy')),
|
|
134
134
|
choices: strategies,
|
|
@@ -168,7 +168,7 @@ export class InteractivePrompts {
|
|
|
168
168
|
): Promise<string> {
|
|
169
169
|
const answers = await inquirer.prompt([
|
|
170
170
|
{
|
|
171
|
-
type: '
|
|
171
|
+
type: 'select',
|
|
172
172
|
name: 'package',
|
|
173
173
|
message,
|
|
174
174
|
choices: packages.map((pkg) => ({ name: pkg, value: pkg })),
|
|
@@ -191,7 +191,7 @@ export class InteractivePrompts {
|
|
|
191
191
|
|
|
192
192
|
const answers = await inquirer.prompt([
|
|
193
193
|
{
|
|
194
|
-
type: '
|
|
194
|
+
type: 'select',
|
|
195
195
|
name: 'path',
|
|
196
196
|
message: t('prompt.selectWorkspace'),
|
|
197
197
|
choices,
|
|
@@ -221,7 +221,7 @@ export class InteractivePrompts {
|
|
|
221
221
|
|
|
222
222
|
const answers = await inquirer.prompt([
|
|
223
223
|
{
|
|
224
|
-
type: '
|
|
224
|
+
type: 'select',
|
|
225
225
|
name: 'selected',
|
|
226
226
|
message: t('prompt.browsePath', { path: currentPath }),
|
|
227
227
|
choices,
|
|
@@ -271,7 +271,7 @@ export class InteractivePrompts {
|
|
|
271
271
|
*/
|
|
272
272
|
async selectTheme(): Promise<string | null> {
|
|
273
273
|
const answers = await inquirer.prompt({
|
|
274
|
-
type: '
|
|
274
|
+
type: 'select',
|
|
275
275
|
name: 'theme',
|
|
276
276
|
message: t('prompt.selectTheme'),
|
|
277
277
|
choices: [
|
|
@@ -294,7 +294,7 @@ export class InteractivePrompts {
|
|
|
294
294
|
cliOutput.print(chalk.bold.blue(`\n${t('prompt.configWizard')}\n`))
|
|
295
295
|
|
|
296
296
|
const themeAnswer = await inquirer.prompt({
|
|
297
|
-
type: '
|
|
297
|
+
type: 'select',
|
|
298
298
|
name: 'theme',
|
|
299
299
|
message: t('prompt.selectTheme'),
|
|
300
300
|
choices: [
|
|
@@ -321,7 +321,7 @@ export class InteractivePrompts {
|
|
|
321
321
|
})
|
|
322
322
|
|
|
323
323
|
const strategyAnswer = await inquirer.prompt({
|
|
324
|
-
type: '
|
|
324
|
+
type: 'select',
|
|
325
325
|
name: 'updateStrategy',
|
|
326
326
|
message: t('prompt.defaultStrategy'),
|
|
327
327
|
choices: [
|
|
@@ -398,7 +398,7 @@ export class InteractivePrompts {
|
|
|
398
398
|
|
|
399
399
|
const answers = await inquirer.prompt([
|
|
400
400
|
{
|
|
401
|
-
type: '
|
|
401
|
+
type: 'select',
|
|
402
402
|
name: 'action',
|
|
403
403
|
message: StyledText.iconError(t('prompt.errorMessage', { error })),
|
|
404
404
|
choices: options,
|
|
@@ -544,7 +544,7 @@ export class InteractiveCommandBuilder {
|
|
|
544
544
|
}> {
|
|
545
545
|
const baseCommand = await inquirer.prompt([
|
|
546
546
|
{
|
|
547
|
-
type: '
|
|
547
|
+
type: 'select',
|
|
548
548
|
name: 'command',
|
|
549
549
|
message: t('prompt.whatToDo'),
|
|
550
550
|
choices: [
|
|
@@ -561,7 +561,7 @@ export class InteractiveCommandBuilder {
|
|
|
561
561
|
// Common options
|
|
562
562
|
const common = await inquirer.prompt([
|
|
563
563
|
{
|
|
564
|
-
type: '
|
|
564
|
+
type: 'select',
|
|
565
565
|
name: 'format',
|
|
566
566
|
message: t('prompt.outputFormat'),
|
|
567
567
|
choices: [
|