Files
hyperframes/packages/engine/src/utils/urlDownloader.ts
T
Vance Ingalls 20be2ea1c2 style: apply oxfmt baseline formatting across all source files (#25)
## Summary
- Run `oxfmt .` across the entire codebase to establish formatted baseline
- 299 files changed — mechanical formatting only, no logic changes
- Double quotes, semicolons, 2-space indent, trailing commas, 100 print width

Part 3/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm format:check` — all 426 files pass
- [x] `pnpm -r typecheck` — all packages pass
- [x] `pnpm build` — all packages build
- [x] All 348 tests pass
2026-03-23 17:15:14 -07:00

83 lines
2.5 KiB
TypeScript

import { createWriteStream, existsSync, mkdirSync } from "fs";
import { createHash } from "crypto";
import { join, extname } from "path";
import { Readable } from "stream";
import { finished } from "stream/promises";
const downloadPathCache = new Map<string, string>();
const inFlightDownloads = new Map<string, Promise<string>>();
function getFilenameFromUrl(url: string): string {
const hash = createHash("md5").update(url).digest("hex").slice(0, 12);
const urlObj = new URL(url);
const ext = extname(urlObj.pathname) || ".mp4";
return `download_${hash}${ext}`;
}
export async function downloadToTemp(
url: string,
destDir: string,
timeoutMs: number = 300000,
): Promise<string> {
const cachedPath = downloadPathCache.get(url);
if (cachedPath && existsSync(cachedPath)) {
return cachedPath;
}
const inFlight = inFlightDownloads.get(url);
if (inFlight) {
return inFlight;
}
if (!existsSync(destDir)) {
mkdirSync(destDir, { recursive: true });
}
const filename = getFilenameFromUrl(url);
const localPath = join(destDir, filename);
if (existsSync(localPath)) {
downloadPathCache.set(url, localPath);
return localPath;
}
const downloadPromise = (async () => {
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
if (!response.body) {
throw new Error("Response body is empty");
}
const fileStream = createWriteStream(localPath);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const readableStream = Readable.fromWeb(response.body as any);
await finished(readableStream.pipe(fileStream));
downloadPathCache.set(url, localPath);
return localPath;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
if (message.includes("aborted")) {
throw new Error(`[URLDownloader] Download timeout after ${timeoutMs / 1000}s: ${url}`);
}
throw new Error(`[URLDownloader] Download failed: ${message}`);
} finally {
inFlightDownloads.delete(url);
}
})();
inFlightDownloads.set(url, downloadPromise);
return downloadPromise;
}
export function isHttpUrl(path: string): boolean {
return path.startsWith("http://") || path.startsWith("https://");
}