| interface ParsedHuggingFaceUrl { |
| type: string; |
| username: string; |
| profileUrl: string; |
| resourceType: string | null; |
| resourceName: string | null; |
| fullUrl: string; |
| } |
|
|
| |
| |
| |
| |
| |
| export function parseHuggingFaceUrl(url: string): ParsedHuggingFaceUrl { |
| try { |
| |
| url = url.trim().replace(/\/$/, ''); |
|
|
| |
| let parsedUrl: URL; |
| if (url.startsWith('http://') || url.startsWith('https://')) { |
| parsedUrl = new URL(url); |
| } else if (url.startsWith('huggingface.co')) { |
| parsedUrl = new URL(`https://${url}`); |
| } else { |
| |
| return { |
| type: 'profile', |
| username: url, |
| profileUrl: `https://huggingface.co/${url}`, |
| resourceType: null, |
| resourceName: null, |
| fullUrl: `https://huggingface.co/${url}` |
| }; |
| } |
|
|
| |
| if (!parsedUrl.hostname.includes('huggingface.co')) { |
| throw new Error('Not a valid Hugging Face URL'); |
| } |
|
|
| const pathParts = parsedUrl.pathname.split('/').filter(part => part); |
|
|
| if (pathParts.length === 0) { |
| throw new Error('No username or organization found in URL'); |
| } |
|
|
| |
| let username = pathParts[0]; |
| let resourceType: string | null = null; |
| let resourceName: string | null = null; |
| let type = 'profile'; |
|
|
| |
| if (pathParts.length >= 2) { |
| |
| const secondPart = pathParts[1]; |
|
|
| |
| if (secondPart === 'models' || secondPart === 'datasets' || secondPart === 'spaces') { |
| |
| type = 'profile'; |
| resourceType = null; |
| resourceName = null; |
| } else { |
| |
| |
| |
| resourceName = secondPart; |
|
|
| |
| if (parsedUrl.hostname === 'huggingface.co') { |
| |
| if (pathParts.length >= 3) { |
| if (pathParts[2] === 'tree' || pathParts[2] === 'blob' || pathParts[2] === 'resolve') { |
| resourceType = 'model'; |
| } else if (pathParts[2] === 'discussions' || pathParts[2] === 'settings') { |
| resourceType = 'model'; |
| } |
| } else { |
| |
| resourceType = 'model'; |
| } |
| } |
| } |
| } else if (parsedUrl.hostname.includes('.hf.space')) { |
| |
| const subdomain = parsedUrl.hostname.split('.')[0]; |
| if (subdomain.includes('-')) { |
| const parts = subdomain.split('-'); |
| username = parts[0]; |
| resourceName = parts.slice(1).join('-'); |
| resourceType = 'space'; |
| } |
| } |
|
|
| |
| if (parsedUrl.pathname.includes('/datasets/')) { |
| const datasetPath = parsedUrl.pathname.split('/datasets/')[1]; |
| const datasetParts = datasetPath.split('/').filter(p => p); |
| if (datasetParts.length >= 2) { |
| username = datasetParts[0]; |
| resourceType = 'dataset'; |
| resourceName = datasetParts[1]; |
| } |
| } |
|
|
| |
| if (parsedUrl.pathname.includes('/spaces/')) { |
| const spacePath = parsedUrl.pathname.split('/spaces/')[1]; |
| const spaceParts = spacePath.split('/').filter(p => p); |
| if (spaceParts.length >= 2) { |
| username = spaceParts[0]; |
| resourceType = 'space'; |
| resourceName = spaceParts[1]; |
| } |
| } |
|
|
| return { |
| type, |
| username, |
| profileUrl: `https://huggingface.co/${username}`, |
| resourceType, |
| resourceName, |
| fullUrl: parsedUrl.href |
| }; |
| } catch (error: any) { |
| throw new Error(`Invalid Hugging Face URL: ${error.message}`); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| export function getAvatarUrl(username: string): string { |
| |
| return `https://huggingface.co/avatars/${username}.svg`; |
| } |