UNPKG

@huggingface/hub

Version:

Utilities to interact with the Hugging Face hub

1,548 lines (1,514 loc) 109 kB
import { __privateAdd, __privateGet, __privateMethod, __privateSet, __publicField } from "./chunk-NZTU4WRF.mjs"; // src/consts.ts var HUB_URL = "https://huggingface.co"; // src/error.ts async function createApiError(response, opts) { var _a, _b; const error = new HubApiError(response.url, response.status, (_a = response.headers.get("X-Request-Id")) != null ? _a : opts == null ? void 0 : opts.requestId); error.message = `Api error with status ${error.statusCode}${(opts == null ? void 0 : opts.message) ? `. ${opts.message}` : ""}`; const trailer = [`URL: ${error.url}`, error.requestId ? `Request ID: ${error.requestId}` : void 0].filter(Boolean).join(". "); if ((_b = response.headers.get("Content-Type")) == null ? void 0 : _b.startsWith("application/json")) { const json = await response.json(); error.message = json.error || json.message || error.message; if (json.error_description) { error.message = error.message ? error.message + `: ${json.error_description}` : json.error_description; } error.data = json; } else { error.data = { message: await response.text() }; } error.message += `. ${trailer}`; throw error; } var HubApiError = class extends Error { constructor(url, statusCode, requestId, message) { super(message); __publicField(this, "statusCode"); __publicField(this, "url"); __publicField(this, "requestId"); __publicField(this, "data"); this.statusCode = statusCode; this.requestId = requestId; this.url = url; } }; var InvalidApiResponseFormatError = class extends Error { }; // src/utils/checkCredentials.ts function checkAccessToken(accessToken) { if (!accessToken.startsWith("hf_")) { throw new TypeError("Your access token must start with 'hf_'"); } } function checkCredentials(params) { var _a; if (params.accessToken) { checkAccessToken(params.accessToken); return params.accessToken; } if ((_a = params.credentials) == null ? void 0 : _a.accessToken) { checkAccessToken(params.credentials.accessToken); return params.credentials.accessToken; } } // src/utils/toRepoId.ts function toRepoId(repo) { if (typeof repo !== "string") { return repo; } if (repo.startsWith("model/") || repo.startsWith("models/")) { throw new TypeError( "A repo designation for a model should not start with 'models/', directly specify the model namespace / name" ); } if (repo.startsWith("space/")) { throw new TypeError("Spaces should start with 'spaces/', plural, not 'space/'"); } if (repo.startsWith("dataset/")) { throw new TypeError("Datasets should start with 'dataset/', plural, not 'dataset/'"); } const slashes = repo.split("/").length - 1; if (repo.startsWith("spaces/")) { if (slashes !== 2) { throw new TypeError("Space Id must include namespace and name of the space"); } return { type: "space", name: repo.slice("spaces/".length) }; } if (repo.startsWith("datasets/")) { if (slashes > 2) { throw new TypeError("Too many slashes in repo designation: " + repo); } return { type: "dataset", name: repo.slice("datasets/".length) }; } if (slashes > 1) { throw new TypeError("Too many slashes in repo designation: " + repo); } return { type: "model", name: repo }; } // src/lib/check-repo-access.ts async function checkRepoAccess(params) { const accessToken = params && checkCredentials(params); const repoId = toRepoId(params.repo); const response = await (params.fetch || fetch)(`${(params == null ? void 0 : params.hubUrl) || HUB_URL}/api/${repoId.type}s/${repoId.name}`, { headers: { ...accessToken ? { Authorization: `Bearer ${accessToken}` } : {} } }); if (!response.ok) { throw await createApiError(response); } } // src/utils/range.ts function range(n, b) { return b ? Array(b - n).fill(0).map((_, i) => n + i) : Array(n).fill(0).map((_, i) => i); } // src/utils/chunk.ts function chunk(arr, chunkSize) { if (isNaN(chunkSize) || chunkSize < 1) { throw new RangeError("Invalid chunk size: " + chunkSize); } if (!arr.length) { return []; } if (arr.length <= chunkSize) { return [arr]; } return range(Math.ceil(arr.length / chunkSize)).map((i) => { return arr.slice(i * chunkSize, (i + 1) * chunkSize); }); } // src/utils/promisesQueue.ts async function promisesQueue(factories, concurrency) { const results = []; const executing = /* @__PURE__ */ new Set(); let index = 0; for (const factory of factories) { const closureIndex = index++; const e = factory().then((r) => { results[closureIndex] = r; executing.delete(e); }); executing.add(e); if (executing.size >= concurrency) { await Promise.race(executing); } } await Promise.all(executing); return results; } // src/utils/promisesQueueStreaming.ts async function promisesQueueStreaming(factories, concurrency) { const executing = []; for await (const factory of factories) { const e = factory().then(() => { executing.splice(executing.indexOf(e), 1); }); executing.push(e); if (executing.length >= concurrency) { await Promise.race(executing); } } await Promise.all(executing); } // src/utils/eventToGenerator.ts async function* eventToGenerator(cb) { const promises = []; function addPromise() { let resolve2; let reject; const p = new Promise((res, rej) => { resolve2 = res; reject = rej; }); promises.push({ p, resolve: resolve2, reject }); } addPromise(); const callbackRes = Promise.resolve().then( () => cb( (y) => { var _a; addPromise(); (_a = promises.at(-2)) == null ? void 0 : _a.resolve({ done: false, value: y }); }, (r) => { var _a; addPromise(); (_a = promises.at(-2)) == null ? void 0 : _a.resolve({ done: true, value: r }); }, (err) => { var _a; return (_a = promises.shift()) == null ? void 0 : _a.reject(err); } ) ).catch((err) => { var _a; return (_a = promises.shift()) == null ? void 0 : _a.reject(err); }); while (1) { const p = promises[0]; if (!p) { throw new Error("Logic error in eventGenerator, promises should never be empty"); } const result = await p.p; promises.shift(); if (result.done) { await callbackRes; return result.value; } yield result.value; } throw new Error("Unreachable"); } // src/utils/hexFromBytes.ts function hexFromBytes(arr) { if (globalThis.Buffer) { return globalThis.Buffer.from(arr).toString("hex"); } else { const bin = []; arr.forEach((byte) => { bin.push(byte.toString(16).padStart(2, "0")); }); return bin.join(""); } } // src/utils/isBackend.ts var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"; var isWebWorker = typeof self === "object" && self.constructor && self.constructor.name === "DedicatedWorkerGlobalScope"; var isBackend = !isBrowser && !isWebWorker; // src/utils/isFrontend.ts var isFrontend = !isBackend; // src/utils/sha256.ts async function getWebWorkerCode() { const sha256Module = await import("./sha256-wrapper-GDBS2T5O.mjs"); return URL.createObjectURL(new Blob([sha256Module.createSHA256WorkerCode()])); } var pendingWorkers = []; var runningWorkers = /* @__PURE__ */ new Set(); var resolve; var waitPromise = new Promise((r) => { resolve = r; }); async function getWorker(poolSize) { { const worker2 = pendingWorkers.pop(); if (worker2) { runningWorkers.add(worker2); return worker2; } } if (!poolSize) { const worker2 = new Worker(await getWebWorkerCode()); runningWorkers.add(worker2); return worker2; } if (poolSize <= 0) { throw new TypeError("Invalid webworker pool size: " + poolSize); } while (runningWorkers.size >= poolSize) { await waitPromise; } const worker = new Worker(await getWebWorkerCode()); runningWorkers.add(worker); return worker; } async function freeWorker(worker, poolSize) { if (!poolSize) { return destroyWorker(worker); } runningWorkers.delete(worker); pendingWorkers.push(worker); const r = resolve; waitPromise = new Promise((r2) => { resolve = r2; }); r(); } function destroyWorker(worker) { runningWorkers.delete(worker); worker.terminate(); const r = resolve; waitPromise = new Promise((r2) => { resolve = r2; }); r(); } async function* sha256(buffer, opts) { var _a, _b; yield 0; const maxCryptoSize = typeof (opts == null ? void 0 : opts.useWebWorker) === "object" && (opts == null ? void 0 : opts.useWebWorker.minSize) !== void 0 ? opts.useWebWorker.minSize : 1e7; if (buffer.size < maxCryptoSize && ((_a = globalThis.crypto) == null ? void 0 : _a.subtle)) { const res = hexFromBytes( new Uint8Array( await globalThis.crypto.subtle.digest("SHA-256", buffer instanceof Blob ? await buffer.arrayBuffer() : buffer) ) ); yield 1; return res; } if (isFrontend) { if (opts == null ? void 0 : opts.useWebWorker) { try { const poolSize = typeof (opts == null ? void 0 : opts.useWebWorker) === "object" ? opts.useWebWorker.poolSize : void 0; const worker = await getWorker(poolSize); let messageHandler; let errorHandler; const cleanup = () => { worker.removeEventListener("message", messageHandler); worker.removeEventListener("error", errorHandler); }; return yield* eventToGenerator((yieldCallback, returnCallback, rejectCallback) => { var _a2, _b2; messageHandler = (event) => { var _a3; if (event.data.sha256) { cleanup(); freeWorker(worker, poolSize); returnCallback(event.data.sha256); } else if (event.data.progress) { yieldCallback(event.data.progress); try { (_a3 = opts.abortSignal) == null ? void 0 : _a3.throwIfAborted(); } catch (err) { cleanup(); destroyWorker(worker); rejectCallback(err); } } else { cleanup(); destroyWorker(worker); rejectCallback(event); } }; errorHandler = (event) => { cleanup(); destroyWorker(worker); rejectCallback(event.error); }; if (opts == null ? void 0 : opts.abortSignal) { try { (_a2 = opts.abortSignal) == null ? void 0 : _a2.throwIfAborted(); } catch (err) { cleanup(); destroyWorker(worker); rejectCallback((_b2 = opts.abortSignal.reason) != null ? _b2 : new DOMException("Aborted", "AbortError")); return; } const abortListener = () => { var _a3, _b3, _c; cleanup(); destroyWorker(worker); rejectCallback((_b3 = (_a3 = opts.abortSignal) == null ? void 0 : _a3.reason) != null ? _b3 : new DOMException("Aborted", "AbortError")); (_c = opts.abortSignal) == null ? void 0 : _c.removeEventListener("abort", abortListener); }; opts.abortSignal.addEventListener("abort", abortListener); } worker.addEventListener("message", messageHandler); worker.addEventListener("error", errorHandler); worker.postMessage({ file: buffer }); }); } catch (err) { console.warn("Failed to use web worker for sha256", err); } } if (!wasmModule) { wasmModule = await import("./sha256-wrapper-GDBS2T5O.mjs"); } const sha2562 = await wasmModule.createSHA256(); sha2562.init(); const reader = buffer.stream().getReader(); const total = buffer.size; let bytesDone = 0; while (true) { const { done, value } = await reader.read(); if (done) { break; } sha2562.update(value); bytesDone += value.length; yield bytesDone / total; (_b = opts == null ? void 0 : opts.abortSignal) == null ? void 0 : _b.throwIfAborted(); } return sha2562.digest("hex"); } if (!cryptoModule) { cryptoModule = await import("./sha256-node-TNZ2WHTI.mjs"); } return yield* cryptoModule.sha256Node(buffer, { abortSignal: opts == null ? void 0 : opts.abortSignal }); } var cryptoModule; var wasmModule; // src/utils/WebBlob.ts var WebBlob = class extends Blob { constructor(url, start, end, contentType, full, customFetch, accessToken) { super([]); __publicField(this, "url"); __publicField(this, "start"); __publicField(this, "end"); __publicField(this, "contentType"); __publicField(this, "full"); __publicField(this, "fetch"); __publicField(this, "accessToken"); this.url = url; this.start = start; this.end = end; this.contentType = contentType; this.full = full; this.fetch = customFetch; this.accessToken = accessToken; } static async create(url, opts) { var _a, _b; const customFetch = (_a = opts == null ? void 0 : opts.fetch) != null ? _a : fetch; const response = await customFetch(url, { method: "HEAD", ...(opts == null ? void 0 : opts.accessToken) && { headers: { Authorization: `Bearer ${opts.accessToken}` } } }); const size = Number(response.headers.get("content-length")); const contentType = response.headers.get("content-type") || ""; const supportRange = response.headers.get("accept-ranges") === "bytes"; if (!supportRange || size < ((_b = opts == null ? void 0 : opts.cacheBelow) != null ? _b : 1e6)) { return await (await customFetch(url)).blob(); } return new WebBlob(url, 0, size, contentType, true, customFetch, opts == null ? void 0 : opts.accessToken); } get size() { return this.end - this.start; } get type() { return this.contentType; } slice(start = 0, end = this.size) { if (start < 0 || end < 0) { new TypeError("Unsupported negative start/end on WebBlob.slice"); } const slice = new WebBlob( this.url, this.start + start, Math.min(this.start + end, this.end), this.contentType, start === 0 && end === this.size ? this.full : false, this.fetch, this.accessToken ); return slice; } async arrayBuffer() { const result = await this.fetchRange(); return result.arrayBuffer(); } async text() { const result = await this.fetchRange(); return result.text(); } stream() { const stream = new TransformStream(); this.fetchRange().then((response) => { var _a; return (_a = response.body) == null ? void 0 : _a.pipeThrough(stream); }).catch((error) => stream.writable.abort(error.message)); return stream.readable; } fetchRange() { const fetch2 = this.fetch; if (this.full) { return fetch2(this.url, { ...this.accessToken && { headers: { Authorization: `Bearer ${this.accessToken}` } } }).then((resp) => resp.ok ? resp : createApiError(resp)); } return fetch2(this.url, { headers: { Range: `bytes=${this.start}-${this.end - 1}`, ...this.accessToken && { Authorization: `Bearer ${this.accessToken}` } } }).then((resp) => resp.ok ? resp : createApiError(resp)); } }; // src/utils/base64FromBytes.ts function base64FromBytes(arr) { if (globalThis.Buffer) { return globalThis.Buffer.from(arr).toString("base64"); } else { const bin = []; arr.forEach((byte) => { bin.push(String.fromCharCode(byte)); }); return globalThis.btoa(bin.join("")); } } // src/utils/createBlobs.ts async function createBlobs(url, destPath, opts) { if (url.protocol === "http:" || url.protocol === "https:") { const blob = await WebBlob.create(url, { fetch: opts == null ? void 0 : opts.fetch, accessToken: opts == null ? void 0 : opts.accessToken }); return [{ path: destPath, blob }]; } if (isFrontend) { throw new TypeError(`Unsupported URL protocol "${url.protocol}"`); } if (url.protocol === "file:") { const { FileBlob } = await import("./FileBlob-7MRLQ6TG.mjs"); const { subPaths } = await import("./sub-paths-F6TP7MGR.mjs"); const paths = await subPaths(url, opts == null ? void 0 : opts.maxFolderDepth); if (paths.length === 1 && paths[0].relativePath === ".") { const blob = await FileBlob.create(url); return [{ path: destPath, blob }]; } return Promise.all( paths.map(async (path) => ({ path: `${destPath}/${path.relativePath}`.replace(/\/[.]$/, "").replaceAll("//", "/").replace(/^[.]?\//, ""), blob: await FileBlob.create(new URL(path.path)) })) ); } throw new TypeError(`Unsupported URL protocol "${url.protocol}"`); } // src/lib/commit.ts var CONCURRENT_SHAS = 5; var CONCURRENT_LFS_UPLOADS = 5; var MULTIPART_PARALLEL_UPLOAD = 5; function isFileOperation(op) { const ret = op.operation === "addOrUpdate"; if (ret && !(op.content instanceof Blob)) { throw new TypeError("Precondition failed: op.content should be a Blob"); } return ret; } async function* commitIter(params) { var _a, _b, _c, _d, _e, _f, _g; const accessToken = checkCredentials(params); const repoId = toRepoId(params.repo); yield { event: "phase", phase: "preuploading" }; const lfsShas = /* @__PURE__ */ new Map(); const abortController = new AbortController(); const abortSignal = abortController.signal; if (!abortSignal.throwIfAborted) { abortSignal.throwIfAborted = () => { if (abortSignal.aborted) { throw new DOMException("Aborted", "AbortError"); } }; } if (params.abortSignal) { params.abortSignal.addEventListener("abort", () => abortController.abort()); } try { const allOperations = (await Promise.all( params.operations.map(async (operation) => { if (operation.operation !== "addOrUpdate") { return operation; } if (!(operation.content instanceof URL)) { return { ...operation, content: operation.content }; } const lazyBlobs = await createBlobs(operation.content, operation.path, { fetch: params.fetch, maxFolderDepth: params.maxFolderDepth }); abortSignal == null ? void 0 : abortSignal.throwIfAborted(); return lazyBlobs.map((blob) => ({ ...operation, content: blob.blob, path: blob.path })); }) )).flat(1); const gitAttributes = (_a = allOperations.filter(isFileOperation).find((op) => op.path === ".gitattributes")) == null ? void 0 : _a.content; for (const operations of chunk(allOperations.filter(isFileOperation), 100)) { const payload = { gitAttributes: gitAttributes && await gitAttributes.text(), files: await Promise.all( operations.map(async (operation) => ({ path: operation.path, size: operation.content.size, sample: base64FromBytes(new Uint8Array(await operation.content.slice(0, 512).arrayBuffer())) })) ) }; abortSignal == null ? void 0 : abortSignal.throwIfAborted(); const res = await ((_b = params.fetch) != null ? _b : fetch)( `${(_c = params.hubUrl) != null ? _c : HUB_URL}/api/${repoId.type}s/${repoId.name}/preupload/${encodeURIComponent( (_d = params.branch) != null ? _d : "main" )}` + (params.isPullRequest ? "?create_pr=1" : ""), { method: "POST", headers: { ...accessToken && { Authorization: `Bearer ${accessToken}` }, "Content-Type": "application/json" }, body: JSON.stringify(payload), signal: abortSignal } ); if (!res.ok) { throw await createApiError(res); } const json = await res.json(); for (const file of json.files) { if (file.uploadMode === "lfs") { lfsShas.set(file.path, null); } } } yield { event: "phase", phase: "uploadingLargeFiles" }; for (const operations of chunk( allOperations.filter(isFileOperation).filter((op) => lfsShas.has(op.path)), 100 )) { const shas = yield* eventToGenerator((yieldCallback, returnCallback, rejectCallack) => { return promisesQueue( operations.map((op) => async () => { const iterator = sha256(op.content, { useWebWorker: params.useWebWorkers, abortSignal }); let res2; do { res2 = await iterator.next(); if (!res2.done) { yieldCallback({ event: "fileProgress", path: op.path, progress: res2.value, state: "hashing" }); } } while (!res2.done); const sha = res2.value; lfsShas.set(op.path, res2.value); return sha; }), CONCURRENT_SHAS ).then(returnCallback, rejectCallack); }); abortSignal == null ? void 0 : abortSignal.throwIfAborted(); const payload = { operation: "upload", // multipart is a custom protocol for HF transfers: ["basic", "multipart"], hash_algo: "sha_256", ...!params.isPullRequest && { ref: { name: (_e = params.branch) != null ? _e : "main" } }, objects: operations.map((op, i) => ({ oid: shas[i], size: op.content.size })) }; const res = await ((_f = params.fetch) != null ? _f : fetch)( `${(_g = params.hubUrl) != null ? _g : HUB_URL}/${repoId.type === "model" ? "" : repoId.type + "s/"}${repoId.name}.git/info/lfs/objects/batch`, { method: "POST", headers: { ...accessToken && { Authorization: `Bearer ${accessToken}` }, Accept: "application/vnd.git-lfs+json", "Content-Type": "application/vnd.git-lfs+json" }, body: JSON.stringify(payload), signal: abortSignal } ); if (!res.ok) { throw await createApiError(res); } const json = await res.json(); const batchRequestId = res.headers.get("X-Request-Id") || void 0; const shaToOperation = new Map(operations.map((op, i) => [shas[i], op])); yield* eventToGenerator((yieldCallback, returnCallback, rejectCallback) => { return promisesQueueStreaming( json.objects.map((obj) => async () => { var _a2, _b2, _c2; const op = shaToOperation.get(obj.oid); if (!op) { throw new InvalidApiResponseFormatError("Unrequested object ID in response"); } abortSignal == null ? void 0 : abortSignal.throwIfAborted(); if (obj.error) { const errorMessage = `Error while doing LFS batch call for ${operations[shas.indexOf(obj.oid)].path}: ${obj.error.message}${batchRequestId ? ` - Request ID: ${batchRequestId}` : ""}`; throw new HubApiError(res.url, obj.error.code, batchRequestId, errorMessage); } if (!((_a2 = obj.actions) == null ? void 0 : _a2.upload)) { yieldCallback({ event: "fileProgress", path: op.path, progress: 1, state: "uploading" }); return; } yieldCallback({ event: "fileProgress", path: op.path, progress: 0, state: "uploading" }); const content = op.content; const header = obj.actions.upload.header; if (header == null ? void 0 : header.chunk_size) { const chunkSize = parseInt(header.chunk_size); const completionUrl = obj.actions.upload.href; const parts = Object.keys(header).filter((key) => /^[0-9]+$/.test(key)); if (parts.length !== Math.ceil(content.size / chunkSize)) { throw new Error("Invalid server response to upload large LFS file, wrong number of parts"); } const completeReq = { oid: obj.oid, parts: parts.map((part) => ({ partNumber: +part, etag: "" })) }; const progressCallback = (progress) => yieldCallback({ event: "fileProgress", path: op.path, progress, state: "uploading" }); await promisesQueueStreaming( parts.map((part) => async () => { var _a3; abortSignal == null ? void 0 : abortSignal.throwIfAborted(); const index = parseInt(part) - 1; const slice = content.slice(index * chunkSize, (index + 1) * chunkSize); const res3 = await ((_a3 = params.fetch) != null ? _a3 : fetch)(header[part], { method: "PUT", /** Unfortunately, browsers don't support our inherited version of Blob in fetch calls */ body: slice instanceof WebBlob && isFrontend ? await slice.arrayBuffer() : slice, signal: abortSignal, ...{ progressHint: { path: op.path, part: index, numParts: parts.length, progressCallback } // eslint-disable-next-line @typescript-eslint/no-explicit-any } }); if (!res3.ok) { throw await createApiError(res3, { requestId: batchRequestId, message: `Error while uploading part ${part} of ${operations[shas.indexOf(obj.oid)].path} to LFS storage` }); } const eTag = res3.headers.get("ETag"); if (!eTag) { throw new Error("Cannot get ETag of part during multipart upload"); } completeReq.parts[Number(part) - 1].etag = eTag; }), MULTIPART_PARALLEL_UPLOAD ); abortSignal == null ? void 0 : abortSignal.throwIfAborted(); const res2 = await ((_b2 = params.fetch) != null ? _b2 : fetch)(completionUrl, { method: "POST", body: JSON.stringify(completeReq), headers: { Accept: "application/vnd.git-lfs+json", "Content-Type": "application/vnd.git-lfs+json" }, signal: abortSignal }); if (!res2.ok) { throw await createApiError(res2, { requestId: batchRequestId, message: `Error completing multipart upload of ${operations[shas.indexOf(obj.oid)].path} to LFS storage` }); } yieldCallback({ event: "fileProgress", path: op.path, progress: 1, state: "uploading" }); } else { const res2 = await ((_c2 = params.fetch) != null ? _c2 : fetch)(obj.actions.upload.href, { method: "PUT", headers: { ...batchRequestId ? { "X-Request-Id": batchRequestId } : void 0 }, /** Unfortunately, browsers don't support our inherited version of Blob in fetch calls */ body: content instanceof WebBlob && isFrontend ? await content.arrayBuffer() : content, signal: abortSignal, ...{ progressHint: { path: op.path, progressCallback: (progress) => yieldCallback({ event: "fileProgress", path: op.path, progress, state: "uploading" }) } // eslint-disable-next-line @typescript-eslint/no-explicit-any } }); if (!res2.ok) { throw await createApiError(res2, { requestId: batchRequestId, message: `Error while uploading ${operations[shas.indexOf(obj.oid)].path} to LFS storage` }); } yieldCallback({ event: "fileProgress", path: op.path, progress: 1, state: "uploading" }); } }), CONCURRENT_LFS_UPLOADS ).then(returnCallback, rejectCallback); }); } abortSignal == null ? void 0 : abortSignal.throwIfAborted(); yield { event: "phase", phase: "committing" }; return yield* eventToGenerator( async (yieldCallback, returnCallback, rejectCallback) => { var _a2, _b2, _c2; return ((_a2 = params.fetch) != null ? _a2 : fetch)( `${(_b2 = params.hubUrl) != null ? _b2 : HUB_URL}/api/${repoId.type}s/${repoId.name}/commit/${encodeURIComponent( (_c2 = params.branch) != null ? _c2 : "main" )}` + (params.isPullRequest ? "?create_pr=1" : ""), { method: "POST", headers: { ...accessToken && { Authorization: `Bearer ${accessToken}` }, "Content-Type": "application/x-ndjson" }, body: [ { key: "header", value: { summary: params.title, description: params.description, parentCommit: params.parentCommit } }, ...await Promise.all( allOperations.map((operation) => { if (isFileOperation(operation)) { const sha = lfsShas.get(operation.path); if (sha) { return { key: "lfsFile", value: { path: operation.path, algo: "sha256", size: operation.content.size, oid: sha } }; } } return convertOperationToNdJson(operation); }) ) ].map((x) => JSON.stringify(x)).join("\n"), signal: abortSignal, ...{ progressHint: { progressCallback: (progress) => { for (const op of allOperations) { if (isFileOperation(op) && !lfsShas.has(op.path)) { yieldCallback({ event: "fileProgress", path: op.path, progress, state: "uploading" }); } } } } // eslint-disable-next-line @typescript-eslint/no-explicit-any } } ).then(async (res) => { if (!res.ok) { throw await createApiError(res); } const json = await res.json(); returnCallback({ pullRequestUrl: json.pullRequestUrl, commit: { oid: json.commitOid, url: json.commitUrl }, hookOutput: json.hookOutput }); }).catch(rejectCallback); } ); } catch (err) { abortController.abort(); throw err; } } async function commit(params) { const iterator = commitIter(params); let res = await iterator.next(); while (!res.done) { res = await iterator.next(); } return res.value; } async function convertOperationToNdJson(operation) { switch (operation.operation) { case "addOrUpdate": { return { key: "file", value: { content: base64FromBytes(new Uint8Array(await operation.content.arrayBuffer())), path: operation.path, encoding: "base64" } }; } case "delete": { return { key: "deletedFile", value: { path: operation.path } }; } default: throw new TypeError("Unknown operation: " + operation.operation); } } // src/lib/count-commits.ts async function countCommits(params) { var _a, _b, _c, _d; const accessToken = checkCredentials(params); const repoId = toRepoId(params.repo); const url = `${(_a = params.hubUrl) != null ? _a : HUB_URL}/api/${repoId.type}s/${repoId.name}/commits/${(_b = params.revision) != null ? _b : "main"}?limit=1`; const res = await ((_c = params.fetch) != null ? _c : fetch)(url, { headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {} }); if (!res.ok) { throw await createApiError(res); } return parseInt((_d = res.headers.get("x-total-count")) != null ? _d : "0", 10); } // src/lib/create-repo.ts async function createRepo(params) { var _a, _b; const accessToken = checkCredentials(params); const repoId = toRepoId(params.repo); const [namespace, repoName] = repoId.name.split("/"); if (!namespace || !repoName) { throw new TypeError( `"${repoId.name}" is not a fully qualified repo name. It should be of the form "{namespace}/{repoName}".` ); } const res = await ((_a = params.fetch) != null ? _a : fetch)(`${(_b = params.hubUrl) != null ? _b : HUB_URL}/api/repos/create`, { method: "POST", body: JSON.stringify({ name: repoName, private: params.private, organization: namespace, license: params.license, ...repoId.type === "space" ? { type: "space", sdk: "static" } : { type: repoId.type }, files: params.files ? await Promise.all( params.files.map(async (file) => ({ encoding: "base64", path: file.path, content: base64FromBytes( new Uint8Array(file.content instanceof Blob ? await file.content.arrayBuffer() : file.content) ) })) ) : void 0 }), headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" } }); if (!res.ok) { throw await createApiError(res); } const output = await res.json(); return { repoUrl: output.url }; } // src/lib/create-branch.ts async function createBranch(params) { var _a, _b; const repoId = toRepoId(params.repo); const res = await ((_a = params.fetch) != null ? _a : fetch)( `${(_b = params.hubUrl) != null ? _b : HUB_URL}/api/${repoId.type}s/${repoId.name}/branch/${encodeURIComponent(params.branch)}`, { method: "POST", headers: { "Content-Type": "application/json", ...params.accessToken && { Authorization: `Bearer ${params.accessToken}` } }, body: JSON.stringify({ startingPoint: params.revision, ...params.empty && { emptyBranch: true }, overwrite: params.overwrite }) } ); if (!res.ok) { throw await createApiError(res); } } // src/lib/create-collection.ts async function createCollection(params) { var _a, _b; const accessToken = checkCredentials(params); const res = await ((_a = params.fetch) != null ? _a : fetch)(`${(_b = params.hubUrl) != null ? _b : HUB_URL}/api/collections`, { method: "POST", body: JSON.stringify(params.collection), headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" } }); if (!res.ok) { throw await createApiError(res); } const output = await res.json(); return { slug: output.slug }; } // src/utils/pick.ts function pick(o, props) { return Object.assign( {}, ...props.map((prop) => { if (o[prop] !== void 0) { return { [prop]: o[prop] }; } }) ); } // src/utils/parseLinkHeader.ts function parseLinkHeader(header) { const regex = /<(https?:[/][/][^>]+)>;\s+rel="([^"]+)"/g; return Object.fromEntries([...header.matchAll(regex)].map(([, url, rel]) => [rel, url])); } // src/lib/list-datasets.ts var DATASET_EXPAND_KEYS = [ "private", "downloads", "gated", "likes", "lastModified" ]; var DATASET_EXPANDABLE_KEYS = [ "author", "cardData", "citation", "createdAt", "disabled", "description", "downloads", "downloadsAllTime", "gated", "gitalyUid", "lastModified", "likes", "paperswithcode_id", "private", // "siblings", "sha", "tags" ]; async function* listDatasets(params) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const accessToken = params && checkCredentials(params); let totalToFetch = (_a = params == null ? void 0 : params.limit) != null ? _a : Infinity; const search = new URLSearchParams([ ...Object.entries({ limit: String(Math.min(totalToFetch, 500)), ...((_b = params == null ? void 0 : params.search) == null ? void 0 : _b.owner) ? { author: params.search.owner } : void 0, ...((_c = params == null ? void 0 : params.search) == null ? void 0 : _c.query) ? { search: params.search.query } : void 0 }), ...(_f = (_e = (_d = params == null ? void 0 : params.search) == null ? void 0 : _d.tags) == null ? void 0 : _e.map((tag) => ["filter", tag])) != null ? _f : [], ...DATASET_EXPAND_KEYS.map((val) => ["expand", val]), ...(_h = (_g = params == null ? void 0 : params.additionalFields) == null ? void 0 : _g.map((val) => ["expand", val])) != null ? _h : [] ]).toString(); let url = `${(params == null ? void 0 : params.hubUrl) || HUB_URL}/api/datasets` + (search ? "?" + search : ""); while (url) { const res = await ((_i = params == null ? void 0 : params.fetch) != null ? _i : fetch)(url, { headers: { accept: "application/json", ...accessToken ? { Authorization: `Bearer ${accessToken}` } : void 0 } }); if (!res.ok) { throw await createApiError(res); } const items = await res.json(); for (const item of items) { yield { ...(params == null ? void 0 : params.additionalFields) && pick(item, params.additionalFields), id: item._id, name: item.id, private: item.private, downloads: item.downloads, likes: item.likes, gated: item.gated, updatedAt: new Date(item.lastModified) }; totalToFetch--; if (totalToFetch <= 0) { return; } } const linkHeader = res.headers.get("Link"); url = linkHeader ? parseLinkHeader(linkHeader).next : void 0; } } // src/lib/dataset-info.ts async function datasetInfo(params) { var _a, _b, _c; const accessToken = params && checkCredentials(params); const search = new URLSearchParams([ ...DATASET_EXPAND_KEYS.map((val) => ["expand", val]), ...(_b = (_a = params == null ? void 0 : params.additionalFields) == null ? void 0 : _a.map((val) => ["expand", val])) != null ? _b : [] ]).toString(); const response = await (params.fetch || fetch)( `${(params == null ? void 0 : params.hubUrl) || HUB_URL}/api/datasets/${params.name}/revision/${encodeURIComponent( (_c = params.revision) != null ? _c : "HEAD" )}?${search.toString()}`, { headers: { ...accessToken ? { Authorization: `Bearer ${accessToken}` } : {}, Accepts: "application/json" } } ); if (!response.ok) { throw await createApiError(response); } const data = await response.json(); return { ...(params == null ? void 0 : params.additionalFields) && pick(data, params.additionalFields), id: data._id, name: data.id, private: data.private, downloads: data.downloads, likes: data.likes, gated: data.gated, updatedAt: new Date(data.lastModified) }; } // src/lib/delete-branch.ts async function deleteBranch(params) { var _a, _b; const repoId = toRepoId(params.repo); const res = await ((_a = params.fetch) != null ? _a : fetch)( `${(_b = params.hubUrl) != null ? _b : HUB_URL}/api/${repoId.type}s/${repoId.name}/branch/${encodeURIComponent(params.branch)}`, { method: "DELETE", headers: { ...params.accessToken && { Authorization: `Bearer ${params.accessToken}` } } } ); if (!res.ok) { throw await createApiError(res); } } // src/lib/delete-file.ts function deleteFile(params) { var _a; return commit({ ...params.accessToken ? { accessToken: params.accessToken } : { credentials: params.credentials }, repo: params.repo, operations: [ { operation: "delete", path: params.path } ], title: (_a = params.commitTitle) != null ? _a : `Delete ${params.path}`, description: params.commitDescription, hubUrl: params.hubUrl, branch: params.branch, isPullRequest: params.isPullRequest, parentCommit: params.parentCommit, fetch: params.fetch }); } // src/lib/delete-files.ts function deleteFiles(params) { var _a; return commit({ ...params.accessToken ? { accessToken: params.accessToken } : { credentials: params.credentials }, repo: params.repo, operations: params.paths.map((path) => ({ operation: "delete", path })), title: (_a = params.commitTitle) != null ? _a : `Deletes ${params.paths.length} files`, description: params.commitDescription, hubUrl: params.hubUrl, branch: params.branch, isPullRequest: params.isPullRequest, parentCommit: params.parentCommit, fetch: params.fetch }); } // src/lib/delete-repo.ts async function deleteRepo(params) { var _a, _b; const accessToken = checkCredentials(params); const repoId = toRepoId(params.repo); const [namespace, repoName] = repoId.name.split("/"); const res = await ((_a = params.fetch) != null ? _a : fetch)(`${(_b = params.hubUrl) != null ? _b : HUB_URL}/api/repos/delete`, { method: "DELETE", body: JSON.stringify({ name: repoName, organization: namespace, type: repoId.type }), headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" } }); if (!res.ok) { throw await createApiError(res); } } // src/lib/delete-collection.ts async function deleteCollection(params) { var _a, _b; const accessToken = checkCredentials(params); const res = await ((_a = params.fetch) != null ? _a : fetch)(`${(_b = params.hubUrl) != null ? _b : HUB_URL}/api/collections/${params.slug}`, { method: "DELETE", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" } }); if (!res.ok) { throw await createApiError(res); } } // src/vendor/lz4js/util.ts function readU64(b, n) { let x = 0; x |= b[n++] << 0; x |= b[n++] << 8; x |= b[n++] << 16; x |= b[n++] << 24; x |= b[n++] << 32; x |= b[n++] << 40; x |= b[n++] << 48; x |= b[n++] << 56; return x; } function readU32(b, n) { let x = 0; x |= b[n++] << 0; x |= b[n++] << 8; x |= b[n++] << 16; x |= b[n++] << 24; return x; } // src/vendor/lz4js/index.ts var minMatch = 4; var hashSize = 1 << 16; var mlBits = 4; var mlMask = (1 << mlBits) - 1; var runBits = 4; var runMask = (1 << runBits) - 1; var blockBuf = makeBuffer(5 << 20); var hashTable = makeHashTable(); var magicNum = 407708164; var fdContentChksum = 4; var fdContentSize = 8; var fdBlockChksum = 16; var fdVersion = 64; var fdVersionMask = 192; var bsUncompressed = 2147483648; var bsShift = 4; var bsMask = 7; var bsMap = { 4: 65536, 5: 262144, 6: 1048576, 7: 4194304 }; function makeHashTable() { try { return new Uint32Array(hashSize); } catch (error) { const hashTable2 = new Array(hashSize); for (let i = 0; i < hashSize; i++) { hashTable2[i] = 0; } return hashTable2; } } function makeBuffer(size) { return new Uint8Array(size); } function sliceArray(array, start, end) { return array.slice(start, end); } function decompressBound(src) { let sIndex = 0; if (readU32(src, sIndex) !== magicNum) { throw new Error("invalid magic number"); } sIndex += 4; const descriptor = src[sIndex++]; if ((descriptor & fdVersionMask) !== fdVersion) { throw new Error("incompatible descriptor version " + (descriptor & fdVersionMask)); } const useBlockSum = (descriptor & fdBlockChksum) !== 0; const useContentSize = (descriptor & fdContentSize) !== 0; const bsIdx = src[sIndex++] >> bsShift & bsMask; if (bsMap[bsIdx] === void 0) { throw new Error("invalid block size " + bsIdx); } const maxBlockSize = bsMap[bsIdx]; if (useContentSize) { return readU64(src, sIndex); } sIndex++; let maxSize = 0; while (true) { let blockSize = readU32(src, sIndex); sIndex += 4; if (blockSize & bsUncompressed) { blockSize &= ~bsUncompressed; maxSize += blockSize; } else if (blockSize > 0) { maxSize += maxBlockSize; } if (blockSize === 0) { return maxSize; } if (useBlockSum) { sIndex += 4; } sIndex += blockSize; } } function decompressBlock(src, dst, sIndex, sLength, dIndex) { let mLength, mOffset, sEnd, n, i; const hasCopyWithin = dst.copyWithin !== void 0 && dst.fill !== void 0; sEnd = sIndex + sLength; while (sIndex < sEnd) { const token = src[sIndex++]; let literalCount = token >> 4; if (literalCount > 0) { if (literalCount === 15) { while (true) { literalCount += src[sIndex]; if (src[sIndex++] !== 255) { break; } } } for (n = sIndex + literalCount; sIndex < n; ) { dst[dIndex++] = src[sIndex++]; } } if (sIndex >= sEnd) { break; } mLength = token & 15; mOffset = src[sIndex++] | src[sIndex++] << 8; if (mLength === 15) { while (true) { mLength += src[sIndex]; if (src[sIndex++] !== 255) { break; } } } mLength += minMatch; if (hasCopyWithin && mOffset === 1) { dst.fill(dst[dIndex - 1] | 0, dIndex, dIndex + mLength); dIndex += mLength; } else if (hasCopyWithin && mOffset > mLength && mLength > 31) { dst.copyWithin(dIndex, dIndex - mOffset, dIndex - mOffset + mLength); dIndex += mLength; } else { for (i = dIndex - mOffset, n = i + mLength; i < n; ) { dst[dIndex++] = dst[i++] | 0; } } } return dIndex; } function decompressFrame(src, dst) { let useBlockSum, useContentSum, useContentSize, descriptor; let sIndex = 0; let dIndex = 0; if (readU32(src, sIndex) !== magicNum) { throw new Error("invalid magic number"); } sIndex += 4; descriptor = src[sIndex++]; if ((descriptor & fdVersionMask) !== fdVersion) { throw new Error("incompatible descriptor version"); } useBlockSum = (descriptor & fdBlockChksum) !== 0; useContentSum = (descriptor & fdContentChksum) !== 0; useContentSize = (descriptor & fdContentSize) !== 0; const bsIdx = src[sIndex++] >> bsShift & bsMask; if (bsMap[bsIdx] === void 0) { throw new Error("invalid block size"); } if (useContentSize) { sIndex += 8; } sIndex++; while (true) { var compSize; compSize = readU32(src, sIndex); sIndex += 4; if (compSize === 0) { break; } if (useBlockSum) { sIndex += 4; } if ((compSize & bsUncompressed) !== 0) { compSize &= ~bsUncompressed; for (let j = 0; j < compSize; j++) { dst[dIndex++] = src[sIndex++]; } } else { dIndex = decompressBlock(src, dst, sIndex, compSize, dIndex); sIndex += compSize; } } if (useContentSum) { sIndex += 4; } return dIndex; } function decompress(src, maxSize) { let dst, size; if (maxSize === void 0) { maxSize = decompressBound(src); } dst = makeBuffer(maxSize); size = decompressFrame(src, dst); if (size !== maxSize) { dst = sliceArray(dst, 0, size); } return dst; } // src/utils/RangeList.ts var RangeList = class { constructor() { __publicField(this, "ranges", []); } /** * Add a range to the list. If it overlaps with existing ranges, * it will split them and increment reference counts accordingly. */ add(start, end) { if (end <= start) { throw new TypeError("End must be greater than start"); } const overlappingRanges = []; for (let i = 0; i < this.ranges.length; i++) { const range2 = this.ranges[i]; if (start < range2.end && end > range2.start) { overlappingRanges.push({ index: i, range: range2 }); } if (range2.data !== null) { throw new Error("Overlapping range already has data"); } } if (overlappingRanges.length === 0) { this.ranges.push({ start, end, refCount: 1, data: null }); this.ranges.sort((a, b) => a.start - b.start); return; } const newRanges = []; let currentPos = start; for (let i = 0; i < overlappingRanges.length; i++) { const { range: range2 } = overlappingRanges[i]; if (currentPos < range2.start) { newRanges.push({ start: currentPos, end: range2.start, refCount: 1, data: null }); } else if (range2.start < currentPos) { newRanges.push({ start: range2.start, end: currentPos, refCount: range2.refCount, data: null }); } newRanges.push({ start: Math.max(currentPos, range2.start), end: Math.min(end, range2.end), refCount: range2.refCount + 1, data: null }); if (ra