( raw: string, )
| 75 | // falls through to the server-side detection so OpenAPI/MCP/GraphQL URLs keep |
| 76 | // their existing flows. |
| 77 | const detectGitRepository = ( |
| 78 | raw: string, |
| 79 | ): { readonly endpoint: string; readonly slug: string } | null => { |
| 80 | const value = raw.trim(); |
| 81 | if (!URL.canParse(value)) return null; |
| 82 | const parsed = new URL(value); |
| 83 | if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null; |
| 84 | if (parsed.username || parsed.password) return null; |
| 85 | const segments = parsed.pathname.split("/").filter(Boolean); |
| 86 | const knownGitHost = |
| 87 | GIT_REPO_HOSTS.has(parsed.hostname.toLowerCase()) && |
| 88 | segments.length === 2 && |
| 89 | parsed.search === ""; |
| 90 | if (!parsed.pathname.endsWith(".git") && !knownGitHost) return null; |
| 91 | const name = segments.at(-1)?.replace(/\.git$/, "") ?? ""; |
| 92 | if (!name) return null; |
| 93 | parsed.hash = ""; |
| 94 | return { |
| 95 | endpoint: parsed.toString(), |
| 96 | slug: name |
| 97 | .trim() |
| 98 | .toLowerCase() |
| 99 | .replace(/[^a-z0-9-]+/g, "-") |
| 100 | .replace(/^-+|-+$/g, "") |
| 101 | .slice(0, 80), |
| 102 | }; |
| 103 | }; |
| 104 | |
| 105 | // --------------------------------------------------------------------------- |
| 106 | // Page |
no test coverage detected