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.
Files changed (220) 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 -582
  21. package/README.md +0 -690
  22. package/README.zh-CN.md +0 -630
  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 -836
  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 -145
  210. package/dist/infrastructure/external-services/NpmRegistryService.d.ts.map +0 -1
  211. package/dist/infrastructure/external-services/NpmRegistryService.js +0 -466
  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
@@ -1,663 +0,0 @@
1
- /**
2
- * File System Service
3
- *
4
- * Provides abstracted file system operations for the application.
5
- * Handles reading/writing workspace files, package.json, and pnpm-workspace.yaml.
6
- */
7
- import fs from 'fs/promises';
8
- import { glob } from 'glob';
9
- import path from 'path';
10
- import YAML from 'yaml';
11
- export class FileSystemService {
12
- /**
13
- * Check if a file exists
14
- */
15
- async exists(filePath) {
16
- try {
17
- await fs.access(filePath);
18
- return true;
19
- }
20
- catch {
21
- return false;
22
- }
23
- }
24
- /**
25
- * Check if a path is a directory
26
- */
27
- async isDirectory(dirPath) {
28
- try {
29
- const stat = await fs.stat(dirPath);
30
- return stat.isDirectory();
31
- }
32
- catch {
33
- return false;
34
- }
35
- }
36
- /**
37
- * Read a text file
38
- */
39
- async readTextFile(filePath) {
40
- try {
41
- return await fs.readFile(filePath, 'utf-8');
42
- }
43
- catch (error) {
44
- throw new Error(`Failed to read file ${filePath}: ${error}`);
45
- }
46
- }
47
- /**
48
- * Write a text file
49
- */
50
- async writeTextFile(filePath, content) {
51
- try {
52
- // Ensure directory exists
53
- await fs.mkdir(path.dirname(filePath), { recursive: true });
54
- await fs.writeFile(filePath, content, 'utf-8');
55
- }
56
- catch (error) {
57
- throw new Error(`Failed to write file ${filePath}: ${error}`);
58
- }
59
- }
60
- /**
61
- * Read and parse a JSON file
62
- */
63
- async readJsonFile(filePath) {
64
- try {
65
- const content = await this.readTextFile(filePath);
66
- return JSON.parse(content);
67
- }
68
- catch (error) {
69
- throw new Error(`Failed to read JSON file ${filePath}: ${error}`);
70
- }
71
- }
72
- /**
73
- * Write a JSON file
74
- */
75
- async writeJsonFile(filePath, data, indent = 2) {
76
- try {
77
- const content = JSON.stringify(data, null, indent);
78
- await this.writeTextFile(filePath, content);
79
- }
80
- catch (error) {
81
- throw new Error(`Failed to write JSON file ${filePath}: ${error}`);
82
- }
83
- }
84
- /**
85
- * Read and parse a YAML file
86
- */
87
- async readYamlFile(filePath) {
88
- try {
89
- const content = await this.readTextFile(filePath);
90
- return YAML.parse(content);
91
- }
92
- catch (error) {
93
- throw new Error(`Failed to read YAML file ${filePath}: ${error}`);
94
- }
95
- }
96
- /**
97
- * Write a YAML file
98
- */
99
- async writeYamlFile(filePath, data) {
100
- try {
101
- const content = YAML.stringify(data, {
102
- indent: 2,
103
- });
104
- await this.writeTextFile(filePath, content);
105
- }
106
- catch (error) {
107
- throw new Error(`Failed to write YAML file ${filePath}: ${error}`);
108
- }
109
- }
110
- /**
111
- * Write a YAML file while preserving comments and formatting
112
- */
113
- async writeYamlFilePreservingFormat(filePath, data) {
114
- try {
115
- // Read the original file to preserve comments and formatting
116
- const originalContent = await this.readTextFile(filePath);
117
- // Use smart YAML updating that preserves comments and formatting
118
- const updatedContent = this.updateYamlPreservingFormat(originalContent, data);
119
- await this.writeTextFile(filePath, updatedContent);
120
- }
121
- catch (error) {
122
- // If reading the original file fails, fall back to regular YAML writing
123
- console.warn(`Could not preserve YAML format for ${filePath}, falling back to standard formatting`);
124
- await this.writeYamlFile(filePath, data);
125
- }
126
- }
127
- /**
128
- * Update YAML content while preserving comments and formatting
129
- */
130
- updateYamlPreservingFormat(originalContent, newData) {
131
- const lines = originalContent.split('\n');
132
- const result = [];
133
- let i = 0;
134
- // Helper function to update a specific section
135
- const updateSection = (sectionName, newValue) => {
136
- if (!(sectionName in newData)) {
137
- return false;
138
- }
139
- // Find the section in the original content
140
- let sectionStartIndex = -1;
141
- let sectionEndIndex = -1;
142
- let indentLevel = 0;
143
- for (let j = i; j < lines.length; j++) {
144
- const fullLine = lines[j];
145
- if (!fullLine)
146
- continue;
147
- const line = fullLine.trim();
148
- if (line.startsWith(`${sectionName}:`)) {
149
- sectionStartIndex = j;
150
- indentLevel = fullLine.length - fullLine.trimStart().length;
151
- // Find the end of this section
152
- for (let k = j + 1; k < lines.length; k++) {
153
- const nextLine = lines[k];
154
- if (!nextLine)
155
- continue;
156
- const nextLineTrimmed = nextLine.trim();
157
- const nextIndentLevel = nextLine.length - nextLine.trimStart().length;
158
- // If we find a line with same or less indentation that defines a new section, stop
159
- if (nextIndentLevel <= indentLevel &&
160
- nextLineTrimmed.includes(':') &&
161
- !nextLineTrimmed.startsWith('#')) {
162
- sectionEndIndex = k - 1;
163
- break;
164
- }
165
- // If we find a line that's not empty, not indented enough to be part of this section, stop
166
- // Special case: comments at the same level after an empty line should end the section
167
- if (nextLineTrimmed !== '' && nextIndentLevel <= indentLevel) {
168
- if (nextLineTrimmed.startsWith('#') && nextIndentLevel === indentLevel) {
169
- // Check if there was an empty line before this comment
170
- let hasEmptyLineBefore = false;
171
- for (let m = k - 1; m > j; m--) {
172
- const prevLine = lines[m];
173
- if (!prevLine || prevLine.trim() === '') {
174
- hasEmptyLineBefore = true;
175
- break;
176
- }
177
- if (prevLine.trim() !== '') {
178
- break;
179
- }
180
- }
181
- if (hasEmptyLineBefore) {
182
- sectionEndIndex = k - 1;
183
- break;
184
- }
185
- }
186
- else if (!nextLineTrimmed.startsWith('#')) {
187
- sectionEndIndex = k - 1;
188
- break;
189
- }
190
- }
191
- }
192
- if (sectionEndIndex === -1) {
193
- sectionEndIndex = lines.length - 1;
194
- }
195
- break;
196
- }
197
- }
198
- if (sectionStartIndex !== -1) {
199
- // Update the section
200
- const sectionContent = this.formatYamlSection(sectionName, newValue, indentLevel, lines, sectionStartIndex, sectionEndIndex);
201
- // Add lines before the section
202
- for (let j = i; j < sectionStartIndex; j++) {
203
- const lineContent = lines[j];
204
- if (lineContent !== undefined) {
205
- result.push(lineContent);
206
- }
207
- }
208
- // Add the updated section
209
- result.push(...sectionContent);
210
- // Update the position to after this section
211
- i = sectionEndIndex + 1;
212
- return true;
213
- }
214
- return false;
215
- };
216
- // Process the file line by line
217
- while (i < lines.length) {
218
- const currentLine = lines[i];
219
- if (!currentLine) {
220
- result.push('');
221
- i++;
222
- continue;
223
- }
224
- const line = currentLine.trim();
225
- // Handle main sections
226
- if (line.startsWith('packages:')) {
227
- if (updateSection('packages', newData.packages)) {
228
- continue;
229
- }
230
- }
231
- else if (line.startsWith('catalog:')) {
232
- if (updateSection('catalog', newData.catalog)) {
233
- continue;
234
- }
235
- }
236
- else if (line.startsWith('catalogs:')) {
237
- if (updateSection('catalogs', newData.catalogs)) {
238
- continue;
239
- }
240
- }
241
- else if (line.startsWith('catalogMode:')) {
242
- if ('catalogMode' in newData) {
243
- const indent = currentLine.length - currentLine.trimStart().length;
244
- result.push(' '.repeat(indent) + `catalogMode: ${newData.catalogMode}`);
245
- i++;
246
- continue;
247
- }
248
- }
249
- else if (line.startsWith('shamefullyHoist:')) {
250
- if ('shamefullyHoist' in newData) {
251
- const indent = currentLine.length - currentLine.trimStart().length;
252
- result.push(' '.repeat(indent) + `shamefullyHoist: ${newData.shamefullyHoist}`);
253
- i++;
254
- continue;
255
- }
256
- }
257
- else if (line.startsWith('linkWorkspacePackages:')) {
258
- if ('linkWorkspacePackages' in newData) {
259
- const indent = currentLine.length - currentLine.trimStart().length;
260
- result.push(' '.repeat(indent) + `linkWorkspacePackages: ${newData.linkWorkspacePackages}`);
261
- i++;
262
- continue;
263
- }
264
- }
265
- // Keep the original line if not updated
266
- result.push(currentLine);
267
- i++;
268
- }
269
- return result.join('\n');
270
- }
271
- /**
272
- * Format a YAML section with proper indentation while preserving internal structure
273
- */
274
- formatYamlSection(sectionName, value, baseIndent = 0, originalLines, sectionStart, sectionEnd) {
275
- const lines = [];
276
- const indent = ' '.repeat(baseIndent);
277
- if (sectionName === 'packages' && Array.isArray(value)) {
278
- lines.push(`${indent}packages:`);
279
- for (const pkg of value) {
280
- lines.push(`${indent} - "${pkg}"`);
281
- }
282
- }
283
- else if ((sectionName === 'catalog' || sectionName === 'catalogs') &&
284
- typeof value === 'object') {
285
- if (sectionName === 'catalog') {
286
- lines.push(`${indent}catalog:`);
287
- // Try to preserve original structure and comments if available
288
- if (originalLines && sectionStart !== undefined && sectionEnd !== undefined) {
289
- const valueEntries = Object.entries(value);
290
- const processedPackages = new Set();
291
- // First pass: update existing packages while preserving comments
292
- for (let i = sectionStart + 1; i <= sectionEnd; i++) {
293
- const line = originalLines[i];
294
- if (!line)
295
- continue;
296
- const trimmed = line.trim();
297
- // Preserve comments and empty lines
298
- if (trimmed.startsWith('#') || trimmed === '') {
299
- lines.push(line);
300
- continue;
301
- }
302
- // Check if this line defines a package (with or without quotes)
303
- const packageMatch = trimmed.match(/^(['"]?)([a-zA-Z0-9@\-_.\\/]+)\1:\s*(.+)$/);
304
- if (packageMatch && packageMatch[2]) {
305
- const packageName = packageMatch[2];
306
- const newVersion = value[packageName];
307
- if (newVersion !== undefined) {
308
- // Update with new version while preserving indentation and quotes
309
- const originalIndent = line.length - line.trimStart().length;
310
- const quote = packageMatch[1] || ''; // Preserve original quote style
311
- lines.push(' '.repeat(originalIndent) + `${quote}${packageName}${quote}: ${newVersion}`);
312
- processedPackages.add(packageName);
313
- }
314
- else {
315
- // Keep the line as is if package not in new data
316
- lines.push(line);
317
- }
318
- }
319
- else {
320
- // Keep other lines as is
321
- lines.push(line);
322
- }
323
- }
324
- // Second pass: add any new packages that weren't in the original
325
- for (const [pkg, version] of valueEntries) {
326
- if (!processedPackages.has(pkg)) {
327
- lines.push(`${indent} ${pkg}: ${version}`);
328
- }
329
- }
330
- }
331
- else {
332
- // Fallback to simple formatting
333
- for (const [pkg, version] of Object.entries(value)) {
334
- lines.push(`${indent} ${pkg}: ${version}`);
335
- }
336
- }
337
- }
338
- else {
339
- // Handle catalogs section with format preservation
340
- lines.push(`${indent}catalogs:`);
341
- if (originalLines && sectionStart !== undefined && sectionEnd !== undefined) {
342
- // Try to preserve original structure for catalogs section
343
- this.formatCatalogsSection(lines, value, baseIndent, originalLines, sectionStart, sectionEnd);
344
- }
345
- else {
346
- // Fallback to simple formatting
347
- for (const [catalogName, catalog] of Object.entries(value)) {
348
- lines.push(`${indent} ${catalogName}:`);
349
- for (const [pkg, version] of Object.entries(catalog)) {
350
- lines.push(`${indent} ${pkg}: ${version}`);
351
- }
352
- }
353
- }
354
- }
355
- }
356
- return lines;
357
- }
358
- /**
359
- * Format catalogs section while preserving structure and comments
360
- */
361
- formatCatalogsSection(lines, value, baseIndent, originalLines, sectionStart, sectionEnd) {
362
- const indent = ' '.repeat(baseIndent);
363
- const processedCatalogs = new Set();
364
- let i = sectionStart + 1;
365
- while (i <= sectionEnd) {
366
- const line = originalLines[i];
367
- if (!line) {
368
- i++;
369
- continue;
370
- }
371
- const trimmed = line.trim();
372
- // Preserve comments and empty lines
373
- if (trimmed.startsWith('#') || trimmed === '') {
374
- lines.push(line);
375
- i++;
376
- continue;
377
- }
378
- // Check if this line defines a catalog
379
- const catalogMatch = trimmed.match(/^([a-zA-Z0-9\-_.]+):\s*$/);
380
- if (catalogMatch && catalogMatch[1]) {
381
- const catalogName = catalogMatch[1];
382
- const catalogData = value[catalogName];
383
- if (catalogData) {
384
- // This catalog exists in the new data
385
- const originalIndent = line.length - line.trimStart().length;
386
- lines.push(' '.repeat(originalIndent) + `${catalogName}:`);
387
- processedCatalogs.add(catalogName);
388
- // Process packages within this catalog
389
- i++;
390
- while (i <= sectionEnd) {
391
- const packageLine = originalLines[i];
392
- if (!packageLine) {
393
- i++;
394
- continue;
395
- }
396
- const packageTrimmed = packageLine.trim();
397
- const packageIndent = packageLine.length - packageLine.trimStart().length;
398
- // If we hit another catalog or section at same/lesser indent, break
399
- if (packageIndent <= originalIndent &&
400
- packageTrimmed !== '' &&
401
- !packageTrimmed.startsWith('#')) {
402
- break;
403
- }
404
- // Preserve comments and empty lines
405
- if (packageTrimmed.startsWith('#') || packageTrimmed === '') {
406
- lines.push(packageLine);
407
- i++;
408
- continue;
409
- }
410
- // Check if this line defines a package
411
- const packageMatch = packageTrimmed.match(/^(['"]?)([a-zA-Z0-9@\-_.\\/]+)\1:\s*(.+)$/);
412
- if (packageMatch && packageMatch[2]) {
413
- const packageName = packageMatch[2];
414
- const newVersion = catalogData[packageName];
415
- if (newVersion !== undefined) {
416
- // Update with new version while preserving indentation and quotes
417
- const quote = packageMatch[1] || '';
418
- lines.push(' '.repeat(packageIndent) + `${quote}${packageName}${quote}: ${newVersion}`);
419
- }
420
- else {
421
- // Keep the line as is if package not in new data
422
- lines.push(packageLine);
423
- }
424
- }
425
- else {
426
- // Keep other lines as is
427
- lines.push(packageLine);
428
- }
429
- i++;
430
- }
431
- // Add any new packages that weren't in the original
432
- for (const [pkg, version] of Object.entries(catalogData)) {
433
- if (!this.packageExistsInCatalogSection(originalLines, sectionStart, sectionEnd, catalogName, pkg)) {
434
- lines.push(`${indent} ${pkg}: ${version}`);
435
- }
436
- }
437
- }
438
- else {
439
- // This catalog doesn't exist in new data, keep as is
440
- lines.push(line);
441
- i++;
442
- }
443
- }
444
- else {
445
- // Not a catalog definition, keep as is
446
- lines.push(line);
447
- i++;
448
- }
449
- }
450
- // Add any new catalogs that weren't in the original
451
- for (const [catalogName, catalogData] of Object.entries(value)) {
452
- if (!processedCatalogs.has(catalogName)) {
453
- lines.push(`${indent} ${catalogName}:`);
454
- for (const [pkg, version] of Object.entries(catalogData)) {
455
- lines.push(`${indent} ${pkg}: ${version}`);
456
- }
457
- }
458
- }
459
- }
460
- /**
461
- * Check if a package exists in a catalog section
462
- */
463
- packageExistsInCatalogSection(lines, sectionStart, sectionEnd, catalogName, packageName) {
464
- let foundCatalog = false;
465
- for (let i = sectionStart + 1; i <= sectionEnd; i++) {
466
- const line = lines[i];
467
- if (!line)
468
- continue;
469
- const trimmed = line.trim();
470
- // Check if we found the catalog
471
- if (trimmed === `${catalogName}:`) {
472
- foundCatalog = true;
473
- continue;
474
- }
475
- // If we found another catalog, stop
476
- if (foundCatalog && trimmed.match(/^[a-zA-Z0-9\-_.]+:\s*$/)) {
477
- break;
478
- }
479
- // If we're in the right catalog, check for the package
480
- if (foundCatalog) {
481
- const packageMatch = trimmed.match(/^(['"]?)([a-zA-Z0-9@\-_.\\/]+)\1:\s*(.+)$/);
482
- if (packageMatch && packageMatch[2] === packageName) {
483
- return true;
484
- }
485
- }
486
- }
487
- return false;
488
- }
489
- /**
490
- * Read pnpm-workspace.yaml configuration
491
- */
492
- async readPnpmWorkspaceConfig(workspacePath) {
493
- const configPath = workspacePath.getPnpmWorkspaceConfigPath().toString();
494
- if (!(await this.exists(configPath))) {
495
- throw new Error(`pnpm-workspace.yaml not found at ${configPath}`);
496
- }
497
- return await this.readYamlFile(configPath);
498
- }
499
- /**
500
- * Write pnpm-workspace.yaml configuration
501
- */
502
- async writePnpmWorkspaceConfig(workspacePath, config) {
503
- const configPath = workspacePath.getPnpmWorkspaceConfigPath().toString();
504
- await this.writeYamlFilePreservingFormat(configPath, config);
505
- }
506
- /**
507
- * Read package.json file
508
- */
509
- async readPackageJson(packagePath) {
510
- const packageJsonPath = packagePath.getPackageJsonPath().toString();
511
- if (!(await this.exists(packageJsonPath))) {
512
- throw new Error(`package.json not found at ${packageJsonPath}`);
513
- }
514
- return await this.readJsonFile(packageJsonPath);
515
- }
516
- /**
517
- * Write package.json file
518
- */
519
- async writePackageJson(packagePath, packageData) {
520
- const packageJsonPath = packagePath.getPackageJsonPath().toString();
521
- await this.writeJsonFile(packageJsonPath, packageData);
522
- }
523
- /**
524
- * Find package.json files using glob patterns
525
- */
526
- async findPackageJsonFiles(workspacePath, patterns) {
527
- const results = [];
528
- for (const pattern of patterns) {
529
- try {
530
- // Convert pattern to absolute path and look for package.json
531
- const absolutePattern = path.resolve(workspacePath.toString(), pattern, 'package.json');
532
- const matches = await glob(absolutePattern, {
533
- ignore: ['**/node_modules/**'],
534
- absolute: true,
535
- });
536
- results.push(...matches);
537
- }
538
- catch (error) {
539
- // Continue with other patterns if one fails
540
- console.warn(`Failed to process pattern ${pattern}:`, error);
541
- }
542
- }
543
- // Remove duplicates and return
544
- return Array.from(new Set(results));
545
- }
546
- /**
547
- * Find directories matching patterns
548
- */
549
- async findDirectories(workspacePath, patterns) {
550
- const results = [];
551
- for (const pattern of patterns) {
552
- try {
553
- const absolutePattern = path.resolve(workspacePath.toString(), pattern);
554
- const matches = await glob(absolutePattern, {
555
- ignore: ['**/node_modules/**'],
556
- absolute: true,
557
- });
558
- results.push(...matches);
559
- }
560
- catch (error) {
561
- console.warn(`Failed to process pattern ${pattern}:`, error);
562
- }
563
- }
564
- return Array.from(new Set(results));
565
- }
566
- /**
567
- * Check if a directory contains a pnpm workspace
568
- */
569
- async isPnpmWorkspace(dirPath) {
570
- const workspaceConfigPath = path.join(dirPath, 'pnpm-workspace.yaml');
571
- const packageJsonPath = path.join(dirPath, 'package.json');
572
- // Must have both pnpm-workspace.yaml and package.json
573
- return (await this.exists(workspaceConfigPath)) && (await this.exists(packageJsonPath));
574
- }
575
- /**
576
- * Find the nearest pnpm workspace by traversing up the directory tree
577
- */
578
- async findNearestWorkspace(startPath) {
579
- let currentPath = path.resolve(startPath);
580
- while (currentPath !== path.dirname(currentPath)) {
581
- if (await this.isPnpmWorkspace(currentPath)) {
582
- return currentPath;
583
- }
584
- currentPath = path.dirname(currentPath);
585
- }
586
- return null;
587
- }
588
- /**
589
- * Get file modification time
590
- */
591
- async getModificationTime(filePath) {
592
- try {
593
- const stat = await fs.stat(filePath);
594
- return stat.mtime;
595
- }
596
- catch (error) {
597
- throw new Error(`Failed to get modification time for ${filePath}: ${error}`);
598
- }
599
- }
600
- /**
601
- * Create a backup of a file
602
- */
603
- async createBackup(filePath) {
604
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
605
- const backupPath = `${filePath}.backup.${timestamp}`;
606
- try {
607
- await fs.copyFile(filePath, backupPath);
608
- return backupPath;
609
- }
610
- catch (error) {
611
- throw new Error(`Failed to create backup of ${filePath}: ${error}`);
612
- }
613
- }
614
- /**
615
- * Restore a file from backup
616
- */
617
- async restoreFromBackup(originalPath, backupPath) {
618
- try {
619
- await fs.copyFile(backupPath, originalPath);
620
- }
621
- catch (error) {
622
- throw new Error(`Failed to restore ${originalPath} from backup: ${error}`);
623
- }
624
- }
625
- /**
626
- * Remove a file
627
- */
628
- async removeFile(filePath) {
629
- try {
630
- await fs.unlink(filePath);
631
- }
632
- catch (error) {
633
- throw new Error(`Failed to remove file ${filePath}: ${error}`);
634
- }
635
- }
636
- /**
637
- * List files in a directory
638
- */
639
- async listFiles(dirPath) {
640
- try {
641
- const items = await fs.readdir(dirPath, { withFileTypes: true });
642
- return items.filter((item) => item.isFile()).map((item) => path.join(dirPath, item.name));
643
- }
644
- catch (error) {
645
- throw new Error(`Failed to list files in ${dirPath}: ${error}`);
646
- }
647
- }
648
- /**
649
- * List directories in a directory
650
- */
651
- async listDirectories(dirPath) {
652
- try {
653
- const items = await fs.readdir(dirPath, { withFileTypes: true });
654
- return items
655
- .filter((item) => item.isDirectory())
656
- .map((item) => path.join(dirPath, item.name));
657
- }
658
- catch (error) {
659
- throw new Error(`Failed to list directories in ${dirPath}: ${error}`);
660
- }
661
- }
662
- }
663
- //# sourceMappingURL=FileSystemService.js.map