Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 143ea15

Browse files
committed
Support R2Bucket#list() startAfter option
Note this is returning slightly different, but still correct, results to the real implementation. This is due a restriction of Miniflare's storage abstraction, see the comment in `list()` for more details. We're planning to replace this very soon though, so this shouldn't be a problem for long.
1 parent c154dc3 commit 143ea15

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

packages/tre/src/plugins/r2/gateway.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,26 @@ export class R2Gateway {
139139
async list(listOptions: R2ListOptions = {}): Promise<R2Objects> {
140140
validate.limit(listOptions.limit);
141141

142-
const { prefix = "", include = [], cursor = "" } = listOptions;
142+
const { prefix = "", include = [], cursor = "", startAfter } = listOptions;
143143
let { delimiter, limit = MAX_LIST_KEYS } = listOptions;
144144
if (delimiter === "") delimiter = undefined;
145145

146-
// if include contains inputs, we reduce the limit to max 100
146+
// If include contains inputs, we reduce the limit to max 100
147147
if (include.length > 0) limit = Math.min(limit, 100);
148148

149+
// If startAfter is set, we should increment the limit here, as `startAfter`
150+
// is exclusive, but we're using inclusive `start` to implement it.
151+
// Ideally we want to return `limit` number of keys here. However, doing
152+
// this would be incompatible with the returned opaque `cursor`. Luckily,
153+
// the R2 list contract allows us to return less than `limit` keys, as
154+
// long as we set `truncated: true`. We'll fix this behaviour when we switch
155+
// to the new storage system.
149156
const res = await this.storage.list<R2ObjectMetadata>({
150157
prefix,
151158
limit,
152159
cursor,
153160
delimiter,
161+
start: startAfter,
154162
});
155163
const delimitedPrefixes = new Set(res.delimitedPrefixes ?? []);
156164

@@ -169,6 +177,11 @@ export class R2Gateway {
169177
return new R2Object(metadata);
170178
});
171179

180+
if (startAfter !== undefined && objects[0]?.key === startAfter) {
181+
// If the first key matched `startAfter`, remove it as this is exclusive
182+
objects.splice(0, 1);
183+
}
184+
172185
const cursorLength = res.cursor.length > 0;
173186
return {
174187
objects,

0 commit comments

Comments
 (0)