UNPKG

@capgo/cli

Version:

A CLI to upload to capgo servers

530 lines (529 loc) 19.4 kB
import type { Channel } from './api/channels'; import type { DecryptResult } from './bundle/decrypt'; import type { EncryptResult } from './bundle/encrypt'; import type { ZipResult } from './bundle/zip'; import type { StarAllRepositoryResult } from './github'; import type { ProbeInternalResult } from './probe'; import type { AccountIdOptions, AddAppOptions, AddChannelOptions, AddOrganizationOptions, AppInfo, BundleCompatibilityOptions, BundleInfo, CleanupOptions, CurrentBundleOptions, DecryptBundleOptions, DeleteOldKeyOptions, DeleteOrganizationOptions, DeviceStats, DoctorOptions, EncryptBundleOptions, GenerateKeyOptions, GetStatsOptions, ListOrganizationsOptions, LoginOptions, OrganizationInfo, ProbeOptions, RequestBuildOptions, SaveKeyOptions, SDKResult, SetSettingOptions, StarAllRepositoriesOptions, StarRepoOptions, UpdateAppOptions, UpdateChannelOptions, UpdateOrganizationOptions, UploadOptions, UploadResult, ZipBundleOptions } from './schemas/sdk'; import { getInfoInternal } from './app/info'; import { checkCompatibilityInternal } from './bundle/compatibility'; export type DoctorInfo = Awaited<ReturnType<typeof getInfoInternal>>; type CompatibilityReport = Awaited<ReturnType<typeof checkCompatibilityInternal>>['finalCompatibility']; export type BundleCompatibilityEntry = CompatibilityReport[number]; export type { UpdateProbeResult } from './app/updateProbe'; /** * Capgo SDK for programmatic access to all CLI functionality. * Use this class to integrate Capgo operations directly into your application. * * @example * ```typescript * // Initialize SDK * const sdk = new CapgoSDK({ apikey: 'your-api-key' }) * * // Upload a bundle * const result = await sdk.uploadBundle({ * appId: 'com.example.app', * path: './dist', * bundle: '1.0.0', * channel: 'production' * }) * * if (result.success) { * console.log('Upload successful!') * } * ``` */ export declare class CapgoSDK { private readonly apikey?; private readonly supaHost?; private readonly supaAnon?; constructor(options?: { apikey?: string; supaHost?: string; supaAnon?: string; }); /** * Save an API key locally or in the home directory */ login(options: LoginOptions): Promise<SDKResult>; /** * Run Capgo Doctor diagnostics and return the report */ doctor(options?: DoctorOptions): Promise<SDKResult<DoctorInfo>>; /** * Add a new app to Capgo Cloud * * @example * ```typescript * const result = await sdk.addApp({ * appId: 'com.example.app', * name: 'My App', * icon: './icon.png' * }) * ``` */ addApp(options: AddAppOptions): Promise<SDKResult>; /** * Update an existing app in Capgo Cloud * * Note: This method requires CLI function refactoring to work without exit(). * Currently it will throw an error. * * @example * ```typescript * const result = await sdk.updateApp({ * appId: 'com.example.app', * name: 'Updated App Name', * retention: 30 * }) * ``` */ updateApp(options: UpdateAppOptions): Promise<SDKResult>; /** * Delete an app from Capgo Cloud * * @param appId - The app ID to delete * @param skipConfirmation - Skip owner confirmation check (use with caution) * * @example * ```typescript * const result = await sdk.deleteApp('com.example.app') * ``` */ deleteApp(appId: string, skipConfirmation?: boolean): Promise<SDKResult>; /** * List all apps for the authenticated account * * @example * ```typescript * const result = await sdk.listApps() * if (result.success) { * result.data?.forEach(app => { * console.log(`${app.name} (${app.appId})`) * }) * } * ``` */ listApps(): Promise<SDKResult<AppInfo[]>>; /** * Retrieve the account ID associated with the configured API key */ getAccountId(options?: AccountIdOptions): Promise<SDKResult<string>>; /** * Star the Capgo repository on GitHub * * @example * ```typescript * const result = await sdk.starRepo({ repository: 'Cap-go/capacitor-updater' }) * if (result.success) { * console.log(`${result.data?.repository} starred`) * } * ``` */ starRepo(options?: StarRepoOptions): Promise<SDKResult<{ repository: string; alreadyStarred: boolean; }>>; /** * Star the Capgo-related repositories on GitHub * * @example * ```typescript * const result = await sdk.starAllRepositories() * if (result.success) { * for (const entry of result.data ?? []) { * console.log(entry.repository, entry.status) * } * } * ``` */ starAllRepositories(options?: StarAllRepositoriesOptions): Promise<SDKResult<StarAllRepositoryResult[]>>; checkBundleCompatibility(options: BundleCompatibilityOptions): Promise<SDKResult<BundleCompatibilityEntry[]>>; encryptBundle(options: EncryptBundleOptions): Promise<SDKResult<EncryptResult>>; decryptBundle(options: DecryptBundleOptions): Promise<SDKResult<DecryptResult>>; zipBundle(options: ZipBundleOptions): Promise<SDKResult<ZipResult>>; /** * Upload a bundle to Capgo Cloud * * @example * ```typescript * const result = await sdk.uploadBundle({ * appId: 'com.example.app', * path: './dist', * bundle: '1.0.0', * channel: 'production', * comment: 'New features added' * }) * ``` */ uploadBundle(options: UploadOptions): Promise<UploadResult>; /** * List bundles for an app * * @example * ```typescript * const result = await sdk.listBundles('com.example.app') * if (result.success) { * result.data?.forEach(bundle => { * console.log(`${bundle.version} - ${bundle.uploadedAt}`) * }) * } * ``` */ listBundles(appId: string): Promise<SDKResult<BundleInfo[]>>; /** * Delete a specific bundle * * Note: This method requires CLI function refactoring to work without exit(). * * @example * ```typescript * const result = await sdk.deleteBundle('com.example.app', '1.0.0') * ``` */ deleteBundle(appId: string, bundleId: string): Promise<SDKResult>; /** * Cleanup old bundles, keeping only recent versions * * @example * ```typescript * const result = await sdk.cleanupBundles({ * appId: 'com.example.app', * keep: 5, * force: true * }) * ``` */ cleanupBundles(options: CleanupOptions): Promise<SDKResult<{ removed: number; kept: number; }>>; /** * Request a native build for your app with store publishing * * SECURITY GUARANTEE: * Credentials provided to this method are NEVER stored on Capgo servers. * They are used only during the build process and automatically deleted * after completion (maximum 24 hours retention). Build outputs may optionally * be uploaded for time-limited download links. * * @example * ```typescript * const result = await sdk.requestBuild({ * appId: 'com.example.app', * path: './my-project', * lane: 'ios', // Must be exactly "ios" or "android" * credentials: { * BUILD_CERTIFICATE_BASE64: 'base64-cert...', * CAPGO_IOS_PROVISIONING_MAP: '{"com.example.app":{"profile":"base64...","name":"match AppStore com.example.app"}}', * P12_PASSWORD: 'cert-password', * APPLE_KEY_ID: 'KEY123', * APPLE_ISSUER_ID: 'issuer-uuid', * APPLE_KEY_CONTENT: 'base64-p8...', * APP_STORE_CONNECT_TEAM_ID: 'team-id' * } * }) * * if (result.success) { * console.log('Job ID:', result.data.jobId) * } * ``` */ requestBuild(options: RequestBuildOptions): Promise<SDKResult<{ jobId: string; uploadUrl: string; status: string; }>>; getCurrentBundle(appId: string, channelId: string, options?: CurrentBundleOptions): Promise<SDKResult<string>>; /** * Create a new channel for app distribution * * @example * ```typescript * const result = await sdk.addChannel({ * channelId: 'production', * appId: 'com.example.app', * default: true * }) * ``` */ addChannel(options: AddChannelOptions): Promise<SDKResult>; /** * Update channel settings * * @example * ```typescript * const result = await sdk.updateChannel({ * channelId: 'production', * appId: 'com.example.app', * bundle: '1.0.0' * }) * ``` */ updateChannel(options: UpdateChannelOptions): Promise<SDKResult>; /** * Delete a channel * * @example * ```typescript * const result = await sdk.deleteChannel('staging', 'com.example.app') * ``` */ deleteChannel(channelId: string, appId: string, deleteBundle?: boolean): Promise<SDKResult>; /** * List all channels for an app * * @example * ```typescript * const result = await sdk.listChannels('com.example.app') * if (result.success) { * result.data?.forEach(channel => { * console.log(`${channel.name} - ${channel.isDefault ? 'default' : 'normal'}`) * }) * } * ``` */ listChannels(appId: string): Promise<SDKResult<Channel[]>>; /** * Generate Capgo encryption keys (private/public pair) */ generateEncryptionKeys(options?: GenerateKeyOptions): Promise<SDKResult>; /** * Save a public encryption key into the Capacitor config */ saveEncryptionKey(options?: SaveKeyOptions): Promise<SDKResult>; /** * Delete legacy (v1) encryption keys from the project */ deleteLegacyEncryptionKey(options?: DeleteOldKeyOptions): Promise<SDKResult<{ deleted: boolean; }>>; listOrganizations(options?: ListOrganizationsOptions): Promise<SDKResult<OrganizationInfo[]>>; addOrganization(options: AddOrganizationOptions): Promise<SDKResult<OrganizationInfo>>; updateOrganization(options: UpdateOrganizationOptions): Promise<SDKResult<OrganizationInfo>>; deleteOrganization(orgId: string, options?: DeleteOrganizationOptions): Promise<SDKResult<{ deleted: boolean; }>>; /** * Get device statistics/logs from Capgo backend * * This method works similarly to waitLog, allowing you to poll for device activity. * Use the `after` parameter to get only new stats since a previous call. * * @example * ```typescript * // Get recent stats for an app * const result = await sdk.getStats({ * appId: 'com.example.app', * rangeStart: new Date().toISOString(), * limit: 100 * }) * * if (result.success && result.data) { * result.data.forEach(stat => { * console.log(`${stat.deviceId}: ${stat.action}`) * }) * } * * // Poll for new stats (similar to waitLog) * let after = new Date().toISOString() * const poll = async () => { * const result = await sdk.getStats({ * appId: 'com.example.app', * after * }) * * if (result.success && result.data && result.data.length > 0) { * // Update 'after' to newest timestamp * const newest = result.data.reduce((max, d) => { * const t = new Date(d.createdAt).getTime() * return Math.max(max, t) * }, new Date(after).getTime()) * after = new Date(newest).toISOString() * * // Process new stats * result.data.forEach(stat => console.log(stat)) * } * } * ``` */ getStats(options: GetStatsOptions): Promise<SDKResult<DeviceStats[]>>; setAppSetting(path: string, options: SetSettingOptions): Promise<SDKResult>; probe(options: ProbeOptions): Promise<SDKResult<ProbeInternalResult>>; } /** * Upload a bundle to Capgo Cloud (functional API) * * @example * ```typescript * const result = await uploadBundle({ * appId: 'com.example.app', * path: './dist', * bundle: '1.0.0', * apikey: 'your-api-key' * }) * ``` */ export declare function uploadBundle(options: UploadOptions): Promise<UploadResult>; export declare function login(options: LoginOptions): Promise<SDKResult>; export declare function doctor(options?: DoctorOptions): Promise<SDKResult<DoctorInfo>>; export declare function checkBundleCompatibility(options: BundleCompatibilityOptions): Promise<SDKResult<BundleCompatibilityEntry[]>>; export declare function encryptBundle(options: EncryptBundleOptions): Promise<SDKResult<EncryptResult>>; export declare function decryptBundle(options: DecryptBundleOptions): Promise<SDKResult<DecryptResult>>; export declare function zipBundle(options: ZipBundleOptions): Promise<SDKResult<ZipResult>>; export declare function starRepo(options?: StarRepoOptions): Promise<SDKResult<{ repository: string; alreadyStarred: boolean; }>>; export declare function starAllRepositories(options?: StarAllRepositoriesOptions): Promise<SDKResult<StarAllRepositoryResult[]>>; export declare function generateEncryptionKeys(options?: GenerateKeyOptions): Promise<SDKResult>; export declare function saveEncryptionKey(options?: SaveKeyOptions): Promise<SDKResult>; export declare function deleteLegacyEncryptionKey(options?: DeleteOldKeyOptions): Promise<SDKResult<{ deleted: boolean; }>>; export declare function getCurrentBundle(appId: string, channelId: string, options?: CurrentBundleOptions): Promise<SDKResult<string>>; export declare function updateAppSetting(path: string, options: SetSettingOptions): Promise<SDKResult>; export declare function getAccountId(options?: AccountIdOptions): Promise<SDKResult<string>>; export declare function listOrganizations(options?: ListOrganizationsOptions): Promise<SDKResult<OrganizationInfo[]>>; export declare function addOrganization(options: AddOrganizationOptions): Promise<SDKResult<OrganizationInfo>>; export declare function updateOrganization(options: UpdateOrganizationOptions): Promise<SDKResult<OrganizationInfo>>; export declare function deleteOrganization(orgId: string, options?: DeleteOrganizationOptions): Promise<SDKResult<{ deleted: boolean; }>>; /** * Add a new app to Capgo Cloud (functional API) * * @example * ```typescript * const result = await addApp({ * appId: 'com.example.app', * name: 'My App', * apikey: 'your-api-key' * }) * ``` */ export declare function addApp(options: AddAppOptions): Promise<SDKResult>; /** * List bundles for an app (functional API) * * @example * ```typescript * const result = await listBundles('com.example.app', { apikey: 'your-api-key' }) * ``` */ export declare function listBundles(appId: string, options?: { apikey?: string; supaHost?: string; supaAnon?: string; }): Promise<SDKResult<BundleInfo[]>>; /** * Add a new channel (functional API) * * @example * ```typescript * const result = await addChannel({ * channelId: 'production', * appId: 'com.example.app', * apikey: 'your-api-key' * }) * ``` */ export declare function addChannel(options: AddChannelOptions): Promise<SDKResult>; /** * Request a native build for your app (functional API) * * SECURITY GUARANTEE: * Credentials are NEVER stored on Capgo servers. They are used only during * the build process and automatically deleted after completion. * Build outputs may optionally be uploaded for time-limited download links. * * @example * ```typescript * const result = await requestBuild({ * appId: 'com.example.app', * path: './my-project', * lane: 'ios', // Must be exactly "ios" or "android" * credentials: { * // iOS credentials (use standard environment variable names) * BUILD_CERTIFICATE_BASE64: 'base64-encoded-cert', * BUILD_PROVISION_PROFILE_BASE64: 'base64-encoded-profile', * P12_PASSWORD: 'cert-password', * APPLE_KEY_ID: 'KEY123', * APPLE_ISSUER_ID: 'issuer-uuid', * APPLE_KEY_CONTENT: 'base64-encoded-p8', * APP_STORE_CONNECT_TEAM_ID: 'team-id', * // Android credentials (use standard environment variable names) * ANDROID_KEYSTORE_FILE: 'base64-encoded-keystore', * KEYSTORE_KEY_ALIAS: 'my-key-alias', * KEYSTORE_KEY_PASSWORD: 'key-password', * KEYSTORE_STORE_PASSWORD: 'store-password', * PLAY_CONFIG_JSON: 'base64-encoded-service-account-json' * }, * apikey: 'your-api-key' * }) * * if (result.success) { * console.log('Job ID:', result.data.jobId) * console.log('Status:', result.data.status) * } * ``` */ export declare function requestBuild(options: RequestBuildOptions): Promise<SDKResult<{ jobId: string; uploadUrl: string; status: string; }>>; /** * Get device statistics/logs from Capgo backend (functional API) * * This function works similarly to waitLog, allowing you to poll for device activity. * * @example * ```typescript * // Get recent stats for an app * const result = await getStats({ * appId: 'com.example.app', * apikey: 'your-api-key', * rangeStart: new Date().toISOString(), * limit: 100 * }) * * if (result.success && result.data) { * result.data.forEach(stat => { * console.log(`${stat.deviceId}: ${stat.action}`) * }) * } * ``` */ export declare function getStats(options: GetStatsOptions): Promise<SDKResult<DeviceStats[]>>; export declare function probeUpdates(options: ProbeOptions): Promise<SDKResult<ProbeInternalResult>>; /** * Get Capacitor configuration * * @example * ```typescript * const config = await getCapacitorConfig() * if (config) { * console.log(config.appId) * } * ``` */ export declare function getCapacitorConfig(): Promise<{ config: { [x: string]: unknown; appId: string; appName: string; webDir: string; plugins?: Record<string, any> | undefined; android?: Record<string, any> | undefined; }; path: string; } | null>; export type { BuildCredentials } from './build/request'; export type { CapacitorConfig } from './config'; export type { ProbeInternalResult } from './probe'; export type { AccountIdOptions, AddAppOptions, AddChannelOptions, AddOrganizationOptions, AppInfo, BundleCompatibilityOptions, BundleInfo, CleanupOptions, CurrentBundleOptions, DecryptBundleOptions, DeleteOldKeyOptions, DeleteOrganizationOptions, DeviceStats, DoctorOptions, EncryptBundleOptions, GenerateKeyOptions, GetStatsOptions, ListOrganizationsOptions, LoginOptions, OrganizationInfo, ProbeOptions, RequestBuildOptions, SaveKeyOptions, SDKResult, SetSettingOptions, StarAllRepositoriesOptions, StarRepoOptions, StatsOrder, UpdateAppOptions, UpdateChannelOptions, UpdateOrganizationOptions, UploadOptions, UploadResult, ZipBundleOptions, } from './schemas/sdk'; export type { Database } from './types/supabase.types'; export { createSupabaseClient } from './utils'; export { formatApiErrorForCli, getSecurityPolicyMessage, isSecurityPolicyError, parseSecurityPolicyError, SECURITY_POLICY_ERRORS, SECURITY_POLICY_MESSAGES, } from './utils/security_policy_errors'; export type { ParsedSecurityError, SecurityPolicyErrorCode } from './utils/security_policy_errors';