@openrewrite/rewrite 8.72.2 → 8.72.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.
- package/dist/execution.js +3 -16
- package/dist/execution.js.map +1 -1
- package/dist/index.js +34 -49
- package/dist/index.js.map +1 -1
- package/dist/java/markers.js +12 -29
- package/dist/java/markers.js.map +1 -1
- package/dist/java/print.js +2 -13
- package/dist/java/print.js.map +1 -1
- package/dist/java/rpc.js +1344 -1725
- package/dist/java/rpc.js.map +1 -1
- package/dist/java/type-visitor.js +143 -184
- package/dist/java/type-visitor.js.map +1 -1
- package/dist/java/visitor.js +1072 -1249
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/add-import.js +495 -534
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/autodetect.js +116 -159
- package/dist/javascript/autodetect.js.map +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js +41 -57
- package/dist/javascript/cleanup/add-parse-int-radix.js.map +1 -1
- package/dist/javascript/cleanup/prefer-optional-chain.js +89 -105
- package/dist/javascript/cleanup/prefer-optional-chain.js.map +1 -1
- package/dist/javascript/cleanup/use-object-property-shorthand.js +74 -95
- package/dist/javascript/cleanup/use-object-property-shorthand.js.map +1 -1
- package/dist/javascript/comparator.js +815 -1167
- package/dist/javascript/comparator.js.map +1 -1
- package/dist/javascript/dependency-workspace.js +206 -219
- package/dist/javascript/dependency-workspace.js.map +1 -1
- package/dist/javascript/format/format.js +682 -908
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/minimum-viable-spacing-visitor.js +152 -231
- package/dist/javascript/format/minimum-viable-spacing-visitor.js.map +1 -1
- package/dist/javascript/format/normalize-whitespace-visitor.js +12 -31
- package/dist/javascript/format/normalize-whitespace-visitor.js.map +1 -1
- package/dist/javascript/format/prettier-config-loader.js +134 -153
- package/dist/javascript/format/prettier-config-loader.js.map +1 -1
- package/dist/javascript/format/prettier-format.js +112 -129
- package/dist/javascript/format/prettier-format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +112 -136
- package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
- package/dist/javascript/markers.js +59 -92
- package/dist/javascript/markers.js.map +1 -1
- package/dist/javascript/migrate/es6/modernize-octal-escape-sequences.js +39 -52
- package/dist/javascript/migrate/es6/modernize-octal-escape-sequences.js.map +1 -1
- package/dist/javascript/migrate/es6/modernize-octal-literals.js +25 -38
- package/dist/javascript/migrate/es6/modernize-octal-literals.js.map +1 -1
- package/dist/javascript/migrate/es6/remove-duplicate-object-keys.js +66 -82
- package/dist/javascript/migrate/es6/remove-duplicate-object-keys.js.map +1 -1
- package/dist/javascript/migrate/typescript/export-assignment-to-export-default.js +10 -23
- package/dist/javascript/migrate/typescript/export-assignment-to-export-default.js.map +1 -1
- package/dist/javascript/node-resolution-result.js +137 -166
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/package-json-parser.js +312 -343
- package/dist/javascript/package-json-parser.js.map +1 -1
- package/dist/javascript/package-manager.js +145 -170
- package/dist/javascript/package-manager.js.map +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +94 -68
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/print.js +1572 -1835
- package/dist/javascript/print.js.map +1 -1
- package/dist/javascript/project-parser.js +151 -172
- package/dist/javascript/project-parser.js.map +1 -1
- package/dist/javascript/recipes/add-dependency.js +140 -175
- package/dist/javascript/recipes/add-dependency.js.map +1 -1
- package/dist/javascript/recipes/async-callback-in-sync-array-method.js +20 -36
- package/dist/javascript/recipes/async-callback-in-sync-array-method.js.map +1 -1
- package/dist/javascript/recipes/auto-format.js +3 -14
- package/dist/javascript/recipes/auto-format.js.map +1 -1
- package/dist/javascript/recipes/change-import.js +447 -495
- package/dist/javascript/recipes/change-import.js.map +1 -1
- package/dist/javascript/recipes/order-imports.js +162 -175
- package/dist/javascript/recipes/order-imports.js.map +1 -1
- package/dist/javascript/recipes/upgrade-dependency-version.js +167 -197
- package/dist/javascript/recipes/upgrade-dependency-version.js.map +1 -1
- package/dist/javascript/recipes/upgrade-transitive-dependency-version.js +166 -193
- package/dist/javascript/recipes/upgrade-transitive-dependency-version.js.map +1 -1
- package/dist/javascript/remove-import.js +689 -724
- package/dist/javascript/remove-import.js.map +1 -1
- package/dist/javascript/rpc.js +1007 -1332
- package/dist/javascript/rpc.js.map +1 -1
- package/dist/javascript/search/find-dependency.js +84 -110
- package/dist/javascript/search/find-dependency.js.map +1 -1
- package/dist/javascript/search/uses-method.js +5 -19
- package/dist/javascript/search/uses-method.js.map +1 -1
- package/dist/javascript/search/uses-type.js +9 -20
- package/dist/javascript/search/uses-type.js.map +1 -1
- package/dist/javascript/templating/comparator.js +737 -822
- package/dist/javascript/templating/comparator.js.map +1 -1
- package/dist/javascript/templating/engine.js +211 -245
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/pattern.js +169 -190
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +172 -210
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/templating/rewrite.js +75 -97
- package/dist/javascript/templating/rewrite.js.map +1 -1
- package/dist/javascript/templating/template.js +69 -82
- package/dist/javascript/templating/template.js.map +1 -1
- package/dist/javascript/tree-debug.js +109 -137
- package/dist/javascript/tree-debug.js.map +1 -1
- package/dist/javascript/visitor.js +1090 -1254
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/json/print.js +72 -103
- package/dist/json/print.js.map +1 -1
- package/dist/json/rpc.js +120 -181
- package/dist/json/rpc.js.map +1 -1
- package/dist/json/visitor.js +69 -100
- package/dist/json/visitor.js.map +1 -1
- package/dist/marketplace.js +20 -33
- package/dist/marketplace.js.map +1 -1
- package/dist/parse-error.js +41 -62
- package/dist/parse-error.js.map +1 -1
- package/dist/parser.js +7 -18
- package/dist/parser.js.map +1 -1
- package/dist/path-utils.js +46 -59
- package/dist/path-utils.js.map +1 -1
- package/dist/preconditions.js +30 -47
- package/dist/preconditions.js.map +1 -1
- package/dist/print.js +6 -19
- package/dist/print.js.map +1 -1
- package/dist/recipe.js +42 -73
- package/dist/recipe.js.map +1 -1
- package/dist/rpc/index.js +74 -115
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/queue.js +71 -90
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/recipe.js +32 -57
- package/dist/rpc/recipe.js.map +1 -1
- package/dist/rpc/request/generate.js +4 -13
- package/dist/rpc/request/generate.js.map +1 -1
- package/dist/rpc/request/get-languages.js +2 -11
- package/dist/rpc/request/get-languages.js.map +1 -1
- package/dist/rpc/request/get-marketplace.js +9 -20
- package/dist/rpc/request/get-marketplace.js.map +1 -1
- package/dist/rpc/request/get-object.js +4 -13
- package/dist/rpc/request/get-object.js.map +1 -1
- package/dist/rpc/request/install-recipes.js +25 -36
- package/dist/rpc/request/install-recipes.js.map +1 -1
- package/dist/rpc/request/metrics.js +8 -17
- package/dist/rpc/request/metrics.js.map +1 -1
- package/dist/rpc/request/parse-project.js +36 -45
- package/dist/rpc/request/parse-project.js.map +1 -1
- package/dist/rpc/request/parse.js +5 -14
- package/dist/rpc/request/parse.js.map +1 -1
- package/dist/rpc/request/prepare-recipe.js +37 -52
- package/dist/rpc/request/prepare-recipe.js.map +1 -1
- package/dist/rpc/request/print.js +5 -14
- package/dist/rpc/request/print.js.map +1 -1
- package/dist/rpc/request/visit.js +56 -71
- package/dist/rpc/request/visit.js.map +1 -1
- package/dist/rpc/rewrite-rpc.js +70 -97
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/rpc/server.js +76 -89
- package/dist/rpc/server.js.map +1 -1
- package/dist/run.js +47 -66
- package/dist/run.js.map +1 -1
- package/dist/search/is-source-file.js +8 -19
- package/dist/search/is-source-file.js.map +1 -1
- package/dist/test/rewrite-test.js +154 -188
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/text/print.js +23 -38
- package/dist/text/print.js.map +1 -1
- package/dist/text/rpc.js +29 -44
- package/dist/text/rpc.js.map +1 -1
- package/dist/text/visitor.js +16 -33
- package/dist/text/visitor.js.map +1 -1
- package/dist/util.js +13 -24
- package/dist/util.js.map +1 -1
- package/dist/version.txt +1 -1
- package/dist/visitor.js +84 -115
- package/dist/visitor.js.map +1 -1
- package/dist/yaml/index.d.ts +2 -0
- package/dist/yaml/index.d.ts.map +1 -1
- package/dist/yaml/index.js +2 -0
- package/dist/yaml/index.js.map +1 -1
- package/dist/yaml/markers.d.ts +21 -0
- package/dist/yaml/markers.d.ts.map +1 -0
- package/dist/yaml/markers.js +37 -0
- package/dist/yaml/markers.js.map +1 -0
- package/dist/yaml/parser.d.ts.map +1 -1
- package/dist/yaml/parser.js +4 -1
- package/dist/yaml/parser.js.map +1 -1
- package/dist/yaml/print.d.ts +1 -1
- package/dist/yaml/print.d.ts.map +1 -1
- package/dist/yaml/print.js +175 -208
- package/dist/yaml/print.js.map +1 -1
- package/dist/yaml/rpc.js +154 -219
- package/dist/yaml/rpc.js.map +1 -1
- package/dist/yaml/visitor.js +78 -113
- package/dist/yaml/visitor.js.map +1 -1
- package/package.json +1 -1
- package/src/javascript/parser.ts +56 -14
- package/src/yaml/index.ts +2 -0
- package/src/yaml/markers.ts +70 -0
- package/src/yaml/parser.ts +5 -1
- package/src/yaml/print.ts +5 -2
|
@@ -32,15 +32,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
35
|
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
45
36
|
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
46
37
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
@@ -180,56 +171,54 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
180
171
|
/**
|
|
181
172
|
* Creates a NodeResolutionResult marker from the package.json content and optional lock file.
|
|
182
173
|
*/
|
|
183
|
-
createMarker(input, dir) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
// Resolve dir relative to relativeTo if dir is relative (e.g., '.' when package.json is at root)
|
|
199
|
-
const absoluteDir = this.relativeTo && !path.isAbsolute(dir)
|
|
200
|
-
? path.resolve(this.relativeTo, dir)
|
|
201
|
-
: dir;
|
|
202
|
-
const lockResult = yield this.tryReadLockFileWithWalkUp(absoluteDir, this.relativeTo);
|
|
203
|
-
lockContent = lockResult === null || lockResult === void 0 ? void 0 : lockResult.content;
|
|
204
|
-
packageManager = lockResult === null || lockResult === void 0 ? void 0 : lockResult.packageManager;
|
|
205
|
-
}
|
|
206
|
-
// Read .npmrc configurations from all scopes
|
|
207
|
-
const projectDir = this.relativeTo || dir;
|
|
208
|
-
const npmrcConfigs = yield (0, node_resolution_result_1.readNpmrcConfigs)(projectDir);
|
|
209
|
-
// Detect workspace member paths if this is a workspace root
|
|
210
|
-
// Check both package.json workspaces (npm/yarn) and pnpm-workspace.yaml (pnpm)
|
|
211
|
-
let workspacePackagePaths;
|
|
174
|
+
async createMarker(input, dir) {
|
|
175
|
+
try {
|
|
176
|
+
const content = (0, parser_1.parserInputRead)(input);
|
|
177
|
+
const packageJson = JSON.parse(content);
|
|
178
|
+
// Determine the relative path for the marker
|
|
179
|
+
const filePath = (0, parser_1.parserInputFile)(input);
|
|
180
|
+
const relativePath = this.relativeTo
|
|
181
|
+
? path.relative(this.relativeTo, filePath)
|
|
182
|
+
: filePath;
|
|
183
|
+
// Try to read lock file if dependency resolution is not skipped
|
|
184
|
+
// First try the directory containing the package.json, then walk up toward relativeTo
|
|
185
|
+
let lockContent = undefined;
|
|
186
|
+
let packageManager = undefined;
|
|
187
|
+
if (!this.skipDependencyResolution) {
|
|
188
|
+
// Resolve dir relative to relativeTo if dir is relative (e.g., '.' when package.json is at root)
|
|
212
189
|
const absoluteDir = this.relativeTo && !path.isAbsolute(dir)
|
|
213
190
|
? path.resolve(this.relativeTo, dir)
|
|
214
191
|
: dir;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
|
|
192
|
+
const lockResult = await this.tryReadLockFileWithWalkUp(absoluteDir, this.relativeTo);
|
|
193
|
+
lockContent = lockResult === null || lockResult === void 0 ? void 0 : lockResult.content;
|
|
194
|
+
packageManager = lockResult === null || lockResult === void 0 ? void 0 : lockResult.packageManager;
|
|
195
|
+
}
|
|
196
|
+
// Read .npmrc configurations from all scopes
|
|
197
|
+
const projectDir = this.relativeTo || dir;
|
|
198
|
+
const npmrcConfigs = await (0, node_resolution_result_1.readNpmrcConfigs)(projectDir);
|
|
199
|
+
// Detect workspace member paths if this is a workspace root
|
|
200
|
+
// Check both package.json workspaces (npm/yarn) and pnpm-workspace.yaml (pnpm)
|
|
201
|
+
let workspacePackagePaths;
|
|
202
|
+
const absoluteDir = this.relativeTo && !path.isAbsolute(dir)
|
|
203
|
+
? path.resolve(this.relativeTo, dir)
|
|
204
|
+
: dir;
|
|
205
|
+
if (packageJson.workspaces) {
|
|
206
|
+
// npm/yarn style workspaces defined in package.json
|
|
207
|
+
workspacePackagePaths = await this.resolveWorkspacePackagePaths(packageJson.workspaces, absoluteDir, this.relativeTo);
|
|
208
|
+
}
|
|
209
|
+
else if (packageManager === node_resolution_result_1.PackageManager.Pnpm) {
|
|
210
|
+
// pnpm workspaces defined in pnpm-workspace.yaml
|
|
211
|
+
const pnpmWorkspacePatterns = await this.readPnpmWorkspacePatterns(absoluteDir);
|
|
212
|
+
if (pnpmWorkspacePatterns && pnpmWorkspacePatterns.length > 0) {
|
|
213
|
+
workspacePackagePaths = await this.resolveWorkspacePackagePaths(pnpmWorkspacePatterns, absoluteDir, this.relativeTo);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return (0, node_resolution_result_1.createNodeResolutionResultMarker)(relativePath, packageJson, lockContent, workspacePackagePaths, packageManager, npmrcConfigs.length > 0 ? npmrcConfigs : undefined);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
console.warn(`Failed to create NodeResolutionResult marker: ${error}`);
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
233
222
|
}
|
|
234
223
|
/**
|
|
235
224
|
* Resolves workspace glob patterns to actual package.json paths.
|
|
@@ -244,74 +233,70 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
244
233
|
* @param relativeTo Optional base path for creating relative paths
|
|
245
234
|
* @returns Array of relative paths to workspace member package.json files
|
|
246
235
|
*/
|
|
247
|
-
resolveWorkspacePackagePaths(workspaces, projectDir, relativeTo) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
memberPaths.push(relativePath);
|
|
279
|
-
}
|
|
236
|
+
async resolveWorkspacePackagePaths(workspaces, projectDir, relativeTo) {
|
|
237
|
+
// Normalize workspaces to array format
|
|
238
|
+
const patterns = Array.isArray(workspaces)
|
|
239
|
+
? workspaces
|
|
240
|
+
: workspaces.packages;
|
|
241
|
+
if (!patterns || patterns.length === 0) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
// Separate include and exclude patterns
|
|
245
|
+
const includePatterns = patterns.filter(p => !p.startsWith('!'));
|
|
246
|
+
const excludePatterns = patterns.filter(p => p.startsWith('!')).map(p => p.slice(1));
|
|
247
|
+
// Create picomatch matchers
|
|
248
|
+
const isIncluded = includePatterns.length > 0
|
|
249
|
+
? (0, picomatch_1.default)(includePatterns, { dot: false })
|
|
250
|
+
: () => false;
|
|
251
|
+
const isExcluded = excludePatterns.length > 0
|
|
252
|
+
? (0, picomatch_1.default)(excludePatterns, { dot: false })
|
|
253
|
+
: () => false;
|
|
254
|
+
// Collect all candidate directories by walking the project
|
|
255
|
+
const candidateDirs = await this.collectCandidateWorkspaceDirs(projectDir, includePatterns);
|
|
256
|
+
const memberPaths = [];
|
|
257
|
+
const basePath = relativeTo || projectDir;
|
|
258
|
+
for (const candidateDir of candidateDirs) {
|
|
259
|
+
// Get relative path from project root for pattern matching
|
|
260
|
+
const relativeDir = path.relative(projectDir, candidateDir);
|
|
261
|
+
// Check if directory matches include patterns and not exclude patterns
|
|
262
|
+
if (isIncluded(relativeDir) && !isExcluded(relativeDir)) {
|
|
263
|
+
const packageJsonPath = path.join(candidateDir, 'package.json');
|
|
264
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
265
|
+
const relativePath = path.relative(basePath, packageJsonPath);
|
|
266
|
+
memberPaths.push(relativePath);
|
|
280
267
|
}
|
|
281
268
|
}
|
|
282
|
-
|
|
283
|
-
|
|
269
|
+
}
|
|
270
|
+
return memberPaths.length > 0 ? memberPaths : undefined;
|
|
284
271
|
}
|
|
285
272
|
/**
|
|
286
273
|
* Collects candidate directories that might match workspace patterns.
|
|
287
274
|
* Uses the patterns to determine how deep to scan.
|
|
288
275
|
*/
|
|
289
|
-
collectCandidateWorkspaceDirs(projectDir, patterns) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
// Use walkDirs with appropriate depth limit
|
|
306
|
-
const dirs = yield (0, path_utils_1.walkDirs)(absoluteBaseDir, {
|
|
307
|
-
maxDepth: hasRecursive ? undefined : 0,
|
|
308
|
-
excludeDirs: path_utils_1.DEFAULT_DIR_EXCLUSIONS
|
|
309
|
-
});
|
|
310
|
-
candidates.push(...dirs);
|
|
276
|
+
async collectCandidateWorkspaceDirs(projectDir, patterns) {
|
|
277
|
+
const candidates = [];
|
|
278
|
+
// Determine the maximum depth we need to scan based on patterns
|
|
279
|
+
// "packages/*" -> depth 1 under packages/
|
|
280
|
+
// "packages/**" -> unlimited depth under packages/
|
|
281
|
+
// "{apps,libs}/*" -> depth 1 under apps/ and libs/
|
|
282
|
+
for (const pattern of patterns) {
|
|
283
|
+
// Extract base directories from pattern (before any wildcards)
|
|
284
|
+
const baseDirs = this.extractBaseDirs(pattern);
|
|
285
|
+
const hasRecursive = pattern.includes('**');
|
|
286
|
+
for (const baseDir of baseDirs) {
|
|
287
|
+
const absoluteBaseDir = path.join(projectDir, baseDir);
|
|
288
|
+
if (!fs.existsSync(absoluteBaseDir)) {
|
|
289
|
+
continue;
|
|
311
290
|
}
|
|
291
|
+
// Use walkDirs with appropriate depth limit
|
|
292
|
+
const dirs = await (0, path_utils_1.walkDirs)(absoluteBaseDir, {
|
|
293
|
+
maxDepth: hasRecursive ? undefined : 0,
|
|
294
|
+
excludeDirs: path_utils_1.DEFAULT_DIR_EXCLUSIONS
|
|
295
|
+
});
|
|
296
|
+
candidates.push(...dirs);
|
|
312
297
|
}
|
|
313
|
-
|
|
314
|
-
|
|
298
|
+
}
|
|
299
|
+
return candidates;
|
|
315
300
|
}
|
|
316
301
|
/**
|
|
317
302
|
* Extracts base directory paths from a glob pattern.
|
|
@@ -346,22 +331,20 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
346
331
|
* @param projectDir The absolute path to the project directory
|
|
347
332
|
* @returns Array of workspace patterns, or undefined if file doesn't exist
|
|
348
333
|
*/
|
|
349
|
-
readPnpmWorkspacePatterns(projectDir) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
return parsed.packages;
|
|
357
|
-
}
|
|
358
|
-
return undefined;
|
|
359
|
-
}
|
|
360
|
-
catch (_a) {
|
|
361
|
-
// File doesn't exist or couldn't be parsed
|
|
362
|
-
return undefined;
|
|
334
|
+
async readPnpmWorkspacePatterns(projectDir) {
|
|
335
|
+
const pnpmWorkspacePath = path.join(projectDir, 'pnpm-workspace.yaml');
|
|
336
|
+
try {
|
|
337
|
+
const content = await fsp.readFile(pnpmWorkspacePath, 'utf-8');
|
|
338
|
+
const parsed = YAML.parse(content);
|
|
339
|
+
if (parsed && Array.isArray(parsed.packages)) {
|
|
340
|
+
return parsed.packages;
|
|
363
341
|
}
|
|
364
|
-
|
|
342
|
+
return undefined;
|
|
343
|
+
}
|
|
344
|
+
catch (_a) {
|
|
345
|
+
// File doesn't exist or couldn't be parsed
|
|
346
|
+
return undefined;
|
|
347
|
+
}
|
|
365
348
|
}
|
|
366
349
|
/**
|
|
367
350
|
* Attempts to find and read a lock file by walking up the directory tree.
|
|
@@ -375,30 +358,28 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
375
358
|
* @param rootDir Optional root directory to stop walking at (e.g., relativeTo/git root)
|
|
376
359
|
* @returns Object with parsed lock file content and detected package manager, or undefined if none found
|
|
377
360
|
*/
|
|
378
|
-
tryReadLockFileWithWalkUp(startDir, rootDir) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return undefined;
|
|
401
|
-
});
|
|
361
|
+
async tryReadLockFileWithWalkUp(startDir, rootDir) {
|
|
362
|
+
// Normalize paths for comparison
|
|
363
|
+
const normalizedRoot = rootDir ? path.resolve(rootDir) : undefined;
|
|
364
|
+
let currentDir = path.resolve(startDir);
|
|
365
|
+
// Walk up the directory tree looking for a lock file
|
|
366
|
+
while (true) {
|
|
367
|
+
const result = await this.tryReadLockFile(currentDir);
|
|
368
|
+
if (result) {
|
|
369
|
+
return result;
|
|
370
|
+
}
|
|
371
|
+
// If we've reached rootDir, stop walking (don't go above it)
|
|
372
|
+
if (normalizedRoot && currentDir === normalizedRoot) {
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
// Check if we've reached the filesystem root
|
|
376
|
+
const parentDir = path.dirname(currentDir);
|
|
377
|
+
if (parentDir === currentDir) {
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
currentDir = parentDir;
|
|
381
|
+
}
|
|
382
|
+
return undefined;
|
|
402
383
|
}
|
|
403
384
|
/**
|
|
404
385
|
* Attempts to read and parse a lock file from the given directory.
|
|
@@ -406,76 +387,72 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
406
387
|
*
|
|
407
388
|
* @returns Object with parsed lock file content and detected package manager, or undefined if no lock file found
|
|
408
389
|
*/
|
|
409
|
-
tryReadLockFile(dir) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
return { content: parsed, packageManager };
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
// Parse lock file based on package manager
|
|
433
|
-
const content = yield this.parseLockFileContent(config.filename, fileContent, dir);
|
|
434
|
-
if (content) {
|
|
435
|
-
return { content, packageManager };
|
|
390
|
+
async tryReadLockFile(dir) {
|
|
391
|
+
var _a;
|
|
392
|
+
// Use shared lock file detection config (first match wins based on priority)
|
|
393
|
+
for (const config of (0, package_manager_1.getLockFileDetectionConfig)()) {
|
|
394
|
+
const lockPath = path.join(dir, config.filename);
|
|
395
|
+
if (!fs.existsSync(lockPath)) {
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
// Lock file exists - determine package manager
|
|
399
|
+
// Once we find a lock file, we commit to this package manager even if parsing fails
|
|
400
|
+
try {
|
|
401
|
+
const fileContent = await fsp.readFile(lockPath, 'utf-8');
|
|
402
|
+
const packageManager = typeof config.packageManager === 'function'
|
|
403
|
+
? config.packageManager(fileContent)
|
|
404
|
+
: config.packageManager;
|
|
405
|
+
// For package managers where lock file omits details, prefer node_modules
|
|
406
|
+
if (config.preferNodeModules) {
|
|
407
|
+
const parsed = await this.walkNodeModules(dir);
|
|
408
|
+
if (parsed) {
|
|
409
|
+
return { content: parsed, packageManager };
|
|
436
410
|
}
|
|
437
|
-
// Lock file exists but couldn't be parsed - still return the package manager
|
|
438
|
-
// This ensures we use the correct package manager even without resolved dependencies
|
|
439
|
-
return { content: { lockfileVersion: 0, packages: {} }, packageManager };
|
|
440
411
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
? node_resolution_result_1.PackageManager.YarnClassic // Default for yarn.lock if we can't read content
|
|
446
|
-
: config.packageManager;
|
|
447
|
-
return { content: { lockfileVersion: 0, packages: {} }, packageManager };
|
|
412
|
+
// Parse lock file based on package manager
|
|
413
|
+
const content = await this.parseLockFileContent(config.filename, fileContent, dir);
|
|
414
|
+
if (content) {
|
|
415
|
+
return { content, packageManager };
|
|
448
416
|
}
|
|
417
|
+
// Lock file exists but couldn't be parsed - still return the package manager
|
|
418
|
+
// This ensures we use the correct package manager even without resolved dependencies
|
|
419
|
+
return { content: { lockfileVersion: 0, packages: {} }, packageManager };
|
|
449
420
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
421
|
+
catch (error) {
|
|
422
|
+
(_a = console.debug) === null || _a === void 0 ? void 0 : _a.call(console, `Failed to parse ${config.filename}: ${error}`);
|
|
423
|
+
// Even on error, we found this lock file - return the package manager with empty content
|
|
424
|
+
const packageManager = typeof config.packageManager === 'function'
|
|
425
|
+
? node_resolution_result_1.PackageManager.YarnClassic // Default for yarn.lock if we can't read content
|
|
426
|
+
: config.packageManager;
|
|
427
|
+
return { content: { lockfileVersion: 0, packages: {} }, packageManager };
|
|
456
428
|
}
|
|
457
|
-
|
|
458
|
-
|
|
429
|
+
}
|
|
430
|
+
// Fallback: if node_modules exists but no lock file was found (e.g., symlinked from another workspace),
|
|
431
|
+
// walk node_modules to get resolved dependency information
|
|
432
|
+
const parsed = await this.walkNodeModules(dir);
|
|
433
|
+
if (parsed) {
|
|
434
|
+
// Assume npm as the default package manager when only node_modules exists
|
|
435
|
+
return { content: parsed, packageManager: node_resolution_result_1.PackageManager.Npm };
|
|
436
|
+
}
|
|
437
|
+
return undefined;
|
|
459
438
|
}
|
|
460
439
|
/**
|
|
461
440
|
* Parses lock file content based on the lock file type.
|
|
462
441
|
*/
|
|
463
|
-
parseLockFileContent(filename, content, dir) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
});
|
|
442
|
+
async parseLockFileContent(filename, content, dir) {
|
|
443
|
+
switch (filename) {
|
|
444
|
+
case 'package-lock.json':
|
|
445
|
+
return JSON.parse(content);
|
|
446
|
+
case 'bun.lock':
|
|
447
|
+
return this.convertBunLockToNpmFormat(this.parseJsonc(content));
|
|
448
|
+
case 'pnpm-lock.yaml':
|
|
449
|
+
// Fall back to pnpm CLI when node_modules unavailable
|
|
450
|
+
return this.getPnpmDependencies(dir);
|
|
451
|
+
case 'yarn.lock':
|
|
452
|
+
return this.parseYarnLock(content);
|
|
453
|
+
default:
|
|
454
|
+
return undefined;
|
|
455
|
+
}
|
|
479
456
|
}
|
|
480
457
|
/**
|
|
481
458
|
* Parses JSONC (JSON with Comments and trailing commas) content.
|
|
@@ -492,82 +469,78 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
492
469
|
* @param dir The project directory containing node_modules
|
|
493
470
|
* @returns npm package-lock.json format with packages map, or undefined if node_modules doesn't exist
|
|
494
471
|
*/
|
|
495
|
-
walkNodeModules(dir) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
} : undefined;
|
|
516
|
-
});
|
|
472
|
+
async walkNodeModules(dir) {
|
|
473
|
+
const nodeModulesPath = path.join(dir, 'node_modules');
|
|
474
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
475
|
+
return undefined;
|
|
476
|
+
}
|
|
477
|
+
const packages = {
|
|
478
|
+
"": {} // Root package placeholder
|
|
479
|
+
};
|
|
480
|
+
// Check if this is a pnpm project (has .pnpm directory)
|
|
481
|
+
const pnpmPath = path.join(nodeModulesPath, '.pnpm');
|
|
482
|
+
if (fs.existsSync(pnpmPath)) {
|
|
483
|
+
await this.walkPnpmNodeModules(pnpmPath, packages);
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
await this.walkNodeModulesRecursive(nodeModulesPath, 'node_modules', packages);
|
|
487
|
+
}
|
|
488
|
+
return Object.keys(packages).length > 1 ? {
|
|
489
|
+
lockfileVersion: 3,
|
|
490
|
+
packages
|
|
491
|
+
} : undefined;
|
|
517
492
|
}
|
|
518
493
|
/**
|
|
519
494
|
* Walks pnpm's .pnpm directory structure to build packages map.
|
|
520
495
|
* pnpm stores packages in .pnpm/<name>@<version>/node_modules/<name>/
|
|
521
496
|
*/
|
|
522
|
-
walkPnpmNodeModules(pnpmPath, packages) {
|
|
523
|
-
|
|
524
|
-
|
|
497
|
+
async walkPnpmNodeModules(pnpmPath, packages) {
|
|
498
|
+
let entries;
|
|
499
|
+
try {
|
|
500
|
+
entries = await fsp.readdir(pnpmPath, { withFileTypes: true });
|
|
501
|
+
}
|
|
502
|
+
catch (_a) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
// Process entries in parallel for better performance
|
|
506
|
+
await Promise.all(entries.map(async (entry) => {
|
|
507
|
+
// Skip non-directories and special files
|
|
508
|
+
if (!entry.isDirectory() || entry.name === 'node_modules') {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
// Parse name@version from directory name
|
|
512
|
+
// pnpm directory format: <name>@<version> or <name>@<version>_<peer-deps-context>
|
|
513
|
+
// Handle scoped packages: @scope+name@version
|
|
514
|
+
// Example: @babel+helper-module-transforms@7.28.3_@babel+core@7.28.5
|
|
515
|
+
// -> name: @babel/helper-module-transforms, version: 7.28.3
|
|
516
|
+
// First, strip peer dependency context (everything after first _)
|
|
517
|
+
const underscoreIndex = entry.name.indexOf('_');
|
|
518
|
+
const mainPart = underscoreIndex > 0 ? entry.name.substring(0, underscoreIndex) : entry.name;
|
|
519
|
+
// Now parse name@version from the main part
|
|
520
|
+
const atIndex = mainPart.lastIndexOf('@');
|
|
521
|
+
if (atIndex <= 0)
|
|
522
|
+
return;
|
|
523
|
+
let name = mainPart.substring(0, atIndex);
|
|
524
|
+
const version = mainPart.substring(atIndex + 1);
|
|
525
|
+
// pnpm encodes @ as + in scoped packages: @scope+name -> @scope/name
|
|
526
|
+
if (name.startsWith('@') && name.includes('+')) {
|
|
527
|
+
name = name.replace('+', '/');
|
|
528
|
+
}
|
|
529
|
+
// The actual package is at .pnpm/<name>@<version>/node_modules/<name>/
|
|
530
|
+
const pkgDir = path.join(pnpmPath, entry.name, 'node_modules', name.replace('/', path.sep));
|
|
531
|
+
const packageJsonPath = path.join(pkgDir, 'package.json');
|
|
532
|
+
let pkgJson;
|
|
525
533
|
try {
|
|
526
|
-
|
|
534
|
+
const content = await fsp.readFile(packageJsonPath, 'utf-8');
|
|
535
|
+
pkgJson = JSON.parse(content);
|
|
527
536
|
}
|
|
528
537
|
catch (_a) {
|
|
529
538
|
return;
|
|
530
539
|
}
|
|
531
|
-
//
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
// Parse name@version from directory name
|
|
538
|
-
// pnpm directory format: <name>@<version> or <name>@<version>_<peer-deps-context>
|
|
539
|
-
// Handle scoped packages: @scope+name@version
|
|
540
|
-
// Example: @babel+helper-module-transforms@7.28.3_@babel+core@7.28.5
|
|
541
|
-
// -> name: @babel/helper-module-transforms, version: 7.28.3
|
|
542
|
-
// First, strip peer dependency context (everything after first _)
|
|
543
|
-
const underscoreIndex = entry.name.indexOf('_');
|
|
544
|
-
const mainPart = underscoreIndex > 0 ? entry.name.substring(0, underscoreIndex) : entry.name;
|
|
545
|
-
// Now parse name@version from the main part
|
|
546
|
-
const atIndex = mainPart.lastIndexOf('@');
|
|
547
|
-
if (atIndex <= 0)
|
|
548
|
-
return;
|
|
549
|
-
let name = mainPart.substring(0, atIndex);
|
|
550
|
-
const version = mainPart.substring(atIndex + 1);
|
|
551
|
-
// pnpm encodes @ as + in scoped packages: @scope+name -> @scope/name
|
|
552
|
-
if (name.startsWith('@') && name.includes('+')) {
|
|
553
|
-
name = name.replace('+', '/');
|
|
554
|
-
}
|
|
555
|
-
// The actual package is at .pnpm/<name>@<version>/node_modules/<name>/
|
|
556
|
-
const pkgDir = path.join(pnpmPath, entry.name, 'node_modules', name.replace('/', path.sep));
|
|
557
|
-
const packageJsonPath = path.join(pkgDir, 'package.json');
|
|
558
|
-
let pkgJson;
|
|
559
|
-
try {
|
|
560
|
-
const content = yield fsp.readFile(packageJsonPath, 'utf-8');
|
|
561
|
-
pkgJson = JSON.parse(content);
|
|
562
|
-
}
|
|
563
|
-
catch (_a) {
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
// Use name@version as the key for pnpm (flat structure with version)
|
|
567
|
-
const pkgKey = `node_modules/${name}@${version}`;
|
|
568
|
-
packages[pkgKey] = PackageJsonParser.extractPackageMetadata(pkgJson, version);
|
|
569
|
-
})));
|
|
570
|
-
});
|
|
540
|
+
// Use name@version as the key for pnpm (flat structure with version)
|
|
541
|
+
const pkgKey = `node_modules/${name}@${version}`;
|
|
542
|
+
packages[pkgKey] = PackageJsonParser.extractPackageMetadata(pkgJson, version);
|
|
543
|
+
}));
|
|
571
544
|
}
|
|
572
545
|
/**
|
|
573
546
|
* Recursively walks a node_modules directory, reading package.json files
|
|
@@ -577,79 +550,75 @@ class PackageJsonParser extends parser_1.Parser {
|
|
|
577
550
|
* @param relativePath Relative path from project root (e.g., "node_modules" or "node_modules/foo/node_modules")
|
|
578
551
|
* @param packages The packages map to populate
|
|
579
552
|
*/
|
|
580
|
-
walkNodeModulesRecursive(nodeModulesPath, relativePath, packages) {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
553
|
+
async walkNodeModulesRecursive(nodeModulesPath, relativePath, packages) {
|
|
554
|
+
let entries;
|
|
555
|
+
try {
|
|
556
|
+
entries = await fsp.readdir(nodeModulesPath, { withFileTypes: true });
|
|
557
|
+
}
|
|
558
|
+
catch (_a) {
|
|
559
|
+
return; // Directory not readable
|
|
560
|
+
}
|
|
561
|
+
// Process entries in parallel for better performance
|
|
562
|
+
await Promise.all(entries.map(async (entry) => {
|
|
563
|
+
// Skip hidden files
|
|
564
|
+
if (entry.name.startsWith('.')) {
|
|
565
|
+
return;
|
|
585
566
|
}
|
|
586
|
-
|
|
587
|
-
|
|
567
|
+
// Accept directories and symlinks (pnpm uses symlinks)
|
|
568
|
+
const isDirectoryOrSymlink = entry.isDirectory() || entry.isSymbolicLink();
|
|
569
|
+
if (!isDirectoryOrSymlink) {
|
|
570
|
+
return;
|
|
588
571
|
}
|
|
589
|
-
//
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
572
|
+
// Handle scoped packages (@scope/name)
|
|
573
|
+
if (entry.name.startsWith('@')) {
|
|
574
|
+
const scopePath = path.join(nodeModulesPath, entry.name);
|
|
575
|
+
let scopeEntries;
|
|
576
|
+
try {
|
|
577
|
+
scopeEntries = await fsp.readdir(scopePath, { withFileTypes: true });
|
|
594
578
|
}
|
|
595
|
-
|
|
596
|
-
const isDirectoryOrSymlink = entry.isDirectory() || entry.isSymbolicLink();
|
|
597
|
-
if (!isDirectoryOrSymlink) {
|
|
579
|
+
catch (_a) {
|
|
598
580
|
return;
|
|
599
581
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
let scopeEntries;
|
|
604
|
-
try {
|
|
605
|
-
scopeEntries = yield fsp.readdir(scopePath, { withFileTypes: true });
|
|
606
|
-
}
|
|
607
|
-
catch (_a) {
|
|
582
|
+
await Promise.all(scopeEntries.map(async (scopeEntry) => {
|
|
583
|
+
// Accept directories and symlinks for scoped packages too
|
|
584
|
+
if (!scopeEntry.isDirectory() && !scopeEntry.isSymbolicLink())
|
|
608
585
|
return;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
else {
|
|
620
|
-
const pkgPath = path.join(nodeModulesPath, entry.name);
|
|
621
|
-
yield this.processPackage(pkgPath, `${relativePath}/${entry.name}`, packages);
|
|
622
|
-
}
|
|
623
|
-
})));
|
|
624
|
-
});
|
|
586
|
+
const scopedName = `${entry.name}/${scopeEntry.name}`;
|
|
587
|
+
const pkgPath = path.join(scopePath, scopeEntry.name);
|
|
588
|
+
await this.processPackage(pkgPath, `${relativePath}/${scopedName}`, packages);
|
|
589
|
+
}));
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
const pkgPath = path.join(nodeModulesPath, entry.name);
|
|
593
|
+
await this.processPackage(pkgPath, `${relativePath}/${entry.name}`, packages);
|
|
594
|
+
}
|
|
595
|
+
}));
|
|
625
596
|
}
|
|
626
597
|
/**
|
|
627
598
|
* Processes a single package directory, reading its package.json and
|
|
628
599
|
* recursively processing nested node_modules.
|
|
629
600
|
*/
|
|
630
|
-
processPackage(pkgPath, relativePath, packages) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
});
|
|
601
|
+
async processPackage(pkgPath, relativePath, packages) {
|
|
602
|
+
const packageJsonPath = path.join(pkgPath, 'package.json');
|
|
603
|
+
// Read and parse the package's package.json
|
|
604
|
+
let pkgJson;
|
|
605
|
+
try {
|
|
606
|
+
const content = await fsp.readFile(packageJsonPath, 'utf-8');
|
|
607
|
+
pkgJson = JSON.parse(content);
|
|
608
|
+
}
|
|
609
|
+
catch (_a) {
|
|
610
|
+
return; // Not a valid package
|
|
611
|
+
}
|
|
612
|
+
packages[relativePath] = PackageJsonParser.extractPackageMetadata(pkgJson);
|
|
613
|
+
// Recursively process nested node_modules
|
|
614
|
+
const nestedNodeModules = path.join(pkgPath, 'node_modules');
|
|
615
|
+
try {
|
|
616
|
+
await fsp.access(nestedNodeModules);
|
|
617
|
+
await this.walkNodeModulesRecursive(nestedNodeModules, `${relativePath}/node_modules`, packages);
|
|
618
|
+
}
|
|
619
|
+
catch (_b) {
|
|
620
|
+
// No nested node_modules, that's fine
|
|
621
|
+
}
|
|
653
622
|
}
|
|
654
623
|
/**
|
|
655
624
|
* Converts bun.lock format to npm package-lock.json format for unified processing.
|