Langsung ke konten

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.

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

Berikut cara membuat dan mengupload bundel secara manual tanpa menggunakan Capgo CLI:

Pertama, buat aset web aplikasi Anda:

Terminal window
npm run build

Langkah 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.

Terminal window
npm install adm-zip @tomasklaen/checksum

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 CLI
function 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
};
}
// Usage
async 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;
}
// Usage
async function main() {
const checksum = await calculateChecksum('./my-app-1.2.3.zip');
console.log('Checksum:', checksum);
}
main();

Unggah file zip Anda ke penyimpanan mana pun yang dapat diakses web:

Terminal window
# Example: Upload to your server via scp
scp my-app-1.2.3.zip user@your-server.com:/var/www/bundles/
# Example: Upload to S3 using AWS CLI
aws s3 cp my-app-1.2.3.zip s3://your-bucket/bundles/
# Example: Upload via curl to a custom endpoint
curl -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.zip
  • https://github.com/username/repo/releases/download/v1.2.3/bundle.zip
  • https://cdn.jsdelivr.net/gh/username/repo@v1.2.3/dist.zip

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;
}
ParameterDeskripsiDiperlukan
app_idPengenal aplikasi AndaYa
versionPaket (versi) versi semantik (misalnya, “1.2.3”)Ya
external_urlDapat diakses publik URL HTTPS tempat paket dapat diunduh (tidak diperlukan autentikasi)Ya
checksumChecksum SHA256 dari file zipYa

Zip bundel Anda harus mengikuti persyaratan berikut:

  1. File Indeks Root: Harus memiliki index.html di tingkat root
  2. Capacitor Integrasi: Harus memanggil notifyAppReady() dalam kode aplikasi Anda
  3. Jalur Aset: Gunakan jalur relatif untuk semua aset
bundle.zip
├── index.html
├── assets/
│ ├── app.js
│ └── styles.css
└── images/

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:

Terminal window
npm install adm-zip @tomasklaen/checksum node-fetch

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 matches
async 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;
}
// Usage
async 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 konsisten
2. **Optimasi Penyimpanan**: Hapus bundel yang tidak digunakan secara berkala
3. **Kompatibilitas Paket (versi)**: Tetapkan persyaratan versi asli minimum yang sesuai
4. **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
```typescript
interface 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
}
Terminal window
# Get all bundles
curl -H "authorization: your-api-key" \
"https://api.capgo.app/bundle/?app_id=app_123"
# Get next page
curl -H "authorization: your-api-key" \
"https://api.capgo.app/bundle/?app_id=app_123&page=1"
{
"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.

Untuk menghapus paket tertentu:

interface BundleDelete {
app_id: string
version: string
}

Untuk menghapus semua bundel:

interface BundleDeleteAll {
app_id: string
}
Terminal window
# Delete specific bundle
curl -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 bundles
curl -X DELETE \
-H "authorization: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"app_id": "app_123"
}' \
https://api.capgo.app/bundle/
{
"status": "ok"
}

https://api.capgo.app/bundle/

Buat bundel baru dengan URL eksternal.

interface CreateBundleBody {
app_id: string
version: string
external_url: string // Must be publicly accessible HTTPS URL
checksum: string
}
Terminal window
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/
{
"status": "ok"
}

https://api.capgo.app/bundle/metadata

Perbarui metadata paket seperti informasi tautan dan komentar.

interface UpdateMetadataBody {
app_id: string
version_id: number // bundle (version) id
link?: string
comment?: string
}
Terminal window
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/metadata
{
"status": "success"
}

https://api.capgo.app/bundle/

Tetapkan bundel ke saluran tertentu. Ini menghubungkan bundel (versi) ke saluran distribusi.

interface SetChannelBody {
app_id: string
version_id: number // bundle (version) id
channel_id: number
}
Terminal window
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/
{
"status": "success",
"message": "Bundle 1.0.0 set to channel production"
}

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"
}
  1. Bersihkan Paket Lama (Versi)
// Delete outdated beta bundles (versions)
{
"app_id": "app_123",
"version": "1.0.0-beta.1"
}
  1. Setel Ulang Aplikasi
// Remove all bundles to start fresh
{
"app_id": "app_123"
}
  1. Kebijakan Retensi: Tentukan berapa lama paket lama akan disimpan
  2. Manajemen Ukuran: Memantau ukuran paket dan penggunaan penyimpanan
  3. Strategi Pencadangan: Pertimbangkan untuk mencadangkan paket penting (versi)
  4. Optimasi Biaya: Hapus paket yang tidak diperlukan untuk mengoptimalkan biaya penyimpanan