import { ProviderInfo, ModelData } from "../types/heatmap"; export async function fetchOrganizationData(authors: string[]) { try { // Fetch data for all authors const authorsData = await Promise.all( authors.map(async (author) => { try { // Try organizations API first const orgResponse = await fetch(`https://huggingface.co/api/organizations/${author}/overview`); if (orgResponse.ok) { const data = await orgResponse.json(); return { author, fullName: data.fullname || author, avatarUrl: data.avatarUrl || null, isVerified: data.isVerified || false, isEnterprise: data.isEnterprise || false, numModels: data.numModels || 0, numSpaces: data.numSpaces || 0, numDatasets: data.numDatasets || 0, numFollowers: data.numFollowers || 0, numUsers: data.numUsers || 0, }; } // Fallback to users API if organization doesn't exist const userResponse = await fetch(`https://huggingface.co/api/users/${author}/overview`); if (userResponse.ok) { const data = await userResponse.json(); return { author, fullName: data.fullname || author, avatarUrl: data.avatarUrl || null, isVerified: false, isEnterprise: false, numModels: data.numModels || 0, numSpaces: data.numSpaces || 0, numDatasets: data.numDatasets || 0, numFollowers: data.numFollowers || 0, numUsers: 0, }; } throw new Error('Neither organization nor user API returned valid data'); } catch (error) { console.error(`Error fetching data for ${author}:`, error); return { author, fullName: author, avatarUrl: null, isVerified: false, isEnterprise: false, numModels: 0, numSpaces: 0, numDatasets: 0, numFollowers: 0, numUsers: 0, }; } }) ); // Use the primary author for main display name and avatar const primaryAuthor = authorsData[0]; // Aggregate stats from all authors const aggregatedStats = authorsData.reduce( (acc, authorData) => ({ numModels: acc.numModels + (authorData.numModels || 0), numSpaces: acc.numSpaces + (authorData.numSpaces || 0), numDatasets: acc.numDatasets + (authorData.numDatasets || 0), numFollowers: acc.numFollowers + (authorData.numFollowers || 0), numUsers: acc.numUsers + (authorData.numUsers || 0), }), { numModels: 0, numSpaces: 0, numDatasets: 0, numFollowers: 0, numUsers: 0 } ); return { fullName: primaryAuthor.fullName, avatarUrl: primaryAuthor.avatarUrl, isVerified: primaryAuthor.isVerified, isEnterprise: primaryAuthor.isEnterprise, authorsData, // Include all authors data for multi-logo display ...aggregatedStats, }; } catch (error) { console.error(`Error fetching organization data for authors:`, error); const primaryAuthor = authors[0]; return { fullName: primaryAuthor, avatarUrl: null, isVerified: false, isEnterprise: false, authorsData: [{ author: primaryAuthor, fullName: primaryAuthor, avatarUrl: null, isVerified: false, isEnterprise: false, numModels: 0, numSpaces: 0, numDatasets: 0, numFollowers: 0, numUsers: 0, }], numModels: 0, numSpaces: 0, numDatasets: 0, numFollowers: 0, numUsers: 0, }; } } export async function fetchAllProvidersData(providers: ProviderInfo[], modelDataMap?: Map): Promise { return Promise.all(providers.map(async (providerInfo) => { const orgData = await fetchOrganizationData(providerInfo.authors); // Calculate total downloads from model data let totalDownloads = 0; if (modelDataMap) { for (const author of providerInfo.authors) { const authorModels = modelDataMap.get(author) || []; totalDownloads += authorModels.reduce((sum, model) => sum + (model.downloads || 0), 0); } } return { ...providerInfo, ...orgData, totalDownloads, }; })); } export async function fetchAuthorData(author: string): Promise { const entityTypes = ["models", "datasets", "spaces"] as const; try { const allData = await Promise.all( entityTypes.map(async (type) => { const response = await fetch( `https://huggingface.co/api/${type}?author=${author}&sort=createdAt&direction=-1` ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data.map((item: any): ModelData => ({ createdAt: item.createdAt, id: item.id, downloads: item.downloads || 0, })); }) ); return allData.flat(); } catch (error) { console.error(`Error fetching data for author ${author}:`, error); return []; } } export async function fetchAllAuthorsData(authors: string[]): Promise<{ flatData: ModelData[], dataMap: Map }> { try { const allData = await Promise.all( authors.map(async (author) => ({ author, data: await fetchAuthorData(author) })) ); const flatData = allData.flatMap(item => item.data); const dataMap = new Map(allData.map(item => [item.author, item.data])); return { flatData, dataMap }; } catch (error) { console.error("Error fetching data for all authors:", error); return { flatData: [], dataMap: new Map() }; } }