@wordpress/core-data 7.6.0 → 7.7.1-next.5368f64a9.0
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 +2 -0
- package/README.md +2 -2
- package/build/actions.js +39 -16
- package/build/actions.js.map +1 -1
- package/build/footnotes/index.js +5 -1
- package/build/footnotes/index.js.map +1 -1
- package/build/hooks/use-entity-prop.js +4 -4
- package/build/hooks/use-entity-prop.js.map +1 -1
- package/build/reducer.js +5 -0
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +77 -36
- package/build/resolvers.js.map +1 -1
- package/build/utils/index.js +2 -2
- package/build/utils/index.js.map +1 -1
- package/build/utils/user-permissions.js +5 -7
- package/build/utils/user-permissions.js.map +1 -1
- package/build-module/actions.js +38 -16
- package/build-module/actions.js.map +1 -1
- package/build-module/footnotes/index.js +5 -1
- package/build-module/footnotes/index.js.map +1 -1
- package/build-module/hooks/use-entity-prop.js +4 -4
- package/build-module/hooks/use-entity-prop.js.map +1 -1
- package/build-module/reducer.js +5 -0
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +78 -37
- package/build-module/resolvers.js.map +1 -1
- package/build-module/utils/index.js +1 -1
- package/build-module/utils/index.js.map +1 -1
- package/build-module/utils/user-permissions.js +4 -6
- package/build-module/utils/user-permissions.js.map +1 -1
- package/build-types/actions.d.ts +20 -2
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/footnotes/index.d.ts.map +1 -1
- package/build-types/hooks/use-entity-prop.d.ts +5 -5
- package/build-types/hooks/use-entity-prop.d.ts.map +1 -1
- package/build-types/index.d.ts +5 -2
- package/build-types/index.d.ts.map +1 -1
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts +5 -3
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/utils/index.d.ts +1 -1
- package/build-types/utils/user-permissions.d.ts +1 -1
- package/build-types/utils/user-permissions.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/actions.js +38 -16
- package/src/footnotes/index.js +9 -4
- package/src/hooks/test/use-entity-records.js +2 -2
- package/src/hooks/use-entity-prop.js +4 -4
- package/src/reducer.js +5 -0
- package/src/resolvers.js +117 -54
- package/src/test/resolvers.js +5 -12
- package/src/utils/index.js +1 -1
- package/src/utils/user-permissions.js +4 -6
- package/tsconfig.tsbuildinfo +1 -1
package/src/resolvers.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
forwardResolver,
|
|
20
20
|
getNormalizedCommaSeparable,
|
|
21
21
|
getUserPermissionCacheKey,
|
|
22
|
-
|
|
22
|
+
getUserPermissionsFromAllowHeader,
|
|
23
23
|
ALLOWED_RESOURCE_ACTIONS,
|
|
24
24
|
} from './utils';
|
|
25
25
|
import { getSyncProvider } from './sync';
|
|
@@ -155,7 +155,7 @@ export const getEntityRecord =
|
|
|
155
155
|
}
|
|
156
156
|
);
|
|
157
157
|
|
|
158
|
-
if ( query !== undefined ) {
|
|
158
|
+
if ( query !== undefined && query._fields ) {
|
|
159
159
|
query = { ...query, include: [ key ] };
|
|
160
160
|
|
|
161
161
|
// The resolution cache won't consider query as reusable based on the
|
|
@@ -173,26 +173,36 @@ export const getEntityRecord =
|
|
|
173
173
|
|
|
174
174
|
const response = await apiFetch( { path, parse: false } );
|
|
175
175
|
const record = await response.json();
|
|
176
|
-
const permissions =
|
|
176
|
+
const permissions = getUserPermissionsFromAllowHeader(
|
|
177
|
+
response.headers?.get( 'allow' )
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const canUserResolutionsArgs = [];
|
|
181
|
+
const receiveUserPermissionArgs = {};
|
|
182
|
+
for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
|
|
183
|
+
receiveUserPermissionArgs[
|
|
184
|
+
getUserPermissionCacheKey( action, {
|
|
185
|
+
kind,
|
|
186
|
+
name,
|
|
187
|
+
id: key,
|
|
188
|
+
} )
|
|
189
|
+
] = permissions[ action ];
|
|
190
|
+
|
|
191
|
+
canUserResolutionsArgs.push( [
|
|
192
|
+
action,
|
|
193
|
+
{ kind, name, id: key },
|
|
194
|
+
] );
|
|
195
|
+
}
|
|
177
196
|
|
|
178
197
|
registry.batch( () => {
|
|
179
198
|
dispatch.receiveEntityRecords( kind, name, record, query );
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
dispatch.receiveUserPermission(
|
|
188
|
-
permissionKey,
|
|
189
|
-
permissions[ action ]
|
|
190
|
-
);
|
|
191
|
-
dispatch.finishResolution( 'canUser', [
|
|
192
|
-
action,
|
|
193
|
-
{ kind, name, id: key },
|
|
194
|
-
] );
|
|
195
|
-
}
|
|
199
|
+
dispatch.receiveUserPermissions(
|
|
200
|
+
receiveUserPermissionArgs
|
|
201
|
+
);
|
|
202
|
+
dispatch.finishResolutions(
|
|
203
|
+
'canUser',
|
|
204
|
+
canUserResolutionsArgs
|
|
205
|
+
);
|
|
196
206
|
} );
|
|
197
207
|
}
|
|
198
208
|
} finally {
|
|
@@ -271,6 +281,10 @@ export const getEntityRecords =
|
|
|
271
281
|
};
|
|
272
282
|
} else {
|
|
273
283
|
records = Object.values( await apiFetch( { path } ) );
|
|
284
|
+
meta = {
|
|
285
|
+
totalItems: records.length,
|
|
286
|
+
totalPages: 1,
|
|
287
|
+
};
|
|
274
288
|
}
|
|
275
289
|
|
|
276
290
|
// If we request fields but the result doesn't contain the fields,
|
|
@@ -299,19 +313,55 @@ export const getEntityRecords =
|
|
|
299
313
|
meta
|
|
300
314
|
);
|
|
301
315
|
|
|
302
|
-
// When requesting all fields, the list of results can be used to
|
|
303
|
-
//
|
|
316
|
+
// When requesting all fields, the list of results can be used to resolve
|
|
317
|
+
// the `getEntityRecord` and `canUser` selectors in addition to `getEntityRecords`.
|
|
304
318
|
// See https://github.com/WordPress/gutenberg/pull/26575
|
|
319
|
+
// See https://github.com/WordPress/gutenberg/pull/64504
|
|
305
320
|
if ( ! query?._fields && ! query.context ) {
|
|
306
321
|
const key = entityConfig.key || DEFAULT_ENTITY_KEY;
|
|
307
322
|
const resolutionsArgs = records
|
|
308
323
|
.filter( ( record ) => record?.[ key ] )
|
|
309
324
|
.map( ( record ) => [ kind, name, record[ key ] ] );
|
|
310
325
|
|
|
326
|
+
const targetHints = records
|
|
327
|
+
.filter( ( record ) => record?.[ key ] )
|
|
328
|
+
.map( ( record ) => ( {
|
|
329
|
+
id: record[ key ],
|
|
330
|
+
permissions: getUserPermissionsFromAllowHeader(
|
|
331
|
+
record?._links?.self?.[ 0 ].targetHints.allow
|
|
332
|
+
),
|
|
333
|
+
} ) );
|
|
334
|
+
|
|
335
|
+
const canUserResolutionsArgs = [];
|
|
336
|
+
const receiveUserPermissionArgs = {};
|
|
337
|
+
for ( const targetHint of targetHints ) {
|
|
338
|
+
for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
|
|
339
|
+
canUserResolutionsArgs.push( [
|
|
340
|
+
action,
|
|
341
|
+
{ kind, name, id: targetHint.id },
|
|
342
|
+
] );
|
|
343
|
+
|
|
344
|
+
receiveUserPermissionArgs[
|
|
345
|
+
getUserPermissionCacheKey( action, {
|
|
346
|
+
kind,
|
|
347
|
+
name,
|
|
348
|
+
id: targetHint.id,
|
|
349
|
+
} )
|
|
350
|
+
] = targetHint.permissions[ action ];
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
dispatch.receiveUserPermissions(
|
|
355
|
+
receiveUserPermissionArgs
|
|
356
|
+
);
|
|
311
357
|
dispatch.finishResolutions(
|
|
312
358
|
'getEntityRecord',
|
|
313
359
|
resolutionsArgs
|
|
314
360
|
);
|
|
361
|
+
dispatch.finishResolutions(
|
|
362
|
+
'canUser',
|
|
363
|
+
canUserResolutionsArgs
|
|
364
|
+
);
|
|
315
365
|
}
|
|
316
366
|
|
|
317
367
|
dispatch.__unstableReleaseStoreLock( lock );
|
|
@@ -440,7 +490,12 @@ export const canUser =
|
|
|
440
490
|
return;
|
|
441
491
|
}
|
|
442
492
|
|
|
443
|
-
|
|
493
|
+
// Optional chaining operator is used here because the API requests don't
|
|
494
|
+
// return the expected result in the React native version. Instead, API requests
|
|
495
|
+
// only return the result, without including response properties like the headers.
|
|
496
|
+
const permissions = getUserPermissionsFromAllowHeader(
|
|
497
|
+
response.headers?.get( 'allow' )
|
|
498
|
+
);
|
|
444
499
|
registry.batch( () => {
|
|
445
500
|
for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
|
|
446
501
|
const key = getUserPermissionCacheKey( action, resource, id );
|
|
@@ -463,9 +518,9 @@ export const canUser =
|
|
|
463
518
|
* Checks whether the current user can perform the given action on the given
|
|
464
519
|
* REST resource.
|
|
465
520
|
*
|
|
466
|
-
* @param {string}
|
|
467
|
-
* @param {string}
|
|
468
|
-
* @param {string} recordId Record's id.
|
|
521
|
+
* @param {string} kind Entity kind.
|
|
522
|
+
* @param {string} name Entity name.
|
|
523
|
+
* @param {number|string} recordId Record's id.
|
|
469
524
|
*/
|
|
470
525
|
export const canUserEditEntityRecord =
|
|
471
526
|
( kind, name, recordId ) =>
|
|
@@ -700,7 +755,7 @@ export const getUserPatternCategories =
|
|
|
700
755
|
|
|
701
756
|
export const getNavigationFallbackId =
|
|
702
757
|
() =>
|
|
703
|
-
async ( { dispatch, select } ) => {
|
|
758
|
+
async ( { dispatch, select, registry } ) => {
|
|
704
759
|
const fallback = await apiFetch( {
|
|
705
760
|
path: addQueryArgs( '/wp-block-editor/v1/navigation-fallback', {
|
|
706
761
|
_embed: true,
|
|
@@ -709,9 +764,13 @@ export const getNavigationFallbackId =
|
|
|
709
764
|
|
|
710
765
|
const record = fallback?._embedded?.self;
|
|
711
766
|
|
|
712
|
-
|
|
767
|
+
registry.batch( () => {
|
|
768
|
+
dispatch.receiveNavigationFallbackId( fallback?.id );
|
|
769
|
+
|
|
770
|
+
if ( ! record ) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
713
773
|
|
|
714
|
-
if ( record ) {
|
|
715
774
|
// If the fallback is already in the store, don't invalidate navigation queries.
|
|
716
775
|
// Otherwise, invalidate the cache for the scenario where there were no Navigation
|
|
717
776
|
// posts in the state and the fallback created one.
|
|
@@ -735,7 +794,7 @@ export const getNavigationFallbackId =
|
|
|
735
794
|
'wp_navigation',
|
|
736
795
|
fallback.id,
|
|
737
796
|
] );
|
|
738
|
-
}
|
|
797
|
+
} );
|
|
739
798
|
};
|
|
740
799
|
|
|
741
800
|
export const getDefaultTemplateId =
|
|
@@ -762,7 +821,7 @@ export const getDefaultTemplateId =
|
|
|
762
821
|
*/
|
|
763
822
|
export const getRevisions =
|
|
764
823
|
( kind, name, recordKey, query = {} ) =>
|
|
765
|
-
async ( { dispatch } ) => {
|
|
824
|
+
async ( { dispatch, registry } ) => {
|
|
766
825
|
const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
|
|
767
826
|
const entityConfig = configs.find(
|
|
768
827
|
( config ) => config.name === name && config.kind === kind
|
|
@@ -829,32 +888,36 @@ export const getRevisions =
|
|
|
829
888
|
} );
|
|
830
889
|
}
|
|
831
890
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
891
|
+
registry.batch( () => {
|
|
892
|
+
dispatch.receiveRevisions(
|
|
893
|
+
kind,
|
|
894
|
+
name,
|
|
895
|
+
recordKey,
|
|
896
|
+
records,
|
|
897
|
+
query,
|
|
898
|
+
false,
|
|
899
|
+
meta
|
|
900
|
+
);
|
|
841
901
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
902
|
+
// When requesting all fields, the list of results can be used to
|
|
903
|
+
// resolve the `getRevision` selector in addition to `getRevisions`.
|
|
904
|
+
if ( ! query?._fields && ! query.context ) {
|
|
905
|
+
const key = entityConfig.key || DEFAULT_ENTITY_KEY;
|
|
906
|
+
const resolutionsArgs = records
|
|
907
|
+
.filter( ( record ) => record[ key ] )
|
|
908
|
+
.map( ( record ) => [
|
|
909
|
+
kind,
|
|
910
|
+
name,
|
|
911
|
+
recordKey,
|
|
912
|
+
record[ key ],
|
|
913
|
+
] );
|
|
854
914
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
915
|
+
dispatch.finishResolutions(
|
|
916
|
+
'getRevision',
|
|
917
|
+
resolutionsArgs
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
} );
|
|
858
921
|
}
|
|
859
922
|
};
|
|
860
923
|
|
package/src/test/resolvers.js
CHANGED
|
@@ -36,8 +36,8 @@ describe( 'getEntityRecord', () => {
|
|
|
36
36
|
receiveEntityRecords: jest.fn(),
|
|
37
37
|
__unstableAcquireStoreLock: jest.fn(),
|
|
38
38
|
__unstableReleaseStoreLock: jest.fn(),
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
receiveUserPermissions: jest.fn(),
|
|
40
|
+
finishResolutions: jest.fn(),
|
|
41
41
|
} );
|
|
42
42
|
triggerFetch.mockReset();
|
|
43
43
|
} );
|
|
@@ -80,7 +80,6 @@ describe( 'getEntityRecord', () => {
|
|
|
80
80
|
|
|
81
81
|
it( 'accepts a query that overrides default api path', async () => {
|
|
82
82
|
const query = { context: 'view', _envelope: '1' };
|
|
83
|
-
const queryObj = { include: [ 'post' ], ...query };
|
|
84
83
|
|
|
85
84
|
const select = {
|
|
86
85
|
hasEntityRecords: jest.fn( () => {} ),
|
|
@@ -98,13 +97,6 @@ describe( 'getEntityRecord', () => {
|
|
|
98
97
|
query
|
|
99
98
|
)( { dispatch, select, registry } );
|
|
100
99
|
|
|
101
|
-
// Check resolution cache for an existing entity that fulfills the request with query.
|
|
102
|
-
expect( select.hasEntityRecords ).toHaveBeenCalledWith(
|
|
103
|
-
'root',
|
|
104
|
-
'postType',
|
|
105
|
-
queryObj
|
|
106
|
-
);
|
|
107
|
-
|
|
108
100
|
// Trigger apiFetch, test that the query is present in the url.
|
|
109
101
|
expect( triggerFetch ).toHaveBeenCalledWith( {
|
|
110
102
|
path: '/wp/v2/types/post?context=view&_envelope=1',
|
|
@@ -116,7 +108,7 @@ describe( 'getEntityRecord', () => {
|
|
|
116
108
|
'root',
|
|
117
109
|
'postType',
|
|
118
110
|
POST_TYPE,
|
|
119
|
-
|
|
111
|
+
query
|
|
120
112
|
);
|
|
121
113
|
|
|
122
114
|
// Locks should have been acquired and released.
|
|
@@ -181,7 +173,7 @@ describe( 'getEntityRecords', () => {
|
|
|
181
173
|
{},
|
|
182
174
|
false,
|
|
183
175
|
undefined,
|
|
184
|
-
|
|
176
|
+
{ totalItems: 2, totalPages: 1 }
|
|
185
177
|
);
|
|
186
178
|
} );
|
|
187
179
|
|
|
@@ -219,6 +211,7 @@ describe( 'getEntityRecords', () => {
|
|
|
219
211
|
const finishResolutions = jest.fn();
|
|
220
212
|
const dispatch = Object.assign( jest.fn(), {
|
|
221
213
|
receiveEntityRecords: jest.fn(),
|
|
214
|
+
receiveUserPermissions: jest.fn(),
|
|
222
215
|
__unstableAcquireStoreLock: jest.fn(),
|
|
223
216
|
__unstableReleaseStoreLock: jest.fn(),
|
|
224
217
|
finishResolutions,
|
package/src/utils/index.js
CHANGED
|
@@ -11,6 +11,6 @@ export { default as getNestedValue } from './get-nested-value';
|
|
|
11
11
|
export { default as isNumericID } from './is-numeric-id';
|
|
12
12
|
export {
|
|
13
13
|
getUserPermissionCacheKey,
|
|
14
|
-
|
|
14
|
+
getUserPermissionsFromAllowHeader,
|
|
15
15
|
ALLOWED_RESOURCE_ACTIONS,
|
|
16
16
|
} from './user-permissions';
|
|
@@ -5,13 +5,11 @@ export const ALLOWED_RESOURCE_ACTIONS = [
|
|
|
5
5
|
'delete',
|
|
6
6
|
];
|
|
7
7
|
|
|
8
|
-
export function
|
|
8
|
+
export function getUserPermissionsFromAllowHeader( allowedMethods ) {
|
|
9
9
|
const permissions = {};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// only return the result, without including response properties like the headers.
|
|
14
|
-
const allowedMethods = response.headers?.get( 'allow' ) || '';
|
|
10
|
+
if ( ! allowedMethods ) {
|
|
11
|
+
return permissions;
|
|
12
|
+
}
|
|
15
13
|
|
|
16
14
|
const methods = {
|
|
17
15
|
create: 'POST',
|