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.
- package/bin/pcu.js +1 -1
- package/dist/index.js +9559 -32
- package/dist/index.js.map +1 -1
- package/package.json +61 -103
- package/src/cli/commands/checkCommand.ts +227 -0
- package/src/cli/commands/initCommand.ts +394 -0
- package/src/cli/commands/securityCommand.ts +569 -0
- package/src/cli/commands/updateCommand.ts +245 -0
- package/src/cli/formatters/outputFormatter.ts +830 -0
- package/src/cli/formatters/progressBar.ts +700 -0
- package/src/cli/index.ts +565 -0
- package/src/cli/interactive/interactivePrompts.ts +517 -0
- package/src/cli/options/globalOptions.ts +380 -0
- package/src/cli/options/index.ts +5 -0
- package/src/cli/themes/colorTheme.ts +379 -0
- package/src/cli/validators/commandValidator.ts +395 -0
- package/src/cli/validators/index.ts +5 -0
- package/src/index.ts +4 -0
- package/LICENSE +0 -21
- package/README.ja.md +0 -582
- package/README.md +0 -690
- package/README.zh-CN.md +0 -630
- package/dist/application/services/CatalogUpdateService.d.ts +0 -209
- package/dist/application/services/CatalogUpdateService.d.ts.map +0 -1
- package/dist/application/services/CatalogUpdateService.js +0 -836
- package/dist/application/services/CatalogUpdateService.js.map +0 -1
- package/dist/application/services/WorkspaceService.d.ts +0 -139
- package/dist/application/services/WorkspaceService.d.ts.map +0 -1
- package/dist/application/services/WorkspaceService.js +0 -340
- package/dist/application/services/WorkspaceService.js.map +0 -1
- package/dist/cli/commands/CheckCommand.d.ts +0 -40
- package/dist/cli/commands/CheckCommand.d.ts.map +0 -1
- package/dist/cli/commands/CheckCommand.js +0 -177
- package/dist/cli/commands/CheckCommand.js.map +0 -1
- package/dist/cli/commands/InitCommand.d.ts +0 -53
- package/dist/cli/commands/InitCommand.d.ts.map +0 -1
- package/dist/cli/commands/InitCommand.js +0 -338
- package/dist/cli/commands/InitCommand.js.map +0 -1
- package/dist/cli/commands/SecurityCommand.d.ts +0 -113
- package/dist/cli/commands/SecurityCommand.d.ts.map +0 -1
- package/dist/cli/commands/SecurityCommand.js +0 -410
- package/dist/cli/commands/SecurityCommand.js.map +0 -1
- package/dist/cli/commands/UpdateCommand.d.ts +0 -44
- package/dist/cli/commands/UpdateCommand.d.ts.map +0 -1
- package/dist/cli/commands/UpdateCommand.js +0 -189
- package/dist/cli/commands/UpdateCommand.js.map +0 -1
- package/dist/cli/formatters/OutputFormatter.d.ts +0 -116
- package/dist/cli/formatters/OutputFormatter.d.ts.map +0 -1
- package/dist/cli/formatters/OutputFormatter.js +0 -664
- package/dist/cli/formatters/OutputFormatter.js.map +0 -1
- package/dist/cli/formatters/ProgressBar.d.ts +0 -195
- package/dist/cli/formatters/ProgressBar.d.ts.map +0 -1
- package/dist/cli/formatters/ProgressBar.js +0 -622
- package/dist/cli/formatters/ProgressBar.js.map +0 -1
- package/dist/cli/index.d.ts +0 -12
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -492
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/interactive/InteractivePrompts.d.ts +0 -85
- package/dist/cli/interactive/InteractivePrompts.d.ts.map +0 -1
- package/dist/cli/interactive/InteractivePrompts.js +0 -434
- package/dist/cli/interactive/InteractivePrompts.js.map +0 -1
- package/dist/cli/options/GlobalOptions.d.ts +0 -117
- package/dist/cli/options/GlobalOptions.d.ts.map +0 -1
- package/dist/cli/options/GlobalOptions.js +0 -278
- package/dist/cli/options/GlobalOptions.js.map +0 -1
- package/dist/cli/options/index.d.ts +0 -5
- package/dist/cli/options/index.d.ts.map +0 -1
- package/dist/cli/options/index.js +0 -5
- package/dist/cli/options/index.js.map +0 -1
- package/dist/cli/themes/ColorTheme.d.ts +0 -211
- package/dist/cli/themes/ColorTheme.d.ts.map +0 -1
- package/dist/cli/themes/ColorTheme.js +0 -267
- package/dist/cli/themes/ColorTheme.js.map +0 -1
- package/dist/cli/validators/CommandValidator.d.ts +0 -60
- package/dist/cli/validators/CommandValidator.d.ts.map +0 -1
- package/dist/cli/validators/CommandValidator.js +0 -319
- package/dist/cli/validators/CommandValidator.js.map +0 -1
- package/dist/cli/validators/index.d.ts +0 -5
- package/dist/cli/validators/index.d.ts.map +0 -1
- package/dist/cli/validators/index.js +0 -5
- package/dist/cli/validators/index.js.map +0 -1
- package/dist/common/config/Config.d.ts +0 -142
- package/dist/common/config/Config.d.ts.map +0 -1
- package/dist/common/config/Config.js +0 -382
- package/dist/common/config/Config.js.map +0 -1
- package/dist/common/config/ConfigLoader.d.ts +0 -49
- package/dist/common/config/ConfigLoader.d.ts.map +0 -1
- package/dist/common/config/ConfigLoader.js +0 -180
- package/dist/common/config/ConfigLoader.js.map +0 -1
- package/dist/common/config/PackageFilterConfig.d.ts +0 -56
- package/dist/common/config/PackageFilterConfig.d.ts.map +0 -1
- package/dist/common/config/PackageFilterConfig.js +0 -94
- package/dist/common/config/PackageFilterConfig.js.map +0 -1
- package/dist/common/config/index.d.ts +0 -8
- package/dist/common/config/index.d.ts.map +0 -1
- package/dist/common/config/index.js +0 -8
- package/dist/common/config/index.js.map +0 -1
- package/dist/common/error-handling/ErrorTracker.d.ts +0 -48
- package/dist/common/error-handling/ErrorTracker.d.ts.map +0 -1
- package/dist/common/error-handling/ErrorTracker.js +0 -93
- package/dist/common/error-handling/ErrorTracker.js.map +0 -1
- package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts +0 -74
- package/dist/common/error-handling/UserFriendlyErrorHandler.d.ts.map +0 -1
- package/dist/common/error-handling/UserFriendlyErrorHandler.js +0 -703
- package/dist/common/error-handling/UserFriendlyErrorHandler.js.map +0 -1
- package/dist/common/error-handling/index.d.ts +0 -11
- package/dist/common/error-handling/index.d.ts.map +0 -1
- package/dist/common/error-handling/index.js +0 -9
- package/dist/common/error-handling/index.js.map +0 -1
- package/dist/common/logger/Logger.d.ts +0 -110
- package/dist/common/logger/Logger.d.ts.map +0 -1
- package/dist/common/logger/Logger.js +0 -289
- package/dist/common/logger/Logger.js.map +0 -1
- package/dist/common/logger/index.d.ts +0 -6
- package/dist/common/logger/index.d.ts.map +0 -1
- package/dist/common/logger/index.js +0 -6
- package/dist/common/logger/index.js.map +0 -1
- package/dist/common/types/cli.d.ts +0 -265
- package/dist/common/types/cli.d.ts.map +0 -1
- package/dist/common/types/cli.js +0 -5
- package/dist/common/types/cli.js.map +0 -1
- package/dist/common/types/core.d.ts +0 -270
- package/dist/common/types/core.d.ts.map +0 -1
- package/dist/common/types/core.js +0 -32
- package/dist/common/types/core.js.map +0 -1
- package/dist/common/types/index.d.ts +0 -8
- package/dist/common/types/index.d.ts.map +0 -1
- package/dist/common/types/index.js +0 -8
- package/dist/common/types/index.js.map +0 -1
- package/dist/common/utils/VersionChecker.d.ts +0 -54
- package/dist/common/utils/VersionChecker.d.ts.map +0 -1
- package/dist/common/utils/VersionChecker.js +0 -180
- package/dist/common/utils/VersionChecker.js.map +0 -1
- package/dist/common/utils/async.d.ts +0 -74
- package/dist/common/utils/async.d.ts.map +0 -1
- package/dist/common/utils/async.js +0 -228
- package/dist/common/utils/async.js.map +0 -1
- package/dist/common/utils/format.d.ts +0 -32
- package/dist/common/utils/format.d.ts.map +0 -1
- package/dist/common/utils/format.js +0 -121
- package/dist/common/utils/format.js.map +0 -1
- package/dist/common/utils/git.d.ts +0 -44
- package/dist/common/utils/git.d.ts.map +0 -1
- package/dist/common/utils/git.js +0 -147
- package/dist/common/utils/git.js.map +0 -1
- package/dist/common/utils/index.d.ts +0 -12
- package/dist/common/utils/index.d.ts.map +0 -1
- package/dist/common/utils/index.js +0 -12
- package/dist/common/utils/index.js.map +0 -1
- package/dist/common/utils/string.d.ts +0 -56
- package/dist/common/utils/string.d.ts.map +0 -1
- package/dist/common/utils/string.js +0 -134
- package/dist/common/utils/string.js.map +0 -1
- package/dist/common/utils/validation.d.ts +0 -88
- package/dist/common/utils/validation.d.ts.map +0 -1
- package/dist/common/utils/validation.js +0 -308
- package/dist/common/utils/validation.js.map +0 -1
- package/dist/domain/entities/Catalog.d.ts +0 -117
- package/dist/domain/entities/Catalog.d.ts.map +0 -1
- package/dist/domain/entities/Catalog.js +0 -240
- package/dist/domain/entities/Catalog.js.map +0 -1
- package/dist/domain/entities/Package.d.ts +0 -143
- package/dist/domain/entities/Package.d.ts.map +0 -1
- package/dist/domain/entities/Package.js +0 -272
- package/dist/domain/entities/Package.js.map +0 -1
- package/dist/domain/entities/Workspace.d.ts +0 -95
- package/dist/domain/entities/Workspace.d.ts.map +0 -1
- package/dist/domain/entities/Workspace.js +0 -173
- package/dist/domain/entities/Workspace.js.map +0 -1
- package/dist/domain/repositories/WorkspaceRepository.d.ts +0 -41
- package/dist/domain/repositories/WorkspaceRepository.d.ts.map +0 -1
- package/dist/domain/repositories/WorkspaceRepository.js +0 -8
- package/dist/domain/repositories/WorkspaceRepository.js.map +0 -1
- package/dist/domain/value-objects/CatalogCollection.d.ts +0 -106
- package/dist/domain/value-objects/CatalogCollection.d.ts.map +0 -1
- package/dist/domain/value-objects/CatalogCollection.js +0 -230
- package/dist/domain/value-objects/CatalogCollection.js.map +0 -1
- package/dist/domain/value-objects/PackageCollection.d.ts +0 -122
- package/dist/domain/value-objects/PackageCollection.d.ts.map +0 -1
- package/dist/domain/value-objects/PackageCollection.js +0 -263
- package/dist/domain/value-objects/PackageCollection.js.map +0 -1
- package/dist/domain/value-objects/Version.d.ts +0 -141
- package/dist/domain/value-objects/Version.d.ts.map +0 -1
- package/dist/domain/value-objects/Version.js +0 -268
- package/dist/domain/value-objects/Version.js.map +0 -1
- package/dist/domain/value-objects/WorkspaceConfig.d.ts +0 -144
- package/dist/domain/value-objects/WorkspaceConfig.d.ts.map +0 -1
- package/dist/domain/value-objects/WorkspaceConfig.js +0 -357
- package/dist/domain/value-objects/WorkspaceConfig.js.map +0 -1
- package/dist/domain/value-objects/WorkspaceId.d.ts +0 -51
- package/dist/domain/value-objects/WorkspaceId.d.ts.map +0 -1
- package/dist/domain/value-objects/WorkspaceId.js +0 -104
- package/dist/domain/value-objects/WorkspaceId.js.map +0 -1
- package/dist/domain/value-objects/WorkspacePath.d.ts +0 -75
- package/dist/domain/value-objects/WorkspacePath.d.ts.map +0 -1
- package/dist/domain/value-objects/WorkspacePath.js +0 -128
- package/dist/domain/value-objects/WorkspacePath.js.map +0 -1
- package/dist/index.d.ts +0 -25
- package/dist/index.d.ts.map +0 -1
- package/dist/infrastructure/cache/Cache.d.ts +0 -161
- package/dist/infrastructure/cache/Cache.d.ts.map +0 -1
- package/dist/infrastructure/cache/Cache.js +0 -398
- package/dist/infrastructure/cache/Cache.js.map +0 -1
- package/dist/infrastructure/cache/index.d.ts +0 -6
- package/dist/infrastructure/cache/index.d.ts.map +0 -1
- package/dist/infrastructure/cache/index.js +0 -6
- package/dist/infrastructure/cache/index.js.map +0 -1
- package/dist/infrastructure/external-services/NpmRegistryService.d.ts +0 -145
- package/dist/infrastructure/external-services/NpmRegistryService.d.ts.map +0 -1
- package/dist/infrastructure/external-services/NpmRegistryService.js +0 -466
- package/dist/infrastructure/external-services/NpmRegistryService.js.map +0 -1
- package/dist/infrastructure/file-system/FileSystemService.d.ts +0 -120
- package/dist/infrastructure/file-system/FileSystemService.d.ts.map +0 -1
- package/dist/infrastructure/file-system/FileSystemService.js +0 -663
- package/dist/infrastructure/file-system/FileSystemService.js.map +0 -1
- package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts +0 -57
- package/dist/infrastructure/repositories/FileWorkspaceRepository.d.ts.map +0 -1
- package/dist/infrastructure/repositories/FileWorkspaceRepository.js +0 -179
- 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
|