pnpm-catalog-updates 0.5.7 โ†’ 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.
Files changed (224) hide show
  1. package/bin/pcu.js +1 -1
  2. package/dist/index.js +9559 -32
  3. package/dist/index.js.map +1 -1
  4. package/package.json +61 -103
  5. package/src/cli/commands/checkCommand.ts +227 -0
  6. package/src/cli/commands/initCommand.ts +394 -0
  7. package/src/cli/commands/securityCommand.ts +569 -0
  8. package/src/cli/commands/updateCommand.ts +245 -0
  9. package/src/cli/formatters/outputFormatter.ts +830 -0
  10. package/src/cli/formatters/progressBar.ts +700 -0
  11. package/src/cli/index.ts +565 -0
  12. package/src/cli/interactive/interactivePrompts.ts +517 -0
  13. package/src/cli/options/globalOptions.ts +380 -0
  14. package/src/cli/options/index.ts +5 -0
  15. package/src/cli/themes/colorTheme.ts +379 -0
  16. package/src/cli/validators/commandValidator.ts +395 -0
  17. package/src/cli/validators/index.ts +5 -0
  18. package/src/index.ts +4 -0
  19. package/LICENSE +0 -21
  20. package/README.ja.md +0 -587
  21. package/README.md +0 -694
  22. package/README.zh-CN.md +0 -634
  23. package/dist/application/services/CatalogUpdateService.d.ts +0 -209
  24. package/dist/application/services/CatalogUpdateService.d.ts.map +0 -1
  25. package/dist/application/services/CatalogUpdateService.js +0 -839
  26. package/dist/application/services/CatalogUpdateService.js.map +0 -1
  27. package/dist/application/services/WorkspaceService.d.ts +0 -139
  28. package/dist/application/services/WorkspaceService.d.ts.map +0 -1
  29. package/dist/application/services/WorkspaceService.js +0 -340
  30. package/dist/application/services/WorkspaceService.js.map +0 -1
  31. package/dist/cli/commands/CheckCommand.d.ts +0 -40
  32. package/dist/cli/commands/CheckCommand.d.ts.map +0 -1
  33. package/dist/cli/commands/CheckCommand.js +0 -177
  34. package/dist/cli/commands/CheckCommand.js.map +0 -1
  35. package/dist/cli/commands/InitCommand.d.ts +0 -53
  36. package/dist/cli/commands/InitCommand.d.ts.map +0 -1
  37. package/dist/cli/commands/InitCommand.js +0 -338
  38. package/dist/cli/commands/InitCommand.js.map +0 -1
  39. package/dist/cli/commands/SecurityCommand.d.ts +0 -113
  40. package/dist/cli/commands/SecurityCommand.d.ts.map +0 -1
  41. package/dist/cli/commands/SecurityCommand.js +0 -410
  42. package/dist/cli/commands/SecurityCommand.js.map +0 -1
  43. package/dist/cli/commands/UpdateCommand.d.ts +0 -44
  44. package/dist/cli/commands/UpdateCommand.d.ts.map +0 -1
  45. package/dist/cli/commands/UpdateCommand.js +0 -189
  46. package/dist/cli/commands/UpdateCommand.js.map +0 -1
  47. package/dist/cli/formatters/OutputFormatter.d.ts +0 -116
  48. package/dist/cli/formatters/OutputFormatter.d.ts.map +0 -1
  49. package/dist/cli/formatters/OutputFormatter.js +0 -664
  50. package/dist/cli/formatters/OutputFormatter.js.map +0 -1
  51. package/dist/cli/formatters/ProgressBar.d.ts +0 -195
  52. package/dist/cli/formatters/ProgressBar.d.ts.map +0 -1
  53. package/dist/cli/formatters/ProgressBar.js +0 -622
  54. package/dist/cli/formatters/ProgressBar.js.map +0 -1
  55. package/dist/cli/index.d.ts +0 -12
  56. package/dist/cli/index.d.ts.map +0 -1
  57. package/dist/cli/index.js +0 -492
  58. package/dist/cli/index.js.map +0 -1
  59. package/dist/cli/interactive/InteractivePrompts.d.ts +0 -85
  60. package/dist/cli/interactive/InteractivePrompts.d.ts.map +0 -1
  61. package/dist/cli/interactive/InteractivePrompts.js +0 -434
  62. package/dist/cli/interactive/InteractivePrompts.js.map +0 -1
  63. package/dist/cli/options/GlobalOptions.d.ts +0 -117
  64. package/dist/cli/options/GlobalOptions.d.ts.map +0 -1
  65. package/dist/cli/options/GlobalOptions.js +0 -278
  66. package/dist/cli/options/GlobalOptions.js.map +0 -1
  67. package/dist/cli/options/index.d.ts +0 -5
  68. package/dist/cli/options/index.d.ts.map +0 -1
  69. package/dist/cli/options/index.js +0 -5
  70. package/dist/cli/options/index.js.map +0 -1
  71. package/dist/cli/themes/ColorTheme.d.ts +0 -211
  72. package/dist/cli/themes/ColorTheme.d.ts.map +0 -1
  73. package/dist/cli/themes/ColorTheme.js +0 -267
  74. package/dist/cli/themes/ColorTheme.js.map +0 -1
  75. package/dist/cli/validators/CommandValidator.d.ts +0 -60
  76. package/dist/cli/validators/CommandValidator.d.ts.map +0 -1
  77. package/dist/cli/validators/CommandValidator.js +0 -319
  78. package/dist/cli/validators/CommandValidator.js.map +0 -1
  79. package/dist/cli/validators/index.d.ts +0 -5
  80. package/dist/cli/validators/index.d.ts.map +0 -1
  81. package/dist/cli/validators/index.js +0 -5
  82. package/dist/cli/validators/index.js.map +0 -1
  83. package/dist/common/config/Config.d.ts +0 -142
  84. package/dist/common/config/Config.d.ts.map +0 -1
  85. package/dist/common/config/Config.js +0 -382
  86. package/dist/common/config/Config.js.map +0 -1
  87. package/dist/common/config/ConfigLoader.d.ts +0 -49
  88. package/dist/common/config/ConfigLoader.d.ts.map +0 -1
  89. package/dist/common/config/ConfigLoader.js +0 -180
  90. package/dist/common/config/ConfigLoader.js.map +0 -1
  91. package/dist/common/config/PackageFilterConfig.d.ts +0 -56
  92. package/dist/common/config/PackageFilterConfig.d.ts.map +0 -1
  93. package/dist/common/config/PackageFilterConfig.js +0 -94
  94. package/dist/common/config/PackageFilterConfig.js.map +0 -1
  95. package/dist/common/config/index.d.ts +0 -8
  96. package/dist/common/config/index.d.ts.map +0 -1
  97. package/dist/common/config/index.js +0 -8
  98. package/dist/common/config/index.js.map +0 -1
  99. package/dist/common/error-handling/ErrorTracker.d.ts +0 -48
  100. package/dist/common/error-handling/ErrorTracker.d.ts.map +0 -1
  101. package/dist/common/error-handling/ErrorTracker.js +0 -93
  102. package/dist/common/error-handling/ErrorTracker.js.map +0 -1
  103. package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts +0 -74
  104. package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts.map +0 -1
  105. package/dist/common/error-handling/UserFriendlyErrorHandler.js +0 -703
  106. package/dist/common/error-handling/UserFriendlyErrorHandler.js.map +0 -1
  107. package/dist/common/error-handling/index.d.ts +0 -11
  108. package/dist/common/error-handling/index.d.ts.map +0 -1
  109. package/dist/common/error-handling/index.js +0 -9
  110. package/dist/common/error-handling/index.js.map +0 -1
  111. package/dist/common/logger/Logger.d.ts +0 -110
  112. package/dist/common/logger/Logger.d.ts.map +0 -1
  113. package/dist/common/logger/Logger.js +0 -289
  114. package/dist/common/logger/Logger.js.map +0 -1
  115. package/dist/common/logger/index.d.ts +0 -6
  116. package/dist/common/logger/index.d.ts.map +0 -1
  117. package/dist/common/logger/index.js +0 -6
  118. package/dist/common/logger/index.js.map +0 -1
  119. package/dist/common/types/cli.d.ts +0 -265
  120. package/dist/common/types/cli.d.ts.map +0 -1
  121. package/dist/common/types/cli.js +0 -5
  122. package/dist/common/types/cli.js.map +0 -1
  123. package/dist/common/types/core.d.ts +0 -270
  124. package/dist/common/types/core.d.ts.map +0 -1
  125. package/dist/common/types/core.js +0 -32
  126. package/dist/common/types/core.js.map +0 -1
  127. package/dist/common/types/index.d.ts +0 -8
  128. package/dist/common/types/index.d.ts.map +0 -1
  129. package/dist/common/types/index.js +0 -8
  130. package/dist/common/types/index.js.map +0 -1
  131. package/dist/common/utils/VersionChecker.d.ts +0 -54
  132. package/dist/common/utils/VersionChecker.d.ts.map +0 -1
  133. package/dist/common/utils/VersionChecker.js +0 -180
  134. package/dist/common/utils/VersionChecker.js.map +0 -1
  135. package/dist/common/utils/async.d.ts +0 -74
  136. package/dist/common/utils/async.d.ts.map +0 -1
  137. package/dist/common/utils/async.js +0 -228
  138. package/dist/common/utils/async.js.map +0 -1
  139. package/dist/common/utils/format.d.ts +0 -32
  140. package/dist/common/utils/format.d.ts.map +0 -1
  141. package/dist/common/utils/format.js +0 -121
  142. package/dist/common/utils/format.js.map +0 -1
  143. package/dist/common/utils/git.d.ts +0 -44
  144. package/dist/common/utils/git.d.ts.map +0 -1
  145. package/dist/common/utils/git.js +0 -147
  146. package/dist/common/utils/git.js.map +0 -1
  147. package/dist/common/utils/index.d.ts +0 -12
  148. package/dist/common/utils/index.d.ts.map +0 -1
  149. package/dist/common/utils/index.js +0 -12
  150. package/dist/common/utils/index.js.map +0 -1
  151. package/dist/common/utils/string.d.ts +0 -56
  152. package/dist/common/utils/string.d.ts.map +0 -1
  153. package/dist/common/utils/string.js +0 -134
  154. package/dist/common/utils/string.js.map +0 -1
  155. package/dist/common/utils/validation.d.ts +0 -88
  156. package/dist/common/utils/validation.d.ts.map +0 -1
  157. package/dist/common/utils/validation.js +0 -308
  158. package/dist/common/utils/validation.js.map +0 -1
  159. package/dist/domain/entities/Catalog.d.ts +0 -117
  160. package/dist/domain/entities/Catalog.d.ts.map +0 -1
  161. package/dist/domain/entities/Catalog.js +0 -240
  162. package/dist/domain/entities/Catalog.js.map +0 -1
  163. package/dist/domain/entities/Package.d.ts +0 -143
  164. package/dist/domain/entities/Package.d.ts.map +0 -1
  165. package/dist/domain/entities/Package.js +0 -272
  166. package/dist/domain/entities/Package.js.map +0 -1
  167. package/dist/domain/entities/Workspace.d.ts +0 -95
  168. package/dist/domain/entities/Workspace.d.ts.map +0 -1
  169. package/dist/domain/entities/Workspace.js +0 -173
  170. package/dist/domain/entities/Workspace.js.map +0 -1
  171. package/dist/domain/repositories/WorkspaceRepository.d.ts +0 -41
  172. package/dist/domain/repositories/WorkspaceRepository.d.ts.map +0 -1
  173. package/dist/domain/repositories/WorkspaceRepository.js +0 -8
  174. package/dist/domain/repositories/WorkspaceRepository.js.map +0 -1
  175. package/dist/domain/value-objects/CatalogCollection.d.ts +0 -106
  176. package/dist/domain/value-objects/CatalogCollection.d.ts.map +0 -1
  177. package/dist/domain/value-objects/CatalogCollection.js +0 -230
  178. package/dist/domain/value-objects/CatalogCollection.js.map +0 -1
  179. package/dist/domain/value-objects/PackageCollection.d.ts +0 -122
  180. package/dist/domain/value-objects/PackageCollection.d.ts.map +0 -1
  181. package/dist/domain/value-objects/PackageCollection.js +0 -263
  182. package/dist/domain/value-objects/PackageCollection.js.map +0 -1
  183. package/dist/domain/value-objects/Version.d.ts +0 -141
  184. package/dist/domain/value-objects/Version.d.ts.map +0 -1
  185. package/dist/domain/value-objects/Version.js +0 -268
  186. package/dist/domain/value-objects/Version.js.map +0 -1
  187. package/dist/domain/value-objects/WorkspaceConfig.d.ts +0 -144
  188. package/dist/domain/value-objects/WorkspaceConfig.d.ts.map +0 -1
  189. package/dist/domain/value-objects/WorkspaceConfig.js +0 -357
  190. package/dist/domain/value-objects/WorkspaceConfig.js.map +0 -1
  191. package/dist/domain/value-objects/WorkspaceId.d.ts +0 -51
  192. package/dist/domain/value-objects/WorkspaceId.d.ts.map +0 -1
  193. package/dist/domain/value-objects/WorkspaceId.js +0 -104
  194. package/dist/domain/value-objects/WorkspaceId.js.map +0 -1
  195. package/dist/domain/value-objects/WorkspacePath.d.ts +0 -75
  196. package/dist/domain/value-objects/WorkspacePath.d.ts.map +0 -1
  197. package/dist/domain/value-objects/WorkspacePath.js +0 -128
  198. package/dist/domain/value-objects/WorkspacePath.js.map +0 -1
  199. package/dist/index.d.ts +0 -25
  200. package/dist/index.d.ts.map +0 -1
  201. package/dist/infrastructure/cache/Cache.d.ts +0 -161
  202. package/dist/infrastructure/cache/Cache.d.ts.map +0 -1
  203. package/dist/infrastructure/cache/Cache.js +0 -398
  204. package/dist/infrastructure/cache/Cache.js.map +0 -1
  205. package/dist/infrastructure/cache/index.d.ts +0 -6
  206. package/dist/infrastructure/cache/index.d.ts.map +0 -1
  207. package/dist/infrastructure/cache/index.js +0 -6
  208. package/dist/infrastructure/cache/index.js.map +0 -1
  209. package/dist/infrastructure/external-services/NpmRegistryService.d.ts +0 -153
  210. package/dist/infrastructure/external-services/NpmRegistryService.d.ts.map +0 -1
  211. package/dist/infrastructure/external-services/NpmRegistryService.js +0 -511
  212. package/dist/infrastructure/external-services/NpmRegistryService.js.map +0 -1
  213. package/dist/infrastructure/file-system/FileSystemService.d.ts +0 -120
  214. package/dist/infrastructure/file-system/FileSystemService.d.ts.map +0 -1
  215. package/dist/infrastructure/file-system/FileSystemService.js +0 -663
  216. package/dist/infrastructure/file-system/FileSystemService.js.map +0 -1
  217. package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts +0 -57
  218. package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts.map +0 -1
  219. package/dist/infrastructure/repositories/FileWorkspaceRepository.js +0 -179
  220. package/dist/infrastructure/repositories/FileWorkspaceRepository.js.map +0 -1
  221. package/dist/infrastructure/utils/NpmrcParser.d.ts +0 -40
  222. package/dist/infrastructure/utils/NpmrcParser.d.ts.map +0 -1
  223. package/dist/infrastructure/utils/NpmrcParser.js +0 -157
  224. package/dist/infrastructure/utils/NpmrcParser.js.map +0 -1
