import * as plugins from './plugins.js'; import type { IArchiveEntry, ITarEntry, TCompressionLevel } from './interfaces.js'; import { GzipTools } from './classes.gziptools.js'; /** * TAR archive creation and extraction utilities using modern-tar (browser-compatible) */ export class TarTools { /** * Pack files into a TAR buffer */ public async packFiles(files: IArchiveEntry[]): Promise { const entries: ITarEntry[] = []; for (const file of files) { let data: Uint8Array; if (typeof file.content === 'string') { data = new TextEncoder().encode(file.content); } else if (file.content instanceof Uint8Array) { data = file.content; } else if (file.content instanceof plugins.smartfile.SmartFile) { data = new Uint8Array(file.content.contents); } else if (file.content instanceof plugins.smartfile.StreamFile) { const buffer = await file.content.getContentAsBuffer(); data = new Uint8Array(buffer); } else { throw new Error('Unsupported content type for TAR entry'); } entries.push({ header: { name: file.archivePath, size: data.length, type: 'file', mode: file.mode, mtime: file.mtime, }, body: data, }); } return plugins.modernTar.packTar(entries); } /** * Extract a TAR buffer to an array of entries */ public async extractTar(data: Uint8Array): Promise> { const entries = await plugins.modernTar.unpackTar(data); const result: Array<{ path: string; content: Uint8Array; isDirectory: boolean }> = []; for (const entry of entries) { const isDirectory = entry.header.type === 'directory' || entry.header.name.endsWith('/'); // modern-tar uses 'data' property, not 'body' const content = entry.data ?? new Uint8Array(0); result.push({ path: entry.header.name, content, isDirectory, }); } return result; } /** * Pack files into a TAR.GZ buffer */ public async packFilesToTarGz( files: IArchiveEntry[], compressionLevel?: TCompressionLevel ): Promise { const tarBuffer = await this.packFiles(files); const gzipTools = new GzipTools(); return gzipTools.compress(tarBuffer, compressionLevel); } /** * Extract a TAR.GZ buffer to an array of entries */ public async extractTarGz(data: Uint8Array): Promise> { const gzipTools = new GzipTools(); const tarBuffer = await gzipTools.decompress(data); return this.extractTar(tarBuffer); } }