Skip to main content
Glama
MIT License
27,120
19,780
  • Linux
  • Apple
gitHubArchiveApi.ts•3.62 kB
import { RepomixError } from '../../shared/errorHandle.js'; import type { GitHubRepoInfo } from './gitRemoteParse.js'; /** * Constructs GitHub archive download URL * Format: https://github.com/owner/repo/archive/refs/heads/branch.zip * For tags: https://github.com/owner/repo/archive/refs/tags/tag.zip * For commits: https://github.com/owner/repo/archive/commit.zip */ export const buildGitHubArchiveUrl = (repoInfo: GitHubRepoInfo): string => { const { owner, repo, ref } = repoInfo; const baseUrl = `https://github.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/archive`; if (!ref) { // Default to HEAD (repository's default branch) return `${baseUrl}/HEAD.zip`; } // Check if ref looks like a commit SHA (40 hex chars or shorter) const isCommitSha = /^[0-9a-f]{4,40}$/i.test(ref); if (isCommitSha) { return `${baseUrl}/${encodeURIComponent(ref)}.zip`; } // For branches and tags, we need to determine the type // Default to branch format, will fallback to tag if needed return `${baseUrl}/refs/heads/${encodeURIComponent(ref)}.zip`; }; /** * Builds alternative archive URL for master branch as fallback */ export const buildGitHubMasterArchiveUrl = (repoInfo: GitHubRepoInfo): string | null => { const { owner, repo, ref } = repoInfo; if (ref) { return null; // Only applicable when no ref is specified } return `https://github.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/archive/refs/heads/master.zip`; }; /** * Builds alternative archive URL for tags */ export const buildGitHubTagArchiveUrl = (repoInfo: GitHubRepoInfo): string | null => { const { owner, repo, ref } = repoInfo; if (!ref || /^[0-9a-f]{4,40}$/i.test(ref)) { return null; // Not applicable for commits or no ref } return `https://github.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/archive/refs/tags/${encodeURIComponent(ref)}.zip`; }; /** * Gets the expected archive filename from GitHub * Format: repo-branch.zip or repo-sha.zip */ export const getArchiveFilename = (repoInfo: GitHubRepoInfo): string => { const { repo, ref } = repoInfo; const refPart = ref || 'HEAD'; // GitHub uses the last part of the ref for the filename const refName = refPart.includes('/') ? refPart.split('/').pop() : refPart; return `${repo}-${refName}.zip`; }; /** * Checks if a response indicates a GitHub API rate limit or error */ export const checkGitHubResponse = (response: Response): void => { if (response.status === 404) { throw new RepomixError( 'Repository not found or is private. Please check the repository URL and your access permissions.', ); } if (response.status === 403) { const rateLimitRemaining = response.headers.get('X-RateLimit-Remaining'); if (rateLimitRemaining === '0') { const resetTime = response.headers.get('X-RateLimit-Reset'); const resetDate = resetTime ? new Date(Number.parseInt(resetTime, 10) * 1000) : null; throw new RepomixError( `GitHub API rate limit exceeded. ${resetDate ? `Rate limit resets at ${resetDate.toISOString()}` : 'Please try again later.'}`, ); } throw new RepomixError( 'Access denied. The repository might be private or you might not have permission to access it.', ); } if (response.status === 500 || response.status === 502 || response.status === 503 || response.status === 504) { throw new RepomixError('GitHub server error. Please try again later.'); } if (!response.ok) { throw new RepomixError(`GitHub API error: ${response.status} ${response.statusText}`); } };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yamadashy/repomix'

If you have feedback or need assistance with the MCP directory API, please join our Discord server