unzipper-esm
Version:
Unzip cross-platform streaming API
154 lines (141 loc) • 4.77 kB
JavaScript
import fs from 'graceful-fs';
import { PassThrough } from 'stream'; // 'node:stream'
import directory from './directory.js';
export default {
buffer: function(buffer, options) {
const source = {
stream: function(offset, length) {
const stream = new PassThrough();
const end = length ? offset + length : undefined;
stream.end(buffer.slice(offset, end));
return stream;
},
size: function() {
return Promise.resolve(buffer.length);
}
};
return directory(source, options);
},
file: function(filename, options) {
const source = {
stream: function(start, length) {
const end = length ? start + length : undefined;
return fs.createReadStream(filename, {start, end});
},
size: function() {
return new Promise(function(resolve, reject) {
fs.stat(filename, function(err, d) {
if (err)
reject(err);
else
resolve(d.size);
});
});
}
};
return directory(source, options);
},
url: function(request, params, options) {
if (typeof params === 'string')
params = {url: params};
if (!params.url)
throw 'URL missing';
params.headers = params.headers || {};
const source = {
stream : function(offset, length) {
const options = Object.create(params);
const end = length ? offset + length : '';
options.headers = Object.create(params.headers);
options.headers.range = 'bytes='+offset+'-' + end;
return request(options);
},
size: function() {
return new Promise(function(resolve, reject) {
const req = request(params);
req.on('response', function(d) {
req.abort();
if (!d.headers['content-length'])
reject(new Error('Missing content length header'));
else
resolve(d.headers['content-length']);
}).on('error', reject);
});
}
};
return directory(source, options);
},
s3 : function(client, params, options) {
const source = {
size: function() {
return new Promise(function(resolve, reject) {
client.headObject(params, function(err, d) {
if (err)
reject(err);
else
resolve(d.ContentLength);
});
});
},
stream: function(offset, length) {
const d = {};
for (const key in params)
d[key] = params[key];
const end = length ? offset + length : '';
d.Range = 'bytes='+offset+'-' + end;
return client.getObject(d).createReadStream();
}
};
return directory(source, options);
},
s3_v3: function (client, params, options) {
// `GetObjectCommand` and `HeadObjectCommand` from "@aws-sdk/client-s3" package
// are not included in the distribution by default. The authors said:
//
// "To keep node-unzipper super small, a decision was made to not include optional
// third party sdks as a part of the library itself. unzipper has plenty of users
// that do not require the s3 features and it would be very inefficient to force them to do so".
//
const { GetObjectCommand, HeadObjectCommand } = global;
if (!GetObjectCommand || !HeadObjectCommand) {
// throw new Error('AWS S3 v3 support should be exported separately. See: https://github.com/ZJONSSON/node-unzipper/issues/330');
throw new Error('You must set `global.GetObjectCommand` and `global.HeadObjectCommand` variables first');
}
const source = {
size: async () => {
const head = await client.send(
new HeadObjectCommand({
Bucket: params.Bucket,
Key: params.Key,
})
);
if(!head.ContentLength) {
return 0;
}
return head.ContentLength;
},
stream: (offset, length) => {
const stream = new PassThrough();
const end = length ? offset + length : "";
client
.send(
new GetObjectCommand({
Bucket: params.Bucket,
Key: params.Key,
Range: `bytes=${offset}-${end}`,
})
)
.then((response) => {
response.Body.pipe(stream);
})
.catch((error) => {
stream.emit("error", error);
});
return stream;
},
};
return directory(source, options);
},
custom: function(source, options) {
return directory(source, options);
}
};