async function cleanS3Bucket (bucketName) {
  const result = await s3.listObjectsV2({
    Bucket: bucketName,
    ExpectedBucketOwner: process.env.SourceAccount
  }).promise()

  console.log(`result: ${inspectStringify(result)}`)
  const keys = result.Contents.map((obj) => {
    console.log(`obj: ${inspectStringify(obj)}`)
    return { Key: obj.Key }
  })

  if (keys.length) {
    console.log(`Attempting to delete ${keys.length} objects. The first one in the list is: ${keys[0].Key}`)
    const result = await s3.deleteObjects({
      Bucket: bucketName,
      Delete: {
        Objects: keys
      },
      ExpectedBucketOwner: process.env.SourceAccount
    }).promise()
    console.log(`deleteObjects result: ${inspectStringify(result)}`)
  }
}
Deletes all the objects in an S3 bucket. This is useful because the bucket must be empty (zero objects) before it
can be deleted by CFN. So, when the custom resource receives a DELETE request from CFN, it first deletes all the
files in the S3 bucket, then tells CFN that the deletion succeeded, at which point CFN deletes the now-empty bucket.
This is safe to use on both empty and non-empty buckets.

@param bucketName the name of the bucket to be cleaned
@returns {Promise.<Object>|undefined} the object returned by the S3 SDK or, if the bucket was empty, undefined