From d06bc581811552d8c46a381788fee274d183f4a5 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Thu, 14 Nov 2024 15:28:52 +0530 Subject: [PATCH 01/18] [core-data] Document and add types for dynamic actions and selectors. --- packages/core-data/src/dynamic-actions.ts | 97 +++++ packages/core-data/src/dynamic-selectors.ts | 369 ++++++++++++++++++ packages/core-data/src/entity-types/base.ts | 61 +++ packages/core-data/src/entity-types/index.ts | 9 + .../core-data/src/entity-types/post-status.ts | 56 +++ .../core-data/src/entity-types/post-type.ts | 106 +++++ packages/core-data/src/index.js | 15 +- packages/core-data/src/selectors.ts | 2 +- 8 files changed, 712 insertions(+), 3 deletions(-) create mode 100644 packages/core-data/src/dynamic-actions.ts create mode 100644 packages/core-data/src/dynamic-selectors.ts create mode 100644 packages/core-data/src/entity-types/base.ts create mode 100644 packages/core-data/src/entity-types/post-status.ts create mode 100644 packages/core-data/src/entity-types/post-type.ts diff --git a/packages/core-data/src/dynamic-actions.ts b/packages/core-data/src/dynamic-actions.ts new file mode 100644 index 00000000000000..a0c715d283a7b4 --- /dev/null +++ b/packages/core-data/src/dynamic-actions.ts @@ -0,0 +1,97 @@ +/** + * Internal dependencies + */ +import type * as ET from './entity-types'; + +type DeleteRecordsHttpQuery = Record< string, any >; + +type SaveRecordOptions = { + throwOnError?: boolean; +}; + +type DeleteRecordOptions = { + throwOnError?: boolean; +}; + +/** + * Save the site settings + * + * @param data The site settings + * @param options + */ +export declare function saveSite( + data: Partial< ET.Settings >, + options?: SaveRecordOptions +): Promise< void >; + +/** + * Save comment + * + * @param data The comment data + * @param options + */ +export declare function saveComment( + data: { id: number } & Partial< ET.Comment >, + options?: SaveRecordOptions +): Promise< void >; + +/** + * Save media item + * + * @param data The media item + * @param options + */ +export declare function saveMedia( + data: { id: number } & Partial< ET.Attachment >, + options?: SaveRecordOptions +): Promise< void >; + +/** + * Save user + * + * @param data The user data + * @param options + */ +export declare function saveUser( + data: { id: number } & Partial< ET.User >, + options?: SaveRecordOptions +): Promise< void >; + +/** + * Delete a comment + * + * @param id The comment ID + * @param query Special query parameters for the DELETE API call + * @param options Delete options + */ +export declare function deleteComment( + id: number, + query?: DeleteRecordsHttpQuery, + options?: DeleteRecordOptions +): Promise< void >; + +/** + * Delete a media item + * + * @param id The media item ID + * @param query Special query parameters for the DELETE API call + * @param options Delete options + */ +export declare function deleteMedia( + id: number, + query?: DeleteRecordsHttpQuery, + options?: DeleteRecordOptions +): Promise< void >; + +/** + * Delete a user + * + * @param id The user ID + * @param query Special query parameters for the DELETE API call + * @param options Delete options + */ +export declare function deleteUser( + id: number, + query?: DeleteRecordsHttpQuery, + options?: DeleteRecordOptions +): Promise< void >; diff --git a/packages/core-data/src/dynamic-selectors.ts b/packages/core-data/src/dynamic-selectors.ts new file mode 100644 index 00000000000000..fc683ca7abd07e --- /dev/null +++ b/packages/core-data/src/dynamic-selectors.ts @@ -0,0 +1,369 @@ +/** + * Internal dependencies + */ +import type { GetRecordsHttpQuery, State } from './selectors'; +import type * as ET from './entity-types'; + +type Nullable< T > = T | null; + +/** + * Get post type object by name. + * + * @param state Data state. + * @param name Post type name. + * @param query Optional query. If requesting specific + */ +export declare function getPostType( + state: State, + name: string, + query?: GetRecordsHttpQuery +): ET.PostType | undefined; + +/** + * Get the list of post type objects. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getPostTypes( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.PostType > >; + +/** + * Get media item by ID. + * + * @param state Data state. + * @param id Media item ID. + * @param query Optional query. If requesting specific + */ +export declare function getMedia( + state: State, + id: number, + query?: GetRecordsHttpQuery +): ET.Attachment | undefined; + +/** + * Get the media items list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getMediaItems( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Attachment > >; + +/** + * Get taxonomy object by name. + * + * @param state Data state. + * @param name Taxonomy name. + * @param query Optional query. If requesting specific + */ +export declare function getTaxonomy( + state: State, + name: string, + query?: GetRecordsHttpQuery +): ET.Taxonomy | undefined; + +/** + * Get the list of taxonomy objects. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getTaxonomies( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Taxonomy > >; + +/** + * Get sidebar by ID. + * + * @param state Data state. + * @param id Sidebar ID. + * @param query Optional query. If requesting specific + */ +export declare function getSidebar( + state: State, + id: string, + query?: GetRecordsHttpQuery +): ET.Sidebar | undefined; + +/** + * Get the sidebar list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getSidebars( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Sidebar > >; + +/** + * Get widget by ID. + * + * @param state Data state. + * @param id Sidebar ID. + * @param query Optional query. If requesting specific + */ +export declare function getWidget( + state: State, + id: string, + query?: GetRecordsHttpQuery +): ET.Widget | undefined; + +/** + * Get the widgets list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getWidgets( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Widget > >; + +/** + * Get widget type by ID. + * + * @param state Data state. + * @param id Sidebar ID. + * @param query Optional query. If requesting specific + */ +export declare function getWidgetType( + state: State, + id: string, + query?: GetRecordsHttpQuery +): ET.WidgetType | undefined; + +/** + * Get widget types list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getWidgetTypes( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.WidgetType > >; + +/** + * Get user by ID. + * + * @param state Data state. + * @param userId User ID. + * @param query Optional query. If requesting specific + */ +export declare function getUser( + state: State, + userId: number, + query?: GetRecordsHttpQuery +): ET.User | undefined; + +/** + * Get the users list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getUsers( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.User > >; + +/** + * Get comment by ID. + * + * @param state Data state. + * @param commentId Comment ID. + * @param query Optional query. If requesting specific + */ +export declare function getComment( + state: State, + commentId: number, + query?: GetRecordsHttpQuery +): ET.Comment | undefined; + +/** + * Get the comments list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getComments( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Comment > >; + +/** + * Get menu by ID. + * + * @param state Data state. + * @param id Menu ID. + * @param query Optional query. If requesting specific + */ +export declare function getMenu( + state: State, + id: number, + query?: GetRecordsHttpQuery +): ET.NavMenu | undefined; + +/** + * Get the menus list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getMenus( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.NavMenu > >; + +/** + * Get menu item by ID. + * + * @param state Data state. + * @param id Menu item ID. + * @param query Optional query. If requesting specific + */ +export declare function getMenuItem( + state: State, + id: number, + query?: GetRecordsHttpQuery +): ET.NavMenuItem | undefined; + +/** + * Get the menu items list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getMenuItems( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.NavMenuItem > >; + +/** + * Get menu location by ID. + * + * @param state Data state. + * @param location Menu location. + * @param query Optional query. If requesting specific + */ +export declare function getMenuLocation( + state: State, + location: string, + query?: GetRecordsHttpQuery +): ET.MenuLocation | undefined; + +/** + * Get the menu locations. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getMenuLocations( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.MenuLocation > >; + +/** + * Get theme by stylesheet. + * + * @param state Data state. + * @param stylesheet Theme stylesheet, e.g. "twentytwentyfour" + * @param query Optional query. If requesting specific + */ +export declare function getTheme( + state: State, + stylesheet: string, + query?: GetRecordsHttpQuery +): ET.Theme | undefined; + +/** + * Get the themes list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getThemes( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Theme > >; + +/** + * Get plugin. + * + * @param state Data state. + * @param plugin The plugin file, e.g. "classic-editor/classic-editor" + * @param query Optional query. If requesting specific + */ +export declare function getPlugin( + state: State, + plugin: string, + query?: GetRecordsHttpQuery +): ET.Plugin | undefined; + +/** + * Get the plugins list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getPlugins( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.Plugin > >; + +/** + * Get post status by name. + * + * @param state Data state. + * @param status The name of a registered post status.. + * @param query Optional query. If requesting specific + */ +export declare function getStatus( + state: State, + status: string, + query?: GetRecordsHttpQuery +): ET.PostStatusObject | undefined; + +/** + * Get the list of post statuses. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ +export declare function getStatuses( + state: State, + query?: GetRecordsHttpQuery +): Nullable< Array< ET.PostStatusObject > >; + +/** + * Get the site object. + * + * @param state Data state. + * @param key Not used. + * @param query Optional query. If requesting specific + */ +export declare function getSite( + state: State, + key?: null, + query?: GetRecordsHttpQuery +): ET.Settings | undefined; + +/** + * Get the basic site information. + * + * @param state Data state. + * @param key Not used. + * @param query Optional query. If requesting specific + */ +export declare function getUnstableBase( + state: State, + key?: null, + query?: GetRecordsHttpQuery +): ET.Base | undefined; diff --git a/packages/core-data/src/entity-types/base.ts b/packages/core-data/src/entity-types/base.ts new file mode 100644 index 00000000000000..3d11bd2081e24f --- /dev/null +++ b/packages/core-data/src/entity-types/base.ts @@ -0,0 +1,61 @@ +/** + * Internal dependencies + */ +import type { Context, OmitNevers } from './helpers'; +import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; + +declare module './base-entity-records' { + export namespace BaseEntityRecords { + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + export interface Base< C extends Context > { + /** + * Site description. + */ + description: string; + + /** + * GMT offset for the site. + */ + gmt_offset: string | number; + + /** + * Home URL. + */ + home: string; + + /** + * Site title + */ + name: string; + + /** + * Site icon ID. + */ + site_icon?: number; + + /** + * Site icon URL. + */ + site_icon_url: string; + + /** + * Site logo ID. + */ + site_logo?: number; + + /** + * Site timezone string. + */ + timezone_string: string; + + /** + * Site URL. + */ + url: string; + } + } +} + +export type Base< C extends Context = 'edit' > = OmitNevers< + _BaseEntityRecords.Base< C > +>; diff --git a/packages/core-data/src/entity-types/index.ts b/packages/core-data/src/entity-types/index.ts index 0e601137cbcb6c..66e8cc0c699f72 100644 --- a/packages/core-data/src/entity-types/index.ts +++ b/packages/core-data/src/entity-types/index.ts @@ -11,6 +11,9 @@ import type { NavMenuItem } from './nav-menu-item'; import type { Page } from './page'; import type { Plugin } from './plugin'; import type { Post } from './post'; +import type { PostStatusObject } from './post-status'; +import type { PostType } from './post-type'; +import type { Base } from './base'; import type { PostRevision } from './post-revision'; import type { Settings } from './settings'; import type { Sidebar } from './sidebar'; @@ -27,6 +30,7 @@ export type { BaseEntityRecords } from './base-entity-records'; export type { Attachment, + Base, Comment, Context, GlobalStylesRevision, @@ -36,6 +40,8 @@ export type { Page, Plugin, Post, + PostStatusObject, + PostType, PostRevision, Settings, Sidebar, @@ -84,6 +90,7 @@ export type { */ export interface PerPackageEntityRecords< C extends Context > { core: + | Base< C > | Attachment< C > | Comment< C > | GlobalStylesRevision< C > @@ -93,6 +100,8 @@ export interface PerPackageEntityRecords< C extends Context > { | Page< C > | Plugin< C > | Post< C > + | PostStatusObject< C > + | PostType< C > | PostRevision< C > | Settings< C > | Sidebar< C > diff --git a/packages/core-data/src/entity-types/post-status.ts b/packages/core-data/src/entity-types/post-status.ts new file mode 100644 index 00000000000000..50508918b1b8f9 --- /dev/null +++ b/packages/core-data/src/entity-types/post-status.ts @@ -0,0 +1,56 @@ +/** + * Internal dependencies + */ +import type { Context, OmitNevers } from './helpers'; +import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; + +declare module './base-entity-records' { + export namespace BaseEntityRecords { + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + export interface PostStatusObject< C extends Context > { + /** + * The title for the status. + */ + name: string; + + /** + * Whether posts with this status should be private. + */ + private: boolean; + + /** + * Whether posts with this status should be protected. + */ + protected: boolean; + + /** + * Whether posts of this status should be shown in the front end of the site. + */ + public: boolean; + + /** + * Whether posts with this status should be publicly-queryable. + */ + queryable: boolean; + + /** + * Whether to include posts in the edit listing for their post type. + */ + show_in_list: boolean; + + /** + * An alphanumeric identifier for the status. + */ + slug: string; + + /** + * Whether posts of this status may have floating published dates. + */ + date_floating: boolean; + } + } +} + +export type PostStatusObject< C extends Context = 'edit' > = OmitNevers< + _BaseEntityRecords.PostType< C > +>; diff --git a/packages/core-data/src/entity-types/post-type.ts b/packages/core-data/src/entity-types/post-type.ts new file mode 100644 index 00000000000000..492cc946a5148d --- /dev/null +++ b/packages/core-data/src/entity-types/post-type.ts @@ -0,0 +1,106 @@ +/** + * Internal dependencies + */ +import type { Context, OmitNevers } from './helpers'; +import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; + +declare module './base-entity-records' { + export namespace BaseEntityRecords { + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + export interface PostType< C extends Context > { + /** + * All capabilities used by the post type. + */ + capabilities: Record< string, string >; + + /** + * A human-readable description of the post type. + */ + description: string; + + /** + * Whether or not the post type should have children. + */ + hierarchical: boolean; + + /** + * If the value is a string, the value will be used as the archive slug. If the value is false the post type has no archive. + */ + has_archive: string | boolean; + + /** + * The visibility settings for the post type. + */ + visibility: { + /** + * Whether to generate a default UI for managing this post type. + */ + show_ui: boolean; + + /** + * Whether to make the post type available for selection in navigation menus. + */ + show_in_nav_menus: boolean; + }; + + /** + * Whether or not the post type can be viewed. + */ + viewable: boolean; + + /** + * Human-readable labels for the post type for various contexts. + */ + labels: Record< string, string >; + + /** + * The title for the post type. + */ + name: string; + + /** + * An alphanumeric identifier for the post type. + */ + slug: string; + + /** + * The icon for the post type. + */ + icon: string | null; + + /** + * All features, supported by the post type. + */ + supports: Record< string, boolean >; + + /** + * Taxonomies associated with post type. + */ + taxonomies: Array< string >; + + /** + * REST base route for the post type. + */ + rest_base: string; + + /** + * REST route's namespace for the post type. + */ + rest_namespace: string; + + /** + * The block template associated with the post type. + */ + template: Array< object >; + + /** + * The template_lock associated with the post type, or false if none. + */ + template_lock: string | boolean; + } + } +} + +export type PostType< C extends Context = 'edit' > = OmitNevers< + _BaseEntityRecords.PostType< C > +>; diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 99507a914f377b..369a768ac7c98a 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -20,6 +20,8 @@ import { } from './entities'; import { STORE_NAME } from './name'; import { unlock } from './lock-unlock'; +import * as dynamicSelectorDefinitions from './dynamic-selectors'; +import * as dynamicActionDefinitions from './dynamic-actions'; // The entity selectors/resolvers and actions are shortcuts to their generic equivalents // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecords) @@ -68,8 +70,17 @@ const entityActions = entitiesConfig.reduce( ( result, entity ) => { const storeConfig = () => ( { reducer, - actions: { ...actions, ...entityActions, ...createLocksActions() }, - selectors: { ...selectors, ...entitySelectors }, + actions: { + ...actions, + ...entityActions, + ...createLocksActions(), + ...dynamicActionDefinitions, + }, + selectors: { + ...selectors, + ...entitySelectors, + ...dynamicSelectorDefinitions, + }, resolvers: { ...resolvers, ...entityResolvers }, } ); diff --git a/packages/core-data/src/selectors.ts b/packages/core-data/src/selectors.ts index 7ea8c2f7f26d53..f4ce8efceb1bb1 100644 --- a/packages/core-data/src/selectors.ts +++ b/packages/core-data/src/selectors.ts @@ -113,7 +113,7 @@ type Optional< T > = T | undefined; /** * HTTP Query parameters sent with the API request to fetch the entity records. */ -type GetRecordsHttpQuery = Record< string, any >; +export type GetRecordsHttpQuery = Record< string, any >; /** * Arguments for EntityRecord selectors. From b3778a37e1a40b8fcf2ed513832a3c3d90de1664 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Thu, 14 Nov 2024 15:29:18 +0530 Subject: [PATCH 02/18] Now that things are typed, we don't expect an error --- packages/fields/src/fields/parent/parent-edit.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/fields/src/fields/parent/parent-edit.tsx b/packages/fields/src/fields/parent/parent-edit.tsx index 21cdbee7a365a4..d42b732a003e85 100644 --- a/packages/fields/src/fields/parent/parent-edit.tsx +++ b/packages/fields/src/fields/parent/parent-edit.tsx @@ -122,7 +122,6 @@ export function PageAttributesParent( { const { parentPostTitle, pageItems, isHierarchical } = useSelect( ( select ) => { - // @ts-expect-error getPostType is not typed const { getEntityRecord, getEntityRecords, getPostType } = select( coreStore ); From 0b72ca3620cba3446d8f6addd6830be73fd9413f Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Thu, 14 Nov 2024 16:01:12 +0530 Subject: [PATCH 03/18] Put definitions first to allow it be overridden --- packages/core-data/src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 369a768ac7c98a..9d4d83eca15ee0 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -71,15 +71,15 @@ const entityActions = entitiesConfig.reduce( ( result, entity ) => { const storeConfig = () => ( { reducer, actions: { + ...dynamicActionDefinitions, ...actions, ...entityActions, ...createLocksActions(), - ...dynamicActionDefinitions, }, selectors: { + ...dynamicSelectorDefinitions, ...selectors, ...entitySelectors, - ...dynamicSelectorDefinitions, }, resolvers: { ...resolvers, ...entityResolvers }, } ); From 3928817476fb0c1c7b00d4d374caa0abac74d30c Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Thu, 14 Nov 2024 19:27:39 +0530 Subject: [PATCH 04/18] Use namespaces to avoid direct imports --- packages/core-data/src/dynamic-actions.ts | 168 ++--- packages/core-data/src/dynamic-selectors.ts | 668 ++++++++++---------- packages/core-data/src/index.js | 8 +- 3 files changed, 424 insertions(+), 420 deletions(-) diff --git a/packages/core-data/src/dynamic-actions.ts b/packages/core-data/src/dynamic-actions.ts index a0c715d283a7b4..1fafa767db92f9 100644 --- a/packages/core-data/src/dynamic-actions.ts +++ b/packages/core-data/src/dynamic-actions.ts @@ -3,95 +3,97 @@ */ import type * as ET from './entity-types'; -type DeleteRecordsHttpQuery = Record< string, any >; +export namespace DynamicActions { + type DeleteRecordsHttpQuery = Record< string, any >; -type SaveRecordOptions = { - throwOnError?: boolean; -}; + type SaveRecordOptions = { + throwOnError?: boolean; + }; -type DeleteRecordOptions = { - throwOnError?: boolean; -}; + type DeleteRecordOptions = { + throwOnError?: boolean; + }; -/** - * Save the site settings - * - * @param data The site settings - * @param options - */ -export declare function saveSite( - data: Partial< ET.Settings >, - options?: SaveRecordOptions -): Promise< void >; + /** + * Save the site settings + * + * @param data The site settings + * @param options + */ + export declare function saveSite( + data: Partial< ET.Settings >, + options?: SaveRecordOptions + ): Promise< void >; -/** - * Save comment - * - * @param data The comment data - * @param options - */ -export declare function saveComment( - data: { id: number } & Partial< ET.Comment >, - options?: SaveRecordOptions -): Promise< void >; + /** + * Save comment + * + * @param data The comment data + * @param options + */ + export declare function saveComment( + data: { id: number } & Partial< ET.Comment >, + options?: SaveRecordOptions + ): Promise< void >; -/** - * Save media item - * - * @param data The media item - * @param options - */ -export declare function saveMedia( - data: { id: number } & Partial< ET.Attachment >, - options?: SaveRecordOptions -): Promise< void >; + /** + * Save media item + * + * @param data The media item + * @param options + */ + export declare function saveMedia( + data: { id: number } & Partial< ET.Attachment >, + options?: SaveRecordOptions + ): Promise< void >; -/** - * Save user - * - * @param data The user data - * @param options - */ -export declare function saveUser( - data: { id: number } & Partial< ET.User >, - options?: SaveRecordOptions -): Promise< void >; + /** + * Save user + * + * @param data The user data + * @param options + */ + export declare function saveUser( + data: { id: number } & Partial< ET.User >, + options?: SaveRecordOptions + ): Promise< void >; -/** - * Delete a comment - * - * @param id The comment ID - * @param query Special query parameters for the DELETE API call - * @param options Delete options - */ -export declare function deleteComment( - id: number, - query?: DeleteRecordsHttpQuery, - options?: DeleteRecordOptions -): Promise< void >; + /** + * Delete a comment + * + * @param id The comment ID + * @param query Special query parameters for the DELETE API call + * @param options Delete options + */ + export declare function deleteComment( + id: number, + query?: DeleteRecordsHttpQuery, + options?: DeleteRecordOptions + ): Promise< void >; -/** - * Delete a media item - * - * @param id The media item ID - * @param query Special query parameters for the DELETE API call - * @param options Delete options - */ -export declare function deleteMedia( - id: number, - query?: DeleteRecordsHttpQuery, - options?: DeleteRecordOptions -): Promise< void >; + /** + * Delete a media item + * + * @param id The media item ID + * @param query Special query parameters for the DELETE API call + * @param options Delete options + */ + export declare function deleteMedia( + id: number, + query?: DeleteRecordsHttpQuery, + options?: DeleteRecordOptions + ): Promise< void >; -/** - * Delete a user - * - * @param id The user ID - * @param query Special query parameters for the DELETE API call - * @param options Delete options - */ -export declare function deleteUser( - id: number, - query?: DeleteRecordsHttpQuery, - options?: DeleteRecordOptions -): Promise< void >; + /** + * Delete a user + * + * @param id The user ID + * @param query Special query parameters for the DELETE API call + * @param options Delete options + */ + export declare function deleteUser( + id: number, + query?: DeleteRecordsHttpQuery, + options?: DeleteRecordOptions + ): Promise< void >; +} diff --git a/packages/core-data/src/dynamic-selectors.ts b/packages/core-data/src/dynamic-selectors.ts index fc683ca7abd07e..f711299aa5d4ac 100644 --- a/packages/core-data/src/dynamic-selectors.ts +++ b/packages/core-data/src/dynamic-selectors.ts @@ -4,366 +4,368 @@ import type { GetRecordsHttpQuery, State } from './selectors'; import type * as ET from './entity-types'; -type Nullable< T > = T | null; +export namespace DynamicSelectors { + type Nullable< T > = T | null; -/** - * Get post type object by name. - * - * @param state Data state. - * @param name Post type name. - * @param query Optional query. If requesting specific - */ -export declare function getPostType( - state: State, - name: string, - query?: GetRecordsHttpQuery -): ET.PostType | undefined; + /** + * Get post type object by name. + * + * @param state Data state. + * @param name Post type name. + * @param query Optional query. If requesting specific + */ + export declare function getPostType( + state: State, + name: string, + query?: GetRecordsHttpQuery + ): ET.PostType | undefined; -/** - * Get the list of post type objects. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getPostTypes( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.PostType > >; + /** + * Get the list of post type objects. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getPostTypes( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.PostType > >; -/** - * Get media item by ID. - * - * @param state Data state. - * @param id Media item ID. - * @param query Optional query. If requesting specific - */ -export declare function getMedia( - state: State, - id: number, - query?: GetRecordsHttpQuery -): ET.Attachment | undefined; + /** + * Get media item by ID. + * + * @param state Data state. + * @param id Media item ID. + * @param query Optional query. If requesting specific + */ + export declare function getMedia( + state: State, + id: number, + query?: GetRecordsHttpQuery + ): ET.Attachment | undefined; -/** - * Get the media items list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getMediaItems( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Attachment > >; + /** + * Get the media items list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getMediaItems( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Attachment > >; -/** - * Get taxonomy object by name. - * - * @param state Data state. - * @param name Taxonomy name. - * @param query Optional query. If requesting specific - */ -export declare function getTaxonomy( - state: State, - name: string, - query?: GetRecordsHttpQuery -): ET.Taxonomy | undefined; + /** + * Get taxonomy object by name. + * + * @param state Data state. + * @param name Taxonomy name. + * @param query Optional query. If requesting specific + */ + export declare function getTaxonomy( + state: State, + name: string, + query?: GetRecordsHttpQuery + ): ET.Taxonomy | undefined; -/** - * Get the list of taxonomy objects. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getTaxonomies( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Taxonomy > >; + /** + * Get the list of taxonomy objects. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getTaxonomies( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Taxonomy > >; -/** - * Get sidebar by ID. - * - * @param state Data state. - * @param id Sidebar ID. - * @param query Optional query. If requesting specific - */ -export declare function getSidebar( - state: State, - id: string, - query?: GetRecordsHttpQuery -): ET.Sidebar | undefined; + /** + * Get sidebar by ID. + * + * @param state Data state. + * @param id Sidebar ID. + * @param query Optional query. If requesting specific + */ + export declare function getSidebar( + state: State, + id: string, + query?: GetRecordsHttpQuery + ): ET.Sidebar | undefined; -/** - * Get the sidebar list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getSidebars( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Sidebar > >; + /** + * Get the sidebar list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getSidebars( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Sidebar > >; -/** - * Get widget by ID. - * - * @param state Data state. - * @param id Sidebar ID. - * @param query Optional query. If requesting specific - */ -export declare function getWidget( - state: State, - id: string, - query?: GetRecordsHttpQuery -): ET.Widget | undefined; + /** + * Get widget by ID. + * + * @param state Data state. + * @param id Sidebar ID. + * @param query Optional query. If requesting specific + */ + export declare function getWidget( + state: State, + id: string, + query?: GetRecordsHttpQuery + ): ET.Widget | undefined; -/** - * Get the widgets list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getWidgets( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Widget > >; + /** + * Get the widgets list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getWidgets( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Widget > >; -/** - * Get widget type by ID. - * - * @param state Data state. - * @param id Sidebar ID. - * @param query Optional query. If requesting specific - */ -export declare function getWidgetType( - state: State, - id: string, - query?: GetRecordsHttpQuery -): ET.WidgetType | undefined; + /** + * Get widget type by ID. + * + * @param state Data state. + * @param id Sidebar ID. + * @param query Optional query. If requesting specific + */ + export declare function getWidgetType( + state: State, + id: string, + query?: GetRecordsHttpQuery + ): ET.WidgetType | undefined; -/** - * Get widget types list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getWidgetTypes( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.WidgetType > >; + /** + * Get widget types list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getWidgetTypes( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.WidgetType > >; -/** - * Get user by ID. - * - * @param state Data state. - * @param userId User ID. - * @param query Optional query. If requesting specific - */ -export declare function getUser( - state: State, - userId: number, - query?: GetRecordsHttpQuery -): ET.User | undefined; + /** + * Get user by ID. + * + * @param state Data state. + * @param userId User ID. + * @param query Optional query. If requesting specific + */ + export declare function getUser( + state: State, + userId: number, + query?: GetRecordsHttpQuery + ): ET.User | undefined; -/** - * Get the users list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getUsers( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.User > >; + /** + * Get the users list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getUsers( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.User > >; -/** - * Get comment by ID. - * - * @param state Data state. - * @param commentId Comment ID. - * @param query Optional query. If requesting specific - */ -export declare function getComment( - state: State, - commentId: number, - query?: GetRecordsHttpQuery -): ET.Comment | undefined; + /** + * Get comment by ID. + * + * @param state Data state. + * @param commentId Comment ID. + * @param query Optional query. If requesting specific + */ + export declare function getComment( + state: State, + commentId: number, + query?: GetRecordsHttpQuery + ): ET.Comment | undefined; -/** - * Get the comments list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getComments( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Comment > >; + /** + * Get the comments list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getComments( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Comment > >; -/** - * Get menu by ID. - * - * @param state Data state. - * @param id Menu ID. - * @param query Optional query. If requesting specific - */ -export declare function getMenu( - state: State, - id: number, - query?: GetRecordsHttpQuery -): ET.NavMenu | undefined; + /** + * Get menu by ID. + * + * @param state Data state. + * @param id Menu ID. + * @param query Optional query. If requesting specific + */ + export declare function getMenu( + state: State, + id: number, + query?: GetRecordsHttpQuery + ): ET.NavMenu | undefined; -/** - * Get the menus list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getMenus( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.NavMenu > >; + /** + * Get the menus list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getMenus( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.NavMenu > >; -/** - * Get menu item by ID. - * - * @param state Data state. - * @param id Menu item ID. - * @param query Optional query. If requesting specific - */ -export declare function getMenuItem( - state: State, - id: number, - query?: GetRecordsHttpQuery -): ET.NavMenuItem | undefined; + /** + * Get menu item by ID. + * + * @param state Data state. + * @param id Menu item ID. + * @param query Optional query. If requesting specific + */ + export declare function getMenuItem( + state: State, + id: number, + query?: GetRecordsHttpQuery + ): ET.NavMenuItem | undefined; -/** - * Get the menu items list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getMenuItems( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.NavMenuItem > >; + /** + * Get the menu items list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getMenuItems( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.NavMenuItem > >; -/** - * Get menu location by ID. - * - * @param state Data state. - * @param location Menu location. - * @param query Optional query. If requesting specific - */ -export declare function getMenuLocation( - state: State, - location: string, - query?: GetRecordsHttpQuery -): ET.MenuLocation | undefined; + /** + * Get menu location by ID. + * + * @param state Data state. + * @param location Menu location. + * @param query Optional query. If requesting specific + */ + export declare function getMenuLocation( + state: State, + location: string, + query?: GetRecordsHttpQuery + ): ET.MenuLocation | undefined; -/** - * Get the menu locations. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getMenuLocations( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.MenuLocation > >; + /** + * Get the menu locations. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getMenuLocations( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.MenuLocation > >; -/** - * Get theme by stylesheet. - * - * @param state Data state. - * @param stylesheet Theme stylesheet, e.g. "twentytwentyfour" - * @param query Optional query. If requesting specific - */ -export declare function getTheme( - state: State, - stylesheet: string, - query?: GetRecordsHttpQuery -): ET.Theme | undefined; + /** + * Get theme by stylesheet. + * + * @param state Data state. + * @param stylesheet Theme stylesheet, e.g. "twentytwentyfour" + * @param query Optional query. If requesting specific + */ + export declare function getTheme( + state: State, + stylesheet: string, + query?: GetRecordsHttpQuery + ): ET.Theme | undefined; -/** - * Get the themes list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getThemes( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Theme > >; + /** + * Get the themes list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getThemes( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Theme > >; -/** - * Get plugin. - * - * @param state Data state. - * @param plugin The plugin file, e.g. "classic-editor/classic-editor" - * @param query Optional query. If requesting specific - */ -export declare function getPlugin( - state: State, - plugin: string, - query?: GetRecordsHttpQuery -): ET.Plugin | undefined; + /** + * Get plugin. + * + * @param state Data state. + * @param plugin The plugin file, e.g. "classic-editor/classic-editor" + * @param query Optional query. If requesting specific + */ + export declare function getPlugin( + state: State, + plugin: string, + query?: GetRecordsHttpQuery + ): ET.Plugin | undefined; -/** - * Get the plugins list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getPlugins( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.Plugin > >; + /** + * Get the plugins list. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getPlugins( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.Plugin > >; -/** - * Get post status by name. - * - * @param state Data state. - * @param status The name of a registered post status.. - * @param query Optional query. If requesting specific - */ -export declare function getStatus( - state: State, - status: string, - query?: GetRecordsHttpQuery -): ET.PostStatusObject | undefined; + /** + * Get post status by name. + * + * @param state Data state. + * @param status The name of a registered post status.. + * @param query Optional query. If requesting specific + */ + export declare function getStatus( + state: State, + status: string, + query?: GetRecordsHttpQuery + ): ET.PostStatusObject | undefined; -/** - * Get the list of post statuses. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ -export declare function getStatuses( - state: State, - query?: GetRecordsHttpQuery -): Nullable< Array< ET.PostStatusObject > >; + /** + * Get the list of post statuses. + * + * @param state Data state. + * @param query Optional query. If requesting specific + */ + export declare function getStatuses( + state: State, + query?: GetRecordsHttpQuery + ): Nullable< Array< ET.PostStatusObject > >; -/** - * Get the site object. - * - * @param state Data state. - * @param key Not used. - * @param query Optional query. If requesting specific - */ -export declare function getSite( - state: State, - key?: null, - query?: GetRecordsHttpQuery -): ET.Settings | undefined; + /** + * Get the site object. + * + * @param state Data state. + * @param key Not used. + * @param query Optional query. If requesting specific + */ + export declare function getSite( + state: State, + key?: null, + query?: GetRecordsHttpQuery + ): ET.Settings | undefined; -/** - * Get the basic site information. - * - * @param state Data state. - * @param key Not used. - * @param query Optional query. If requesting specific - */ -export declare function getUnstableBase( - state: State, - key?: null, - query?: GetRecordsHttpQuery -): ET.Base | undefined; + /** + * Get the basic site information. + * + * @param state Data state. + * @param key Not used. + * @param query Optional query. If requesting specific + */ + export declare function getUnstableBase( + state: State, + key?: null, + query?: GetRecordsHttpQuery + ): ET.Base | undefined; +} diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 9d4d83eca15ee0..8470ce5c0c1aee 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -20,8 +20,8 @@ import { } from './entities'; import { STORE_NAME } from './name'; import { unlock } from './lock-unlock'; -import * as dynamicSelectorDefinitions from './dynamic-selectors'; -import * as dynamicActionDefinitions from './dynamic-actions'; +import { DynamicSelectors } from './dynamic-selectors'; +import { DynamicActions } from './dynamic-actions'; // The entity selectors/resolvers and actions are shortcuts to their generic equivalents // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecords) @@ -71,13 +71,13 @@ const entityActions = entitiesConfig.reduce( ( result, entity ) => { const storeConfig = () => ( { reducer, actions: { - ...dynamicActionDefinitions, + ...DynamicActions, ...actions, ...entityActions, ...createLocksActions(), }, selectors: { - ...dynamicSelectorDefinitions, + ...DynamicSelectors, ...selectors, ...entitySelectors, }, From c583805b40be25db97c31047c329aa2c2e409981 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 11 Dec 2024 15:17:41 +0530 Subject: [PATCH 05/18] Remove unnecessary `ts-expect-error` --- .../fields/src/components/create-template-part-modal/index.tsx | 1 - packages/fields/src/fields/parent/parent-edit.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/fields/src/components/create-template-part-modal/index.tsx b/packages/fields/src/components/create-template-part-modal/index.tsx index 4043a7824fac49..2115c5ed605677 100644 --- a/packages/fields/src/components/create-template-part-modal/index.tsx +++ b/packages/fields/src/components/create-template-part-modal/index.tsx @@ -71,7 +71,6 @@ export default function CreateTemplatePartModal( { } & CreateTemplatePartModalContentsProps ) { const defaultModalTitle = useSelect( ( select ) => - // @ts-expect-error getPostType is not typed with 'wp_template_part' as argument. select( coreStore ).getPostType( 'wp_template_part' )?.labels ?.add_new_item, [] diff --git a/packages/fields/src/fields/parent/parent-edit.tsx b/packages/fields/src/fields/parent/parent-edit.tsx index d42b732a003e85..60830b02c4ade1 100644 --- a/packages/fields/src/fields/parent/parent-edit.tsx +++ b/packages/fields/src/fields/parent/parent-edit.tsx @@ -288,7 +288,6 @@ export const ParentEdit = ( { const { id } = field; const homeUrl = useSelect( ( select ) => { - // @ts-expect-error getEntityRecord is not typed with unstableBase as argument. return select( coreStore ).getEntityRecord< { home: string; } >( 'root', '__unstableBase' )?.home as string; From 8bf0ea57ac55e764ca2f8cf97fe799b42ddb6ca2 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Thu, 12 Dec 2024 12:16:24 +0530 Subject: [PATCH 06/18] Add notice for new entities --- packages/core-data/src/entities.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index 2730cdf3d64bf4..c4f5002d6c3c30 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -215,6 +215,12 @@ export const rootEntitiesConfig = [ plural: 'statuses', key: 'slug', }, + /** + * Adding a new entity? + * + * Don't forget to update the relevant dynamic actions and selectors + * in dynamic-actions.ts and dynamic-selectors.ts. + */ ]; export const additionalEntityConfigLoaders = [ @@ -226,6 +232,12 @@ export const additionalEntityConfigLoaders = [ plural: 'sites', loadEntities: loadSiteEntity, }, + /** + * Adding a new entity? + * + * Don't forget to update the relevant dynamic actions and selectors + * in dynamic-actions.ts and dynamic-selectors.ts. + */ ]; /** From 0096e002990bff0bcfe0d80d43d64cdeacc9a7c1 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 16:13:10 +0530 Subject: [PATCH 07/18] Use existing Type instead of new PostType --- packages/core-data/src/dynamic-selectors.ts | 4 +- packages/core-data/src/entity-types/index.ts | 3 - .../core-data/src/entity-types/post-status.ts | 2 +- .../core-data/src/entity-types/post-type.ts | 106 ------------------ 4 files changed, 3 insertions(+), 112 deletions(-) delete mode 100644 packages/core-data/src/entity-types/post-type.ts diff --git a/packages/core-data/src/dynamic-selectors.ts b/packages/core-data/src/dynamic-selectors.ts index f711299aa5d4ac..09ac04d24053a5 100644 --- a/packages/core-data/src/dynamic-selectors.ts +++ b/packages/core-data/src/dynamic-selectors.ts @@ -18,7 +18,7 @@ export namespace DynamicSelectors { state: State, name: string, query?: GetRecordsHttpQuery - ): ET.PostType | undefined; + ): ET.Type | undefined; /** * Get the list of post type objects. @@ -29,7 +29,7 @@ export namespace DynamicSelectors { export declare function getPostTypes( state: State, query?: GetRecordsHttpQuery - ): Nullable< Array< ET.PostType > >; + ): Nullable< Array< ET.Type > >; /** * Get media item by ID. diff --git a/packages/core-data/src/entity-types/index.ts b/packages/core-data/src/entity-types/index.ts index 66e8cc0c699f72..2c60f199098016 100644 --- a/packages/core-data/src/entity-types/index.ts +++ b/packages/core-data/src/entity-types/index.ts @@ -12,7 +12,6 @@ import type { Page } from './page'; import type { Plugin } from './plugin'; import type { Post } from './post'; import type { PostStatusObject } from './post-status'; -import type { PostType } from './post-type'; import type { Base } from './base'; import type { PostRevision } from './post-revision'; import type { Settings } from './settings'; @@ -41,7 +40,6 @@ export type { Plugin, Post, PostStatusObject, - PostType, PostRevision, Settings, Sidebar, @@ -101,7 +99,6 @@ export interface PerPackageEntityRecords< C extends Context > { | Plugin< C > | Post< C > | PostStatusObject< C > - | PostType< C > | PostRevision< C > | Settings< C > | Sidebar< C > diff --git a/packages/core-data/src/entity-types/post-status.ts b/packages/core-data/src/entity-types/post-status.ts index 50508918b1b8f9..92360dfdc17a60 100644 --- a/packages/core-data/src/entity-types/post-status.ts +++ b/packages/core-data/src/entity-types/post-status.ts @@ -52,5 +52,5 @@ declare module './base-entity-records' { } export type PostStatusObject< C extends Context = 'edit' > = OmitNevers< - _BaseEntityRecords.PostType< C > + _BaseEntityRecords.Type< C > >; diff --git a/packages/core-data/src/entity-types/post-type.ts b/packages/core-data/src/entity-types/post-type.ts deleted file mode 100644 index 492cc946a5148d..00000000000000 --- a/packages/core-data/src/entity-types/post-type.ts +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Internal dependencies - */ -import type { Context, OmitNevers } from './helpers'; -import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; - -declare module './base-entity-records' { - export namespace BaseEntityRecords { - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - export interface PostType< C extends Context > { - /** - * All capabilities used by the post type. - */ - capabilities: Record< string, string >; - - /** - * A human-readable description of the post type. - */ - description: string; - - /** - * Whether or not the post type should have children. - */ - hierarchical: boolean; - - /** - * If the value is a string, the value will be used as the archive slug. If the value is false the post type has no archive. - */ - has_archive: string | boolean; - - /** - * The visibility settings for the post type. - */ - visibility: { - /** - * Whether to generate a default UI for managing this post type. - */ - show_ui: boolean; - - /** - * Whether to make the post type available for selection in navigation menus. - */ - show_in_nav_menus: boolean; - }; - - /** - * Whether or not the post type can be viewed. - */ - viewable: boolean; - - /** - * Human-readable labels for the post type for various contexts. - */ - labels: Record< string, string >; - - /** - * The title for the post type. - */ - name: string; - - /** - * An alphanumeric identifier for the post type. - */ - slug: string; - - /** - * The icon for the post type. - */ - icon: string | null; - - /** - * All features, supported by the post type. - */ - supports: Record< string, boolean >; - - /** - * Taxonomies associated with post type. - */ - taxonomies: Array< string >; - - /** - * REST base route for the post type. - */ - rest_base: string; - - /** - * REST route's namespace for the post type. - */ - rest_namespace: string; - - /** - * The block template associated with the post type. - */ - template: Array< object >; - - /** - * The template_lock associated with the post type, or false if none. - */ - template_lock: string | boolean; - } - } -} - -export type PostType< C extends Context = 'edit' > = OmitNevers< - _BaseEntityRecords.PostType< C > ->; From a6612e62f11c600733957e6b90e46ecd25fe55d7 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 20:49:54 +0530 Subject: [PATCH 08/18] Dynamically create entity selectors and actions --- packages/core-data/src/dynamic-actions.ts | 99 ------ packages/core-data/src/dynamic-entities.ts | 101 ++++++ packages/core-data/src/dynamic-selectors.ts | 371 -------------------- packages/core-data/src/index.js | 7 +- 4 files changed, 104 insertions(+), 474 deletions(-) delete mode 100644 packages/core-data/src/dynamic-actions.ts create mode 100644 packages/core-data/src/dynamic-entities.ts delete mode 100644 packages/core-data/src/dynamic-selectors.ts diff --git a/packages/core-data/src/dynamic-actions.ts b/packages/core-data/src/dynamic-actions.ts deleted file mode 100644 index 1fafa767db92f9..00000000000000 --- a/packages/core-data/src/dynamic-actions.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Internal dependencies - */ -import type * as ET from './entity-types'; - -export namespace DynamicActions { - type DeleteRecordsHttpQuery = Record< string, any >; - - type SaveRecordOptions = { - throwOnError?: boolean; - }; - - type DeleteRecordOptions = { - throwOnError?: boolean; - }; - - /** - * Save the site settings - * - * @param data The site settings - * @param options - */ - export declare function saveSite( - data: Partial< ET.Settings >, - options?: SaveRecordOptions - ): Promise< void >; - - /** - * Save comment - * - * @param data The comment data - * @param options - */ - export declare function saveComment( - data: { id: number } & Partial< ET.Comment >, - options?: SaveRecordOptions - ): Promise< void >; - - /** - * Save media item - * - * @param data The media item - * @param options - */ - export declare function saveMedia( - data: { id: number } & Partial< ET.Attachment >, - options?: SaveRecordOptions - ): Promise< void >; - - /** - * Save user - * - * @param data The user data - * @param options - */ - export declare function saveUser( - data: { id: number } & Partial< ET.User >, - options?: SaveRecordOptions - ): Promise< void >; - - /** - * Delete a comment - * - * @param id The comment ID - * @param query Special query parameters for the DELETE API call - * @param options Delete options - */ - export declare function deleteComment( - id: number, - query?: DeleteRecordsHttpQuery, - options?: DeleteRecordOptions - ): Promise< void >; - - /** - * Delete a media item - * - * @param id The media item ID - * @param query Special query parameters for the DELETE API call - * @param options Delete options - */ - export declare function deleteMedia( - id: number, - query?: DeleteRecordsHttpQuery, - options?: DeleteRecordOptions - ): Promise< void >; - - /** - * Delete a user - * - * @param id The user ID - * @param query Special query parameters for the DELETE API call - * @param options Delete options - */ - export declare function deleteUser( - id: number, - query?: DeleteRecordsHttpQuery, - options?: DeleteRecordOptions - ): Promise< void >; -} diff --git a/packages/core-data/src/dynamic-entities.ts b/packages/core-data/src/dynamic-entities.ts new file mode 100644 index 00000000000000..70fafcc188f329 --- /dev/null +++ b/packages/core-data/src/dynamic-entities.ts @@ -0,0 +1,101 @@ +/** + * Internal dependencies + */ +import type { GetRecordsHttpQuery, State } from './selectors'; +import type * as ET from './entity-types'; + +export type WPEntityTypes< C extends ET.Context = 'edit' > = { + Comment: ET.Comment< C >; + Media: ET.Attachment< C >; + Menu: ET.NavMenu< C >; + MenuItem: ET.NavMenuItem< C >; + MenuLocation: ET.MenuLocation< C >; + Plugin: ET.Plugin< C >; + Post: ET.Post< C >; + PostRevision: ET.PostRevision< C >; + PostType: ET.Type< C >; + Settings: ET.Settings< C >; + Sidebar: ET.Sidebar< C >; + Status: ET.PostStatusObject< C >; + Taxonomy: ET.Taxonomy< C >; + Theme: ET.Theme< C >; + UnstableBase: ET.Base< C >; + User: ET.User< C >; + Widget: ET.Widget< C >; + WidgetType: ET.WidgetType< C >; +}; + +/** + * A simple utility that pluralizes a string. + * Converts: + * - "post" to "posts" + * - "taxonomy" to "taxonomies" + * - "media" to "mediaItems" + */ +type PluralizeEntity< T extends string > = T extends 'Media' + ? 'MediaItems' + : T extends `${ infer U }y` + ? `${ U }ies` + : `${ T }s`; + +/** + * A simple utility that singularizes a string. + * + * Converts: + * - "posts" to "post" + * - "taxonomies" to "taxonomy" + * - "mediaItems" to "media" + */ +type SingularizeEntity< T extends string > = T extends 'MediaItems' + ? 'Media' + : T extends `${ infer U }ies` + ? `${ U }y` + : T extends `${ infer U }s` + ? U + : T; + +export type SingularGetters = { + [ Key in `get${ keyof WPEntityTypes }` ]: ( + state: State, + id: number | string, + query?: GetRecordsHttpQuery + ) => WPEntityTypes[ Key extends `get${ infer E }` ? E : never ] | undefined; +}; + +export type PluralGetters = { + [ Key in `get${ PluralizeEntity< keyof WPEntityTypes > }` ]: ( + state: State, + query?: GetRecordsHttpQuery + ) => Array< + WPEntityTypes[ Key extends `get${ infer E }` + ? SingularizeEntity< E > + : never ] + > | null; +}; + +type ActionOptions = { + throwOnError?: boolean; +}; + +type DeleteRecordsHttpQuery = Record< string, any >; + +export type SaveActions = { + [ Key in `save${ keyof WPEntityTypes }` ]: ( + data: Partial< + WPEntityTypes[ Key extends `save${ infer E }` ? E : never ] + >, + options?: ActionOptions + ) => Promise< void >; +}; + +export type DeleteActions = { + [ Key in `delete${ keyof WPEntityTypes }` ]: ( + id: number | string, + query?: DeleteRecordsHttpQuery, + options?: ActionOptions + ) => Promise< void >; +}; + +export let dynamicActions: SaveActions & DeleteActions; + +export let dynamicSelectors: SingularGetters & PluralGetters; diff --git a/packages/core-data/src/dynamic-selectors.ts b/packages/core-data/src/dynamic-selectors.ts deleted file mode 100644 index 09ac04d24053a5..00000000000000 --- a/packages/core-data/src/dynamic-selectors.ts +++ /dev/null @@ -1,371 +0,0 @@ -/** - * Internal dependencies - */ -import type { GetRecordsHttpQuery, State } from './selectors'; -import type * as ET from './entity-types'; - -export namespace DynamicSelectors { - type Nullable< T > = T | null; - - /** - * Get post type object by name. - * - * @param state Data state. - * @param name Post type name. - * @param query Optional query. If requesting specific - */ - export declare function getPostType( - state: State, - name: string, - query?: GetRecordsHttpQuery - ): ET.Type | undefined; - - /** - * Get the list of post type objects. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getPostTypes( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Type > >; - - /** - * Get media item by ID. - * - * @param state Data state. - * @param id Media item ID. - * @param query Optional query. If requesting specific - */ - export declare function getMedia( - state: State, - id: number, - query?: GetRecordsHttpQuery - ): ET.Attachment | undefined; - - /** - * Get the media items list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getMediaItems( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Attachment > >; - - /** - * Get taxonomy object by name. - * - * @param state Data state. - * @param name Taxonomy name. - * @param query Optional query. If requesting specific - */ - export declare function getTaxonomy( - state: State, - name: string, - query?: GetRecordsHttpQuery - ): ET.Taxonomy | undefined; - - /** - * Get the list of taxonomy objects. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getTaxonomies( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Taxonomy > >; - - /** - * Get sidebar by ID. - * - * @param state Data state. - * @param id Sidebar ID. - * @param query Optional query. If requesting specific - */ - export declare function getSidebar( - state: State, - id: string, - query?: GetRecordsHttpQuery - ): ET.Sidebar | undefined; - - /** - * Get the sidebar list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getSidebars( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Sidebar > >; - - /** - * Get widget by ID. - * - * @param state Data state. - * @param id Sidebar ID. - * @param query Optional query. If requesting specific - */ - export declare function getWidget( - state: State, - id: string, - query?: GetRecordsHttpQuery - ): ET.Widget | undefined; - - /** - * Get the widgets list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getWidgets( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Widget > >; - - /** - * Get widget type by ID. - * - * @param state Data state. - * @param id Sidebar ID. - * @param query Optional query. If requesting specific - */ - export declare function getWidgetType( - state: State, - id: string, - query?: GetRecordsHttpQuery - ): ET.WidgetType | undefined; - - /** - * Get widget types list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getWidgetTypes( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.WidgetType > >; - - /** - * Get user by ID. - * - * @param state Data state. - * @param userId User ID. - * @param query Optional query. If requesting specific - */ - export declare function getUser( - state: State, - userId: number, - query?: GetRecordsHttpQuery - ): ET.User | undefined; - - /** - * Get the users list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getUsers( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.User > >; - - /** - * Get comment by ID. - * - * @param state Data state. - * @param commentId Comment ID. - * @param query Optional query. If requesting specific - */ - export declare function getComment( - state: State, - commentId: number, - query?: GetRecordsHttpQuery - ): ET.Comment | undefined; - - /** - * Get the comments list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getComments( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Comment > >; - - /** - * Get menu by ID. - * - * @param state Data state. - * @param id Menu ID. - * @param query Optional query. If requesting specific - */ - export declare function getMenu( - state: State, - id: number, - query?: GetRecordsHttpQuery - ): ET.NavMenu | undefined; - - /** - * Get the menus list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getMenus( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.NavMenu > >; - - /** - * Get menu item by ID. - * - * @param state Data state. - * @param id Menu item ID. - * @param query Optional query. If requesting specific - */ - export declare function getMenuItem( - state: State, - id: number, - query?: GetRecordsHttpQuery - ): ET.NavMenuItem | undefined; - - /** - * Get the menu items list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getMenuItems( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.NavMenuItem > >; - - /** - * Get menu location by ID. - * - * @param state Data state. - * @param location Menu location. - * @param query Optional query. If requesting specific - */ - export declare function getMenuLocation( - state: State, - location: string, - query?: GetRecordsHttpQuery - ): ET.MenuLocation | undefined; - - /** - * Get the menu locations. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getMenuLocations( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.MenuLocation > >; - - /** - * Get theme by stylesheet. - * - * @param state Data state. - * @param stylesheet Theme stylesheet, e.g. "twentytwentyfour" - * @param query Optional query. If requesting specific - */ - export declare function getTheme( - state: State, - stylesheet: string, - query?: GetRecordsHttpQuery - ): ET.Theme | undefined; - - /** - * Get the themes list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getThemes( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Theme > >; - - /** - * Get plugin. - * - * @param state Data state. - * @param plugin The plugin file, e.g. "classic-editor/classic-editor" - * @param query Optional query. If requesting specific - */ - export declare function getPlugin( - state: State, - plugin: string, - query?: GetRecordsHttpQuery - ): ET.Plugin | undefined; - - /** - * Get the plugins list. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getPlugins( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.Plugin > >; - - /** - * Get post status by name. - * - * @param state Data state. - * @param status The name of a registered post status.. - * @param query Optional query. If requesting specific - */ - export declare function getStatus( - state: State, - status: string, - query?: GetRecordsHttpQuery - ): ET.PostStatusObject | undefined; - - /** - * Get the list of post statuses. - * - * @param state Data state. - * @param query Optional query. If requesting specific - */ - export declare function getStatuses( - state: State, - query?: GetRecordsHttpQuery - ): Nullable< Array< ET.PostStatusObject > >; - - /** - * Get the site object. - * - * @param state Data state. - * @param key Not used. - * @param query Optional query. If requesting specific - */ - export declare function getSite( - state: State, - key?: null, - query?: GetRecordsHttpQuery - ): ET.Settings | undefined; - - /** - * Get the basic site information. - * - * @param state Data state. - * @param key Not used. - * @param query Optional query. If requesting specific - */ - export declare function getUnstableBase( - state: State, - key?: null, - query?: GetRecordsHttpQuery - ): ET.Base | undefined; -} diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 8470ce5c0c1aee..db0fc854961332 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -20,8 +20,7 @@ import { } from './entities'; import { STORE_NAME } from './name'; import { unlock } from './lock-unlock'; -import { DynamicSelectors } from './dynamic-selectors'; -import { DynamicActions } from './dynamic-actions'; +import { dynamicActions, dynamicSelectors } from './dynamic-entities'; // The entity selectors/resolvers and actions are shortcuts to their generic equivalents // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecords) @@ -71,13 +70,13 @@ const entityActions = entitiesConfig.reduce( ( result, entity ) => { const storeConfig = () => ( { reducer, actions: { - ...DynamicActions, + ...dynamicActions, ...actions, ...entityActions, ...createLocksActions(), }, selectors: { - ...DynamicSelectors, + ...dynamicSelectors, ...selectors, ...entitySelectors, }, From bea1374a263f7e65702c508c2f715dcd649320f4 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 20:51:42 +0530 Subject: [PATCH 09/18] Remove unnecessary comment --- packages/core-data/src/entities.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index c4f5002d6c3c30..2730cdf3d64bf4 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -215,12 +215,6 @@ export const rootEntitiesConfig = [ plural: 'statuses', key: 'slug', }, - /** - * Adding a new entity? - * - * Don't forget to update the relevant dynamic actions and selectors - * in dynamic-actions.ts and dynamic-selectors.ts. - */ ]; export const additionalEntityConfigLoaders = [ @@ -232,12 +226,6 @@ export const additionalEntityConfigLoaders = [ plural: 'sites', loadEntities: loadSiteEntity, }, - /** - * Adding a new entity? - * - * Don't forget to update the relevant dynamic actions and selectors - * in dynamic-actions.ts and dynamic-selectors.ts. - */ ]; /** From 5293486eb28bcf483d205bdd7e6397fe50fa45db Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 21:03:29 +0530 Subject: [PATCH 10/18] Export base type as UnstableBase --- packages/core-data/src/dynamic-entities.ts | 2 +- packages/core-data/src/entity-types/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-data/src/dynamic-entities.ts b/packages/core-data/src/dynamic-entities.ts index 70fafcc188f329..4d523d5c52fb3e 100644 --- a/packages/core-data/src/dynamic-entities.ts +++ b/packages/core-data/src/dynamic-entities.ts @@ -19,7 +19,7 @@ export type WPEntityTypes< C extends ET.Context = 'edit' > = { Status: ET.PostStatusObject< C >; Taxonomy: ET.Taxonomy< C >; Theme: ET.Theme< C >; - UnstableBase: ET.Base< C >; + UnstableBase: ET.UnstableBase< C >; User: ET.User< C >; Widget: ET.Widget< C >; WidgetType: ET.WidgetType< C >; diff --git a/packages/core-data/src/entity-types/index.ts b/packages/core-data/src/entity-types/index.ts index 2c60f199098016..8492c7d4e606e3 100644 --- a/packages/core-data/src/entity-types/index.ts +++ b/packages/core-data/src/entity-types/index.ts @@ -29,7 +29,7 @@ export type { BaseEntityRecords } from './base-entity-records'; export type { Attachment, - Base, + Base as UnstableBase, Comment, Context, GlobalStylesRevision, From 105423acbac1c133071c6e4b95fb78cb89878de2 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 21:07:49 +0530 Subject: [PATCH 11/18] Add template related types to base --- packages/core-data/src/entity-types/base.ts | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/core-data/src/entity-types/base.ts b/packages/core-data/src/entity-types/base.ts index 3d11bd2081e24f..ef5e7b0ca2b05f 100644 --- a/packages/core-data/src/entity-types/base.ts +++ b/packages/core-data/src/entity-types/base.ts @@ -4,6 +4,19 @@ import type { Context, OmitNevers } from './helpers'; import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; +type TemplatePartArea = { + area: string; + label: string; + icon: string; + description: string; +}; + +type TemplateType = { + title: string; + description: string; + slug: string; +}; + declare module './base-entity-records' { export namespace BaseEntityRecords { /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ @@ -52,6 +65,16 @@ declare module './base-entity-records' { * Site URL. */ url: string; + + /** + * Default template part areas. + */ + default_template_part_areas?: Array< TemplatePartArea >; + + /** + * Default template types + */ + default_template_types?: Array< TemplateType >; } } } From 1a459900a95709ea0a3dc60d7751b10e5ea0dd88 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 21:08:48 +0530 Subject: [PATCH 12/18] Get rid of one more @ts-expect-error --- .../components/create-template-part-modal/index.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/fields/src/components/create-template-part-modal/index.tsx b/packages/fields/src/components/create-template-part-modal/index.tsx index 2115c5ed605677..4414981dac066c 100644 --- a/packages/fields/src/components/create-template-part-modal/index.tsx +++ b/packages/fields/src/components/create-template-part-modal/index.tsx @@ -16,6 +16,7 @@ import { __experimentalVStack as VStack, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; +import type { UnstableBase } from '@wordpress/core-data'; import { store as coreStore } from '@wordpress/core-data'; import { useDispatch, useSelect } from '@wordpress/data'; import { useState } from '@wordpress/element'; @@ -50,13 +51,6 @@ type CreateTemplatePartModalContentsProps = { defaultTitle?: string; }; -type TemplatePartArea = { - area: string; - label: string; - icon: string; - description: string; -}; - /** * A React component that renders a modal for creating a template part. The modal displays a title and the contents for creating the template part. * This component should not live in this package, it should be moved to a dedicated package responsible for managing template. @@ -132,9 +126,8 @@ export function CreateTemplatePartModalContents( { const defaultTemplatePartAreas = useSelect( ( select ) => - // @ts-expect-error getEntityRecord is not typed with unstableBase as argument. select( coreStore ).getEntityRecord< { - default_template_part_areas: Array< TemplatePartArea >; + default_template_part_areas: UnstableBase[ 'default_template_part_areas' ]; } >( 'root', '__unstableBase' )?.default_template_part_areas, [] ); From fa2a98b00308de336f934e18064ed1b6729446cd Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 21:12:38 +0530 Subject: [PATCH 13/18] Fix Site, Status and Revision types --- packages/core-data/src/dynamic-entities.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/core-data/src/dynamic-entities.ts b/packages/core-data/src/dynamic-entities.ts index 4d523d5c52fb3e..3fd24342b88af3 100644 --- a/packages/core-data/src/dynamic-entities.ts +++ b/packages/core-data/src/dynamic-entities.ts @@ -11,11 +11,10 @@ export type WPEntityTypes< C extends ET.Context = 'edit' > = { MenuItem: ET.NavMenuItem< C >; MenuLocation: ET.MenuLocation< C >; Plugin: ET.Plugin< C >; - Post: ET.Post< C >; - PostRevision: ET.PostRevision< C >; PostType: ET.Type< C >; - Settings: ET.Settings< C >; + Revision: ET.PostRevision< C >; Sidebar: ET.Sidebar< C >; + Site: ET.Settings< C >; Status: ET.PostStatusObject< C >; Taxonomy: ET.Taxonomy< C >; Theme: ET.Theme< C >; @@ -31,9 +30,12 @@ export type WPEntityTypes< C extends ET.Context = 'edit' > = { * - "post" to "posts" * - "taxonomy" to "taxonomies" * - "media" to "mediaItems" + * - "status" to "statuses" */ type PluralizeEntity< T extends string > = T extends 'Media' ? 'MediaItems' + : T extends 'Status' + ? 'Statuses' : T extends `${ infer U }y` ? `${ U }ies` : `${ T }s`; @@ -45,9 +47,12 @@ type PluralizeEntity< T extends string > = T extends 'Media' * - "posts" to "post" * - "taxonomies" to "taxonomy" * - "mediaItems" to "media" + * - "statuses" to "status" */ type SingularizeEntity< T extends string > = T extends 'MediaItems' ? 'Media' + : T extends 'Statuses' + ? 'Status' : T extends `${ infer U }ies` ? `${ U }y` : T extends `${ infer U }s` From 1f5bd6795fe050bd4cbc3f0722d349617854186b Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Fri, 3 Jan 2025 19:32:48 +0530 Subject: [PATCH 14/18] Add GlobalStyles --- packages/core-data/src/dynamic-entities.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/core-data/src/dynamic-entities.ts b/packages/core-data/src/dynamic-entities.ts index 3fd24342b88af3..7ee9e3e9b1f38f 100644 --- a/packages/core-data/src/dynamic-entities.ts +++ b/packages/core-data/src/dynamic-entities.ts @@ -6,6 +6,7 @@ import type * as ET from './entity-types'; export type WPEntityTypes< C extends ET.Context = 'edit' > = { Comment: ET.Comment< C >; + GlobalStyles: ET.GlobalStylesRevision< C >; Media: ET.Attachment< C >; Menu: ET.NavMenu< C >; MenuItem: ET.NavMenuItem< C >; @@ -32,7 +33,9 @@ export type WPEntityTypes< C extends ET.Context = 'edit' > = { * - "media" to "mediaItems" * - "status" to "statuses" */ -type PluralizeEntity< T extends string > = T extends 'Media' +type PluralizeEntity< T extends string > = T extends 'GlobalStyles' + ? 'GlobalStylesVariations' + : T extends 'Media' ? 'MediaItems' : T extends 'Status' ? 'Statuses' @@ -49,7 +52,9 @@ type PluralizeEntity< T extends string > = T extends 'Media' * - "mediaItems" to "media" * - "statuses" to "status" */ -type SingularizeEntity< T extends string > = T extends 'MediaItems' +type SingularizeEntity< T extends string > = T extends 'GlobalStylesVariations' + ? 'GlobalStyles' + : T extends 'MediaItems' ? 'Media' : T extends 'Statuses' ? 'Status' From 7b2364341879c691acfca17d0b9b7e1239700748 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Fri, 3 Jan 2025 19:59:18 +0530 Subject: [PATCH 15/18] Disable plural for global styles --- packages/core-data/src/dynamic-entities.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/core-data/src/dynamic-entities.ts b/packages/core-data/src/dynamic-entities.ts index 7ee9e3e9b1f38f..821d798cce9f54 100644 --- a/packages/core-data/src/dynamic-entities.ts +++ b/packages/core-data/src/dynamic-entities.ts @@ -34,7 +34,7 @@ export type WPEntityTypes< C extends ET.Context = 'edit' > = { * - "status" to "statuses" */ type PluralizeEntity< T extends string > = T extends 'GlobalStyles' - ? 'GlobalStylesVariations' + ? never : T extends 'Media' ? 'MediaItems' : T extends 'Status' @@ -52,9 +52,7 @@ type PluralizeEntity< T extends string > = T extends 'GlobalStyles' * - "mediaItems" to "media" * - "statuses" to "status" */ -type SingularizeEntity< T extends string > = T extends 'GlobalStylesVariations' - ? 'GlobalStyles' - : T extends 'MediaItems' +type SingularizeEntity< T extends string > = T extends 'MediaItems' ? 'Media' : T extends 'Statuses' ? 'Status' From 465521b028167e11270058794e4d10705d70848d Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Fri, 3 Jan 2025 20:28:49 +0530 Subject: [PATCH 16/18] Add a note about "GlobalStyles" --- packages/core-data/src/dynamic-entities.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core-data/src/dynamic-entities.ts b/packages/core-data/src/dynamic-entities.ts index 821d798cce9f54..51b579cb0cfcf0 100644 --- a/packages/core-data/src/dynamic-entities.ts +++ b/packages/core-data/src/dynamic-entities.ts @@ -32,6 +32,8 @@ export type WPEntityTypes< C extends ET.Context = 'edit' > = { * - "taxonomy" to "taxonomies" * - "media" to "mediaItems" * - "status" to "statuses" + * + * It does not pluralize "GlobalStyles" due to lack of clarity about it at time of writing. */ type PluralizeEntity< T extends string > = T extends 'GlobalStyles' ? never From a4fea0bb7f43abd4956b1b01f7e0f100c44e3977 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Fri, 3 Jan 2025 20:29:12 +0530 Subject: [PATCH 17/18] Fix type for gmt_offset --- packages/core-data/src/entity-types/base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-data/src/entity-types/base.ts b/packages/core-data/src/entity-types/base.ts index ef5e7b0ca2b05f..1507ab1a1c9042 100644 --- a/packages/core-data/src/entity-types/base.ts +++ b/packages/core-data/src/entity-types/base.ts @@ -29,7 +29,7 @@ declare module './base-entity-records' { /** * GMT offset for the site. */ - gmt_offset: string | number; + gmt_offset: string; /** * Home URL. From 70f681e7969d03ede6f76dd0b91f555b57d004c1 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Fri, 3 Jan 2025 20:30:07 +0530 Subject: [PATCH 18/18] Export and use TemplatePartArea --- packages/core-data/src/entity-types/base.ts | 4 ++-- packages/core-data/src/entity-types/index.ts | 8 +++++--- .../src/components/create-template-part-modal/index.tsx | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/core-data/src/entity-types/base.ts b/packages/core-data/src/entity-types/base.ts index 1507ab1a1c9042..79a3039ad140dc 100644 --- a/packages/core-data/src/entity-types/base.ts +++ b/packages/core-data/src/entity-types/base.ts @@ -4,14 +4,14 @@ import type { Context, OmitNevers } from './helpers'; import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; -type TemplatePartArea = { +export type TemplatePartArea = { area: string; label: string; icon: string; description: string; }; -type TemplateType = { +export type TemplateType = { title: string; description: string; slug: string; diff --git a/packages/core-data/src/entity-types/index.ts b/packages/core-data/src/entity-types/index.ts index 8492c7d4e606e3..68087a74005b2c 100644 --- a/packages/core-data/src/entity-types/index.ts +++ b/packages/core-data/src/entity-types/index.ts @@ -3,6 +3,7 @@ */ import type { Context, Updatable } from './helpers'; import type { Attachment } from './attachment'; +import type { Base, TemplatePartArea, TemplateType } from './base'; import type { Comment } from './comment'; import type { GlobalStylesRevision } from './global-styles-revision'; import type { MenuLocation } from './menu-location'; @@ -12,7 +13,6 @@ import type { Page } from './page'; import type { Plugin } from './plugin'; import type { Post } from './post'; import type { PostStatusObject } from './post-status'; -import type { Base } from './base'; import type { PostRevision } from './post-revision'; import type { Settings } from './settings'; import type { Sidebar } from './sidebar'; @@ -39,15 +39,17 @@ export type { Page, Plugin, Post, - PostStatusObject, PostRevision, + PostStatusObject, Settings, Sidebar, Taxonomy, + TemplatePartArea, + TemplateType, Theme, + Type, Updatable, User, - Type, Widget, WidgetType, WpTemplate, diff --git a/packages/fields/src/components/create-template-part-modal/index.tsx b/packages/fields/src/components/create-template-part-modal/index.tsx index 2664429298580e..927192eee17fcd 100644 --- a/packages/fields/src/components/create-template-part-modal/index.tsx +++ b/packages/fields/src/components/create-template-part-modal/index.tsx @@ -11,7 +11,7 @@ import { __experimentalVStack as VStack, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; -import type { UnstableBase } from '@wordpress/core-data'; +import type { TemplatePartArea } from '@wordpress/core-data'; import { store as coreStore } from '@wordpress/core-data'; import { useDispatch, useSelect } from '@wordpress/data'; import { useState } from '@wordpress/element'; @@ -129,7 +129,7 @@ export function CreateTemplatePartModalContents( { const defaultTemplatePartAreas = useSelect( ( select ) => select( coreStore ).getEntityRecord< { - default_template_part_areas: UnstableBase[ 'default_template_part_areas' ]; + default_template_part_areas: Array< TemplatePartArea >; } >( 'root', '__unstableBase' )?.default_template_part_areas, [] );