Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions scripts/build-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const siteUrl = (process.env.OSSRANK_SITE_URL ?? 'https://ossrank.dev').replace(
const sitemapEntries: Array<{ path: string; priority: string; changefreq: string }> = [];
const assetVersion = '20260509-polish1';
const updateCadenceLabel = 'Weekly refresh';
const externalLinkAttrs = 'target="_blank" rel="noopener noreferrer"';
const logoSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="OSSRank"><defs><linearGradient id="g" x1="18" y1="112" x2="110" y2="16" gradientUnits="userSpaceOnUse"><stop stop-color="#dc614f"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><rect width="128" height="128" rx="30" fill="#07111f"/><path d="M31 88h18V58H31v30Zm24 0h18V40H55v48Zm24 0h18V26H79v62Z" fill="url(#g)"/><path d="M28 96h74" stroke="#fff8ed" stroke-width="8" stroke-linecap="round" opacity=".9"/></svg>`;

function normalizeRoute(path: string): string {
Expand Down Expand Up @@ -139,7 +140,7 @@ function rankMovementBadge(entry: RankedContributor): string {

function contributorTable(snapshot: RankingSnapshot<RankedContributor>): string {
const rows = [...snapshot.entries].sort((a, b) => a.rank - b.rank);
return `<div class="table-wrap"><table id="contributors" aria-label="Top GitHub contributors in ${escapeHtml(snapshot.name)}"><thead><tr><th>Rank</th><th>Movement</th><th>Username</th><th><button data-sort="commits">Commits (1y)</button></th><th><button data-sort="prs">Public PRs (1y)</button></th><th><button data-sort="repos">Repos</button></th><th><button data-sort="followers">Followers</button></th><th>Location</th><th>Discovery</th></tr></thead><tbody>${rows.map((entry) => `<tr data-commits="${entry.observed_public_commits ?? 0}" data-prs="${entry.observed_public_pull_requests ?? 0}" data-repos="${entry.public_repos ?? 0}" data-followers="${entry.followers}"><td class="rank"><span class="rank-pill">#${entry.rank}</span></td><td>${rankMovementBadge(entry)}</td><td><div class="contributor-name"><a href="${entry.profile_url}">${escapeHtml(entry.login)}</a></div><small>${escapeHtml(entry.name ?? 'Public GitHub profile')}</small></td><td><strong class="metric">${(entry.observed_public_commits ?? 0).toLocaleString()}</strong></td><td><strong class="metric">${(entry.observed_public_pull_requests ?? 0).toLocaleString()}</strong></td><td>${(entry.public_repos ?? 0).toLocaleString()}</td><td>${entry.followers.toLocaleString()}</td><td>${escapeHtml(entry.location ?? 'Unknown')}<small>${escapeHtml(entry.location_confidence ?? 'unknown')}</small></td><td>${statusPill(entry.discovered_by_query ?? 'query', 'source')}</td></tr>`).join('')}</tbody></table></div><script>
return `<div class="table-wrap"><table id="contributors" aria-label="Top GitHub contributors in ${escapeHtml(snapshot.name)}"><thead><tr><th>Rank</th><th>Movement</th><th>Username</th><th><button data-sort="commits">Commits (1y)</button></th><th><button data-sort="prs">Public PRs (1y)</button></th><th><button data-sort="repos">Repos</button></th><th><button data-sort="followers">Followers</button></th><th>Location</th><th>Discovery</th></tr></thead><tbody>${rows.map((entry) => `<tr data-commits="${entry.observed_public_commits ?? 0}" data-prs="${entry.observed_public_pull_requests ?? 0}" data-repos="${entry.public_repos ?? 0}" data-followers="${entry.followers}"><td class="rank"><span class="rank-pill">#${entry.rank}</span></td><td>${rankMovementBadge(entry)}</td><td><div class="contributor-name"><a href="${entry.profile_url}" ${externalLinkAttrs}>${escapeHtml(entry.login)}</a></div><small>${escapeHtml(entry.name ?? 'Public GitHub profile')}</small></td><td><strong class="metric">${(entry.observed_public_commits ?? 0).toLocaleString()}</strong></td><td><strong class="metric">${(entry.observed_public_pull_requests ?? 0).toLocaleString()}</strong></td><td>${(entry.public_repos ?? 0).toLocaleString()}</td><td>${entry.followers.toLocaleString()}</td><td>${escapeHtml(entry.location ?? 'Unknown')}<small>${escapeHtml(entry.location_confidence ?? 'unknown')}</small></td><td>${statusPill(entry.discovered_by_query ?? 'query', 'source')}</td></tr>`).join('')}</tbody></table></div><script>
const table = document.querySelector('#contributors');
const tbody = table?.querySelector('tbody');
function sortRows(metric) {
Expand All @@ -158,7 +159,7 @@ function capped(value: number | undefined): string {
}

function projectTable(snapshot: RankingSnapshot<RankedProject>): string {
return `<div class="table-wrap"><table><thead><tr><th>Rank</th><th>Project</th><th>Merged PRs 30d</th><th>Commits 30d</th><th>Contributors</th><th>Releases 90d</th><th>Stars</th><th>Discovery</th></tr></thead><tbody>${snapshot.entries.map((entry) => `<tr><td class="rank"><span class="rank-pill">#${entry.rank}</span></td><td><a href="${entry.url}">${escapeHtml(entry.full_name)}</a><div class="project-meta">${statusPill(entry.primary_language ?? 'mixed', 'language')}</div></td><td><strong class="metric">${capped(entry.pull_requests_merged_30d ?? entry.pull_requests_merged_7d)}</strong><small>${capped(entry.pull_requests_merged_7d)} in 7d</small></td><td>${(entry.recent_commits_30d ?? 0).toLocaleString()}</td><td>${(entry.total_contributors_observed ?? entry.active_contributors_30d).toLocaleString()}</td><td>${(entry.releases_90d ?? 0).toLocaleString()}</td><td>${entry.stars.toLocaleString()}</td><td>${statusPill(entry.discovered_by_query ?? 'query', 'source')}</td></tr>`).join('')}</tbody></table></div>`;
return `<div class="table-wrap"><table><thead><tr><th>Rank</th><th>Project</th><th>Merged PRs 30d</th><th>Commits 30d</th><th>Contributors</th><th>Releases 90d</th><th>Stars</th><th>Discovery</th></tr></thead><tbody>${snapshot.entries.map((entry) => `<tr><td class="rank"><span class="rank-pill">#${entry.rank}</span></td><td><a href="${entry.url}" ${externalLinkAttrs}>${escapeHtml(entry.full_name)}</a><div class="project-meta">${statusPill(entry.primary_language ?? 'mixed', 'language')}</div></td><td><strong class="metric">${capped(entry.pull_requests_merged_30d ?? entry.pull_requests_merged_7d)}</strong><small>${capped(entry.pull_requests_merged_7d)} in 7d</small></td><td>${(entry.recent_commits_30d ?? 0).toLocaleString()}</td><td>${(entry.total_contributors_observed ?? entry.active_contributors_30d).toLocaleString()}</td><td>${(entry.releases_90d ?? 0).toLocaleString()}</td><td>${entry.stars.toLocaleString()}</td><td>${statusPill(entry.discovered_by_query ?? 'query', 'source')}</td></tr>`).join('')}</tbody></table></div>`;
}

function queryStats(snapshot: RankingSnapshot<unknown>): string {
Expand Down
Loading