Skip to content

Commit f83cab7

Browse files
authored
Add internal route to count the number of objects in a bucket (#48)
1 parent a6c49bc commit f83cab7

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/routes/internal.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,53 @@ describe('/internal Routes', () => {
113113
expect(list.objects.length).toBe(0);
114114
});
115115
});
116+
117+
describe('/internal/count-objects route', () => {
118+
beforeEach(() => {
119+
workerEnv = getMiniflareBindings();
120+
ctx = new ExecutionContext();
121+
});
122+
123+
afterEach(() => {
124+
vi.restoreAllMocks();
125+
});
126+
127+
test('should return the number of objects in R2 when bucket is empty', async () => {
128+
const request = new Request('http://localhost/internal/count-objects', {
129+
method: 'GET',
130+
headers: {
131+
'Content-Type': 'application/json',
132+
Authorization: `Bearer ${workerEnv.TURBO_TOKEN}`,
133+
},
134+
});
135+
const response = await app.fetch(request, workerEnv, ctx);
136+
expect(response.status).toBe(200);
137+
expect(await response.json()).toEqual({ count: 0 });
138+
});
139+
140+
test('should return the number of objects in R2 when bucket is not empty', async () => {
141+
await workerEnv.R2_STORE.put('key', 'value');
142+
const request = new Request('http://localhost/internal/count-objects', {
143+
method: 'GET',
144+
headers: {
145+
'Content-Type': 'application/json',
146+
Authorization: `Bearer ${workerEnv.TURBO_TOKEN}`,
147+
},
148+
});
149+
const response = await app.fetch(request, workerEnv, ctx);
150+
expect(response.status).toBe(200);
151+
expect(await response.json()).toEqual({ count: 1 });
152+
});
153+
154+
test('should return 401 if no auth token is provided', async () => {
155+
const request = new Request('http://localhost/internal/count-objects', {
156+
method: 'GET',
157+
headers: {
158+
'Content-Type': 'application/json',
159+
},
160+
});
161+
const response = await app.fetch(request, workerEnv, ctx);
162+
expect(response.status).toBe(401);
163+
});
164+
});
116165
});

src/routes/internal.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,18 @@ internalRouter.post(
4848
return c.json({ success: true });
4949
}
5050
);
51+
52+
internalRouter.get('/count-objects', async (c) => {
53+
let truncated = false;
54+
let cursor: string | undefined;
55+
let list: R2Objects;
56+
let count = 0;
57+
do {
58+
list = await c.env.R2_STORE.list({ limit: 999, cursor });
59+
truncated = list.truncated;
60+
cursor = list.truncated ? list.cursor : undefined;
61+
count += list.objects.length;
62+
} while (truncated);
63+
64+
return c.json({ count });
65+
});

0 commit comments

Comments
 (0)