node-unzipper icon indicating copy to clipboard operation
node-unzipper copied to clipboard

Feature request: support for `aws-sdk` v3

Open neverendingqs opened this issue 4 years ago • 4 comments
trafficstars

The S3 client for v3 of the SDK signature has changed when trying to create a read stream.

The signature has changed so that instead of https://github.com/ZJONSSON/node-unzipper/blob/7f83183d4475abeaaa9251d3511c840647bca788/lib/Open/index.js#L86-L92, it would have to look something like

stream: function(offset,length) { 
  var d = {}; 
  for (var key in params) 
    d[key] = params[key]; 
  d.Range = 'bytes='+offset+'-' + (length ? length : ''); 
  return new Promise(function(resolve,reject) {
    client.getObject(d, function(err, data) {
      if (err)
        reject(err);
      else
        resolve(data.Body);
    });
 });
}

, although it's unclear how to distinguish between a v2 client and a v3 client and if the caller would be happy with a Promise being returned instead of the stream directly.

If a v3 client is passed in, the following error is thrown in the current version of unzipper:

ERROR TypeError: client.getObject(...).createReadStream is not a function

neverendingqs avatar Jun 14 '21 16:06 neverendingqs

Any updates on this issue?

openwebsolns avatar May 02 '23 18:05 openwebsolns

AFAIK the getObject method of SDK v3 does not support the 'synchronous' way of creating stream; the response.Body is available asynchronously (via callback/promise). Should the support will be implemented, some refactoring of existing code will be required. This may involve some breaking changes, unfortunately, with node v8.

CMIIW, the SDK v3 also bumps the minimum supported node version to v10

alvin-nt avatar May 10 '23 06:05 alvin-nt

I have created PR https://github.com/ZJONSSON/node-unzipper/pull/277. Please check if any changes are required.

Suggestions for test scripts are welcome, since I have yet to figure out how to implement one.

alvin-nt avatar May 10 '23 07:05 alvin-nt

Workaround I did that worked:

const directory = await unzipper.Open.custom({
    async size() {
        const info = await s3.send(
            new HeadObjectCommand({
                Bucket: bucket,
                Key: key,
            }),
        );

        return info.ContentLength;
    },

    stream(offset, length) {
        const stream = new PassThrough();

        s3.send(
            new GetObjectCommand({
                Bucket: bucket,
                Key: key,
                Range: `bytes=${offset}-${length ?? ""}`,
            }),
        )
            .then((response) => {
                response.Body.pipe(stream);
             })
            .catch((error) => {
                stream.emit("error", error);
            });

        return stream;
     },
});

Sljux avatar Mar 18 '24 14:03 Sljux