BREAKING CHANGE(SmartArchive): Refactor public API: rename factory/extraction methods, introduce typed interfaces and improved compression tools
This commit is contained in:
@@ -1,24 +1,41 @@
|
||||
import type { SmartArchive } from './classes.smartarchive.js';
|
||||
import type { TSupportedMime } from './interfaces.js';
|
||||
import * as plugins from './plugins.js';
|
||||
|
||||
/**
|
||||
* Type for decompression streams
|
||||
*/
|
||||
export type TDecompressionStream =
|
||||
| plugins.stream.Transform
|
||||
| plugins.stream.Duplex
|
||||
| plugins.tarStream.Extract;
|
||||
|
||||
/**
|
||||
* Result of archive analysis
|
||||
*/
|
||||
export interface IAnalyzedResult {
|
||||
fileType: plugins.fileType.FileTypeResult;
|
||||
fileType: plugins.fileType.FileTypeResult | undefined;
|
||||
isArchive: boolean;
|
||||
resultStream: plugins.smartstream.SmartDuplex;
|
||||
decompressionStream:
|
||||
| plugins.stream.Transform
|
||||
| plugins.stream.Duplex
|
||||
| plugins.tarStream.Extract;
|
||||
resultStream: plugins.smartstream.SmartDuplex<Buffer, Buffer>;
|
||||
decompressionStream: TDecompressionStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes archive streams to detect format and provide decompression
|
||||
*/
|
||||
export class ArchiveAnalyzer {
|
||||
smartArchiveRef: SmartArchive;
|
||||
private smartArchiveRef: SmartArchive;
|
||||
|
||||
constructor(smartArchiveRefArg: SmartArchive) {
|
||||
this.smartArchiveRef = smartArchiveRefArg;
|
||||
}
|
||||
|
||||
private async mimeTypeIsArchive(mimeType: string): Promise<boolean> {
|
||||
/**
|
||||
* Check if a MIME type represents an archive format
|
||||
*/
|
||||
private async mimeTypeIsArchive(mimeType: string | undefined): Promise<boolean> {
|
||||
if (!mimeType) return false;
|
||||
|
||||
const archiveMimeTypes: Set<string> = new Set([
|
||||
'application/zip',
|
||||
'application/x-rar-compressed',
|
||||
@@ -26,50 +43,46 @@ export class ArchiveAnalyzer {
|
||||
'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<
|
||||
plugins.stream.Transform | plugins.stream.Duplex | plugins.tarStream.Extract
|
||||
> {
|
||||
/**
|
||||
* Get the appropriate decompression stream for a MIME type
|
||||
*/
|
||||
private async getDecompressionStream(mimeTypeArg: TSupportedMime): Promise<TDecompressionStream> {
|
||||
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
|
||||
return this.smartArchiveRef.bzip2Tools.getDecompressionStream();
|
||||
case 'application/x-tar':
|
||||
return this.smartArchiveRef.tarTools.getDecompressionStream(); // replace with your own tar decompression stream
|
||||
return this.smartArchiveRef.tarTools.getDecompressionStream();
|
||||
default:
|
||||
// Handle unsupported formats or no decompression needed
|
||||
return plugins.smartstream.createPassThrough();
|
||||
}
|
||||
}
|
||||
|
||||
public getAnalyzedStream() {
|
||||
/**
|
||||
* Create an analyzed stream that detects archive type and provides decompression
|
||||
* Emits a single IAnalyzedResult object
|
||||
*/
|
||||
public getAnalyzedStream(): plugins.smartstream.SmartDuplex<Buffer, IAnalyzedResult> {
|
||||
let firstRun = true;
|
||||
const resultStream = plugins.smartstream.createPassThrough();
|
||||
const analyzerstream = new plugins.smartstream.SmartDuplex<
|
||||
Buffer,
|
||||
IAnalyzedResult
|
||||
>({
|
||||
|
||||
const analyzerstream = new plugins.smartstream.SmartDuplex<Buffer, IAnalyzedResult>({
|
||||
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 decompressionStream = await this.getDecompressionStream(fileType?.mime as TSupportedMime);
|
||||
|
||||
const result: IAnalyzedResult = {
|
||||
fileType,
|
||||
isArchive: await this.mimeTypeIsArchive(fileType?.mime),
|
||||
@@ -81,11 +94,12 @@ export class ArchiveAnalyzer {
|
||||
await resultStream.backpressuredPush(chunkArg);
|
||||
return null;
|
||||
},
|
||||
finalFunction: async (tools) => {
|
||||
finalFunction: async () => {
|
||||
resultStream.push(null);
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
return analyzerstream;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user