Skip to content

Instantly share code, notes, and snippets.

@loretoparisi
Last active July 6, 2022 18:12
Show Gist options
  • Save loretoparisi/3994ff64d1181572d6ae1855862e0816 to your computer and use it in GitHub Desktop.
Save loretoparisi/3994ff64d1181572d6ae1855862e0816 to your computer and use it in GitHub Desktop.
NodeJS JavaScript AWS S3 getObject, putObject, deleteObject with async await and recursive approach for nested S3 folders
async function getObjectAsync(bucket, key) {
try {
const data = await s3
.getObject({ Bucket: bucket, Key: key })
.promise();
var contents = data.Body.toString('utf-8');
return contents;
} catch (err) {
console.log(err);
}
}//getObjectAsync
async function putObjectAsync(value, bucket, key) {
try {
var extras = {
Bucket: bucket,
Key: key
};
extras.Body = value; // set object as it is
const data = await s3
.putObject(extras)
.promise();
return data;
} catch (err) {
console.log(err);
}
}//putObjectAsync
async function deleteObjectAsync(bucket, key) {
try {
var extras = {
Bucket: bucket,
Key: key
};
const data = await s3
.deleteObject(extras)
.promise();
return data;
} catch (err) {
console.log(err);
}
}//deleteObjectAsync
async function deleteVersionedObjectAsync(bucket, key) {
var params = {
Bucket: bucket,
Key: key
};
var data = await s3.deleteObject(params).promise();
if (!Util.empty(data) &&
data.DeleteMarker &&
!Util.empty(data.VersionId)) { // object version to delete
var VersionId = data.VersionId, res;
// The bucket is versioned - https://docs.aws.amazon.com/AmazonS3/latest/dev/DeleteMarker.html
// { "DeleteMarker": true, "VersionId": "azW0.aiZyTSQzjwFe0YkIkGyL.JXJK8y" }
console.log("delete key:%s version:%s", params.Key, VersionId);
var params = {
Bucket: params.Bucket,
Key: params.Key,
VersionId: VersionId
};
res = await s3.deleteObject(params).promise();
var params = {
Bucket: params.Bucket,
Key: params.Key,
// LP: see https://stackoverflow.com/questions/67423667/aws-nodejs-sdk-cannot-delete-object
VersionId: 'null'
};
res = await s3.deleteObject(params).promise();
return res;
}
return data;
}//deleteVersionedObjectAsync
async function deleteObjectFolderAsync(bucket, prefix) {
var params = {
Bucket: bucket,
Prefix: prefix
};
const data = await s3.listObjects(params).promise();
if (data && data.Contents.length == 0) { // empty folder
var res = await s3.deleteObject(params).promise();
return res;
}
params = { Bucket: bucket };
params.Delete = { Objects: [] };
data.Contents.forEach(function (content) {
params.Delete.Objects.push({
Key: content.Key,
// LP: see https://stackoverflow.com/questions/67423667/aws-nodejs-sdk-cannot-delete-object
VersionId: 'null'
});
});
var res = await s3.deleteObjects(params).promise();
return res;
}//deleteObjectFolderAsync
async function deleteObjectFolderRecursiveAsync(bucket, path) {
var getDirectoryPrefixes = async (bucket, path) => {
const prefixes = [];
const promises = [];
const listParams = {
Bucket: bucket,
Prefix: path
};
const listedObjects = await s3
.listObjectsV2(listParams)
.promise();
if (
listedObjects.Contents.length > 0 ||
listedObjects.CommonPrefixes.length > 0
) {
listedObjects.Contents.forEach(({ Key }) => {
prefixes.push({ Key });
});
listedObjects.CommonPrefixes.forEach(({ Prefix }) => {
prefixes.push({ Key: Prefix });
promises.push(getDirectoryPrefixes(Prefix));
});
}
const subPrefixes = await Promise.all(promises);
subPrefixes.map(arrPrefixes => {
arrPrefixes.map(prefix => {
prefixes.push(prefix);
});
});
return prefixes;
}//getDirectoryPrefixes
const prefixes = await getDirectoryPrefixes(bucket, path);
if (prefixes.length > 0) {
const deleteParams = {
Bucket: bucket,
Delete: { Objects: prefixes }
};
return s3.deleteObjects(deleteParams).promise();
}
return s3
.deleteObject({
Bucket: bucket,
Key: path
})
.promise();
}//deleteObjectFolderRecursiveAsync
@loretoparisi
Copy link
Author

To use in a for loop, please use the for...of

(async () => {
    for(key of keys) {
       const contents = await getObjectAsync(bucket, key);
       var jsonObj=JSON.parse(contents);
       jsonObj.bar='foo';
       const new_contents = JSON.stringify(jsonObj);
       const result = await putObjectAsync(bucket, new_key);
    }
})();

To use in a callback, please make the callback async:

myEventEmitter.on('myEvent', async (value) => {
     const contents = await getObjectAsync(bucket, key);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment