pnpm-catalog-updates 0.7.19 → 1.0.1
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 +27 -0
- 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,42 +5,46 @@
|
|
|
5
5
|
* Provides consistent option parsing and validation.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { Option } from 'commander'
|
|
8
|
+
import { Option } from 'commander'
|
|
9
9
|
|
|
10
10
|
export interface GlobalCliOptions {
|
|
11
|
-
workspace?: string
|
|
12
|
-
verbose?: boolean
|
|
13
|
-
color?: boolean
|
|
14
|
-
registry?: string
|
|
15
|
-
timeout?: number
|
|
16
|
-
config?: string
|
|
11
|
+
workspace?: string
|
|
12
|
+
verbose?: boolean
|
|
13
|
+
color?: boolean
|
|
14
|
+
registry?: string
|
|
15
|
+
timeout?: number
|
|
16
|
+
config?: string
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface CheckCliOptions extends GlobalCliOptions {
|
|
20
|
-
catalog?: string
|
|
21
|
-
format?: 'table' | 'json' | 'yaml' | 'minimal'
|
|
22
|
-
target?: 'latest' | 'greatest' | 'minor' | 'patch' | 'newest'
|
|
23
|
-
prerelease?: boolean
|
|
24
|
-
include?: string[]
|
|
25
|
-
exclude?: string[]
|
|
20
|
+
catalog?: string
|
|
21
|
+
format?: 'table' | 'json' | 'yaml' | 'minimal'
|
|
22
|
+
target?: 'latest' | 'greatest' | 'minor' | 'patch' | 'newest'
|
|
23
|
+
prerelease?: boolean
|
|
24
|
+
include?: string[]
|
|
25
|
+
exclude?: string[]
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export interface UpdateCliOptions extends CheckCliOptions {
|
|
29
|
-
interactive?: boolean
|
|
30
|
-
dryRun?: boolean
|
|
31
|
-
force?: boolean
|
|
32
|
-
createBackup?: boolean
|
|
29
|
+
interactive?: boolean
|
|
30
|
+
dryRun?: boolean
|
|
31
|
+
force?: boolean
|
|
32
|
+
createBackup?: boolean
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface AnalyzeCliOptions extends GlobalCliOptions {
|
|
36
|
-
format?: 'table' | 'json' | 'yaml' | 'minimal'
|
|
36
|
+
format?: 'table' | 'json' | 'yaml' | 'minimal'
|
|
37
|
+
ai?: boolean
|
|
38
|
+
provider?: 'auto' | 'claude' | 'gemini' | 'codex'
|
|
39
|
+
analysisType?: 'impact' | 'security' | 'compatibility' | 'recommend'
|
|
40
|
+
skipCache?: boolean
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
export interface WorkspaceCliOptions extends GlobalCliOptions {
|
|
40
|
-
validate?: boolean
|
|
41
|
-
stats?: boolean
|
|
42
|
-
info?: boolean
|
|
43
|
-
format?: 'table' | 'json' | 'yaml' | 'minimal'
|
|
44
|
+
validate?: boolean
|
|
45
|
+
stats?: boolean
|
|
46
|
+
info?: boolean
|
|
47
|
+
format?: 'table' | 'json' | 'yaml' | 'minimal'
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
@@ -60,7 +64,7 @@ export const globalOptions = [
|
|
|
60
64
|
.env('PCU_TIMEOUT'),
|
|
61
65
|
|
|
62
66
|
new Option('--config <path>', 'path to configuration file').env('PCU_CONFIG'),
|
|
63
|
-
]
|
|
67
|
+
]
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
70
|
* Check command specific options
|
|
@@ -85,7 +89,7 @@ export const checkOptions = [
|
|
|
85
89
|
new Option('--include <pattern...>', 'include packages matching pattern').env('PCU_INCLUDE'),
|
|
86
90
|
|
|
87
91
|
new Option('--exclude <pattern...>', 'exclude packages matching pattern').env('PCU_EXCLUDE'),
|
|
88
|
-
]
|
|
92
|
+
]
|
|
89
93
|
|
|
90
94
|
/**
|
|
91
95
|
* Update command specific options
|
|
@@ -100,7 +104,7 @@ export const updateOptions = [
|
|
|
100
104
|
new Option('--force', 'force updates even if risky').env('PCU_FORCE'),
|
|
101
105
|
|
|
102
106
|
new Option('--create-backup', 'create backup files before updating').env('PCU_CREATE_BACKUP'),
|
|
103
|
-
]
|
|
107
|
+
]
|
|
104
108
|
|
|
105
109
|
/**
|
|
106
110
|
* Analyze command specific options
|
|
@@ -112,7 +116,21 @@ export const analyzeOptions = [
|
|
|
112
116
|
.choices(['table', 'json', 'yaml', 'minimal'])
|
|
113
117
|
.default('table')
|
|
114
118
|
.env('PCU_OUTPUT_FORMAT'),
|
|
115
|
-
|
|
119
|
+
|
|
120
|
+
new Option('--ai', 'enable AI-powered analysis').env('PCU_AI_ENABLED'),
|
|
121
|
+
|
|
122
|
+
new Option('--provider <name>', 'AI provider to use')
|
|
123
|
+
.choices(['auto', 'claude', 'gemini', 'codex'])
|
|
124
|
+
.default('auto')
|
|
125
|
+
.env('PCU_AI_PROVIDER'),
|
|
126
|
+
|
|
127
|
+
new Option('--analysis-type <type>', 'type of AI analysis')
|
|
128
|
+
.choices(['impact', 'security', 'compatibility', 'recommend'])
|
|
129
|
+
.default('impact')
|
|
130
|
+
.env('PCU_AI_ANALYSIS_TYPE'),
|
|
131
|
+
|
|
132
|
+
new Option('--skip-cache', 'skip AI analysis cache').env('PCU_AI_SKIP_CACHE'),
|
|
133
|
+
]
|
|
116
134
|
|
|
117
135
|
/**
|
|
118
136
|
* Workspace command specific options
|
|
@@ -130,7 +148,7 @@ export const workspaceOptions = [
|
|
|
130
148
|
.choices(['table', 'json', 'yaml', 'minimal'])
|
|
131
149
|
.default('table')
|
|
132
150
|
.env('PCU_OUTPUT_FORMAT'),
|
|
133
|
-
]
|
|
151
|
+
]
|
|
134
152
|
|
|
135
153
|
/**
|
|
136
154
|
* Option groups for better help organization
|
|
@@ -178,203 +196,242 @@ export const optionGroups = {
|
|
|
178
196
|
new Option('--timeout <ms>', 'request timeout').argParser(parseInt),
|
|
179
197
|
],
|
|
180
198
|
},
|
|
181
|
-
}
|
|
199
|
+
}
|
|
182
200
|
|
|
183
201
|
/**
|
|
184
202
|
* Utility functions for option handling
|
|
185
203
|
*/
|
|
186
204
|
export class OptionUtils {
|
|
205
|
+
private static parseBoolean(value: unknown): boolean {
|
|
206
|
+
if (value === undefined || value === null) return false
|
|
207
|
+
if (typeof value === 'boolean') return value
|
|
208
|
+
if (typeof value === 'number') return value !== 0
|
|
209
|
+
if (typeof value === 'string') {
|
|
210
|
+
const normalized = value.trim().toLowerCase()
|
|
211
|
+
if (normalized === '') return false
|
|
212
|
+
if (['false', '0', 'no', 'off', 'n'].includes(normalized)) return false
|
|
213
|
+
if (['true', '1', 'yes', 'on', 'y'].includes(normalized)) return true
|
|
214
|
+
return true
|
|
215
|
+
}
|
|
216
|
+
return Boolean(value)
|
|
217
|
+
}
|
|
218
|
+
|
|
187
219
|
/**
|
|
188
220
|
* Parse and validate global options
|
|
189
221
|
*/
|
|
190
222
|
static parseGlobalOptions(options: any): GlobalCliOptions {
|
|
191
|
-
const parsed: GlobalCliOptions = {}
|
|
223
|
+
const parsed: GlobalCliOptions = {}
|
|
192
224
|
|
|
193
225
|
if (options.workspace) {
|
|
194
|
-
parsed.workspace = String(options.workspace).trim()
|
|
226
|
+
parsed.workspace = String(options.workspace).trim()
|
|
195
227
|
}
|
|
196
228
|
|
|
197
229
|
if (options.verbose !== undefined) {
|
|
198
|
-
parsed.verbose =
|
|
230
|
+
parsed.verbose = OptionUtils.parseBoolean(options.verbose)
|
|
199
231
|
}
|
|
200
232
|
|
|
201
233
|
if (options.color !== undefined) {
|
|
202
|
-
parsed.color =
|
|
234
|
+
parsed.color = OptionUtils.parseBoolean(options.color)
|
|
203
235
|
}
|
|
204
236
|
|
|
205
237
|
if (options.registry) {
|
|
206
|
-
parsed.registry = String(options.registry).trim()
|
|
238
|
+
parsed.registry = String(options.registry).trim()
|
|
207
239
|
}
|
|
208
240
|
|
|
209
241
|
if (options.timeout) {
|
|
210
|
-
const timeout = parseInt(String(options.timeout), 10)
|
|
211
|
-
if (!isNaN(timeout) && timeout > 0) {
|
|
212
|
-
parsed.timeout = timeout
|
|
242
|
+
const timeout = parseInt(String(options.timeout), 10)
|
|
243
|
+
if (!Number.isNaN(timeout) && timeout > 0) {
|
|
244
|
+
parsed.timeout = timeout
|
|
213
245
|
}
|
|
214
246
|
}
|
|
215
247
|
|
|
216
248
|
if (options.config) {
|
|
217
|
-
parsed.config = String(options.config).trim()
|
|
249
|
+
parsed.config = String(options.config).trim()
|
|
218
250
|
}
|
|
219
251
|
|
|
220
|
-
return parsed
|
|
252
|
+
return parsed
|
|
221
253
|
}
|
|
222
254
|
|
|
223
255
|
/**
|
|
224
256
|
* Parse check command options
|
|
225
257
|
*/
|
|
226
258
|
static parseCheckOptions(options: any): CheckCliOptions {
|
|
227
|
-
const global =
|
|
228
|
-
const check: CheckCliOptions = { ...global }
|
|
259
|
+
const global = OptionUtils.parseGlobalOptions(options)
|
|
260
|
+
const check: CheckCliOptions = { ...global }
|
|
229
261
|
|
|
230
262
|
if (options.catalog) {
|
|
231
|
-
check.catalog = String(options.catalog).trim()
|
|
263
|
+
check.catalog = String(options.catalog).trim()
|
|
232
264
|
}
|
|
233
265
|
|
|
234
266
|
if (options.format && typeof options.format === 'string') {
|
|
235
|
-
check.format = options.format as Exclude<CheckCliOptions['format'], undefined
|
|
267
|
+
check.format = options.format as Exclude<CheckCliOptions['format'], undefined>
|
|
236
268
|
}
|
|
237
269
|
|
|
238
270
|
if (options.target && typeof options.target === 'string') {
|
|
239
|
-
check.target = options.target as Exclude<CheckCliOptions['target'], undefined
|
|
271
|
+
check.target = options.target as Exclude<CheckCliOptions['target'], undefined>
|
|
240
272
|
}
|
|
241
273
|
|
|
242
274
|
if (options.prerelease !== undefined) {
|
|
243
|
-
check.prerelease =
|
|
275
|
+
check.prerelease = OptionUtils.parseBoolean(options.prerelease)
|
|
244
276
|
}
|
|
245
277
|
|
|
246
278
|
if (options.include) {
|
|
247
279
|
check.include = Array.isArray(options.include)
|
|
248
280
|
? options.include.map((p: any) => String(p).trim()).filter(Boolean)
|
|
249
|
-
: [String(options.include).trim()].filter(Boolean)
|
|
281
|
+
: [String(options.include).trim()].filter(Boolean)
|
|
250
282
|
}
|
|
251
283
|
|
|
252
284
|
if (options.exclude) {
|
|
253
285
|
check.exclude = Array.isArray(options.exclude)
|
|
254
286
|
? options.exclude.map((p: any) => String(p).trim()).filter(Boolean)
|
|
255
|
-
: [String(options.exclude).trim()].filter(Boolean)
|
|
287
|
+
: [String(options.exclude).trim()].filter(Boolean)
|
|
256
288
|
}
|
|
257
289
|
|
|
258
|
-
return check
|
|
290
|
+
return check
|
|
259
291
|
}
|
|
260
292
|
|
|
261
293
|
/**
|
|
262
294
|
* Parse update command options
|
|
263
295
|
*/
|
|
264
296
|
static parseUpdateOptions(options: any): UpdateCliOptions {
|
|
265
|
-
const check =
|
|
266
|
-
const update: UpdateCliOptions = { ...check }
|
|
297
|
+
const check = OptionUtils.parseCheckOptions(options)
|
|
298
|
+
const update: UpdateCliOptions = { ...check }
|
|
267
299
|
|
|
268
300
|
if (options.interactive !== undefined) {
|
|
269
|
-
update.interactive =
|
|
301
|
+
update.interactive = OptionUtils.parseBoolean(options.interactive)
|
|
270
302
|
}
|
|
271
303
|
|
|
272
304
|
if (options.dryRun !== undefined) {
|
|
273
|
-
update.dryRun =
|
|
305
|
+
update.dryRun = OptionUtils.parseBoolean(options.dryRun)
|
|
274
306
|
}
|
|
275
307
|
|
|
276
308
|
if (options.force !== undefined) {
|
|
277
|
-
update.force =
|
|
309
|
+
update.force = OptionUtils.parseBoolean(options.force)
|
|
278
310
|
}
|
|
279
311
|
|
|
280
312
|
if (options.createBackup !== undefined) {
|
|
281
|
-
update.createBackup =
|
|
313
|
+
update.createBackup = OptionUtils.parseBoolean(options.createBackup)
|
|
282
314
|
}
|
|
283
315
|
|
|
284
|
-
return update
|
|
316
|
+
return update
|
|
285
317
|
}
|
|
286
318
|
|
|
287
319
|
/**
|
|
288
320
|
* Parse analyze command options
|
|
289
321
|
*/
|
|
290
322
|
static parseAnalyzeOptions(options: any): AnalyzeCliOptions {
|
|
291
|
-
const global =
|
|
292
|
-
const analyze: AnalyzeCliOptions = { ...global }
|
|
323
|
+
const global = OptionUtils.parseGlobalOptions(options)
|
|
324
|
+
const analyze: AnalyzeCliOptions = { ...global }
|
|
293
325
|
|
|
294
326
|
if (options.format && typeof options.format === 'string') {
|
|
295
|
-
analyze.format = options.format as Exclude<AnalyzeCliOptions['format'], undefined
|
|
327
|
+
analyze.format = options.format as Exclude<AnalyzeCliOptions['format'], undefined>
|
|
296
328
|
}
|
|
297
329
|
|
|
298
|
-
|
|
330
|
+
if (options.ai !== undefined) {
|
|
331
|
+
analyze.ai = OptionUtils.parseBoolean(options.ai)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (options.provider && typeof options.provider === 'string') {
|
|
335
|
+
analyze.provider = options.provider as Exclude<AnalyzeCliOptions['provider'], undefined>
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (options.analysisType && typeof options.analysisType === 'string') {
|
|
339
|
+
analyze.analysisType = options.analysisType as Exclude<
|
|
340
|
+
AnalyzeCliOptions['analysisType'],
|
|
341
|
+
undefined
|
|
342
|
+
>
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (options.skipCache !== undefined) {
|
|
346
|
+
analyze.skipCache = OptionUtils.parseBoolean(options.skipCache)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return analyze
|
|
299
350
|
}
|
|
300
351
|
|
|
301
352
|
/**
|
|
302
353
|
* Parse workspace command options
|
|
303
354
|
*/
|
|
304
355
|
static parseWorkspaceOptions(options: any): WorkspaceCliOptions {
|
|
305
|
-
const global =
|
|
306
|
-
const workspace: WorkspaceCliOptions = { ...global }
|
|
356
|
+
const global = OptionUtils.parseGlobalOptions(options)
|
|
357
|
+
const workspace: WorkspaceCliOptions = { ...global }
|
|
307
358
|
|
|
308
359
|
if (options.validate !== undefined) {
|
|
309
|
-
workspace.validate =
|
|
360
|
+
workspace.validate = OptionUtils.parseBoolean(options.validate)
|
|
310
361
|
}
|
|
311
362
|
|
|
312
363
|
if (options.stats !== undefined) {
|
|
313
|
-
workspace.stats =
|
|
364
|
+
workspace.stats = OptionUtils.parseBoolean(options.stats)
|
|
314
365
|
}
|
|
315
366
|
|
|
316
367
|
if (options.info !== undefined) {
|
|
317
|
-
workspace.info =
|
|
368
|
+
workspace.info = OptionUtils.parseBoolean(options.info)
|
|
318
369
|
}
|
|
319
370
|
|
|
320
371
|
if (options.format && typeof options.format === 'string') {
|
|
321
|
-
workspace.format = options.format as Exclude<WorkspaceCliOptions['format'], undefined
|
|
372
|
+
workspace.format = options.format as Exclude<WorkspaceCliOptions['format'], undefined>
|
|
322
373
|
}
|
|
323
374
|
|
|
324
|
-
return workspace
|
|
375
|
+
return workspace
|
|
325
376
|
}
|
|
326
377
|
|
|
327
378
|
/**
|
|
328
379
|
* Generate help text for option group
|
|
329
380
|
*/
|
|
330
381
|
static generateHelpText(groupName: keyof typeof optionGroups): string {
|
|
331
|
-
const group = optionGroups[groupName]
|
|
332
|
-
if (!group) return ''
|
|
382
|
+
const group = optionGroups[groupName]
|
|
383
|
+
if (!group) return ''
|
|
333
384
|
|
|
334
|
-
const lines = [`${group.title}:`]
|
|
385
|
+
const lines = [`${group.title}:`]
|
|
335
386
|
|
|
336
387
|
for (const option of group.options) {
|
|
337
|
-
const flags = option.flags
|
|
338
|
-
const description = option.description || ''
|
|
339
|
-
const choices = option.argChoices ? ` (choices: ${option.argChoices.join(', ')})` : ''
|
|
340
|
-
const defaultValue = option.defaultValue ? ` (default: ${option.defaultValue})` : ''
|
|
388
|
+
const flags = option.flags
|
|
389
|
+
const description = option.description || ''
|
|
390
|
+
const choices = option.argChoices ? ` (choices: ${option.argChoices.join(', ')})` : ''
|
|
391
|
+
const defaultValue = option.defaultValue ? ` (default: ${option.defaultValue})` : ''
|
|
341
392
|
|
|
342
|
-
lines.push(` ${flags.padEnd(30)} ${description}${choices}${defaultValue}`)
|
|
393
|
+
lines.push(` ${flags.padEnd(30)} ${description}${choices}${defaultValue}`)
|
|
343
394
|
}
|
|
344
395
|
|
|
345
|
-
return lines.join('\n')
|
|
396
|
+
return lines.join('\n')
|
|
346
397
|
}
|
|
347
398
|
|
|
348
399
|
/**
|
|
349
400
|
* Validate option combinations
|
|
350
401
|
*/
|
|
351
402
|
static validateOptionCombinations(command: string, options: any): string[] {
|
|
352
|
-
const errors: string[] = []
|
|
403
|
+
const errors: string[] = []
|
|
353
404
|
|
|
354
405
|
switch (command) {
|
|
355
406
|
case 'update':
|
|
356
|
-
if (
|
|
357
|
-
|
|
407
|
+
if (
|
|
408
|
+
OptionUtils.parseBoolean(options.interactive) &&
|
|
409
|
+
OptionUtils.parseBoolean(options.dryRun)
|
|
410
|
+
) {
|
|
411
|
+
errors.push('Cannot use --interactive with --dry-run')
|
|
358
412
|
}
|
|
359
|
-
break
|
|
413
|
+
break
|
|
360
414
|
|
|
361
|
-
case 'workspace':
|
|
362
|
-
const actionCount = [options.validate, options.stats, options.info].filter(
|
|
415
|
+
case 'workspace': {
|
|
416
|
+
const actionCount = [options.validate, options.stats, options.info].filter((v) =>
|
|
417
|
+
OptionUtils.parseBoolean(v)
|
|
418
|
+
).length
|
|
363
419
|
if (actionCount > 1) {
|
|
364
|
-
errors.push('Cannot use multiple workspace actions simultaneously')
|
|
420
|
+
errors.push('Cannot use multiple workspace actions simultaneously')
|
|
365
421
|
}
|
|
366
422
|
if (actionCount === 0) {
|
|
367
423
|
// Default to info
|
|
368
|
-
options.info = true
|
|
424
|
+
options.info = true
|
|
369
425
|
}
|
|
370
|
-
break
|
|
426
|
+
break
|
|
427
|
+
}
|
|
371
428
|
}
|
|
372
429
|
|
|
373
430
|
// Global validations
|
|
374
|
-
if (options.verbose && options.silent) {
|
|
375
|
-
errors.push('Cannot use both --verbose and --silent')
|
|
431
|
+
if (OptionUtils.parseBoolean(options.verbose) && OptionUtils.parseBoolean(options.silent)) {
|
|
432
|
+
errors.push('Cannot use both --verbose and --silent')
|
|
376
433
|
}
|
|
377
434
|
|
|
378
|
-
return errors
|
|
435
|
+
return errors
|
|
379
436
|
}
|
|
380
437
|
}
|
package/src/cli/options/index.ts
CHANGED