@push.rocks/smartarchive 4.2.4 → 5.0.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/bzip2/bititerator.d.ts +6 -1
- package/dist_ts/bzip2/bititerator.js +30 -24
- package/dist_ts/bzip2/bzip2.d.ts +27 -12
- package/dist_ts/bzip2/bzip2.js +325 -263
- package/dist_ts/bzip2/index.d.ts +4 -1
- package/dist_ts/bzip2/index.js +36 -38
- package/dist_ts/classes.archiveanalyzer.d.ts +25 -5
- package/dist_ts/classes.archiveanalyzer.js +19 -8
- package/dist_ts/classes.bzip2tools.d.ts +1 -1
- package/dist_ts/classes.gziptools.d.ts +43 -6
- package/dist_ts/classes.gziptools.js +76 -24
- package/dist_ts/classes.smartarchive.d.ts +198 -16
- package/dist_ts/classes.smartarchive.js +652 -79
- package/dist_ts/classes.tartools.d.ts +31 -4
- package/dist_ts/classes.tartools.js +93 -32
- package/dist_ts/classes.ziptools.d.ts +47 -12
- package/dist_ts/classes.ziptools.js +128 -23
- package/dist_ts/errors.d.ts +44 -0
- package/dist_ts/errors.js +62 -0
- package/dist_ts/index.d.ts +4 -0
- package/dist_ts/index.js +9 -1
- package/dist_ts/interfaces.d.ts +119 -0
- package/dist_ts/interfaces.js +2 -0
- package/package.json +1 -1
- package/readme.hints.md +69 -23
- package/readme.md +360 -274
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/bzip2/bititerator.ts +43 -27
- package/ts/bzip2/bzip2.ts +289 -171
- package/ts/bzip2/index.ts +52 -50
- package/ts/classes.archiveanalyzer.ts +42 -28
- package/ts/classes.gziptools.ts +91 -33
- package/ts/classes.smartarchive.ts +765 -140
- package/ts/classes.tartools.ts +124 -52
- package/ts/classes.ziptools.ts +147 -34
- package/ts/errors.ts +70 -0
- package/ts/index.ts +11 -0
- package/ts/interfaces.ts +136 -0
|
@@ -1,87 +1,280 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
-
import * as paths from './paths.js';
|
|
3
2
|
import { Bzip2Tools } from './classes.bzip2tools.js';
|
|
4
3
|
import { GzipTools } from './classes.gziptools.js';
|
|
5
4
|
import { TarTools } from './classes.tartools.js';
|
|
6
5
|
import { ZipTools } from './classes.ziptools.js';
|
|
7
|
-
import { ArchiveAnalyzer
|
|
6
|
+
import { ArchiveAnalyzer } from './classes.archiveanalyzer.js';
|
|
7
|
+
/**
|
|
8
|
+
* Main class for archive manipulation with fluent API
|
|
9
|
+
* Supports TAR, ZIP, GZIP, and BZIP2 formats
|
|
10
|
+
*
|
|
11
|
+
* @example Extraction from URL
|
|
12
|
+
* ```typescript
|
|
13
|
+
* await SmartArchive.create()
|
|
14
|
+
* .url('https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz')
|
|
15
|
+
* .stripComponents(1)
|
|
16
|
+
* .extract('./node_modules/lodash');
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Creation with thenable
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const archive = await SmartArchive.create()
|
|
22
|
+
* .format('tar.gz')
|
|
23
|
+
* .compression(9)
|
|
24
|
+
* .entry('config.json', JSON.stringify(config))
|
|
25
|
+
* .directory('./src');
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
8
28
|
export class SmartArchive {
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
static
|
|
16
|
-
|
|
17
|
-
smartArchiveInstance.sourceFilePath = filePathArg;
|
|
18
|
-
return smartArchiveInstance;
|
|
19
|
-
}
|
|
20
|
-
static async fromArchiveStream(streamArg) {
|
|
21
|
-
const smartArchiveInstance = new SmartArchive();
|
|
22
|
-
smartArchiveInstance.sourceStream = streamArg;
|
|
23
|
-
return smartArchiveInstance;
|
|
29
|
+
// ============================================
|
|
30
|
+
// STATIC ENTRY POINT
|
|
31
|
+
// ============================================
|
|
32
|
+
/**
|
|
33
|
+
* Create a new SmartArchive instance for fluent configuration
|
|
34
|
+
*/
|
|
35
|
+
static create() {
|
|
36
|
+
return new SmartArchive();
|
|
24
37
|
}
|
|
25
38
|
constructor() {
|
|
26
|
-
//
|
|
39
|
+
// ============================================
|
|
40
|
+
// TOOLS (public for internal use)
|
|
41
|
+
// ============================================
|
|
27
42
|
this.tarTools = new TarTools();
|
|
28
43
|
this.zipTools = new ZipTools();
|
|
29
44
|
this.gzipTools = new GzipTools();
|
|
30
45
|
this.bzip2Tools = new Bzip2Tools(this);
|
|
31
46
|
this.archiveAnalyzer = new ArchiveAnalyzer(this);
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
|
|
47
|
+
this._compressionLevel = 6;
|
|
48
|
+
this.pendingEntries = [];
|
|
49
|
+
this.pendingDirectories = [];
|
|
50
|
+
// ============================================
|
|
51
|
+
// FLUENT STATE
|
|
52
|
+
// ============================================
|
|
53
|
+
this._mode = null;
|
|
54
|
+
this._filters = [];
|
|
55
|
+
this._excludePatterns = [];
|
|
56
|
+
this._includePatterns = [];
|
|
57
|
+
this._stripComponents = 0;
|
|
58
|
+
this._overwrite = false;
|
|
36
59
|
}
|
|
60
|
+
// ============================================
|
|
61
|
+
// SOURCE METHODS (set extraction mode)
|
|
62
|
+
// ============================================
|
|
37
63
|
/**
|
|
38
|
-
*
|
|
64
|
+
* Load archive from URL
|
|
39
65
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
66
|
+
url(urlArg) {
|
|
67
|
+
this.ensureNotInCreateMode('url');
|
|
68
|
+
this._mode = 'extract';
|
|
69
|
+
this.sourceUrl = urlArg;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Load archive from file path
|
|
74
|
+
*/
|
|
75
|
+
file(pathArg) {
|
|
76
|
+
this.ensureNotInCreateMode('file');
|
|
77
|
+
this._mode = 'extract';
|
|
78
|
+
this.sourceFilePath = pathArg;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Load archive from readable stream
|
|
83
|
+
*/
|
|
84
|
+
stream(streamArg) {
|
|
85
|
+
this.ensureNotInCreateMode('stream');
|
|
86
|
+
this._mode = 'extract';
|
|
87
|
+
this.sourceStream = streamArg;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Load archive from buffer
|
|
92
|
+
*/
|
|
93
|
+
buffer(bufferArg) {
|
|
94
|
+
this.ensureNotInCreateMode('buffer');
|
|
95
|
+
this._mode = 'extract';
|
|
96
|
+
this.sourceStream = plugins.stream.Readable.from(bufferArg);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
// ============================================
|
|
100
|
+
// FORMAT METHODS (set creation mode)
|
|
101
|
+
// ============================================
|
|
102
|
+
/**
|
|
103
|
+
* Set output format for archive creation
|
|
104
|
+
*/
|
|
105
|
+
format(fmt) {
|
|
106
|
+
this.ensureNotInExtractMode('format');
|
|
107
|
+
this._mode = 'create';
|
|
108
|
+
this.creationFormat = fmt;
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Set compression level (0-9)
|
|
113
|
+
*/
|
|
114
|
+
compression(level) {
|
|
115
|
+
this._compressionLevel = level;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
// ============================================
|
|
119
|
+
// CONTENT METHODS (creation mode)
|
|
120
|
+
// ============================================
|
|
121
|
+
/**
|
|
122
|
+
* Add a single file entry to the archive
|
|
123
|
+
*/
|
|
124
|
+
entry(archivePath, content) {
|
|
125
|
+
this.ensureNotInExtractMode('entry');
|
|
126
|
+
if (!this._mode)
|
|
127
|
+
this._mode = 'create';
|
|
128
|
+
this.pendingEntries.push({ archivePath, content });
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Add multiple entries to the archive
|
|
133
|
+
*/
|
|
134
|
+
entries(entriesArg) {
|
|
135
|
+
this.ensureNotInExtractMode('entries');
|
|
136
|
+
if (!this._mode)
|
|
137
|
+
this._mode = 'create';
|
|
138
|
+
for (const e of entriesArg) {
|
|
139
|
+
this.pendingEntries.push({ archivePath: e.archivePath, content: e.content });
|
|
56
140
|
}
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Add an entire directory to the archive (queued, resolved at build time)
|
|
145
|
+
*/
|
|
146
|
+
directory(sourcePath, archiveBase) {
|
|
147
|
+
this.ensureNotInExtractMode('directory');
|
|
148
|
+
if (!this._mode)
|
|
149
|
+
this._mode = 'create';
|
|
150
|
+
this.pendingDirectories.push({ sourcePath, archiveBase });
|
|
151
|
+
return this;
|
|
57
152
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Add a SmartFile to the archive
|
|
155
|
+
*/
|
|
156
|
+
addSmartFile(fileArg, archivePath) {
|
|
157
|
+
this.ensureNotInExtractMode('addSmartFile');
|
|
158
|
+
if (!this._mode)
|
|
159
|
+
this._mode = 'create';
|
|
160
|
+
this.pendingEntries.push({
|
|
161
|
+
archivePath: archivePath || fileArg.relative,
|
|
162
|
+
content: fileArg,
|
|
163
|
+
});
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Add a StreamFile to the archive
|
|
168
|
+
*/
|
|
169
|
+
addStreamFile(fileArg, archivePath) {
|
|
170
|
+
this.ensureNotInExtractMode('addStreamFile');
|
|
171
|
+
if (!this._mode)
|
|
172
|
+
this._mode = 'create';
|
|
173
|
+
this.pendingEntries.push({
|
|
174
|
+
archivePath: archivePath || fileArg.relativeFilePath,
|
|
175
|
+
content: fileArg,
|
|
176
|
+
});
|
|
177
|
+
return this;
|
|
178
|
+
}
|
|
179
|
+
// ============================================
|
|
180
|
+
// FILTER METHODS (both modes)
|
|
181
|
+
// ============================================
|
|
182
|
+
/**
|
|
183
|
+
* Filter entries by predicate function
|
|
184
|
+
*/
|
|
185
|
+
filter(predicate) {
|
|
186
|
+
this._filters.push(predicate);
|
|
187
|
+
return this;
|
|
63
188
|
}
|
|
64
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Include only entries matching the pattern
|
|
191
|
+
*/
|
|
192
|
+
include(pattern) {
|
|
193
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
194
|
+
this._includePatterns.push(regex);
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Exclude entries matching the pattern
|
|
199
|
+
*/
|
|
200
|
+
exclude(pattern) {
|
|
201
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
202
|
+
this._excludePatterns.push(regex);
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
// ============================================
|
|
206
|
+
// EXTRACTION OPTIONS
|
|
207
|
+
// ============================================
|
|
208
|
+
/**
|
|
209
|
+
* Strip N leading path components from extracted files
|
|
210
|
+
*/
|
|
211
|
+
stripComponents(n) {
|
|
212
|
+
this._stripComponents = n;
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Overwrite existing files during extraction
|
|
217
|
+
*/
|
|
218
|
+
overwrite(value = true) {
|
|
219
|
+
this._overwrite = value;
|
|
220
|
+
return this;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Set output filename for single-file archives (gz, bz2)
|
|
224
|
+
*/
|
|
225
|
+
fileName(name) {
|
|
226
|
+
this._fileName = name;
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
// ============================================
|
|
230
|
+
// TERMINAL METHODS - EXTRACTION
|
|
231
|
+
// ============================================
|
|
232
|
+
/**
|
|
233
|
+
* Extract archive to filesystem directory
|
|
234
|
+
*/
|
|
235
|
+
async extract(targetDir) {
|
|
236
|
+
this.ensureExtractionSource();
|
|
65
237
|
const done = plugins.smartpromise.defer();
|
|
66
|
-
const streamFileStream = await this.
|
|
238
|
+
const streamFileStream = await this.toStreamFiles();
|
|
67
239
|
streamFileStream.pipe(new plugins.smartstream.SmartDuplex({
|
|
68
240
|
objectMode: true,
|
|
69
|
-
writeFunction: async (streamFileArg
|
|
70
|
-
const
|
|
71
|
-
console.log(streamFileArg.relativeFilePath
|
|
72
|
-
? streamFileArg.relativeFilePath
|
|
73
|
-
: 'no relative path');
|
|
241
|
+
writeFunction: async (streamFileArg) => {
|
|
242
|
+
const innerDone = plugins.smartpromise.defer();
|
|
74
243
|
const streamFile = streamFileArg;
|
|
244
|
+
let relativePath = streamFile.relativeFilePath || this._fileName || 'extracted_file';
|
|
245
|
+
// Apply stripComponents
|
|
246
|
+
if (this._stripComponents > 0) {
|
|
247
|
+
const parts = relativePath.split('/');
|
|
248
|
+
relativePath = parts.slice(this._stripComponents).join('/');
|
|
249
|
+
if (!relativePath) {
|
|
250
|
+
innerDone.resolve();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Apply filter
|
|
255
|
+
const filterFn = this.buildFilterFunction();
|
|
256
|
+
if (filterFn) {
|
|
257
|
+
const entryInfo = {
|
|
258
|
+
path: relativePath,
|
|
259
|
+
size: 0,
|
|
260
|
+
isDirectory: false,
|
|
261
|
+
isFile: true,
|
|
262
|
+
};
|
|
263
|
+
if (!filterFn(entryInfo)) {
|
|
264
|
+
innerDone.resolve();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
75
268
|
const readStream = await streamFile.createReadStream();
|
|
76
269
|
await plugins.fsPromises.mkdir(targetDir, { recursive: true });
|
|
77
|
-
const writePath = plugins.path.join(targetDir,
|
|
270
|
+
const writePath = plugins.path.join(targetDir, relativePath);
|
|
78
271
|
await plugins.fsPromises.mkdir(plugins.path.dirname(writePath), { recursive: true });
|
|
79
272
|
const writeStream = plugins.fs.createWriteStream(writePath);
|
|
80
273
|
readStream.pipe(writeStream);
|
|
81
274
|
writeStream.on('finish', () => {
|
|
82
|
-
|
|
275
|
+
innerDone.resolve();
|
|
83
276
|
});
|
|
84
|
-
await
|
|
277
|
+
await innerDone.promise;
|
|
85
278
|
},
|
|
86
279
|
finalFunction: async () => {
|
|
87
280
|
done.resolve();
|
|
@@ -89,41 +282,44 @@ export class SmartArchive {
|
|
|
89
282
|
}));
|
|
90
283
|
return done.promise;
|
|
91
284
|
}
|
|
92
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Extract archive to a stream of StreamFile objects
|
|
287
|
+
*/
|
|
288
|
+
async toStreamFiles() {
|
|
289
|
+
this.ensureExtractionSource();
|
|
93
290
|
const streamFileIntake = new plugins.smartstream.StreamIntake({
|
|
94
291
|
objectMode: true,
|
|
95
292
|
});
|
|
96
|
-
|
|
293
|
+
// Guard to prevent multiple signalEnd calls
|
|
294
|
+
let hasSignaledEnd = false;
|
|
295
|
+
const safeSignalEnd = () => {
|
|
296
|
+
if (!hasSignaledEnd) {
|
|
297
|
+
hasSignaledEnd = true;
|
|
298
|
+
streamFileIntake.signalEnd();
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
const archiveStream = await this.getSourceStream();
|
|
97
302
|
const createAnalyzedStream = () => this.archiveAnalyzer.getAnalyzedStream();
|
|
98
|
-
// lets create a function that can be called multiple times to unpack layers of archives
|
|
99
303
|
const createUnpackStream = () => plugins.smartstream.createTransformFunction(async (analyzedResultChunk) => {
|
|
100
304
|
if (analyzedResultChunk.fileType?.mime === 'application/x-tar') {
|
|
101
305
|
const tarStream = analyzedResultChunk.decompressionStream;
|
|
102
306
|
tarStream.on('entry', async (header, stream, next) => {
|
|
103
307
|
if (header.type === 'directory') {
|
|
104
|
-
|
|
105
|
-
stream.resume(); // Consume directory stream
|
|
308
|
+
stream.resume();
|
|
106
309
|
stream.on('end', () => next());
|
|
107
310
|
return;
|
|
108
311
|
}
|
|
109
|
-
console.log(`tar stream file: ${header.name}`);
|
|
110
|
-
// Create a PassThrough stream to buffer the data
|
|
111
312
|
const passThrough = new plugins.stream.PassThrough();
|
|
112
313
|
const streamfile = plugins.smartfile.StreamFile.fromStream(passThrough, header.name);
|
|
113
|
-
// Push the streamfile immediately
|
|
114
314
|
streamFileIntake.push(streamfile);
|
|
115
|
-
// Pipe the tar entry stream to the passthrough
|
|
116
315
|
stream.pipe(passThrough);
|
|
117
|
-
// Move to next entry when this one ends
|
|
118
316
|
stream.on('end', () => {
|
|
119
317
|
passThrough.end();
|
|
120
318
|
next();
|
|
121
319
|
});
|
|
122
320
|
});
|
|
123
|
-
tarStream.on('finish',
|
|
124
|
-
|
|
125
|
-
// Only signal end if this is the final stream
|
|
126
|
-
streamFileIntake.signalEnd();
|
|
321
|
+
tarStream.on('finish', () => {
|
|
322
|
+
safeSignalEnd();
|
|
127
323
|
});
|
|
128
324
|
analyzedResultChunk.resultStream.pipe(analyzedResultChunk.decompressionStream);
|
|
129
325
|
}
|
|
@@ -132,33 +328,410 @@ export class SmartArchive {
|
|
|
132
328
|
.pipe(analyzedResultChunk.decompressionStream)
|
|
133
329
|
.pipe(new plugins.smartstream.SmartDuplex({
|
|
134
330
|
objectMode: true,
|
|
135
|
-
writeFunction: async (streamFileArg
|
|
331
|
+
writeFunction: async (streamFileArg) => {
|
|
136
332
|
streamFileIntake.push(streamFileArg);
|
|
137
333
|
},
|
|
138
334
|
finalFunction: async () => {
|
|
139
|
-
|
|
335
|
+
safeSignalEnd();
|
|
140
336
|
},
|
|
141
337
|
}));
|
|
142
338
|
}
|
|
143
|
-
else if (analyzedResultChunk.isArchive &&
|
|
144
|
-
analyzedResultChunk.decompressionStream) {
|
|
339
|
+
else if (analyzedResultChunk.isArchive && analyzedResultChunk.decompressionStream) {
|
|
145
340
|
// For nested archives (like gzip containing tar)
|
|
146
|
-
|
|
341
|
+
analyzedResultChunk.resultStream
|
|
147
342
|
.pipe(analyzedResultChunk.decompressionStream)
|
|
148
343
|
.pipe(createAnalyzedStream())
|
|
149
344
|
.pipe(createUnpackStream());
|
|
150
|
-
// Don't signal end here - let the nested unpacker handle it
|
|
151
345
|
}
|
|
152
346
|
else {
|
|
153
347
|
const streamFile = plugins.smartfile.StreamFile.fromStream(analyzedResultChunk.resultStream, analyzedResultChunk.fileType?.ext);
|
|
154
348
|
streamFileIntake.push(streamFile);
|
|
155
|
-
|
|
349
|
+
safeSignalEnd();
|
|
156
350
|
}
|
|
157
|
-
}, {
|
|
158
|
-
objectMode: true,
|
|
159
|
-
});
|
|
351
|
+
}, { objectMode: true });
|
|
160
352
|
archiveStream.pipe(createAnalyzedStream()).pipe(createUnpackStream());
|
|
161
353
|
return streamFileIntake;
|
|
162
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Extract archive to an array of SmartFile objects (in-memory)
|
|
357
|
+
*/
|
|
358
|
+
async toSmartFiles() {
|
|
359
|
+
this.ensureExtractionSource();
|
|
360
|
+
const streamFiles = await this.toStreamFiles();
|
|
361
|
+
const smartFiles = [];
|
|
362
|
+
const filterFn = this.buildFilterFunction();
|
|
363
|
+
const pendingConversions = [];
|
|
364
|
+
return new Promise((resolve, reject) => {
|
|
365
|
+
streamFiles.on('data', (streamFile) => {
|
|
366
|
+
// Track all async conversions to ensure they complete before resolving
|
|
367
|
+
const conversion = (async () => {
|
|
368
|
+
try {
|
|
369
|
+
const smartFile = await streamFile.toSmartFile();
|
|
370
|
+
// Apply filter if configured
|
|
371
|
+
if (filterFn) {
|
|
372
|
+
const passes = filterFn({
|
|
373
|
+
path: smartFile.relative,
|
|
374
|
+
size: smartFile.contents.length,
|
|
375
|
+
isDirectory: false,
|
|
376
|
+
isFile: true,
|
|
377
|
+
});
|
|
378
|
+
if (!passes)
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
smartFiles.push(smartFile);
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
reject(err);
|
|
385
|
+
}
|
|
386
|
+
})();
|
|
387
|
+
pendingConversions.push(conversion);
|
|
388
|
+
});
|
|
389
|
+
streamFiles.on('end', async () => {
|
|
390
|
+
// Wait for all conversions to complete before resolving
|
|
391
|
+
await Promise.all(pendingConversions);
|
|
392
|
+
resolve(smartFiles);
|
|
393
|
+
});
|
|
394
|
+
streamFiles.on('error', reject);
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Extract a single file from the archive by path
|
|
399
|
+
*/
|
|
400
|
+
async extractFile(filePath) {
|
|
401
|
+
this.ensureExtractionSource();
|
|
402
|
+
const streamFiles = await this.toStreamFiles();
|
|
403
|
+
return new Promise((resolve, reject) => {
|
|
404
|
+
let found = false;
|
|
405
|
+
streamFiles.on('data', async (streamFile) => {
|
|
406
|
+
if (streamFile.relativeFilePath === filePath || streamFile.relativeFilePath?.endsWith(filePath)) {
|
|
407
|
+
found = true;
|
|
408
|
+
try {
|
|
409
|
+
const smartFile = await streamFile.toSmartFile();
|
|
410
|
+
resolve(smartFile);
|
|
411
|
+
}
|
|
412
|
+
catch (err) {
|
|
413
|
+
reject(err);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
streamFiles.on('end', () => {
|
|
418
|
+
if (!found) {
|
|
419
|
+
resolve(null);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
streamFiles.on('error', reject);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
// ============================================
|
|
426
|
+
// TERMINAL METHODS - OUTPUT
|
|
427
|
+
// ============================================
|
|
428
|
+
/**
|
|
429
|
+
* Build and finalize the archive, returning this instance
|
|
430
|
+
*/
|
|
431
|
+
async build() {
|
|
432
|
+
await this.doBuild();
|
|
433
|
+
return this;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Internal build implementation (avoids thenable recursion)
|
|
437
|
+
*/
|
|
438
|
+
async doBuild() {
|
|
439
|
+
if (this._mode === 'extract') {
|
|
440
|
+
// For extraction mode, nothing to build
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
if (this.archiveBuffer) {
|
|
444
|
+
// Already built
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
// For creation mode, build the archive buffer
|
|
448
|
+
this.ensureCreationFormat();
|
|
449
|
+
await this.resolveDirectories();
|
|
450
|
+
const entries = this.getFilteredEntries();
|
|
451
|
+
if (this.creationFormat === 'tar' || this.creationFormat === 'tar.gz' || this.creationFormat === 'tgz') {
|
|
452
|
+
if (this.creationFormat === 'tar') {
|
|
453
|
+
this.archiveBuffer = await this.tarTools.packFiles(entries);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
this.archiveBuffer = await this.tarTools.packFilesToTarGz(entries, this._compressionLevel);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
else if (this.creationFormat === 'zip') {
|
|
460
|
+
this.archiveBuffer = await this.zipTools.createZip(entries, this._compressionLevel);
|
|
461
|
+
}
|
|
462
|
+
else if (this.creationFormat === 'gz') {
|
|
463
|
+
if (entries.length !== 1) {
|
|
464
|
+
throw new Error('GZIP format only supports a single file');
|
|
465
|
+
}
|
|
466
|
+
let content;
|
|
467
|
+
if (typeof entries[0].content === 'string') {
|
|
468
|
+
content = Buffer.from(entries[0].content);
|
|
469
|
+
}
|
|
470
|
+
else if (Buffer.isBuffer(entries[0].content)) {
|
|
471
|
+
content = entries[0].content;
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
throw new Error('GZIP format requires string or Buffer content');
|
|
475
|
+
}
|
|
476
|
+
this.archiveBuffer = await this.gzipTools.compress(content, this._compressionLevel);
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
throw new Error(`Unsupported format: ${this.creationFormat}`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Build archive and return as Buffer
|
|
484
|
+
*/
|
|
485
|
+
async toBuffer() {
|
|
486
|
+
if (this._mode === 'create' && !this.archiveBuffer) {
|
|
487
|
+
await this.doBuild();
|
|
488
|
+
}
|
|
489
|
+
if (this.archiveBuffer) {
|
|
490
|
+
return this.archiveBuffer;
|
|
491
|
+
}
|
|
492
|
+
// For extraction mode, get the source as buffer
|
|
493
|
+
const stream = await this.getSourceStream();
|
|
494
|
+
return this.streamToBuffer(stream);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Build archive and write to file
|
|
498
|
+
*/
|
|
499
|
+
async toFile(filePath) {
|
|
500
|
+
const buffer = await this.toBuffer();
|
|
501
|
+
await plugins.fsPromises.mkdir(plugins.path.dirname(filePath), { recursive: true });
|
|
502
|
+
await plugins.fsPromises.writeFile(filePath, buffer);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Get archive as a readable stream
|
|
506
|
+
*/
|
|
507
|
+
async toStream() {
|
|
508
|
+
if (this._mode === 'create' && !this.archiveBuffer) {
|
|
509
|
+
await this.doBuild();
|
|
510
|
+
}
|
|
511
|
+
if (this.archiveBuffer) {
|
|
512
|
+
return plugins.stream.Readable.from(this.archiveBuffer);
|
|
513
|
+
}
|
|
514
|
+
return this.getSourceStream();
|
|
515
|
+
}
|
|
516
|
+
// ============================================
|
|
517
|
+
// TERMINAL METHODS - ANALYSIS
|
|
518
|
+
// ============================================
|
|
519
|
+
/**
|
|
520
|
+
* Analyze the archive and return metadata
|
|
521
|
+
*/
|
|
522
|
+
async analyze() {
|
|
523
|
+
this.ensureExtractionSource();
|
|
524
|
+
const stream = await this.getSourceStream();
|
|
525
|
+
const firstChunk = await this.readFirstChunk(stream);
|
|
526
|
+
const fileType = await plugins.fileType.fileTypeFromBuffer(firstChunk);
|
|
527
|
+
let format = null;
|
|
528
|
+
let isCompressed = false;
|
|
529
|
+
let isArchive = false;
|
|
530
|
+
if (fileType) {
|
|
531
|
+
switch (fileType.mime) {
|
|
532
|
+
case 'application/gzip':
|
|
533
|
+
format = 'gz';
|
|
534
|
+
isCompressed = true;
|
|
535
|
+
isArchive = true;
|
|
536
|
+
break;
|
|
537
|
+
case 'application/zip':
|
|
538
|
+
format = 'zip';
|
|
539
|
+
isCompressed = true;
|
|
540
|
+
isArchive = true;
|
|
541
|
+
break;
|
|
542
|
+
case 'application/x-tar':
|
|
543
|
+
format = 'tar';
|
|
544
|
+
isArchive = true;
|
|
545
|
+
break;
|
|
546
|
+
case 'application/x-bzip2':
|
|
547
|
+
format = 'bz2';
|
|
548
|
+
isCompressed = true;
|
|
549
|
+
isArchive = true;
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
format,
|
|
555
|
+
isCompressed,
|
|
556
|
+
isArchive,
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* List all entries in the archive
|
|
561
|
+
*/
|
|
562
|
+
async list() {
|
|
563
|
+
this.ensureExtractionSource();
|
|
564
|
+
const entries = [];
|
|
565
|
+
const streamFiles = await this.toStreamFiles();
|
|
566
|
+
return new Promise((resolve, reject) => {
|
|
567
|
+
streamFiles.on('data', (streamFile) => {
|
|
568
|
+
entries.push({
|
|
569
|
+
path: streamFile.relativeFilePath || 'unknown',
|
|
570
|
+
size: 0, // Size not available without reading
|
|
571
|
+
isDirectory: false,
|
|
572
|
+
isFile: true,
|
|
573
|
+
});
|
|
574
|
+
});
|
|
575
|
+
streamFiles.on('end', () => resolve(entries));
|
|
576
|
+
streamFiles.on('error', reject);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Check if a specific file exists in the archive
|
|
581
|
+
*/
|
|
582
|
+
async hasFile(filePath) {
|
|
583
|
+
this.ensureExtractionSource();
|
|
584
|
+
const entries = await this.list();
|
|
585
|
+
return entries.some((e) => e.path === filePath || e.path.endsWith(filePath));
|
|
586
|
+
}
|
|
587
|
+
// ============================================
|
|
588
|
+
// PRIVATE HELPERS
|
|
589
|
+
// ============================================
|
|
590
|
+
/**
|
|
591
|
+
* Ensure we're not in create mode when calling extraction methods
|
|
592
|
+
*/
|
|
593
|
+
ensureNotInCreateMode(methodName) {
|
|
594
|
+
if (this._mode === 'create') {
|
|
595
|
+
throw new Error(`Cannot call .${methodName}() in creation mode. ` +
|
|
596
|
+
`Use extraction methods (.url(), .file(), .stream(), .buffer()) for extraction mode.`);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Ensure we're not in extract mode when calling creation methods
|
|
601
|
+
*/
|
|
602
|
+
ensureNotInExtractMode(methodName) {
|
|
603
|
+
if (this._mode === 'extract') {
|
|
604
|
+
throw new Error(`Cannot call .${methodName}() in extraction mode. ` +
|
|
605
|
+
`Use .format() for creation mode.`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Ensure an extraction source is configured
|
|
610
|
+
*/
|
|
611
|
+
ensureExtractionSource() {
|
|
612
|
+
if (!this.sourceUrl && !this.sourceFilePath && !this.sourceStream && !this.archiveBuffer) {
|
|
613
|
+
throw new Error('No source configured. Call .url(), .file(), .stream(), or .buffer() first.');
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Ensure a format is configured for creation
|
|
618
|
+
*/
|
|
619
|
+
ensureCreationFormat() {
|
|
620
|
+
if (!this.creationFormat) {
|
|
621
|
+
throw new Error('No format specified. Call .format() before creating archive.');
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Get the source stream
|
|
626
|
+
*/
|
|
627
|
+
async getSourceStream() {
|
|
628
|
+
if (this.archiveBuffer) {
|
|
629
|
+
return plugins.stream.Readable.from(this.archiveBuffer);
|
|
630
|
+
}
|
|
631
|
+
if (this.sourceStream) {
|
|
632
|
+
return this.sourceStream;
|
|
633
|
+
}
|
|
634
|
+
if (this.sourceUrl) {
|
|
635
|
+
const response = await plugins.smartrequest.SmartRequest.create()
|
|
636
|
+
.url(this.sourceUrl)
|
|
637
|
+
.get();
|
|
638
|
+
const webStream = response.stream();
|
|
639
|
+
return plugins.stream.Readable.fromWeb(webStream);
|
|
640
|
+
}
|
|
641
|
+
if (this.sourceFilePath) {
|
|
642
|
+
return plugins.fs.createReadStream(this.sourceFilePath);
|
|
643
|
+
}
|
|
644
|
+
throw new Error('No archive source configured');
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Build a combined filter function from all configured filters
|
|
648
|
+
*/
|
|
649
|
+
buildFilterFunction() {
|
|
650
|
+
const hasFilters = this._filters.length > 0 ||
|
|
651
|
+
this._includePatterns.length > 0 ||
|
|
652
|
+
this._excludePatterns.length > 0;
|
|
653
|
+
if (!hasFilters) {
|
|
654
|
+
return undefined;
|
|
655
|
+
}
|
|
656
|
+
return (entry) => {
|
|
657
|
+
// Check include patterns (if any specified, at least one must match)
|
|
658
|
+
if (this._includePatterns.length > 0) {
|
|
659
|
+
const included = this._includePatterns.some((p) => p.test(entry.path));
|
|
660
|
+
if (!included)
|
|
661
|
+
return false;
|
|
662
|
+
}
|
|
663
|
+
// Check exclude patterns (none must match)
|
|
664
|
+
for (const pattern of this._excludePatterns) {
|
|
665
|
+
if (pattern.test(entry.path))
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
// Check custom filters (all must pass)
|
|
669
|
+
for (const filter of this._filters) {
|
|
670
|
+
if (!filter(entry))
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
return true;
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Resolve pending directories to entries
|
|
678
|
+
*/
|
|
679
|
+
async resolveDirectories() {
|
|
680
|
+
for (const dir of this.pendingDirectories) {
|
|
681
|
+
const files = await plugins.listFileTree(dir.sourcePath, '**/*');
|
|
682
|
+
for (const filePath of files) {
|
|
683
|
+
const archivePath = dir.archiveBase
|
|
684
|
+
? plugins.path.join(dir.archiveBase, filePath)
|
|
685
|
+
: filePath;
|
|
686
|
+
const absolutePath = plugins.path.join(dir.sourcePath, filePath);
|
|
687
|
+
const content = await plugins.fsPromises.readFile(absolutePath);
|
|
688
|
+
this.pendingEntries.push({
|
|
689
|
+
archivePath,
|
|
690
|
+
content,
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
this.pendingDirectories = [];
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Get entries filtered by include/exclude patterns
|
|
698
|
+
*/
|
|
699
|
+
getFilteredEntries() {
|
|
700
|
+
const filterFn = this.buildFilterFunction();
|
|
701
|
+
if (!filterFn) {
|
|
702
|
+
return this.pendingEntries;
|
|
703
|
+
}
|
|
704
|
+
return this.pendingEntries.filter((entry) => filterFn({
|
|
705
|
+
path: entry.archivePath,
|
|
706
|
+
size: 0,
|
|
707
|
+
isDirectory: false,
|
|
708
|
+
isFile: true,
|
|
709
|
+
}));
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Convert a stream to buffer
|
|
713
|
+
*/
|
|
714
|
+
async streamToBuffer(stream) {
|
|
715
|
+
const chunks = [];
|
|
716
|
+
return new Promise((resolve, reject) => {
|
|
717
|
+
stream.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
718
|
+
stream.on('end', () => resolve(Buffer.concat(chunks)));
|
|
719
|
+
stream.on('error', reject);
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Read first chunk from stream
|
|
724
|
+
*/
|
|
725
|
+
async readFirstChunk(stream) {
|
|
726
|
+
return new Promise((resolve, reject) => {
|
|
727
|
+
const onData = (chunk) => {
|
|
728
|
+
stream.removeListener('data', onData);
|
|
729
|
+
stream.removeListener('error', reject);
|
|
730
|
+
resolve(chunk);
|
|
731
|
+
};
|
|
732
|
+
stream.on('data', onData);
|
|
733
|
+
stream.on('error', reject);
|
|
734
|
+
});
|
|
735
|
+
}
|
|
163
736
|
}
|
|
164
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFyY2hpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNtYXJ0YXJjaGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssS0FBSyxNQUFNLFlBQVksQ0FBQztBQUVwQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFakQsT0FBTyxFQUNMLGVBQWUsR0FFaEIsTUFBTSw4QkFBOEIsQ0FBQztBQUl0QyxNQUFNLE9BQU8sWUFBWTtJQUN2QixTQUFTO0lBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBYztRQUMvQyxNQUFNLG9CQUFvQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDaEQsb0JBQW9CLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztRQUN4QyxPQUFPLG9CQUFvQixDQUFDO0lBQzlCLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FDakMsV0FBbUI7UUFFbkIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2hELG9CQUFvQixDQUFDLGNBQWMsR0FBRyxXQUFXLENBQUM7UUFDbEQsT0FBTyxvQkFBb0IsQ0FBQztJQUM5QixDQUFDO0lBRU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FDbkMsU0FHNEI7UUFFNUIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2hELG9CQUFvQixDQUFDLFlBQVksR0FBRyxTQUFTLENBQUM7UUFDOUMsT0FBTyxvQkFB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
|
|
737
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFyY2hpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNtYXJ0YXJjaGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQVV4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDakQsT0FBTyxFQUFFLGVBQWUsRUFBd0IsTUFBTSw4QkFBOEIsQ0FBQztBQVVyRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUN2QiwrQ0FBK0M7SUFDL0MscUJBQXFCO0lBQ3JCLCtDQUErQztJQUUvQzs7T0FFRztJQUNJLE1BQU0sQ0FBQyxNQUFNO1FBQ2xCLE9BQU8sSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBMENEO1FBeENBLCtDQUErQztRQUMvQyxrQ0FBa0M7UUFDbEMsK0NBQStDO1FBRXhDLGFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzFCLGFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzFCLGNBQVMsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzVCLGVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQyxvQkFBZSxHQUFHLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBZ0IzQyxzQkFBaUIsR0FBc0IsQ0FBQyxDQUFDO1FBQ3pDLG1CQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUNyQyx1QkFBa0IsR0FBd0IsRUFBRSxDQUFDO1FBRXJELCtDQUErQztRQUMvQyxlQUFl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
|