Bundles
Los paquetes son los paquetes de actualización principales en Capgo. Cada paquete contiene los recursos web (HTML, CSS, JS) que conforman el contenido de su aplicación. Los Paquetes API le permiten administrar estos paquetes de actualización, incluso enumerarlos y eliminarlos.
Comprender los paquetes
Section titled “Comprender los paquetes”Un paquete representa un paquete (versión) específico del contenido web de su aplicación e incluye:
- Paquete (versión): número de versión semántica del paquete
- Suma de comprobación: hash único para verificar la integridad del paquete
- Información de almacenamiento: detalles sobre dónde y cómo se almacena el paquete
- Requisitos nativos: requisitos mínimos de versión nativa de la aplicación
- Metadatos: hora de creación, propiedad y otra información de seguimiento
Creación manual de paquetes (sin CLI)
Section titled “Creación manual de paquetes (sin CLI)”A continuación se explica cómo crear y cargar paquetes manualmente sin utilizar Capgo CLI:
Paso 1: crea tu aplicación
Section titled “Paso 1: crea tu aplicación”Primero, cree los recursos web de su aplicación:
npm run buildPaso 2: Crear paquete zip usando los mismos paquetes que Capgo CLI
Section titled “Paso 2: Crear paquete zip usando los mismos paquetes que Capgo CLI”Importante: Utilice exactamente los mismos paquetes JavaScript que Capgo CLI utiliza internamente para garantizar la compatibilidad.
Instalar los paquetes necesarios
Section titled “Instalar los paquetes necesarios”npm install adm-zip @tomasklaen/checksumCrear paquete Zip con JavaScript (igual que Capgo CLI)
Section titled “Crear paquete Zip con JavaScript (igual que Capgo CLI)”Nota: En los ejemplos siguientes, version se refiere al nombre del paquete (versión) utilizado por 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();Paso 3: Calcule la suma de comprobación SHA256 utilizando el mismo paquete que CLI
Section titled “Paso 3: Calcule la suma de comprobación SHA256 utilizando el mismo paquete 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();Paso 4: Cargue el paquete en su almacenamiento
Section titled “Paso 4: Cargue el paquete en su almacenamiento”Cargue su archivo zip en cualquier almacenamiento accesible desde la 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"Importante: Su paquete debe ser accesible públicamente a través de una URL HTTPS (no se requiere autenticación). Los servidores de Capgo deben descargar el paquete desde esta URL.
Ejemplos de URL públicas válidas:
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
Paso 5: Registre el paquete con Capgo API
Section titled “Paso 5: Registre el paquete con Capgo API”Registre el paquete externo con Capgo mediante llamadas directas 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 Parámetros
Section titled “API Parámetros”| Parámetro | Descripción | Requerido |
|---|---|---|
app_id | Su identificador de aplicación | Sí |
version | Paquete (versión) versión semántica (por ejemplo, “1.2.3”) | Sí |
external_url | Accesible públicamente URL HTTPS donde se puede descargar el paquete (no se requiere autenticación) | Sí |
checksum | Suma de comprobación SHA256 del archivo zip | Sí |
Requisitos de estructura del paquete
Section titled “Requisitos de estructura del paquete”El paquete zip debe seguir estos requisitos:
- Archivo de índice raíz: debe tener
index.htmlen el nivel raíz - Capacitor Integración: debe llamar a
notifyAppReady()en el código de su aplicación - Rutas de activos: use rutas relativas para todos los activos
Estructura de paquete válida
Section titled “Estructura de paquete válida”bundle.zip├── index.html├── assets/│ ├── app.js│ └── styles.css└── images/Ejemplo completo de flujo de trabajo manual
Section titled “Ejemplo completo de flujo de trabajo manual”Script Node.js simple para comprimir, realizar suma de verificación y cargar en 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);Instalar dependencias:
npm install adm-zip @tomasklaen/checksum node-fetchVerificación de suma de verificación
Section titled “Verificación de suma de verificación”JavaScript Cálculo de suma de comprobación (igual que Capgo CLI)
Section titled “JavaScript Cálculo de suma de comprobación (igual que Capgo CLI)”Utilice exactamente el mismo paquete y método que Capgo CLI utiliza internamente:
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();```### Importancia de la suma de comprobación
- **Integridad del paquete**: garantiza que el paquete no se haya dañado durante la transferencia- **API Verificación**: Capgo verifica las sumas de verificación antes de aceptar paquetes- **Verificación del complemento**: el complemento móvil verifica las sumas de verificación antes de aplicar las actualizaciones
## Mejores prácticas
1. **Gestión de paquetes (versión)**: utilice el control de versiones semántico de forma coherente2. **Optimización de almacenamiento**: elimine periódicamente los paquetes no utilizados3. **Compatibilidad del paquete (versión)**: establezca los requisitos mínimos de versión nativa adecuados4. **Estrategia de copia de seguridad**: mantener copias de seguridad de paquetes (versiones) críticos
## Puntos finales
### OBTENER
`https://api.capgo.app/bundle/`
Recuperar información del paquete. Devuelve 50 paquetes por página.
#### Parámetros de consulta- `app_id`: Requerido. El ID de tu aplicación- `page`: Opcional. Número de página para paginación
#### Tipo de respuesta
```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}Solicitud de ejemplo
Section titled “Solicitud de ejemplo”# 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"Ejemplo de respuesta
Section titled “Ejemplo de respuesta”{ "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" } ]}BORRAR
Section titled “BORRAR”https://api.capgo.app/bundle/
Elimine uno o todos los paquetes de una aplicación. Úselo con precaución ya que esta acción no se puede deshacer.
Parámetros de consulta
Section titled “Parámetros de consulta”Para eliminar un paquete específico:
interface BundleDelete { app_id: string version: string}Para eliminar todos los paquetes:
interface BundleDeleteAll { app_id: string}Solicitudes de ejemplo
Section titled “Solicitudes de ejemplo”# 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/Respuesta exitosa
Section titled “Respuesta exitosa”{ "status": "ok"}PUBLICAR
Section titled “PUBLICAR”https://api.capgo.app/bundle/
Cree un nuevo paquete con URL externa.
Cuerpo de solicitud
Section titled “Cuerpo de solicitud”interface CreateBundleBody { app_id: string version: string external_url: string // Must be publicly accessible HTTPS URL checksum: string}Solicitud de ejemplo
Section titled “Solicitud de ejemplo”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/Respuesta exitosa
Section titled “Respuesta exitosa”{ "status": "ok"}PUBLICACIÓN (Metadatos)
Section titled “PUBLICACIÓN (Metadatos)”https://api.capgo.app/bundle/metadata
Actualice los metadatos del paquete, como la información de enlaces y comentarios.
Cuerpo de solicitud
Section titled “Cuerpo de solicitud”interface UpdateMetadataBody { app_id: string version_id: number // bundle (version) id link?: string comment?: string}Solicitud de ejemplo
Section titled “Solicitud de ejemplo”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/metadataRespuesta exitosa
Section titled “Respuesta exitosa”{ "status": "success"}https://api.capgo.app/bundle/
Establece un paquete para un canal específico. Esto vincula un paquete (versión) a un canal de distribución.
Cuerpo de solicitud
Section titled “Cuerpo de solicitud”interface SetChannelBody { app_id: string version_id: number // bundle (version) id channel_id: number}Solicitud de ejemplo
Section titled “Solicitud de ejemplo”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/Respuesta exitosa
Section titled “Respuesta exitosa”{ "status": "success", "message": "Bundle 1.0.0 set to channel production"}Manejo de errores
Section titled “Manejo de errores”Escenarios de error comunes y sus respuestas:
// 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"}Casos de uso comunes
Section titled “Casos de uso comunes”- Limpiar paquetes antiguos (versiones)
// Delete outdated beta bundles (versions){ "app_id": "app_123", "version": "1.0.0-beta.1"}- Restablecimiento de aplicación
// Remove all bundles to start fresh{ "app_id": "app_123"}Consideraciones de almacenamiento
Section titled “Consideraciones de almacenamiento”- Política de retención: defina cuánto tiempo conservar los paquetes antiguos
- Administración de tamaños: supervise los tamaños de los paquetes y el uso de almacenamiento
- Estrategia de copia de seguridad: considere realizar una copia de seguridad de paquetes (versiones) críticos
- Optimización de costos: elimine paquetes innecesarios para optimizar los costos de almacenamiento