Skip to content

Commit

Permalink
Core Data: Support entities in the 'canUser' selector
Browse files Browse the repository at this point in the history
  • Loading branch information
Mamaduka committed Jul 9, 2024
1 parent 9a8be7c commit 15462d4
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ _Parameters_

- _state_ `State`: Data state.
- _action_ `string`: Action to check. One of: 'create', 'read', 'update', 'delete'.
- _resource_ `string`: REST resource to check, e.g. 'media' or 'posts'.
- _resource_ `string | Record< string, any >`: REST resource to check, e.g. 'media' or 'posts'.
- _id_ `EntityRecordKey`: Optional ID of the rest resource to check.

_Returns_
Expand Down
2 changes: 1 addition & 1 deletion packages/core-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ _Parameters_

- _state_ `State`: Data state.
- _action_ `string`: Action to check. One of: 'create', 'read', 'update', 'delete'.
- _resource_ `string`: REST resource to check, e.g. 'media' or 'posts'.
- _resource_ `string | Record< string, any >`: REST resource to check, e.g. 'media' or 'posts'.
- _id_ `EntityRecordKey`: Optional ID of the rest resource to check.

_Returns_
Expand Down
41 changes: 33 additions & 8 deletions packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,15 +360,35 @@ export const getEmbedPreview =
export const canUser =
( requestedAction, resource, id ) =>
async ( { dispatch, registry } ) => {
const { hasStartedResolution } = registry.select( STORE_NAME );

const resourcePath = id ? `${ resource }/${ id }` : resource;
const retrievedActions = [ 'create', 'read', 'update', 'delete' ];

if ( ! retrievedActions.includes( requestedAction ) ) {
throw new Error( `'${ requestedAction }' is not a valid action.` );
}

let resourcePath = null;
if ( typeof resource === 'object' ) {
const configs = await dispatch(
getOrLoadEntitiesConfig( resource.kind, resource.name )
);
const entityConfig = configs.find(
( config ) =>
config.name === resource.name &&
config.kind === resource.name
);
if ( ! entityConfig ) {
return;
}

resourcePath =
entityConfig.baseURL + ( resource.id ? '/' + resource.id : '' );
} else {
// @todo: Maybe warn when detecting a legacy usage.
resourcePath = `/wp/v2/${ resource }` + ( id ? '/' + id : '' );
}

const { hasStartedResolution } = registry.select( STORE_NAME );

// Prevent resolving the same resource twice.
for ( const relatedAction of retrievedActions ) {
if ( relatedAction === requestedAction ) {
Expand All @@ -387,7 +407,7 @@ export const canUser =
let response;
try {
response = await apiFetch( {
path: `/wp/v2/${ resourcePath }`,
path: resourcePath,
method: 'OPTIONS',
parse: false,
} );
Expand Down Expand Up @@ -416,10 +436,15 @@ export const canUser =

registry.batch( () => {
for ( const action of retrievedActions ) {
dispatch.receiveUserPermission(
`${ action }/${ resourcePath }`,
permissions[ action ]
);
const key = (
typeof resource === 'object'
? [ action, resource.kind, resource.name, resource.id ]
: [ action, resource, id ]
)
.filter( Boolean )
.join( '/' );

dispatch.receiveUserPermission( key, permissions[ action ] );
}
} );
};
Expand Down
11 changes: 9 additions & 2 deletions packages/core-data/src/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1145,10 +1145,17 @@ export function isPreviewEmbedFallback( state: State, url: string ): boolean {
export function canUser(
state: State,
action: string,
resource: string,
resource: string | Record< string, any >,
id?: EntityRecordKey
): boolean | undefined {
const key = [ action, resource, id ].filter( Boolean ).join( '/' );
const key = (
typeof resource === 'object'
? [ action, resource.kind, resource.name, resource.id ]
: [ action, resource, id ]
)
.filter( Boolean )
.join( '/' );

return state.userPermissions[ key ];
}

Expand Down

0 comments on commit 15462d4

Please sign in to comment.