/** * Unified ArchiveFile class supporting both ZIP and TAR formats. * * The class provides a common API for creating, reading, and modifying archives, * with format-specific features available based on the `format` option. * * @example Create a ZIP archive (default) * ```ts * const archive = new ArchiveFile(); * archive.addFile("./readme.md"); * archive.addDirectory("./src"); * await archive.writeToFile("./output.zip"); * ``` * * @example Create a TAR archive * ```ts * const archive = new ArchiveFile({ format: "tar" }); * archive.addFile("./readme.md"); * archive.addDirectory("./src"); * await archive.writeToFile("./output.tar"); * ``` * * @example Create a gzipped TAR archive * ```ts * const archive = new ArchiveFile({ format: "tar", gzip: true }); * archive.addFile("./readme.md"); * await archive.writeToFile("./output.tar.gz"); * ``` * * @module */ import { type ArchiveSink } from "../io/archive-sink.js"; import type { ArchiveFormat } from "../shared/types.js"; import type { AddFileOptions, AddDirectoryOptions, AddGlobOptions, AddTarFileOptions, AddTarDirectoryOptions, AddTarGlobOptions, ExtractToOptions, ArchiveFileOptions, ArchiveFileOptionsZip, ArchiveFileOptionsTar, OpenArchiveOptionsZip, OpenArchiveOptionsTar, WriteArchiveOptions, ArchiveEntryInfo, ZipEntryInfo, ArchiveStreamOptions, ArchiveStreamOperation } from "./types.js"; /** * Unified archive file class supporting both ZIP and TAR formats. * * This class provides file system integration for creating and reading archives. * * @template F - Archive format ("zip" or "tar") */ export declare class ArchiveFile { private readonly _format; private _zipOptions; private _zipPendingEntries; private _zipData; private _zipParser; private _zipSourcePath; private _zipPassword; private _zipEditView; private _zipAbortController; private _zipBytesWritten; private readonly _tarArchive; private readonly _tarReader; private readonly _tarPendingEntries; private readonly _tarOptions; /** * Create a new ZIP archive file. */ constructor(options?: ArchiveFileOptionsZip); /** * Create a new TAR archive file. */ constructor(options: ArchiveFileOptionsTar); /** * Create a new archive file with the specified format. */ constructor(options?: ArchiveFileOptions); /** * Get the ZIP creation options for createZip/createZipSync. */ private _getCreateZipOptions; /** Get ZIP options (throws if not ZIP format) */ private get _zip_options(); /** Get ZIP pending entries array */ private get _zip_pending(); /** Get ZIP parser (may be null) */ private get _zip_parser(); /** Get ZIP password */ private get _zip_password(); /** Get ZIP edit view (may be null) */ private get _zip_editView(); /** Get TAR pending entries array */ private get _tar_pending(); /** Get TAR archive */ private get _tar_archive(); /** Get TAR options */ private get _tar_options(); /** Set a ZIP state field */ private _setZipState; /** Set the TAR reader for read mode */ private _setTarReader; /** Find pending ZIP entry index by normalized path, or -1 if missing. */ private _findZipPendingIndex; /** * Initialize a ZIP archive from existing ZIP data. */ private _initZipFromData; /** * Initialize a TAR archive from raw data. */ private _initTarFromData; /** * Shared factory logic for creating an archive from data. */ private static _fromData; /** * Create an ArchiveFile from a file on disk. */ static fromFile(filePath: string, options?: OpenArchiveOptionsZip): Promise>; static fromFile(filePath: string, options: OpenArchiveOptionsTar): Promise>; /** * Create an ArchiveFile from a file on disk (sync). */ static fromFileSync(filePath: string, options?: OpenArchiveOptionsZip): ArchiveFile<"zip">; static fromFileSync(filePath: string, options: OpenArchiveOptionsTar): ArchiveFile<"tar">; /** * Create an ArchiveFile from a buffer. */ static fromBuffer(data: Uint8Array, options?: OpenArchiveOptionsZip): ArchiveFile<"zip">; static fromBuffer(data: Uint8Array, options: OpenArchiveOptionsTar): ArchiveFile<"tar">; /** * Get the archive format. */ get format(): F; /** * Get the number of entries in the archive. * * - For ZIP: Returns the exact count from parser (read mode) or pending entries (write mode). * - For TAR in read mode: Returns 0 (TAR is stream-based, use getEntryCountAsync() for actual count). * - For TAR in write mode: Returns the pending entry count. */ get entryCount(): number; /** * Get the exact entry count asynchronously. * * This method is useful for TAR archives in read mode, where entries must be * iterated to count them (due to the stream-based nature of TAR). * * For ZIP archives, this returns the same value as `entryCount`. * * @returns The number of entries in the archive */ getEntryCountAsync(): Promise; /** * Get the source file path if the archive was loaded from disk. */ get sourcePath(): string | null; /** * Check if the current operation has been aborted (ZIP only). */ get aborted(): boolean; /** * Add a file from disk to the archive. */ addFile(filePath: string, options?: F extends "tar" ? AddTarFileOptions : AddFileOptions): this; /** * Add a buffer to the archive. */ addBuffer(data: Uint8Array, name: string, options?: F extends "tar" ? AddTarFileOptions : AddFileOptions): this; /** * Add text content to the archive. */ addText(content: string, name: string, options?: F extends "tar" ? AddTarFileOptions : AddFileOptions): this; /** * Add a stream to the archive. */ appendStream(stream: AsyncIterable | ReadableStream, name: string, options?: F extends "tar" ? AddTarFileOptions : AddFileOptions): this; /** * Add a symbolic link to the archive. */ symlink(name: string, target: string, mode?: number): this; /** * Add a directory recursively to the archive. */ addDirectory(dirPath: string, options?: F extends "tar" ? AddTarDirectoryOptions : AddDirectoryOptions): this; /** * Add files matching a glob pattern to the archive. */ addGlob(pattern: string, options?: F extends "tar" ? AddTarGlobOptions : AddGlobOptions): this; /** * Check if an entry exists (ZIP only). */ has(entryPath: string): F extends "zip" ? boolean : never; /** * Delete an entry (ZIP only). */ delete(entryPath: string): F extends "zip" ? boolean : never; /** * Set/replace an entry (ZIP only). */ set(entryPath: string, data: Uint8Array | string, options?: AddFileOptions): F extends "zip" ? this : never; /** * Rename an entry (ZIP only). */ rename(oldPath: string, newPath: string): F extends "zip" ? boolean : never; /** * Set a password for encryption (ZIP only). */ setPassword(password: string | Uint8Array | undefined): F extends "zip" ? this : never; /** * Build the archive and return as a buffer. */ toBuffer(): Promise; /** * Build the archive and return as a buffer (sync). */ toBufferSync(): Uint8Array; /** * Alias for toBuffer(). */ bytes(): Promise; /** * Alias for toBufferSync(). */ bytesSync(): Uint8Array; /** * Write the archive to a file. */ writeToFile(filePath: string, options?: WriteArchiveOptions): Promise; /** * Write the archive to a file (sync). */ writeToFileSync(filePath: string, options?: WriteArchiveOptions): void; /** * Generate archive as an async iterable stream. * * This is the most memory-efficient way to create archives, as it streams * data directly from sources to output without buffering the entire archive. * * @example * ```ts * const archive = new ArchiveFile(); * archive.addFile("large-file.bin"); * archive.addDirectory("./data"); * * // Recommended: pipeTo() handles backpressure end-to-end. * await archive.pipeTo(createWriteStream("output.zip")); * * // Or stream manually — REMEMBER to honor backpressure on the sink: * import { once } from "node:events"; * const writeStream = createWriteStream("output.zip"); * for await (const chunk of archive.stream()) { * if (!writeStream.write(chunk)) { * await once(writeStream, "drain"); * } * } * writeStream.end(); * ``` */ stream(options?: ArchiveStreamOptions): AsyncIterable; /** * Get streaming operation with abort/progress control. * * @example * ```ts * const op = archive.operation({ * onProgress: (p) => console.log(`${p.entriesDone}/${p.entriesTotal}`), * }); * * // Read chunks * for await (const chunk of op.iterable) { * process(chunk); * } * * // Or abort if needed * op.abort(); * ``` */ operation(options?: ArchiveStreamOptions): ArchiveStreamOperation; /** * Pipe archive stream to a sink (WritableStream or Node.js Writable). * * @example * ```ts * // Node.js Writable * await archive.pipeTo(createWriteStream("output.zip")); * * // Web WritableStream * await archive.pipeTo(writableStream); * ``` */ pipeTo(sink: ArchiveSink, options?: ArchiveStreamOptions): Promise; /** * Stream archive directly to a file. * * This is the most efficient way to write large archives to disk, * as it avoids buffering the entire archive in memory. * * @example * ```ts * const archive = new ArchiveFile(); * archive.addDirectory("./huge-folder"); * await archive.streamToFile("output.zip", { * onProgress: (p) => console.log(`${p.bytesOut} bytes written`), * }); * ``` */ streamToFile(filePath: string, options?: ArchiveStreamOptions & WriteArchiveOptions): Promise; /** * Get all entry info objects. */ getEntries(): Promise; /** * Get all entry info objects (sync). */ getEntriesSync(): ArchiveEntryInfo[]; /** * Get entry names (file paths). */ getEntryNames(): string[]; /** * Get a specific entry's info. */ getEntry(entryPath: string): ZipEntryInfo | null; /** * Read an entry as bytes. */ readEntry(entryPath: string, password?: string | Uint8Array): Promise; /** * Read an entry as bytes (sync). */ readEntrySync(entryPath: string, password?: string | Uint8Array): Uint8Array | null; /** * Read an entry as text. */ readAsText(entryPath: string, encoding?: string): Promise; /** * Read an entry as text (sync). */ readAsTextSync(entryPath: string, encoding?: string): string | null; /** * Extract the archive to a directory. */ extractTo(targetDir: string, options?: ExtractToOptions): Promise; /** * Extract the archive to a directory (sync). */ extractToSync(targetDir: string, options?: ExtractToOptions): void; /** * Extract a single entry to a file (ZIP only). */ extractEntryTo(entryPath: string, targetPath: string, options?: ExtractToOptions): Promise; /** * Synchronously extract a single entry to a file (ZIP only). */ extractEntryToSync(entryPath: string, targetPath: string, options?: ExtractToOptions): boolean; /** * Check if the archive contains encrypted entries (ZIP only). */ hasEncryptedEntries(): boolean; /** * Get the archive comment (ZIP only). */ getZipComment(): string; /** * Set or update the archive comment (ZIP only). */ addZipComment(comment: string): this; /** * Get the comment for a specific entry (ZIP only). */ getZipEntryComment(entryPath: string): string | null; /** * Check if there are pending modifications. */ hasPendingChanges(): boolean; /** * Abort the current operation (ZIP only). */ abort(): this; /** * Get the number of bytes written so far (ZIP only). */ pointer(): number; /** * Get the AbortSignal for the current operation (ZIP only). */ getAbortSignal(): AbortSignal | undefined; private _buildZip; private _buildZipSync; /** * Synchronous version of pending entry processing. * Avoids the async overhead when all operations are sync. */ private _processZipPendingEntrySync; private _extractZip; private _extractZipSync; private _buildTar; private _buildTarSync; private _processTarEntry; private _processTarEntrySync; /** * Add a file entry from directory/glob traversal to the TAR archive (sync version). */ private _addTarFileEntrySync; /** * Build ZIP archive as a stream using the true streaming ZipArchive API. */ private _buildZipStream; /** * Build TAR archive as a stream using the true streaming TarArchive API. */ private _buildTarStream; private _extractTar; }