You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

git-ripper

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

git-ripper - npm Package Compare versions

Comparing version

to
1.4.7

2

package.json
{
"name": "git-ripper",
"version": "1.4.6",
"version": "1.4.7",
"description": "CLI tool that lets you download specific folders from GitHub repositories without cloning the entire repo.",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -91,3 +91,3 @@ import fs from "fs";

chalk.green(
`✓ Archive created: ${outputPath} (${(size / 1024 / 1024).toFixed(
`Archive created: ${outputPath} (${(size / 1024 / 1024).toFixed(
2

@@ -94,0 +94,0 @@ )} MB)`

@@ -55,3 +55,5 @@ import axios from "axios";

try {
const repoInfoUrl = `https://api.github.com/repos/${owner}/${repo}`;
const repoInfoUrl = `https://api.github.com/repos/${encodeURIComponent(
owner
)}/${encodeURIComponent(repo)}`;
const repoInfoResponse = await axios.get(repoInfoUrl);

@@ -79,3 +81,7 @@ effectiveBranch = repoInfoResponse.data.default_branch;

const apiUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${effectiveBranch}?recursive=1`;
const apiUrl = `https://api.github.com/repos/${encodeURIComponent(
owner
)}/${encodeURIComponent(repo)}/git/trees/${encodeURIComponent(
effectiveBranch
)}?recursive=1`;

@@ -169,3 +175,5 @@ try {

try {
const repoInfoUrl = `https://api.github.com/repos/${owner}/${repo}`;
const repoInfoUrl = `https://api.github.com/repos/${encodeURIComponent(
owner
)}/${encodeURIComponent(repo)}`;
const repoInfoResponse = await axios.get(repoInfoUrl);

@@ -197,6 +205,12 @@ effectiveBranch = repoInfoResponse.data.default_branch;

const baseUrl = `https://raw.githubusercontent.com/${owner}/${repo}`;
const baseUrl = `https://raw.githubusercontent.com/${encodeURIComponent(
owner
)}/${encodeURIComponent(repo)}`;
const encodedFilePath = filePath
.split("/")
.map((part) => encodeURIComponent(part))
.join("/");
const fileUrlPath = effectiveBranch
? `/${effectiveBranch}/${filePath}`
: `/${filePath}`; // filePath might be at root
? `/${encodeURIComponent(effectiveBranch)}/${encodedFilePath}`
: `/${encodedFilePath}`; // filePath might be at root
const url = `${baseUrl}${fileUrlPath}`;

@@ -490,3 +504,3 @@

console.log(
chalk.red(`❌ Download failed: No files were downloaded successfully`)
chalk.red(`Download failed: No files were downloaded successfully`)
);

