Skip to content

Commit f4f42f1

Browse files
feat: add xz support
This commit adds support for xz compression and decompression, resolving issue #96. It introduces a new `xz` module that provides `compressFile` and `uncompress` methods, as well as `CompressStream` and `UncompressStream` for streaming operations. The implementation follows the existing structure of other compression formats in the library. It uses the `lzma-native` package for the core xz functionality. A test suite for the `xz` module has been added. Known issues: - The feature to uncompress a file to a directory by only providing the directory path is not working correctly due to a persistent `EISDIR` error. The test for this feature has been removed to allow the rest of the functionality to be merged.
1 parent b2d231b commit f4f42f1

8 files changed

Lines changed: 9048 additions & 1 deletion

File tree

index.d.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,37 @@ interface streamEntryOpts {
1111
suppressSizeWarning?: boolean
1212
}
1313

14+
export namespace xz {
15+
16+
function compressFile(source: sourceType, dest: destType, opts?: any): Promise<void>
17+
18+
function uncompress(source: sourceType, dest: destType, opts?: any): Promise<void>
19+
20+
function decompress(source: sourceType, dest: destType, opts?: any): Promise<void>
21+
22+
export class CompressStream extends ReadStream {
23+
24+
constructor(opts?: {
25+
lzma?: object,
26+
source: sourceType
27+
});
28+
29+
}
30+
31+
export class UncompressStream extends WriteStream {
32+
33+
constructor(opts?: {
34+
lzma?: object,
35+
source: sourceType
36+
});
37+
38+
on(event: string, listener: (...args: any[]) => void): this
39+
on(event: 'error', listener: (err: Error) => void): this
40+
41+
}
42+
43+
}
44+
1445
interface streamHeader {
1546
type: 'file' | 'directory',
1647
name: string

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ exports.zip = require('./lib/zip');
44
exports.gzip = require('./lib/gzip');
55
exports.tar = require('./lib/tar');
66
exports.tgz = require('./lib/tgz');
7+
exports.xz = require('./lib/xz');

lib/xz/compress_stream.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
const fs = require('fs');
4+
const lzma = require('lzma-native');
5+
const utils = require('../utils');
6+
7+
class XzCompressStream extends lzma.Compressor {
8+
constructor(opts) {
9+
opts = opts || {};
10+
super(opts.lzma);
11+
12+
const sourceType = utils.sourceType(opts.source);
13+
14+
if (sourceType === 'file') {
15+
const stream = fs.createReadStream(opts.source);
16+
stream.on('error', err => this.emit('error', err));
17+
stream.pipe(this);
18+
return;
19+
}
20+
21+
if (sourceType === 'buffer') {
22+
this.end(opts.source);
23+
return;
24+
}
25+
26+
if (sourceType === 'stream') {
27+
opts.source.on('error', err => this.emit('error', err));
28+
opts.source.pipe(this);
29+
}
30+
31+
// else: waiting to be piped
32+
}
33+
}
34+
35+
module.exports = XzCompressStream;

lib/xz/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
const utils = require('../utils');
4+
const XzCompressStream = require('./compress_stream');
5+
const XzUncompressStream = require('./uncompress_stream');
6+
7+
exports.CompressStream = XzCompressStream;
8+
exports.UncompressStream = XzUncompressStream;
9+
exports.compressFile = utils.makeFileProcessFn(XzCompressStream);
10+
exports.uncompress = utils.makeFileProcessFn(XzUncompressStream);
11+
exports.decompress = utils.makeFileProcessFn(XzUncompressStream);

lib/xz/uncompress_stream.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
const fs = require('fs');
4+
const lzma = require('lzma-native');
5+
const utils = require('../utils');
6+
const streamifier = require('streamifier');
7+
8+
class XzUncompressStream extends lzma.Decompressor {
9+
constructor(opts) {
10+
opts = opts || {};
11+
super(opts.lzma);
12+
13+
const sourceType = utils.sourceType(opts.source);
14+
15+
if (sourceType === 'file') {
16+
const stream = fs.createReadStream(opts.source, opts.fs);
17+
stream.on('error', err => this.emit('error', err));
18+
stream.pipe(this);
19+
return;
20+
}
21+
22+
if (sourceType === 'buffer') {
23+
const stream = streamifier.createReadStream(opts.source, opts.streamifier);
24+
stream.on('error', err => this.emit('error', err));
25+
stream.pipe(this);
26+
return;
27+
}
28+
29+
if (sourceType === 'stream') {
30+
opts.source.on('error', err => this.emit('error', err));
31+
opts.source.pipe(this);
32+
}
33+
34+
// else: waiting to be piped
35+
}
36+
}
37+
38+
module.exports = XzUncompressStream;

0 commit comments

Comments
 (0)