Les bundles
Copiez un prompt de configuration incluant les étapes d'installation et le guide markdown complet pour ce plugin.
Les bundles sont les packages de mise à jour centraux de Capgo. Chaque bundle contient les assets web (HTML, CSS, JS) qui constituent le contenu de votre application. L'API des bundles vous permet de gérer ces packages, notamment en les listant ou en les supprimant.
Comprendre les bundles
Section intitulée « Comprendre les bundles »Un bundle représente une version spécifique du contenu web de votre application et comprend :
- Bundle (version): Numéro de version sémantique pour le bundle
- Checksum: Hash unique pour vérifier l'intégrité du bundle
- Infos de stockage: Détails sur l'emplacement et la méthode de stockage du bundle
- Prérequis natifs: Exigences minimales de version de l'application native
- Métadonnées: Heure de création, propriétaire et autres infos de suivi
Création manuelle d'un bundle (sans CLI)
Section intitulée « Création manuelle de bundle (sans CLI) »Voici comment créer et envoyer des bundles manuellement sans utiliser le CLI Capgo :
Étape 1 : Compiler votre application
Étape 1 : Compilez votre applicationFirst, build your app’s web assets:
npm run buildÉtape 2 : Créer le zip du bundle avec les mêmes packages que Capgo CLI
Étape 2 : Créez le zip du bundle avec les mêmes packages que Capgo CLIImportant: Utilisez exactement les mêmes packages JavaScript que Capgo CLI utilise en interne pour garantir la compatibilité.
Installer les packages requis
Section intitulée « Installer les packages requis »npm install adm-zip @tomasklaen/checksumCréer un bundle Zip avec JavaScript (identique à Capgo CLI)
Section intitulée « Créer un bundle Zip avec JavaScript (identique à Capgo CLI) »Note : dans les exemples ci-dessous, version fait référence au nom du bundle (version) utilisé par 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();Étape 3 : Calculer le checksum SHA256 avec le même package que CLI
Section intitulée « Étape 3 : Calculer le checksum SHA256 avec le même package que 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();Étape 4 : Envoyer le bundle vers votre stockage
Section intitulée « Étape 4 : Envoyer le bundle vers votre stockage »Upload your zip file to any web-accessible storage:
# 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"Important: votre bundle doit être accessible publiquement via une URL HTTPS (sans authentification). Les serveurs de Capgo doivent pouvoir télécharger le bundle depuis cette URL.
Exemples d'URL publiques valides :
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
Étape 5 : Enregistrer le bundle auprès de Capgo API
Section intitulée « Étape 5 : Enregistrer le bundle auprès de Capgo via API »Enregistrez le bundle externe auprès de Capgo via des appels API directs :
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;}Paramètres API
Section intitulée « Paramètres API »| Paramètre | Description | Requis |
|---|---|---|
app_id | L'identifiant de votre application | Oui |
version | Bundle (version) Version sémantique (ex. : « 1.2.3 ») | Oui |
external_url | Accessible publiquement URL HTTPS pour télécharger le bundle (sans authentification) | Oui |
checksum | Checksum SHA256 du fichier zip | Oui |
Structure requise du bundle
Section intitulée « Exigences de structure du bundle »Votre zip de bundle doit respecter ces exigences :
- Fichier index à la racine: Doit être présent
index.htmlau niveau racine - Intégration Capacitor: Doit appeler
notifyAppReady()dans votre application code - Chemins des assets: Utilisez des chemins relatifs pour tous les assets
Structure valide du bundle
Section intitulée « Structure de bundle valide »bundle.zip├── index.html├── assets/│ ├── app.js│ └── styles.css└── images/Exemple de workflow manuel complet
Section intitulée « Exemple de workflow manuel complet »Script Node.js simple pour zipper, calculer le checksum et envoyer vers 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);Installer les dépendances :
npm install adm-zip @tomasklaen/checksum node-fetchVérification du checksum
Section intitulée « Vérification du checksum »Calcul du checksum JavaScript (identique à Capgo CLI)
Section intitulée « Calcul du checksum JavaScript (identique à Capgo CLI) »Utilisez exactement le même package et la même méthode que Capgo CLI utilise en interne :
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();Importance du checksum
Section intitulée « Importance du checksum »- Intégrité du bundle: Garantit que le bundle n'a pas été corrompu pendant le transfert
- Vérification API: Capgo vérifie les checksums avant d'accepter les bundles
- Vérification du plugin: Le plugin mobile vérifie les checksums avant d'appliquer les mises à jour
Bonnes pratiques
Section intitulée « Bonnes pratiques »- Gestion des bundles (versions) : Utilisez versionnage sémantique consistently
- Optimisation du stockage: Supprimez périodiquement les bundles inutilisés
- Compatibilité des bundles (versions): Définissez les exigences minimales de version native appropriées
- Stratégie de sauvegarde: Maintenez des sauvegardes de vos bundles critiques (versions)
Endpoints
Section intitulée « Endpoints »https://api.capgo.app/bundle/
Récupère les informations du bundle. Sans filtres, retourne 50 bundles par page. Avec version ou id, retourne le même format de tableau JSON avec zéro ou un bundle.
Paramètres de requête
Section intitulée « Paramètres de requête »app_id: Requis. L'ID de votre applicationpage: Optionnel. Numéro de page pour la pagination (ignoré quandversionouidest définie)version: Optionnel. Nom exact de la version du bundle (app_versions.name, par exemple1.2.3"). Renvoie un tableau JSON contenant zéro ou un élément.id: Optionnel. ID numérique du bundle (app_versions.id"). Renvoie un tableau JSON contenant zéro ou un élément.
Utilisez le même authorization header et le même scoping d'application via la clé API que la liste paginée. Les valeurs rejetées par la validation du query-schema renvoient une invalid_query erreur.
Vérifier si une version existe (CI)
Section intitulée « Vérifier si une version existe (CI) »Utilisez ceci avant l'upload ou l'assignation d'un canal si vous avez besoin d'une vérification HTTP plutôt que du CLI :
curl -H "authorization: YOUR_API_KEY" \ "https://api.capgo.app/bundle/?app_id=com.example.app&version=1.2.3"Un tableau JSON non vide signifie que cette version existe déjà pour l'app. Un tableau vide signifie qu'elle n'existe pas.
Pour les workflows d'upload, le flag Capgo CLI bundle upload --version-exists-ok renvoie déjà un succès si la version cible existe, ce qui évite d'appeler cet endpoint pour de nombreux jobs CI.
Type de réponse
Section intitulée « Type de réponse »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}Exemple de requête
Section intitulée « Exemple de requête »# 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"
# Look up one bundle by version namecurl -H "authorization: your-api-key" \ "https://api.capgo.app/bundle/?app_id=app_123&version=1.0.0"
# Look up one bundle by idcurl -H "authorization: your-api-key" \ "https://api.capgo.app/bundle/?app_id=app_123&id=456"Exemple de réponse
Section intitulée « Exemple de réponse »[ { "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" }]Supprimer
Section intitulée « DELETE »https://api.capgo.app/bundle/
Supprimez un ou tous les bundles d'une application. Utilisez cette action avec prudence, car elle est irréversible.
Paramètres de requête
Section intitulée « Paramètres de requête »Pour supprimer un bundle spécifique :
interface BundleDelete { app_id: string version: string}Pour supprimer tous les bundles :
interface BundleDeleteAll { app_id: string}Exemples de requêtes
Section intitulée « Exemples de requêtes »# 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/Réponse en cas de succès
Section intitulée « Réponse en cas de succès »{ "status": "ok"}https://api.capgo.app/bundle/
Créer un nouveau bundle avec une URL externe.
Corps de la requête
Section intitulée « Corps de la requête »interface CreateBundleBody { app_id: string version: string external_url: string // Must be publicly accessible HTTPS URL checksum: string}Exemple de requête
Section intitulée « Exemple de requête »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/Réponse en cas de succès
Section intitulée « Réponse en cas de succès »{ "status": "ok"}POST (Métadonnées)
Section intitulée « POST (Metadata) »https://api.capgo.app/bundle/metadata
Mettre à jour les métadonnées du bundle, comme le lien et les informations de commentaire.
Corps de la requête
Section intitulée « Corps de la requête »interface UpdateMetadataBody { app_id: string version_id: number // bundle (version) id link?: string comment?: string}Exemple de requête
Section intitulée « Exemple de requête »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/metadataRéponse en cas de succès
Section intitulée « Réponse en cas de succès »{ "status": "success"}https://api.capgo.app/bundle/
Assigne un bundle à un canal spécifique. Cela lie un bundle (version) à un canal pour sa distribution.
Corps de la requête
Section intitulée « Corps de la requête »interface SetChannelBody { app_id: string version_id: number // bundle (version) id channel_id: number target?: "auto" | "stable" | "rollout" // default: auto}target contrôle l'endroit où le bundle est lié lorsque le canal a un déploiement progressif configuré :
auto— la cible de déploiement si le déploiement progressif est configuré ; stable sinon (par défaut).rollout— always set the rollout target; stable fallback unchanged.stable— remplace le fallback stable (solution de secours).
Exemple de requête
Section intitulée « Exemple de requête »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/Réponse en cas de succès
Section intitulée « Réponse en cas de succès »{ "status": "success", "message": "Bundle 1.0.0 set to channel production"}Gestion des erreurs
Section intitulée « Gestion des erreurs »Toutes les erreurs utilisent le format d'erreur standard décrit dans la Aperçu de API.
Scénarios d'erreur courants et leurs réponses :
// app_id is not a reverse-domain identifier{ "error": "invalid_app_id", "message": "App ID must be a reverse domain string", "moreInfo": { "app_id": "my app" }}
// Deleting a bundle without access to the app{ "error": "cannot_delete_bundle", "message": "You can't access this app", "moreInfo": { "app_id": "com.example.app" }}
// Deleting a bundle that a channel still uses{ "error": "cannot_delete_linked_version", "message": "Cannot delete a bundle linked to a channel", "moreInfo": { "app_id": "com.example.app", "version": "1.0.0" }}
// Creating a bundle whose version is not valid semver{ "error": "invalid_version_format", "message": "Version must be valid semver format (e.g., 1.0.0, 1.0.0-alpha.1)", "moreInfo": { "version": "v1" }}
// Setting a channel to a bundle that does not exist{ "error": "cannot_find_version", "message": "Cannot find version", "moreInfo": {}}Cas d'usage courants
Section intitulée « Cas d'utilisation courants »- Nettoyer les anciens bundles (versions)
// Delete outdated beta bundles (versions){ "app_id": "app_123", "version": "1.0.0-beta.1"}- App Reset
// Remove all bundles to start fresh{ "app_id": "app_123"}Considérations sur le stockage
Section intitulée « Considérations sur le stockage »- Politique de rétention: Define how long to keep old bundles
- Gestion de la taille: Monitor bundle sizes and storage usage
- Stratégie de sauvegarde: Envisagez de sauvegarder les bundles (versions) critiques
- Optimisation des coûts: Supprimez les bundles inutiles pour optimiser vos coûts de stockage
Continuer depuis Bundles
Section intitulée « Continuer depuis Bundles »Si vous utilisez Les bundles pour planifier le stockage et la gestion des fichiers, connectez-l’à @capgo/capacitor-data-storage-sqlite pour les détails d'implémentation dans @capgo/capacitor-data-storage-sqlite, Utiliser @capgo/capacitor-data-storage-sqlite pour la capacité native dans Utiliser @capgo/capacitor-data-storage-sqlite @capgo/capacitor-file pour les détails d'implémentation dans @capgo/capacitor-file, Utiliser @capgo/capacitor-file pour la capacité native dans Utiliser @capgo/capacitor-file, et @capgo/capacitor-uploader pour les détails d'implémentation dans @capgo/capacitor-uploader.