UNPKG

depshield

Version:

Smart Dependency Analyzer & Optimizer - Find unused npm packages, reduce bundle size, and improve project health with AST-based detection.

76 lines (75 loc) 2.98 kB
import fs from 'fs/promises'; import path from 'path'; import { glob } from 'glob'; import yaml from 'js-yaml'; export class WorkspaceManager { rootPath; constructor(rootPath) { this.rootPath = rootPath; } async detectWorkspace() { try { // Check for pnpm-workspace.yaml try { await fs.access(path.join(this.rootPath, 'pnpm-workspace.yaml')); return 'pnpm'; } catch { } // Check for package.json workspaces const pkgJsonPath = path.join(this.rootPath, 'package.json'); const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8')); if (pkgJson.workspaces) { return 'npm'; // or yarn, but npm handles the workspaces key similarly for detection } return null; } catch (error) { return null; } } async getPackages() { const type = await this.detectWorkspace(); if (!type) { throw new Error('No workspace configuration found (pnpm-workspace.yaml or package.json workspaces)'); } let patterns = []; if (type === 'pnpm') { const yamlContent = await fs.readFile(path.join(this.rootPath, 'pnpm-workspace.yaml'), 'utf-8'); const doc = yaml.load(yamlContent); if (doc && doc.packages) { patterns = doc.packages; } } else { const pkgJson = JSON.parse(await fs.readFile(path.join(this.rootPath, 'package.json'), 'utf-8')); patterns = Array.isArray(pkgJson.workspaces) ? pkgJson.workspaces : pkgJson.workspaces.packages || []; } const packages = []; for (const pattern of patterns) { // glob patterns might match directories. We need to find package.json inside them. // If pattern ends with /*, glob will find directories. // We want to find the package.json files. const searchPattern = pattern.endsWith('/') ? `${pattern}package.json` : `${pattern}/package.json`; const matches = await glob(searchPattern, { cwd: this.rootPath, ignore: ['**/node_modules/**'] }); for (const match of matches) { const pkgPath = path.join(this.rootPath, path.dirname(match)); const pkgJsonContent = await fs.readFile(path.join(this.rootPath, match), 'utf-8'); try { const pkgJson = JSON.parse(pkgJsonContent); packages.push({ name: pkgJson.name || path.basename(pkgPath), path: pkgPath, packageJson: pkgJson }); } catch (e) { // Ignore invalid package.json } } } return packages; } }