( keys: string[], context: StorageContext )
| 468 | * share `context`. Idempotent on missing keys. |
| 469 | */ |
| 470 | export async function deleteFiles( |
| 471 | keys: string[], |
| 472 | context: StorageContext |
| 473 | ): Promise<{ deleted: number; failed: Array<{ key: string; error: string }> }> { |
| 474 | if (keys.length === 0) return { deleted: 0, failed: [] } |
| 475 | |
| 476 | const config = getStorageConfig(context) |
| 477 | |
| 478 | if (USE_S3_STORAGE) { |
| 479 | const { deleteManyFromS3 } = await import('@/lib/uploads/providers/s3/client') |
| 480 | const { failed } = await deleteManyFromS3(keys, createS3Config(config)) |
| 481 | return { deleted: keys.length - failed.length, failed } |
| 482 | } |
| 483 | |
| 484 | const failed: Array<{ key: string; error: string }> = [] |
| 485 | let cursor = 0 |
| 486 | const runWorker = async (): Promise<void> => { |
| 487 | while (cursor < keys.length) { |
| 488 | const idx = cursor++ |
| 489 | const key = keys[idx] |
| 490 | try { |
| 491 | await deleteFile({ key, context }) |
| 492 | } catch (error) { |
| 493 | failed.push({ key, error: getErrorMessage(error) }) |
| 494 | } |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | const workerCount = Math.min(PER_FILE_DELETE_CONCURRENCY, keys.length) |
| 499 | await Promise.all(Array.from({ length: workerCount }, runWorker)) |
| 500 | |
| 501 | return { deleted: keys.length - failed.length, failed } |
| 502 | } |
| 503 | |
| 504 | /** |
| 505 | * Check whether an object exists in the configured cloud storage provider. |
nothing calls this directly
no test coverage detected