@wordpress/core-data 4.1.1 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/build/actions.js +1 -1
- package/build/actions.js.map +1 -1
- package/build/hooks/constants.js +18 -0
- package/build/hooks/constants.js.map +1 -0
- package/build/hooks/memoize.js +18 -0
- package/build/hooks/memoize.js.map +1 -0
- package/build/hooks/use-entity-record.js +60 -0
- package/build/hooks/use-entity-record.js.map +1 -0
- package/build/hooks/use-entity-records.js +67 -0
- package/build/hooks/use-entity-records.js.map +1 -0
- package/build/hooks/use-query-select.js +130 -0
- package/build/hooks/use-query-select.js.map +1 -0
- package/build/index.js +34 -3
- package/build/index.js.map +1 -1
- package/build/resolvers.js +2 -17
- package/build/resolvers.js.map +1 -1
- package/build/types/attachment.js +6 -0
- package/build/types/attachment.js.map +1 -0
- package/build/types/base-entity-types.js +47 -0
- package/build/types/base-entity-types.js.map +1 -0
- package/build/types/comment.js +6 -0
- package/build/types/comment.js.map +1 -0
- package/build/types/helpers.js +6 -0
- package/build/types/helpers.js.map +1 -0
- package/build/types/index.js +6 -0
- package/build/types/index.js.map +1 -0
- package/build/types/menu-location.js +6 -0
- package/build/types/menu-location.js.map +1 -0
- package/build/types/nav-menu-item.js +6 -0
- package/build/types/nav-menu-item.js.map +1 -0
- package/build/types/nav-menu.js +6 -0
- package/build/types/nav-menu.js.map +1 -0
- package/build/types/navigation-area.js +6 -0
- package/build/types/navigation-area.js.map +1 -0
- package/build/types/page.js +6 -0
- package/build/types/page.js.map +1 -0
- package/build/types/plugin.js +6 -0
- package/build/types/plugin.js.map +1 -0
- package/build/types/post.js +6 -0
- package/build/types/post.js.map +1 -0
- package/build/types/settings.js +6 -0
- package/build/types/settings.js.map +1 -0
- package/build/types/sidebar.js +6 -0
- package/build/types/sidebar.js.map +1 -0
- package/build/types/taxonomy.js +6 -0
- package/build/types/taxonomy.js.map +1 -0
- package/build/types/theme.js +6 -0
- package/build/types/theme.js.map +1 -0
- package/build/types/type.js +6 -0
- package/build/types/type.js.map +1 -0
- package/build/types/user.js +6 -0
- package/build/types/user.js.map +1 -0
- package/build/types/widget-type.js +6 -0
- package/build/types/widget-type.js.map +1 -0
- package/build/types/widget.js +6 -0
- package/build/types/widget.js.map +1 -0
- package/build/types/wp-template-part.js +6 -0
- package/build/types/wp-template-part.js.map +1 -0
- package/build/types/wp-template.js +6 -0
- package/build/types/wp-template.js.map +1 -0
- package/build-module/actions.js +1 -1
- package/build-module/actions.js.map +1 -1
- package/build-module/hooks/constants.js +10 -0
- package/build-module/hooks/constants.js.map +1 -0
- package/build-module/hooks/memoize.js +7 -0
- package/build-module/hooks/memoize.js.map +1 -0
- package/build-module/hooks/use-entity-record.js +49 -0
- package/build-module/hooks/use-entity-record.js.map +1 -0
- package/build-module/hooks/use-entity-records.js +56 -0
- package/build-module/hooks/use-entity-records.js.map +1 -0
- package/build-module/hooks/use-query-select.js +116 -0
- package/build-module/hooks/use-query-select.js.map +1 -0
- package/build-module/index.js +4 -2
- package/build-module/index.js.map +1 -1
- package/build-module/resolvers.js +3 -18
- package/build-module/resolvers.js.map +1 -1
- package/build-module/types/attachment.js +2 -0
- package/build-module/types/attachment.js.map +1 -0
- package/build-module/types/base-entity-types.js +39 -0
- package/build-module/types/base-entity-types.js.map +1 -0
- package/build-module/types/comment.js +2 -0
- package/build-module/types/comment.js.map +1 -0
- package/build-module/types/helpers.js +2 -0
- package/build-module/types/helpers.js.map +1 -0
- package/build-module/types/index.js +2 -0
- package/build-module/types/index.js.map +1 -0
- package/build-module/types/menu-location.js +2 -0
- package/build-module/types/menu-location.js.map +1 -0
- package/build-module/types/nav-menu-item.js +2 -0
- package/build-module/types/nav-menu-item.js.map +1 -0
- package/build-module/types/nav-menu.js +2 -0
- package/build-module/types/nav-menu.js.map +1 -0
- package/build-module/types/navigation-area.js +2 -0
- package/build-module/types/navigation-area.js.map +1 -0
- package/build-module/types/page.js +2 -0
- package/build-module/types/page.js.map +1 -0
- package/build-module/types/plugin.js +2 -0
- package/build-module/types/plugin.js.map +1 -0
- package/build-module/types/post.js +2 -0
- package/build-module/types/post.js.map +1 -0
- package/build-module/types/settings.js +2 -0
- package/build-module/types/settings.js.map +1 -0
- package/build-module/types/sidebar.js +2 -0
- package/build-module/types/sidebar.js.map +1 -0
- package/build-module/types/taxonomy.js +2 -0
- package/build-module/types/taxonomy.js.map +1 -0
- package/build-module/types/theme.js +2 -0
- package/build-module/types/theme.js.map +1 -0
- package/build-module/types/type.js +2 -0
- package/build-module/types/type.js.map +1 -0
- package/build-module/types/user.js +2 -0
- package/build-module/types/user.js.map +1 -0
- package/build-module/types/widget-type.js +2 -0
- package/build-module/types/widget-type.js.map +1 -0
- package/build-module/types/widget.js +2 -0
- package/build-module/types/widget.js.map +1 -0
- package/build-module/types/wp-template-part.js +2 -0
- package/build-module/types/wp-template-part.js.map +1 -0
- package/build-module/types/wp-template.js +2 -0
- package/build-module/types/wp-template.js.map +1 -0
- package/package.json +5 -4
- package/src/actions.js +1 -1
- package/src/hooks/constants.ts +7 -0
- package/src/hooks/memoize.js +7 -0
- package/src/hooks/test/use-entity-record.js +74 -0
- package/src/hooks/test/use-entity-records.js +78 -0
- package/src/hooks/test/use-query-select.js +194 -0
- package/src/hooks/use-entity-record.ts +72 -0
- package/src/hooks/use-entity-records.ts +79 -0
- package/src/hooks/use-query-select.ts +131 -0
- package/src/index.js +3 -1
- package/src/resolvers.js +3 -17
- package/src/test/resolvers.js +4 -10
- package/src/types/README.md +193 -0
- package/src/types/attachment.ts +146 -0
- package/src/types/base-entity-types.ts +36 -0
- package/src/types/comment.ts +96 -0
- package/src/types/helpers.ts +153 -0
- package/src/types/index.ts +72 -0
- package/src/types/menu-location.ts +29 -0
- package/src/types/nav-menu-item.ts +106 -0
- package/src/types/nav-menu.ts +53 -0
- package/src/types/navigation-area.ts +29 -0
- package/src/types/page.ts +144 -0
- package/src/types/plugin.ts +74 -0
- package/src/types/post.ts +153 -0
- package/src/types/settings.ts +93 -0
- package/src/types/sidebar.ts +60 -0
- package/src/types/taxonomy.ts +92 -0
- package/src/types/theme.ts +222 -0
- package/src/types/type.ts +80 -0
- package/src/types/user.ts +109 -0
- package/src/types/widget-type.ts +37 -0
- package/src/types/widget.ts +64 -0
- package/src/types/wp-template-part.ts +94 -0
- package/src/types/wp-template.ts +94 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Entity Records Types
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The types in this directory are designed to support the following use-cases:
|
|
6
|
+
|
|
7
|
+
* Provide type-hinting and documentation for entity records fetched in the various REST API contexts.
|
|
8
|
+
* Type-check the values we use to *edit* entity records, the values that are sent back to the server as updates.
|
|
9
|
+
|
|
10
|
+
**Warning:** The types model the expected API responses which is **not** the same as having a full type safety for the API-related operations. The API responses are type-cast to these definitions and therefore may not match those expectations; for example, a plugin could modify the response, or the API endpoint could have a nuanced implementation in which strings are sometimes used instead of numbers.
|
|
11
|
+
|
|
12
|
+
### Context-aware type checks for entity records
|
|
13
|
+
|
|
14
|
+
WordPress REST API returns different responses based on the `context` query parameter, which typically is one of `view`, `edit`, or `embed`. See the [REST API documentation](https://developer.wordpress.org/rest-api/) to learn more.
|
|
15
|
+
|
|
16
|
+
For example, requesting `/wp/v2/posts/1?context=view` yields:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
{
|
|
20
|
+
"content": {
|
|
21
|
+
"protected": false,
|
|
22
|
+
"rendered": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n"
|
|
23
|
+
},
|
|
24
|
+
"title": {
|
|
25
|
+
"rendered": "Hello world!"
|
|
26
|
+
}
|
|
27
|
+
// other fields
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
While requesting `/wp/v2/posts/1?context=edit`, yields:
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
{
|
|
35
|
+
"content": {
|
|
36
|
+
"block_version": 1,
|
|
37
|
+
"protected": false,
|
|
38
|
+
"raw": "<!-- wp:paragraph -->\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n<!-- /wp:paragraph -->",
|
|
39
|
+
"rendered": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n"
|
|
40
|
+
},
|
|
41
|
+
"title": {
|
|
42
|
+
"raw": "Hello world!",
|
|
43
|
+
"rendered": "Hello world!"
|
|
44
|
+
}
|
|
45
|
+
// other fields
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
And, finally, requesting `/wp/v2/posts/1?context=embed` yields:
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
{
|
|
53
|
+
// Note content is missing
|
|
54
|
+
"title": {
|
|
55
|
+
"rendered": "Hello world!"
|
|
56
|
+
}
|
|
57
|
+
// other fields
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
These contexts are supported by the core-data resolvers like `getEntityRecord()` and `getEntityRecords()` to retrieve the appropriate "flavor" of the data.
|
|
62
|
+
|
|
63
|
+
The types describing different entity records must thus be aware of the relevant API context. This is implemented using the `Context` type parameter. For example, the implementation of the `Post` type resembles the following snippet:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
interface Post<C extends Context> {
|
|
67
|
+
/**
|
|
68
|
+
* A named status for the post.
|
|
69
|
+
*/
|
|
70
|
+
status: ContextualField< PostStatus, 'view' | 'edit', C >;
|
|
71
|
+
|
|
72
|
+
// ... other fields ...
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The `status` field is a `PostStatus` when the requesting context is `view` or `edit`, but if requested with an `embed` context the field won't appear on the `Post` object at all.
|
|
77
|
+
|
|
78
|
+
### Static type checks for *edited* entity records, where certain fields become strings instead of objects.
|
|
79
|
+
|
|
80
|
+
When the `post` is retrieved using `getEntityRecord`, its `content` field is an object:
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
const post = wp.data.select('core').getEntityRecord( 'postType', 'post', 1, { context: 'view' } )
|
|
84
|
+
// `post.content` is an object with two fields: protected and rendered
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The block markup stored in `content` can only be rendered on the server so the REST API exposes both the raw markup and the rendered version. For example, `content.rendered` could used as a visual preview, and `content.raw` could be used to populate the code editor.
|
|
88
|
+
|
|
89
|
+
When updating that field from the JavaScript code, however, all we can set is the raw value that the server will eventually render. The API expects us to send a much simpler `string` form which is the raw form that needs to be stored in the database.
|
|
90
|
+
|
|
91
|
+
The types reflect this through the `Updatable<EntityRecord>` wrapper:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
interface Post< C extends Context > {
|
|
95
|
+
title: {
|
|
96
|
+
raw: string;
|
|
97
|
+
rendered: string;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const post : Post< 'edit' > = ...
|
|
102
|
+
// post.title is an object with properties `raw` and `rendered`
|
|
103
|
+
|
|
104
|
+
const post : Updatable<Post< 'edit' >> = ...
|
|
105
|
+
// post.title is a string
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The `getEditedEntityRecord` selector returns the Updatable version of the entity records:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
const post = wp.data.select('core').getEditedEntityRecord( 'postType', 'post', 1 );
|
|
112
|
+
// `post.content` is a string
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Helpers
|
|
116
|
+
|
|
117
|
+
### Context
|
|
118
|
+
|
|
119
|
+
The REST API context parameter.
|
|
120
|
+
|
|
121
|
+
### ContextualField
|
|
122
|
+
|
|
123
|
+
`ContextualField` makes the field available only in the specified given contexts, and ensure the field is absent from the object when in a different context.
|
|
124
|
+
|
|
125
|
+
Example:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
interface Post< C extends Context > {
|
|
129
|
+
…
|
|
130
|
+
modified: ContextualField< string, 'edit' | 'view', C >;
|
|
131
|
+
password: ContextualField< string, 'edit', C >;
|
|
132
|
+
…
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const post: Post<'edit'> = …
|
|
136
|
+
// post.modified exists as a string
|
|
137
|
+
// post.password exists as a string
|
|
138
|
+
|
|
139
|
+
const post: Post<'view'> = …
|
|
140
|
+
// post.modified still exists as a string
|
|
141
|
+
// post.password is missing, undefined, because we're not in the `edit` context.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### OmitNevers
|
|
145
|
+
|
|
146
|
+
Removes all the properties of type never, even the deeply nested ones.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
type MyType = {
|
|
150
|
+
foo: string;
|
|
151
|
+
bar: never;
|
|
152
|
+
nested: {
|
|
153
|
+
foo: string;
|
|
154
|
+
bar: never;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const x = {} as OmitNevers<MyType>;
|
|
158
|
+
// x is of type { foo: string; nested: { foo: string; }}
|
|
159
|
+
// The `never` properties were removed entirely
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Updatable
|
|
163
|
+
|
|
164
|
+
Updatable<EntityRecord> is a type describing Edited Entity Records. They are like
|
|
165
|
+
regular Entity Records, but they have all the local edits applied on top of the REST API data.
|
|
166
|
+
|
|
167
|
+
This turns certain field from an object into a string.
|
|
168
|
+
|
|
169
|
+
Entities like Post have fields that only be rendered on the server, like title, excerpt,
|
|
170
|
+
and content. The REST API exposes both the raw markup and the rendered version of those fields.
|
|
171
|
+
For example, in the block editor, content.rendered could used as a visual preview, and
|
|
172
|
+
content.raw could be used to populate the code editor.
|
|
173
|
+
|
|
174
|
+
When updating these rendered fields, JavaScript is not be able to properly render arbitrary block
|
|
175
|
+
markup. Therefore, it stores only the raw markup without the rendered part. And since that's a string,
|
|
176
|
+
the entire field becomes a string.
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
type Post< C extends Context > {
|
|
180
|
+
title: RenderedText< C >;
|
|
181
|
+
}
|
|
182
|
+
const post = {} as Post;
|
|
183
|
+
// post.title is an object with raw and rendered properties
|
|
184
|
+
|
|
185
|
+
const updatablePost = {} as Updatable< Post >;
|
|
186
|
+
// updatablePost.title is a string
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### RenderedText
|
|
190
|
+
|
|
191
|
+
A string that the server renders which often involves modifications from the raw source string.
|
|
192
|
+
|
|
193
|
+
For example, block HTML with the comment delimiters exists in `post_content` but those comments are stripped out when rendering to a page view. Similarly, plugins might modify content or replace shortcodes.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
Context,
|
|
6
|
+
ContextualField,
|
|
7
|
+
MediaType,
|
|
8
|
+
PostStatus,
|
|
9
|
+
RenderedText,
|
|
10
|
+
OmitNevers,
|
|
11
|
+
CommentingStatus,
|
|
12
|
+
PingStatus,
|
|
13
|
+
} from './helpers';
|
|
14
|
+
|
|
15
|
+
import { BaseEntityTypes as _BaseEntityTypes } from './base-entity-types';
|
|
16
|
+
|
|
17
|
+
declare module './base-entity-types' {
|
|
18
|
+
export namespace BaseEntityTypes {
|
|
19
|
+
export interface Attachment< C extends Context > {
|
|
20
|
+
/**
|
|
21
|
+
* The date the post was published, in the site's timezone.
|
|
22
|
+
*/
|
|
23
|
+
date: string | null;
|
|
24
|
+
/**
|
|
25
|
+
* The date the post was published, as GMT.
|
|
26
|
+
*/
|
|
27
|
+
date_gmt: ContextualField< string | null, 'view' | 'edit', C >;
|
|
28
|
+
/**
|
|
29
|
+
* The globally unique identifier for the post.
|
|
30
|
+
*/
|
|
31
|
+
guid: ContextualField< RenderedText< C >, 'view' | 'edit', C >;
|
|
32
|
+
/**
|
|
33
|
+
* Unique identifier for the post.
|
|
34
|
+
*/
|
|
35
|
+
id: number;
|
|
36
|
+
/**
|
|
37
|
+
* URL to the post.
|
|
38
|
+
*/
|
|
39
|
+
link: string;
|
|
40
|
+
/**
|
|
41
|
+
* The date the post was last modified, in the site's timezone.
|
|
42
|
+
*/
|
|
43
|
+
modified: ContextualField< string, 'view' | 'edit', C >;
|
|
44
|
+
/**
|
|
45
|
+
* The date the post was last modified, as GMT.
|
|
46
|
+
*/
|
|
47
|
+
modified_gmt: ContextualField< string, 'view' | 'edit', C >;
|
|
48
|
+
/**
|
|
49
|
+
* An alphanumeric identifier for the post unique to its type.
|
|
50
|
+
*/
|
|
51
|
+
slug: string;
|
|
52
|
+
/**
|
|
53
|
+
* A named status for the post.
|
|
54
|
+
*/
|
|
55
|
+
status: ContextualField< PostStatus, 'view' | 'edit', C >;
|
|
56
|
+
/**
|
|
57
|
+
* Type of post.
|
|
58
|
+
*/
|
|
59
|
+
type: string;
|
|
60
|
+
/**
|
|
61
|
+
* Permalink template for the post.
|
|
62
|
+
*/
|
|
63
|
+
permalink_template: ContextualField< string, 'edit', C >;
|
|
64
|
+
/**
|
|
65
|
+
* Slug automatically generated from the post title.
|
|
66
|
+
*/
|
|
67
|
+
generated_slug: ContextualField< string, 'edit', C >;
|
|
68
|
+
/**
|
|
69
|
+
* The title for the post.
|
|
70
|
+
*/
|
|
71
|
+
title: RenderedText< C >;
|
|
72
|
+
/**
|
|
73
|
+
* The ID for the author of the post.
|
|
74
|
+
*/
|
|
75
|
+
author: number;
|
|
76
|
+
/**
|
|
77
|
+
* Whether or not comments are open on the post.
|
|
78
|
+
*/
|
|
79
|
+
comment_status: ContextualField<
|
|
80
|
+
CommentingStatus,
|
|
81
|
+
'view' | 'edit',
|
|
82
|
+
C
|
|
83
|
+
>;
|
|
84
|
+
/**
|
|
85
|
+
* Whether or not the post can be pinged.
|
|
86
|
+
*/
|
|
87
|
+
ping_status: ContextualField< PingStatus, 'view' | 'edit', C >;
|
|
88
|
+
/**
|
|
89
|
+
* Meta fields.
|
|
90
|
+
*/
|
|
91
|
+
meta: ContextualField<
|
|
92
|
+
Record< string, string >,
|
|
93
|
+
'view' | 'edit',
|
|
94
|
+
C
|
|
95
|
+
>;
|
|
96
|
+
/**
|
|
97
|
+
* The theme file to use to display the post.
|
|
98
|
+
*/
|
|
99
|
+
template: ContextualField< string, 'view' | 'edit', C >;
|
|
100
|
+
/**
|
|
101
|
+
* Alternative text to display when attachment is not displayed.
|
|
102
|
+
*/
|
|
103
|
+
alt_text: string;
|
|
104
|
+
/**
|
|
105
|
+
* The attachment caption.
|
|
106
|
+
*/
|
|
107
|
+
caption: ContextualField< string, 'edit', C >;
|
|
108
|
+
/**
|
|
109
|
+
* The attachment description.
|
|
110
|
+
*/
|
|
111
|
+
description: ContextualField<
|
|
112
|
+
RenderedText< C >,
|
|
113
|
+
'view' | 'edit',
|
|
114
|
+
C
|
|
115
|
+
>;
|
|
116
|
+
/**
|
|
117
|
+
* Attachment type.
|
|
118
|
+
*/
|
|
119
|
+
media_type: MediaType;
|
|
120
|
+
/**
|
|
121
|
+
* The attachment MIME type.
|
|
122
|
+
*/
|
|
123
|
+
mime_type: string;
|
|
124
|
+
/**
|
|
125
|
+
* Details about the media file, specific to its type.
|
|
126
|
+
*/
|
|
127
|
+
media_details: Record< string, string >;
|
|
128
|
+
/**
|
|
129
|
+
* The ID for the associated post of the attachment.
|
|
130
|
+
*/
|
|
131
|
+
post: ContextualField< number, 'view' | 'edit', C >;
|
|
132
|
+
/**
|
|
133
|
+
* URL to the original attachment file.
|
|
134
|
+
*/
|
|
135
|
+
source_url: string;
|
|
136
|
+
/**
|
|
137
|
+
* List of the missing image sizes of the attachment.
|
|
138
|
+
*/
|
|
139
|
+
missing_image_sizes: ContextualField< string[], 'edit', C >;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export type Attachment< C extends Context > = OmitNevers<
|
|
145
|
+
_BaseEntityTypes.Attachment< C >
|
|
146
|
+
>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module exists solely to make the BaseEntityTypes namespace extensible
|
|
3
|
+
* with declaration merging:
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* declare module './base-entity-types' {
|
|
7
|
+
* export namespace BaseEntityTypes {
|
|
8
|
+
* export interface Comment< C extends Context > {
|
|
9
|
+
* id: number;
|
|
10
|
+
* // ...
|
|
11
|
+
* }
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The huge upside is that consumers of @wordpress/core-data may extend the
|
|
17
|
+
* exported data types using interface merging as follows:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import type { Context } from '@wordpress/core-data';
|
|
21
|
+
* declare module '@wordpress/core-data' {
|
|
22
|
+
* export namespace BaseEntityTypes {
|
|
23
|
+
* export interface Comment< C extends Context > {
|
|
24
|
+
* numberOfViews: number;
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* import type { Comment } from '@wordpress/core-data';
|
|
30
|
+
* const c : Comment< 'view' > = ...;
|
|
31
|
+
*
|
|
32
|
+
* // c.numberOfViews is a number
|
|
33
|
+
* // c.id is still present
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export namespace BaseEntityTypes {}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
AvatarUrls,
|
|
6
|
+
Context,
|
|
7
|
+
ContextualField,
|
|
8
|
+
OmitNevers,
|
|
9
|
+
RenderedText,
|
|
10
|
+
} from './helpers';
|
|
11
|
+
import { BaseEntityTypes as _BaseEntityTypes } from './base-entity-types';
|
|
12
|
+
|
|
13
|
+
export type CommentStatus = 'hold' | 'approve' | 'spam' | 'trash' | '1' | '0';
|
|
14
|
+
|
|
15
|
+
declare module './base-entity-types' {
|
|
16
|
+
export namespace BaseEntityTypes {
|
|
17
|
+
export interface Comment< C extends Context > {
|
|
18
|
+
/**
|
|
19
|
+
* Unique identifier for the comment.
|
|
20
|
+
*/
|
|
21
|
+
id: number;
|
|
22
|
+
/**
|
|
23
|
+
* The ID of the user object, if author was a user.
|
|
24
|
+
*/
|
|
25
|
+
author: number;
|
|
26
|
+
/**
|
|
27
|
+
* Email address for the comment author.
|
|
28
|
+
*/
|
|
29
|
+
author_email: ContextualField< string, 'edit', C >;
|
|
30
|
+
/**
|
|
31
|
+
* IP address for the comment author.
|
|
32
|
+
*/
|
|
33
|
+
author_ip: ContextualField< string, 'edit', C >;
|
|
34
|
+
/**
|
|
35
|
+
* Display name for the comment author.
|
|
36
|
+
*/
|
|
37
|
+
author_name: string;
|
|
38
|
+
/**
|
|
39
|
+
* URL for the comment author.
|
|
40
|
+
*/
|
|
41
|
+
author_url: string;
|
|
42
|
+
/**
|
|
43
|
+
* User agent for the comment author.
|
|
44
|
+
*/
|
|
45
|
+
author_user_agent: ContextualField< string, 'edit', C >;
|
|
46
|
+
/**
|
|
47
|
+
* The content for the comment.
|
|
48
|
+
*/
|
|
49
|
+
content: RenderedText< C >;
|
|
50
|
+
/**
|
|
51
|
+
* The date the comment was published, in the site's timezone.
|
|
52
|
+
*/
|
|
53
|
+
date: string;
|
|
54
|
+
/**
|
|
55
|
+
* The date the comment was published, as GMT.
|
|
56
|
+
*/
|
|
57
|
+
date_gmt: ContextualField< string, 'view' | 'edit', C >;
|
|
58
|
+
/**
|
|
59
|
+
* URL to the comment.
|
|
60
|
+
*/
|
|
61
|
+
link: string;
|
|
62
|
+
/**
|
|
63
|
+
* The ID for the parent of the comment.
|
|
64
|
+
*/
|
|
65
|
+
parent: number;
|
|
66
|
+
/**
|
|
67
|
+
* The ID of the associated post object.
|
|
68
|
+
*/
|
|
69
|
+
post: ContextualField< number, 'view' | 'edit', C >;
|
|
70
|
+
/**
|
|
71
|
+
* State of the comment.
|
|
72
|
+
*/
|
|
73
|
+
status: ContextualField< CommentStatus, 'view' | 'edit', C >;
|
|
74
|
+
/**
|
|
75
|
+
* Type of the comment.
|
|
76
|
+
*/
|
|
77
|
+
type: string;
|
|
78
|
+
/**
|
|
79
|
+
* Avatar URLs for the comment author.
|
|
80
|
+
*/
|
|
81
|
+
author_avatar_urls: AvatarUrls;
|
|
82
|
+
/**
|
|
83
|
+
* Meta fields.
|
|
84
|
+
*/
|
|
85
|
+
meta: ContextualField<
|
|
86
|
+
Record< string, string >,
|
|
87
|
+
'view' | 'edit',
|
|
88
|
+
C
|
|
89
|
+
>;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type Comment< C extends Context > = OmitNevers<
|
|
95
|
+
_BaseEntityTypes.Comment< C >
|
|
96
|
+
>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { EntityRecord } from './index';
|
|
5
|
+
|
|
6
|
+
export interface AvatarUrls {
|
|
7
|
+
/**
|
|
8
|
+
* Avatar URL with image size of 24 pixels.
|
|
9
|
+
*/
|
|
10
|
+
'24': string;
|
|
11
|
+
/**
|
|
12
|
+
* Avatar URL with image size of 48 pixels.
|
|
13
|
+
*/
|
|
14
|
+
'48': string;
|
|
15
|
+
/**
|
|
16
|
+
* Avatar URL with image size of 96 pixels.
|
|
17
|
+
*/
|
|
18
|
+
'96': string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type MediaType = 'image' | 'file';
|
|
22
|
+
export type CommentingStatus = 'open' | 'closed';
|
|
23
|
+
export type PingStatus = 'open' | 'closed';
|
|
24
|
+
export type PostStatus = 'publish' | 'future' | 'draft' | 'pending' | 'private';
|
|
25
|
+
export type PostFormat =
|
|
26
|
+
| 'standard'
|
|
27
|
+
| 'aside'
|
|
28
|
+
| 'chat'
|
|
29
|
+
| 'gallery'
|
|
30
|
+
| 'link'
|
|
31
|
+
| 'image'
|
|
32
|
+
| 'quote'
|
|
33
|
+
| 'status'
|
|
34
|
+
| 'video'
|
|
35
|
+
| 'audio';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The REST API context parameter.
|
|
39
|
+
*/
|
|
40
|
+
export type Context = 'view' | 'edit' | 'embed';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* ContextualField makes the field available only in the specified given contexts,
|
|
44
|
+
* and ensure the field is absent from the object when in a different context.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* interface Post< C extends Context > {
|
|
49
|
+
* …
|
|
50
|
+
* modified: ContextualField< string, 'edit' | 'view', C >;
|
|
51
|
+
* password: ContextualField< string, 'edit', C >;
|
|
52
|
+
* …
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* const post: Post<'edit'> = …
|
|
56
|
+
* // post.modified exists as a string
|
|
57
|
+
* // post.password exists as a string
|
|
58
|
+
*
|
|
59
|
+
* const post: Post<'view'> = …
|
|
60
|
+
* // post.modified still exists as a string
|
|
61
|
+
* // post.password is missing, undefined, because we're not in the `edit` context.
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export type ContextualField<
|
|
65
|
+
FieldType,
|
|
66
|
+
AvailableInContexts extends Context,
|
|
67
|
+
C extends Context
|
|
68
|
+
> = AvailableInContexts extends C ? FieldType : never;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Removes all the properties of type never, even the deeply nested ones.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* type MyType = {
|
|
76
|
+
* foo: string;
|
|
77
|
+
* bar: never;
|
|
78
|
+
* nested: {
|
|
79
|
+
* foo: string;
|
|
80
|
+
* bar: never;
|
|
81
|
+
* }
|
|
82
|
+
* }
|
|
83
|
+
* const x = {} as OmitNevers<MyType>;
|
|
84
|
+
* // x is of type { foo: string; nested: { foo: string; }}
|
|
85
|
+
* // The `never` properties were removed entirely
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export type OmitNevers<
|
|
89
|
+
T,
|
|
90
|
+
Nevers = {
|
|
91
|
+
[ K in keyof T ]: Exclude< T[ K ], undefined > extends never
|
|
92
|
+
? never
|
|
93
|
+
: T[ K ] extends Record< string, unknown >
|
|
94
|
+
? OmitNevers< T[ K ] >
|
|
95
|
+
: T[ K ];
|
|
96
|
+
}
|
|
97
|
+
> = Pick<
|
|
98
|
+
Nevers,
|
|
99
|
+
{
|
|
100
|
+
[ K in keyof Nevers ]: Nevers[ K ] extends never ? never : K;
|
|
101
|
+
}[ keyof Nevers ]
|
|
102
|
+
>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* A string that the server renders which often involves
|
|
106
|
+
* modifications from the raw source string.
|
|
107
|
+
*
|
|
108
|
+
* For example, block HTML with the comment delimiters exists
|
|
109
|
+
* in `post_content` but those comments are stripped out when
|
|
110
|
+
* rendering to a page view. Similarly, plugins might modify
|
|
111
|
+
* content or replace shortcodes.
|
|
112
|
+
*/
|
|
113
|
+
export interface RenderedText< C extends Context > {
|
|
114
|
+
/**
|
|
115
|
+
* The source string which will be rendered on page views.
|
|
116
|
+
*/
|
|
117
|
+
raw: ContextualField< string, 'edit', C >;
|
|
118
|
+
/**
|
|
119
|
+
* The output of the raw source after processing and filtering on the server.
|
|
120
|
+
*/
|
|
121
|
+
rendered: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Updatable<EntityRecord> is a type describing Edited Entity Records. They are like
|
|
126
|
+
* regular Entity Records, but they have all the local edits applied on top of the REST API data.
|
|
127
|
+
*
|
|
128
|
+
* This turns certain field from an object into a string.
|
|
129
|
+
*
|
|
130
|
+
* Entities like Post have fields that only be rendered on the server, like title, excerpt,
|
|
131
|
+
* and content. The REST API exposes both the raw markup and the rendered version of those fields.
|
|
132
|
+
* For example, in the block editor, content.rendered could used as a visual preview, and
|
|
133
|
+
* content.raw could be used to populate the code editor.
|
|
134
|
+
*
|
|
135
|
+
* When updating these rendered fields, Javascript is not be able to properly render arbitrary block
|
|
136
|
+
* markup. Therefore, it stores only the raw markup without the rendered part. And since that's a string,
|
|
137
|
+
* the entire field becomes a string.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* type Post< C extends Context > {
|
|
142
|
+
* title: RenderedText< C >;
|
|
143
|
+
* }
|
|
144
|
+
* const post = {} as Post;
|
|
145
|
+
* // post.title is an object with raw and rendered properties
|
|
146
|
+
*
|
|
147
|
+
* const updatablePost = {} as Updatable< Post >;
|
|
148
|
+
* // updatablePost.title is a string
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export type Updatable< T extends EntityRecord< 'edit' > > = {
|
|
152
|
+
[ K in keyof T ]: T[ K ] extends RenderedText< any > ? string : T[ K ];
|
|
153
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { Attachment } from './attachment';
|
|
5
|
+
import type { Comment } from './comment';
|
|
6
|
+
import type { MenuLocation } from './menu-location';
|
|
7
|
+
import type { NavMenu } from './nav-menu';
|
|
8
|
+
import type { NavMenuItem } from './nav-menu-item';
|
|
9
|
+
import type { NavigationArea } from './navigation-area';
|
|
10
|
+
import type { Page } from './page';
|
|
11
|
+
import type { Plugin } from './plugin';
|
|
12
|
+
import type { Post } from './post';
|
|
13
|
+
import type { Settings } from './settings';
|
|
14
|
+
import type { Sidebar } from './sidebar';
|
|
15
|
+
import type { Taxonomy } from './taxonomy';
|
|
16
|
+
import type { Theme } from './theme';
|
|
17
|
+
import type { User } from './user';
|
|
18
|
+
import type { Type } from './type';
|
|
19
|
+
import type { Widget } from './widget';
|
|
20
|
+
import type { WidgetType } from './widget-type';
|
|
21
|
+
import type { WpTemplate } from './wp-template';
|
|
22
|
+
import type { WpTemplatePart } from './wp-template-part';
|
|
23
|
+
import type { Context, Updatable } from './helpers';
|
|
24
|
+
|
|
25
|
+
export type { BaseEntityTypes } from './base-entity-types';
|
|
26
|
+
|
|
27
|
+
export type {
|
|
28
|
+
Context,
|
|
29
|
+
Updatable,
|
|
30
|
+
Attachment,
|
|
31
|
+
Comment,
|
|
32
|
+
MenuLocation,
|
|
33
|
+
NavMenu,
|
|
34
|
+
NavMenuItem,
|
|
35
|
+
NavigationArea,
|
|
36
|
+
Page,
|
|
37
|
+
Plugin,
|
|
38
|
+
Post,
|
|
39
|
+
Settings,
|
|
40
|
+
Sidebar,
|
|
41
|
+
Taxonomy,
|
|
42
|
+
Theme,
|
|
43
|
+
User,
|
|
44
|
+
Type,
|
|
45
|
+
Widget,
|
|
46
|
+
WidgetType,
|
|
47
|
+
WpTemplate,
|
|
48
|
+
WpTemplatePart,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type EntityRecord< C extends Context > =
|
|
52
|
+
| Attachment< C >
|
|
53
|
+
| Comment< C >
|
|
54
|
+
| MenuLocation< C >
|
|
55
|
+
| NavMenu< C >
|
|
56
|
+
| NavMenuItem< C >
|
|
57
|
+
| NavigationArea< C >
|
|
58
|
+
| Page< C >
|
|
59
|
+
| Plugin< C >
|
|
60
|
+
| Post< C >
|
|
61
|
+
| Settings< C >
|
|
62
|
+
| Sidebar< C >
|
|
63
|
+
| Taxonomy< C >
|
|
64
|
+
| Theme< C >
|
|
65
|
+
| Type< C >
|
|
66
|
+
| User< C >
|
|
67
|
+
| Widget< C >
|
|
68
|
+
| WidgetType< C >
|
|
69
|
+
| WpTemplate< C >
|
|
70
|
+
| WpTemplatePart< C >;
|
|
71
|
+
|
|
72
|
+
export type UpdatableEntityRecord = Updatable< EntityRecord< 'edit' > >;
|