import type { SmartArchive } from './classes.smartarchive.js'; import * as plugins from './plugins.js'; export interface IAnalyzedResult { fileType: plugins.fileType.FileTypeResult; isArchive: boolean; resultStream: plugins.smartstream.SmartDuplex; decompressionStream: plugins.stream.Transform | plugins.stream.Duplex | plugins.tarStream.Extract; } export class ArchiveAnalyzer { smartArchiveRef: SmartArchive; constructor(smartArchiveRefArg: SmartArchive) { this.smartArchiveRef = smartArchiveRefArg; } private async mimeTypeIsArchive(mimeType: string): Promise { const archiveMimeTypes: Set = new Set([ 'application/zip', 'application/x-rar-compressed', 'application/x-tar', 'application/gzip', 'application/x-7z-compressed', 'application/x-bzip2', // Add other archive mime types here ]); return archiveMimeTypes.has(mimeType); } private async getDecompressionStream( mimeTypeArg: plugins.fileType.FileTypeResult['mime'] ): Promise { switch (mimeTypeArg) { case 'application/gzip': return this.smartArchiveRef.gzipTools.getDecompressionStream(); case 'application/zip': return this.smartArchiveRef.zipTools.getDecompressionStream(); case 'application/x-bzip2': return await this.smartArchiveRef.bzip2Tools.getDecompressionStream(); // replace with your own bzip2 decompression stream case 'application/x-tar': return this.smartArchiveRef.tarTools.getDecompressionStream(); // replace with your own tar decompression stream default: // Handle unsupported formats or no decompression needed return plugins.smartstream.createPassThrough(); } } public getAnalyzedStream() { let firstRun = true; const resultStream = plugins.smartstream.createPassThrough(); const analyzerstream = new plugins.smartstream.SmartDuplex({ readableObjectMode: true, writeFunction: async (chunkArg: Buffer, streamtools) => { if (firstRun) { firstRun = false; const fileType = await plugins.fileType.fileTypeFromBuffer(chunkArg); const decompressionStream = await this.getDecompressionStream(fileType?.mime as any); /** * analyzed stream emits once with this object */ const result: IAnalyzedResult = { fileType, isArchive: await this.mimeTypeIsArchive(fileType?.mime), resultStream, decompressionStream, }; await streamtools.push(result); } await resultStream.backpressuredPush(chunkArg); return null; }, finalFunction: async (tools) => { resultStream.push(null); return null; } }); return analyzerstream; } }