Skip to Content
API Reference

API Reference

Complete API documentation for FluxMedia packages.

MediaUploader

The main class for uploading files. Supports fallback providers, transactional uploads, and plugin orchestration.

Constructor

new MediaUploader( provider: MediaProvider, plugins?: FluxMediaPlugin[], config?: MediaUploaderConfig )

Parameters:

ParameterTypeDescription
providerMediaProviderPrimary storage provider
pluginsFluxMediaPlugin[]Optional array of plugins to register
configMediaUploaderConfigOptional configuration for fallback, error handling

MediaUploaderConfig

interface MediaUploaderConfig { fallbackProvider?: MediaProvider; fallbackOnErrors?: MediaErrorCode[]; onFallback?: (error: MediaError, fallbackProvider: MediaProvider) => void; }
OptionTypeDescription
fallbackProviderMediaProviderProvider to use when primary fails
fallbackOnErrorsMediaErrorCode[]Error codes that trigger fallback (default: network, rate-limit, provider errors)
onFallbackfunctionCallback when fallback is triggered

Example:

import { MediaUploader, MediaErrorCode } from '@fluxmedia/core'; const uploader = new MediaUploader(primaryProvider, [analyticsPlugin], { fallbackProvider: backupProvider, fallbackOnErrors: [ MediaErrorCode.NETWORK_ERROR, MediaErrorCode.RATE_LIMITED, MediaErrorCode.PROVIDER_ERROR, ], onFallback: (error, provider) => { console.warn(`Falling back to ${provider.name}: ${error.message}`); }, });

Methods

upload(file, options?)

Upload a single file. Automatically falls back to the fallback provider on qualifying errors.

async upload(file: UploadInput, options?: UploadOptions): Promise<UploadResult>

delete(id)

Delete a file by ID.

async delete(id: string): Promise<void>

get(id)

Get file metadata.

async get(id: string): Promise<UploadResult>

getUrl(id, transform?)

Generate a URL synchronously, optionally with transformations.

getUrl(id: string, transform?: TransformationOptions): string

getUrlAsync(id, transform?)

Generate a URL asynchronously (for providers that need async URL generation like signed URLs).

async getUrlAsync(id: string, transform?: TransformationOptions): Promise<string>

uploadMultiple(files, options?)

Upload multiple files with concurrency control. Routes through plugin hooks.

async uploadMultiple( files: UploadInput[], options?: UploadOptions & { concurrency?: number; onBatchProgress?: (completed: number, total: number) => void; } ): Promise<UploadResult[]>

deleteMultiple(ids)

Delete multiple files. Routes through plugin hooks.

async deleteMultiple(ids: string[]): Promise<void>

uploadWithTransaction(file, options?, callbacks?)

Upload with transaction semantics — commit on success, rollback on failure.

async uploadWithTransaction<T>( file: UploadInput, options?: UploadOptions, callbacks?: TransactionCallbacks<T> ): Promise<{ result: UploadResult; committed: T }>

TransactionCallbacks:

interface TransactionCallbacks<T> { onCommit: (result: UploadResult) => Promise<T>; onRollback?: (result: UploadResult, error: Error) => Promise<void>; }

Example:

const { result, committed } = await uploader.uploadWithTransaction( file, { folder: 'documents' }, { onCommit: async (result) => { // Save to database after successful upload return await db.documents.create({ url: result.url, storageKey: result.storageKey }); }, onRollback: async (result, error) => { // Clean up the uploaded file if commit fails await uploader.delete(result.id); }, } );

supports(feature)

Check if provider supports a feature.

supports(feature: string): boolean

use(plugin)

Register a plugin. Calls plugin.init() if defined.

async use(plugin: FluxMediaPlugin): Promise<this>

Types

UploadInput

Union type for all accepted upload inputs:

type UploadInput = File | Buffer | Readable | ReadableStream;

Supports browser File objects, Node.js Buffer, Node.js Readable streams, and web ReadableStream.

UploadOptions

interface UploadOptions { folder?: string; filename?: string; tags?: string[]; metadata?: Record<string, unknown>; transformation?: TransformationOptions; onProgress?: (percent: number) => void; onByteProgress?: (loaded: number, total: number) => void; uniqueFilename?: boolean; // Generate unique names (default: true) contentType?: string; // MIME type override signal?: AbortSignal; // Abort controller signal }
OptionTypeDescription
folderstringDestination folder path
filenamestringCustom filename
tagsstring[]Tags for organization
metadataRecord<string, unknown>Custom metadata key-value pairs
transformationTransformationOptionsApply transformations on upload
onProgress(percent: number) => voidNormalized 0-100 progress callback
onByteProgress(loaded: number, total: number) => voidRaw byte-level progress callback
uniqueFilenamebooleanGenerate unique filenames (default: true)
contentTypestringOverride auto-detected MIME type
signalAbortSignalCancel in-flight uploads via AbortController

UploadResult

interface UploadResult { id: string; storageKey: string; url: string; publicUrl: string; size: number; format: string; width?: number; height?: number; provider: string; metadata: Record<string, unknown>; createdAt: Date; }
FieldTypeDescription
idstringUnique identifier for the uploaded file
storageKeystringProvider-specific storage key (e.g., S3 object key, Cloudinary public ID)
urlstringDirect URL to the file
publicUrlstringPublic-facing URL
sizenumberFile size in bytes
formatstringFile format/extension
widthnumberImage width (if applicable)
heightnumberImage height (if applicable)
providerstringProvider name that handled the upload
metadataRecord<string, unknown>Additional metadata
createdAtDateUpload timestamp

TransformationOptions

interface TransformationOptions { width?: number; height?: number; fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside'; quality?: number; format?: 'auto' | 'webp' | 'avif' | 'jpg' | 'png'; }

MediaProvider

interface MediaProvider { readonly name: string; readonly features: ProviderFeatures; readonly native: unknown; upload(file: UploadInput, options?: UploadOptions): Promise<UploadResult>; delete(id: string): Promise<void>; get(id: string): Promise<UploadResult>; getUrl(id: string, transform?: TransformationOptions): string; uploadMultiple(files: UploadInput[], options?: UploadOptions): Promise<UploadResult[]>; deleteMultiple(ids: string[]): Promise<void>; search?(query: SearchOptions): Promise<UploadResult[]>; }

ProviderFeatures

interface ProviderFeatures { transformations: { resize: boolean; crop: boolean; format: boolean; quality: boolean; blur: boolean; rotate: boolean; effects: boolean; }; capabilities: { signedUploads: boolean; directUpload: boolean; multipartUpload: boolean; videoProcessing: boolean; aiTagging: boolean; facialDetection: boolean; }; storage: { maxFileSize: number; supportedFormats: string[]; }; }

File Type Detection

Detect file types using magic bytes (more reliable than extensions).

getFileType(buffer)

import { getFileType } from '@fluxmedia/core'; const type = await getFileType(buffer); console.log(type); // { mime: 'image/jpeg', ext: 'jpg' }

getFileTypeFromStream(stream)

For large files without loading into memory:

import { getFileTypeFromStream } from '@fluxmedia/core'; const type = await getFileTypeFromStream(readableStream);

Helper Functions

import { isImage, isVideo } from '@fluxmedia/core'; if (await isImage(buffer)) { // Handle image } if (await isVideo(buffer)) { // Handle video }

Errors

MediaError

Structured error class with typed error codes and provider context.

class MediaError extends Error { code: MediaErrorCode; provider: string; originalError?: unknown; details?: Record<string, unknown>; }

MediaErrorCode

enum MediaErrorCode { // Upload errors UPLOAD_FAILED = 'UPLOAD_FAILED', FILE_TOO_LARGE = 'FILE_TOO_LARGE', INVALID_FILE_TYPE = 'INVALID_FILE_TYPE', NETWORK_ERROR = 'NETWORK_ERROR', // Authentication errors INVALID_CREDENTIALS = 'INVALID_CREDENTIALS', UNAUTHORIZED = 'UNAUTHORIZED', // Provider errors PROVIDER_ERROR = 'PROVIDER_ERROR', RATE_LIMITED = 'RATE_LIMITED', QUOTA_EXCEEDED = 'QUOTA_EXCEEDED', // Configuration errors INVALID_CONFIG = 'INVALID_CONFIG', MISSING_CREDENTIALS = 'MISSING_CREDENTIALS', // File errors FILE_NOT_FOUND = 'FILE_NOT_FOUND', DELETE_FAILED = 'DELETE_FAILED', }

createMediaError

Factory function for creating consistent MediaError instances:

import { createMediaError, MediaErrorCode } from '@fluxmedia/core'; const error = createMediaError(MediaErrorCode.UPLOAD_FAILED, 'Upload timed out', 'cloudinary', { originalError: err, details: { timeout: 30000 }, });

PartialUploadError

Specialized error for resumable multipart uploads. Preserves upload context so retries can resume from where they left off.

class PartialUploadError extends MediaError { uploadContext: PartialUploadContext; }

PartialUploadContext

interface PartialUploadContext { uploadId: string; completedParts: number[]; totalParts: number; bytesUploaded: number; provider: string; }

Example — Handling partial upload failures:

import { PartialUploadError } from '@fluxmedia/core'; import { withRetry } from '@fluxmedia/plugins'; // withRetry automatically resumes from PartialUploadContext const result = await withRetry( (resumeContext) => uploader.upload(file, { metadata: resumeContext ? { _resumeFrom: resumeContext } : {}, }), { maxRetries: 3, exponentialBackoff: true } );

Plugin Types

FluxMediaPlugin

interface FluxMediaPlugin { name: string; version?: string; optional?: boolean; // If true, errors in hooks are caught and logged hooks: PluginHooks; init?: () => Promise<void> | void; // Called when plugin is registered destroy?: () => Promise<void> | void; // Called when plugin is unregistered }

The optional flag enables graceful degradation — if an optional plugin’s hook throws, the error is caught and the upload continues. This is ideal for non-critical plugins like analytics or metadata extraction.

PluginHooks

interface PluginHooks { beforeUpload?: ( file: File | Buffer, options: UploadOptions ) => Promise<{ file: File | Buffer; options: UploadOptions } | void>; afterUpload?: (result: UploadResult) => Promise<UploadResult>; onError?: ( error: Error, context: { file: File | Buffer; options: UploadOptions; phase: UploadPhase; uploadResult?: UploadResult; } ) => Promise<void>; beforeDelete?: (id: string) => Promise<string | void>; afterDelete?: (id: string) => Promise<void>; beforeGetUrl?: ( id: string, transform?: TransformationOptions ) => Promise<{ id: string; transform?: TransformationOptions } | void>; }

UploadPhase

type UploadPhase = 'before' | 'upload' | 'after';

Indicates which phase of the upload pipeline the error occurred in, available in onError context.

createPlugin Helper

import { createPlugin } from '@fluxmedia/core'; const myPlugin = createPlugin( 'my-plugin', { beforeUpload: async (file, options) => { return { file, options }; }, }, { optional: true } );

Analytics Event Types

Typed events for the analytics plugin. The TrackFunction is generic — TypeScript automatically enforces that event data matches the event type.

AnalyticsEventType

type AnalyticsEventType = | 'media.upload.started' | 'media.upload.completed' | 'media.delete.completed' | 'media.error';

TrackFunction

type TrackFunction = <T extends AnalyticsEventType>(event: T, data: AnalyticsEventMap[T]) => void;

Event Data Types

interface UploadStartedEventData { fileName: string; fileSize: number; folder?: string; uploadId: string; } interface UploadCompletedEventData { fileId: string; fileName: string; fileSize: number; format: string; provider: string; duration: number; totalUploads: number; totalSize: number; } interface DeleteCompletedEventData { fileId: string; } interface ErrorEventData { operation: 'upload' | 'delete' | 'get'; error: { message: string; name: string }; totalErrors: number; }

Testing Utilities

Helpers for testing custom providers and upload logic.

createMockProvider

Creates a mock MediaProvider for unit tests:

import { createMockProvider, createMockUploadResult } from '@fluxmedia/core'; const provider = createMockProvider({ name: 'test-provider', }); const result = await provider.upload(file);

createProviderContractTests

Validates that a custom provider correctly implements the MediaProvider interface:

import { createProviderContractTests } from '@fluxmedia/core'; createProviderContractTests('MyProvider', () => new MyProvider({ ... }));

This runs a suite of tests verifying:

  • Required properties (name, features)
  • Feature matrix structure (transformations, capabilities, storage)
  • All required methods exist (upload, delete, get, getUrl, uploadMultiple, deleteMultiple, native)
  • getUrl returns valid URL strings
Last updated on