@@ -500,3 +514,3 @@ return {

} else {
console.log(chalk.yellow(`⚠️ Download completed with errors`));
console.log(chalk.yellow(`Download completed with errors`));
return {

@@ -511,3 +525,3 @@ success: false,

console.log(
chalk.green(`✅ All ${succeeded} files downloaded successfully!`)
chalk.green(`All ${succeeded} files downloaded successfully!`)
);

@@ -524,3 +538,3 @@ console.log(chalk.green(`Folder cloned successfully!`));

// Log the specific error details
console.error(chalk.red(`❌ Error downloading folder: ${error.message}`));
console.error(chalk.red(`Error downloading folder: ${error.message}`));

@@ -550,5 +564,13 @@ // Re-throw the error so the main CLI can exit with proper error code

const resumeManager = new ResumeManager();
const url = `https://github.com/${owner}/${repo}/tree/${branch || "main"}/${
folderPath || ""
}`;
const encodedFolderPath = folderPath
? folderPath
.split("/")
.map((part) => encodeURIComponent(part))
.join("/")
: "";
const url = `https://github.com/${encodeURIComponent(
owner
)}/${encodeURIComponent(repo)}/tree/${encodeURIComponent(
branch || "main"
)}/${encodedFolderPath}`;

@@ -566,3 +588,3 @@ // Clear checkpoint if force restart is requested

chalk.blue(
`🔄 Found previous download from ${new Date(
`Found previous download from ${new Date(
checkpoint.timestamp

@@ -574,3 +596,3 @@ ).toLocaleString()}`

chalk.blue(
`📊 Progress: ${checkpoint.downloadedFiles.length}/${checkpoint.totalFiles} files completed`
`Progress: ${checkpoint.downloadedFiles.length}/${checkpoint.totalFiles} files completed`
)

@@ -601,7 +623,7 @@ );

chalk.yellow(
`🔧 Detected ${corruptedCount} corrupted files, will re-download`
`Detected ${corruptedCount} corrupted files, will re-download`
)
);
}
console.log(chalk.green(`✅ Verified ${validFiles.length} existing files`));
console.log(chalk.green(`Verified ${validFiles.length} existing files`));
}

@@ -655,3 +677,3 @@

chalk.cyan(
`📥 Starting download of ${totalFiles} files from ${chalk.white(
`Starting download of ${totalFiles} files from ${chalk.white(
owner + "/" + repo

@@ -664,3 +686,3 @@ )}...`

checkpoint.totalFiles = totalFiles;
console.log(chalk.cyan(`📥 Resuming download...`));
console.log(chalk.cyan(`Resuming download...`));
}

@@ -680,3 +702,3 @@

if (remainingFiles.length === 0) {
console.log(chalk.green(`🎉 All files already downloaded!`));
console.log(chalk.green(`All files already downloaded!`));
resumeManager.cleanupCheckpoint(url, outputDir);

@@ -687,3 +709,3 @@ return;

console.log(
chalk.cyan(`📥 Downloading ${remainingFiles.length} remaining files...`)
chalk.cyan(`Downloading ${remainingFiles.length} remaining files...`)
);

@@ -772,6 +794,4 @@

progressBar.stop();
console.log(
chalk.blue(`\n⏸️ Download interrupted. Progress saved.`)
);
console.log(chalk.blue(`💡 Run the same command again to resume.`));
console.log(chalk.blue(`\nDownload interrupted. Progress saved.`));
console.log(chalk.blue(`Run the same command again to resume.`));
return;

@@ -813,3 +833,3 @@ }

console.log(
chalk.blue(`💡 Run the same command again to retry failed downloads`)
chalk.blue(`Run the same command again to retry failed downloads`)
);

@@ -820,3 +840,3 @@

console.log(
chalk.red(`❌ Download failed: No files were downloaded successfully`)
chalk.red(`Download failed: No files were downloaded successfully`)
);

@@ -830,3 +850,3 @@ return {

} else {
console.log(chalk.yellow(`⚠️ Download completed with errors`));
console.log(chalk.yellow(`Download completed with errors`));
return {

@@ -841,3 +861,3 @@ success: false,

console.log(
chalk.green(`🎉 All ${succeeded} files downloaded successfully!`)
chalk.green(`All ${succeeded} files downloaded successfully!`)
);

@@ -859,5 +879,5 @@ resumeManager.cleanupCheckpoint(url, outputDir);

console.error(chalk.red(`❌ Error downloading folder: ${error.message}`));
console.error(chalk.red(`Error downloading folder: ${error.message}`));
throw error;
}
};

@@ -79,3 +79,3 @@ import { program } from "commander";

console.log(chalk.cyan("\n📋 Download Checkpoints:"));
console.log(chalk.cyan("\nDownload Checkpoints:"));
checkpoints.forEach((cp, index) => {

@@ -155,8 +155,8 @@ console.log(chalk.blue(`\n${index + 1}. ID: ${cp.id}`));

operationType === "archive"
? `❌ Archive creation failed: ${error.message}`
: `❌ Download failed: ${error.message}`;
? `Archive creation failed: ${error.message}`
: `Download failed: ${error.message}`;
console.error(chalk.red(failMsg));
process.exit(1);
} else if (!createArchive && result && !result.success) {
console.error(chalk.red(`❌ Download failed`));
console.error(chalk.red(`Download failed`));
process.exit(1);

@@ -163,0 +163,0 @@ } else if (!createArchive && result && result.isEmpty) {

@@ -19,6 +19,6 @@ export function parseGitHubUrl(url) {

// Extract components from the matched pattern
const owner = match[1];
const repo = match[2];
const branch = match[3]; // Branch might not be in the URL for root downloads
const folderPath = match[4] || ""; // Empty string if no folder path
const owner = decodeURIComponent(match[1]);
const repo = decodeURIComponent(match[2]);
const branch = match[3] ? decodeURIComponent(match[3]) : ""; // Branch is an empty string if not present
const folderPath = match[4] ? decodeURIComponent(match[4]) : ""; // Empty string if no folder path

@@ -25,0 +25,0 @@ // Additional validation