@wordpress/core-data 7.3.0 → 7.4.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 +53 -5
- package/build/entity-context.js +13 -0
- package/build/entity-context.js.map +1 -0
- package/build/entity-provider.js +4 -189
- package/build/entity-provider.js.map +1 -1
- package/build/hooks/index.js +22 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/use-entity-block-editor.js +140 -0
- package/build/hooks/use-entity-block-editor.js.map +1 -0
- package/build/hooks/use-entity-id.js +28 -0
- package/build/hooks/use-entity-id.js.map +1 -0
- package/build/hooks/use-entity-prop.js +65 -0
- package/build/hooks/use-entity-prop.js.map +1 -0
- package/build/hooks/use-resource-permissions.js +25 -8
- package/build/hooks/use-resource-permissions.js.map +1 -1
- package/build/resolvers.js +64 -60
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +16 -8
- package/build/selectors.js.map +1 -1
- package/build/utils/index.js +19 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/user-permissions.js +32 -0
- package/build/utils/user-permissions.js.map +1 -0
- package/build-module/entity-context.js +6 -0
- package/build-module/entity-context.js.map +1 -0
- package/build-module/entity-provider.js +3 -183
- package/build-module/entity-provider.js.map +1 -1
- package/build-module/hooks/index.js +3 -0
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/use-entity-block-editor.js +132 -0
- package/build-module/hooks/use-entity-block-editor.js.map +1 -0
- package/build-module/hooks/use-entity-id.js +22 -0
- package/build-module/hooks/use-entity-id.js.map +1 -0
- package/build-module/hooks/use-entity-prop.js +58 -0
- package/build-module/hooks/use-entity-prop.js.map +1 -0
- package/build-module/hooks/use-resource-permissions.js +25 -8
- package/build-module/hooks/use-resource-permissions.js.map +1 -1
- package/build-module/resolvers.js +65 -61
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +17 -9
- package/build-module/selectors.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/user-permissions.js +24 -0
- package/build-module/utils/user-permissions.js.map +1 -0
- package/build-types/actions.d.ts +2 -2
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/batch/create-batch.d.ts.map +1 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/entity-context.d.ts +2 -0
- package/build-types/entity-context.d.ts.map +1 -0
- package/build-types/entity-provider.d.ts +0 -47
- package/build-types/entity-provider.d.ts.map +1 -1
- package/build-types/fetch/__experimental-fetch-url-data.d.ts.map +1 -1
- package/build-types/hooks/index.d.ts +3 -0
- package/build-types/hooks/index.d.ts.map +1 -1
- package/build-types/hooks/use-entity-block-editor.d.ts +22 -0
- package/build-types/hooks/use-entity-block-editor.d.ts.map +1 -0
- package/build-types/hooks/use-entity-id.d.ts +9 -0
- package/build-types/hooks/use-entity-id.d.ts.map +1 -0
- package/build-types/hooks/use-entity-prop.d.ts +19 -0
- package/build-types/hooks/use-entity-prop.d.ts.map +1 -0
- package/build-types/hooks/use-resource-permissions.d.ts +8 -70
- package/build-types/hooks/use-resource-permissions.d.ts.map +1 -1
- package/build-types/index.d.ts +35 -32
- package/build-types/index.d.ts.map +1 -1
- package/build-types/locks/reducer.d.ts +1 -1
- package/build-types/locks/reducer.d.ts.map +1 -1
- package/build-types/queried-data/actions.d.ts +1 -1
- package/build-types/queried-data/actions.d.ts.map +1 -1
- package/build-types/queried-data/get-query-parts.d.ts.map +1 -1
- package/build-types/queried-data/reducer.d.ts +1 -1
- package/build-types/queried-data/reducer.d.ts.map +1 -1
- package/build-types/queried-data/selectors.d.ts +0 -1
- package/build-types/queried-data/selectors.d.ts.map +1 -1
- package/build-types/reducer.d.ts +13 -13
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts +3 -2
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/selectors.d.ts +11 -6
- package/build-types/selectors.d.ts.map +1 -1
- package/build-types/utils/get-nested-value.d.ts.map +1 -1
- package/build-types/utils/get-normalized-comma-separable.d.ts.map +1 -1
- package/build-types/utils/if-matching-action.d.ts +1 -1
- package/build-types/utils/index.d.ts +1 -0
- package/build-types/utils/on-sub-key.d.ts +1 -1
- package/build-types/utils/replace-action.d.ts +1 -1
- package/build-types/utils/set-nested-value.d.ts.map +1 -1
- package/build-types/utils/user-permissions.d.ts +4 -0
- package/build-types/utils/user-permissions.d.ts.map +1 -0
- package/package.json +18 -17
- package/src/entity-context.js +6 -0
- package/src/entity-provider.js +2 -209
- package/src/hooks/index.ts +3 -0
- package/src/hooks/test/use-entity-record.js +5 -3
- package/src/hooks/test/use-resource-permissions.js +96 -5
- package/src/hooks/use-entity-block-editor.js +148 -0
- package/src/hooks/use-entity-id.js +21 -0
- package/src/hooks/use-entity-prop.js +60 -0
- package/src/hooks/use-resource-permissions.ts +46 -9
- package/src/resolvers.js +85 -67
- package/src/selectors.ts +18 -9
- package/src/test/entity-provider.js +6 -2
- package/src/test/resolvers.js +217 -50
- package/src/test/selectors.js +18 -55
- package/src/utils/index.js +5 -0
- package/src/utils/user-permissions.js +39 -0
- package/tsconfig.json +2 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import deprecated from '@wordpress/deprecated';
|
|
5
|
+
import warning from '@wordpress/warning';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
@@ -41,20 +42,34 @@ type ResourcePermissionsResolution< IdType > = [
|
|
|
41
42
|
( IdType extends void ? SpecificResourcePermissionsResolution : {} ),
|
|
42
43
|
];
|
|
43
44
|
|
|
45
|
+
type EntityResource = { kind: string; name: string; id?: string | number };
|
|
46
|
+
|
|
47
|
+
function useResourcePermissions< IdType = void >(
|
|
48
|
+
resource: string,
|
|
49
|
+
id?: IdType
|
|
50
|
+
): ResourcePermissionsResolution< IdType >;
|
|
51
|
+
|
|
52
|
+
function useResourcePermissions< IdType = void >(
|
|
53
|
+
resource: EntityResource,
|
|
54
|
+
id?: never
|
|
55
|
+
): ResourcePermissionsResolution< IdType >;
|
|
56
|
+
|
|
44
57
|
/**
|
|
45
58
|
* Resolves resource permissions.
|
|
46
59
|
*
|
|
47
60
|
* @since 6.1.0 Introduced in WordPress core.
|
|
48
61
|
*
|
|
49
|
-
* @param resource
|
|
50
|
-
*
|
|
62
|
+
* @param resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }`
|
|
63
|
+
* or REST base as a string - `media`.
|
|
64
|
+
* @param id Optional ID of the resource to check, e.g. 10. Note: This argument is discouraged
|
|
65
|
+
* when using an entity object as a resource to check permissions and will be ignored.
|
|
51
66
|
*
|
|
52
67
|
* @example
|
|
53
68
|
* ```js
|
|
54
69
|
* import { useResourcePermissions } from '@wordpress/core-data';
|
|
55
70
|
*
|
|
56
71
|
* function PagesList() {
|
|
57
|
-
* const { canCreate, isResolving } = useResourcePermissions( '
|
|
72
|
+
* const { canCreate, isResolving } = useResourcePermissions( { kind: 'postType', name: 'page' } );
|
|
58
73
|
*
|
|
59
74
|
* if ( isResolving ) {
|
|
60
75
|
* return 'Loading ...';
|
|
@@ -82,7 +97,7 @@ type ResourcePermissionsResolution< IdType > = [
|
|
|
82
97
|
* canUpdate,
|
|
83
98
|
* canDelete,
|
|
84
99
|
* isResolving
|
|
85
|
-
* } = useResourcePermissions( '
|
|
100
|
+
* } = useResourcePermissions( { kind: 'postType', name: 'page', id: pageId } );
|
|
86
101
|
*
|
|
87
102
|
* if ( isResolving ) {
|
|
88
103
|
* return 'Loading ...';
|
|
@@ -109,15 +124,35 @@ type ResourcePermissionsResolution< IdType > = [
|
|
|
109
124
|
* @return Entity records data.
|
|
110
125
|
* @template IdType
|
|
111
126
|
*/
|
|
112
|
-
|
|
113
|
-
resource: string,
|
|
127
|
+
function useResourcePermissions< IdType = void >(
|
|
128
|
+
resource: string | EntityResource,
|
|
114
129
|
id?: IdType
|
|
115
130
|
): ResourcePermissionsResolution< IdType > {
|
|
131
|
+
// Serialize `resource` to a string that can be safely used as a React dep.
|
|
132
|
+
// We can't just pass `resource` as one of the deps, because if it is passed
|
|
133
|
+
// as an object literal, then it will be a different object on each call even
|
|
134
|
+
// if the values remain the same.
|
|
135
|
+
const isEntity = typeof resource === 'object';
|
|
136
|
+
const resourceAsString = isEntity ? JSON.stringify( resource ) : resource;
|
|
137
|
+
|
|
138
|
+
if ( isEntity && typeof id !== 'undefined' ) {
|
|
139
|
+
warning(
|
|
140
|
+
`When 'resource' is an entity object, passing 'id' as a separate argument isn't supported.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
116
144
|
return useQuerySelect(
|
|
117
145
|
( resolve ) => {
|
|
146
|
+
const hasId = isEntity ? !! resource.id : !! id;
|
|
118
147
|
const { canUser } = resolve( coreStore );
|
|
119
|
-
const create = canUser(
|
|
120
|
-
|
|
148
|
+
const create = canUser(
|
|
149
|
+
'create',
|
|
150
|
+
isEntity
|
|
151
|
+
? { kind: resource.kind, name: resource.name }
|
|
152
|
+
: resource
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
if ( ! hasId ) {
|
|
121
156
|
const read = canUser( 'read', resource );
|
|
122
157
|
|
|
123
158
|
const isResolving = create.isResolving || read.isResolving;
|
|
@@ -168,10 +203,12 @@ export default function useResourcePermissions< IdType = void >(
|
|
|
168
203
|
canDelete: hasResolved && _delete.data,
|
|
169
204
|
};
|
|
170
205
|
},
|
|
171
|
-
[
|
|
206
|
+
[ resourceAsString, id ]
|
|
172
207
|
);
|
|
173
208
|
}
|
|
174
209
|
|
|
210
|
+
export default useResourcePermissions;
|
|
211
|
+
|
|
175
212
|
export function __experimentalUseResourcePermissions(
|
|
176
213
|
resource: string,
|
|
177
214
|
id?: unknown
|
package/src/resolvers.js
CHANGED
|
@@ -15,7 +15,13 @@ import apiFetch from '@wordpress/api-fetch';
|
|
|
15
15
|
*/
|
|
16
16
|
import { STORE_NAME } from './name';
|
|
17
17
|
import { getOrLoadEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
forwardResolver,
|
|
20
|
+
getNormalizedCommaSeparable,
|
|
21
|
+
getUserPermissionCacheKey,
|
|
22
|
+
getUserPermissionsFromResponse,
|
|
23
|
+
ALLOWED_RESOURCE_ACTIONS,
|
|
24
|
+
} from './utils';
|
|
19
25
|
import { getSyncProvider } from './sync';
|
|
20
26
|
import { fetchBlockPatterns } from './fetch';
|
|
21
27
|
|
|
@@ -58,7 +64,7 @@ export const getCurrentUser =
|
|
|
58
64
|
*/
|
|
59
65
|
export const getEntityRecord =
|
|
60
66
|
( kind, name, key = '', query ) =>
|
|
61
|
-
async ( { select, dispatch } ) => {
|
|
67
|
+
async ( { select, dispatch, registry } ) => {
|
|
62
68
|
const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
|
|
63
69
|
const entityConfig = configs.find(
|
|
64
70
|
( config ) => config.name === name && config.kind === kind
|
|
@@ -165,8 +171,29 @@ export const getEntityRecord =
|
|
|
165
171
|
}
|
|
166
172
|
}
|
|
167
173
|
|
|
168
|
-
const
|
|
169
|
-
|
|
174
|
+
const response = await apiFetch( { path, parse: false } );
|
|
175
|
+
const record = await response.json();
|
|
176
|
+
const permissions = getUserPermissionsFromResponse( response );
|
|
177
|
+
|
|
178
|
+
registry.batch( () => {
|
|
179
|
+
dispatch.receiveEntityRecords( kind, name, record, query );
|
|
180
|
+
|
|
181
|
+
for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
|
|
182
|
+
const permissionKey = getUserPermissionCacheKey(
|
|
183
|
+
action,
|
|
184
|
+
{ kind, name, id: key }
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
dispatch.receiveUserPermission(
|
|
188
|
+
permissionKey,
|
|
189
|
+
permissions[ action ]
|
|
190
|
+
);
|
|
191
|
+
dispatch.finishResolution( 'canUser', [
|
|
192
|
+
action,
|
|
193
|
+
{ kind, name, id: key },
|
|
194
|
+
] );
|
|
195
|
+
}
|
|
196
|
+
} );
|
|
170
197
|
}
|
|
171
198
|
} finally {
|
|
172
199
|
dispatch.__unstableReleaseStoreLock( lock );
|
|
@@ -281,16 +308,10 @@ export const getEntityRecords =
|
|
|
281
308
|
.filter( ( record ) => record?.[ key ] )
|
|
282
309
|
.map( ( record ) => [ kind, name, record[ key ] ] );
|
|
283
310
|
|
|
284
|
-
dispatch(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
} );
|
|
289
|
-
dispatch( {
|
|
290
|
-
type: 'FINISH_RESOLUTIONS',
|
|
291
|
-
selectorName: 'getEntityRecord',
|
|
292
|
-
args: resolutionsArgs,
|
|
293
|
-
} );
|
|
311
|
+
dispatch.finishResolutions(
|
|
312
|
+
'getEntityRecord',
|
|
313
|
+
resolutionsArgs
|
|
314
|
+
);
|
|
294
315
|
}
|
|
295
316
|
|
|
296
317
|
dispatch.__unstableReleaseStoreLock( lock );
|
|
@@ -352,25 +373,47 @@ export const getEmbedPreview =
|
|
|
352
373
|
* Checks whether the current user can perform the given action on the given
|
|
353
374
|
* REST resource.
|
|
354
375
|
*
|
|
355
|
-
* @param {string}
|
|
356
|
-
*
|
|
357
|
-
* @param {string}
|
|
358
|
-
*
|
|
376
|
+
* @param {string} requestedAction Action to check. One of: 'create', 'read', 'update',
|
|
377
|
+
* 'delete'.
|
|
378
|
+
* @param {string|Object} resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }`
|
|
379
|
+
* or REST base as a string - `media`.
|
|
380
|
+
* @param {?string} id ID of the rest resource to check.
|
|
359
381
|
*/
|
|
360
382
|
export const canUser =
|
|
361
383
|
( requestedAction, resource, id ) =>
|
|
362
384
|
async ( { dispatch, registry } ) => {
|
|
363
|
-
|
|
385
|
+
if ( ! ALLOWED_RESOURCE_ACTIONS.includes( requestedAction ) ) {
|
|
386
|
+
throw new Error( `'${ requestedAction }' is not a valid action.` );
|
|
387
|
+
}
|
|
364
388
|
|
|
365
|
-
|
|
366
|
-
|
|
389
|
+
let resourcePath = null;
|
|
390
|
+
if ( typeof resource === 'object' ) {
|
|
391
|
+
if ( ! resource.kind || ! resource.name ) {
|
|
392
|
+
throw new Error( 'The entity resource object is not valid.' );
|
|
393
|
+
}
|
|
367
394
|
|
|
368
|
-
|
|
369
|
-
|
|
395
|
+
const configs = await dispatch(
|
|
396
|
+
getOrLoadEntitiesConfig( resource.kind, resource.name )
|
|
397
|
+
);
|
|
398
|
+
const entityConfig = configs.find(
|
|
399
|
+
( config ) =>
|
|
400
|
+
config.name === resource.name &&
|
|
401
|
+
config.kind === resource.kind
|
|
402
|
+
);
|
|
403
|
+
if ( ! entityConfig ) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
resourcePath =
|
|
408
|
+
entityConfig.baseURL + ( resource.id ? '/' + resource.id : '' );
|
|
409
|
+
} else {
|
|
410
|
+
resourcePath = `/wp/v2/${ resource }` + ( id ? '/' + id : '' );
|
|
370
411
|
}
|
|
371
412
|
|
|
413
|
+
const { hasStartedResolution } = registry.select( STORE_NAME );
|
|
414
|
+
|
|
372
415
|
// Prevent resolving the same resource twice.
|
|
373
|
-
for ( const relatedAction of
|
|
416
|
+
for ( const relatedAction of ALLOWED_RESOURCE_ACTIONS ) {
|
|
374
417
|
if ( relatedAction === requestedAction ) {
|
|
375
418
|
continue;
|
|
376
419
|
}
|
|
@@ -387,7 +430,7 @@ export const canUser =
|
|
|
387
430
|
let response;
|
|
388
431
|
try {
|
|
389
432
|
response = await apiFetch( {
|
|
390
|
-
path:
|
|
433
|
+
path: resourcePath,
|
|
391
434
|
method: 'OPTIONS',
|
|
392
435
|
parse: false,
|
|
393
436
|
} );
|
|
@@ -397,29 +440,21 @@ export const canUser =
|
|
|
397
440
|
return;
|
|
398
441
|
}
|
|
399
442
|
|
|
400
|
-
|
|
401
|
-
// return the expected result in the native version. Instead, API requests
|
|
402
|
-
// only return the result, without including response properties like the headers.
|
|
403
|
-
const allowHeader = response.headers?.get( 'allow' );
|
|
404
|
-
const allowedMethods = allowHeader?.allow || allowHeader || '';
|
|
405
|
-
|
|
406
|
-
const permissions = {};
|
|
407
|
-
const methods = {
|
|
408
|
-
create: 'POST',
|
|
409
|
-
read: 'GET',
|
|
410
|
-
update: 'PUT',
|
|
411
|
-
delete: 'DELETE',
|
|
412
|
-
};
|
|
413
|
-
for ( const [ actionName, methodName ] of Object.entries( methods ) ) {
|
|
414
|
-
permissions[ actionName ] = allowedMethods.includes( methodName );
|
|
415
|
-
}
|
|
416
|
-
|
|
443
|
+
const permissions = getUserPermissionsFromResponse( response );
|
|
417
444
|
registry.batch( () => {
|
|
418
|
-
for ( const action of
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
445
|
+
for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
|
|
446
|
+
const key = getUserPermissionCacheKey( action, resource, id );
|
|
447
|
+
|
|
448
|
+
dispatch.receiveUserPermission( key, permissions[ action ] );
|
|
449
|
+
|
|
450
|
+
// Mark related action resolutions as finished.
|
|
451
|
+
if ( action !== requestedAction ) {
|
|
452
|
+
dispatch.finishResolution( 'canUser', [
|
|
453
|
+
action,
|
|
454
|
+
resource,
|
|
455
|
+
id,
|
|
456
|
+
] );
|
|
457
|
+
}
|
|
423
458
|
}
|
|
424
459
|
} );
|
|
425
460
|
};
|
|
@@ -435,16 +470,7 @@ export const canUser =
|
|
|
435
470
|
export const canUserEditEntityRecord =
|
|
436
471
|
( kind, name, recordId ) =>
|
|
437
472
|
async ( { dispatch } ) => {
|
|
438
|
-
|
|
439
|
-
const entityConfig = configs.find(
|
|
440
|
-
( config ) => config.name === name && config.kind === kind
|
|
441
|
-
);
|
|
442
|
-
if ( ! entityConfig ) {
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const resource = entityConfig.__unstable_rest_base;
|
|
447
|
-
await dispatch( canUser( 'update', resource, recordId ) );
|
|
473
|
+
await dispatch( canUser( 'update', { kind, name, id: recordId } ) );
|
|
448
474
|
};
|
|
449
475
|
|
|
450
476
|
/**
|
|
@@ -826,16 +852,8 @@ export const getRevisions =
|
|
|
826
852
|
record[ key ],
|
|
827
853
|
] );
|
|
828
854
|
|
|
829
|
-
dispatch(
|
|
830
|
-
|
|
831
|
-
selectorName: 'getRevision',
|
|
832
|
-
args: resolutionsArgs,
|
|
833
|
-
} );
|
|
834
|
-
dispatch( {
|
|
835
|
-
type: 'FINISH_RESOLUTIONS',
|
|
836
|
-
selectorName: 'getRevision',
|
|
837
|
-
args: resolutionsArgs,
|
|
838
|
-
} );
|
|
855
|
+
dispatch.startResolutions( 'getRevision', resolutionsArgs );
|
|
856
|
+
dispatch.finishResolutions( 'getRevision', resolutionsArgs );
|
|
839
857
|
}
|
|
840
858
|
}
|
|
841
859
|
};
|
package/src/selectors.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
isRawAttribute,
|
|
21
21
|
setNestedValue,
|
|
22
22
|
isNumericID,
|
|
23
|
+
getUserPermissionCacheKey,
|
|
23
24
|
} from './utils';
|
|
24
25
|
import type * as ET from './entity-types';
|
|
25
26
|
import type { UndoManager } from '@wordpress/undo-manager';
|
|
@@ -120,6 +121,8 @@ type EntityRecordArgs =
|
|
|
120
121
|
| [ string, string, EntityRecordKey ]
|
|
121
122
|
| [ string, string, EntityRecordKey, GetRecordsHttpQuery ];
|
|
122
123
|
|
|
124
|
+
type EntityResource = { kind: string; name: string; id?: EntityRecordKey };
|
|
125
|
+
|
|
123
126
|
/**
|
|
124
127
|
* Shared reference to an empty object for cases where it is important to avoid
|
|
125
128
|
* returning a new object reference on every invocation, as in a connected or
|
|
@@ -1136,7 +1139,8 @@ export function isPreviewEmbedFallback( state: State, url: string ): boolean {
|
|
|
1136
1139
|
*
|
|
1137
1140
|
* @param state Data state.
|
|
1138
1141
|
* @param action Action to check. One of: 'create', 'read', 'update', 'delete'.
|
|
1139
|
-
* @param resource
|
|
1142
|
+
* @param resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }`
|
|
1143
|
+
* or REST base as a string - `media`.
|
|
1140
1144
|
* @param id Optional ID of the rest resource to check.
|
|
1141
1145
|
*
|
|
1142
1146
|
* @return Whether or not the user can perform the action,
|
|
@@ -1145,10 +1149,16 @@ export function isPreviewEmbedFallback( state: State, url: string ): boolean {
|
|
|
1145
1149
|
export function canUser(
|
|
1146
1150
|
state: State,
|
|
1147
1151
|
action: string,
|
|
1148
|
-
resource: string,
|
|
1152
|
+
resource: string | EntityResource,
|
|
1149
1153
|
id?: EntityRecordKey
|
|
1150
1154
|
): boolean | undefined {
|
|
1151
|
-
const
|
|
1155
|
+
const isEntity = typeof resource === 'object';
|
|
1156
|
+
if ( isEntity && ( ! resource.kind || ! resource.name ) ) {
|
|
1157
|
+
return false;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
const key = getUserPermissionCacheKey( action, resource, id );
|
|
1161
|
+
|
|
1152
1162
|
return state.userPermissions[ key ];
|
|
1153
1163
|
}
|
|
1154
1164
|
|
|
@@ -1173,13 +1183,12 @@ export function canUserEditEntityRecord(
|
|
|
1173
1183
|
name: string,
|
|
1174
1184
|
recordId: EntityRecordKey
|
|
1175
1185
|
): boolean | undefined {
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1180
|
-
const resource = entityConfig.__unstable_rest_base;
|
|
1186
|
+
deprecated( `wp.data.select( 'core' ).canUserEditEntityRecord()`, {
|
|
1187
|
+
since: '6.7',
|
|
1188
|
+
alternative: `wp.data.select( 'core' ).canUser( 'update', { kind, name, id } )`,
|
|
1189
|
+
} );
|
|
1181
1190
|
|
|
1182
|
-
return canUser( state, 'update',
|
|
1191
|
+
return canUser( state, 'update', { kind, name, id: recordId } );
|
|
1183
1192
|
}
|
|
1184
1193
|
|
|
1185
1194
|
/**
|
|
@@ -14,13 +14,14 @@ import {
|
|
|
14
14
|
} from '@wordpress/blocks';
|
|
15
15
|
import { RichText, useBlockProps } from '@wordpress/block-editor';
|
|
16
16
|
import { createRegistry, RegistryProvider } from '@wordpress/data';
|
|
17
|
-
import '@wordpress/block-library';
|
|
17
|
+
import { registerCoreBlocks } from '@wordpress/block-library';
|
|
18
|
+
import { unregisterFormatType } from '@wordpress/rich-text';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Internal dependencies
|
|
21
22
|
*/
|
|
22
23
|
import { store as coreDataStore } from '../index';
|
|
23
|
-
import
|
|
24
|
+
import useEntityBlockEditor from '../hooks/use-entity-block-editor';
|
|
24
25
|
|
|
25
26
|
const postTypeConfig = {
|
|
26
27
|
kind: 'postType',
|
|
@@ -137,12 +138,15 @@ describe( 'useEntityBlockEditor', () => {
|
|
|
137
138
|
title: 'block title',
|
|
138
139
|
edit,
|
|
139
140
|
} );
|
|
141
|
+
|
|
142
|
+
registerCoreBlocks();
|
|
140
143
|
} );
|
|
141
144
|
|
|
142
145
|
afterEach( () => {
|
|
143
146
|
getBlockTypes().forEach( ( block ) => {
|
|
144
147
|
unregisterBlockType( block.name );
|
|
145
148
|
} );
|
|
149
|
+
unregisterFormatType( 'core/footnote' );
|
|
146
150
|
} );
|
|
147
151
|
|
|
148
152
|
it( 'does not mutate block attributes that include an array of strings or null values', async () => {
|