File size: 5,534 Bytes
19d10a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9879cf
 
19d10a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import dotenv from 'dotenv';
// Load root .env first
dotenv.config({ path: '/Volumes/sms/edtech/.env' });

const { R2_ACCOUNT_ID, R2_BUCKET, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_PUBLIC_URL } = process.env;

// ── Fast fail: show config status first ──────────────────────────────────────
console.log('\nπŸ“‹ R2 Config Check:');
console.log(`   R2_ACCOUNT_ID:       ${R2_ACCOUNT_ID ? 'βœ… ' + R2_ACCOUNT_ID : '❌ MISSING'}`);
console.log(`   R2_BUCKET:           ${R2_BUCKET ? 'βœ… ' + R2_BUCKET : '❌ MISSING'}`);
console.log(`   R2_ACCESS_KEY_ID:    ${R2_ACCESS_KEY_ID ? 'βœ… SET' : '❌ MISSING'}`);
console.log(`   R2_SECRET_ACCESS_KEY:${R2_SECRET_ACCESS_KEY ? 'βœ… SET' : '❌ MISSING'}`);
console.log(`   R2_PUBLIC_URL:       ${R2_PUBLIC_URL ? 'βœ… ' + R2_PUBLIC_URL : '❌ MISSING'}`);

if (!R2_ACCOUNT_ID || !R2_BUCKET || !R2_ACCESS_KEY_ID || !R2_SECRET_ACCESS_KEY || !R2_PUBLIC_URL) {
    console.error('\n❌ Missing R2 credentials. Add these to /Volumes/sms/edtech/.env:');
    console.error('\n   R2_ACCOUNT_ID=<your_cloudflare_account_id>');
    console.error('   R2_BUCKET=<your_bucket_name>');
    console.error('   R2_ACCESS_KEY_ID=<your_r2_api_token_key_id>');
    console.error('   R2_SECRET_ACCESS_KEY=<your_r2_api_token_secret>');
    console.error('   R2_PUBLIC_URL=https://r2.xamle.sn');
    console.error('\n   Find them on: dash.cloudflare.com β†’ R2 β†’ Manage R2 API Tokens');
    process.exit(1);
}

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import fs from 'fs';
import path from 'path';

const ARTIFACTS_DIR = '/Users/macbookair/.gemini/antigravity/brain/ea618d02-1ee0-47c1-a2b7-aed00a3604bc';

const IMAGE_MAP = [
    { src: 'xaml_t1_j1_activity_1772065123770.png', dest: 'images/t1/bes1_activity.png' },
    { src: 'xaml_t1_j1_5_remediation_1772065225648.png', dest: 'images/t1/bes1_5_remediation.png' },
    { src: 'xaml_t1_j2_customer_1772065290030.png', dest: 'images/t1/bes2_customer.png' },
    { src: 'xaml_t1_j3_problem_1772065392345.png', dest: 'images/t1/bes3_problem.png' },
    { src: 'xaml_t1_j4_solution_1772065519438.png', dest: 'images/t1/bes4_solution.png' },
    { src: 'xaml_t1_j5_differentiation_v2_1772065582075.png', dest: 'images/t1/bes5_differentiation.png' },
    { src: 'xaml_t1_j6_pricing_v2_1772065655264.png', dest: 'images/t1/bes6_pricing.png' },
    { src: 'xaml_t1_j7_channel_sales_v2_1772065752541.png', dest: 'images/t1/bes7_channel.png' },
    { src: 'xaml_t1_j8_trust_1772065782385.png', dest: 'images/t1/bes8_trust.png' },
    { src: 'xaml_t1_j9_pitch_1772065807317.png', dest: 'images/t1/bes9_pitch.png' },
    { src: 'xaml_t1_j10_objections_1772065830459.png', dest: 'images/t1/bes10_objections.png' },
    { src: 'xaml_t1_j11_plan_1772065894417.png', dest: 'images/t1/bes11_plan.png' },
    { src: 'xaml_t1_j12_success_1772065982976.png', dest: 'images/t1/bes12_success.png' },
];

async function main() {
    const { R2_ACCOUNT_ID, R2_BUCKET, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_PUBLIC_URL } = process.env;

    console.log('πŸ“‹ R2 Config Check:');
    console.log('   R2_ACCOUNT_ID:', R2_ACCOUNT_ID ? 'βœ… SET' : '❌ MISSING');
    console.log('   R2_BUCKET:', R2_BUCKET ? `βœ… ${R2_BUCKET}` : '❌ MISSING');
    console.log('   R2_ACCESS_KEY_ID:', R2_ACCESS_KEY_ID ? 'βœ… SET' : '❌ MISSING');
    console.log('   R2_SECRET_ACCESS_KEY:', R2_SECRET_ACCESS_KEY ? 'βœ… SET' : '❌ MISSING');
    console.log('   R2_PUBLIC_URL:', R2_PUBLIC_URL || '❌ MISSING');

    if (!R2_ACCOUNT_ID || !R2_BUCKET || !R2_ACCESS_KEY_ID || !R2_SECRET_ACCESS_KEY) {
        console.error('\n❌ Missing R2 environment variables. Stopping.');
        process.exit(1);
    }

    const client = new S3Client({
        region: 'auto',
        endpoint: `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
        credentials: { accessKeyId: R2_ACCESS_KEY_ID, secretAccessKey: R2_SECRET_ACCESS_KEY },
    });

    console.log('\nπŸš€ Uploading 13 T1 images to R2...\n');
    let ok = 0, failed = 0;

    for (const { src, dest } of IMAGE_MAP) {
        const srcPath = path.join(ARTIFACTS_DIR, src);

        if (!fs.existsSync(srcPath)) {
            console.warn(`⚠️  Not found: ${src}`);
            failed++;
            continue;
        }

        try {
            const buf = fs.readFileSync(srcPath);
            await client.send(new PutObjectCommand({
                Bucket: R2_BUCKET,
                Key: dest,
                Body: buf,
                ContentType: 'image/png',
                CacheControl: 'public, max-age=31536000',
            }));
            const publicUrl = `${(R2_PUBLIC_URL || '').replace(/\/$/, '')}/${dest}`;
            console.log(`βœ… ${dest}`);
            console.log(`   URL: ${publicUrl}`);
            ok++;
        } catch (e: unknown) {
            console.error(`❌ ${dest}: ${(e instanceof Error ? (e instanceof Error ? e.message : String(e)) : String(e))}`);
            failed++;
        }
    }

    console.log(`\n── RΓ‰SULTAT ────────────────────`);
    console.log(`βœ… Uploaded: ${ok}/${IMAGE_MAP.length}`);
    if (failed > 0) {
        console.log(`❌ Failed:   ${failed}`);
        process.exit(1);
    } else {
        console.log(`\nπŸŽ‰ Toutes les images T1 sont maintenant sur R2 !`);
        console.log(`   Les leΓ§ons WhatsApp du module T1 afficheront bien les images.`);
    }
}

main().catch(e => { console.error(e); process.exit(1); });