mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-05 10:14:30 +00:00
* feat(media-use): core infrastructure — manifest, cache, adopt, probe Foundation for media-use — the media resolution layer for HyperFrames. - manifest.mjs: JSONL read/write/find for .media/manifest.jsonl - index-gen.mjs: regenerate agent-readable index.md from manifest - cache.mjs: content-addressed global cache at ~/.media/ (SHA-256, sentinel) - freeze.mjs: download URL or copy local file to .media/ - probe.mjs: extract duration/dimensions via ffprobe - adopt.mjs: scan assets/ directory, register existing files with metadata - 19 passing tests (manifest round-trip, cache, promote, index generation) * fix(media-use): oxfmt formatting + cap freeze download size Format adopt/cache/probe/manifest.test (CI oxfmt --check gate). Cap freezeUrl downloads at 256MB so a hostile/runaway URL can't fill the disk (addresses CodeQL #670: network data written to file). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
27 lines
1.1 KiB
JavaScript
27 lines
1.1 KiB
JavaScript
import { writeFileSync, copyFileSync, mkdirSync } from "node:fs";
|
|
import { dirname } from "node:path";
|
|
|
|
// ponytail: bound the download so a hostile/runaway URL can't fill the disk.
|
|
// 256MB covers any real media asset; raise if 4K video sources ever exceed it.
|
|
const MAX_FREEZE_BYTES = 256 * 1024 * 1024;
|
|
|
|
export async function freezeUrl(url, destPath) {
|
|
const res = await fetch(url);
|
|
if (!res.ok) throw new Error(`freeze failed: HTTP ${res.status} for ${String(url).slice(0, 80)}`);
|
|
const bytes = Buffer.from(await res.arrayBuffer());
|
|
if (bytes.length === 0)
|
|
throw new Error(`freeze failed: empty response for ${String(url).slice(0, 80)}`);
|
|
if (bytes.length > MAX_FREEZE_BYTES)
|
|
throw new Error(
|
|
`freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BYTES} cap for ${String(url).slice(0, 80)}`,
|
|
);
|
|
mkdirSync(dirname(destPath), { recursive: true });
|
|
writeFileSync(destPath, bytes);
|
|
return bytes.length;
|
|
}
|
|
|
|
export function freezeLocalFile(srcPath, destPath) {
|
|
mkdirSync(dirname(destPath), { recursive: true });
|
|
copyFileSync(srcPath, destPath);
|
|
}
|