@wordpress/core-data 4.0.1-next.253d9b6e21.0 → 4.0.3
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/README.md +11 -3
- package/build/actions.js +124 -117
- package/build/actions.js.map +1 -1
- package/build/batch/default-processor.js +58 -27
- package/build/batch/default-processor.js.map +1 -1
- package/build/entities.js +24 -18
- package/build/entities.js.map +1 -1
- package/build/index.js +9 -17
- package/build/index.js.map +1 -1
- package/build/locks/actions.js +17 -77
- package/build/locks/actions.js.map +1 -1
- package/build/locks/engine.js +77 -0
- package/build/locks/engine.js.map +1 -0
- package/build/locks/reducer.js +1 -5
- package/build/locks/reducer.js.map +1 -1
- package/build/locks/selectors.js +6 -6
- package/build/locks/selectors.js.map +1 -1
- package/build/queried-data/get-query-parts.js +9 -4
- package/build/queried-data/get-query-parts.js.map +1 -1
- package/build/queried-data/selectors.js +3 -9
- package/build/queried-data/selectors.js.map +1 -1
- package/build/reducer.js +1 -4
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +120 -91
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +31 -11
- package/build/selectors.js.map +1 -1
- package/build/utils/if-not-resolved.js +6 -21
- package/build/utils/if-not-resolved.js.map +1 -1
- package/build/utils/index.js +8 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/is-raw-attribute.js +19 -0
- package/build/utils/is-raw-attribute.js.map +1 -0
- package/build-module/actions.js +106 -107
- package/build-module/actions.js.map +1 -1
- package/build-module/batch/default-processor.js +57 -27
- package/build-module/batch/default-processor.js.map +1 -1
- package/build-module/entities.js +19 -14
- package/build-module/entities.js.map +1 -1
- package/build-module/index.js +10 -14
- package/build-module/index.js.map +1 -1
- package/build-module/locks/actions.js +14 -68
- package/build-module/locks/actions.js.map +1 -1
- package/build-module/locks/engine.js +66 -0
- package/build-module/locks/engine.js.map +1 -0
- package/build-module/locks/reducer.js +1 -2
- package/build-module/locks/reducer.js.map +1 -1
- package/build-module/locks/selectors.js +4 -4
- package/build-module/locks/selectors.js.map +1 -1
- package/build-module/queried-data/get-query-parts.js +9 -4
- package/build-module/queried-data/get-query-parts.js.map +1 -1
- package/build-module/queried-data/selectors.js +3 -9
- package/build-module/queried-data/selectors.js.map +1 -1
- package/build-module/reducer.js +1 -3
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +94 -74
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +30 -10
- package/build-module/selectors.js.map +1 -1
- package/build-module/utils/if-not-resolved.js +6 -19
- package/build-module/utils/if-not-resolved.js.map +1 -1
- package/build-module/utils/index.js +1 -0
- package/build-module/utils/index.js.map +1 -1
- package/build-module/utils/is-raw-attribute.js +12 -0
- package/build-module/utils/is-raw-attribute.js.map +1 -0
- package/package.json +11 -12
- package/src/actions.js +112 -189
- package/src/batch/default-processor.js +57 -26
- package/src/batch/test/default-processor.js +53 -26
- package/src/entities.js +15 -16
- package/src/index.js +7 -10
- package/src/locks/actions.js +10 -61
- package/src/locks/engine.js +43 -0
- package/src/locks/reducer.js +1 -3
- package/src/locks/selectors.js +4 -4
- package/src/locks/test/engine.js +135 -0
- package/src/locks/test/reducer.js +1 -1
- package/src/locks/test/selectors.js +105 -124
- package/src/queried-data/get-query-parts.js +11 -6
- package/src/queried-data/selectors.js +2 -9
- package/src/queried-data/test/get-query-parts.js +1 -1
- package/src/queried-data/test/selectors.js +1 -0
- package/src/reducer.js +0 -2
- package/src/resolvers.js +86 -106
- package/src/selectors.js +113 -40
- package/src/test/actions.js +243 -172
- package/src/test/entities.js +40 -26
- package/src/test/resolvers.js +270 -223
- package/src/test/selectors.js +71 -0
- package/src/utils/if-not-resolved.js +8 -26
- package/src/utils/index.js +1 -0
- package/src/utils/is-raw-attribute.js +11 -0
- package/src/utils/test/if-not-resolved.js +28 -27
- package/src/utils/test/is-raw-attribute.js +22 -0
- package/build/controls.js +0 -44
- package/build/controls.js.map +0 -1
- package/build/locks/index.js +0 -47
- package/build/locks/index.js.map +0 -1
- package/build-module/controls.js +0 -31
- package/build-module/controls.js.map +0 -1
- package/build-module/locks/index.js +0 -4
- package/build-module/locks/index.js.map +0 -1
- package/src/controls.js +0 -31
- package/src/locks/index.js +0 -3
- package/src/locks/test/actions.js +0 -307
- package/src/test/integration.js +0 -264
package/src/resolvers.js
CHANGED
|
@@ -7,33 +7,14 @@ import { find, includes, get, hasIn, compact, uniq } from 'lodash';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { addQueryArgs } from '@wordpress/url';
|
|
10
|
-
import
|
|
11
|
-
import { apiFetch } from '@wordpress/data-controls';
|
|
12
|
-
/**
|
|
13
|
-
* Internal dependencies
|
|
14
|
-
*/
|
|
15
|
-
import { regularFetch } from './controls';
|
|
16
|
-
import { STORE_NAME } from './name';
|
|
10
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
17
11
|
|
|
18
12
|
/**
|
|
19
13
|
* Internal dependencies
|
|
20
14
|
*/
|
|
21
|
-
import {
|
|
22
|
-
receiveUserQuery,
|
|
23
|
-
receiveCurrentTheme,
|
|
24
|
-
receiveCurrentUser,
|
|
25
|
-
receiveEntityRecords,
|
|
26
|
-
receiveThemeSupports,
|
|
27
|
-
receiveEmbedPreview,
|
|
28
|
-
receiveUserPermission,
|
|
29
|
-
receiveAutosaves,
|
|
30
|
-
} from './actions';
|
|
15
|
+
import { STORE_NAME } from './name';
|
|
31
16
|
import { getKindEntities, DEFAULT_ENTITY_KEY } from './entities';
|
|
32
17
|
import { ifNotResolved, getNormalizedCommaSeparable } from './utils';
|
|
33
|
-
import {
|
|
34
|
-
__unstableAcquireStoreLock,
|
|
35
|
-
__unstableReleaseStoreLock,
|
|
36
|
-
} from './locks';
|
|
37
18
|
|
|
38
19
|
/**
|
|
39
20
|
* Requests authors from the REST API.
|
|
@@ -41,22 +22,22 @@ import {
|
|
|
41
22
|
* @param {Object|undefined} query Optional object of query parameters to
|
|
42
23
|
* include with request.
|
|
43
24
|
*/
|
|
44
|
-
export
|
|
25
|
+
export const getAuthors = ( query ) => async ( { dispatch } ) => {
|
|
45
26
|
const path = addQueryArgs(
|
|
46
27
|
'/wp/v2/users/?who=authors&per_page=100',
|
|
47
28
|
query
|
|
48
29
|
);
|
|
49
|
-
const users =
|
|
50
|
-
|
|
51
|
-
}
|
|
30
|
+
const users = await apiFetch( { path } );
|
|
31
|
+
dispatch.receiveUserQuery( path, users );
|
|
32
|
+
};
|
|
52
33
|
|
|
53
34
|
/**
|
|
54
35
|
* Requests the current user from the REST API.
|
|
55
36
|
*/
|
|
56
|
-
export
|
|
57
|
-
const currentUser =
|
|
58
|
-
|
|
59
|
-
}
|
|
37
|
+
export const getCurrentUser = () => async ( { dispatch } ) => {
|
|
38
|
+
const currentUser = await apiFetch( { path: '/wp/v2/users/me' } );
|
|
39
|
+
dispatch.receiveCurrentUser( currentUser );
|
|
40
|
+
};
|
|
60
41
|
|
|
61
42
|
/**
|
|
62
43
|
* Requests an entity's record from the REST API.
|
|
@@ -67,18 +48,22 @@ export function* getCurrentUser() {
|
|
|
67
48
|
* @param {Object|undefined} query Optional object of query parameters to
|
|
68
49
|
* include with request.
|
|
69
50
|
*/
|
|
70
|
-
export
|
|
71
|
-
|
|
51
|
+
export const getEntityRecord = ( kind, name, key = '', query ) => async ( {
|
|
52
|
+
select,
|
|
53
|
+
dispatch,
|
|
54
|
+
} ) => {
|
|
55
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
72
56
|
const entity = find( entities, { kind, name } );
|
|
73
|
-
if ( ! entity ) {
|
|
57
|
+
if ( ! entity || entity?.__experimentalNoFetch ) {
|
|
74
58
|
return;
|
|
75
59
|
}
|
|
76
60
|
|
|
77
|
-
const lock =
|
|
61
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
78
62
|
STORE_NAME,
|
|
79
63
|
[ 'entities', 'data', kind, name, key ],
|
|
80
64
|
{ exclusive: false }
|
|
81
65
|
);
|
|
66
|
+
|
|
82
67
|
try {
|
|
83
68
|
if ( query !== undefined && query._fields ) {
|
|
84
69
|
// If requesting specific fields, items and query association to said
|
|
@@ -111,27 +96,21 @@ export function* getEntityRecord( kind, name, key = '', query ) {
|
|
|
111
96
|
// The resolution cache won't consider query as reusable based on the
|
|
112
97
|
// fields, so it's tested here, prior to initiating the REST request,
|
|
113
98
|
// and without causing `getEntityRecords` resolution to occur.
|
|
114
|
-
const hasRecords =
|
|
115
|
-
STORE_NAME,
|
|
116
|
-
'hasEntityRecords',
|
|
117
|
-
kind,
|
|
118
|
-
name,
|
|
119
|
-
query
|
|
120
|
-
);
|
|
99
|
+
const hasRecords = select.hasEntityRecords( kind, name, query );
|
|
121
100
|
if ( hasRecords ) {
|
|
122
101
|
return;
|
|
123
102
|
}
|
|
124
103
|
}
|
|
125
104
|
|
|
126
|
-
const record =
|
|
127
|
-
|
|
105
|
+
const record = await apiFetch( { path } );
|
|
106
|
+
dispatch.receiveEntityRecords( kind, name, record, query );
|
|
128
107
|
} catch ( error ) {
|
|
129
108
|
// We need a way to handle and access REST API errors in state
|
|
130
109
|
// Until then, catching the error ensures the resolver is marked as resolved.
|
|
131
110
|
} finally {
|
|
132
|
-
|
|
111
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
133
112
|
}
|
|
134
|
-
}
|
|
113
|
+
};
|
|
135
114
|
|
|
136
115
|
/**
|
|
137
116
|
* Requests an entity's record from the REST API.
|
|
@@ -156,18 +135,21 @@ export const getEditedEntityRecord = ifNotResolved(
|
|
|
156
135
|
* @param {string} name Entity name.
|
|
157
136
|
* @param {Object?} query Query Object.
|
|
158
137
|
*/
|
|
159
|
-
export
|
|
160
|
-
|
|
138
|
+
export const getEntityRecords = ( kind, name, query = {} ) => async ( {
|
|
139
|
+
dispatch,
|
|
140
|
+
} ) => {
|
|
141
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
161
142
|
const entity = find( entities, { kind, name } );
|
|
162
|
-
if ( ! entity ) {
|
|
143
|
+
if ( ! entity || entity?.__experimentalNoFetch ) {
|
|
163
144
|
return;
|
|
164
145
|
}
|
|
165
146
|
|
|
166
|
-
const lock =
|
|
147
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
167
148
|
STORE_NAME,
|
|
168
149
|
[ 'entities', 'data', kind, name ],
|
|
169
150
|
{ exclusive: false }
|
|
170
151
|
);
|
|
152
|
+
|
|
171
153
|
try {
|
|
172
154
|
if ( query._fields ) {
|
|
173
155
|
// If requesting specific fields, items and query association to said
|
|
@@ -187,7 +169,7 @@ export function* getEntityRecords( kind, name, query = {} ) {
|
|
|
187
169
|
...query,
|
|
188
170
|
} );
|
|
189
171
|
|
|
190
|
-
let records = Object.values(
|
|
172
|
+
let records = Object.values( await apiFetch( { path } ) );
|
|
191
173
|
// If we request fields but the result doesn't contain the fields,
|
|
192
174
|
// explicitely set these fields as "undefined"
|
|
193
175
|
// that way we consider the query "fullfilled".
|
|
@@ -203,7 +185,8 @@ export function* getEntityRecords( kind, name, query = {} ) {
|
|
|
203
185
|
} );
|
|
204
186
|
}
|
|
205
187
|
|
|
206
|
-
|
|
188
|
+
dispatch.receiveEntityRecords( kind, name, records, query );
|
|
189
|
+
|
|
207
190
|
// When requesting all fields, the list of results can be used to
|
|
208
191
|
// resolve the `getEntityRecord` selector in addition to `getEntityRecords`.
|
|
209
192
|
// See https://github.com/WordPress/gutenberg/pull/26575
|
|
@@ -213,21 +196,21 @@ export function* getEntityRecords( kind, name, query = {} ) {
|
|
|
213
196
|
.filter( ( record ) => record[ key ] )
|
|
214
197
|
.map( ( record ) => [ kind, name, record[ key ] ] );
|
|
215
198
|
|
|
216
|
-
|
|
199
|
+
dispatch( {
|
|
217
200
|
type: 'START_RESOLUTIONS',
|
|
218
201
|
selectorName: 'getEntityRecord',
|
|
219
202
|
args: resolutionsArgs,
|
|
220
|
-
};
|
|
221
|
-
|
|
203
|
+
} );
|
|
204
|
+
dispatch( {
|
|
222
205
|
type: 'FINISH_RESOLUTIONS',
|
|
223
206
|
selectorName: 'getEntityRecord',
|
|
224
207
|
args: resolutionsArgs,
|
|
225
|
-
};
|
|
208
|
+
} );
|
|
226
209
|
}
|
|
227
210
|
} finally {
|
|
228
|
-
|
|
211
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
229
212
|
}
|
|
230
|
-
}
|
|
213
|
+
};
|
|
231
214
|
|
|
232
215
|
getEntityRecords.shouldInvalidate = ( action, kind, name ) => {
|
|
233
216
|
return (
|
|
@@ -241,39 +224,39 @@ getEntityRecords.shouldInvalidate = ( action, kind, name ) => {
|
|
|
241
224
|
/**
|
|
242
225
|
* Requests the current theme.
|
|
243
226
|
*/
|
|
244
|
-
export
|
|
245
|
-
const activeThemes =
|
|
227
|
+
export const getCurrentTheme = () => async ( { dispatch } ) => {
|
|
228
|
+
const activeThemes = await apiFetch( {
|
|
246
229
|
path: '/wp/v2/themes?status=active',
|
|
247
230
|
} );
|
|
248
|
-
|
|
249
|
-
}
|
|
231
|
+
dispatch.receiveCurrentTheme( activeThemes[ 0 ] );
|
|
232
|
+
};
|
|
250
233
|
|
|
251
234
|
/**
|
|
252
235
|
* Requests theme supports data from the index.
|
|
253
236
|
*/
|
|
254
|
-
export
|
|
255
|
-
const activeThemes =
|
|
237
|
+
export const getThemeSupports = () => async ( { dispatch } ) => {
|
|
238
|
+
const activeThemes = await apiFetch( {
|
|
256
239
|
path: '/wp/v2/themes?status=active',
|
|
257
240
|
} );
|
|
258
|
-
|
|
259
|
-
}
|
|
241
|
+
dispatch.receiveThemeSupports( activeThemes[ 0 ].theme_supports );
|
|
242
|
+
};
|
|
260
243
|
|
|
261
244
|
/**
|
|
262
245
|
* Requests a preview from the from the Embed API.
|
|
263
246
|
*
|
|
264
247
|
* @param {string} url URL to get the preview for.
|
|
265
248
|
*/
|
|
266
|
-
export
|
|
249
|
+
export const getEmbedPreview = ( url ) => async ( { dispatch } ) => {
|
|
267
250
|
try {
|
|
268
|
-
const embedProxyResponse =
|
|
251
|
+
const embedProxyResponse = await apiFetch( {
|
|
269
252
|
path: addQueryArgs( '/oembed/1.0/proxy', { url } ),
|
|
270
253
|
} );
|
|
271
|
-
|
|
254
|
+
dispatch.receiveEmbedPreview( url, embedProxyResponse );
|
|
272
255
|
} catch ( error ) {
|
|
273
256
|
// Embed API 404s if the URL cannot be embedded, so we have to catch the error from the apiRequest here.
|
|
274
|
-
|
|
257
|
+
dispatch.receiveEmbedPreview( url, false );
|
|
275
258
|
}
|
|
276
|
-
}
|
|
259
|
+
};
|
|
277
260
|
|
|
278
261
|
/**
|
|
279
262
|
* Checks whether the current user can perform the given action on the given
|
|
@@ -284,7 +267,7 @@ export function* getEmbedPreview( url ) {
|
|
|
284
267
|
* @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
|
|
285
268
|
* @param {?string} id ID of the rest resource to check.
|
|
286
269
|
*/
|
|
287
|
-
export
|
|
270
|
+
export const canUser = ( action, resource, id ) => async ( { dispatch } ) => {
|
|
288
271
|
const methods = {
|
|
289
272
|
create: 'POST',
|
|
290
273
|
read: 'GET',
|
|
@@ -301,7 +284,7 @@ export function* canUser( action, resource, id ) {
|
|
|
301
284
|
|
|
302
285
|
let response;
|
|
303
286
|
try {
|
|
304
|
-
response =
|
|
287
|
+
response = await apiFetch( {
|
|
305
288
|
path,
|
|
306
289
|
// Ideally this would always be an OPTIONS request, but unfortunately there's
|
|
307
290
|
// a bug in the REST API which causes the Allow header to not be sent on
|
|
@@ -329,8 +312,8 @@ export function* canUser( action, resource, id ) {
|
|
|
329
312
|
|
|
330
313
|
const key = compact( [ action, resource, id ] ).join( '/' );
|
|
331
314
|
const isAllowed = includes( allowHeader, method );
|
|
332
|
-
|
|
333
|
-
}
|
|
315
|
+
dispatch.receiveUserPermission( key, isAllowed );
|
|
316
|
+
};
|
|
334
317
|
|
|
335
318
|
/**
|
|
336
319
|
* Checks whether the current user can perform the given action on the given
|
|
@@ -340,16 +323,18 @@ export function* canUser( action, resource, id ) {
|
|
|
340
323
|
* @param {string} name Entity name.
|
|
341
324
|
* @param {string} recordId Record's id.
|
|
342
325
|
*/
|
|
343
|
-
export
|
|
344
|
-
|
|
326
|
+
export const canUserEditEntityRecord = ( kind, name, recordId ) => async ( {
|
|
327
|
+
dispatch,
|
|
328
|
+
} ) => {
|
|
329
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
345
330
|
const entity = find( entities, { kind, name } );
|
|
346
331
|
if ( ! entity ) {
|
|
347
332
|
return;
|
|
348
333
|
}
|
|
349
334
|
|
|
350
335
|
const resource = entity.__unstable_rest_base;
|
|
351
|
-
|
|
352
|
-
}
|
|
336
|
+
await dispatch( canUser( 'update', resource, recordId ) );
|
|
337
|
+
};
|
|
353
338
|
|
|
354
339
|
/**
|
|
355
340
|
* Request autosave data from the REST API.
|
|
@@ -357,20 +342,19 @@ export function* canUserEditEntityRecord( kind, name, recordId ) {
|
|
|
357
342
|
* @param {string} postType The type of the parent post.
|
|
358
343
|
* @param {number} postId The id of the parent post.
|
|
359
344
|
*/
|
|
360
|
-
export
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const autosaves = yield apiFetch( {
|
|
345
|
+
export const getAutosaves = ( postType, postId ) => async ( {
|
|
346
|
+
dispatch,
|
|
347
|
+
resolveSelect,
|
|
348
|
+
} ) => {
|
|
349
|
+
const { rest_base: restBase } = await resolveSelect.getPostType( postType );
|
|
350
|
+
const autosaves = await apiFetch( {
|
|
367
351
|
path: `/wp/v2/${ restBase }/${ postId }/autosaves?context=edit`,
|
|
368
352
|
} );
|
|
369
353
|
|
|
370
354
|
if ( autosaves && autosaves.length ) {
|
|
371
|
-
|
|
355
|
+
dispatch.receiveAutosaves( postId, autosaves );
|
|
372
356
|
}
|
|
373
|
-
}
|
|
357
|
+
};
|
|
374
358
|
|
|
375
359
|
/**
|
|
376
360
|
* Request autosave data from the REST API.
|
|
@@ -381,31 +365,30 @@ export function* getAutosaves( postType, postId ) {
|
|
|
381
365
|
* @param {string} postType The type of the parent post.
|
|
382
366
|
* @param {number} postId The id of the parent post.
|
|
383
367
|
*/
|
|
384
|
-
export
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
postId
|
|
390
|
-
);
|
|
391
|
-
}
|
|
368
|
+
export const getAutosave = ( postType, postId ) => async ( {
|
|
369
|
+
resolveSelect,
|
|
370
|
+
} ) => {
|
|
371
|
+
await resolveSelect.getAutosaves( postType, postId );
|
|
372
|
+
};
|
|
392
373
|
|
|
393
374
|
/**
|
|
394
375
|
* Retrieve the frontend template used for a given link.
|
|
395
376
|
*
|
|
396
377
|
* @param {string} link Link.
|
|
397
378
|
*/
|
|
398
|
-
export
|
|
379
|
+
export const __experimentalGetTemplateForLink = ( link ) => async ( {
|
|
380
|
+
dispatch,
|
|
381
|
+
resolveSelect,
|
|
382
|
+
} ) => {
|
|
399
383
|
// Ideally this should be using an apiFetch call
|
|
400
384
|
// We could potentially do so by adding a "filter" to the `wp_template` end point.
|
|
401
385
|
// Also it seems the returned object is not a regular REST API post type.
|
|
402
386
|
let template;
|
|
403
387
|
try {
|
|
404
|
-
template =
|
|
405
|
-
addQueryArgs( link, {
|
|
406
|
-
|
|
407
|
-
} )
|
|
408
|
-
);
|
|
388
|
+
template = await window
|
|
389
|
+
.fetch( addQueryArgs( link, { '_wp-find-template': true } ) )
|
|
390
|
+
.then( ( res ) => res.json() )
|
|
391
|
+
.then( ( { data } ) => data );
|
|
409
392
|
} catch ( e ) {
|
|
410
393
|
// For non-FSE themes, it is possible that this request returns an error.
|
|
411
394
|
}
|
|
@@ -414,21 +397,18 @@ export function* __experimentalGetTemplateForLink( link ) {
|
|
|
414
397
|
return;
|
|
415
398
|
}
|
|
416
399
|
|
|
417
|
-
|
|
418
|
-
const record = yield controls.select(
|
|
419
|
-
STORE_NAME,
|
|
420
|
-
'getEntityRecord',
|
|
400
|
+
const record = await resolveSelect.getEntityRecord(
|
|
421
401
|
'postType',
|
|
422
402
|
'wp_template',
|
|
423
403
|
template.id
|
|
424
404
|
);
|
|
425
405
|
|
|
426
406
|
if ( record ) {
|
|
427
|
-
|
|
407
|
+
dispatch.receiveEntityRecords( 'postType', 'wp_template', [ record ], {
|
|
428
408
|
'find-template': link,
|
|
429
409
|
} );
|
|
430
410
|
}
|
|
431
|
-
}
|
|
411
|
+
};
|
|
432
412
|
|
|
433
413
|
__experimentalGetTemplateForLink.shouldInvalidate = ( action ) => {
|
|
434
414
|
return (
|
package/src/selectors.js
CHANGED
|
@@ -17,7 +17,7 @@ import deprecated from '@wordpress/deprecated';
|
|
|
17
17
|
import { STORE_NAME } from './name';
|
|
18
18
|
import { getQueriedItems } from './queried-data';
|
|
19
19
|
import { DEFAULT_ENTITY_KEY } from './entities';
|
|
20
|
-
import { getNormalizedCommaSeparable } from './utils';
|
|
20
|
+
import { getNormalizedCommaSeparable, isRawAttribute } from './utils';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Shared reference to an empty array for cases where it is important to avoid
|
|
@@ -134,40 +134,63 @@ export function getEntity( state, kind, name ) {
|
|
|
134
134
|
*
|
|
135
135
|
* @return {Object?} Record.
|
|
136
136
|
*/
|
|
137
|
-
export
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
const context = query?.context ?? 'default';
|
|
147
|
-
|
|
148
|
-
if ( query === undefined ) {
|
|
149
|
-
// If expecting a complete item, validate that completeness.
|
|
150
|
-
if ( ! queriedState.itemIsComplete[ context ]?.[ key ] ) {
|
|
137
|
+
export const getEntityRecord = createSelector(
|
|
138
|
+
( state, kind, name, key, query ) => {
|
|
139
|
+
const queriedState = get( state.entities.data, [
|
|
140
|
+
kind,
|
|
141
|
+
name,
|
|
142
|
+
'queriedData',
|
|
143
|
+
] );
|
|
144
|
+
if ( ! queriedState ) {
|
|
151
145
|
return undefined;
|
|
152
146
|
}
|
|
147
|
+
const context = query?.context ?? 'default';
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
if ( query === undefined ) {
|
|
150
|
+
// If expecting a complete item, validate that completeness.
|
|
151
|
+
if ( ! queriedState.itemIsComplete[ context ]?.[ key ] ) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
156
154
|
|
|
157
|
-
|
|
158
|
-
if ( item && query._fields ) {
|
|
159
|
-
const filteredItem = {};
|
|
160
|
-
const fields = getNormalizedCommaSeparable( query._fields );
|
|
161
|
-
for ( let f = 0; f < fields.length; f++ ) {
|
|
162
|
-
const field = fields[ f ].split( '.' );
|
|
163
|
-
const value = get( item, field );
|
|
164
|
-
set( filteredItem, field, value );
|
|
155
|
+
return queriedState.items[ context ][ key ];
|
|
165
156
|
}
|
|
166
|
-
return filteredItem;
|
|
167
|
-
}
|
|
168
157
|
|
|
169
|
-
|
|
170
|
-
|
|
158
|
+
const item = queriedState.items[ context ]?.[ key ];
|
|
159
|
+
if ( item && query._fields ) {
|
|
160
|
+
const filteredItem = {};
|
|
161
|
+
const fields = getNormalizedCommaSeparable( query._fields );
|
|
162
|
+
for ( let f = 0; f < fields.length; f++ ) {
|
|
163
|
+
const field = fields[ f ].split( '.' );
|
|
164
|
+
const value = get( item, field );
|
|
165
|
+
set( filteredItem, field, value );
|
|
166
|
+
}
|
|
167
|
+
return filteredItem;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return item;
|
|
171
|
+
},
|
|
172
|
+
( state, kind, name, recordId, query ) => {
|
|
173
|
+
const context = query?.context ?? 'default';
|
|
174
|
+
return [
|
|
175
|
+
get( state.entities.data, [
|
|
176
|
+
kind,
|
|
177
|
+
name,
|
|
178
|
+
'queriedData',
|
|
179
|
+
'items',
|
|
180
|
+
context,
|
|
181
|
+
recordId,
|
|
182
|
+
] ),
|
|
183
|
+
get( state.entities.data, [
|
|
184
|
+
kind,
|
|
185
|
+
name,
|
|
186
|
+
'queriedData',
|
|
187
|
+
'itemIsComplete',
|
|
188
|
+
context,
|
|
189
|
+
recordId,
|
|
190
|
+
] ),
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
);
|
|
171
194
|
|
|
172
195
|
/**
|
|
173
196
|
* Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity from the API if the entity record isn't available in the local state.
|
|
@@ -205,19 +228,44 @@ export const getRawEntityRecord = createSelector(
|
|
|
205
228
|
return (
|
|
206
229
|
record &&
|
|
207
230
|
Object.keys( record ).reduce( ( accumulator, _key ) => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
231
|
+
if ( isRawAttribute( getEntity( state, kind, name ), _key ) ) {
|
|
232
|
+
// Because edits are the "raw" attribute values,
|
|
233
|
+
// we return those from record selectors to make rendering,
|
|
234
|
+
// comparisons, and joins with edits easier.
|
|
235
|
+
accumulator[ _key ] = get(
|
|
236
|
+
record[ _key ],
|
|
237
|
+
'raw',
|
|
238
|
+
record[ _key ]
|
|
239
|
+
);
|
|
240
|
+
} else {
|
|
241
|
+
accumulator[ _key ] = record[ _key ];
|
|
242
|
+
}
|
|
216
243
|
return accumulator;
|
|
217
244
|
}, {} )
|
|
218
245
|
);
|
|
219
246
|
},
|
|
220
|
-
( state ) =>
|
|
247
|
+
( state, kind, name, recordId, query ) => {
|
|
248
|
+
const context = query?.context ?? 'default';
|
|
249
|
+
return [
|
|
250
|
+
state.entities.config,
|
|
251
|
+
get( state.entities.data, [
|
|
252
|
+
kind,
|
|
253
|
+
name,
|
|
254
|
+
'queriedData',
|
|
255
|
+
'items',
|
|
256
|
+
context,
|
|
257
|
+
recordId,
|
|
258
|
+
] ),
|
|
259
|
+
get( state.entities.data, [
|
|
260
|
+
kind,
|
|
261
|
+
name,
|
|
262
|
+
'queriedData',
|
|
263
|
+
'itemIsComplete',
|
|
264
|
+
context,
|
|
265
|
+
recordId,
|
|
266
|
+
] ),
|
|
267
|
+
];
|
|
268
|
+
}
|
|
221
269
|
);
|
|
222
270
|
|
|
223
271
|
/**
|
|
@@ -404,7 +452,10 @@ export const getEntityRecordNonTransientEdits = createSelector(
|
|
|
404
452
|
return acc;
|
|
405
453
|
}, {} );
|
|
406
454
|
},
|
|
407
|
-
( state ) => [
|
|
455
|
+
( state, kind, name, recordId ) => [
|
|
456
|
+
state.entities.config,
|
|
457
|
+
get( state.entities.data, [ kind, name, 'edits', recordId ] ),
|
|
458
|
+
]
|
|
408
459
|
);
|
|
409
460
|
|
|
410
461
|
/**
|
|
@@ -442,7 +493,29 @@ export const getEditedEntityRecord = createSelector(
|
|
|
442
493
|
...getRawEntityRecord( state, kind, name, recordId ),
|
|
443
494
|
...getEntityRecordEdits( state, kind, name, recordId ),
|
|
444
495
|
} ),
|
|
445
|
-
( state ) =>
|
|
496
|
+
( state, kind, name, recordId, query ) => {
|
|
497
|
+
const context = query?.context ?? 'default';
|
|
498
|
+
return [
|
|
499
|
+
state.entities.config,
|
|
500
|
+
get( state.entities.data, [
|
|
501
|
+
kind,
|
|
502
|
+
name,
|
|
503
|
+
'queriedData',
|
|
504
|
+
'items',
|
|
505
|
+
context,
|
|
506
|
+
recordId,
|
|
507
|
+
] ),
|
|
508
|
+
get( state.entities.data, [
|
|
509
|
+
kind,
|
|
510
|
+
name,
|
|
511
|
+
'queriedData',
|
|
512
|
+
'itemIsComplete',
|
|
513
|
+
context,
|
|
514
|
+
recordId,
|
|
515
|
+
] ),
|
|
516
|
+
get( state.entities.data, [ kind, name, 'edits', recordId ] ),
|
|
517
|
+
];
|
|
518
|
+
}
|
|
446
519
|
);
|
|
447
520
|
|
|
448
521
|
/**
|