Spaces:
Running
Running
Download hf.js from noodcon/Training-Process: direct link, hf CLI and curl.
- Browser
- Download file 3.88 kB
-
https://huggingface.co/spaces/noodcon/Training-Process/resolve/main/hf.js
- Command line
-
hf download hf://spaces/noodcon/Training-Process/hf.js
-
curl -L -o hf.js https://huggingface.co/spaces/noodcon/Training-Process/resolve/main/hf.js
3.88 kB
| import { CONFIG } from "./config.js"; | |
| const AUTH_URL = "https://huggingface.co/oauth/authorize"; | |
| const TOKEN_URL = "https://huggingface.co/oauth/token"; | |
| const redirectUri = () => location.origin + location.pathname; | |
| function b64url(bytes) { | |
| let s = ""; | |
| bytes.forEach((b) => (s += String.fromCharCode(b))); | |
| return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); | |
| } | |
| function randomString(len) { | |
| const a = new Uint8Array(len); | |
| crypto.getRandomValues(a); | |
| return b64url(a).slice(0, len); | |
| } | |
| export async function login() { | |
| if (!CONFIG.HF_OAUTH_CLIENT_ID) { | |
| alert("HF_OAUTH_CLIENT_ID is empty in config.js"); | |
| return; | |
| } | |
| const verifier = randomString(64); | |
| const state = randomString(24); | |
| const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)); | |
| const challenge = b64url(new Uint8Array(digest)); | |
| sessionStorage.setItem("hf_pkce", JSON.stringify({ verifier, state })); | |
| const params = new URLSearchParams({ | |
| client_id: CONFIG.HF_OAUTH_CLIENT_ID, | |
| redirect_uri: redirectUri(), | |
| response_type: "code", | |
| scope: "openid profile write-repos", | |
| state, | |
| code_challenge: challenge, | |
| code_challenge_method: "S256", | |
| }); | |
| location.href = `${AUTH_URL}?${params}`; | |
| } | |
| export function logout() { | |
| sessionStorage.removeItem("hf_token"); | |
| sessionStorage.removeItem("hf_pkce"); | |
| } | |
| // Call once on load. Returns the access token if this page was opened from the OAuth redirect. | |
| export async function handleRedirect() { | |
| const url = new URL(location.href); | |
| const code = url.searchParams.get("code"); | |
| if (!code) return null; | |
| const saved = JSON.parse(sessionStorage.getItem("hf_pkce") || "null"); | |
| history.replaceState({}, "", location.pathname); | |
| if (!saved || saved.state !== url.searchParams.get("state")) { | |
| throw new Error("OAuth state mismatch, please sign in again"); | |
| } | |
| const body = new URLSearchParams({ | |
| grant_type: "authorization_code", | |
| code, | |
| redirect_uri: redirectUri(), | |
| client_id: CONFIG.HF_OAUTH_CLIENT_ID, | |
| code_verifier: saved.verifier, | |
| }); | |
| const res = await fetch(TOKEN_URL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | |
| body, | |
| }); | |
| sessionStorage.removeItem("hf_pkce"); | |
| if (!res.ok) throw new Error(`token exchange failed (${res.status})`); | |
| const json = await res.json(); | |
| sessionStorage.setItem("hf_token", json.access_token); | |
| return json.access_token; | |
| } | |
| export async function whoami(token) { | |
| const res = await fetch("https://huggingface.co/api/whoami-v2", { | |
| headers: { Authorization: `Bearer ${token}` }, | |
| }); | |
| if (!res.ok) return null; | |
| return res.json(); | |
| } | |
| // Public read. The timestamp query defeats stale caches. | |
| export async function readData() { | |
| const url = `https://huggingface.co/datasets/${CONFIG.DATA_REPO}/resolve/main/${CONFIG.DATA_FILE}?t=${Date.now()}`; | |
| const res = await fetch(url, { cache: "no-store" }); | |
| if (!res.ok) throw new Error(`HTTP ${res.status}`); | |
| return res.json(); | |
| } | |
| // Admin write: commit the full JSON file to the dataset repo. | |
| export async function writeData(token, data) { | |
| const bytes = new TextEncoder().encode(JSON.stringify(data, null, 2)); | |
| let bin = ""; | |
| bytes.forEach((b) => (bin += String.fromCharCode(b))); | |
| const content = btoa(bin); | |
| const ndjson = [ | |
| JSON.stringify({ key: "header", value: { summary: `Update ${CONFIG.DATA_FILE} from dashboard`, description: "" } }), | |
| JSON.stringify({ key: "file", value: { path: CONFIG.DATA_FILE, encoding: "base64", content } }), | |
| ].join("\n"); | |
| const res = await fetch(`https://huggingface.co/api/datasets/${CONFIG.DATA_REPO}/commit/main`, { | |
| method: "POST", | |
| headers: { | |
| Authorization: `Bearer ${token}`, | |
| "Content-Type": "application/x-ndjson", | |
| }, | |
| body: ndjson, | |
| }); | |
| if (!res.ok) throw new Error(`commit failed (${res.status})`); | |
| } | |