import { formatBytes } from "@add-ideas/toolbox-helpers"; import { ArchivePolicyError } from "./errors"; export const ARCHIVE_LIMITS = Object.freeze({ maxSourceBytes: 512 * 1024 * 1024, maxEntries: 20_000, maxDisplayedEntries: 5_000, maxExpandedBytes: 512 * 1024 * 1024, maxEntryBytes: 256 * 1024 * 1024, maxCompressionRatio: 200, maxPathBytes: 4_096, maxPathSegments: 64, maxSegmentBytes: 255, maxPreviewTextBytes: 2 * 1024 * 1024, maxPreviewHexBytes: 128 * 1024, maxPreviewImageBytes: 24 * 1024 * 1024, maxPreviewImagePixels: 40_000_000, maxPreviewImageEdge: 32_768, maxCreateFiles: 5_000, maxCreateBytes: 512 * 1024 * 1024, maxPaxHeaderBytes: 1024 * 1024, maxGzipMembers: 256, maxPasswordBytes: 1_024, maxStructuralHeaderBytes: 16 * 1024 * 1024, maxArchiveHeaderBlocks: 40_000, }); export function assertFiniteSafeInteger(value: number, label: string): void { if (!Number.isSafeInteger(value) || value < 0) { throw new ArchivePolicyError( "INVALID_SIZE", `${label} is not a safe non-negative byte count.`, ); } } export function assertSourceSize(file: Blob): void { if (file.size > ARCHIVE_LIMITS.maxSourceBytes) { throw new ArchivePolicyError( "SOURCE_TOO_LARGE", `Archive exceeds the ${formatBytes(ARCHIVE_LIMITS.maxSourceBytes)} source limit.`, ); } } export { formatBytes }; export function throwIfAborted(signal?: AbortSignal): void { if (signal?.aborted) { throw signal.reason instanceof Error ? signal.reason : new DOMException("Operation cancelled.", "AbortError"); } }