@wordpress/core-data
Version:
Access to and manipulation of core WordPress entities.
382 lines (381 loc) • 10.7 kB
JavaScript
// packages/core-data/src/entities.js
import { capitalCase, pascalCase } from "change-case";
import apiFetch from "@wordpress/api-fetch";
import { __unstableSerializeAndClean, parse } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import { getSyncManager } from "./sync";
import {
applyPostChangesToCRDTDoc,
defaultApplyChangesToCRDTDoc,
defaultGetChangesFromCRDTDoc,
getPostChangesFromCRDTDoc
} from "./utils/crdt";
var DEFAULT_ENTITY_KEY = "id";
var POST_RAW_ATTRIBUTES = ["title", "excerpt", "content"];
var blocksTransientEdits = {
blocks: {
read: (record) => parse(record.content?.raw ?? ""),
write: (record) => ({
content: __unstableSerializeAndClean(record.blocks)
})
}
};
var rootEntitiesConfig = [
{
label: __("Base"),
kind: "root",
key: false,
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"
},
{
label: __("Post Type"),
name: "postType",
kind: "root",
key: "slug",
baseURL: "/wp/v2/types",
baseURLParams: { context: "edit" },
plural: "postTypes"
},
{
name: "media",
kind: "root",
baseURL: "/wp/v2/media",
baseURLParams: { context: "edit" },
plural: "mediaItems",
label: __("Media"),
rawAttributes: ["caption", "title", "description"],
supportsPagination: true
},
{
name: "taxonomy",
kind: "root",
key: "slug",
baseURL: "/wp/v2/taxonomies",
baseURLParams: { context: "edit" },
plural: "taxonomies",
label: __("Taxonomy")
},
{
name: "sidebar",
kind: "root",
baseURL: "/wp/v2/sidebars",
baseURLParams: { context: "edit" },
plural: "sidebars",
transientEdits: { blocks: true },
label: __("Widget areas")
},
{
name: "widget",
kind: "root",
baseURL: "/wp/v2/widgets",
baseURLParams: { context: "edit" },
plural: "widgets",
transientEdits: { blocks: true },
label: __("Widgets")
},
{
name: "widgetType",
kind: "root",
baseURL: "/wp/v2/widget-types",
baseURLParams: { context: "edit" },
plural: "widgetTypes",
label: __("Widget types")
},
{
label: __("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: __("Comment"),
supportsPagination: true
},
{
name: "menu",
kind: "root",
baseURL: "/wp/v2/menus",
baseURLParams: { context: "edit" },
plural: "menus",
label: __("Menu"),
supportsPagination: true
},
{
name: "menuItem",
kind: "root",
baseURL: "/wp/v2/menu-items",
baseURLParams: { context: "edit" },
plural: "menuItems",
label: __("Menu Item"),
rawAttributes: ["title"],
supportsPagination: true
},
{
name: "menuLocation",
kind: "root",
baseURL: "/wp/v2/menu-locations",
baseURLParams: { context: "edit" },
plural: "menuLocations",
label: __("Menu Location"),
key: "name"
},
{
label: __("Global Styles"),
name: "globalStyles",
kind: "root",
baseURL: "/wp/v2/global-styles",
baseURLParams: { context: "edit" },
plural: "globalStylesVariations",
// Should be different from name.
getTitle: () => __("Custom Styles"),
getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/${parentId}/revisions${revisionId ? "/" + revisionId : ""}`,
supportsPagination: true
},
{
label: __("Themes"),
name: "theme",
kind: "root",
baseURL: "/wp/v2/themes",
baseURLParams: { context: "edit" },
plural: "themes",
key: "stylesheet"
},
{
label: __("Plugins"),
name: "plugin",
kind: "root",
baseURL: "/wp/v2/plugins",
baseURLParams: { context: "edit" },
plural: "plugins",
key: "plugin"
},
{
label: __("Status"),
name: "status",
kind: "root",
baseURL: "/wp/v2/statuses",
baseURLParams: { context: "edit" },
plural: "statuses",
key: "slug"
},
{
label: __("Registered Templates"),
name: "registeredTemplate",
kind: "root",
baseURL: "/wp/v2/registered-templates",
key: "id"
},
{
label: __("Font Collections"),
name: "fontCollection",
kind: "root",
baseURL: "/wp/v2/font-collections",
baseURLParams: { context: "view" },
plural: "fontCollections",
key: "slug"
}
];
var deprecatedEntities = {
root: {
media: {
since: "6.9",
alternative: {
kind: "postType",
name: "attachment"
}
}
}
};
var additionalEntityConfigLoaders = [
{ kind: "postType", loadEntities: loadPostTypeEntities },
{ kind: "taxonomy", loadEntities: loadTaxonomyEntities },
{
kind: "root",
name: "site",
plural: "sites",
loadEntities: loadSiteEntity
}
];
var prePersistPostType = (persistedRecord, edits, name, isTemplate) => {
const newEdits = {};
if (!isTemplate && persistedRecord?.status === "auto-draft") {
if (!edits.status && !newEdits.status) {
newEdits.status = "draft";
}
if ((!edits.title || edits.title === "Auto Draft") && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === "Auto Draft")) {
newEdits.title = "";
}
}
if (persistedRecord && window.__experimentalEnableSync) {
if (globalThis.IS_GUTENBERG_PLUGIN) {
const objectType = `postType/${name}`;
const objectId = persistedRecord.id;
const meta = getSyncManager()?.createMeta(objectType, objectId);
newEdits.meta = {
...edits.meta,
...meta
};
}
}
return newEdits;
};
async function loadPostTypeEntities() {
const postTypes = await apiFetch({
path: "/wp/v2/types?context=view"
});
return Object.entries(postTypes ?? {}).map(([name, postType]) => {
const isTemplate = ["wp_template", "wp_template_part"].includes(
name
);
const namespace = postType?.rest_namespace ?? "wp/v2";
const entity = {
kind: "postType",
baseURL: `/${namespace}/${postType.rest_base}`,
baseURLParams: { context: "edit" },
name,
label: postType.name,
transientEdits: {
...blocksTransientEdits,
selection: true
},
mergedEdits: { meta: true },
rawAttributes: POST_RAW_ATTRIBUTES,
getTitle: (record) => record?.title?.rendered || record?.title || (isTemplate ? capitalCase(record.slug ?? "") : String(record.id)),
__unstablePrePersist: (persistedRecord, edits) => prePersistPostType(persistedRecord, edits, name, isTemplate),
__unstable_rest_base: postType.rest_base,
supportsPagination: true,
getRevisionsUrl: (parentId, revisionId) => `/${namespace}/${postType.rest_base}/${parentId}/revisions${revisionId ? "/" + revisionId : ""}`,
revisionKey: isTemplate && !window?.__experimentalTemplateActivate ? "wp_id" : DEFAULT_ENTITY_KEY
};
if (window.__experimentalEnableSync) {
if (globalThis.IS_GUTENBERG_PLUGIN) {
entity.syncConfig = {
/**
* Apply changes from the local editor to the local CRDT document so
* that those changes can be synced to other peers (via the provider).
*
* @param {import('@wordpress/sync').CRDTDoc} crdtDoc
* @param {Partial< import('@wordpress/sync').ObjectData >} changes
* @return {void}
*/
applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, postType),
/**
* Extract changes from a CRDT document that can be used to update the
* local editor state.
*
* @param {import('@wordpress/sync').CRDTDoc} crdtDoc
* @param {import('@wordpress/sync').ObjectData} editedRecord
* @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record
*/
getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc(
crdtDoc,
editedRecord,
postType
),
/**
* Sync features supported by the entity.
*
* @type {Record< string, boolean >}
*/
supports: {
crdtPersistence: true
}
};
}
}
return entity;
});
}
async function loadTaxonomyEntities() {
const taxonomies = await apiFetch({
path: "/wp/v2/taxonomies?context=view"
});
return Object.entries(taxonomies ?? {}).map(([name, taxonomy]) => {
const namespace = taxonomy?.rest_namespace ?? "wp/v2";
return {
kind: "taxonomy",
baseURL: `/${namespace}/${taxonomy.rest_base}`,
baseURLParams: { context: "edit" },
name,
label: taxonomy.name,
getTitle: (record) => record?.name,
supportsPagination: true
};
});
}
async function loadSiteEntity() {
const entity = {
label: __("Site"),
name: "site",
kind: "root",
key: false,
baseURL: "/wp/v2/settings",
meta: {}
};
if (window.__experimentalEnableSync) {
if (globalThis.IS_GUTENBERG_PLUGIN) {
entity.syncConfig = {
applyChangesToCRDTDoc: defaultApplyChangesToCRDTDoc,
getChangesFromCRDTDoc: defaultGetChangesFromCRDTDoc
};
}
}
const site = await apiFetch({
path: entity.baseURL,
method: "OPTIONS"
});
const labels = {};
Object.entries(site?.schema?.properties ?? {}).forEach(
([key, value]) => {
if (typeof value === "object" && value.title) {
labels[key] = value.title;
}
}
);
return [{ ...entity, meta: { labels } }];
}
var getMethodName = (kind, name, prefix = "get") => {
const kindPrefix = kind === "root" ? "" : pascalCase(kind);
const suffix = pascalCase(name);
return `${prefix}${kindPrefix}${suffix}`;
};
export {
DEFAULT_ENTITY_KEY,
additionalEntityConfigLoaders,
deprecatedEntities,
getMethodName,
prePersistPostType,
rootEntitiesConfig
};
//# sourceMappingURL=entities.js.map