/ opencodehub / scripts / empty-r3-bucket.cjs
swadhinbiswas feat: OpenCodeHub v1.1.0 - Enterprise Features & Storage Adapters Β· 2/15/2026
719a1cb
98 lines Β· 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
 * Empty R3 Bucket Script
 * 
 * This script deletes ALL objects from the R3 bucket to start fresh.
 * Use with caution!
 * 
 * Usage: node scripts/empty-r3-bucket.cjs
 */

const { S3Client, ListObjectsV2Command, DeleteObjectsCommand } = require('@aws-sdk/client-s3');
const fs = require('fs');
const path = require('path');

// Load .env file manually
const envPath = path.join(__dirname, '..', '.env');
const envFile = fs.readFileSync(envPath, 'utf8');
envFile.split('\n').forEach(line => {
    const match = line.match(/^([^#=]+)=(.*)$/);
    if (match) {
        const key = match[1].trim();
        const value = match[2].trim().replace(/^["']|["']$/g, '');
        process.env[key] = value;
    }
});

const client = new S3Client({
    region: process.env.STORAGE_REGION || 'auto',
    endpoint: process.env.STORAGE_ENDPOINT,
    credentials: {
        accessKeyId: process.env.STORAGE_ACCESS_KEY_ID,
        secretAccessKey: process.env.STORAGE_SECRET_ACCESS_KEY,
    },
    forcePathStyle: true,
});

const BUCKET = process.env.STORAGE_BUCKET;

async function emptyBucket() {
    console.log(`πŸ—‘οΈ  Emptying bucket: ${BUCKET}\n`);

    let totalDeleted = 0;
    let continuationToken;

    do {
        // List objects
        const listCommand = new ListObjectsV2Command({
            Bucket: BUCKET,
            ContinuationToken: continuationToken,
            MaxKeys: 1000,
        });

        const listResponse = await client.send(listCommand);

        if (!listResponse.Contents || listResponse.Contents.length === 0) {
            console.log('No more objects to delete.');
            break;
        }

        console.log(`Found ${listResponse.Contents.length} objects to delete...`);

        // Delete objects in batches
        const objectsToDelete = listResponse.Contents.map(obj => ({ Key: obj.Key }));

        const deleteCommand = new DeleteObjectsCommand({
            Bucket: BUCKET,
            Delete: {
                Objects: objectsToDelete,
                Quiet: false,
            },
        });

        const deleteResponse = await client.send(deleteCommand);

        const deleted = deleteResponse.Deleted?.length || 0;
        totalDeleted += deleted;

        console.log(`βœ… Deleted ${deleted} objects`);

        if (deleteResponse.Errors && deleteResponse.Errors.length > 0) {
            console.error('❌ Errors during deletion:');
            deleteResponse.Errors.forEach(err => {
                console.error(`  - ${err.Key}: ${err.Message}`);
            });
        }

        continuationToken = listResponse.NextContinuationToken;

    } while (continuationToken);

    console.log(`\nβœ… Total objects deleted: ${totalDeleted}`);
    console.log('πŸŽ‰ Bucket is now empty!');
}

emptyBucket().catch(err => {
    console.error('❌ Error emptying bucket:', err);
    process.exit(1);
});