: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Each function is passed an object containing
* `saveEntityRecord`, `saveEditedEntityRecord`, and
* @return {(thunkArgs: Object) => Promise} A promise that resolves to an array containing the return
* values of each function given in `requests`.
const __experimentalBatch = requests => async ({
const batch = createBatch();
saveEntityRecord(kind, name, record, options) {
return batch.add(add => dispatch.saveEntityRecord(kind, name, record, {
saveEditedEntityRecord(kind, name, recordId, options) {
return batch.add(add => dispatch.saveEditedEntityRecord(kind, name, recordId, {
deleteEntityRecord(kind, name, recordId, query, options) {
return batch.add(add => dispatch.deleteEntityRecord(kind, name, recordId, query, {
const resultPromises = requests.map(request => request(api));
const [, ...results] = await Promise.all([batch.run(), ...resultPromises]);
* Action triggered to save an entity record's edits.
* @param {string} kind Kind of the entity.
* @param {string} name Name of the entity.
* @param {Object} recordId ID of the record.
* @param {Object} options Saving options.
const saveEditedEntityRecord = (kind, name, recordId, options) => async ({
if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
const configs = await dispatch(getOrLoadEntitiesConfig(kind, name));
const entityConfig = configs.find(config => config.kind === kind && config.name === name);
const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
return await dispatch.saveEntityRecord(kind, name, record, options);
* Action triggered to save only specified properties for the entity.
* @param {string} kind Kind of the entity.
* @param {string} name Name of the entity.
* @param {Object} recordId ID of the record.
* @param {Array} itemsToSave List of entity properties or property paths to save.
* @param {Object} options Saving options.
const __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({
if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
for (const item of itemsToSave) {
setNestedValue(editsToSave, item, getNestedValue(edits, item));
const configs = await dispatch(getOrLoadEntitiesConfig(kind, name));
const entityConfig = configs.find(config => config.kind === kind && config.name === name);
const entityIdKey = entityConfig?.key || DEFAULT_ENTITY_KEY;
// If a record key is provided then update the existing record.
// This necessitates providing `recordKey` to saveEntityRecord as part of the
// `record` argument (here called `editsToSave`) to stop that action creating
// a new record and instead cause it to update the existing record.
editsToSave[entityIdKey] = recordId;
return await dispatch.saveEntityRecord(kind, name, editsToSave, options);
* Returns an action object used in signalling that Upload permissions have been received.
* @deprecated since WP 5.9, use receiveUserPermission instead.
* @param {boolean} hasUploadPermissions Does the user have permission to upload files?
* @return {Object} Action object.
function receiveUploadPermissions(hasUploadPermissions) {
external_wp_deprecated_default()("wp.data.dispatch( 'core' ).receiveUploadPermissions", {
alternative: 'receiveUserPermission'
return receiveUserPermission('create/media', hasUploadPermissions);
* Returns an action object used in signalling that the current user has
* permission to perform an action on a REST resource.
* Ignored from documentation as it's internal to the data store.
* @param {string} key A key that represents the action and REST resource.
* @param {boolean} isAllowed Whether or not the user can perform the action.
* @return {Object} Action object.
function receiveUserPermission(key, isAllowed) {
type: 'RECEIVE_USER_PERMISSION',
* Returns an action object used in signalling that the autosaves for a
* post have been received.
* Ignored from documentation as it's internal to the data store.
* @param {number} postId The id of the post that is parent to the autosave.
* @param {Array|Object} autosaves An array of autosaves or singular autosave object.
* @return {Object} Action object.
function receiveAutosaves(postId, autosaves) {
type: 'RECEIVE_AUTOSAVES',
autosaves: Array.isArray(autosaves) ? autosaves : [autosaves]
* Returns an action object signalling that the fallback Navigation
* Menu id has been received.
* @param {integer} fallbackId the id of the fallback Navigation Menu
* @return {Object} Action object.
function receiveNavigationFallbackId(fallbackId) {
type: 'RECEIVE_NAVIGATION_FALLBACK_ID',
* Returns an action object used to set the template for a given query.
* @param {Object} query The lookup query.
* @param {string} templateId The resolved template id.
* @return {Object} Action object.
function receiveDefaultTemplateId(query, templateId) {
type: 'RECEIVE_DEFAULT_TEMPLATE',
* Action triggered to receive revision items.
* @param {string} kind Kind of the received entity record revisions.
* @param {string} name Name of the received entity record revisions.
* @param {number|string} recordKey The key of the entity record whose revisions you want to fetch.
* @param {Array|Object} records Revisions received.
* @param {?Object} query Query Object.
* @param {?boolean} invalidateCache Should invalidate query caches.
* @param {?Object} meta Meta information about pagination.
const receiveRevisions = (kind, name, recordKey, records, query, invalidateCache = false, meta) => async ({
const configs = await dispatch(getOrLoadEntitiesConfig(kind, name));
const entityConfig = configs.find(config => config.kind === kind && config.name === name);
const key = entityConfig && entityConfig?.revisionKey ? entityConfig.revisionKey : DEFAULT_ENTITY_KEY;
type: 'RECEIVE_ITEM_REVISIONS',
items: Array.isArray(records) ? records : [records],
;// CONCATENATED MODULE: ./node_modules/@wordpress/core-data/build-module/entities.js
const DEFAULT_ENTITY_KEY = 'id';
const POST_RAW_ATTRIBUTES = ['title', 'excerpt', 'content'];
const rootEntitiesConfig = [{
label: (0,external_wp_i18n_namespaceObject.__)('Base'),
_fields: ['description', 'gmt_offset', 'home', 'name', 'site_icon', 'site_icon_url', 'site_logo', 'timezone_string', 'url'].join(',')
// The entity doesn't support selecting multiple records.
// The property is maintained for backward compatibility.
plural: '__unstableBases',
return external_wp_apiFetch_default()({
applyChangesToDoc: (doc, changes) => {
const document = doc.getMap('document');
Object.entries(changes).forEach(([key, value]) => {
if (document.get(key) !== value) {
document.set(key, value);
return doc.getMap('document').toJSON();
syncObjectType: 'root/base',
getSyncObjectId: () => 'index'
label: (0,external_wp_i18n_namespaceObject.__)('Post Type'),
return external_wp_apiFetch_default()({
path: `/wp/v2/types/${id}?context=edit`
applyChangesToDoc: (doc, changes) => {
const document = doc.getMap('document');
Object.entries(changes).forEach(([key, value]) => {
if (document.get(key) !== value) {
document.set(key, value);
return doc.getMap('document').toJSON();
syncObjectType: 'root/postType',
getSyncObjectId: id => id
label: (0,external_wp_i18n_namespaceObject.__)('Media'),
rawAttributes: ['caption', 'title', 'description'],
baseURL: '/wp/v2/taxonomies',
label: (0,external_wp_i18n_namespaceObject.__)('Taxonomy')
baseURL: '/wp/v2/sidebars',
label: (0,external_wp_i18n_namespaceObject.__)('Widget areas')
baseURL: '/wp/v2/widgets',
label: (0,external_wp_i18n_namespaceObject.__)('Widgets')
baseURL: '/wp/v2/widget-types',
label: (0,external_wp_i18n_namespaceObject.__)('Widget types')
label: (0,external_wp_i18n_namespaceObject.__)('User'),
baseURL: '/wp/v2/comments',
label: (0,external_wp_i18n_namespaceObject.__)('Comment')
label: (0,external_wp_i18n_namespaceObject.__)('Menu')
baseURL: '/wp/v2/menu-items',
label: (0,external_wp_i18n_namespaceObject.__)('Menu Item'),
baseURL: '/wp/v2/menu-locations',
label: (0,external_wp_i18n_namespaceObject.__)('Menu Location'),
label: (0,external_wp_i18n_namespaceObject.__)('Global Styles'),
baseURL: '/wp/v2/global-styles',
plural: 'globalStylesVariations',
// Should be different from name.
getTitle: record => record?.title?.rendered || record?.title,
getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/${parentId}/revisions${revisionId ? '/' + revisionId : ''}`,
label: (0,external_wp_i18n_namespaceObject.__)('Themes'),
baseURL: '/wp/v2/themes',
label: (0,external_wp_i18n_namespaceObject.__)('Plugins'),
baseURL: '/wp/v2/plugins',
label: (0,external_wp_i18n_namespaceObject.__)('Status'),
baseURL: '/wp/v2/statuses',
const additionalEntityConfigLoaders = [{
loadEntities: loadPostTypeEntities
loadEntities: loadTaxonomyEntities
loadEntities: loadSiteEntity
* Returns a function to be used to retrieve extra edits to apply before persisting a post type.
* @param {Object} persistedRecord Already persisted Post
* @param {Object} edits Edits.
* @return {Object} Updated edits.
const prePersistPostType = (persistedRecord, edits) => {
if (persistedRecord?.status === 'auto-draft') {
// Saving an auto-draft should create a draft by default.
if (!edits.status && !newEdits.status) {
newEdits.status = 'draft';
// Fix the auto-draft default title.
if ((!edits.title || edits.title === 'Auto Draft') && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === 'Auto Draft')) {
const serialisableBlocksCache = new WeakMap();
function makeBlockAttributesSerializable(attributes) {
for (const [key, value] of Object.entries(attributes)) {
if (value instanceof external_wp_richText_namespaceObject.RichTextData) {
newAttributes[key] = value.valueOf();
function makeBlocksSerializable(blocks) {
return blocks.map(block => {
attributes: makeBlockAttributesSerializable(attributes),