import { tokenManager } from "./oauth"; interface OrganizationInfo { type: string; id: string; name: string; role: string; } interface WhoAmIResponse { type: string; id: string; name: string; email?: string; fullname?: string; avatarUrl?: string; orgs: OrganizationInfo[]; } interface OrganizationMember { user: string; role: string; } async function getOrganizationInfo( accessToken: string ): Promise { const response = await fetch("https://huggingface.co/api/whoami-v2", { headers: { Authorization: `Bearer ${accessToken}`, }, }); if (!response.ok) { throw new Error( `Failed to fetch organization info: ${response.statusText}` ); } return response.json(); } async function getOrganizationMembers( accessToken: string, organization: string ): Promise { const response = await fetch( `https://huggingface.co/api/organizations/${organization}/members`, { headers: { Authorization: `Bearer ${accessToken}`, }, } ); if (!response.ok) { throw new Error( `Failed to fetch organization members: ${response.statusText}` ); } return response.json(); } async function createResourceGroup( accessToken: string, organization: string, name: string, members: OrganizationMember[] ): Promise { const response = await fetch( `https://huggingface.co/api/organizations/${organization}/resource-groups`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}`, }, body: JSON.stringify({ name: name, description: `Resource group for repository ${name}`, users: members.map((member) => ({ user: member.user, role: "admin", })), }), } ); if (!response.ok) { throw new Error(`Failed to create resource group: ${response.statusText}`); } } async function createRepository( accessToken: string, name: string, organization?: string, resourceGroupName?: string ): Promise { const response = await fetch("https://huggingface.co/api/repos/create", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}`, }, body: JSON.stringify({ type: "model", name: name, organization: organization, private: false, }), }); if (!response.ok) { throw new Error(`Failed to create repository: ${response.statusText}`); } // If organization and resource group name are provided, create a resource group if (organization && resourceGroupName) { const members = await getOrganizationMembers(accessToken, organization); await createResourceGroup( accessToken, organization, resourceGroupName, members ); } } const init = async (): Promise => { if (tokenManager.isAuthenticated()) { showAuthenticatedUI(); } else { showUnauthenticatedUI(); } }; const showAuthenticatedUI = async () => { const accessToken = tokenManager.getAccessToken(); if (!accessToken) { throw new Error("Access token not found"); } // Hide token form const tokenForm = document.getElementById("token-form"); if (tokenForm) { tokenForm.style.display = "none"; } // Show repo form and signout button const repoForm = document.getElementById("repo-form"); const signoutButton = document.getElementById("signout"); if (repoForm) { repoForm.style.removeProperty("display"); } if (signoutButton) { signoutButton.style.removeProperty("display"); signoutButton.onclick = () => tokenManager.logout(); } // Add create repo functionality const createRepoButton = document.getElementById("create-repo"); const repoNameInput = document.getElementById( "repo-name" ) as HTMLInputElement; const resourceGroupInput = document.getElementById( "resource-group-name" ) as HTMLInputElement; const resourceGroupContainer = document.getElementById( "resource-group-container" ); if (createRepoButton && repoNameInput) { createRepoButton.onclick = async () => { const repoName = repoNameInput.value.trim(); const orgSelect = document.getElementById( "org-select" ) as HTMLSelectElement; if (repoName) { try { const selectedOrg = orgSelect?.value || undefined; const resourceGroupName = selectedOrg ? resourceGroupInput?.value.trim() : undefined; console.log({ selectedOrg, resourceGroupName }); await createRepository( accessToken, repoName, selectedOrg, resourceGroupName ); repoNameInput.value = ""; // Clear input after success if (resourceGroupInput) { resourceGroupInput.value = ""; // Clear resource group input } alert("Repository and resource group created successfully!"); } catch (error) { console.error("Failed to create repository:", error); alert("Failed to create repository. Please try again."); } } }; } // Handle org select change to show/hide resource group input const orgSelect = document.getElementById("org-select") as HTMLSelectElement; if (orgSelect && resourceGroupContainer) { orgSelect.onchange = () => { if (orgSelect.value) { resourceGroupContainer.style.removeProperty("display"); } else { resourceGroupContainer.style.display = "none"; } }; } // Get organization info and populate org select try { const orgInfo = await getOrganizationInfo(accessToken); // Populate org select if (orgSelect && orgInfo.orgs) { orgInfo.orgs.forEach((org) => { const option = document.createElement("option"); option.value = org.name; option.textContent = org.name; orgSelect.appendChild(option); }); } // Display user info const preElement = document.querySelector("pre"); if (preElement) { preElement.textContent = JSON.stringify(orgInfo, null, 2); } } catch (error) { console.error("Failed to fetch organization info:", error); } }; const showUnauthenticatedUI = () => { // Show token form const tokenForm = document.getElementById("token-form"); const tokenInput = document.getElementById("token-input") as HTMLInputElement; const tokenSubmit = document.getElementById("token-submit"); if (tokenForm && tokenInput && tokenSubmit) { tokenForm.style.removeProperty("display"); tokenSubmit.onclick = () => { const token = tokenInput.value.trim(); if (token) { tokenManager.setToken(token); showAuthenticatedUI(); } }; } // Hide other UI elements const repoForm = document.getElementById("repo-form"); const signoutButton = document.getElementById("signout"); if (repoForm) { repoForm.style.display = "none"; } if (signoutButton) { signoutButton.style.display = "none"; } }; init().catch(console.error);