diff -r 48c4eec2b7e6 -r 8c2e4d02f4ef wp/wp-includes/js/dist/media-utils.js --- a/wp/wp-includes/js/dist/media-utils.js Fri Sep 05 18:40:08 2025 +0200 +++ b/wp/wp-includes/js/dist/media-utils.js Fri Sep 05 18:52:52 2025 +0200 @@ -52,14 +52,19 @@ // EXPORTS __webpack_require__.d(__webpack_exports__, { MediaUpload: () => (/* reexport */ media_upload), - uploadMedia: () => (/* reexport */ uploadMedia) + privateApis: () => (/* reexport */ privateApis), + transformAttachment: () => (/* reexport */ transformAttachment), + uploadMedia: () => (/* reexport */ uploadMedia), + validateFileSize: () => (/* reexport */ validateFileSize), + validateMimeType: () => (/* reexport */ validateMimeType), + validateMimeTypeForUser: () => (/* reexport */ validateMimeTypeForUser) }); -;// CONCATENATED MODULE: external ["wp","element"] +;// external ["wp","element"] const external_wp_element_namespaceObject = window["wp"]["element"]; -;// CONCATENATED MODULE: external ["wp","i18n"] +;// external ["wp","i18n"] const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; -;// CONCATENATED MODULE: ./node_modules/@wordpress/media-utils/build-module/components/media-upload/index.js +;// ./node_modules/@wordpress/media-utils/build-module/components/media-upload/index.js /** * WordPress dependencies */ @@ -123,6 +128,45 @@ }; /** + * Prepares the default frame for selecting a single media item. + * + * @return {window.wp.media.view.MediaFrame.Select} The default media workflow. + */ +const getSingleMediaFrame = () => { + const { + wp + } = window; + + // Extend the default Select frame, and use the same `createStates` method as in core, + // but with the addition of `filterable: 'uploaded'` to the Library state, so that + // the user can filter the media library by uploaded media. + return wp.media.view.MediaFrame.Select.extend({ + /** + * Create the default states on the frame. + */ + createStates() { + const options = this.options; + if (this.options.states) { + return; + } + + // Add the default states. + this.states.add([ + // Main states. + new wp.media.controller.Library({ + library: wp.media.query(options.library), + multiple: options.multiple, + title: options.title, + priority: 20, + filterable: 'uploaded' // Allow filtering by uploaded images. + }), new wp.media.controller.EditImage({ + model: options.editImage + })]); + } + }); +}; + +/** * Prepares the Gallery toolbars and frames. * * @return {window.wp.media.view.MediaFrame.Post} The default media workflow. @@ -311,7 +355,7 @@ state: currentState, multiple, selection, - editing: value && value.length ? true : false + editing: !!value?.length }); wp.media.frame = this.frame; this.initializeListeners(); @@ -353,6 +397,49 @@ featuredImageId: featuredImageId || -1 }; } + + /** + * Initializes the Media Library requirements for the single image flow. + * + * @return {void} + */ + buildAndSetSingleMediaFrame() { + const { + wp + } = window; + const { + allowedTypes, + multiple = false, + title = (0,external_wp_i18n_namespaceObject.__)('Select or Upload Media'), + value + } = this.props; + const frameConfig = { + title, + multiple + }; + if (!!allowedTypes) { + frameConfig.library = { + type: allowedTypes + }; + } + + // If a frame already exists, remove it. + if (this.frame) { + this.frame.remove(); + } + const singleImageFrame = getSingleMediaFrame(); + const attachments = getAttachmentsCollection(value); + const selection = new wp.media.model.Selection(attachments.models, { + props: attachments.props.toJSON() + }); + this.frame = new singleImageFrame({ + mimeType: allowedTypes, + multiple, + selection, + ...frameConfig + }); + wp.media.frame = this.frame; + } componentWillUnmount() { this.frame?.remove(); } @@ -427,6 +514,7 @@ if (onClose) { onClose(); } + this.frame.detach(); } updateCollection() { const frameContent = this.frame.content.get(); @@ -445,29 +533,14 @@ } openModal() { const { - allowedTypes, gallery = false, unstableFeaturedImageFlow = false, - modalClass, - multiple = false, - title = (0,external_wp_i18n_namespaceObject.__)('Select or Upload Media') + modalClass } = this.props; - const { - wp - } = window; if (gallery) { this.buildAndSetGalleryFrame(); } else { - const frameConfig = { - title, - multiple - }; - if (!!allowedTypes) { - frameConfig.library = { - type: allowedTypes - }; - } - this.frame = wp.media(frameConfig); + this.buildAndSetSingleMediaFrame(); } if (modalClass) { this.frame.$el.addClass(modalClass); @@ -486,223 +559,505 @@ } /* harmony default export */ const media_upload = (MediaUpload); -;// CONCATENATED MODULE: ./node_modules/@wordpress/media-utils/build-module/components/index.js +;// ./node_modules/@wordpress/media-utils/build-module/components/index.js + + +;// external ["wp","blob"] +const external_wp_blob_namespaceObject = window["wp"]["blob"]; +;// external ["wp","apiFetch"] +const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"]; +var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject); +;// ./node_modules/@wordpress/media-utils/build-module/utils/flatten-form-data.js +/** + * Determines whether the passed argument appears to be a plain object. + * + * @param data The object to inspect. + */ +function isPlainObject(data) { + return data !== null && typeof data === 'object' && Object.getPrototypeOf(data) === Object.prototype; +} + +/** + * Recursively flatten data passed to form data, to allow using multi-level objects. + * + * @param {FormData} formData Form data object. + * @param {string} key Key to amend to form data object + * @param {string|Object} data Data to be amended to form data. + */ +function flattenFormData(formData, key, data) { + if (isPlainObject(data)) { + for (const [name, value] of Object.entries(data)) { + flattenFormData(formData, `${key}[${name}]`, value); + } + } else if (data !== undefined) { + formData.append(key, String(data)); + } +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/transform-attachment.js +/** + * Internal dependencies + */ + +/** + * Transforms an attachment object from the REST API shape into the shape expected by the block editor and other consumers. + * + * @param attachment REST API attachment object. + */ +function transformAttachment(attachment) { + var _attachment$caption$r; + // eslint-disable-next-line camelcase + const { + alt_text, + source_url, + ...savedMediaProps + } = attachment; + return { + ...savedMediaProps, + alt: attachment.alt_text, + caption: (_attachment$caption$r = attachment.caption?.raw) !== null && _attachment$caption$r !== void 0 ? _attachment$caption$r : '', + title: attachment.title.raw, + url: attachment.source_url, + poster: attachment._embedded?.['wp:featuredmedia']?.[0]?.source_url || undefined + }; +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/upload-to-server.js +/** + * WordPress dependencies + */ + + +/** + * Internal dependencies + */ + + +async function uploadToServer(file, additionalData = {}, signal) { + // Create upload payload. + const data = new FormData(); + data.append('file', file, file.name || file.type.replace('/', '.')); + for (const [key, value] of Object.entries(additionalData)) { + flattenFormData(data, key, value); + } + return transformAttachment(await external_wp_apiFetch_default()({ + // This allows the video block to directly get a video's poster image. + path: '/wp/v2/media?_embed=wp:featuredmedia', + body: data, + method: 'POST', + signal + })); +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/upload-error.js +/** + * MediaError class. + * + * Small wrapper around the `Error` class + * to hold an error code and a reference to a file object. + */ +class UploadError extends Error { + constructor({ + code, + message, + file, + cause + }) { + super(message, { + cause + }); + Object.setPrototypeOf(this, new.target.prototype); + this.code = code; + this.file = file; + } +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/validate-mime-type.js +/** + * WordPress dependencies + */ + + +/** + * Internal dependencies + */ -;// CONCATENATED MODULE: external ["wp","apiFetch"] -const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"]; -var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject); -;// CONCATENATED MODULE: external ["wp","blob"] -const external_wp_blob_namespaceObject = window["wp"]["blob"]; -;// CONCATENATED MODULE: ./node_modules/@wordpress/media-utils/build-module/utils/upload-media.js +/** + * Verifies if the caller (e.g. a block) supports this mime type. + * + * @param file File object. + * @param allowedTypes List of allowed mime types. + */ +function validateMimeType(file, allowedTypes) { + if (!allowedTypes) { + return; + } + + // Allowed type specified by consumer. + const isAllowedType = allowedTypes.some(allowedType => { + // If a complete mimetype is specified verify if it matches exactly the mime type of the file. + if (allowedType.includes('/')) { + return allowedType === file.type; + } + // Otherwise a general mime type is used, and we should verify if the file mimetype starts with it. + return file.type.startsWith(`${allowedType}/`); + }); + if (file.type && !isAllowedType) { + throw new UploadError({ + code: 'MIME_TYPE_NOT_SUPPORTED', + message: (0,external_wp_i18n_namespaceObject.sprintf)( + // translators: %s: file name. + (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, this file type is not supported here.'), file.name), + file + }); + } +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/get-mime-types-array.js +/** + * Browsers may use unexpected mime types, and they differ from browser to browser. + * This function computes a flexible array of mime types from the mime type structured provided by the server. + * Converts { jpg|jpeg|jpe: "image/jpeg" } into [ "image/jpeg", "image/jpg", "image/jpeg", "image/jpe" ] + * + * @param {?Object} wpMimeTypesObject Mime type object received from the server. + * Extensions are keys separated by '|' and values are mime types associated with an extension. + * + * @return An array of mime types or null + */ +function getMimeTypesArray(wpMimeTypesObject) { + if (!wpMimeTypesObject) { + return null; + } + return Object.entries(wpMimeTypesObject).flatMap(([extensionsString, mime]) => { + const [type] = mime.split('/'); + const extensions = extensionsString.split('|'); + return [mime, ...extensions.map(extension => `${type}/${extension}`)]; + }); +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/validate-mime-type-for-user.js +/** + * WordPress dependencies + */ + + +/** + * Internal dependencies + */ + + + +/** + * Verifies if the user is allowed to upload this mime type. + * + * @param file File object. + * @param wpAllowedMimeTypes List of allowed mime types and file extensions. + */ +function validateMimeTypeForUser(file, wpAllowedMimeTypes) { + // Allowed types for the current WP_User. + const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes); + if (!allowedMimeTypesForUser) { + return; + } + const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(file.type); + if (file.type && !isAllowedMimeTypeForUser) { + throw new UploadError({ + code: 'MIME_TYPE_NOT_ALLOWED_FOR_USER', + message: (0,external_wp_i18n_namespaceObject.sprintf)( + // translators: %s: file name. + (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, you are not allowed to upload this file type.'), file.name), + file + }); + } +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/validate-file-size.js +/** + * WordPress dependencies + */ + + +/** + * Internal dependencies + */ + + +/** + * Verifies whether the file is within the file upload size limits for the site. + * + * @param file File object. + * @param maxUploadFileSize Maximum upload size in bytes allowed for the site. + */ +function validateFileSize(file, maxUploadFileSize) { + // Don't allow empty files to be uploaded. + if (file.size <= 0) { + throw new UploadError({ + code: 'EMPTY_FILE', + message: (0,external_wp_i18n_namespaceObject.sprintf)( + // translators: %s: file name. + (0,external_wp_i18n_namespaceObject.__)('%s: This file is empty.'), file.name), + file + }); + } + if (maxUploadFileSize && file.size > maxUploadFileSize) { + throw new UploadError({ + code: 'SIZE_ABOVE_LIMIT', + message: (0,external_wp_i18n_namespaceObject.sprintf)( + // translators: %s: file name. + (0,external_wp_i18n_namespaceObject.__)('%s: This file exceeds the maximum upload size for this site.'), file.name), + file + }); + } +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/upload-media.js /** * WordPress dependencies */ -const noop = () => {}; +/** + * Internal dependencies + */ + + + + + /** - * Browsers may use unexpected mime types, and they differ from browser to browser. - * This function computes a flexible array of mime types from the mime type structured provided by the server. - * Converts { jpg|jpeg|jpe: "image/jpeg" } into [ "image/jpeg", "image/jpg", "image/jpeg", "image/jpe" ] - * The computation of this array instead of directly using the object, - * solves the problem in chrome where mp3 files have audio/mp3 as mime type instead of audio/mpeg. - * https://bugs.chromium.org/p/chromium/issues/detail?id=227004 + * Upload a media file when the file upload button is activated + * or when adding a file to the editor via drag & drop. * - * @param {?Object} wpMimeTypesObject Mime type object received from the server. - * Extensions are keys separated by '|' and values are mime types associated with an extension. - * - * @return {?Array} An array of mime types or the parameter passed if it was "falsy". + * @param $0 Parameters object passed to the function. + * @param $0.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed. + * @param $0.additionalData Additional data to include in the request. + * @param $0.filesList List of files. + * @param $0.maxUploadFileSize Maximum upload size in bytes allowed for the site. + * @param $0.onError Function called when an error happens. + * @param $0.onFileChange Function called each time a file or a temporary representation of the file is available. + * @param $0.wpAllowedMimeTypes List of allowed mime types and file extensions. + * @param $0.signal Abort signal. + * @param $0.multiple Whether to allow multiple files to be uploaded. */ -function getMimeTypesArray(wpMimeTypesObject) { - if (!wpMimeTypesObject) { - return wpMimeTypesObject; - } - return Object.entries(wpMimeTypesObject).map(([extensionsString, mime]) => { - const [type] = mime.split('/'); - const extensions = extensionsString.split('|'); - return [mime, ...extensions.map(extension => `${type}/${extension}`)]; - }).flat(); -} - -/** - * Media Upload is used by audio, image, gallery, video, and file blocks to - * handle uploading a media file when a file upload button is activated. - * - * TODO: future enhancement to add an upload indicator. - * - * @param {Object} $0 Parameters object passed to the function. - * @param {?Array} $0.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed. - * @param {?Object} $0.additionalData Additional data to include in the request. - * @param {Array} $0.filesList List of files. - * @param {?number} $0.maxUploadFileSize Maximum upload size in bytes allowed for the site. - * @param {Function} $0.onError Function called when an error happens. - * @param {Function} $0.onFileChange Function called each time a file or a temporary representation of the file is available. - * @param {?Object} $0.wpAllowedMimeTypes List of allowed mime types and file extensions. - */ -async function uploadMedia({ +function uploadMedia({ + wpAllowedMimeTypes, allowedTypes, additionalData = {}, filesList, maxUploadFileSize, - onError = noop, + onError, onFileChange, - wpAllowedMimeTypes = null + signal, + multiple = true }) { - // Cast filesList to array. - const files = [...filesList]; + if (!multiple && filesList.length > 1) { + onError?.(new Error((0,external_wp_i18n_namespaceObject.__)('Only one file can be used here.'))); + return; + } + const validFiles = []; const filesSet = []; - const setAndUpdateFiles = (idx, value) => { - (0,external_wp_blob_namespaceObject.revokeBlobURL)(filesSet[idx]?.url); - filesSet[idx] = value; - onFileChange(filesSet.filter(Boolean)); - }; - - // Allowed type specified by consumer. - const isAllowedType = fileType => { - if (!allowedTypes) { - return true; + const setAndUpdateFiles = (index, value) => { + // For client-side media processing, this is handled by the upload-media package. + if (!window.__experimentalMediaProcessing) { + if (filesSet[index]?.url) { + (0,external_wp_blob_namespaceObject.revokeBlobURL)(filesSet[index].url); + } } - return allowedTypes.some(allowedType => { - // If a complete mimetype is specified verify if it matches exactly the mime type of the file. - if (allowedType.includes('/')) { - return allowedType === fileType; - } - // Otherwise a general mime type is used and we should verify if the file mimetype starts with it. - return fileType.startsWith(`${allowedType}/`); - }); + filesSet[index] = value; + onFileChange?.(filesSet.filter(attachment => attachment !== null)); }; - - // Allowed types for the current WP_User. - const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes); - const isAllowedMimeTypeForUser = fileType => { - return allowedMimeTypesForUser.includes(fileType); - }; - const validFiles = []; - for (const mediaFile of files) { + for (const mediaFile of filesList) { // Verify if user is allowed to upload this mime type. // Defer to the server when type not detected. - if (allowedMimeTypesForUser && mediaFile.type && !isAllowedMimeTypeForUser(mediaFile.type)) { - onError({ - code: 'MIME_TYPE_NOT_ALLOWED_FOR_USER', - message: (0,external_wp_i18n_namespaceObject.sprintf)( - // translators: %s: file name. - (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, you are not allowed to upload this file type.'), mediaFile.name), - file: mediaFile - }); + try { + validateMimeTypeForUser(mediaFile, wpAllowedMimeTypes); + } catch (error) { + onError?.(error); continue; } - // Check if the block supports this mime type. + // Check if the caller (e.g. a block) supports this mime type. // Defer to the server when type not detected. - if (mediaFile.type && !isAllowedType(mediaFile.type)) { - onError({ - code: 'MIME_TYPE_NOT_SUPPORTED', - message: (0,external_wp_i18n_namespaceObject.sprintf)( - // translators: %s: file name. - (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, this file type is not supported here.'), mediaFile.name), - file: mediaFile - }); + try { + validateMimeType(mediaFile, allowedTypes); + } catch (error) { + onError?.(error); continue; } // Verify if file is greater than the maximum file upload size allowed for the site. - if (maxUploadFileSize && mediaFile.size > maxUploadFileSize) { - onError({ - code: 'SIZE_ABOVE_LIMIT', - message: (0,external_wp_i18n_namespaceObject.sprintf)( - // translators: %s: file name. - (0,external_wp_i18n_namespaceObject.__)('%s: This file exceeds the maximum upload size for this site.'), mediaFile.name), - file: mediaFile - }); - continue; - } - - // Don't allow empty files to be uploaded. - if (mediaFile.size <= 0) { - onError({ - code: 'EMPTY_FILE', - message: (0,external_wp_i18n_namespaceObject.sprintf)( - // translators: %s: file name. - (0,external_wp_i18n_namespaceObject.__)('%s: This file is empty.'), mediaFile.name), - file: mediaFile - }); + try { + validateFileSize(mediaFile, maxUploadFileSize); + } catch (error) { + onError?.(error); continue; } validFiles.push(mediaFile); - // Set temporary URL to create placeholder media file, this is replaced - // with final file from media gallery when upload is `done` below. - filesSet.push({ - url: (0,external_wp_blob_namespaceObject.createBlobURL)(mediaFile) - }); - onFileChange(filesSet); + // For client-side media processing, this is handled by the upload-media package. + if (!window.__experimentalMediaProcessing) { + // Set temporary URL to create placeholder media file, this is replaced + // with final file from media gallery when upload is `done` below. + filesSet.push({ + url: (0,external_wp_blob_namespaceObject.createBlobURL)(mediaFile) + }); + onFileChange?.(filesSet); + } } - for (let idx = 0; idx < validFiles.length; ++idx) { - const mediaFile = validFiles[idx]; + validFiles.map(async (file, index) => { try { - var _savedMedia$caption$r; - const savedMedia = await createMediaFromFile(mediaFile, additionalData); - // eslint-disable-next-line camelcase - const { - alt_text, - source_url, - ...savedMediaProps - } = savedMedia; - const mediaObject = { - ...savedMediaProps, - alt: savedMedia.alt_text, - caption: (_savedMedia$caption$r = savedMedia.caption?.raw) !== null && _savedMedia$caption$r !== void 0 ? _savedMedia$caption$r : '', - title: savedMedia.title.raw, - url: savedMedia.source_url - }; - setAndUpdateFiles(idx, mediaObject); + const attachment = await uploadToServer(file, additionalData, signal); + setAndUpdateFiles(index, attachment); } catch (error) { // Reset to empty on failure. - setAndUpdateFiles(idx, null); + setAndUpdateFiles(index, null); + + // @wordpress/api-fetch throws any response that isn't in the 200 range as-is. let message; - if (error.message) { - message = error.message; + if (typeof error === 'object' && error !== null && 'message' in error) { + message = typeof error.message === 'string' ? error.message : String(error.message); } else { message = (0,external_wp_i18n_namespaceObject.sprintf)( // translators: %s: file name - (0,external_wp_i18n_namespaceObject.__)('Error while uploading file %s to the media library.'), mediaFile.name); + (0,external_wp_i18n_namespaceObject.__)('Error while uploading file %s to the media library.'), file.name); } - onError({ + onError?.(new UploadError({ code: 'GENERAL', message, - file: mediaFile - }); + file, + cause: error instanceof Error ? error : undefined + })); } + }); +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/sideload-to-server.js +/** + * WordPress dependencies + */ + + +/** + * Internal dependencies + */ + + + + +/** + * Uploads a file to the server without creating an attachment. + * + * @param file Media File to Save. + * @param attachmentId Parent attachment ID. + * @param additionalData Additional data to include in the request. + * @param signal Abort signal. + * + * @return The saved attachment. + */ +async function sideloadToServer(file, attachmentId, additionalData = {}, signal) { + // Create upload payload. + const data = new FormData(); + data.append('file', file, file.name || file.type.replace('/', '.')); + for (const [key, value] of Object.entries(additionalData)) { + flattenFormData(data, key, value); + } + return transformAttachment(await external_wp_apiFetch_default()({ + path: `/wp/v2/media/${attachmentId}/sideload`, + body: data, + method: 'POST', + signal + })); +} + +;// ./node_modules/@wordpress/media-utils/build-module/utils/sideload-media.js +/** + * WordPress dependencies + */ + + +/** + * Internal dependencies + */ + + + +const noop = () => {}; +/** + * Uploads a file to the server without creating an attachment. + * + * @param $0 Parameters object passed to the function. + * @param $0.file Media File to Save. + * @param $0.attachmentId Parent attachment ID. + * @param $0.additionalData Additional data to include in the request. + * @param $0.signal Abort signal. + * @param $0.onFileChange Function called each time a file or a temporary representation of the file is available. + * @param $0.onError Function called when an error happens. + */ +async function sideloadMedia({ + file, + attachmentId, + additionalData = {}, + signal, + onFileChange, + onError = noop +}) { + try { + const attachment = await sideloadToServer(file, attachmentId, additionalData, signal); + onFileChange?.([attachment]); + } catch (error) { + let message; + if (error instanceof Error) { + message = error.message; + } else { + message = (0,external_wp_i18n_namespaceObject.sprintf)( + // translators: %s: file name + (0,external_wp_i18n_namespaceObject.__)('Error while sideloading file %s to the server.'), file.name); + } + onError(new UploadError({ + code: 'GENERAL', + message, + file, + cause: error instanceof Error ? error : undefined + })); } } +;// external ["wp","privateApis"] +const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; +;// ./node_modules/@wordpress/media-utils/build-module/lock-unlock.js /** - * @param {File} file Media File to Save. - * @param {?Object} additionalData Additional data to include in the request. - * - * @return {Promise} Media Object Promise. + * WordPress dependencies */ -function createMediaFromFile(file, additionalData) { - // Create upload payload. - const data = new window.FormData(); - data.append('file', file, file.name || file.type.replace('/', '.')); - if (additionalData) { - Object.entries(additionalData).forEach(([key, value]) => data.append(key, value)); - } - return external_wp_apiFetch_default()({ - path: '/wp/v2/media', - body: data, - method: 'POST' - }); -} -;// CONCATENATED MODULE: ./node_modules/@wordpress/media-utils/build-module/utils/index.js +const { + lock, + unlock +} = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/media-utils'); + +;// ./node_modules/@wordpress/media-utils/build-module/private-apis.js +/** + * Internal dependencies + */ -;// CONCATENATED MODULE: ./node_modules/@wordpress/media-utils/build-module/index.js + +/** + * Private @wordpress/media-utils APIs. + */ +const privateApis = {}; +lock(privateApis, { + sideloadMedia: sideloadMedia +}); + +;// ./node_modules/@wordpress/media-utils/build-module/index.js + + + + +