@wordpress/upload-media
Version:
Core media upload logic.
8 lines (7 loc) • 15 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/store/types.ts"],
"sourcesContent": ["/**\n * Sub-size data returned by the sideload endpoint.\n *\n * Each sideload returns this lightweight object instead of a full attachment.\n * The client accumulates these and sends them all to the finalize endpoint.\n */\nexport interface SubSizeData {\n\t/**\n\t * Size name, or an array of names when the same sideloaded file is\n\t * registered under multiple sizes that share identical dimensions.\n\t */\n\timage_size: string | string[];\n\twidth?: number;\n\theight?: number;\n\tfile: string;\n\tmime_type?: string;\n\tfilesize?: number;\n\toriginal_image?: string;\n}\n\nexport type QueueItemId = string;\n\nexport type QueueStatus = 'active' | 'paused';\n\nexport type BatchId = string;\n\nexport interface QueueItem {\n\tid: QueueItemId;\n\tsourceFile: File;\n\tfile: File;\n\t// Original HEIC/HEIF file, kept separately so it can be sideloaded\n\t// as the attachment's \"original_image\" after the converted JPEG is\n\t// uploaded. Not set for non-HEIC items.\n\toriginalHeicFile?: File;\n\t// Original animated GIF, kept separately so it can be transcoded to a\n\t// video and sideloaded as a companion file of the GIF image attachment\n\t// (recorded in attachment metadata as `animated_video`). Not set for\n\t// non-animated-GIF items.\n\tanimatedGifFile?: File;\n\tposter?: File;\n\tattachment?: Partial< Attachment >;\n\tstatus: ItemStatus;\n\tadditionalData: AdditionalData;\n\tonChange?: OnChangeHandler;\n\tonSuccess?: OnSuccessHandler;\n\tonError?: OnErrorHandler;\n\tonBatchSuccess?: OnBatchSuccessHandler;\n\tcurrentOperation?: OperationType;\n\toperations?: Operation[];\n\terror?: Error;\n\tretryCount?: number;\n\tnextRetryTimestamp?: number;\n\tprogress?: number;\n\tbatchId?: string;\n\tsourceUrl?: string;\n\tsourceAttachmentId?: number;\n\tabortController?: AbortController;\n\tparentId?: QueueItemId;\n\tsubSizes?: SubSizeData[];\n}\n\nexport interface State {\n\tqueue: QueueItem[];\n\tqueueStatus: QueueStatus;\n\tblobUrls: Record< QueueItemId, string[] >;\n\tsettings: Settings;\n}\n\nexport enum Type {\n\tUnknown = 'REDUX_UNKNOWN',\n\tAdd = 'ADD_ITEM',\n\tPrepare = 'PREPARE_ITEM',\n\tCancel = 'CANCEL_ITEM',\n\tRemove = 'REMOVE_ITEM',\n\tRetryItem = 'RETRY_ITEM',\n\tScheduleRetry = 'SCHEDULE_RETRY',\n\tPauseItem = 'PAUSE_ITEM',\n\tResumeItem = 'RESUME_ITEM',\n\tPauseQueue = 'PAUSE_QUEUE',\n\tResumeQueue = 'RESUME_QUEUE',\n\tOperationStart = 'OPERATION_START',\n\tOperationFinish = 'OPERATION_FINISH',\n\tAddOperations = 'ADD_OPERATIONS',\n\tCacheBlobUrl = 'CACHE_BLOB_URL',\n\tRevokeBlobUrls = 'REVOKE_BLOB_URLS',\n\tUpdateProgress = 'UPDATE_PROGRESS',\n\tAccumulateSubSize = 'ACCUMULATE_SUB_SIZE',\n\tUpdateSettings = 'UPDATE_SETTINGS',\n}\n\ntype Action< T = Type, Payload = Record< string, unknown > > = {\n\ttype: T;\n} & Payload;\n\nexport type UnknownAction = Action< Type.Unknown >;\nexport type AddAction = Action<\n\tType.Add,\n\t{\n\t\titem: Omit< QueueItem, 'operations' > &\n\t\t\tPartial< Pick< QueueItem, 'operations' > >;\n\t}\n>;\nexport type OperationStartAction = Action<\n\tType.OperationStart,\n\t{ id: QueueItemId; operation: OperationType }\n>;\nexport type OperationFinishAction = Action<\n\tType.OperationFinish,\n\t{\n\t\tid: QueueItemId;\n\t\titem: Partial< QueueItem >;\n\t}\n>;\nexport type AddOperationsAction = Action<\n\tType.AddOperations,\n\t{ id: QueueItemId; operations: Operation[] }\n>;\nexport type CancelAction = Action<\n\tType.Cancel,\n\t{ id: QueueItemId; error: Error }\n>;\nexport type RetryItemAction = Action< Type.RetryItem, { id: QueueItemId } >;\nexport type ScheduleRetryAction = Action<\n\tType.ScheduleRetry,\n\t{\n\t\tid: QueueItemId;\n\t\terror: Error;\n\t\tretryCount: number;\n\t\tnextRetryTimestamp: number;\n\t}\n>;\nexport type PauseItemAction = Action< Type.PauseItem, { id: QueueItemId } >;\nexport type ResumeItemAction = Action< Type.ResumeItem, { id: QueueItemId } >;\nexport type PauseQueueAction = Action< Type.PauseQueue >;\nexport type ResumeQueueAction = Action< Type.ResumeQueue >;\nexport type RemoveAction = Action< Type.Remove, { id: QueueItemId } >;\nexport type CacheBlobUrlAction = Action<\n\tType.CacheBlobUrl,\n\t{ id: QueueItemId; blobUrl: string }\n>;\nexport type RevokeBlobUrlsAction = Action<\n\tType.RevokeBlobUrls,\n\t{ id: QueueItemId }\n>;\nexport type UpdateProgressAction = Action<\n\tType.UpdateProgress,\n\t{ id: QueueItemId; progress: number }\n>;\nexport type AccumulateSubSizeAction = Action<\n\tType.AccumulateSubSize,\n\t{ id: QueueItemId; subSize: SubSizeData }\n>;\nexport type UpdateSettingsAction = Action<\n\tType.UpdateSettings,\n\t{ settings: Partial< Settings > }\n>;\n\ninterface UploadMediaArgs {\n\t// Additional data to include in the request.\n\tadditionalData?: AdditionalData;\n\t// Array with the types of media that can be uploaded, if unset all types are allowed.\n\tallowedTypes?: string[];\n\t// List of files.\n\tfilesList: File[];\n\t// Maximum upload size in bytes allowed for the site.\n\tmaxUploadFileSize?: number;\n\t// Function called when an error happens.\n\tonError?: OnErrorHandler;\n\t// Function called each time a file or a temporary representation of the file is available.\n\tonFileChange?: OnChangeHandler;\n\t// Function called once a file has completely finished uploading, including thumbnails.\n\tonSuccess?: OnSuccessHandler;\n\t// List of allowed mime types and file extensions.\n\twpAllowedMimeTypes?: Record< string, string > | null;\n\t// Abort signal.\n\tsignal?: AbortSignal;\n}\n\n/**\n * Arguments for sideloading a file to an existing attachment.\n *\n * Sideloading adds additional image sizes (thumbnails) to an already\n * uploaded attachment without creating a new attachment.\n */\nexport interface SideloadMediaArgs {\n\t/** File to sideload (typically a resized version of the original). */\n\tfile: File;\n\t/** Attachment ID to add the sideloaded file to. */\n\tattachmentId: number;\n\t/** Additional data to include in the request. */\n\tadditionalData?: AdditionalData;\n\t/** Function called when an error happens. */\n\tonError?: OnErrorHandler;\n\t/** Function called when the sideload completes with sub-size data. */\n\tonSuccess?: ( subSize: SubSizeData ) => void;\n\t/** Abort signal to cancel the sideload operation. */\n\tsignal?: AbortSignal;\n}\n\nexport interface Settings {\n\t// Registered image sizes from the server.\n\tallImageSizes?: Record< string, ImageSizeCrop >;\n\t// Function for uploading files to the server.\n\tmediaUpload: ( args: UploadMediaArgs ) => void;\n\t// Function for sideloading files to existing attachments.\n\tmediaSideload?: ( args: SideloadMediaArgs ) => void;\n\t// List of allowed mime types and file extensions.\n\tallowedMimeTypes?: Record< string, string > | null;\n\t// Maximum upload file size.\n\tmaxUploadFileSize?: number;\n\t// Maximum number of concurrent uploads.\n\tmaxConcurrentUploads: number;\n\t// Maximum number of concurrent image processing operations (resize, crop, rotate).\n\tmaxConcurrentImageProcessing: number;\n\t// Big image size threshold in pixels.\n\t// Images larger than this will be scaled down.\n\t// Default is 2560 (matching WordPress core).\n\tbigImageSizeThreshold?: number;\n\t// Default image quality (0-1) for resize/crop operations.\n\t// Default is 0.82 if not set.\n\timageQuality?: number;\n\t// Function for finalizing an upload after all client-side processing is complete.\n\t// May return the up-to-date attachment so the queue and block markup can pick\n\t// up the post-finalize URL (the scaled file), which is required for `srcset`.\n\tmediaFinalize?: (\n\t\tid: number,\n\t\tsubSizes: SubSizeData[]\n\t) => Promise< Partial< Attachment > | void >;\n\t// Whether to convert animated GIFs to video (MP4/WebM) during upload.\n\t// When enabled, animated GIFs are transcoded to video for smaller file sizes.\n\t// Default is true.\n\tgifConvert?: boolean;\n\t// Output format for GIF-to-video conversion.\n\t// Accepts 'video/mp4' or 'video/webm'. Default is 'video/mp4'.\n\tvideoOutputFormat?: 'video/mp4' | 'video/webm';\n\t// Retry settings for automatic retry on failure.\n\tretry?: RetrySettings;\n\t// Function for deleting an attachment from the server. Used to clean up\n\t// the parent attachment when client-side sub-size processing fails after\n\t// the parent file has already been uploaded.\n\tmediaDelete?: ( id: number ) => Promise< void >;\n}\n\n// Matches the Attachment type from the media-utils package.\nexport interface Attachment {\n\tid: number;\n\talt: string;\n\tcaption: string;\n\ttitle: string;\n\turl: string;\n\tfilename: string | null;\n\tfilesize: number | null;\n\tmedia_type: 'image' | 'file';\n\tmime_type: string;\n\tfeatured_media?: number;\n\tmissing_image_sizes?: string[];\n\tposter?: string;\n\tmeta?:\n\t\t| []\n\t\t| {\n\t\t\t\t[ k: string ]: unknown;\n\t\t };\n\t/**\n\t * EXIF orientation value from the original image.\n\t * Values 1-8 follow the EXIF specification.\n\t * A value other than 1 indicates the image needs rotation.\n\t *\n\t * Orientation values:\n\t * 1 = Normal (no rotation needed)\n\t * 2 = Flipped horizontally\n\t * 3 = Rotated 180°\n\t * 4 = Flipped vertically\n\t * 5 = Rotated 90° CCW and flipped horizontally\n\t * 6 = Rotated 90° CW\n\t * 7 = Rotated 90° CW and flipped horizontally\n\t * 8 = Rotated 90° CCW\n\t */\n\texif_orientation?: number;\n\t/** Output MIME type for format conversion, or null/undefined if no conversion needed. */\n\timage_output_format?: string | null;\n\t/** Whether to use progressive/interlaced encoding. */\n\timage_save_progressive?: boolean;\n\t/**\n\t * Encode quality (1-100) from the `wp_editor_set_quality` filter.\n\t * `default` applies to the full-size image; `sizes` holds per-registered-size\n\t * overrides keyed by size name, present only where they differ from `default`.\n\t */\n\timage_quality?: {\n\t\tdefault: number;\n\t\tsizes: Record< string, number >;\n\t};\n}\n\nexport type OnChangeHandler = ( attachments: Partial< Attachment >[] ) => void;\nexport type OnSuccessHandler = ( attachments: Partial< Attachment >[] ) => void;\nexport type OnErrorHandler = ( error: Error ) => void;\nexport type OnBatchSuccessHandler = () => void;\n\nexport enum ItemStatus {\n\tQueued = 'QUEUED',\n\tProcessing = 'PROCESSING',\n\tPaused = 'PAUSED',\n\tPendingRetry = 'PENDING_RETRY',\n\tUploaded = 'UPLOADED',\n\tError = 'ERROR',\n}\n\nexport enum OperationType {\n\tPrepare = 'PREPARE',\n\tUpload = 'UPLOAD',\n\tResizeCrop = 'RESIZE_CROP',\n\tRotate = 'ROTATE',\n\tTranscodeImage = 'TRANSCODE_IMAGE',\n\tTranscodeGif = 'TRANSCODE_GIF',\n\tThumbnailGeneration = 'THUMBNAIL_GENERATION',\n\tFinalize = 'FINALIZE',\n\t// UltraHDR operations\n\tDetectUltraHdr = 'DETECT_ULTRAHDR',\n}\n\n/**\n * Defines the dimensions and cropping behavior for an image size.\n */\nexport interface ImageSizeCrop {\n\t/** Target width in pixels. */\n\twidth: number;\n\t/** Target height in pixels. */\n\theight: number;\n\t/**\n\t * Crop behavior.\n\t * - `true` for hard crop centered.\n\t * - Positional array like `['left', 'top']` for specific crop anchor.\n\t * - `false` or undefined for soft proportional resize.\n\t */\n\tcrop?:\n\t\t| boolean\n\t\t| [ 'left' | 'center' | 'right', 'top' | 'center' | 'bottom' ];\n\t/** Size name identifier (e.g., 'thumbnail', 'medium'). */\n\tname?: string;\n}\n\nexport interface OperationArgs {\n\t[ OperationType.ResizeCrop ]: {\n\t\tresize: ImageSizeCrop;\n\t\t/**\n\t\t * Whether this resize is for the big image size threshold.\n\t\t * If true, uses '-scaled' suffix instead of dimension suffix.\n\t\t */\n\t\tisThresholdResize?: boolean;\n\t\t/**\n\t\t * Re-encode quality (0-1) for the resized image, derived from the\n\t\t * `wp_editor_set_quality` filter. Falls back to the vips default\n\t\t * when omitted.\n\t\t */\n\t\tquality?: number;\n\t};\n\t[ OperationType.Rotate ]: {\n\t\t/**\n\t\t * EXIF orientation value (1-8) indicating the required rotation.\n\t\t * Used to apply the correct rotation/flip transformation.\n\t\t */\n\t\torientation: number;\n\t};\n\t[ OperationType.TranscodeImage ]: {\n\t\t/** Target output format. */\n\t\toutputFormat: ImageFormat;\n\t\t/** Quality setting (0-1). */\n\t\toutputQuality: number;\n\t\t/** Whether to use interlaced encoding. */\n\t\tinterlaced: boolean;\n\t};\n\t[ OperationType.TranscodeGif ]: {\n\t\t/** Video output format: 'mp4' or 'webm'. */\n\t\toutputFormat: 'mp4' | 'webm';\n\t};\n}\n\ntype OperationWithArgs< T extends keyof OperationArgs = keyof OperationArgs > =\n\t[ T, OperationArgs[ T ] ];\n\nexport type Operation = OperationType | OperationWithArgs;\n\nexport type AdditionalData = Record< string, unknown >;\n\n/**\n * Additional data specific to sideload operations.\n *\n * This extends the base AdditionalData with fields required for\n * sideloading image sizes to an existing attachment.\n */\nexport interface SideloadAdditionalData extends AdditionalData {\n\t/** The attachment ID to add the image size to. */\n\tpost: number;\n\t/** The name(s) of the image size being generated (e.g., 'thumbnail', 'medium'). When multiple size names share the same dimensions, an array can be passed to register one file under all names. */\n\timage_size: string | string[];\n}\n\nexport type ImageFormat = 'jpeg' | 'webp' | 'avif' | 'png' | 'gif';\n\n/**\n * Configuration for automatic retry behavior on upload failures.\n */\nexport interface RetrySettings {\n\t/** Maximum number of retry attempts before giving up. */\n\tmaxRetryAttempts: number;\n\t/** Initial delay in milliseconds before the first retry. */\n\tinitialRetryDelayMs: number;\n\t/** Maximum delay in milliseconds (cap for exponential growth). */\n\tmaxRetryDelayMs: number;\n\t/** Multiplier for exponential backoff (e.g., 2 means double each time). */\n\tbackoffMultiplier: number;\n\t/** Jitter factor (0-1) to add randomness and prevent thundering herd. */\n\tretryJitter: number;\n}\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoEO,IAAK,OAAL,kBAAKA,UAAL;AACN,EAAAA,MAAA,aAAU;AACV,EAAAA,MAAA,SAAM;AACN,EAAAA,MAAA,aAAU;AACV,EAAAA,MAAA,YAAS;AACT,EAAAA,MAAA,YAAS;AACT,EAAAA,MAAA,eAAY;AACZ,EAAAA,MAAA,mBAAgB;AAChB,EAAAA,MAAA,eAAY;AACZ,EAAAA,MAAA,gBAAa;AACb,EAAAA,MAAA,gBAAa;AACb,EAAAA,MAAA,iBAAc;AACd,EAAAA,MAAA,oBAAiB;AACjB,EAAAA,MAAA,qBAAkB;AAClB,EAAAA,MAAA,mBAAgB;AAChB,EAAAA,MAAA,kBAAe;AACf,EAAAA,MAAA,oBAAiB;AACjB,EAAAA,MAAA,oBAAiB;AACjB,EAAAA,MAAA,uBAAoB;AACpB,EAAAA,MAAA,oBAAiB;AAnBN,SAAAA;AAAA,GAAA;AAsOL,IAAK,aAAL,kBAAKC,gBAAL;AACN,EAAAA,YAAA,YAAS;AACT,EAAAA,YAAA,gBAAa;AACb,EAAAA,YAAA,YAAS;AACT,EAAAA,YAAA,kBAAe;AACf,EAAAA,YAAA,cAAW;AACX,EAAAA,YAAA,WAAQ;AANG,SAAAA;AAAA,GAAA;AASL,IAAK,gBAAL,kBAAKC,mBAAL;AACN,EAAAA,eAAA,aAAU;AACV,EAAAA,eAAA,YAAS;AACT,EAAAA,eAAA,gBAAa;AACb,EAAAA,eAAA,YAAS;AACT,EAAAA,eAAA,oBAAiB;AACjB,EAAAA,eAAA,kBAAe;AACf,EAAAA,eAAA,yBAAsB;AACtB,EAAAA,eAAA,cAAW;AAEX,EAAAA,eAAA,oBAAiB;AAVN,SAAAA;AAAA,GAAA;",
"names": ["Type", "ItemStatus", "OperationType"]
}