A simple receiver for Skipper that writes Upstreams to
S3 to the configured bucket at the configured path.

@param  {Dictionary} s3ClientOpts
@property {String} fd
@property {String} bucket
etc…
@return {Receiver} (a writable stream)
function S3Receiver (s3ClientOpts) {
      s3ClientOpts = s3ClientOpts || {};
      s3ClientOpts = _.extend({}, globalOpts, s3ClientOpts);

      var wasMaxBytesPerUpstreamQuotaExceeded;
      var wasMaxBytesPerFileQuotaExceeded;
      var maxBytesPerUpstream = s3ClientOpts.maxBytes || undefined;
      var maxBytesPerFile = s3ClientOpts.maxBytesPerFile || undefined;

      var receiver = Writable({ objectMode: true });
      receiver.once('error', (unusedErr)=>{
        // console.log('ERROR ON receiver ::', unusedErr);
      });//œ

      var bytesWrittenByFd = {};

      // console.log('constructed receiver');
      receiver._write = (incomingFileStream, encoding, proceed)=>{
        // console.log('uploading file w/ skipperFd', incomingFileStream.skipperFd);

        // Check for `.skipperFd` (or if not present, `.fd`, for backwards compatibility)
        if (!_.isString(incomingFileStream.skipperFd) || incomingFileStream.skipperFd === '') {
          if (!_.isString(incomingFileStream.fd) || incomingFileStream.fd === '') {
            return proceed(new Error('In skipper-s3: Incoming file stream does not have the expected `.skipperFd` or `.fd` properties-- at least not as a valid string.  If you are using sails-hook-uploads or skipper directly, this should have been automatically attached!  Here is what we got for `.fd` (legacy property): `'+incomingFileStream.fd+'`.  And here is what we got for `.skipperFd` (new property): `'+incomingFileStream.skipperFd+'`'));
          } else {
            // Backwards compatibility:
            incomingFileStream.skipperFd = incomingFileStream.fd;
          }
        }//ﬁ

        var incomingFd = incomingFileStream.skipperFd;
        bytesWrittenByFd[incomingFd] = 0;//« bytes written for this file so far
        incomingFileStream.once('error', (unusedErr)=>{
          // console.log('ERROR ON incoming readable file stream in Skipper S3 adapter (%s) ::', incomingFileStream.filename, unusedErr);
        });//œ
        _uploadFile(incomingFd, incomingFileStream, (progressInfo)=>{
          bytesWrittenByFd[incomingFd] = progressInfo.written;
          incomingFileStream.byteCount = progressInfo.written;//« used by Skipper core
          let totalBytesWrittenForThisUpstream = 0;
          for (let fd in bytesWrittenByFd) {
            totalBytesWrittenForThisUpstream += bytesWrittenByFd[fd];
          }//∞
          // console.log('maxBytesPerUpstream',maxBytesPerUpstream);
          // console.log('bytesWrittenByFd',bytesWrittenByFd);
          // console.log('totalBytesWrittenForThisUpstream',totalBytesWrittenForThisUpstream);
          if (maxBytesPerUpstream && totalBytesWrittenForThisUpstream > maxBytesPerUpstream) {
            wasMaxBytesPerUpstreamQuotaExceeded = true;
            return false;
          } else if (maxBytesPerFile && bytesWrittenByFd[incomingFd] > maxBytesPerFile) {
            wasMaxBytesPerFileQuotaExceeded = true;
            return false;
          } else {
            if (s3ClientOpts.onProgress) {
              s3ClientOpts.onProgress(progressInfo);
            } else {
              receiver.emit('progress', progressInfo);// « for backwards compatibility
            }
            return true;
          }
        }, s3ClientOpts, (err)=>{
          if (err) {
            // console.log(('Receiver: Error writing `' + incomingFileStream.filename + '`:: ' + require('util').inspect(err) + ' :: Cancelling upload and cleaning up already-written bytes...').red);
            if (flaverr.taste({name: 'RequestAbortedError'}, err)) {
              if (maxBytesPerUpstream && wasMaxBytesPerUpstreamQuotaExceeded) {
                err = flaverr({code: 'E_EXCEEDS_UPLOAD_LIMIT'}, new Error(`Upload too big!  Exceeded quota ("maxBytes": ${maxBytesPerUpstream})`));
              } else if (maxBytesPerFile && wasMaxBytesPerFileQuotaExceeded) {
                err = flaverr({code: 'E_EXCEEDS_FILE_SIZE_LIMIT'}, new Error(`One of the attempted file uploads was too big!  Exceeded quota ("maxBytesPerFile": ${maxBytesPerFile})`));
              }//ﬁ
            }//ﬁ
            receiver.emit('error', err);
          } else {
            incomingFileStream.byteCount = bytesWrittenByFd[incomingFd];//« used by Skipper core
            receiver.emit('writefile', incomingFileStream);
            return proceed();
          }
        });//_∏_
      };//ƒ

      return receiver;
    }