@push.rocks/smartarchive 5.0.1 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/classes.archiveanalyzer.d.ts +1 -1
- package/dist_ts/classes.archiveanalyzer.js +34 -4
- package/dist_ts/classes.smartarchive.d.ts +4 -4
- package/dist_ts/classes.smartarchive.js +46 -32
- package/dist_ts/classes.tartools.d.ts +9 -33
- package/dist_ts/classes.tartools.js +18 -153
- package/dist_ts/index.d.ts +2 -6
- package/dist_ts/index.js +7 -11
- package/dist_ts/paths.js +1 -1
- package/dist_ts/plugins.d.ts +2 -9
- package/dist_ts/plugins.js +6 -13
- package/npmextra.json +13 -7
- package/package.json +23 -14
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.archiveanalyzer.ts +33 -5
- package/ts/classes.smartarchive.ts +51 -35
- package/ts/classes.tartools.ts +20 -177
- package/ts/index.ts +7 -11
- package/ts/plugins.ts +5 -17
- package/{ts → ts_shared}/bzip2/bititerator.ts +1 -1
- package/{ts → ts_shared}/bzip2/bzip2.ts +2 -2
- package/{ts → ts_shared}/bzip2/index.ts +6 -6
- package/ts_shared/classes.bzip2tools.ts +14 -0
- package/ts_shared/classes.gziptools.ts +42 -0
- package/ts_shared/classes.tartools.ts +89 -0
- package/ts_shared/classes.ziptools.ts +107 -0
- package/ts_shared/index.ts +17 -0
- package/{ts → ts_shared}/interfaces.ts +18 -7
- package/ts_shared/plugins.ts +22 -0
- package/ts_web/00_commitinfo_data.ts +8 -0
- package/ts_web/index.ts +4 -0
- package/ts_web/plugins.ts +3 -0
- package/dist_ts/bzip2/bititerator.d.ts +0 -6
- package/dist_ts/bzip2/bititerator.js +0 -50
- package/dist_ts/bzip2/bzip2.d.ts +0 -29
- package/dist_ts/bzip2/bzip2.js +0 -398
- package/dist_ts/bzip2/index.d.ts +0 -5
- package/dist_ts/bzip2/index.js +0 -92
- package/dist_ts/classes.bzip2tools.d.ts +0 -7
- package/dist_ts/classes.bzip2tools.js +0 -11
- package/dist_ts/classes.gziptools.d.ts +0 -53
- package/dist_ts/classes.gziptools.js +0 -116
- package/dist_ts/classes.ziptools.d.ts +0 -56
- package/dist_ts/classes.ziptools.js +0 -171
- package/dist_ts/errors.d.ts +0 -44
- package/dist_ts/errors.js +0 -62
- package/dist_ts/interfaces.d.ts +0 -119
- package/dist_ts/interfaces.js +0 -2
- package/dist_ts/smartarchive.classes.smartarchive.d.ts +0 -34
- package/dist_ts/smartarchive.classes.smartarchive.js +0 -116
- package/dist_ts/smartarchive.paths.d.ts +0 -2
- package/dist_ts/smartarchive.paths.js +0 -4
- package/dist_ts/smartarchive.plugins.d.ts +0 -14
- package/dist_ts/smartarchive.plugins.js +0 -19
- package/ts/classes.bzip2tools.ts +0 -16
- package/ts/classes.gziptools.ts +0 -138
- package/ts/classes.ziptools.ts +0 -196
- /package/{ts → ts_shared}/errors.ts +0 -0
package/dist_ts/interfaces.d.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import type * as stream from 'node:stream';
|
|
2
|
-
import type { SmartFile, StreamFile } from '@push.rocks/smartfile';
|
|
3
|
-
/**
|
|
4
|
-
* Supported archive formats
|
|
5
|
-
*/
|
|
6
|
-
export type TArchiveFormat = 'tar' | 'tar.gz' | 'tgz' | 'zip' | 'gz' | 'bz2';
|
|
7
|
-
/**
|
|
8
|
-
* Compression level (0 = no compression, 9 = maximum compression)
|
|
9
|
-
*/
|
|
10
|
-
export type TCompressionLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
11
|
-
/**
|
|
12
|
-
* Supported MIME types for archive detection
|
|
13
|
-
*/
|
|
14
|
-
export type TSupportedMime = 'application/gzip' | 'application/zip' | 'application/x-bzip2' | 'application/x-tar' | undefined;
|
|
15
|
-
/**
|
|
16
|
-
* Entry to add to an archive during creation
|
|
17
|
-
*/
|
|
18
|
-
export interface IArchiveEntry {
|
|
19
|
-
/** Path within the archive */
|
|
20
|
-
archivePath: string;
|
|
21
|
-
/** Content: string, Buffer, Readable stream, SmartFile, or StreamFile */
|
|
22
|
-
content: string | Buffer | stream.Readable | SmartFile | StreamFile;
|
|
23
|
-
/** Optional size hint for streams (improves performance) */
|
|
24
|
-
size?: number;
|
|
25
|
-
/** Optional file mode/permissions */
|
|
26
|
-
mode?: number;
|
|
27
|
-
/** Optional modification time */
|
|
28
|
-
mtime?: Date;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Options for creating archives
|
|
32
|
-
*/
|
|
33
|
-
export interface IArchiveCreationOptions {
|
|
34
|
-
/** Target archive format */
|
|
35
|
-
format: TArchiveFormat;
|
|
36
|
-
/** Compression level (0-9, default depends on format) */
|
|
37
|
-
compressionLevel?: TCompressionLevel;
|
|
38
|
-
/** Base path to strip from file paths in archive */
|
|
39
|
-
basePath?: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Options for extracting archives
|
|
43
|
-
*/
|
|
44
|
-
export interface IArchiveExtractionOptions {
|
|
45
|
-
/** Target directory for extraction */
|
|
46
|
-
targetDir: string;
|
|
47
|
-
/** Optional filename for single-file archives (gz, bz2) */
|
|
48
|
-
fileName?: string;
|
|
49
|
-
/** Number of leading path components to strip */
|
|
50
|
-
stripComponents?: number;
|
|
51
|
-
/** Filter function to select which entries to extract */
|
|
52
|
-
filter?: (entry: IArchiveEntryInfo) => boolean;
|
|
53
|
-
/** Whether to overwrite existing files */
|
|
54
|
-
overwrite?: boolean;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Information about an archive entry
|
|
58
|
-
*/
|
|
59
|
-
export interface IArchiveEntryInfo {
|
|
60
|
-
/** Path of the entry within the archive */
|
|
61
|
-
path: string;
|
|
62
|
-
/** Size in bytes */
|
|
63
|
-
size: number;
|
|
64
|
-
/** Whether this entry is a directory */
|
|
65
|
-
isDirectory: boolean;
|
|
66
|
-
/** Whether this entry is a file */
|
|
67
|
-
isFile: boolean;
|
|
68
|
-
/** Modification time */
|
|
69
|
-
mtime?: Date;
|
|
70
|
-
/** File mode/permissions */
|
|
71
|
-
mode?: number;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Result of archive analysis
|
|
75
|
-
*/
|
|
76
|
-
export interface IArchiveInfo {
|
|
77
|
-
/** Detected archive format */
|
|
78
|
-
format: TArchiveFormat | null;
|
|
79
|
-
/** Whether the archive is compressed */
|
|
80
|
-
isCompressed: boolean;
|
|
81
|
-
/** Whether this is a recognized archive format */
|
|
82
|
-
isArchive: boolean;
|
|
83
|
-
/** List of entries (if available without full extraction) */
|
|
84
|
-
entries?: IArchiveEntryInfo[];
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Options for adding a file to a TAR pack stream
|
|
88
|
-
*/
|
|
89
|
-
export interface IAddFileOptions {
|
|
90
|
-
/** Filename within the archive */
|
|
91
|
-
fileName?: string;
|
|
92
|
-
/** File content */
|
|
93
|
-
content?: string | Buffer | stream.Readable | SmartFile | StreamFile;
|
|
94
|
-
/** Size in bytes (required for streams) */
|
|
95
|
-
byteLength?: number;
|
|
96
|
-
/** Path to file on disk (alternative to content) */
|
|
97
|
-
filePath?: string;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Bit reader interface for BZIP2 decompression
|
|
101
|
-
*/
|
|
102
|
-
export interface IBitReader {
|
|
103
|
-
(n: number | null): number | void;
|
|
104
|
-
bytesRead: number;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Huffman group for BZIP2 decompression
|
|
108
|
-
*/
|
|
109
|
-
export interface IHuffmanGroup {
|
|
110
|
-
permute: Int32Array;
|
|
111
|
-
limit: Int32Array;
|
|
112
|
-
base: Int32Array;
|
|
113
|
-
minLen: number;
|
|
114
|
-
maxLen: number;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Entry filter predicate for fluent API
|
|
118
|
-
*/
|
|
119
|
-
export type TEntryFilter = (entry: IArchiveEntryInfo) => boolean;
|
package/dist_ts/interfaces.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import * as plugins from './smartarchive.plugins.js';
|
|
3
|
-
export declare class SmartArchive {
|
|
4
|
-
constructor();
|
|
5
|
-
/**
|
|
6
|
-
* extracts an archive from a given url
|
|
7
|
-
*/
|
|
8
|
-
extractArchiveFromUrlToFs(urlArg: string, targetDir: string): Promise<void>;
|
|
9
|
-
/**
|
|
10
|
-
* extracts an archive from a given filePath on disk
|
|
11
|
-
* @param filePathArg
|
|
12
|
-
* @param targetDirArg
|
|
13
|
-
*/
|
|
14
|
-
extractArchiveFromFilePathToFs(filePathArg: string, targetDirArg: string): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* extracts to Observable
|
|
17
|
-
* where the Observable is emitting smartfiles
|
|
18
|
-
*/
|
|
19
|
-
extractArchiveFromBufferToObservable(bufferArg: Buffer): Promise<plugins.smartrx.rxjs.ReplaySubject<plugins.smartfile.Smartfile>>;
|
|
20
|
-
extractArchiveWithIntakeAndReplaySubject(): {
|
|
21
|
-
intake: plugins.smartstream.StreamIntake<Buffer>;
|
|
22
|
-
replaySubject: plugins.smartrx.rxjs.ReplaySubject<plugins.smartfile.Smartfile>;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* extracts to Observable
|
|
26
|
-
*/
|
|
27
|
-
extractArchiveFromUrlToObservable(urlArg: string): Promise<plugins.smartrx.rxjs.ReplaySubject<plugins.smartfile.Smartfile>>;
|
|
28
|
-
extractArchiveFromUrlToStream(): Promise<void>;
|
|
29
|
-
extractArchiveFromFilePathToStream(): Promise<void>;
|
|
30
|
-
extractArchiveFromStreamToStream(): Promise<void>;
|
|
31
|
-
packFromStreamToStream(): Promise<void>;
|
|
32
|
-
packFromDirPathToStream(): Promise<void>;
|
|
33
|
-
packFromDirPathToFs(): Promise<void>;
|
|
34
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartarchive.plugins.js';
|
|
2
|
-
import * as paths from './smartarchive.paths.js';
|
|
3
|
-
export class SmartArchive {
|
|
4
|
-
constructor() { }
|
|
5
|
-
/**
|
|
6
|
-
* extracts an archive from a given url
|
|
7
|
-
*/
|
|
8
|
-
async extractArchiveFromUrlToFs(urlArg, targetDir) {
|
|
9
|
-
const parsedPath = plugins.path.parse(urlArg);
|
|
10
|
-
const uniqueFileName = plugins.smartunique.uni() + parsedPath.ext;
|
|
11
|
-
plugins.smartfile.fs.ensureDir(paths.nogitDir); // TODO: totally remove caching needs
|
|
12
|
-
const downloadPath = plugins.path.join(paths.nogitDir, uniqueFileName);
|
|
13
|
-
const downloadedArchive = (await plugins.smartrequest.getBinary(urlArg)).body;
|
|
14
|
-
await plugins.smartfile.memory.toFs(downloadedArchive, downloadPath);
|
|
15
|
-
await this.extractArchiveFromFilePathToFs(downloadPath, targetDir);
|
|
16
|
-
await plugins.smartfile.fs.remove(downloadPath);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* extracts an archive from a given filePath on disk
|
|
20
|
-
* @param filePathArg
|
|
21
|
-
* @param targetDirArg
|
|
22
|
-
*/
|
|
23
|
-
async extractArchiveFromFilePathToFs(filePathArg, targetDirArg) {
|
|
24
|
-
console.log(`extracting ${filePathArg}`);
|
|
25
|
-
const done = plugins.smartpromise.defer();
|
|
26
|
-
filePathArg = plugins.smartpath.transform.makeAbsolute(filePathArg);
|
|
27
|
-
targetDirArg = plugins.smartpath.transform.makeAbsolute(targetDirArg);
|
|
28
|
-
const readableStream = plugins.smartfile.fsStream.createReadStream(filePathArg);
|
|
29
|
-
const extractPipeStop = plugins.tarStream.extract();
|
|
30
|
-
extractPipeStop.on('entry', async (header, stream, next) => {
|
|
31
|
-
const targetFilePath = plugins.path.join(targetDirArg, header.name);
|
|
32
|
-
const parsedPath = plugins.path.parse(targetFilePath);
|
|
33
|
-
await plugins.smartfile.fs.ensureDir(parsedPath.dir);
|
|
34
|
-
const writeStream = plugins.smartfile.fsStream.createWriteStream(targetFilePath);
|
|
35
|
-
stream.pipe(writeStream);
|
|
36
|
-
stream.on('end', () => {
|
|
37
|
-
console.log(`extracted ${header.name}`);
|
|
38
|
-
next();
|
|
39
|
-
});
|
|
40
|
-
stream.resume();
|
|
41
|
-
});
|
|
42
|
-
extractPipeStop.on('finish', () => {
|
|
43
|
-
console.log(`Sucessfully extracted ${filePathArg}!`);
|
|
44
|
-
done.resolve();
|
|
45
|
-
});
|
|
46
|
-
// lets run the stream
|
|
47
|
-
readableStream.pipe(plugins.gunzipMaybe()).pipe(extractPipeStop);
|
|
48
|
-
await done.promise;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* extracts to Observable
|
|
52
|
-
* where the Observable is emitting smartfiles
|
|
53
|
-
*/
|
|
54
|
-
async extractArchiveFromBufferToObservable(bufferArg) {
|
|
55
|
-
const { intake, replaySubject } = this.extractArchiveWithIntakeAndReplaySubject();
|
|
56
|
-
intake.pushData(bufferArg);
|
|
57
|
-
intake.signalEnd();
|
|
58
|
-
return replaySubject;
|
|
59
|
-
}
|
|
60
|
-
extractArchiveWithIntakeAndReplaySubject() {
|
|
61
|
-
const intake = new plugins.smartstream.StreamIntake();
|
|
62
|
-
const replaySubject = new plugins.smartrx.rxjs.ReplaySubject();
|
|
63
|
-
const readableStream = intake.getReadableStream();
|
|
64
|
-
const extractPipeStop = plugins.tarStream.extract();
|
|
65
|
-
extractPipeStop.on('entry', (header, stream, next) => {
|
|
66
|
-
let fileBuffer;
|
|
67
|
-
stream.on('data', (chunkArg) => {
|
|
68
|
-
if (!fileBuffer) {
|
|
69
|
-
fileBuffer = chunkArg;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
fileBuffer = Buffer.concat([fileBuffer, chunkArg]);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
stream.on('end', () => {
|
|
76
|
-
replaySubject.next(new plugins.smartfile.Smartfile({
|
|
77
|
-
base: null,
|
|
78
|
-
contentBuffer: fileBuffer,
|
|
79
|
-
path: `${header.name}`,
|
|
80
|
-
}));
|
|
81
|
-
next();
|
|
82
|
-
});
|
|
83
|
-
stream.resume();
|
|
84
|
-
});
|
|
85
|
-
extractPipeStop.on('finish', () => {
|
|
86
|
-
replaySubject.complete();
|
|
87
|
-
});
|
|
88
|
-
// lets run the stream
|
|
89
|
-
readableStream.pipe(plugins.gunzipMaybe()).pipe(extractPipeStop);
|
|
90
|
-
return {
|
|
91
|
-
intake,
|
|
92
|
-
replaySubject,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* extracts to Observable
|
|
97
|
-
*/
|
|
98
|
-
async extractArchiveFromUrlToObservable(urlArg) {
|
|
99
|
-
const response = await plugins.smartrequest.getBinary(urlArg);
|
|
100
|
-
const replaySubject = this.extractArchiveFromBufferToObservable(response.body);
|
|
101
|
-
return replaySubject;
|
|
102
|
-
}
|
|
103
|
-
// TODO
|
|
104
|
-
async extractArchiveFromUrlToStream() { }
|
|
105
|
-
// TODO
|
|
106
|
-
async extractArchiveFromFilePathToStream() { }
|
|
107
|
-
// TODO
|
|
108
|
-
async extractArchiveFromStreamToStream() { }
|
|
109
|
-
// TODO
|
|
110
|
-
async packFromStreamToStream() { }
|
|
111
|
-
// TODO
|
|
112
|
-
async packFromDirPathToStream() { }
|
|
113
|
-
// TODO
|
|
114
|
-
async packFromDirPathToFs() { }
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhcmNoaXZlLmNsYXNzZXMuc21hcnRhcmNoaXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhcmNoaXZlLmNsYXNzZXMuc21hcnRhcmNoaXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sMkJBQTJCLENBQUM7QUFDckQsT0FBTyxLQUFLLEtBQUssTUFBTSx5QkFBeUIsQ0FBQztBQUVqRCxNQUFNLE9BQU8sWUFBWTtJQUN2QixnQkFBZSxDQUFDO0lBRWhCOztPQUVHO0lBQ0ksS0FBSyxDQUFDLHlCQUF5QixDQUFDLE1BQWMsRUFBRSxTQUFpQjtRQUN0RSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFDbEUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLHFDQUFxQztRQUNyRixNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzlFLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sSUFBSSxDQUFDLDhCQUE4QixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNuRSxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxD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
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartarchive.plugins.js';
|
|
2
|
-
export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '../');
|
|
3
|
-
export const nogitDir = plugins.path.join(packageDir, './.nogit');
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhcmNoaXZlLnBhdGhzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhcmNoaXZlLnBhdGhzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sMkJBQTJCLENBQUM7QUFFckQsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUN6QyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUMvRCxLQUFLLENBQ04sQ0FBQztBQUNGLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUMifQ==
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import * as path from 'path';
|
|
2
|
-
export { path };
|
|
3
|
-
import * as smartfile from '@push.rocks/smartfile';
|
|
4
|
-
import * as smartpath from '@push.rocks/smartpath';
|
|
5
|
-
import * as smartpromise from '@push.rocks/smartpromise';
|
|
6
|
-
import * as smartrequest from '@push.rocks/smartrequest';
|
|
7
|
-
import * as smartunique from '@push.rocks/smartunique';
|
|
8
|
-
import * as smartstream from '@push.rocks/smartstream';
|
|
9
|
-
import * as smartrx from '@push.rocks/smartrx';
|
|
10
|
-
export { smartfile, smartpath, smartpromise, smartrequest, smartunique, smartstream, smartrx };
|
|
11
|
-
import gunzipMaybe from 'gunzip-maybe';
|
|
12
|
-
import tar from 'tar';
|
|
13
|
-
import tarStream from 'tar-stream';
|
|
14
|
-
export { gunzipMaybe, tar, tarStream };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// node native scope
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
export { path };
|
|
4
|
-
// @pushrocks scope
|
|
5
|
-
import * as smartfile from '@push.rocks/smartfile';
|
|
6
|
-
import * as smartpath from '@push.rocks/smartpath';
|
|
7
|
-
import * as smartpromise from '@push.rocks/smartpromise';
|
|
8
|
-
import * as smartrequest from '@push.rocks/smartrequest';
|
|
9
|
-
import * as smartunique from '@push.rocks/smartunique';
|
|
10
|
-
import * as smartstream from '@push.rocks/smartstream';
|
|
11
|
-
import * as smartrx from '@push.rocks/smartrx';
|
|
12
|
-
export { smartfile, smartpath, smartpromise, smartrequest, smartunique, smartstream, smartrx };
|
|
13
|
-
// third party scope
|
|
14
|
-
import gunzipMaybe from 'gunzip-maybe';
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
import tar from 'tar';
|
|
17
|
-
import tarStream from 'tar-stream';
|
|
18
|
-
export { gunzipMaybe, tar, tarStream };
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhcmNoaXZlLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFyY2hpdmUucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFFN0IsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO0FBRWhCLG1CQUFtQjtBQUNuQixPQUFPLEtBQUssU0FBUyxNQUFNLHVCQUF1QixDQUFDO0FBQ25ELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBRS9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUUvRixvQkFBb0I7QUFDcEIsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBRXZDLGFBQWE7QUFDYixPQUFPLEdBQUcsTUFBTSxLQUFLLENBQUM7QUFDdEIsT0FBTyxTQUFTLE1BQU0sWUFBWSxDQUFDO0FBRW5DLE9BQU8sRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDIn0=
|
package/ts/classes.bzip2tools.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { SmartArchive } from './classes.smartarchive.js';
|
|
2
|
-
import * as plugins from './plugins.js';
|
|
3
|
-
|
|
4
|
-
import { unbzip2Stream } from './bzip2/index.js';
|
|
5
|
-
|
|
6
|
-
export class Bzip2Tools {
|
|
7
|
-
smartArchiveRef: SmartArchive;
|
|
8
|
-
|
|
9
|
-
constructor(smartArchiveRefArg: SmartArchive) {
|
|
10
|
-
this.smartArchiveRef = smartArchiveRefArg;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
getDecompressionStream() {
|
|
14
|
-
return unbzip2Stream();
|
|
15
|
-
}
|
|
16
|
-
}
|
package/ts/classes.gziptools.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
|
-
import type { TCompressionLevel } from './interfaces.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Transform stream for GZIP compression using fflate
|
|
6
|
-
*/
|
|
7
|
-
export class GzipCompressionTransform extends plugins.stream.Transform {
|
|
8
|
-
private gzip: plugins.fflate.Gzip;
|
|
9
|
-
|
|
10
|
-
constructor(level: TCompressionLevel = 6) {
|
|
11
|
-
super();
|
|
12
|
-
|
|
13
|
-
// Create a streaming Gzip compressor
|
|
14
|
-
this.gzip = new plugins.fflate.Gzip({ level }, (chunk, final) => {
|
|
15
|
-
this.push(Buffer.from(chunk));
|
|
16
|
-
if (final) {
|
|
17
|
-
this.push(null);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
_transform(
|
|
23
|
-
chunk: Buffer,
|
|
24
|
-
encoding: BufferEncoding,
|
|
25
|
-
callback: plugins.stream.TransformCallback
|
|
26
|
-
): void {
|
|
27
|
-
try {
|
|
28
|
-
this.gzip.push(chunk, false);
|
|
29
|
-
callback();
|
|
30
|
-
} catch (err) {
|
|
31
|
-
callback(err as Error);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
_flush(callback: plugins.stream.TransformCallback): void {
|
|
36
|
-
try {
|
|
37
|
-
this.gzip.push(new Uint8Array(0), true);
|
|
38
|
-
callback();
|
|
39
|
-
} catch (err) {
|
|
40
|
-
callback(err as Error);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Transform stream for GZIP decompression using fflate
|
|
47
|
-
*/
|
|
48
|
-
export class GzipDecompressionTransform extends plugins.stream.Transform {
|
|
49
|
-
private gunzip: plugins.fflate.Gunzip;
|
|
50
|
-
|
|
51
|
-
constructor() {
|
|
52
|
-
super();
|
|
53
|
-
|
|
54
|
-
// Create a streaming Gunzip decompressor
|
|
55
|
-
this.gunzip = new plugins.fflate.Gunzip((chunk, final) => {
|
|
56
|
-
this.push(Buffer.from(chunk));
|
|
57
|
-
if (final) {
|
|
58
|
-
this.push(null);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_transform(
|
|
64
|
-
chunk: Buffer,
|
|
65
|
-
encoding: BufferEncoding,
|
|
66
|
-
callback: plugins.stream.TransformCallback
|
|
67
|
-
): void {
|
|
68
|
-
try {
|
|
69
|
-
this.gunzip.push(chunk, false);
|
|
70
|
-
callback();
|
|
71
|
-
} catch (err) {
|
|
72
|
-
callback(err as Error);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
_flush(callback: plugins.stream.TransformCallback): void {
|
|
77
|
-
try {
|
|
78
|
-
this.gunzip.push(new Uint8Array(0), true);
|
|
79
|
-
callback();
|
|
80
|
-
} catch (err) {
|
|
81
|
-
callback(err as Error);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* GZIP compression and decompression utilities
|
|
88
|
-
*/
|
|
89
|
-
export class GzipTools {
|
|
90
|
-
/**
|
|
91
|
-
* Get a streaming compression transform
|
|
92
|
-
*/
|
|
93
|
-
public getCompressionStream(level?: TCompressionLevel): plugins.stream.Transform {
|
|
94
|
-
return new GzipCompressionTransform(level);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Get a streaming decompression transform
|
|
99
|
-
*/
|
|
100
|
-
public getDecompressionStream(): plugins.stream.Transform {
|
|
101
|
-
return new GzipDecompressionTransform();
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Compress data synchronously
|
|
106
|
-
*/
|
|
107
|
-
public compressSync(data: Buffer, level?: TCompressionLevel): Buffer {
|
|
108
|
-
const options = level !== undefined ? { level } : undefined;
|
|
109
|
-
return Buffer.from(plugins.fflate.gzipSync(data, options));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Decompress data synchronously
|
|
114
|
-
*/
|
|
115
|
-
public decompressSync(data: Buffer): Buffer {
|
|
116
|
-
return Buffer.from(plugins.fflate.gunzipSync(data));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Compress data asynchronously
|
|
121
|
-
* Note: Uses sync version for Deno compatibility (fflate async uses Web Workers
|
|
122
|
-
* which have issues in Deno)
|
|
123
|
-
*/
|
|
124
|
-
public async compress(data: Buffer, level?: TCompressionLevel): Promise<Buffer> {
|
|
125
|
-
// Use sync version wrapped in Promise for cross-runtime compatibility
|
|
126
|
-
return this.compressSync(data, level);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Decompress data asynchronously
|
|
131
|
-
* Note: Uses sync version for Deno compatibility (fflate async uses Web Workers
|
|
132
|
-
* which have issues in Deno)
|
|
133
|
-
*/
|
|
134
|
-
public async decompress(data: Buffer): Promise<Buffer> {
|
|
135
|
-
// Use sync version wrapped in Promise for cross-runtime compatibility
|
|
136
|
-
return this.decompressSync(data);
|
|
137
|
-
}
|
|
138
|
-
}
|
package/ts/classes.ziptools.ts
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
|
-
import type { IArchiveEntry, TCompressionLevel } from './interfaces.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Transform stream for ZIP decompression using fflate
|
|
6
|
-
* Emits StreamFile objects for each file in the archive
|
|
7
|
-
*/
|
|
8
|
-
export class ZipDecompressionTransform extends plugins.smartstream.SmartDuplex<Buffer, plugins.smartfile.StreamFile> {
|
|
9
|
-
private streamtools!: plugins.smartstream.IStreamTools;
|
|
10
|
-
private unzipper = new plugins.fflate.Unzip(async (fileArg) => {
|
|
11
|
-
let resultBuffer: Buffer;
|
|
12
|
-
fileArg.ondata = async (_flateError, dat, final) => {
|
|
13
|
-
resultBuffer
|
|
14
|
-
? (resultBuffer = Buffer.concat([resultBuffer, Buffer.from(dat)]))
|
|
15
|
-
: (resultBuffer = Buffer.from(dat));
|
|
16
|
-
if (final) {
|
|
17
|
-
const streamFile = plugins.smartfile.StreamFile.fromBuffer(resultBuffer);
|
|
18
|
-
streamFile.relativeFilePath = fileArg.name;
|
|
19
|
-
this.streamtools.push(streamFile);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
fileArg.start();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
constructor() {
|
|
26
|
-
super({
|
|
27
|
-
objectMode: true,
|
|
28
|
-
writeFunction: async (chunkArg, streamtoolsArg) => {
|
|
29
|
-
this.streamtools ? null : (this.streamtools = streamtoolsArg);
|
|
30
|
-
this.unzipper.push(
|
|
31
|
-
Buffer.isBuffer(chunkArg) ? chunkArg : Buffer.from(chunkArg as unknown as ArrayBuffer),
|
|
32
|
-
false
|
|
33
|
-
);
|
|
34
|
-
return null;
|
|
35
|
-
},
|
|
36
|
-
finalFunction: async () => {
|
|
37
|
-
this.unzipper.push(Buffer.from(''), true);
|
|
38
|
-
await plugins.smartdelay.delayFor(0);
|
|
39
|
-
await this.streamtools.push(null);
|
|
40
|
-
return null;
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
this.unzipper.register(plugins.fflate.UnzipInflate);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Streaming ZIP compression using fflate
|
|
49
|
-
* Allows adding multiple entries before finalizing
|
|
50
|
-
*/
|
|
51
|
-
export class ZipCompressionStream extends plugins.stream.Duplex {
|
|
52
|
-
private files: Map<string, { data: Uint8Array; options?: plugins.fflate.ZipOptions }> = new Map();
|
|
53
|
-
private finalized = false;
|
|
54
|
-
|
|
55
|
-
constructor() {
|
|
56
|
-
super();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Add a file entry to the ZIP archive
|
|
61
|
-
*/
|
|
62
|
-
public async addEntry(
|
|
63
|
-
fileName: string,
|
|
64
|
-
content: Buffer | plugins.stream.Readable,
|
|
65
|
-
options?: { compressionLevel?: TCompressionLevel }
|
|
66
|
-
): Promise<void> {
|
|
67
|
-
if (this.finalized) {
|
|
68
|
-
throw new Error('Cannot add entries to a finalized ZIP archive');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let data: Buffer;
|
|
72
|
-
if (Buffer.isBuffer(content)) {
|
|
73
|
-
data = content;
|
|
74
|
-
} else {
|
|
75
|
-
// Collect stream to buffer
|
|
76
|
-
const chunks: Buffer[] = [];
|
|
77
|
-
for await (const chunk of content) {
|
|
78
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
79
|
-
}
|
|
80
|
-
data = Buffer.concat(chunks);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
this.files.set(fileName, {
|
|
84
|
-
data: new Uint8Array(data),
|
|
85
|
-
options: options?.compressionLevel !== undefined ? { level: options.compressionLevel } : undefined,
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Finalize the ZIP archive and emit the compressed data
|
|
91
|
-
*/
|
|
92
|
-
public async finalize(): Promise<void> {
|
|
93
|
-
if (this.finalized) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
this.finalized = true;
|
|
97
|
-
|
|
98
|
-
const filesObj: plugins.fflate.Zippable = {};
|
|
99
|
-
for (const [name, { data, options }] of this.files) {
|
|
100
|
-
filesObj[name] = options ? [data, options] : data;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Use sync version for Deno compatibility (fflate async uses Web Workers)
|
|
104
|
-
try {
|
|
105
|
-
const result = plugins.fflate.zipSync(filesObj);
|
|
106
|
-
this.push(Buffer.from(result));
|
|
107
|
-
this.push(null);
|
|
108
|
-
} catch (err) {
|
|
109
|
-
throw err;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
_read(): void {
|
|
114
|
-
// No-op: data is pushed when finalize() is called
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
_write(
|
|
118
|
-
_chunk: Buffer,
|
|
119
|
-
_encoding: BufferEncoding,
|
|
120
|
-
callback: (error?: Error | null) => void
|
|
121
|
-
): void {
|
|
122
|
-
// Not used for ZIP creation - use addEntry() instead
|
|
123
|
-
callback(new Error('Use addEntry() to add files to the ZIP archive'));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* ZIP compression and decompression utilities
|
|
129
|
-
*/
|
|
130
|
-
export class ZipTools {
|
|
131
|
-
/**
|
|
132
|
-
* Get a streaming compression object for creating ZIP archives
|
|
133
|
-
*/
|
|
134
|
-
public getCompressionStream(): ZipCompressionStream {
|
|
135
|
-
return new ZipCompressionStream();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Get a streaming decompression transform for extracting ZIP archives
|
|
140
|
-
*/
|
|
141
|
-
public getDecompressionStream(): ZipDecompressionTransform {
|
|
142
|
-
return new ZipDecompressionTransform();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Create a ZIP archive from an array of entries
|
|
147
|
-
*/
|
|
148
|
-
public async createZip(entries: IArchiveEntry[], compressionLevel?: TCompressionLevel): Promise<Buffer> {
|
|
149
|
-
const filesObj: plugins.fflate.Zippable = {};
|
|
150
|
-
|
|
151
|
-
for (const entry of entries) {
|
|
152
|
-
let data: Uint8Array;
|
|
153
|
-
|
|
154
|
-
if (typeof entry.content === 'string') {
|
|
155
|
-
data = new TextEncoder().encode(entry.content);
|
|
156
|
-
} else if (Buffer.isBuffer(entry.content)) {
|
|
157
|
-
data = new Uint8Array(entry.content);
|
|
158
|
-
} else if (entry.content instanceof plugins.smartfile.SmartFile) {
|
|
159
|
-
data = new Uint8Array(entry.content.contents);
|
|
160
|
-
} else if (entry.content instanceof plugins.smartfile.StreamFile) {
|
|
161
|
-
const buffer = await entry.content.getContentAsBuffer();
|
|
162
|
-
data = new Uint8Array(buffer);
|
|
163
|
-
} else {
|
|
164
|
-
// Readable stream
|
|
165
|
-
const chunks: Buffer[] = [];
|
|
166
|
-
for await (const chunk of entry.content as plugins.stream.Readable) {
|
|
167
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
168
|
-
}
|
|
169
|
-
data = new Uint8Array(Buffer.concat(chunks));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (compressionLevel !== undefined) {
|
|
173
|
-
filesObj[entry.archivePath] = [data, { level: compressionLevel }];
|
|
174
|
-
} else {
|
|
175
|
-
filesObj[entry.archivePath] = data;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Use sync version for Deno compatibility (fflate async uses Web Workers)
|
|
180
|
-
const result = plugins.fflate.zipSync(filesObj);
|
|
181
|
-
return Buffer.from(result);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Extract a ZIP buffer to an array of entries
|
|
186
|
-
*/
|
|
187
|
-
public async extractZip(data: Buffer): Promise<Array<{ path: string; content: Buffer }>> {
|
|
188
|
-
// Use sync version for Deno compatibility (fflate async uses Web Workers)
|
|
189
|
-
const result = plugins.fflate.unzipSync(data);
|
|
190
|
-
const entries: Array<{ path: string; content: Buffer }> = [];
|
|
191
|
-
for (const [path, content] of Object.entries(result)) {
|
|
192
|
-
entries.push({ path, content: Buffer.from(content) });
|
|
193
|
-
}
|
|
194
|
-
return entries;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
File without changes
|