pcu 0.5.7 → 0.6.3

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 (223) 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 +36 -84
  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/README.ja.md +0 -587
  20. package/README.md +0 -694
  21. package/README.zh-CN.md +0 -634
  22. package/dist/application/services/CatalogUpdateService.d.ts +0 -209
  23. package/dist/application/services/CatalogUpdateService.d.ts.map +0 -1
  24. package/dist/application/services/CatalogUpdateService.js +0 -839
  25. package/dist/application/services/CatalogUpdateService.js.map +0 -1
  26. package/dist/application/services/WorkspaceService.d.ts +0 -139
  27. package/dist/application/services/WorkspaceService.d.ts.map +0 -1
  28. package/dist/application/services/WorkspaceService.js +0 -340
  29. package/dist/application/services/WorkspaceService.js.map +0 -1
  30. package/dist/cli/commands/CheckCommand.d.ts +0 -40
  31. package/dist/cli/commands/CheckCommand.d.ts.map +0 -1
  32. package/dist/cli/commands/CheckCommand.js +0 -177
  33. package/dist/cli/commands/CheckCommand.js.map +0 -1
  34. package/dist/cli/commands/InitCommand.d.ts +0 -53
  35. package/dist/cli/commands/InitCommand.d.ts.map +0 -1
  36. package/dist/cli/commands/InitCommand.js +0 -338
  37. package/dist/cli/commands/InitCommand.js.map +0 -1
  38. package/dist/cli/commands/SecurityCommand.d.ts +0 -113
  39. package/dist/cli/commands/SecurityCommand.d.ts.map +0 -1
  40. package/dist/cli/commands/SecurityCommand.js +0 -410
  41. package/dist/cli/commands/SecurityCommand.js.map +0 -1
  42. package/dist/cli/commands/UpdateCommand.d.ts +0 -44
  43. package/dist/cli/commands/UpdateCommand.d.ts.map +0 -1
  44. package/dist/cli/commands/UpdateCommand.js +0 -189
  45. package/dist/cli/commands/UpdateCommand.js.map +0 -1
  46. package/dist/cli/formatters/OutputFormatter.d.ts +0 -116
  47. package/dist/cli/formatters/OutputFormatter.d.ts.map +0 -1
  48. package/dist/cli/formatters/OutputFormatter.js +0 -664
  49. package/dist/cli/formatters/OutputFormatter.js.map +0 -1
  50. package/dist/cli/formatters/ProgressBar.d.ts +0 -195
  51. package/dist/cli/formatters/ProgressBar.d.ts.map +0 -1
  52. package/dist/cli/formatters/ProgressBar.js +0 -622
  53. package/dist/cli/formatters/ProgressBar.js.map +0 -1
  54. package/dist/cli/index.d.ts +0 -12
  55. package/dist/cli/index.d.ts.map +0 -1
  56. package/dist/cli/index.js +0 -492
  57. package/dist/cli/index.js.map +0 -1
  58. package/dist/cli/interactive/InteractivePrompts.d.ts +0 -85
  59. package/dist/cli/interactive/InteractivePrompts.d.ts.map +0 -1
  60. package/dist/cli/interactive/InteractivePrompts.js +0 -434
  61. package/dist/cli/interactive/InteractivePrompts.js.map +0 -1
  62. package/dist/cli/options/GlobalOptions.d.ts +0 -117
  63. package/dist/cli/options/GlobalOptions.d.ts.map +0 -1
  64. package/dist/cli/options/GlobalOptions.js +0 -278
  65. package/dist/cli/options/GlobalOptions.js.map +0 -1
  66. package/dist/cli/options/index.d.ts +0 -5
  67. package/dist/cli/options/index.d.ts.map +0 -1
  68. package/dist/cli/options/index.js +0 -5
  69. package/dist/cli/options/index.js.map +0 -1
  70. package/dist/cli/themes/ColorTheme.d.ts +0 -211
  71. package/dist/cli/themes/ColorTheme.d.ts.map +0 -1
  72. package/dist/cli/themes/ColorTheme.js +0 -267
  73. package/dist/cli/themes/ColorTheme.js.map +0 -1
  74. package/dist/cli/validators/CommandValidator.d.ts +0 -60
  75. package/dist/cli/validators/CommandValidator.d.ts.map +0 -1
  76. package/dist/cli/validators/CommandValidator.js +0 -319
  77. package/dist/cli/validators/CommandValidator.js.map +0 -1
  78. package/dist/cli/validators/index.d.ts +0 -5
  79. package/dist/cli/validators/index.d.ts.map +0 -1
  80. package/dist/cli/validators/index.js +0 -5
  81. package/dist/cli/validators/index.js.map +0 -1
  82. package/dist/common/config/Config.d.ts +0 -142
  83. package/dist/common/config/Config.d.ts.map +0 -1
  84. package/dist/common/config/Config.js +0 -382
  85. package/dist/common/config/Config.js.map +0 -1
  86. package/dist/common/config/ConfigLoader.d.ts +0 -49
  87. package/dist/common/config/ConfigLoader.d.ts.map +0 -1
  88. package/dist/common/config/ConfigLoader.js +0 -180
  89. package/dist/common/config/ConfigLoader.js.map +0 -1
  90. package/dist/common/config/PackageFilterConfig.d.ts +0 -56
  91. package/dist/common/config/PackageFilterConfig.d.ts.map +0 -1
  92. package/dist/common/config/PackageFilterConfig.js +0 -94
  93. package/dist/common/config/PackageFilterConfig.js.map +0 -1
  94. package/dist/common/config/index.d.ts +0 -8
  95. package/dist/common/config/index.d.ts.map +0 -1
  96. package/dist/common/config/index.js +0 -8
  97. package/dist/common/config/index.js.map +0 -1
  98. package/dist/common/error-handling/ErrorTracker.d.ts +0 -48
  99. package/dist/common/error-handling/ErrorTracker.d.ts.map +0 -1
  100. package/dist/common/error-handling/ErrorTracker.js +0 -93
  101. package/dist/common/error-handling/ErrorTracker.js.map +0 -1
  102. package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts +0 -74
  103. package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts.map +0 -1
  104. package/dist/common/error-handling/UserFriendlyErrorHandler.js +0 -703
  105. package/dist/common/error-handling/UserFriendlyErrorHandler.js.map +0 -1
  106. package/dist/common/error-handling/index.d.ts +0 -11
  107. package/dist/common/error-handling/index.d.ts.map +0 -1
  108. package/dist/common/error-handling/index.js +0 -9
  109. package/dist/common/error-handling/index.js.map +0 -1
  110. package/dist/common/logger/Logger.d.ts +0 -110
  111. package/dist/common/logger/Logger.d.ts.map +0 -1
  112. package/dist/common/logger/Logger.js +0 -289
  113. package/dist/common/logger/Logger.js.map +0 -1
  114. package/dist/common/logger/index.d.ts +0 -6
  115. package/dist/common/logger/index.d.ts.map +0 -1
  116. package/dist/common/logger/index.js +0 -6
  117. package/dist/common/logger/index.js.map +0 -1
  118. package/dist/common/types/cli.d.ts +0 -265
  119. package/dist/common/types/cli.d.ts.map +0 -1
  120. package/dist/common/types/cli.js +0 -5
  121. package/dist/common/types/cli.js.map +0 -1
  122. package/dist/common/types/core.d.ts +0 -270
  123. package/dist/common/types/core.d.ts.map +0 -1
  124. package/dist/common/types/core.js +0 -32
  125. package/dist/common/types/core.js.map +0 -1
  126. package/dist/common/types/index.d.ts +0 -8
  127. package/dist/common/types/index.d.ts.map +0 -1
  128. package/dist/common/types/index.js +0 -8
  129. package/dist/common/types/index.js.map +0 -1
  130. package/dist/common/utils/VersionChecker.d.ts +0 -54
  131. package/dist/common/utils/VersionChecker.d.ts.map +0 -1
  132. package/dist/common/utils/VersionChecker.js +0 -180
  133. package/dist/common/utils/VersionChecker.js.map +0 -1
  134. package/dist/common/utils/async.d.ts +0 -74
  135. package/dist/common/utils/async.d.ts.map +0 -1
  136. package/dist/common/utils/async.js +0 -228
  137. package/dist/common/utils/async.js.map +0 -1
  138. package/dist/common/utils/format.d.ts +0 -32
  139. package/dist/common/utils/format.d.ts.map +0 -1
  140. package/dist/common/utils/format.js +0 -121
  141. package/dist/common/utils/format.js.map +0 -1
  142. package/dist/common/utils/git.d.ts +0 -44
  143. package/dist/common/utils/git.d.ts.map +0 -1
  144. package/dist/common/utils/git.js +0 -147
  145. package/dist/common/utils/git.js.map +0 -1
  146. package/dist/common/utils/index.d.ts +0 -12
  147. package/dist/common/utils/index.d.ts.map +0 -1
  148. package/dist/common/utils/index.js +0 -12
  149. package/dist/common/utils/index.js.map +0 -1
  150. package/dist/common/utils/string.d.ts +0 -56
  151. package/dist/common/utils/string.d.ts.map +0 -1
  152. package/dist/common/utils/string.js +0 -134
  153. package/dist/common/utils/string.js.map +0 -1
  154. package/dist/common/utils/validation.d.ts +0 -88
  155. package/dist/common/utils/validation.d.ts.map +0 -1
  156. package/dist/common/utils/validation.js +0 -308
  157. package/dist/common/utils/validation.js.map +0 -1
  158. package/dist/domain/entities/Catalog.d.ts +0 -117
  159. package/dist/domain/entities/Catalog.d.ts.map +0 -1
  160. package/dist/domain/entities/Catalog.js +0 -240
  161. package/dist/domain/entities/Catalog.js.map +0 -1
  162. package/dist/domain/entities/Package.d.ts +0 -143
  163. package/dist/domain/entities/Package.d.ts.map +0 -1
  164. package/dist/domain/entities/Package.js +0 -272
  165. package/dist/domain/entities/Package.js.map +0 -1
  166. package/dist/domain/entities/Workspace.d.ts +0 -95
  167. package/dist/domain/entities/Workspace.d.ts.map +0 -1
  168. package/dist/domain/entities/Workspace.js +0 -173
  169. package/dist/domain/entities/Workspace.js.map +0 -1
  170. package/dist/domain/repositories/WorkspaceRepository.d.ts +0 -41
  171. package/dist/domain/repositories/WorkspaceRepository.d.ts.map +0 -1
  172. package/dist/domain/repositories/WorkspaceRepository.js +0 -8
  173. package/dist/domain/repositories/WorkspaceRepository.js.map +0 -1
  174. package/dist/domain/value-objects/CatalogCollection.d.ts +0 -106
  175. package/dist/domain/value-objects/CatalogCollection.d.ts.map +0 -1
  176. package/dist/domain/value-objects/CatalogCollection.js +0 -230
  177. package/dist/domain/value-objects/CatalogCollection.js.map +0 -1
  178. package/dist/domain/value-objects/PackageCollection.d.ts +0 -122
  179. package/dist/domain/value-objects/PackageCollection.d.ts.map +0 -1
  180. package/dist/domain/value-objects/PackageCollection.js +0 -263
  181. package/dist/domain/value-objects/PackageCollection.js.map +0 -1
  182. package/dist/domain/value-objects/Version.d.ts +0 -141
  183. package/dist/domain/value-objects/Version.d.ts.map +0 -1
  184. package/dist/domain/value-objects/Version.js +0 -268
  185. package/dist/domain/value-objects/Version.js.map +0 -1
  186. package/dist/domain/value-objects/WorkspaceConfig.d.ts +0 -144
  187. package/dist/domain/value-objects/WorkspaceConfig.d.ts.map +0 -1
  188. package/dist/domain/value-objects/WorkspaceConfig.js +0 -357
  189. package/dist/domain/value-objects/WorkspaceConfig.js.map +0 -1
  190. package/dist/domain/value-objects/WorkspaceId.d.ts +0 -51
  191. package/dist/domain/value-objects/WorkspaceId.d.ts.map +0 -1
  192. package/dist/domain/value-objects/WorkspaceId.js +0 -104
  193. package/dist/domain/value-objects/WorkspaceId.js.map +0 -1
  194. package/dist/domain/value-objects/WorkspacePath.d.ts +0 -75
  195. package/dist/domain/value-objects/WorkspacePath.d.ts.map +0 -1
  196. package/dist/domain/value-objects/WorkspacePath.js +0 -128
  197. package/dist/domain/value-objects/WorkspacePath.js.map +0 -1
  198. package/dist/index.d.ts +0 -25
  199. package/dist/index.d.ts.map +0 -1
  200. package/dist/infrastructure/cache/Cache.d.ts +0 -161
  201. package/dist/infrastructure/cache/Cache.d.ts.map +0 -1
  202. package/dist/infrastructure/cache/Cache.js +0 -398
  203. package/dist/infrastructure/cache/Cache.js.map +0 -1
  204. package/dist/infrastructure/cache/index.d.ts +0 -6
  205. package/dist/infrastructure/cache/index.d.ts.map +0 -1
  206. package/dist/infrastructure/cache/index.js +0 -6
  207. package/dist/infrastructure/cache/index.js.map +0 -1
  208. package/dist/infrastructure/external-services/NpmRegistryService.d.ts +0 -153
  209. package/dist/infrastructure/external-services/NpmRegistryService.d.ts.map +0 -1
  210. package/dist/infrastructure/external-services/NpmRegistryService.js +0 -511
  211. package/dist/infrastructure/external-services/NpmRegistryService.js.map +0 -1
  212. package/dist/infrastructure/file-system/FileSystemService.d.ts +0 -120
  213. package/dist/infrastructure/file-system/FileSystemService.d.ts.map +0 -1
  214. package/dist/infrastructure/file-system/FileSystemService.js +0 -663
  215. package/dist/infrastructure/file-system/FileSystemService.js.map +0 -1
  216. package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts +0 -57
  217. package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts.map +0 -1
  218. package/dist/infrastructure/repositories/FileWorkspaceRepository.js +0 -179
  219. package/dist/infrastructure/repositories/FileWorkspaceRepository.js.map +0 -1
  220. package/dist/infrastructure/utils/NpmrcParser.d.ts +0 -40
  221. package/dist/infrastructure/utils/NpmrcParser.d.ts.map +0 -1
  222. package/dist/infrastructure/utils/NpmrcParser.js +0 -157
  223. package/dist/infrastructure/utils/NpmrcParser.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