Release Archive Tools 0.1.0

This commit is contained in:
2026-09-01 02:42:42 +02:00
commit a49ec6b17a
77 changed files with 11528 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
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,
});
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 function formatBytes(bytes: number): string {
if (!Number.isFinite(bytes)) return "unknown";
const units = ["B", "KiB", "MiB", "GiB"];
let value = Math.max(0, bytes);
let unit = 0;
while (value >= 1024 && unit < units.length - 1) {
value /= 1024;
unit += 1;
}
return `${value >= 10 || unit === 0 ? value.toFixed(0) : value.toFixed(1)} ${units[unit]}`;
}
export function throwIfAborted(signal?: AbortSignal): void {
if (signal?.aborted) {
throw signal.reason instanceof Error
? signal.reason
: new DOMException("Operation cancelled.", "AbortError");
}
}