UNPKG

@capgo/capacitor-uploader

Version:
426 lines (425 loc) 12.8 kB
import type { PluginListenerHandle } from '@capacitor/core'; /** * Configuration options for uploading a file. * * @since 0.0.1 */ export interface UploadFileOption { /** * The local file path of the file to upload. * Can be a file:// URL or an absolute path. * * @since 0.0.3 */ filePath: string; /** * The form field name for the file part when using multipart upload. * * If omitted, `uploadOption.fileField` is used (defaults to `'file'`). * * @since 0.0.3 */ fieldName?: string; /** * The MIME type of this file. * If not specified, the plugin will attempt to determine it automatically. * * @since 0.0.3 */ mimeType?: string; } /** * Options for starting a single-file multipart upload. * * @since 8.3.2 */ export interface UploadMultipartOptions { /** * The server URL endpoint where the multipart request should be sent. * * @since 8.3.2 */ url: string; /** * The local file path of the file to upload. * Can be a file:// URL or an absolute path. * * @since 8.3.2 */ filePath: string; /** * The form field name for the uploaded file part. * * @since 8.3.2 */ fieldName: string; /** * Additional form fields to include in the multipart request. * * @since 8.3.2 */ fields?: { [key: string]: string; }; /** * HTTP headers to send with the upload request. * * @since 8.3.2 */ headers?: { [key: string]: string; }; } export interface uploadOption { /** * The local file path of the file to upload. * Can be a file:// URL or an absolute path. * * If you need to upload multiple files in a single multipart request, use `files`. * * @since 0.0.1 */ filePath?: string; /** * Multiple files to upload in a single request. * * When provided, uploads are sent as `multipart/form-data` with one part per file. * Use `fieldName` to control each part name (e.g. `images[]`). * * Note: `PUT` uploads (e.g. presigned S3 URLs) only support a single file. * * @since 0.0.3 */ files?: UploadFileOption[]; /** * The server URL endpoint where the file should be uploaded. * * @since 0.0.1 */ serverUrl: string; /** * The title of the upload notification shown to the user. * Android only. * * @default 'Uploading' * @since 0.0.1 */ notificationTitle?: string; /** * HTTP headers to send with the upload request. * Useful for authentication tokens, content types, etc. * * @since 0.0.1 * @example * ```typescript * headers: { * 'Authorization': 'Bearer token123', * 'X-Custom-Header': 'value' * } * ``` */ headers: { [key: string]: string; }; /** * The HTTP method to use for the upload request. * * @default 'POST' * @since 0.0.1 */ method?: 'PUT' | 'POST'; /** * The MIME type of the file being uploaded. * If not specified, the plugin will attempt to determine it automatically. * * @since 0.0.1 * @example 'image/jpeg', 'application/pdf', 'video/mp4' */ mimeType?: string; /** * Additional form parameters to send with the upload request. * These will be included as form data in multipart uploads. * * @since 0.0.1 */ parameters?: { [key: string]: string; }; /** * The maximum number of times to retry the upload if it fails. * * @since 0.0.1 * @default 0 */ maxRetries?: number; /** * The type of upload to perform. * - 'binary': Uploads the file as raw binary data in the request body * - 'multipart': Uploads the file as multipart/form-data * * @default 'binary' when `method` is `'PUT'`, otherwise `'multipart'` * @since 0.0.2 */ uploadType?: 'binary' | 'multipart'; /** * The form field name for the file when using multipart upload type. * Only used when uploadType is 'multipart'. * * For multi-file uploads via `files`, this is used as the default field name * when a file entry does not specify `fieldName`. * * @default 'file' * @since 0.0.2 */ fileField?: string; } /** * Event emitted during the upload lifecycle. * * @since 0.0.1 */ export interface UploadEvent { /** * The current status of the upload. * - 'uploading': Upload is in progress * - 'completed': Upload finished successfully * - 'failed': Upload encountered an error * * @since 0.0.1 */ name: 'uploading' | 'completed' | 'failed'; /** * Additional data about the upload event. * * @since 0.0.1 */ payload: { /** * Upload progress percentage from 0 to 100. * Only present during 'uploading' events. * * @since 0.0.1 */ percent?: number; /** * Error message if the upload failed. * Only present during 'failed' events. * * @since 0.0.1 */ error?: string; /** * HTTP status code returned by the server. * Present during 'completed' and 'failed' events. * * @since 0.0.1 */ statusCode?: number; }; /** * Unique identifier for this upload task. * * @since 0.0.1 */ id: string; /** * Unique identifier for this specific event instance. * Only present on 'completed' and 'failed' events. * Used with acknowledgeEvent() to confirm receipt and remove the event from the plugin cache. * Progress ('uploading') events do not have an eventId and are not persisted. * * @since 0.0.2 */ eventId?: string; } /** * Capacitor Uploader Plugin for uploading files with background support and progress tracking. * * ### iOS setup * * On iOS the native layer uses a background `URLSession` with the identifier * `CapacitorUploaderBackgroundSession`. Many apps can upload without adding * `UIBackgroundModes`; add `fetch` when you need uploads to continue after the app * is suspended. * * App Store Connect rejects builds that declare `UIBackgroundModes` → `processing` * without `BGTaskSchedulerPermittedIdentifiers`. This plugin does not schedule * `BGTaskScheduler` work, so avoid `processing` unless another feature needs it. * If `processing` is present (for example from older setup guides), include * `CapacitorUploaderBackgroundSession` in `BGTaskSchedulerPermittedIdentifiers` * in your app's `Info.plist`. * * @example * ```xml * <key>UIBackgroundModes</key> * <array> * <string>fetch</string> * </array> * <key>BGTaskSchedulerPermittedIdentifiers</key> * <array> * <string>CapacitorUploaderBackgroundSession</string> * </array> * ``` * * @since 0.0.1 */ export interface UploaderPlugin { /** * Start uploading a file to a server. * * The upload will continue in the background even if the app is closed or backgrounded. * Listen to upload events to track progress, completion, or failure. * * @param options - Configuration for the upload * @returns Promise that resolves with the upload ID * @throws Error if the upload fails to start * @since 0.0.1 * @example * ```typescript * const { id } = await Uploader.startUpload({ * filePath: 'file:///path/to/file.jpg', * serverUrl: 'https://example.com/upload', * headers: { * 'Authorization': 'Bearer token' * }, * method: 'POST', * uploadType: 'multipart', * fileField: 'photo' * }); * console.log('Upload started with ID:', id); * ``` * * @example * ```typescript * const { id } = await Uploader.startUpload({ * serverUrl: 'https://api.example.com/upload', * method: 'POST', * uploadType: 'multipart', * files: [ * { filePath: 'file:///...photo1.jpg', fieldName: 'images[]', mimeType: 'image/jpeg' }, * { filePath: 'file:///...photo2.jpg', fieldName: 'images[]', mimeType: 'image/jpeg' }, * ], * parameters: { albumId: '7' }, * headers: { Authorization: 'Bearer token' }, * }); * console.log('Upload started with ID:', id); * ``` */ startUpload(options: uploadOption): Promise<{ id: string; }>; /** * Start uploading a single file as multipart/form-data. * * This is a convenience API for backends that expect a named file field and * additional form fields. Existing `startUpload` binary uploads are unchanged. * * @param options - Configuration for the multipart upload * @returns Promise that resolves with the upload ID * @throws Error if the upload fails to start * @since 8.3.2 * @example * ```typescript * const { id } = await Uploader.uploadMultipart({ * url: 'https://example.com/upload', * filePath: 'file:///path/to/file.jpg', * fieldName: 'photo', * fields: { albumId: '7' }, * headers: { Authorization: 'Bearer token' }, * }); * console.log('Upload started with ID:', id); * ``` */ uploadMultipart(options: UploadMultipartOptions): Promise<{ id: string; }>; /** * Cancel and remove an ongoing upload. * * This will stop the upload if it's in progress and clean up resources. * * @param options - Object containing the upload ID to remove * @returns Promise that resolves when the upload is removed * @throws Error if the upload ID is not found * @since 0.0.1 * @example * ```typescript * await Uploader.removeUpload({ id: 'upload-123' }); * ``` */ removeUpload(options: { id: string; }): Promise<void>; /** * Listen for upload progress and status events. * * Events are fired for: * - Upload progress updates (with percent) * - Upload completion (with statusCode) * - Upload failure (with error and statusCode) * * @param eventName - Must be 'events' * @param listenerFunc - Callback function to handle upload events * @returns Promise that resolves with a listener handle for removal * @since 0.0.1 * @example * ```typescript * const listener = await Uploader.addListener('events', (event) => { * if (event.name === 'uploading') { * console.log(`Upload ${event.id}: ${event.payload.percent}%`); * } else if (event.name === 'completed') { * console.log(`Upload ${event.id} completed`); * } else if (event.name === 'failed') { * console.error(`Upload ${event.id} failed:`, event.payload.error); * } * }); * * // Remove listener when done * await listener.remove(); * ``` */ addListener(eventName: 'events', listenerFunc: (state: UploadEvent) => void): Promise<PluginListenerHandle>; /** * Acknowledge receipt of an upload event and remove it from the plugin cache. * * Completed and failed events are stored in the plugin's persistent cache so they can be * re-delivered if the app is closed or backgrounded before the event is processed. * Call this method after successfully handling a 'completed' or 'failed' event to prevent * it from being re-broadcast the next time the plugin initialises. * * Progress ('uploading') events do not have an eventId and do not need to be acknowledged. * * @param options - Object containing the eventId to acknowledge * @returns Promise that resolves when the event has been removed from the cache * @since 0.0.2 * @example * ```typescript * const listener = await Uploader.addListener('events', async (event) => { * if (event.name === 'completed' || event.name === 'failed') { * handleUploadResult(event); * if (event.eventId) { * await Uploader.acknowledgeEvent({ eventId: event.eventId }); * } * } * }); * ``` */ acknowledgeEvent(options: { eventId: string; }): Promise<void>; /** * Get the native Capacitor plugin version. * * @returns Promise that resolves with the plugin version * @throws Error if getting the version fails * @since 0.0.1 * @example * ```typescript * const { version } = await Uploader.getPluginVersion(); * console.log('Plugin version:', version); * ``` */ getPluginVersion(): Promise<{ version: string; }>; }