@wordpress/core-data
Version:
Access to and manipulation of core WordPress entities.
482 lines (473 loc) • 13.2 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.rootEntitiesConfig = exports.prePersistPostType = exports.getMethodName = exports.deprecatedEntities = exports.additionalEntityConfigLoaders = exports.DEFAULT_ENTITY_KEY = void 0;
var _changeCase = require("change-case");
var _apiFetch = _interopRequireDefault(require("@wordpress/api-fetch"));
var _i18n = require("@wordpress/i18n");
var _richText = require("@wordpress/rich-text");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
const DEFAULT_ENTITY_KEY = exports.DEFAULT_ENTITY_KEY = 'id';
const POST_RAW_ATTRIBUTES = ['title', 'excerpt', 'content'];
const rootEntitiesConfig = exports.rootEntitiesConfig = [{
label: (0, _i18n.__)('Base'),
kind: 'root',
name: '__unstableBase',
baseURL: '/',
baseURLParams: {
// Please also change the preload path when changing this.
// @see lib/compat/wordpress-6.8/preload.php
_fields: ['description', 'gmt_offset', 'home', 'name', 'site_icon', 'site_icon_url', 'site_logo', 'timezone_string', 'url', 'page_for_posts', 'page_on_front', 'show_on_front'].join(',')
},
// The entity doesn't support selecting multiple records.
// The property is maintained for backward compatibility.
plural: '__unstableBases',
syncConfig: {
fetch: async () => {
return (0, _apiFetch.default)({
path: '/'
});
},
applyChangesToDoc: (doc, changes) => {
const document = doc.getMap('document');
Object.entries(changes).forEach(([key, value]) => {
if (document.get(key) !== value) {
document.set(key, value);
}
});
},
fromCRDTDoc: doc => {
return doc.getMap('document').toJSON();
}
},
syncObjectType: 'root/base',
getSyncObjectId: () => 'index'
}, {
label: (0, _i18n.__)('Post Type'),
name: 'postType',
kind: 'root',
key: 'slug',
baseURL: '/wp/v2/types',
baseURLParams: {
context: 'edit'
},
plural: 'postTypes',
syncConfig: {
fetch: async id => {
return (0, _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);
}
});
},
fromCRDTDoc: doc => {
return doc.getMap('document').toJSON();
}
},
syncObjectType: 'root/postType',
getSyncObjectId: id => id
}, {
name: 'media',
kind: 'root',
baseURL: '/wp/v2/media',
baseURLParams: {
context: 'edit'
},
plural: 'mediaItems',
label: (0, _i18n.__)('Media'),
rawAttributes: ['caption', 'title', 'description'],
supportsPagination: true
}, {
name: 'taxonomy',
kind: 'root',
key: 'slug',
baseURL: '/wp/v2/taxonomies',
baseURLParams: {
context: 'edit'
},
plural: 'taxonomies',
label: (0, _i18n.__)('Taxonomy')
}, {
name: 'sidebar',
kind: 'root',
baseURL: '/wp/v2/sidebars',
baseURLParams: {
context: 'edit'
},
plural: 'sidebars',
transientEdits: {
blocks: true
},
label: (0, _i18n.__)('Widget areas')
}, {
name: 'widget',
kind: 'root',
baseURL: '/wp/v2/widgets',
baseURLParams: {
context: 'edit'
},
plural: 'widgets',
transientEdits: {
blocks: true
},
label: (0, _i18n.__)('Widgets')
}, {
name: 'widgetType',
kind: 'root',
baseURL: '/wp/v2/widget-types',
baseURLParams: {
context: 'edit'
},
plural: 'widgetTypes',
label: (0, _i18n.__)('Widget types')
}, {
label: (0, _i18n.__)('User'),
name: 'user',
kind: 'root',
baseURL: '/wp/v2/users',
getTitle: record => record?.name || record?.slug,
baseURLParams: {
context: 'edit'
},
plural: 'users',
supportsPagination: true
}, {
name: 'comment',
kind: 'root',
baseURL: '/wp/v2/comments',
baseURLParams: {
context: 'edit'
},
plural: 'comments',
label: (0, _i18n.__)('Comment'),
supportsPagination: true
}, {
name: 'menu',
kind: 'root',
baseURL: '/wp/v2/menus',
baseURLParams: {
context: 'edit'
},
plural: 'menus',
label: (0, _i18n.__)('Menu'),
supportsPagination: true
}, {
name: 'menuItem',
kind: 'root',
baseURL: '/wp/v2/menu-items',
baseURLParams: {
context: 'edit'
},
plural: 'menuItems',
label: (0, _i18n.__)('Menu Item'),
rawAttributes: ['title'],
supportsPagination: true
}, {
name: 'menuLocation',
kind: 'root',
baseURL: '/wp/v2/menu-locations',
baseURLParams: {
context: 'edit'
},
plural: 'menuLocations',
label: (0, _i18n.__)('Menu Location'),
key: 'name'
}, {
label: (0, _i18n.__)('Global Styles'),
name: 'globalStyles',
kind: 'root',
baseURL: '/wp/v2/global-styles',
baseURLParams: {
context: 'edit'
},
plural: 'globalStylesVariations',
// Should be different from name.
getTitle: () => (0, _i18n.__)('Custom Styles'),
getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/${parentId}/revisions${revisionId ? '/' + revisionId : ''}`,
supportsPagination: true
}, {
label: (0, _i18n.__)('Themes'),
name: 'theme',
kind: 'root',
baseURL: '/wp/v2/themes',
baseURLParams: {
context: 'edit'
},
plural: 'themes',
key: 'stylesheet'
}, {
label: (0, _i18n.__)('Plugins'),
name: 'plugin',
kind: 'root',
baseURL: '/wp/v2/plugins',
baseURLParams: {
context: 'edit'
},
plural: 'plugins',
key: 'plugin'
}, {
label: (0, _i18n.__)('Status'),
name: 'status',
kind: 'root',
baseURL: '/wp/v2/statuses',
baseURLParams: {
context: 'edit'
},
plural: 'statuses',
key: 'slug'
}];
const deprecatedEntities = exports.deprecatedEntities = {
root: {
media: {
since: '6.9',
alternative: {
kind: 'postType',
name: 'attachment'
}
}
}
};
const additionalEntityConfigLoaders = exports.additionalEntityConfigLoaders = [{
kind: 'postType',
loadEntities: loadPostTypeEntities
}, {
kind: 'taxonomy',
loadEntities: loadTaxonomyEntities
}, {
kind: 'root',
name: 'site',
plural: 'sites',
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) => {
const newEdits = {};
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')) {
newEdits.title = '';
}
}
return newEdits;
};
exports.prePersistPostType = prePersistPostType;
const serialisableBlocksCache = new WeakMap();
function makeBlockAttributesSerializable(attributes) {
const newAttributes = {
...attributes
};
for (const [key, value] of Object.entries(attributes)) {
if (value instanceof _richText.RichTextData) {
newAttributes[key] = value.valueOf();
}
}
return newAttributes;
}
function makeBlocksSerializable(blocks) {
return blocks.map(block => {
const {
innerBlocks,
attributes,
...rest
} = block;
return {
...rest,
attributes: makeBlockAttributesSerializable(attributes),
innerBlocks: makeBlocksSerializable(innerBlocks)
};
});
}
/**
* Returns the list of post type entities.
*
* @return {Promise} Entities promise
*/
async function loadPostTypeEntities() {
const postTypes = await (0, _apiFetch.default)({
path: '/wp/v2/types?context=view'
});
return Object.entries(postTypes !== null && postTypes !== void 0 ? postTypes : {}).map(([name, postType]) => {
var _postType$rest_namesp;
const isTemplate = ['wp_template', 'wp_template_part'].includes(name);
const namespace = (_postType$rest_namesp = postType?.rest_namespace) !== null && _postType$rest_namesp !== void 0 ? _postType$rest_namesp : 'wp/v2';
return {
kind: 'postType',
baseURL: `/${namespace}/${postType.rest_base}`,
baseURLParams: {
context: 'edit'
},
name,
label: postType.name,
transientEdits: {
blocks: true,
selection: true
},
mergedEdits: {
meta: true
},
rawAttributes: POST_RAW_ATTRIBUTES,
getTitle: record => {
var _record$slug;
return record?.title?.rendered || record?.title || (isTemplate ? (0, _changeCase.capitalCase)((_record$slug = record.slug) !== null && _record$slug !== void 0 ? _record$slug : '') : String(record.id));
},
__unstablePrePersist: isTemplate ? undefined : prePersistPostType,
__unstable_rest_base: postType.rest_base,
syncConfig: {
fetch: async id => {
return (0, _apiFetch.default)({
path: `/${namespace}/${postType.rest_base}/${id}?context=edit`
});
},
applyChangesToDoc: (doc, changes) => {
const document = doc.getMap('document');
Object.entries(changes).forEach(([key, value]) => {
if (typeof value !== 'function') {
if (key === 'blocks') {
if (!serialisableBlocksCache.has(value)) {
serialisableBlocksCache.set(value, makeBlocksSerializable(value));
}
value = serialisableBlocksCache.get(value);
}
if (document.get(key) !== value) {
document.set(key, value);
}
}
});
},
fromCRDTDoc: doc => {
return doc.getMap('document').toJSON();
}
},
syncObjectType: 'postType/' + postType.name,
getSyncObjectId: id => id,
supportsPagination: true,
getRevisionsUrl: (parentId, revisionId) => `/${namespace}/${postType.rest_base}/${parentId}/revisions${revisionId ? '/' + revisionId : ''}`,
revisionKey: DEFAULT_ENTITY_KEY
};
});
}
/**
* Returns the list of the taxonomies entities.
*
* @return {Promise} Entities promise
*/
async function loadTaxonomyEntities() {
const taxonomies = await (0, _apiFetch.default)({
path: '/wp/v2/taxonomies?context=view'
});
return Object.entries(taxonomies !== null && taxonomies !== void 0 ? taxonomies : {}).map(([name, taxonomy]) => {
var _taxonomy$rest_namesp;
const namespace = (_taxonomy$rest_namesp = taxonomy?.rest_namespace) !== null && _taxonomy$rest_namesp !== void 0 ? _taxonomy$rest_namesp : 'wp/v2';
return {
kind: 'taxonomy',
baseURL: `/${namespace}/${taxonomy.rest_base}`,
baseURLParams: {
context: 'edit'
},
name,
label: taxonomy.name,
getTitle: record => record?.name,
supportsPagination: true
};
});
}
/**
* Returns the Site entity.
*
* @return {Promise} Entity promise
*/
async function loadSiteEntity() {
var _site$schema$properti;
const entity = {
label: (0, _i18n.__)('Site'),
name: 'site',
kind: 'root',
baseURL: '/wp/v2/settings',
syncConfig: {
fetch: async () => {
return (0, _apiFetch.default)({
path: '/wp/v2/settings'
});
},
applyChangesToDoc: (doc, changes) => {
const document = doc.getMap('document');
Object.entries(changes).forEach(([key, value]) => {
if (document.get(key) !== value) {
document.set(key, value);
}
});
},
fromCRDTDoc: doc => {
return doc.getMap('document').toJSON();
}
},
syncObjectType: 'root/site',
getSyncObjectId: () => 'index',
meta: {}
};
const site = await (0, _apiFetch.default)({
path: entity.baseURL,
method: 'OPTIONS'
});
const labels = {};
Object.entries((_site$schema$properti = site?.schema?.properties) !== null && _site$schema$properti !== void 0 ? _site$schema$properti : {}).forEach(([key, value]) => {
// Ignore properties `title` and `type` keys.
if (typeof value === 'object' && value.title) {
labels[key] = value.title;
}
});
return [{
...entity,
meta: {
labels
}
}];
}
/**
* Returns the entity's getter method name given its kind and name or plural name.
*
* @example
* ```js
* const nameSingular = getMethodName( 'root', 'theme', 'get' );
* // nameSingular is getRootTheme
*
* const namePlural = getMethodName( 'root', 'themes', 'set' );
* // namePlural is setRootThemes
* ```
*
* @param {string} kind Entity kind.
* @param {string} name Entity name or plural name.
* @param {string} prefix Function prefix.
*
* @return {string} Method name
*/
const getMethodName = (kind, name, prefix = 'get') => {
const kindPrefix = kind === 'root' ? '' : (0, _changeCase.pascalCase)(kind);
const suffix = (0, _changeCase.pascalCase)(name);
return `${prefix}${kindPrefix}${suffix}`;
};
exports.getMethodName = getMethodName;
//# sourceMappingURL=entities.js.map
;