MCPcopy
hub / github.com/CodebuffAI/codebuff / normalizeRepositoryUrl

Function normalizeRepositoryUrl

packages/billing/src/org-billing.ts:452–490  ·  view source on GitHub ↗
(url: string)

Source from the content-addressed store, hash-verified

450 * Normalizes a repository URL to a standard format.
451 */
452export function normalizeRepositoryUrl(url: string): string {
453 let normalized = url.toLowerCase().trim()
454
455 // Remove .git suffix
456 if (normalized.endsWith('.git')) {
457 normalized = normalized.slice(0, -4)
458 }
459
460 // Convert SSH to HTTPS
461 if (normalized.startsWith('git@github.com:')) {
462 normalized = normalized.replace('git@github.com:', 'https://github.com/')
463 }
464
465 // Ensure https:// prefix for github URLs
466 if (!normalized.startsWith('http') && normalized.includes('github.com')) {
467 normalized = 'https://' + normalized
468 }
469
470 // Parse URL to extract base repository URL (strip extra paths like /pull/123/files)
471 try {
472 const urlObj = new URL(normalized)
473 const pathSegments = urlObj.pathname
474 .split('/')
475 .filter((segment) => segment.length > 0)
476
477 // For known Git hosting providers, only keep the first two path segments (owner/repo)
478 const knownHosts = ['github.com', 'gitlab.com', 'bitbucket.org']
479 if (knownHosts.includes(urlObj.hostname) && pathSegments.length >= 2) {
480 // Reconstruct URL with only owner/repo path
481 const basePath = `/${pathSegments[0]}/${pathSegments[1]}`
482 normalized = `${urlObj.protocol}//${urlObj.hostname}${basePath}`
483 }
484 } catch (error) {
485 // If URL parsing fails, return the normalized string as-is
486 // This maintains backward compatibility
487 }
488
489 return normalized
490}
491
492/**
493 * Validates and normalizes a repository URL.

Calls

no outgoing calls

Tested by

no test coverage detected