@@ -250,6 +250,11 @@ class PackageManager {
|
||||
|
||||
console.log(chalk.green(`✓ Installed ${name}@${version || 'latest'} from ${source || (isFromCache ? 'cache' : 'registry')}`));
|
||||
|
||||
// Create binary links for locally installed packages
|
||||
if (!options.global) {
|
||||
await this.createBinaryLinksForPackage(name, targetDir);
|
||||
}
|
||||
|
||||
// Install dependencies recursively (with depth control)
|
||||
await this.installDependenciesRecursively(name, targetDir, options);
|
||||
|
||||
@@ -378,6 +383,11 @@ class PackageManager {
|
||||
await this.createGlobalBinLinks(pkg);
|
||||
}
|
||||
|
||||
// Create local binary links if not global
|
||||
if (!options.global && pkg.bin) {
|
||||
await this.createLocalBinLinks(pkg);
|
||||
}
|
||||
|
||||
this.logger.info(`Installed ${pkg.name}@${pkg.version}`);
|
||||
}
|
||||
|
||||
@@ -398,6 +408,8 @@ class PackageManager {
|
||||
// Remove from package.json
|
||||
if (!options.global) {
|
||||
await this.removeFromPackageJson(packageName);
|
||||
// Remove local bin links
|
||||
await this.removeLocalBinLinks(packageName);
|
||||
}
|
||||
|
||||
// Remove global bin links
|
||||
@@ -962,6 +974,62 @@ class PackageManager {
|
||||
}
|
||||
}
|
||||
|
||||
async createLocalBinLinks(pkg) {
|
||||
// Implementation for creating local binary links in node_modules/.bin
|
||||
const binDir = path.join(this.projectRoot, 'node_modules', '.bin');
|
||||
await fs.ensureDir(binDir);
|
||||
|
||||
if (pkg.bin) {
|
||||
// Handle both string and object formats for bin field
|
||||
const binEntries = typeof pkg.bin === 'string'
|
||||
? [[pkg.name, pkg.bin]]
|
||||
: Object.entries(pkg.bin);
|
||||
|
||||
for (const [binName, binPath] of binEntries) {
|
||||
const linkPath = path.join(binDir, binName);
|
||||
const targetPath = path.join(this.projectRoot, 'node_modules', pkg.name, binPath);
|
||||
|
||||
try {
|
||||
// Remove existing link if it exists
|
||||
if (await fs.pathExists(linkPath)) {
|
||||
await fs.remove(linkPath);
|
||||
}
|
||||
|
||||
// Create the symlink
|
||||
await fs.ensureSymlink(targetPath, linkPath);
|
||||
|
||||
// Make the target executable (Unix/Linux only)
|
||||
if (process.platform !== 'win32') {
|
||||
await fs.chmod(targetPath, '755');
|
||||
}
|
||||
|
||||
console.log(chalk.gray(` Created bin link: ${binName} -> ${binPath}`));
|
||||
} catch (error) {
|
||||
console.warn(chalk.yellow(`Warning: Failed to create bin link for ${binName}: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async createBinaryLinksForPackage(packageName, packageDir) {
|
||||
try {
|
||||
const packageJsonPath = path.join(packageDir, 'package.json');
|
||||
|
||||
if (!await fs.pathExists(packageJsonPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const packageJson = await fs.readJson(packageJsonPath);
|
||||
|
||||
if (packageJson.bin) {
|
||||
console.log(chalk.blue(`Creating local bin links for ${packageName}`));
|
||||
await this.createLocalBinLinks(packageJson);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(chalk.yellow(`Warning: Failed to create binary links for ${packageName}: ${error.message}`));
|
||||
}
|
||||
}
|
||||
|
||||
async removeGlobalBinLinks(packageName) {
|
||||
// Implementation for removing global binary links
|
||||
const binDir = path.join(this.globalRoot, 'bin');
|
||||
@@ -983,6 +1051,37 @@ class PackageManager {
|
||||
}
|
||||
}
|
||||
|
||||
async removeLocalBinLinks(packageName) {
|
||||
// Implementation for removing local binary links from node_modules/.bin
|
||||
const binDir = path.join(this.projectRoot, 'node_modules', '.bin');
|
||||
const packageDir = path.join(this.projectRoot, 'node_modules', packageName);
|
||||
|
||||
if (await fs.pathExists(packageDir)) {
|
||||
const packageJsonPath = path.join(packageDir, 'package.json');
|
||||
if (await fs.pathExists(packageJsonPath)) {
|
||||
try {
|
||||
const packageJson = await fs.readJson(packageJsonPath);
|
||||
if (packageJson.bin) {
|
||||
// Handle both string and object formats for bin field
|
||||
const binEntries = typeof packageJson.bin === 'string'
|
||||
? [[packageJson.name, packageJson.bin]]
|
||||
: Object.entries(packageJson.bin);
|
||||
|
||||
for (const [binName] of binEntries) {
|
||||
const linkPath = path.join(binDir, binName);
|
||||
if (await fs.pathExists(linkPath)) {
|
||||
await fs.remove(linkPath);
|
||||
console.log(chalk.gray(` Removed bin link: ${binName}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(chalk.yellow(`Warning: Failed to read package.json for ${packageName}: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fixVulnerabilities(vulnerabilities) {
|
||||
const spinner = ora('Fixing vulnerabilities...').start();
|
||||
|
||||
|
||||
Referencia en una nueva incidencia
Block a user