21
package.json
21
package.json
@@ -48,19 +48,24 @@
|
|||||||
"IMPLEMENTATION.md"
|
"IMPLEMENTATION.md"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "^11.0.0",
|
"body-parser": "^2.2.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"semver": "^7.5.4",
|
"commander": "^11.1.0",
|
||||||
"tar": "^6.1.15",
|
|
||||||
"crypto": "^1.0.1",
|
"crypto": "^1.0.1",
|
||||||
"fs-extra": "^11.1.1",
|
"debug": "^4.4.1",
|
||||||
"node-fetch": "^2.6.12",
|
"express": "^5.1.0",
|
||||||
|
"fs-extra": "^11.3.1",
|
||||||
"inquirer": "^8.2.6",
|
"inquirer": "^8.2.6",
|
||||||
|
"listr2": "^6.6.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"node-fetch": "^2.6.12",
|
||||||
"ora": "^5.4.1",
|
"ora": "^5.4.1",
|
||||||
"listr2": "^6.6.1"
|
"semver": "^7.7.2",
|
||||||
|
"tar": "^6.2.1",
|
||||||
|
"lodash.debounce": "^4.0.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jest": "^29.6.2",
|
"eslint": "^8.45.0",
|
||||||
"eslint": "^8.45.0"
|
"jest": "^29.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,6 +228,9 @@ class PackageManager {
|
|||||||
|
|
||||||
console.log(chalk.green(`✓ Installed ${name}@${version || 'latest'}`));
|
console.log(chalk.green(`✓ Installed ${name}@${version || 'latest'}`));
|
||||||
|
|
||||||
|
// Install dependencies recursively (with depth control)
|
||||||
|
await this.installDependenciesRecursively(name, targetDir, options);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(chalk.red(`✗ Failed to install ${packageSpec}: ${error.message}`));
|
console.error(chalk.red(`✗ Failed to install ${packageSpec}: ${error.message}`));
|
||||||
results.push({ packageSpec, error: error.message });
|
results.push({ packageSpec, error: error.message });
|
||||||
@@ -246,6 +249,94 @@ class PackageManager {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async installDependenciesRecursively(packageName, packageDir, options = {}) {
|
||||||
|
try {
|
||||||
|
// Read the package.json of the installed package
|
||||||
|
const packageJsonPath = path.join(packageDir, 'package.json');
|
||||||
|
|
||||||
|
if (!await fs.pathExists(packageJsonPath)) {
|
||||||
|
// No package.json found, skip dependency installation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const packageJson = await fs.readJson(packageJsonPath);
|
||||||
|
const dependencies = {
|
||||||
|
...packageJson.dependencies,
|
||||||
|
...(options.includeDev ? packageJson.devDependencies : {})
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!dependencies || Object.keys(dependencies).length === 0) {
|
||||||
|
// No dependencies to install
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize installed packages tracking if not exists
|
||||||
|
if (!options._installedPackages) {
|
||||||
|
options._installedPackages = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit recursion depth to prevent infinite loops
|
||||||
|
const currentDepth = options._depth || 0;
|
||||||
|
if (currentDepth > 8) { // Increased from 5 to 8 for better dependency coverage
|
||||||
|
// Silent skip for deep dependencies to avoid log noise
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(chalk.blue(`Installing dependencies for ${packageName}...`));
|
||||||
|
|
||||||
|
// Filter out already installed packages to avoid duplicates
|
||||||
|
const dependenciesToInstall = Object.entries(dependencies).filter(([name, version]) => {
|
||||||
|
const packageKey = `${name}@${version}`;
|
||||||
|
if (options._installedPackages.has(packageKey)) {
|
||||||
|
return false; // Skip already installed package
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if package already exists in node_modules
|
||||||
|
const targetDir = options.global
|
||||||
|
? path.join(this.globalRoot, 'node_modules', name)
|
||||||
|
: path.join(this.projectRoot, 'node_modules', name);
|
||||||
|
|
||||||
|
return !fs.existsSync(targetDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dependenciesToInstall.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare dependency specs for installation
|
||||||
|
const dependencySpecs = dependenciesToInstall.map(([name, version]) => {
|
||||||
|
// Mark as installed to prevent duplicates
|
||||||
|
options._installedPackages.add(`${name}@${version}`);
|
||||||
|
|
||||||
|
// Handle various version formats
|
||||||
|
if (version.startsWith('^') || version.startsWith('~') || version.startsWith('>=') || version.startsWith('<=')) {
|
||||||
|
return `${name}@${version}`;
|
||||||
|
} else if (version === '*' || version === 'latest') {
|
||||||
|
return `${name}@latest`;
|
||||||
|
} else if (semver.validRange(version)) {
|
||||||
|
return `${name}@${version}`;
|
||||||
|
} else {
|
||||||
|
// For non-semver versions (git urls, file paths, etc.), use as-is
|
||||||
|
return `${name}@${version}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Install dependencies recursively by calling installPackages
|
||||||
|
const depOptions = {
|
||||||
|
...options,
|
||||||
|
fromPackageJson: true, // Prevent updating package.json
|
||||||
|
_depth: currentDepth + 1, // Increment depth
|
||||||
|
_installedPackages: options._installedPackages // Pass along installed packages set
|
||||||
|
};
|
||||||
|
|
||||||
|
// Install dependencies
|
||||||
|
await this.installPackages(dependencySpecs, depOptions);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(chalk.yellow(`Failed to install dependencies for ${packageName}: ${error.message}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async installPackage(pkg, options = {}) {
|
async installPackage(pkg, options = {}) {
|
||||||
const targetDir = options.global
|
const targetDir = options.global
|
||||||
? path.join(this.globalRoot, 'node_modules', pkg.name)
|
? path.join(this.globalRoot, 'node_modules', pkg.name)
|
||||||
|
|||||||
Referencia en una nueva incidencia
Block a user