@push.rocks/smartarchive 5.1.0 β 5.2.1
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 +1 -1
- package/dist_ts/classes.smartarchive.d.ts +4 -4
- package/dist_ts/classes.smartarchive.js +29 -24
- package/dist_ts/classes.tartools.d.ts +81 -6
- package/dist_ts/classes.tartools.js +202 -16
- package/dist_ts/index.d.ts +2 -2
- package/dist_ts/index.js +3 -3
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +5 -2
- package/dist_ts_shared/bzip2/bititerator.d.ts +6 -0
- package/dist_ts_shared/bzip2/bititerator.js +50 -0
- package/dist_ts_shared/bzip2/bzip2.d.ts +29 -0
- package/dist_ts_shared/bzip2/bzip2.js +398 -0
- package/dist_ts_shared/bzip2/index.d.ts +5 -0
- package/dist_ts_shared/bzip2/index.js +92 -0
- package/dist_ts_shared/classes.bzip2tools.d.ts +10 -0
- package/dist_ts_shared/classes.bzip2tools.js +14 -0
- package/dist_ts_shared/classes.gziptools.d.ts +26 -0
- package/dist_ts_shared/classes.gziptools.js +38 -0
- package/dist_ts_shared/classes.tartools.d.ts +30 -0
- package/dist_ts_shared/classes.tartools.js +78 -0
- package/dist_ts_shared/classes.ziptools.d.ts +31 -0
- package/dist_ts_shared/classes.ziptools.js +103 -0
- package/dist_ts_shared/errors.d.ts +44 -0
- package/dist_ts_shared/errors.js +62 -0
- package/dist_ts_shared/index.d.ts +8 -0
- package/dist_ts_shared/index.js +14 -0
- package/dist_ts_shared/interfaces.d.ts +129 -0
- package/dist_ts_shared/interfaces.js +2 -0
- package/dist_ts_shared/plugins.d.ts +9 -0
- package/dist_ts_shared/plugins.js +14 -0
- package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
- package/dist_ts_web/00_commitinfo_data.js +9 -0
- package/dist_ts_web/index.d.ts +1 -0
- package/dist_ts_web/index.js +4 -0
- package/dist_ts_web/plugins.d.ts +1 -0
- package/dist_ts_web/plugins.js +4 -0
- package/package.json +7 -5
- package/readme.md +154 -46
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.smartarchive.ts +28 -23
- package/ts/classes.tartools.ts +235 -14
- package/ts/index.ts +2 -2
- package/ts/plugins.ts +4 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../ts_shared/index.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// ts_web - Browser-compatible entry point
|
|
2
|
+
// Re-exports everything from ts_shared
|
|
3
|
+
export * from '../ts_shared/index.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c193ZWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMENBQTBDO0FBQzFDLHVDQUF1QztBQUV2QyxjQUFjLHVCQUF1QixDQUFDIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../ts_shared/plugins.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Browser-compatible plugins for ts_web
|
|
2
|
+
// Re-export from ts_shared
|
|
3
|
+
export * from '../ts_shared/plugins.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHdDQUF3QztBQUN4QywyQkFBMkI7QUFDM0IsY0FBYyx5QkFBeUIsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartarchive",
|
|
3
|
-
"version": "5.1
|
|
3
|
+
"version": "5.2.1",
|
|
4
4
|
"description": "A library for working with archive files, providing utilities for compressing and decompressing data.",
|
|
5
5
|
"main": "dist_ts/index.js",
|
|
6
6
|
"typings": "dist_ts/index.d.ts",
|
|
@@ -35,13 +35,15 @@
|
|
|
35
35
|
"@push.rocks/smartunique": "^3.0.9",
|
|
36
36
|
"@push.rocks/smarturl": "^3.1.0",
|
|
37
37
|
"fflate": "^0.8.2",
|
|
38
|
-
"file-type": "^21.
|
|
39
|
-
"modern-tar": "^0.7.3"
|
|
38
|
+
"file-type": "^21.3.0",
|
|
39
|
+
"modern-tar": "^0.7.3",
|
|
40
|
+
"tar-stream": "^3.1.7"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@git.zone/tsbuild": "^4.
|
|
43
|
+
"@git.zone/tsbuild": "^4.1.2",
|
|
43
44
|
"@git.zone/tsrun": "^2.0.1",
|
|
44
|
-
"@git.zone/tstest": "^3.1.4"
|
|
45
|
+
"@git.zone/tstest": "^3.1.4",
|
|
46
|
+
"@types/tar-stream": "^3.1.3"
|
|
45
47
|
},
|
|
46
48
|
"private": false,
|
|
47
49
|
"files": [
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @push.rocks/smartarchive π¦
|
|
2
2
|
|
|
3
|
-
A powerful, streaming-first archive manipulation library with a fluent builder API. Works seamlessly in Node.js and
|
|
3
|
+
A powerful, streaming-first archive manipulation library with a fluent builder API. Works seamlessly in **Node.js**, **Deno**, and **browsers**.
|
|
4
4
|
|
|
5
5
|
## Issue Reporting and Security
|
|
6
6
|
|
|
@@ -12,11 +12,12 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
12
12
|
- π **Streaming-first architecture** β Process large archives without memory constraints
|
|
13
13
|
- β¨ **Fluent builder API** β Chain methods for readable, expressive code
|
|
14
14
|
- π― **Smart detection** β Automatically identifies archive types via magic bytes
|
|
15
|
-
- β‘ **High performance** β Built on `tar
|
|
15
|
+
- β‘ **High performance** β Built on `modern-tar` and `fflate` for speed
|
|
16
16
|
- π§ **Flexible I/O** β Work with files, URLs, streams, and buffers seamlessly
|
|
17
17
|
- π οΈ **Modern TypeScript** β Full type safety and excellent IDE support
|
|
18
18
|
- π **Dual-mode operation** β Extract existing archives OR create new ones
|
|
19
|
-
- π¦ **Cross-runtime** β Works in
|
|
19
|
+
- π¦ **Cross-runtime** β Works in Node.js, Deno, and browsers
|
|
20
|
+
- π **Browser-ready** β Dedicated browser bundle with zero Node.js dependencies
|
|
20
21
|
|
|
21
22
|
## Installation π₯
|
|
22
23
|
|
|
@@ -71,6 +72,59 @@ await SmartArchive.create()
|
|
|
71
72
|
.extract('./node_modules/lodash');
|
|
72
73
|
```
|
|
73
74
|
|
|
75
|
+
## Browser Usage π
|
|
76
|
+
|
|
77
|
+
smartarchive provides a dedicated browser-compatible bundle with no Node.js dependencies:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Import from the /web subpath for browser environments
|
|
81
|
+
import { TarTools, ZipTools, GzipTools, Bzip2Tools } from '@push.rocks/smartarchive/web';
|
|
82
|
+
|
|
83
|
+
// Create a TAR archive in the browser
|
|
84
|
+
const tarTools = new TarTools();
|
|
85
|
+
const tarBuffer = await tarTools.packFiles([
|
|
86
|
+
{ archivePath: 'hello.txt', content: 'Hello from the browser!' },
|
|
87
|
+
{ archivePath: 'data.json', content: JSON.stringify({ browser: true }) }
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
// Create a TAR.GZ archive
|
|
91
|
+
const tgzBuffer = await tarTools.packFilesToTarGz([
|
|
92
|
+
{ archivePath: 'file.txt', content: 'Compressed!' }
|
|
93
|
+
], 6);
|
|
94
|
+
|
|
95
|
+
// Extract a TAR archive
|
|
96
|
+
const entries = await tarTools.extractTar(tarBuffer);
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
console.log(`${entry.path}: ${entry.content.length} bytes`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Work with ZIP files
|
|
102
|
+
const zipTools = new ZipTools();
|
|
103
|
+
const zipBuffer = await zipTools.createZip([
|
|
104
|
+
{ archivePath: 'doc.txt', content: 'Document content' }
|
|
105
|
+
], 6);
|
|
106
|
+
|
|
107
|
+
const zipEntries = await zipTools.extractZip(zipBuffer);
|
|
108
|
+
|
|
109
|
+
// GZIP compression
|
|
110
|
+
const gzipTools = new GzipTools();
|
|
111
|
+
const compressed = gzipTools.compressSync(new TextEncoder().encode('Hello World'), 6);
|
|
112
|
+
const decompressed = gzipTools.decompressSync(compressed);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Browser Bundle Exports
|
|
116
|
+
|
|
117
|
+
The `/web` subpath exports these browser-compatible tools:
|
|
118
|
+
|
|
119
|
+
| Export | Description |
|
|
120
|
+
|--------|-------------|
|
|
121
|
+
| `TarTools` | Create and extract TAR and TAR.GZ archives |
|
|
122
|
+
| `ZipTools` | Create and extract ZIP archives |
|
|
123
|
+
| `GzipTools` | GZIP compression and decompression |
|
|
124
|
+
| `Bzip2Tools` | BZIP2 decompression (extraction only) |
|
|
125
|
+
|
|
126
|
+
> π‘ **Note:** The browser bundle does **not** include `SmartArchive` (which requires filesystem access). Use the individual tool classes for browser applications.
|
|
127
|
+
|
|
74
128
|
## Core Concepts π‘
|
|
75
129
|
|
|
76
130
|
### Fluent Builder Pattern
|
|
@@ -294,51 +348,107 @@ await SmartArchive.create()
|
|
|
294
348
|
// Use GzipTools directly for compression/decompression
|
|
295
349
|
const gzipTools = new GzipTools();
|
|
296
350
|
|
|
297
|
-
// Compress a buffer
|
|
298
|
-
const
|
|
299
|
-
const
|
|
351
|
+
// Compress a buffer (sync and async available)
|
|
352
|
+
const input = new TextEncoder().encode('Hello World');
|
|
353
|
+
const compressed = gzipTools.compressSync(input, 9);
|
|
354
|
+
const decompressed = gzipTools.decompressSync(compressed);
|
|
300
355
|
|
|
301
|
-
//
|
|
302
|
-
const
|
|
303
|
-
const
|
|
356
|
+
// Async versions (internally use sync for cross-runtime compatibility)
|
|
357
|
+
const compressedAsync = await gzipTools.compress(input, 6);
|
|
358
|
+
const decompressedAsync = await gzipTools.decompress(compressedAsync);
|
|
359
|
+
```
|
|
304
360
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
361
|
+
### Working with TAR archives directly
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { TarTools } from '@push.rocks/smartarchive';
|
|
365
|
+
|
|
366
|
+
const tarTools = new TarTools();
|
|
367
|
+
|
|
368
|
+
// Create a TAR archive from entries (buffer-based, good for small files)
|
|
369
|
+
const tarBuffer = await tarTools.packFiles([
|
|
370
|
+
{ archivePath: 'hello.txt', content: 'Hello, World!' },
|
|
371
|
+
{ archivePath: 'data.json', content: JSON.stringify({ foo: 'bar' }) }
|
|
372
|
+
]);
|
|
373
|
+
|
|
374
|
+
// Create a TAR.GZ archive
|
|
375
|
+
const tgzBuffer = await tarTools.packFilesToTarGz([
|
|
376
|
+
{ archivePath: 'file.txt', content: 'Compressed content' }
|
|
377
|
+
], 6);
|
|
378
|
+
|
|
379
|
+
// Extract a TAR archive
|
|
380
|
+
const entries = await tarTools.extractTar(tarBuffer);
|
|
381
|
+
for (const entry of entries) {
|
|
382
|
+
console.log(`${entry.path}: ${entry.isDirectory ? 'dir' : 'file'}`);
|
|
383
|
+
}
|
|
308
384
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
385
|
+
// Extract a TAR.GZ archive
|
|
386
|
+
const tgzEntries = await tarTools.extractTarGz(tgzBuffer);
|
|
387
|
+
|
|
388
|
+
// Node.js only: Pack a directory (buffer-based)
|
|
389
|
+
const dirBuffer = await tarTools.packDirectory('./src');
|
|
390
|
+
const dirTgzBuffer = await tarTools.packDirectoryToTarGz('./src', 9);
|
|
312
391
|
```
|
|
313
392
|
|
|
314
|
-
###
|
|
393
|
+
### Streaming TAR for Large Files (Node.js only) π
|
|
394
|
+
|
|
395
|
+
For large files that don't fit in memory, use the streaming APIs:
|
|
315
396
|
|
|
316
397
|
```typescript
|
|
317
398
|
import { TarTools } from '@push.rocks/smartarchive';
|
|
399
|
+
import * as fs from 'fs';
|
|
318
400
|
|
|
319
401
|
const tarTools = new TarTools();
|
|
320
402
|
|
|
321
|
-
//
|
|
322
|
-
|
|
403
|
+
// ===== STREAMING PACK =====
|
|
404
|
+
// Create a TAR pack stream - files are processed one at a time
|
|
405
|
+
const pack = tarTools.getPackStream();
|
|
323
406
|
|
|
407
|
+
// Add files with streaming content (requires size for streams)
|
|
324
408
|
await tarTools.addFileToPack(pack, {
|
|
325
|
-
fileName: '
|
|
326
|
-
content: 'Hello
|
|
409
|
+
fileName: 'small.txt',
|
|
410
|
+
content: 'Hello World' // Strings and buffers auto-detect size
|
|
327
411
|
});
|
|
328
412
|
|
|
329
413
|
await tarTools.addFileToPack(pack, {
|
|
330
|
-
fileName: '
|
|
331
|
-
content:
|
|
414
|
+
fileName: 'large-video.mp4',
|
|
415
|
+
content: fs.createReadStream('./video.mp4'),
|
|
416
|
+
size: fs.statSync('./video.mp4').size // Size required for streams
|
|
332
417
|
});
|
|
333
418
|
|
|
334
419
|
pack.finalize();
|
|
335
|
-
pack.pipe(createWriteStream('
|
|
420
|
+
pack.pipe(fs.createWriteStream('output.tar'));
|
|
421
|
+
|
|
422
|
+
// ===== STREAMING DIRECTORY PACK =====
|
|
423
|
+
// Pack entire directory with true streaming (no buffering)
|
|
424
|
+
const tarStream = await tarTools.getDirectoryPackStream('./large-folder');
|
|
425
|
+
tarStream.pipe(fs.createWriteStream('backup.tar'));
|
|
426
|
+
|
|
427
|
+
// With GZIP compression
|
|
428
|
+
const tgzStream = await tarTools.getDirectoryPackStreamGz('./large-folder', 6);
|
|
429
|
+
tgzStream.pipe(fs.createWriteStream('backup.tar.gz'));
|
|
430
|
+
|
|
431
|
+
// ===== STREAMING EXTRACT =====
|
|
432
|
+
// Extract large archives without loading into memory
|
|
433
|
+
const extract = tarTools.getExtractStream();
|
|
336
434
|
|
|
337
|
-
|
|
338
|
-
|
|
435
|
+
extract.on('entry', (header, stream, next) => {
|
|
436
|
+
console.log(`Extracting: ${header.name} (${header.size} bytes)`);
|
|
339
437
|
|
|
340
|
-
|
|
341
|
-
|
|
438
|
+
const writeStream = fs.createWriteStream(`./out/${header.name}`);
|
|
439
|
+
stream.pipe(writeStream);
|
|
440
|
+
writeStream.on('finish', next);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
extract.on('finish', () => console.log('Extraction complete'));
|
|
444
|
+
|
|
445
|
+
fs.createReadStream('large-archive.tar').pipe(extract);
|
|
446
|
+
|
|
447
|
+
// Or use the convenient directory extraction
|
|
448
|
+
await tarTools.extractToDirectory(
|
|
449
|
+
fs.createReadStream('archive.tar'),
|
|
450
|
+
'./output-folder'
|
|
451
|
+
);
|
|
342
452
|
```
|
|
343
453
|
|
|
344
454
|
### Working with ZIP archives directly
|
|
@@ -351,7 +461,7 @@ const zipTools = new ZipTools();
|
|
|
351
461
|
// Create a ZIP archive from entries
|
|
352
462
|
const zipBuffer = await zipTools.createZip([
|
|
353
463
|
{ archivePath: 'readme.txt', content: 'Hello!' },
|
|
354
|
-
{ archivePath: 'data.bin', content:
|
|
464
|
+
{ archivePath: 'data.bin', content: new Uint8Array([0x00, 0x01, 0x02]) }
|
|
355
465
|
], 6);
|
|
356
466
|
|
|
357
467
|
// Extract a ZIP buffer
|
|
@@ -448,13 +558,13 @@ fileStream.on('data', async (file) => {
|
|
|
448
558
|
|
|
449
559
|
## Supported Formats π
|
|
450
560
|
|
|
451
|
-
| Format | Extension(s) | Extract | Create |
|
|
452
|
-
|
|
453
|
-
| TAR | `.tar` | β
| β
|
|
|
454
|
-
| TAR.GZ / TGZ | `.tar.gz`, `.tgz` | β
| β
|
|
|
455
|
-
| ZIP | `.zip` | β
| β
|
|
|
456
|
-
| GZIP | `.gz` | β
| β
|
|
|
457
|
-
| BZIP2 | `.bz2` | β
| β |
|
|
561
|
+
| Format | Extension(s) | Extract | Create | Browser |
|
|
562
|
+
|--------|--------------|---------|--------|---------|
|
|
563
|
+
| TAR | `.tar` | β
| β
| β
|
|
|
564
|
+
| TAR.GZ / TGZ | `.tar.gz`, `.tgz` | β
| β
| β
|
|
|
565
|
+
| ZIP | `.zip` | β
| β
| β
|
|
|
566
|
+
| GZIP | `.gz` | β
| β
| β
|
|
|
567
|
+
| BZIP2 | `.bz2` | β
| β | β
|
|
|
458
568
|
|
|
459
569
|
## Type Definitions
|
|
460
570
|
|
|
@@ -468,7 +578,7 @@ type TCompressionLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
|
468
578
|
// Entry for creating archives
|
|
469
579
|
interface IArchiveEntry {
|
|
470
580
|
archivePath: string;
|
|
471
|
-
content: string | Buffer |
|
|
581
|
+
content: string | Buffer | Uint8Array | SmartFile | StreamFile;
|
|
472
582
|
size?: number;
|
|
473
583
|
mode?: number;
|
|
474
584
|
mtime?: Date;
|
|
@@ -496,9 +606,9 @@ interface IArchiveInfo {
|
|
|
496
606
|
## Performance Tips ποΈ
|
|
497
607
|
|
|
498
608
|
1. **Use streaming for large files** β `.toStreamFiles()` processes entries one at a time without loading the entire archive
|
|
499
|
-
2. **
|
|
500
|
-
3. **
|
|
501
|
-
4. **
|
|
609
|
+
2. **Choose appropriate compression** β Use 1-3 for speed, 6 (default) for balance, 9 for maximum compression
|
|
610
|
+
3. **Filter early** β Use `.include()`/`.exclude()` to skip unwanted entries before processing
|
|
611
|
+
4. **Use Uint8Array in browsers** β The browser bundle works with `Uint8Array` for optimal performance
|
|
502
612
|
|
|
503
613
|
## Error Handling π‘οΈ
|
|
504
614
|
|
|
@@ -524,23 +634,21 @@ try {
|
|
|
524
634
|
|
|
525
635
|
## License and Legal Information
|
|
526
636
|
|
|
527
|
-
This repository contains open-source code
|
|
637
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
|
|
528
638
|
|
|
529
639
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
530
640
|
|
|
531
641
|
### Trademarks
|
|
532
642
|
|
|
533
|
-
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein.
|
|
534
|
-
|
|
535
|
-
### Issue Reporting and Security
|
|
643
|
+
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
|
|
536
644
|
|
|
537
|
-
|
|
645
|
+
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
|
|
538
646
|
|
|
539
647
|
### Company Information
|
|
540
648
|
|
|
541
649
|
Task Venture Capital GmbH
|
|
542
|
-
Registered at District
|
|
650
|
+
Registered at District Court Bremen HRB 35230 HB, Germany
|
|
543
651
|
|
|
544
|
-
For any legal inquiries or
|
|
652
|
+
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
|
545
653
|
|
|
546
654
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -380,36 +380,41 @@ export class SmartArchive {
|
|
|
380
380
|
plugins.smartstream.createTransformFunction<IAnalyzedResult, void>(
|
|
381
381
|
async (analyzedResultChunk) => {
|
|
382
382
|
if (analyzedResultChunk.fileType?.mime === 'application/x-tar') {
|
|
383
|
-
// Use
|
|
384
|
-
|
|
383
|
+
// Use tar-stream for streaming TAR extraction
|
|
384
|
+
// Buffer each entry to ensure tar-stream can proceed to next entry
|
|
385
|
+
const extract = this.tarTools.getExtractStream();
|
|
386
|
+
|
|
387
|
+
extract.on('entry', (header, stream, next) => {
|
|
388
|
+
if (header.type === 'directory') {
|
|
389
|
+
stream.resume(); // Drain the stream
|
|
390
|
+
next();
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
385
393
|
|
|
386
|
-
|
|
387
|
-
chunks
|
|
394
|
+
// Buffer the entry content to avoid blocking tar-stream
|
|
395
|
+
const chunks: Buffer[] = [];
|
|
396
|
+
stream.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
397
|
+
stream.on('end', () => {
|
|
398
|
+
const content = Buffer.concat(chunks);
|
|
399
|
+
const streamFile = plugins.smartfile.StreamFile.fromBuffer(content);
|
|
400
|
+
streamFile.relativeFilePath = header.name;
|
|
401
|
+
streamFileIntake.push(streamFile);
|
|
402
|
+
next();
|
|
403
|
+
});
|
|
404
|
+
stream.on('error', (err: Error) => {
|
|
405
|
+
streamFileIntake.emit('error', err);
|
|
406
|
+
});
|
|
388
407
|
});
|
|
389
408
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const tarBuffer = Buffer.concat(chunks);
|
|
393
|
-
const entries = await this.tarTools.extractTar(new Uint8Array(tarBuffer));
|
|
394
|
-
|
|
395
|
-
for (const entry of entries) {
|
|
396
|
-
if (entry.isDirectory) continue;
|
|
397
|
-
|
|
398
|
-
const streamFile = plugins.smartfile.StreamFile.fromBuffer(
|
|
399
|
-
Buffer.from(entry.content)
|
|
400
|
-
);
|
|
401
|
-
streamFile.relativeFilePath = entry.path;
|
|
402
|
-
streamFileIntake.push(streamFile);
|
|
403
|
-
}
|
|
404
|
-
safeSignalEnd();
|
|
405
|
-
} catch (err) {
|
|
406
|
-
streamFileIntake.emit('error', err);
|
|
407
|
-
}
|
|
409
|
+
extract.on('finish', () => {
|
|
410
|
+
safeSignalEnd();
|
|
408
411
|
});
|
|
409
412
|
|
|
410
|
-
|
|
413
|
+
extract.on('error', (err: Error) => {
|
|
411
414
|
streamFileIntake.emit('error', err);
|
|
412
415
|
});
|
|
416
|
+
|
|
417
|
+
analyzedResultChunk.resultStream.pipe(extract);
|
|
413
418
|
} else if (analyzedResultChunk.fileType?.mime === 'application/zip') {
|
|
414
419
|
analyzedResultChunk.resultStream
|
|
415
420
|
.pipe(analyzedResultChunk.decompressionStream)
|