whdemo / src /main.ts
Charlie
update files
b200338
raw
history blame
7.15 kB
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<WhoAmIResponse> {
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<OrganizationMember[]> {
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<void> {
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<void> {
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<void> => {
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);