Bundles
Bundel adalah paket pembaruan inti di Capgo. Setiap paket berisi aset web (HTML, CSS, JS) yang membentuk konten aplikasi Anda. Bundel API memungkinkan Anda mengelola paket pembaruan ini, termasuk membuat daftar dan menghapusnya.
Pengertian Bundel
Section titled “Pengertian Bundel”Paket mewakili paket (versi) tertentu dari konten web aplikasi Anda dan mencakup:
- Bundle (versi): Nomor versi semantik untuk bundel
- Checksum: Hash unik untuk memverifikasi integritas bundel
- Info Penyimpanan: Detail tentang di mana dan bagaimana bundel disimpan
- Persyaratan Asli: Persyaratan versi aplikasi asli minimum
- Metadata: Waktu pembuatan, kepemilikan, dan informasi pelacakan lainnya
Pembuatan Bundel Manual (Tanpa CLI)
Section titled “Pembuatan Bundel Manual (Tanpa CLI)”Berikut cara membuat dan mengupload bundel secara manual tanpa menggunakan Capgo CLI:
Langkah 1: Bangun Aplikasi Anda
Section titled “Langkah 1: Bangun Aplikasi Anda”Pertama, buat aset web aplikasi Anda:
npm run buildLangkah 2: Buat Bundel Zip Menggunakan Paket yang Sama seperti Capgo CLI
Section titled “Langkah 2: Buat Bundel Zip Menggunakan Paket yang Sama seperti Capgo CLI”Penting: Gunakan paket JavaScript yang sama persis dengan yang Capgo CLI gunakan secara internal untuk memastikan kompatibilitas.
Instal Paket yang Diperlukan
Section titled “Instal Paket yang Diperlukan”npm install adm-zip @tomasklaen/checksumBuat Paket Zip dengan JavaScript (Sama seperti Capgo CLI)
Section titled “Buat Paket Zip dengan JavaScript (Sama seperti Capgo CLI)”Catatan: Pada contoh di bawah, version mengacu pada nama bundel (versi) yang digunakan oleh API.
const fs = require('node:fs');const path = require('node:path');const os = require('node:os');const AdmZip = require('adm-zip');const { checksum: getChecksum } = require('@tomasklaen/checksum');
// Exact same implementation as Capgo CLIfunction zipFileUnix(filePath) { const zip = new AdmZip(); zip.addLocalFolder(filePath); return zip.toBuffer();}
async function zipFileWindows(filePath) { console.log('Zipping file windows mode'); const zip = new AdmZip();
const addToZip = (folderPath, zipPath) => { const items = fs.readdirSync(folderPath);
for (const item of items) { const itemPath = path.join(folderPath, item); const stats = fs.statSync(itemPath);
if (stats.isFile()) { const fileContent = fs.readFileSync(itemPath); zip.addFile(path.join(zipPath, item).split(path.sep).join('/'), fileContent); } else if (stats.isDirectory()) { addToZip(itemPath, path.join(zipPath, item)); } } };
addToZip(filePath, ''); return zip.toBuffer();}
// Main zipFile function (exact same logic as CLI)async function zipFile(filePath) { if (os.platform() === 'win32') { return zipFileWindows(filePath); } else { return zipFileUnix(filePath); }}
async function createBundle(inputPath, outputPath, version) { // Create zip using exact same method as Capgo CLI const zipped = await zipFile(inputPath);
// Write to file fs.writeFileSync(outputPath, zipped);
// Calculate checksum using exact same package as CLI const checksum = await getChecksum(zipped, 'sha256');
return { filename: path.basename(outputPath), version: version, size: zipped.length, checksum: checksum };}
// Usageasync function main() { try { const result = await createBundle('./dist', './my-app-1.2.3.zip', '1.2.3'); console.log('Bundle info:', JSON.stringify(result, null, 2)); } catch (error) { console.error('Error creating bundle:', error); }}
main();Langkah 3: Hitung Checksum SHA256 Menggunakan Paket yang Sama seperti CLI
Section titled “Langkah 3: Hitung Checksum SHA256 Menggunakan Paket yang Sama seperti CLI”const fs = require('node:fs');const { checksum: getChecksum } = require('@tomasklaen/checksum');
async function calculateChecksum(filePath) { const fileBuffer = fs.readFileSync(filePath); // Use exact same package and method as Capgo CLI const checksum = await getChecksum(fileBuffer, 'sha256'); return checksum;}
// Usageasync function main() { const checksum = await calculateChecksum('./my-app-1.2.3.zip'); console.log('Checksum:', checksum);}
main();Langkah 4: Unggah Paket ke Penyimpanan Anda
Section titled “Langkah 4: Unggah Paket ke Penyimpanan Anda”Unggah file zip Anda ke penyimpanan mana pun yang dapat diakses web:
# Example: Upload to your server via scpscp my-app-1.2.3.zip user@your-server.com:/var/www/bundles/
# Example: Upload to S3 using AWS CLIaws s3 cp my-app-1.2.3.zip s3://your-bucket/bundles/
# Example: Upload via curl to a custom endpointcurl -X POST https://your-storage-api.com/upload \ -H "Authorization: Bearer YOUR_TOKEN" \ -F "file=@my-app-1.2.3.zip"Penting: Paket Anda harus dapat diakses publik melalui URL HTTPS (tidak diperlukan autentikasi). Server Capgo perlu mengunduh bundel dari URL ini.
Contoh URL publik yang valid:
https://your-storage.com/bundles/my-app-1.2.3.ziphttps://github.com/username/repo/releases/download/v1.2.3/bundle.ziphttps://cdn.jsdelivr.net/gh/username/repo@v1.2.3/dist.zip
Langkah 5: Daftarkan Paket dengan Capgo API
Section titled “Langkah 5: Daftarkan Paket dengan Capgo API”Daftarkan paket eksternal dengan Capgo menggunakan panggilan langsung API:
async function registerWithCapgo(appId, version, bundleUrl, checksum, apiKey) { const fetch = require('node-fetch');
// Create bundle (version) const response = await fetch('https://api.capgo.app/bundle/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'authorization': apiKey }, body: JSON.stringify({ app_id: appId, version: version, external_url: bundleUrl, checksum: checksum }) });
if (!response.ok) { throw new Error(`Failed to create bundle: ${response.statusText}`); }
const data = await response.json(); console.log('Bundle created:', data);
return data;}API Parameter
Section titled “API Parameter”| Parameter | Deskripsi | Diperlukan |
|---|---|---|
app_id | Pengenal aplikasi Anda | Ya |
version | Paket (versi) versi semantik (misalnya, “1.2.3”) | Ya |
external_url | Dapat diakses publik URL HTTPS tempat paket dapat diunduh (tidak diperlukan autentikasi) | Ya |
checksum | Checksum SHA256 dari file zip | Ya |
Persyaratan Struktur Bundel
Section titled “Persyaratan Struktur Bundel”Zip bundel Anda harus mengikuti persyaratan berikut:
- File Indeks Root: Harus memiliki
index.htmldi tingkat root - Capacitor Integrasi: Harus memanggil
notifyAppReady()dalam kode aplikasi Anda - Jalur Aset: Gunakan jalur relatif untuk semua aset
Struktur Paket yang Valid
Section titled “Struktur Paket yang Valid”bundle.zip├── index.html├── assets/│ ├── app.js│ └── styles.css└── images/Contoh Alur Kerja Manual Lengkap
Section titled “Contoh Alur Kerja Manual Lengkap”Skrip Node.js sederhana untuk di-zip, checksum, dan diunggah ke Capgo:
const fs = require('node:fs');const os = require('node:os');const AdmZip = require('adm-zip');const { checksum: getChecksum } = require('@tomasklaen/checksum');const fetch = require('node-fetch');
async function deployToCapgo() { const APP_ID = 'com.example.app'; const VERSION = '1.2.3'; const BUNDLE_URL = 'https://your-storage.com/bundles/app-1.2.3.zip'; const API_KEY = process.env.CAPGO_API_KEY;
// 1. Create zip (same as Capgo CLI) const zip = new AdmZip(); zip.addLocalFolder('./dist'); const zipped = zip.toBuffer();
// 2. Calculate checksum (same as Capgo CLI) const checksum = await getChecksum(zipped, 'sha256'); console.log('Checksum:', checksum);
// 3. Upload to your storage (replace with your upload logic) // fs.writeFileSync('./bundle.zip', zipped); // ... upload bundle.zip to your storage ...
// 4. Register with Capgo API const response = await fetch('https://api.capgo.app/bundle/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'authorization': API_KEY }, body: JSON.stringify({ app_id: APP_ID, version: VERSION, external_url: BUNDLE_URL, checksum: checksum }) });
if (!response.ok) { throw new Error(`Failed: ${response.statusText}`); }
console.log('Bundle registered with Capgo!');}
deployToCapgo().catch(console.error);Instal dependensi:
npm install adm-zip @tomasklaen/checksum node-fetchVerifikasi Checksum
Section titled “Verifikasi Checksum”JavaScript Perhitungan Checksum (Sama seperti Capgo CLI)
Section titled “JavaScript Perhitungan Checksum (Sama seperti Capgo CLI)”Gunakan paket dan metode yang sama persis dengan yang digunakan Capgo CLI secara internal:
const fs = require('node:fs');const { checksum: getChecksum } = require('@tomasklaen/checksum');
async function calculateChecksum(filePath) { const fileBuffer = fs.readFileSync(filePath); // Use exact same package and method as Capgo CLI const checksum = await getChecksum(fileBuffer, 'sha256'); return checksum;}
// Verify checksum matchesasync function verifyChecksum(filePath, expectedChecksum) { const actualChecksum = await calculateChecksum(filePath); const isValid = actualChecksum === expectedChecksum;
console.log(`File: ${filePath}`); console.log(`Expected: ${expectedChecksum}`); console.log(`Actual: ${actualChecksum}`); console.log(`Valid: ${isValid}`);
return isValid;}
// Usageasync function main() { const bundleChecksum = await calculateChecksum('./my-app-1.2.3.zip'); console.log('SHA256 Checksum:', bundleChecksum);}
main();```### Pentingnya Checksum
- **Integritas Paket**: Memastikan paket tidak rusak selama transfer- **API Verifikasi**: Capgo memverifikasi checksum sebelum menerima paket- **Verifikasi Plugin**: Plugin seluler memverifikasi checksum sebelum menerapkan pembaruan
## Praktik Terbaik
1. **Manajemen Paket (versi)**: Gunakan pembuatan versi semantik secara konsisten2. **Optimasi Penyimpanan**: Hapus bundel yang tidak digunakan secara berkala3. **Kompatibilitas Paket (versi)**: Tetapkan persyaratan versi asli minimum yang sesuai4. **Strategi Pencadangan**: Pertahankan cadangan paket penting (versi)
## Titik akhir
### DAPATKAN
`https://api.capgo.app/bundle/`
Ambil informasi bundel. Mengembalikan 50 bundel per halaman.
#### Parameter Kueri- `app_id`: Wajib. ID aplikasi Anda- `page`: Opsional. Nomor halaman untuk penomoran halaman
#### Jenis Respons
```typescriptinterface Bundle { app_id: string bucket_id: string | null checksum: string | null created_at: string | null deleted: boolean external_url: string | null id: number minUpdateVersion: string | null name: string native_packages: Json[] | null owner_org: string r2_path: string | null session_key: string | null storage_provider: string updated_at: string | null user_id: string | null}Contoh Permintaan
Section titled “Contoh Permintaan”# Get all bundlescurl -H "authorization: your-api-key" \ "https://api.capgo.app/bundle/?app_id=app_123"
# Get next pagecurl -H "authorization: your-api-key" \ "https://api.capgo.app/bundle/?app_id=app_123&page=1"Contoh Respon
Section titled “Contoh Respon”{ "data": [ { "id": 1, "app_id": "app_123", "name": "1.0.0", "checksum": "abc123...", "minUpdateVersion": "1.0.0", "storage_provider": "r2", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "deleted": false, "owner_org": "org_123", "user_id": "user_123" } ]}https://api.capgo.app/bundle/
Hapus satu atau semua paket untuk suatu aplikasi. Gunakan dengan hati-hati karena tindakan ini tidak dapat dibatalkan.
Parameter Kueri
Section titled “Parameter Kueri”Untuk menghapus paket tertentu:
interface BundleDelete { app_id: string version: string}Untuk menghapus semua bundel:
interface BundleDeleteAll { app_id: string}Contoh Permintaan
Section titled “Contoh Permintaan”# Delete specific bundlecurl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "version": "1.0.0" }' \ https://api.capgo.app/bundle/
# Delete all bundlescurl -X DELETE \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123" }' \ https://api.capgo.app/bundle/Respon Sukses
Section titled “Respon Sukses”{ "status": "ok"}POSTINGAN
Section titled “POSTINGAN”https://api.capgo.app/bundle/
Buat bundel baru dengan URL eksternal.
Isi Permintaan
Section titled “Isi Permintaan”interface CreateBundleBody { app_id: string version: string external_url: string // Must be publicly accessible HTTPS URL checksum: string}Contoh Permintaan
Section titled “Contoh Permintaan”curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "com.example.app", "version": "1.2.3", "external_url": "https://your-storage.com/bundles/app-1.2.3.zip", "checksum": "a1b2c3d4e5f6789abcdef123456789abcdef123456789abcdef123456789abcd" }' \ https://api.capgo.app/bundle/Respon Sukses
Section titled “Respon Sukses”{ "status": "ok"}POSTINGAN (Metadata)
Section titled “POSTINGAN (Metadata)”https://api.capgo.app/bundle/metadata
Perbarui metadata paket seperti informasi tautan dan komentar.
Isi Permintaan
Section titled “Isi Permintaan”interface UpdateMetadataBody { app_id: string version_id: number // bundle (version) id link?: string comment?: string}Contoh Permintaan
Section titled “Contoh Permintaan”curl -X POST \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "version_id": 456, "link": "https://github.com/myorg/myapp/releases/tag/v1.0.0", "comment": "Fixed critical bug in authentication" }' \ https://api.capgo.app/bundle/metadataRespon Sukses
Section titled “Respon Sukses”{ "status": "success"}MASUKKAN
Section titled “MASUKKAN”https://api.capgo.app/bundle/
Tetapkan bundel ke saluran tertentu. Ini menghubungkan bundel (versi) ke saluran distribusi.
Isi Permintaan
Section titled “Isi Permintaan”interface SetChannelBody { app_id: string version_id: number // bundle (version) id channel_id: number}Contoh Permintaan
Section titled “Contoh Permintaan”curl -X PUT \ -H "authorization: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "app_id": "app_123", "version_id": 456, "channel_id": 789 }' \ https://api.capgo.app/bundle/Respon Sukses
Section titled “Respon Sukses”{ "status": "success", "message": "Bundle 1.0.0 set to channel production"}Penanganan Kesalahan
Section titled “Penanganan Kesalahan”Skenario kesalahan umum dan tanggapannya:
// Bundle not found{ "error": "Bundle not found", "status": "KO"}
// Invalid bundle (version) format{ "error": "Invalid version format", "status": "KO"}
// Storage error{ "error": "Failed to delete bundle from storage", "status": "KO"}
// Permission denied{ "error": "Insufficient permissions to manage bundles", "status": "KO"}Kasus Penggunaan Umum
Section titled “Kasus Penggunaan Umum”- Bersihkan Paket Lama (Versi)
// Delete outdated beta bundles (versions){ "app_id": "app_123", "version": "1.0.0-beta.1"}- Setel Ulang Aplikasi
// Remove all bundles to start fresh{ "app_id": "app_123"}Pertimbangan Penyimpanan
Section titled “Pertimbangan Penyimpanan”- Kebijakan Retensi: Tentukan berapa lama paket lama akan disimpan
- Manajemen Ukuran: Memantau ukuran paket dan penggunaan penyimpanan
- Strategi Pencadangan: Pertimbangkan untuk mencadangkan paket penting (versi)
- Optimasi Biaya: Hapus paket yang tidak diperlukan untuk mengoptimalkan biaya penyimpanan