UNPKG

gitfm

Version:

A CLI App for searching GitHub/GitLab repos, fetching as filesystem and cloning

165 lines (154 loc) 4.66 kB
import search from "@inquirer/search"; import chalk from "chalk"; async function getCurrentRateLimitsData() { const response = await fetch("https://api.github.com/rate_limit", { method: "GET", headers: { "X-GitHub-Api-Version": "2022-11-28", "Accept": "application/vnd.github+json" }, }); const rateLimits = await response.json(); return rateLimits.resources; } // Fetch repositories based on the search term async function fetchRepos(searchTerm) { try { const rateLimitsData = await getCurrentRateLimitsData(); const searchRequestsRemaining = Number(rateLimitsData.search.remaining); if (searchRequestsRemaining > 0) { const response = await fetch( `https://api.github.com/search/repositories?q=${searchTerm}`, { headers: { "X-GitHub-Api-Version": "2022-11-28", "Accept": "application/vnd.github+json" }, }); const data = await response.json(); return { entries: data.items, length: data.total_count, }; } else { console.log( chalk.yellow( "\nYou ran out of search queries!\nTry again after some minutes!!\n", ), ); console.log( `Visit - https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api to learn more about GitHub API rate limits`, ); process.exit(1); } } catch (err) { console.log("\n", err.message, "\n"); process.exit(1); } } // Show Info of a single repository function repoInfo(repo) { const { name, description, html_url } = repo; console.log(''); console.log( chalk.bgGreenBright(chalk.black("repo name :")), "\t", chalk.bold(name), "\n", ); console.log( chalk.bgGreenBright(chalk.black("Description :")), "\t", chalk.bold(description), "\n", ); console.log( chalk.bgGreenBright(chalk.black("URL :")), "\t", chalk.bold(chalk.underline(html_url)), "\n", ); } function mapRepos(repos) { return repos.map((repo) => ({ name: repo.full_name, value: repo, description: repo.description, })); } // Prompt the user to select a repository from the list with Autocomplete async function promptRepoSelection(repos) { const choices = mapRepos(repos); try { return await search({ message: `${chalk.greenBright("Select a repository: ")}${chalk.yellow("(Autocomplete Available)")}`, source: async (input, { signal }) => { if (signal.aborted) { console.log(chalk.yellow("Aborted!")); process.exit(1); } if (!input) { return choices; } else { const filteredChoices = choices.filter((choice) => choice.name.includes(input), ); return filteredChoices; } }, }); } catch (_) { console.log(chalk.yellow("Aborted! Exiting Gracefully...")); process.exit(1); } } // Fetch the contents of the selected repository as an object // When response statusText is 'OK', the content object will be `fetchRepoContentsResponse().data` // If response status code is >= 400, the `fetchRepoContentsResponse().data` will be error.response.data async function fetchRepoContentsResponse(repoFullName) { try { const rateLimits = await getCurrentRateLimitsData(); const coreRequestsRemaining = Number(rateLimits.core.remaining); if (coreRequestsRemaining > 0) { const response = await fetch( `https://api.github.com/repos/${repoFullName}/contents`, ); const responseData = await response.json(); return { data: responseData, status: Number(response.status), }; } else { console.log( chalk.yellow( `\nYou ran out of request limits!\nTry again after some minutes!!\n`, ), ); } } catch (error) { console.error(error.message,'\n', "Fetch Error"); } } // Render the repository contents as a folder structure function renderRepoContents(contents, indent = " ") { try { contents.forEach((item) => { if (item.type === "dir") { console.log( `${indent}`, chalk.bgCyanBright(chalk.black(`${item.name}`)), chalk.blueBright("/"), ); /* axios.get(item.url).then((response) => { renderRepoContents(response.data, indent + " "); }); */ } else { console.log(`${indent}${item.name}`); } }); } catch (error) { console.error( chalk.bgBlue("Unexpected Error occured while rendering contents"), ); } } export { fetchRepos, fetchRepoContentsResponse, repoInfo, promptRepoSelection, renderRepoContents, };