diff --git a/.gitignore b/.gitignore
index a547bf3..30bc162 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,24 +1 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
+/node_modules
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index bf5819a..0000000
--- a/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# 🚀 GitRepo Zip Fetcher
-
-Effortlessly download GitHub repositories and folders as ZIP files with just a few clicks! 🖱️
-
-## ✨ Features
-
-- 📦 Fetch entire GitHub repos or specific folders
-- 🗜️ Download repositories as ZIP files
-- 🔒 Support for both public and private repositories
-- 🔑 Optional GitHub Personal Access Token integration
-- 📊 Real-time progress tracking
-- 📱 Responsive design for all your devices
-
-## 🚀 How to Use
-
-1. 🌐 Open the app in your favorite web browser
-2. 📝 Enter a GitHub repository URL
-3. 🔑 (Optional) Click "Use Token" to enter your GitHub Personal Access Token
-4. 🚀 Hit the "Fetch" button or press Enter
-5. 📊 Watch the progress in the status output area
-6. 💾 When it's done, your ZIP file will start downloading automatically!
-
-## 🛠️ Dependencies
-
-- [JSZip](https://stuk.github.io/jszip/): ZIP file wizardry 🧙♂️
-- [FileSaver.js](https://github.com/eligrey/FileSaver.js/): Download magic 🪄
-- [Octokit](https://github.com/octokit/octokit.js): GitHub API sorcery 🔮
-
-## 📝 Note
-
-Your privacy is our top priority! 🛡️ This app runs entirely in your browser and doesn't collect or send any personal data. All operations happen on your device for maximum security. 🔒
-
-Enjoy fetching your GitHub repositories with ease! 🎉
diff --git a/bun.lockb b/bun.lockb
deleted file mode 100644
index 11539cb..0000000
Binary files a/bun.lockb and /dev/null differ
diff --git a/github/fetcher.js b/fetcher.js
similarity index 100%
rename from github/fetcher.js
rename to fetcher.js
diff --git a/github/index.html b/github/index.html
deleted file mode 100644
index 8f7bf14..0000000
--- a/github/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
- GitRepo Zip Fetcher
-
-
-
-
-
-
-
-
-
-
-
-
-
- Use Token
-
-
- get_app
- Fetch
-
-
-
- Token usage enhances API rate limit and give access to private repository.
-
-
-
-
-
- Made with ❤️ by Sachin Sharma
- Note: This application runs locally on your computer and does not collect or transmit any personal data.
-
-
-
-
-
-
-
-
-
-
diff --git a/index.html b/index.html
index 5e62a73..aa50d79 100644
--- a/index.html
+++ b/index.html
@@ -9,9 +9,13 @@
content="GitRepo Zip Fetcher is a sleek tool for effortlessly downloading GitHub repositories and folders as ZIP files."
/>
+
-
+
+
diff --git a/package.json b/package.json
deleted file mode 100644
index 4570039..0000000
--- a/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "github-repo-downloader",
- "private": true,
- "version": "1.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview"
- },
- "devDependencies": {
- "@vercel/analytics": "^1.3.1",
- "vite": "^6.1.0"
- }
-}
diff --git a/src/fetcher.js b/src/fetcher.js
deleted file mode 100644
index 919e145..0000000
--- a/src/fetcher.js
+++ /dev/null
@@ -1,150 +0,0 @@
-import { Octokit } from "https://cdn.skypack.dev/@octokit/rest";
-
-document.addEventListener("DOMContentLoaded", () => {
- const repoInput = document.getElementById("repoInput");
- const tokenInput = document.getElementById("tokenInput");
- const fetchBtn = document.getElementById("fetchBtn");
- const statusLog = document.getElementById("statusLog");
- const statusOutput = document.getElementById("statusOutput");
- const fileListElement = document.getElementById("fileList");
- const fileListWrapper = document.getElementById("fileListWrapper");
- const toggleTokenBtn = document.getElementById("toggleTokenBtn");
- const tokenInfo = document.getElementById("tokenInfo");
-
- let fetchedFiles = [];
- let progressPercentage = 0;
-
- const updateStatus = (message) => {
- statusLog.textContent = message;
- statusOutput.style.display = "block";
- };
-
- const updateProgress = (percent) => {
- progressPercentage = percent;
- statusLog.style.background = `linear-gradient(to right, rgba(100, 255, 218, 0.3) ${percent}%, transparent ${percent}%)`;
- statusLog.innerHTML = `${statusLog.textContent} ${percent}% Complete `;
- };
-
- const fetchFolderContents = async (octokit, owner, repo, path) => {
- const response = await octokit.rest.repos.getContent({
- owner,
- repo,
- path,
- });
- return response.data;
- };
-
- const fetchFileContent = async (octokit, owner, repo, path, fileName, totalSize) => {
- const response = await octokit.rest.repos.getContent({
- owner,
- repo,
- path,
- mediaType: {
- format: "raw",
- },
- });
- updateStatus(`Fetching ${fileName}`);
- updateProgress(100);
- return response.data;
- };
-
- const processFolderContents = async (octokit, owner, repo, folder, zip, path = "") => {
- for (const item of folder) {
- if (item.type === "file") {
- updateStatus(`Queueing fetch of ${item.name}`);
- const fileContent = await fetchFileContent(octokit, owner, repo, item.path, item.name, item.size);
- fetchedFiles.push(item);
- updateFileList();
- zip.file(item.name, fileContent);
- } else if (item.type === "dir") {
- const subFolder = await fetchFolderContents(octokit, owner, repo, item.path);
- const subFolderZip = zip.folder(item.name);
- await processFolderContents(octokit, owner, repo, subFolder, subFolderZip, item.path);
- }
- }
- };
-
- const fetchRepositoryContents = async (octokit, owner, repo, path) => {
- try {
- const folderData = await fetchFolderContents(octokit, owner, repo, path);
- const zip = new JSZip();
- await processFolderContents(octokit, owner, repo, folderData, zip, path);
- return zip;
- } catch (error) {
- console.error(`Error: ${error}`);
- throw error;
- }
- };
-
- const updateFileList = () => {
- fileListElement.innerHTML = "";
- fetchedFiles.forEach((file) => {
- const li = document.createElement("li");
- li.textContent = file.name;
- fileListElement.appendChild(li);
- });
- fileListWrapper.style.display = "block";
- fileListElement.scrollTop = fileListElement.scrollHeight;
- };
-
- const fetchRepo = async () => {
- updateStatus("");
- fetchedFiles = [];
- fileListWrapper.style.display = "none";
-
- const repoUrl = repoInput.value;
- const token = tokenInput.value.trim();
-
- if (!repoUrl.includes("github.com")) {
- updateStatus("Invalid URL. Please enter a valid GitHub repository URL.");
- return;
- }
-
- const [, , , owner, repo, , , ...dirParts] = repoUrl.split("/");
- const path = dirParts.join("/");
-
- const octokit = new Octokit({ auth: token });
-
- updateStatus("Fetching repository contents...");
- try {
- const zip = await fetchRepositoryContents(octokit, owner, repo, path);
-
- updateStatus("Compressing files...");
- const content = await zip.generateAsync({ type: "blob" });
- saveAs(content, `${path ? path.replace(/\/|%20/g, "-") : repo}.zip`);
-
- const fileList = zip.file(/.*/);
-
- updateProgress(0);
- updateStatus(
- `Fetched ${fileList.length} files\nUser: ${owner}\nRepository: ${repoUrl}\nFolder: ${path}\nSize: ${(
- content.size /
- 1024 /
- 1024
- ).toFixed(2)} MB`
- );
- } catch (error) {
- if (error.status === 403) {
- updateStatus("Rate limit exceeded. Please try again in a few minutes or use a GitHub Personal Access Token.");
- } else {
- updateStatus(`Error: ${error.message}`);
- }
- }
- };
-
- fetchBtn.addEventListener("click", fetchRepo);
- repoInput.addEventListener("keydown", (e) => {
- if (e.key === "Enter") {
- fetchRepo();
- }
- });
-
- toggleTokenBtn.addEventListener("click", () => {
- const isHidden = tokenInput.style.display === "none";
- tokenInput.style.display = isHidden ? "block" : "none";
- tokenInfo.style.display = isHidden ? "block" : "none";
- toggleTokenBtn.textContent = isHidden ? "Hide Token" : "Use Token";
- });
-
- repoInput.focus();
-});
diff --git a/src/styles.css b/src/styles.css
deleted file mode 100644
index 7b75470..0000000
--- a/src/styles.css
+++ /dev/null
@@ -1,171 +0,0 @@
-:root {
- --accent-color: #64ffda;
- --bg-color: #0a192f;
- --surface-color: #112240;
- --text-color: #ccd6f6;
- --error-color: #ff5370;
-}
-
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-body {
- background: linear-gradient(135deg, #0a192f, #112240);
- font-family: "Poppins", sans-serif;
- color: var(--text-color);
- min-height: 100vh;
-}
-
-.container {
- display: flex;
- flex-direction: column;
- min-height: 100vh;
-}
-
-header {
- background-color: var(--surface-color);
- padding: 2rem;
- text-align: center;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
-}
-
-h1 {
- font-weight: 500;
- margin-bottom: 0.5rem;
- color: var(--accent-color);
- font-size: 2.5rem;
-}
-
-main {
- flex-grow: 1;
- padding: 2rem;
- max-width: 800px;
- margin: 0 auto;
- width: 100%;
-}
-
-.input-wrapper {
- display: flex;
- flex-direction: column;
- gap: 1rem;
- margin-bottom: 1rem;
-}
-
-input {
- flex-grow: 1;
- padding: 0.75rem 1rem;
- border: 2px solid var(--accent-color);
- border-radius: 4px;
- background-color: var(--surface-color);
- color: var(--text-color);
- font-size: 1rem;
- font-family: "Poppins", sans-serif;
-}
-
-button {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 0.3rem;
- padding: 0.75rem 1.5rem;
- border: none;
- border-radius: 4px;
- background-color: var(--accent-color);
- color: var(--bg-color);
- font-size: 1rem;
- font-weight: 500;
- cursor: pointer;
- transition: background-color 0.3s ease, transform 0.1s ease;
-}
-
-button:hover {
- background-color: #45e0bc;
- transform: translateY(-2px);
-}
-
-.token-info {
- font-size: 0.9rem;
- color: var(--accent-color);
- margin-bottom: 1rem;
-}
-
-.toggle-token-btn {
- align-self: flex-start;
- padding: 0.5rem 1rem;
- font-size: 0.9rem;
- background-color: var(--surface-color);
- color: var(--accent-color);
- border: 1px solid var(--accent-color);
- cursor: pointer;
- transition: background-color 0.3s ease;
-}
-
-.toggle-token-btn:hover {
- background-color: rgba(100, 255, 218, 0.1);
-}
-
-.status-output {
- background-color: var(--surface-color);
- border-radius: 4px;
- padding: 1rem;
- margin-bottom: 2rem;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.status-log {
- font-family: "Courier New", monospace;
- white-space: pre-wrap;
- word-break: break-all;
- font-size: 0.9rem;
- line-height: 1.5;
-}
-
-.file-list {
- list-style-type: none;
- max-height: 250px;
- overflow-y: auto;
-}
-
-.file-list li {
- padding: 0.5rem 0;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
- font-size: 0.9rem;
-}
-
-footer {
- background-color: var(--surface-color);
- padding: 1rem;
- text-align: center;
- font-size: 0.9rem;
-}
-
-footer a {
- color: var(--accent-color);
- text-decoration: none;
- font-weight: 500;
-}
-
-.note {
- font-size: 0.8rem;
- color: var(--error-color);
- margin-top: 0.5rem;
-}
-
-@media (max-width: 600px) {
- h1 {
- font-size: 1.8rem;
- }
-
- p {
- font-size: 0.9rem;
- }
- .input-wrapper {
- flex-direction: column;
- }
- input {
- font-size: 0.8rem;
- }
-}
diff --git a/github/styles.css b/styles.css
similarity index 100%
rename from github/styles.css
rename to styles.css