Folders that aren't
S3 stores objects — any bytes — under keys in a bucket, with 11 nines of durability. There are no real folders: photos/2026/a.jpg is just a key containing slashes. Listing with a prefix and a delimiter makes the console *look* like folders.
Listing like S3
function createBucket() {
const objects = new Map();
return {
put(key, body) {
objects.set(key, { body: String(body), size: new TextEncoder().encode(String(body)).length });
},
get(key) {
if (!objects.has(key)) throw new Error("NoSuchKey");
return objects.get(key).body;
},
delete(key) {
objects.delete(key);
},
list({ prefix = "", delimiter, maxKeys = 1000, startAfter = "" } = {}) {
const keys = [...objects.keys()].filter((k) => k.startsWith(prefix) && k > startAfter).sort();
const contents = [];
const prefixes = new Set();
for (const key of keys) {
const rest = key.slice(prefix.length);
const cut = delimiter ? rest.indexOf(delimiter) : -1;
if (cut >= 0) prefixes.add(prefix + rest.slice(0, cut + delimiter.length)); // a "folder"
else contents.push({ key, size: objects.get(key).size });
}
return { contents: contents.slice(0, maxKeys), commonPrefixes: [...prefixes], isTruncated: contents.length > maxKeys };
},
};
}