@@ -1,839 +0,0 @@
1
- /**
2
- * Catalog Update Service
3
- *
4
- * Core application service that handles catalog dependency updates.
5
- * Orchestrates domain objects and infrastructure services to provide
6
- * high-level use cases for checking and updating catalog dependencies.
7
- */
8
- import { WorkspacePath } from '../../domain/value-objects/WorkspacePath.js';
9
- import { Version } from '../../domain/value-objects/Version.js';
10
- import { NpmRegistryService } from '../../infrastructure/external-services/NpmRegistryService.js';
11
- import { ConfigLoader } from '../../common/config/ConfigLoader.js';
12
- import { UserFriendlyErrorHandler } from '../../common/error-handling/UserFriendlyErrorHandler.js';
13
- import { ProgressBar } from '../../cli/formatters/ProgressBar.js';
14
- export class CatalogUpdateService {
15
- workspaceRepository;
16
- registryService;
17
- constructor(workspaceRepository, registryService) {
18
- this.workspaceRepository = workspaceRepository;
19
- this.registryService = registryService;
20
- }
21
- /**
22
- * Create a new CatalogUpdateService with advanced configuration
23
- */
24
- static createWithConfig(workspaceRepository, workspacePath) {
25
- const config = ConfigLoader.loadConfig(workspacePath || process.cwd());
26
- // Create registry service with advanced configuration
27
- const advancedConfig = {};
28
- if (config.advanced?.concurrency !== undefined) {
29
- advancedConfig.concurrency = config.advanced.concurrency;
30
- }
31
- if (config.advanced?.timeout !== undefined) {
32
- advancedConfig.timeout = config.advanced.timeout;
33
- }
34
- if (config.advanced?.retries !== undefined) {
35
- advancedConfig.retries = config.advanced.retries;
36
- }
37
- if (config.advanced?.cacheValidityMinutes !== undefined) {
38
- advancedConfig.cacheValidityMinutes = config.advanced.cacheValidityMinutes;
39
- }
40
- // Use default registry for now, npmrc will handle scoped registries
41
- const registryUrl = 'https://registry.npmjs.org/';
42
- const workingDirectory = workspacePath || process.cwd();
43
- const registryService = new NpmRegistryService(registryUrl, advancedConfig, workingDirectory);
44
- return new CatalogUpdateService(workspaceRepository, registryService);
45
- }
46
- /**
47
- * Check for outdated catalog dependencies
48
- */
49
- async checkOutdatedDependencies(options = {}) {
50
- const workspacePath = WorkspacePath.fromString(options.workspacePath || process.cwd());
51
- // Load configuration
52
- const config = ConfigLoader.loadConfig(workspacePath.toString());
53
- // Load workspace
54
- const workspace = await this.workspaceRepository.findByPath(workspacePath);
55
- if (!workspace) {
56
- throw new Error(`No pnpm workspace found at ${workspacePath.toString()}`);
57
- }
58
- const catalogs = workspace.getCatalogs();
59
- const catalogInfos = [];
60
- let totalOutdated = 0;
61
- // Filter catalogs if specific catalog requested
62
- const catalogsToCheck = options.catalogName
63
- ? [catalogs.get(options.catalogName)].filter(Boolean)
64
- : catalogs.getAll();
65
- if (catalogsToCheck.length === 0) {
66
- throw new Error(options.catalogName
67
- ? `Catalog "${options.catalogName}" not found`
68
- : 'No catalogs found in workspace');
69
- }
70
- // Calculate total packages across all catalogs
71
- let totalPackages = 0;
72
- const allPackagesToCheck = [];
73
- for (const catalog of catalogsToCheck) {
74
- if (!catalog)
75
- continue;
76
- const dependencies = catalog.getDependencies();
77
- const packageArray = Array.from(dependencies);
78
- const packagesToCheck = packageArray.filter(([packageName]) => {
79
- const packageConfig = ConfigLoader.getPackageConfig(packageName, config);
80
- return packageConfig.shouldUpdate;
81
- });
82
- // Add catalog info to each package for processing
83
- packagesToCheck.forEach(([packageName, range]) => {
84
- allPackagesToCheck.push([packageName, range, catalog]);
85
- });
86
- totalPackages += packagesToCheck.length;
87
- }
88
- // Create a single progress bar for all catalogs
89
- let progressBar = null;
90
- if (totalPackages > 0) {
91
- progressBar = new ProgressBar({
92
- text: 'ๆญฃๅœจๆฃ€ๆŸฅไพ่ต–ๅŒ…...',
93
- total: totalPackages,
94
- });
95
- progressBar.start(`ๆญฃๅœจๆฃ€ๆŸฅ ${totalPackages} ไธชไพ่ต–ๅŒ…...`);
96
- }
97
- let completed = 0;
98
- // Check each catalog for outdated dependencies
99
- for (const catalog of catalogsToCheck) {
100
- if (!catalog) {
101
- throw new Error(`Catalog "${catalogsToCheck[0]?.getName() || 'unknown'}" not found`);
102
- }
103
- const dependencies = catalog.getDependencies();
104
- // Convert to array for parallel processing
105
- const packageArray = Array.from(dependencies);
106
- // Filter packages that should be updated based on configuration
107
- const packagesToCheck = packageArray.filter(([packageName]) => {
108
- const packageConfig = ConfigLoader.getPackageConfig(packageName, config);
109
- return packageConfig.shouldUpdate;
110
- });
111
- // Process packages in parallel with concurrency control (pass progress info)
112
- const outdatedDependencies = await this.processPackagesInParallel(packagesToCheck, catalog, workspace, config, options, progressBar, completed, totalPackages);
113
- // Update completed count
114
- completed += packagesToCheck.length;
115
- const catalogInfo = {
116
- catalogName: catalog.getName(),
117
- outdatedDependencies,
118
- totalPackages: dependencies.size,
119
- outdatedCount: outdatedDependencies.length,
120
- };
121
- catalogInfos.push(catalogInfo);
122
- totalOutdated += outdatedDependencies.length;
123
- }
124
- // Complete the progress bar
125
- if (progressBar) {
126
- if (totalOutdated > 0) {
127
- progressBar.succeed(`โœ… ๆฃ€ๆŸฅๅฎŒๆˆ! ๅ‘็Žฐ ${totalOutdated} ไธชๅฏๆ›ดๆ–ฐ็š„ไพ่ต–ๅŒ…`);
128
- }
129
- else {
130
- progressBar.succeed('โœ… ๆฃ€ๆŸฅๅฎŒๆˆ! ๆ‰€ๆœ‰ไพ่ต–ๅŒ…้ƒฝๆ˜ฏๆœ€ๆ–ฐ็š„');
131
- }
132
- }
133
- return {
134
- workspace: {
135
- path: workspacePath.toString(),
136
- name: workspacePath.getDirectoryName(),
137
- },
138
- catalogs: catalogInfos,
139
- totalOutdated,
140
- hasUpdates: totalOutdated > 0,
141
- };
142
- }
143
- /**
144
- * Plan catalog dependency updates
145
- */
146
- async planUpdates(options) {
147
- const outdatedReport = await this.checkOutdatedDependencies(options);
148
- const updates = [];
149
- const conflicts = [];
150
- // Load configuration for package rules and monorepo settings
151
- const workspacePath = options.workspacePath || process.cwd();
152
- const config = ConfigLoader.loadConfig(workspacePath);
153
- // Convert outdated dependencies to planned updates
154
- for (const catalogInfo of outdatedReport.catalogs) {
155
- for (const outdated of catalogInfo.outdatedDependencies) {
156
- // Get package-specific configuration
157
- const packageConfig = ConfigLoader.getPackageConfig(outdated.packageName, config);
158
- const update = {
159
- catalogName: catalogInfo.catalogName,
160
- packageName: outdated.packageName,
161
- currentVersion: outdated.currentVersion,
162
- newVersion: outdated.latestVersion,
163
- updateType: outdated.updateType,
164
- reason: this.getUpdateReason(outdated),
165
- affectedPackages: outdated.affectedPackages,
166
- requireConfirmation: packageConfig.requireConfirmation,
167
- autoUpdate: packageConfig.autoUpdate,
168
- groupUpdate: packageConfig.groupUpdate,
169
- };
170
- updates.push(update);
171
- }
172
- }
173
- // Handle syncVersions - ensure packages in syncVersions list are synchronized across catalogs
174
- if (config.monorepo?.syncVersions && config.monorepo.syncVersions.length > 0) {
175
- const workspacePathObj = WorkspacePath.fromString(workspacePath);
176
- const workspace = await this.workspaceRepository.findByPath(workspacePathObj);
177
- if (workspace) {
178
- updates.push(...(await this.createSyncVersionUpdates(config.monorepo.syncVersions, workspace, updates)));
179
- }
180
- }
181
- // Detect conflicts (same package in multiple catalogs with different versions)
182
- const packageCatalogMap = new Map();
183
- for (const update of updates) {
184
- if (!packageCatalogMap.has(update.packageName)) {
185
- packageCatalogMap.set(update.packageName, []);
186
- }
187
- packageCatalogMap.get(update.packageName).push(update);
188
- }
189
- // Handle conflicts with catalogPriority
190
- for (const [packageName, packageUpdates] of packageCatalogMap) {
191
- if (packageUpdates.length > 1) {
192
- const uniqueVersions = new Set(packageUpdates.map((u) => u.newVersion));
193
- if (uniqueVersions.size > 1) {
194
- const resolvedConflict = this.resolveVersionConflict(packageName, packageUpdates, config.monorepo?.catalogPriority || ['default']);
195
- if (resolvedConflict) {
196
- conflicts.push(resolvedConflict);
197
- }
198
- }
199
- }
200
- }
201
- return {
202
- workspace: outdatedReport.workspace,
203
- updates,
204
- conflicts,
205
- totalUpdates: updates.length,
206
- hasConflicts: conflicts.length > 0,
207
- };
208
- }
209
- /**
210
- * Execute catalog dependency updates
211
- */
212
- async executeUpdates(plan, options) {
213
- const workspacePath = WorkspacePath.fromString(plan.workspace.path);
214
- // Load configuration for security settings
215
- const config = ConfigLoader.loadConfig(workspacePath.toString());
216
- // Load workspace
217
- const workspace = await this.workspaceRepository.findByPath(workspacePath);
218
- if (!workspace) {
219
- throw new Error(`Workspace not found at ${workspacePath.toString()}`);
220
- }
221
- const updatedDependencies = [];
222
- const skippedDependencies = [];
223
- const errors = [];
224
- // Track security updates for notification
225
- const securityUpdates = [];
226
- // Execute updates
227
- for (const update of plan.updates) {
228
- try {
229
- // Skip if conflicts exist and force is not enabled
230
- if (plan.hasConflicts && !options.force) {
231
- const hasConflict = plan.conflicts.some((c) => c.packageName === update.packageName);
232
- if (hasConflict) {
233
- skippedDependencies.push({
234
- catalogName: update.catalogName,
235
- packageName: update.packageName,
236
- currentVersion: update.currentVersion,
237
- reason: 'Version conflict - use --force to override',
238
- });
239
- continue;
240
- }
241
- }
242
- // Check if this is a security update and track it
243
- let isSecurityUpdate = false;
244
- if (config.security?.notifyOnSecurityUpdate) {
245
- try {
246
- const securityReport = await this.registryService.checkSecurityVulnerabilities(update.packageName, update.currentVersion);
247
- if (securityReport.hasVulnerabilities) {
248
- isSecurityUpdate = true;
249
- securityUpdates.push(`${update.packageName}@${update.currentVersion} โ†’ ${update.newVersion}`);
250
- }
251
- }
252
- catch (error) {
253
- UserFriendlyErrorHandler.handleSecurityCheckFailure(update.packageName, error, { operation: 'update' });
254
- }
255
- }
256
- // Perform the update
257
- workspace.updateCatalogDependency(update.catalogName, update.packageName, update.newVersion);
258
- updatedDependencies.push({
259
- catalogName: update.catalogName,
260
- packageName: update.packageName,
261
- fromVersion: update.currentVersion,
262
- toVersion: update.newVersion,
263
- updateType: update.updateType,
264
- });
265
- // Log security update notification
266
- if (isSecurityUpdate && config.security?.notifyOnSecurityUpdate) {
267
- console.log(`โœ… Security fix applied: ${update.packageName}@${update.currentVersion} โ†’ ${update.newVersion}`);
268
- }
269
- }
270
- catch (error) {
271
- errors.push({
272
- catalogName: update.catalogName,
273
- packageName: update.packageName,
274
- error: String(error),
275
- fatal: false,
276
- });
277
- }
278
- }
279
- // Save workspace if not in dry-run mode
280
- if (!options.dryRun && updatedDependencies.length > 0) {
281
- try {
282
- await this.workspaceRepository.save(workspace);
283
- // Show summary of security updates if any
284
- if (securityUpdates.length > 0 && config.security?.notifyOnSecurityUpdate) {
285
- console.log(`\n๐Ÿ”’ Security Updates Summary:`);
286
- console.log(` Applied ${securityUpdates.length} security fix(es):`);
287
- securityUpdates.forEach((update) => console.log(` โ€ข ${update}`));
288
- }
289
- // Show summary of synced version updates
290
- const syncUpdates = updatedDependencies.filter((u) => plan.updates.find((pu) => pu.packageName === u.packageName &&
291
- pu.catalogName === u.catalogName &&
292
- pu.reason.includes('Sync version')));
293
- if (syncUpdates.length > 0) {
294
- console.log(`\n๐Ÿ”„ Version Sync Summary:`);
295
- const syncedPackages = new Set(syncUpdates.map((u) => u.packageName));
296
- console.log(` Synchronized ${syncedPackages.size} package(s) across catalogs:`);
297
- // Group by package name
298
- const syncByPackage = new Map();
299
- syncUpdates.forEach((update) => {
300
- if (!syncByPackage.has(update.packageName)) {
301
- syncByPackage.set(update.packageName, []);
302
- }
303
- syncByPackage.get(update.packageName).push(update);
304
- });
305
- syncByPackage.forEach((updates, packageName) => {
306
- const catalogs = updates.map((u) => u.catalogName).join(', ');
307
- const version = updates[0]?.toVersion;
308
- console.log(` โ€ข ${packageName}@${version} in catalogs: ${catalogs}`);
309
- });
310
- }
311
- // Show catalog priority resolution if any
312
- if (plan.hasConflicts &&
313
- plan.conflicts.some((c) => c.recommendation.includes('Priority catalog'))) {
314
- console.log(`\n๐Ÿ“‹ Catalog Priority Resolutions:`);
315
- plan.conflicts
316
- .filter((c) => c.recommendation.includes('Priority catalog'))
317
- .forEach((conflict) => {
318
- console.log(` โ€ข ${conflict.packageName}: ${conflict.recommendation}`);
319
- });
320
- }
321
- }
322
- catch (error) {
323
- errors.push({
324
- catalogName: '',
325
- packageName: '',
326
- error: `Failed to save workspace: ${error}`,
327
- fatal: true,
328
- });
329
- }
330
- }
331
- return {
332
- success: errors.filter((e) => e.fatal).length === 0,
333
- workspace: plan.workspace,
334
- updatedDependencies,
335
- skippedDependencies,
336
- errors,
337
- totalUpdated: updatedDependencies.length,
338
- totalSkipped: skippedDependencies.length,
339
- totalErrors: errors.length,
340
- };
341
- }
342
- /**
343
- * Analyze the impact of updating a specific dependency
344
- */
345
- async analyzeImpact(catalogName, packageName, newVersion, workspacePath) {
346
- const wsPath = WorkspacePath.fromString(workspacePath || process.cwd());
347
- // Load workspace
348
- const workspace = await this.workspaceRepository.findByPath(wsPath);
349
- if (!workspace) {
350
- throw new Error(`No pnpm workspace found at ${wsPath.toString()}`);
351
- }
352
- const catalog = workspace.getCatalogs().get(catalogName);
353
- if (!catalog) {
354
- throw new Error(`Catalog "${catalogName}" not found`);
355
- }
356
- const currentRange = catalog.getDependencyVersion(packageName);
357
- if (!currentRange) {
358
- throw new Error(`Package "${packageName}" not found in catalog "${catalogName}"`);
359
- }
360
- const currentVersion = currentRange.toString();
361
- const proposedVersion = Version.fromString(newVersion);
362
- const currentVersionObj = currentRange.getMinVersion();
363
- if (!currentVersionObj) {
364
- throw new Error(`Cannot determine current version for ${packageName}`);
365
- }
366
- const updateType = currentVersionObj.getDifferenceType(proposedVersion);
367
- // Get affected packages
368
- const affectedPackagesCollection = workspace.getPackagesUsingCatalogDependency(catalogName, packageName);
369
- const packageImpacts = [];
370
- for (const pkg of affectedPackagesCollection.getAll()) {
371
- const catalogRefs = pkg
372
- .getCatalogReferences()
373
- .filter((ref) => ref.getCatalogName() === catalogName && ref.getPackageName() === packageName);
374
- for (const ref of catalogRefs) {
375
- const isBreakingChange = updateType === 'major';
376
- const compatibilityRisk = this.assessCompatibilityRisk(updateType);
377
- packageImpacts.push({
378
- packageName: pkg.getName(),
379
- packagePath: pkg.getPath().toString(),
380
- dependencyType: ref.getDependencyType(),
381
- isBreakingChange,
382
- compatibilityRisk,
383
- });
384
- }
385
- }
386
- // Check security impact
387
- const securityImpact = await this.analyzeSecurityImpact(packageName, currentVersion, newVersion);
388
- // Assess overall risk
389
- const riskLevel = this.assessOverallRisk(updateType, packageImpacts, securityImpact);
390
- // Generate recommendations
391
- const recommendations = this.generateRecommendations(updateType, securityImpact, packageImpacts);
392
- return {
393
- packageName,
394
- catalogName,
395
- currentVersion,
396
- proposedVersion: newVersion,
397
- updateType: updateType,
398
- affectedPackages: packageImpacts,
399
- riskLevel,
400
- securityImpact,
401
- recommendations,
402
- };
403
- }
404
- /**
405
- * Process packages in parallel with concurrency control and progress tracking
406
- */
407
- async processPackagesInParallel(packagesToCheck, catalog, workspace, config, options, progressBar, startingCompleted = 0, totalPackages = 0) {
408
- const concurrency = config.advanced?.concurrency || 8; // Increased from 5 to match NCU
409
- const outdatedDependencies = [];
410
- let completed = startingCompleted;
411
- // Process packages in chunks with true parallelism within each chunk
412
- const chunks = this.chunkArray(packagesToCheck, concurrency);
413
- for (const chunk of chunks) {
414
- const chunkResults = await Promise.all(chunk.map(async ([packageName, currentRange]) => {
415
- try {
416
- const result = await this.processPackageCheck(packageName, currentRange, catalog, workspace, config, options);
417
- // Update progress for successful package
418
- completed++;
419
- if (progressBar && totalPackages > 0) {
420
- progressBar.update(`ๆญฃๅœจๆฃ€ๆŸฅไพ่ต–ๅŒ…: ${packageName}`, completed, totalPackages);
421
- }
422
- return result;
423
- }
424
- catch (error) {
425
- // Update progress even for failed packages
426
- completed++;
427
- if (progressBar && totalPackages > 0) {
428
- progressBar.update(`่ทณ่ฟ‡ๅŒ… ${packageName} (ๆฃ€ๆŸฅๅคฑ่ดฅ)`, completed, totalPackages);
429
- }
430
- UserFriendlyErrorHandler.handlePackageQueryFailure(packageName, error, {
431
- operation: 'check',
432
- });
433
- return null;
434
- }
435
- }));
436
- // Add successful results to the array
437
- chunkResults.forEach((result) => {
438
- if (result) {
439
- outdatedDependencies.push(result);
440
- }
441
- });
442
- }
443
- return outdatedDependencies;
444
- }
445
- /**
446
- * Process a single package check (extracted from the main loop)
447
- */
448
- async processPackageCheck(packageName, currentRange, catalog, workspace, config, options) {
449
- // Get package-specific configuration
450
- const packageConfig = ConfigLoader.getPackageConfig(packageName, config);
451
- const effectiveTarget = packageConfig.target;
452
- // Defer security checks - only do them after we know the package needs updating
453
- const outdatedInfo = await this.checkPackageUpdate(packageName, currentRange, effectiveTarget, options.includePrerelease || config.defaults?.includePrerelease || false);
454
- if (!outdatedInfo) {
455
- return null; // Package doesn't need updating
456
- }
457
- // Now check for security vulnerabilities only for packages that need updating
458
- let hasSecurityVulnerabilities = false;
459
- if (config.security?.autoFixVulnerabilities) {
460
- try {
461
- const currentVersion = currentRange.getMinVersion()?.toString();
462
- if (currentVersion) {
463
- const securityReport = await this.registryService.checkSecurityVulnerabilities(packageName, currentVersion);
464
- hasSecurityVulnerabilities = securityReport.hasVulnerabilities;
465
- // Allow major updates for security fixes if configured
466
- if (hasSecurityVulnerabilities && config.security.allowMajorForSecurity) {
467
- // Re-check with 'latest' target if security fix requires it
468
- const securityFixInfo = await this.checkPackageUpdate(packageName, currentRange, 'latest', options.includePrerelease || config.defaults?.includePrerelease || false);
469
- if (securityFixInfo) {
470
- Object.assign(outdatedInfo, securityFixInfo);
471
- }
472
- }
473
- }
474
- }
475
- catch (error) {
476
- UserFriendlyErrorHandler.handleSecurityCheckFailure(packageName, error);
477
- }
478
- }
479
- // Get affected packages
480
- const affectedPackages = workspace
481
- .getPackagesUsingCatalogDependency(catalog.getName(), packageName)
482
- .getPackageNames();
483
- // Log security notifications if enabled
484
- if (hasSecurityVulnerabilities && config.security?.notifyOnSecurityUpdate) {
485
- console.warn(`๐Ÿ”’ Security vulnerability detected in ${packageName}@${outdatedInfo.currentVersion}`);
486
- }
487
- return {
488
- ...outdatedInfo,
489
- affectedPackages,
490
- isSecurityUpdate: hasSecurityVulnerabilities || outdatedInfo.isSecurityUpdate,
491
- };
492
- }
493
- /**
494
- * Split array into chunks for parallel processing
495
- */
496
- chunkArray(array, chunkSize) {
497
- const chunks = [];
498
- for (let i = 0; i < array.length; i += chunkSize) {
499
- chunks.push(array.slice(i, i + chunkSize));
500
- }
501
- return chunks;
502
- }
503
- /**
504
- * Check if a package needs updating
505
- */
506
- async checkPackageUpdate(packageName, currentRange, target, includePrerelease) {
507
- try {
508
- // Use lightweight version API for better performance
509
- const versionInfo = await this.registryService.getPackageVersions(packageName);
510
- let targetVersion;
511
- switch (target) {
512
- case 'latest':
513
- targetVersion = Version.fromString(versionInfo.latestVersion);
514
- break;
515
- case 'greatest':
516
- targetVersion = await this.registryService.getGreatestVersion(packageName);
517
- break;
518
- case 'newest':
519
- const newestVersions = await this.registryService.getNewestVersions(packageName, 1);
520
- if (!newestVersions[0]) {
521
- throw new Error(`No versions found for ${packageName}`);
522
- }
523
- targetVersion = newestVersions[0];
524
- break;
525
- case 'minor':
526
- case 'patch':
527
- targetVersion = await this.getConstrainedVersion(packageName, currentRange, target);
528
- break;
529
- default:
530
- targetVersion = Version.fromString(versionInfo.latestVersion);
531
- }
532
- // Skip prereleases unless explicitly requested
533
- if (!includePrerelease && targetVersion.isPrerelease()) {
534
- return null;
535
- }
536
- const currentVersion = currentRange.getMinVersion();
537
- if (!currentVersion) {
538
- return null;
539
- }
540
- // Check if update is needed
541
- if (!targetVersion.isNewerThan(currentVersion)) {
542
- return null;
543
- }
544
- const updateType = currentVersion.getDifferenceType(targetVersion);
545
- // Check for security vulnerabilities
546
- const securityReport = await this.registryService.checkSecurityVulnerabilities(packageName, currentVersion.toString());
547
- return {
548
- packageName,
549
- currentVersion: currentVersion.toString(),
550
- latestVersion: targetVersion.toString(),
551
- wantedVersion: targetVersion.toString(),
552
- updateType: updateType,
553
- isSecurityUpdate: securityReport.hasVulnerabilities,
554
- affectedPackages: [], // Will be filled by caller
555
- };
556
- }
557
- catch (error) {
558
- UserFriendlyErrorHandler.handlePackageQueryFailure(packageName, error, {
559
- operation: 'update-check',
560
- });
561
- return null;
562
- }
563
- }
564
- /**
565
- * Get version constrained by update type
566
- */
567
- async getConstrainedVersion(packageName, currentRange, constraint) {
568
- const currentVersion = currentRange.getMinVersion();
569
- if (!currentVersion) {
570
- throw new Error(`Cannot determine current version for ${packageName}`);
571
- }
572
- const versionInfo = await this.registryService.getPackageVersions(packageName);
573
- // Filter versions based on constraint
574
- const compatibleVersions = versionInfo.versions.filter((v) => {
575
- try {
576
- const version = Version.fromString(v);
577
- const diff = currentVersion.getDifferenceType(version);
578
- if (constraint === 'patch') {
579
- return diff === 'patch' || diff === 'same';
580
- }
581
- else if (constraint === 'minor') {
582
- return diff === 'minor' || diff === 'patch' || diff === 'same';
583
- }
584
- return false;
585
- }
586
- catch {
587
- return false;
588
- }
589
- });
590
- if (compatibleVersions.length === 0) {
591
- return currentVersion;
592
- }
593
- // Return the highest compatible version
594
- if (!compatibleVersions[0]) {
595
- throw new Error(`No compatible versions found for ${packageName}`);
596
- }
597
- return Version.fromString(compatibleVersions[0]);
598
- }
599
- /**
600
- * Generate update reason description
601
- */
602
- getUpdateReason(outdated) {
603
- if (outdated.isSecurityUpdate) {
604
- return 'Security update available';
605
- }
606
- switch (outdated.updateType) {
607
- case 'major':
608
- return 'Major version update available';
609
- case 'minor':
610
- return 'Minor version update available';
611
- case 'patch':
612
- return 'Patch version update available';
613
- default:
614
- return 'Update available';
615
- }
616
- }
617
- /**
618
- * Analyze security impact of version change
619
- */
620
- async analyzeSecurityImpact(packageName, currentVersion, newVersion) {
621
- try {
622
- const [currentSecurity, newSecurity] = await Promise.all([
623
- this.registryService.checkSecurityVulnerabilities(packageName, currentVersion),
624
- this.registryService.checkSecurityVulnerabilities(packageName, newVersion),
625
- ]);
626
- const fixedVulnerabilities = currentSecurity.vulnerabilities.length - newSecurity.vulnerabilities.length;
627
- const newVulnerabilities = Math.max(0, newSecurity.vulnerabilities.length - currentSecurity.vulnerabilities.length);
628
- let severityChange = 'same';
629
- if (fixedVulnerabilities > 0) {
630
- severityChange = 'better';
631
- }
632
- else if (newVulnerabilities > 0) {
633
- severityChange = 'worse';
634
- }
635
- return {
636
- hasVulnerabilities: currentSecurity.hasVulnerabilities || newSecurity.hasVulnerabilities,
637
- fixedVulnerabilities: Math.max(0, fixedVulnerabilities),
638
- newVulnerabilities,
639
- severityChange,
640
- };
641
- }
642
- catch {
643
- return {
644
- hasVulnerabilities: false,
645
- fixedVulnerabilities: 0,
646
- newVulnerabilities: 0,
647
- severityChange: 'same',
648
- };
649
- }
650
- }
651
- /**
652
- * Assess compatibility risk for update type
653
- */
654
- assessCompatibilityRisk(updateType) {
655
- switch (updateType) {
656
- case 'patch':
657
- return 'low';
658
- case 'minor':
659
- return 'medium';
660
- case 'major':
661
- return 'high';
662
- default:
663
- return 'medium';
664
- }
665
- }
666
- /**
667
- * Assess overall risk level
668
- */
669
- assessOverallRisk(updateType, packageImpacts, securityImpact) {
670
- // Security fixes reduce risk
671
- if (securityImpact.fixedVulnerabilities > 0) {
672
- return updateType === 'major' ? 'medium' : 'low';
673
- }
674
- // New vulnerabilities increase risk
675
- if (securityImpact.newVulnerabilities > 0) {
676
- return 'high';
677
- }
678
- // Base risk on update type and number of affected packages
679
- const affectedPackageCount = packageImpacts.length;
680
- if (updateType === 'major') {
681
- return affectedPackageCount > 5 ? 'high' : 'medium';
682
- }
683
- else if (updateType === 'minor') {
684
- return affectedPackageCount > 10 ? 'medium' : 'low';
685
- }
686
- else {
687
- return 'low';
688
- }
689
- }
690
- /**
691
- * Generate recommendations based on analysis
692
- */
693
- generateRecommendations(updateType, securityImpact, packageImpacts) {
694
- const recommendations = [];
695
- if (securityImpact.fixedVulnerabilities > 0) {
696
- recommendations.push('๐Ÿ”’ Security update recommended - fixes known vulnerabilities');
697
- }
698
- if (securityImpact.newVulnerabilities > 0) {
699
- recommendations.push('โš ๏ธ New vulnerabilities detected - review carefully before updating');
700
- }
701
- if (updateType === 'major') {
702
- recommendations.push('๐Ÿ“– Review changelog for breaking changes before updating');
703
- recommendations.push('๐Ÿงช Test thoroughly in development environment');
704
- }
705
- const breakingChangePackages = packageImpacts.filter((p) => p.isBreakingChange);
706
- if (breakingChangePackages.length > 0) {
707
- recommendations.push(`๐Ÿ”ง ${breakingChangePackages.length} package(s) may need code changes`);
708
- }
709
- if (packageImpacts.length > 5) {
710
- recommendations.push('๐Ÿ“ฆ Many packages affected - consider updating in batches');
711
- }
712
- if (recommendations.length === 0) {
713
- recommendations.push('โœ… Low risk update - safe to proceed');
714
- }
715
- return recommendations;
716
- }
717
- /**
718
- * Create sync version updates for packages that should be synchronized across catalogs
719
- */
720
- async createSyncVersionUpdates(syncVersions, workspace, existingUpdates) {
721
- const syncUpdates = [];
722
- const catalogs = workspace.getCatalogs();
723
- const allCatalogs = catalogs.getAll();
724
- for (const packageName of syncVersions) {
725
- // Check if this package exists in multiple catalogs
726
- const catalogsWithPackage = allCatalogs.filter((catalog) => catalog && catalog.getDependencyVersion(packageName));
727
- if (catalogsWithPackage.length <= 1) {
728
- continue; // No need to sync if package is only in one catalog
729
- }
730
- // Find the highest version from existing updates or determine target version
731
- let targetVersion = null;
732
- let targetUpdateType = 'patch';
733
- // Check if this package has any existing updates
734
- const existingUpdate = existingUpdates.find((u) => u.packageName === packageName);
735
- if (existingUpdate) {
736
- targetVersion = existingUpdate.newVersion;
737
- targetUpdateType = existingUpdate.updateType;
738
- }
739
- else {
740
- // Get latest version for this package using lightweight API
741
- try {
742
- const versionInfo = await this.registryService.getPackageVersions(packageName);
743
- targetVersion = versionInfo.latestVersion;
744
- }
745
- catch (error) {
746
- UserFriendlyErrorHandler.handlePackageQueryFailure(packageName, error, {
747
- operation: 'sync',
748
- });
749
- continue;
750
- }
751
- }
752
- if (!targetVersion)
753
- continue;
754
- // Create sync updates for all catalogs that need updating
755
- for (const catalog of catalogsWithPackage) {
756
- const currentRange = catalog.getDependencyVersion(packageName);
757
- if (!currentRange)
758
- continue;
759
- const currentVersion = currentRange.getMinVersion();
760
- if (!currentVersion)
761
- continue;
762
- const currentVersionString = currentVersion.toString();
763
- // Skip if already at target version
764
- if (currentVersionString === targetVersion)
765
- continue;
766
- // Check if this update already exists
767
- const existingUpdateForCatalog = existingUpdates.find((u) => u.packageName === packageName && u.catalogName === catalog.getName());
768
- if (existingUpdateForCatalog) {
769
- // Update the existing update to use the sync version
770
- existingUpdateForCatalog.newVersion = targetVersion;
771
- existingUpdateForCatalog.reason = `Sync version across catalogs: ${existingUpdateForCatalog.reason}`;
772
- }
773
- else {
774
- // Create new sync update
775
- const affectedPackages = workspace
776
- .getPackagesUsingCatalogDependency(catalog.getName(), packageName)
777
- .getPackageNames();
778
- const syncUpdate = {
779
- catalogName: catalog.getName(),
780
- packageName: packageName,
781
- currentVersion: currentVersionString,
782
- newVersion: targetVersion,
783
- updateType: targetUpdateType,
784
- reason: `Sync version with other catalogs`,
785
- affectedPackages,
786
- requireConfirmation: true, // Sync updates should be confirmed
787
- autoUpdate: false,
788
- groupUpdate: true,
789
- };
790
- syncUpdates.push(syncUpdate);
791
- }
792
- }
793
- }
794
- return syncUpdates;
795
- }
796
- /**
797
- * Resolve version conflicts using catalog priority
798
- */
799
- resolveVersionConflict(packageName, packageUpdates, catalogPriority) {
800
- // Find the highest priority catalog with an update for this package
801
- let priorityCatalog = null;
802
- for (const catalogName of catalogPriority) {
803
- const catalogUpdate = packageUpdates.find((u) => u.catalogName === catalogName);
804
- if (catalogUpdate) {
805
- priorityCatalog = catalogUpdate;
806
- break;
807
- }
808
- }
809
- // If no priority catalog found, use the first one
810
- if (!priorityCatalog) {
811
- priorityCatalog = packageUpdates[0] || null;
812
- }
813
- // Update all other catalogs to use the priority catalog's version
814
- const priorityVersion = priorityCatalog?.newVersion;
815
- if (priorityVersion && priorityCatalog) {
816
- for (const update of packageUpdates) {
817
- if (update.catalogName !== priorityCatalog.catalogName) {
818
- update.newVersion = priorityVersion;
819
- update.reason = `Using version from priority catalog (${priorityCatalog.catalogName}): ${update.reason}`;
820
- }
821
- }
822
- }
823
- // Create conflict record for reporting
824
- const uniqueVersions = new Set(packageUpdates.map((u) => u.newVersion));
825
- if (uniqueVersions.size > 1) {
826
- return {
827
- packageName,
828
- catalogs: packageUpdates.map((u) => ({
829
- catalogName: u.catalogName,
830
- currentVersion: u.currentVersion,
831
- proposedVersion: u.newVersion,
832
- })),
833
- recommendation: `Resolved using catalog priority. Priority catalog '${priorityCatalog?.catalogName}' version '${priorityVersion}' selected.`,
834
- };
835
- }
836
- return null;
837
- }
838
- }
839
- //# sourceMappingURL=CatalogUpdateService.js.map