mirror of
https://github.com/saltbo/zpan.git
synced 2026-09-24 23:22:31 +08:00
fix(s3): replace DeleteObjectsCommand with per-key deletes for CF Workers compat
DeleteObjectsCommand returns XML that requires DOMParser to parse, but Cloudflare Workers doesn't have DOMParser. Use parallel deleteObject calls instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
bce4da3ebf
commit
e2ab579773
@@ -204,17 +204,11 @@ describe('S3Service', () => {
|
||||
})
|
||||
|
||||
describe('deleteObjects', () => {
|
||||
it('sends DeleteObjectsCommand with keys', async () => {
|
||||
mockSend.mockResolvedValueOnce({ $metadata: {} })
|
||||
it('sends individual DeleteObjectCommand for each key', async () => {
|
||||
mockSend.mockResolvedValue({ $metadata: {} })
|
||||
await service.deleteObjects(storage, ['a.jpg', 'b.jpg'])
|
||||
expect(mockSend).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
input: {
|
||||
Bucket: 'my-bucket',
|
||||
Delete: { Objects: [{ Key: 'a.jpg' }, { Key: 'b.jpg' }] },
|
||||
},
|
||||
}),
|
||||
)
|
||||
expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({ input: { Bucket: 'my-bucket', Key: 'a.jpg' } }))
|
||||
expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({ input: { Bucket: 'my-bucket', Key: 'b.jpg' } }))
|
||||
})
|
||||
|
||||
it('skips API call for empty keys array', async () => {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
CopyObjectCommand,
|
||||
DeleteObjectCommand,
|
||||
DeleteObjectsCommand,
|
||||
GetObjectCommand,
|
||||
HeadObjectCommand,
|
||||
PutObjectCommand,
|
||||
@@ -89,12 +88,8 @@ export class S3Service {
|
||||
|
||||
async deleteObjects(storage: Storage, keys: string[]): Promise<void> {
|
||||
if (keys.length === 0) return
|
||||
const client = this.createClient(storage)
|
||||
await client.send(
|
||||
new DeleteObjectsCommand({
|
||||
Bucket: storage.bucket,
|
||||
Delete: { Objects: keys.map((Key) => ({ Key })) },
|
||||
}),
|
||||
)
|
||||
// DeleteObjectsCommand returns XML which requires DOMParser to parse.
|
||||
// Cloudflare Workers doesn't have DOMParser, so we delete one-by-one.
|
||||
await Promise.all(keys.map((key) => this.deleteObject(storage, key)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user