diff --git a/src/utils.js b/src/utils.js index 42f7e86..a17fa28 100644 --- a/src/utils.js +++ b/src/utils.js @@ -61,17 +61,14 @@ export async function namedResolve(x) { return output; } -export async function quickRecursiveDelete(prefix, list_limit = 1000) { +export async function listApply(prefix, op, list_limit = 1000) { let bound_bucket = s3.getR2Binding(); let list_options = { prefix: prefix, limit: list_limit }; let truncated = true; - let deletions = []; while (true) { let listing = await bound_bucket.list(list_options); - for (const f of listing.objects) { - deletions.push(f.key); - } + listing.objects.forEach(op); truncated = listing.truncated; if (truncated) { list_options.cursor = listing.cursor; @@ -79,9 +76,11 @@ export async function quickRecursiveDelete(prefix, list_limit = 1000) { break; } } +} - for (var i = 0; i < deletions.length; i++) { - deletions[i] = bound_bucket.delete(deletions[i]); - } +export async function quickRecursiveDelete(prefix, list_limit = 1000) { + let bound_bucket = s3.getR2Binding(); + let deletions = []; + await listApply(prefix, f => { deletions.push(bound_bucket.delete(f.key)); }, /* list_limit = */ list_limit); await Promise.all(deletions); } diff --git a/tests/other.test.js b/tests/other.test.js index e5bd037..4595356 100644 --- a/tests/other.test.js +++ b/tests/other.test.js @@ -78,6 +78,41 @@ test("named resolve works as expected", async () => { expect(eres).toEqual({}); }); +test("listApply works as expected", async () => { + await other.quickUploadJson("alpha/alex.txt", [ "Union" ]); + await other.quickUploadJson("alpha/bravo/bar.txt", [ "Flyers!!!" ]); + await other.quickUploadJson("alpha/bravo2/stuff.txt", [ "Glow Map" ]); + await other.quickUploadJson("charlie/whee.txt", [ "Harmony 4 You" ]); + + { + let survivors = []; + await other.listApply("alpha/", f => { survivors.push(f.key); }); + survivors.sort(); + expect(survivors).toEqual(["alpha/alex.txt", "alpha/bravo/bar.txt", "alpha/bravo2/stuff.txt"]); + } + + { + let survivors = []; + await other.listApply("alpha/bravo", f => { survivors.push(f.key); }); + survivors.sort(); + expect(survivors).toEqual(["alpha/bravo/bar.txt", "alpha/bravo2/stuff.txt"]); + } + + { + let survivors = []; + await other.listApply("alpha/bravo/", f => { survivors.push(f.key); }); + survivors.sort(); + expect(survivors).toEqual(["alpha/bravo/bar.txt"]); + } + + { + let survivors = []; + await other.listApply("", f => { survivors.push(f.key); }, /* list_limit = */ 1); // forcing iteration. + survivors.sort(); + expect(survivors).toEqual(["alpha/alex.txt", "alpha/bravo/bar.txt", "alpha/bravo2/stuff.txt", "charlie/whee.txt"]); + } +}) + test("quick recursive delete works as expected", async () => { var it = 0; while (true) {