-
Notifications
You must be signed in to change notification settings - Fork 451
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,30 @@ | ||
import {useMemo} from 'react' | ||
|
||
import {isErrorWithDetails} from '../../error/types/isErrorWithDetails' | ||
import {useResourceCache} from '../../store/_legacy/ResourceCacheProvider' | ||
|
||
export interface useReleasePermissionsValue { | ||
checkWithPermissionGuard: <T extends (...args: any[]) => Promise<void> | void>( | ||
action: T, | ||
...args: Parameters<T> | ||
) => Promise<boolean> | ||
permissions: {[key: string]: boolean} | ||
} | ||
|
||
type ReleasePermissionError = {details: {type: 'insufficientPermissionsError'}} | ||
|
||
const RELEASE_PERMISSIONS_RESOURCE_CACHE_NAMESPACE = 'ReleasePermissions' | ||
|
||
export const isReleasePermissionError = (error: unknown): error is ReleasePermissionError => | ||
isErrorWithDetails(error) && error.details?.type === 'insufficientPermissionsError' | ||
|
||
/** | ||
* | ||
* @internal | ||
*/ | ||
export function useReleasePermissions(): useReleasePermissionsValue { | ||
function createReleasePermissionsStore(): useReleasePermissionsValue { | ||
let permissions: {[key: string]: boolean} = {} | ||
|
||
/** | ||
* Checks if a release action can be performed by running a dry run of the given action | ||
* | ||
|
@@ -27,17 +36,49 @@ export function useReleasePermissions(): useReleasePermissionsValue { | |
action: T, | ||
...args: Parameters<T> | ||
): Promise<boolean> => { | ||
try { | ||
await action(...args, { | ||
dryRun: true, | ||
skipCrossDatasetReferenceValidation: true, | ||
}) | ||
return true | ||
} catch (e) { | ||
return !isReleasePermissionError(e) | ||
if (permissions[action.name] === undefined) { | ||
try { | ||
await action(...args, { | ||
dryRun: true, | ||
skipCrossDatasetReferenceValidation: true, | ||
}) | ||
permissions = {...permissions, [action.name]: true} | ||
|
||
return true | ||
} catch (e) { | ||
permissions = {...permissions, [action.name]: false} | ||
|
||
return !isReleasePermissionError(e) | ||
} | ||
} else { | ||
return permissions[action.name] | ||
} | ||
} | ||
return { | ||
checkWithPermissionGuard: checkWithPermissionGuard, | ||
permissions, | ||
} | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
export function useReleasePermissions(): useReleasePermissionsValue { | ||
Check failure on line 66 in packages/sanity/src/core/releases/store/useReleasePermissions.ts
|
||
const resourceCache = useResourceCache() | ||
|
||
return useMemo(() => { | ||
const releasePermissionsStore = | ||
resourceCache.get<useReleasePermissionsValue>({ | ||
dependencies: [null], | ||
namespace: RELEASE_PERMISSIONS_RESOURCE_CACHE_NAMESPACE, | ||
}) || createReleasePermissionsStore() | ||
|
||
resourceCache.set({ | ||
namespace: RELEASE_PERMISSIONS_RESOURCE_CACHE_NAMESPACE, | ||
value: releasePermissionsStore, | ||
dependencies: [null], | ||
}) | ||
|
||
return releasePermissionsStore | ||
}, [resourceCache]) | ||
} |