MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / downloadToFile

Function downloadToFile

packages/cli/src/cloud/download.ts:39–98  ·  view source on GitHub ↗
(
  url: string,
  destPath: string,
  options: DownloadOptions = {},
)

Source from the content-addressed store, hash-verified

37 */
38// fallow-ignore-next-line complexity
39export async function downloadToFile(
40 url: string,
41 destPath: string,
42 options: DownloadOptions = {},
43): Promise<DownloadResult> {
44 const fetchImpl = options.fetchImpl ?? fetch;
45 const res = await fetchImpl(url, { signal: options.signal });
46 if (!res.ok) {
47 throw new Error(`Failed to download ${url}: HTTP ${res.status} ${res.statusText}`);
48 }
49 if (!res.body) {
50 throw new Error(`Failed to download ${url}: empty response body`);
51 }
52
53 mkdirSync(dirname(destPath), { recursive: true });
54
55 const totalHeader = res.headers.get("content-length");
56 const total = totalHeader ? Number.parseInt(totalHeader, 10) : undefined;
57 const totalOpt = total !== undefined && Number.isFinite(total) ? total : undefined;
58
59 const file = createWriteStream(destPath);
60 let bytes = 0;
61 let errored = false;
62 try {
63 for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {
64 if (options.signal?.aborted) {
65 throw options.signal.reason instanceof Error
66 ? options.signal.reason
67 : new Error("Download aborted");
68 }
69 bytes += chunk.byteLength;
70 options.onProgress?.(bytes, totalOpt);
71 if (!file.write(chunk)) {
72 await waitForDrain(file, options.signal);
73 }
74 }
75 if (totalOpt !== undefined && bytes !== totalOpt) {
76 throw new Error(
77 `Truncated download: got ${bytes} bytes, expected ${totalOpt} (content-length). ` +
78 `The presigned URL may have expired mid-transfer — refetch via \`hyperframes cloud get\`.`,
79 );
80 }
81 } catch (err) {
82 errored = true;
83 throw err;
84 } finally {
85 await closeFile(file);
86 if (errored) {
87 // Don't let a partial file pose as the final artifact. Best-
88 // effort unlink — if it fails (already gone, permission), we
89 // re-throw the original error.
90 try {
91 unlinkSync(destPath);
92 } catch {
93 /* swallow */
94 }
95 }
96 }

Callers 2

download.test.tsFile · 0.85
streamVideoFunction · 0.85

Calls 4

waitForDrainFunction · 0.85
closeFileFunction · 0.85
getMethod · 0.80
writeMethod · 0.65

Tested by

no test coverage detected