@seed-fe/permission
Version:
Framework-agnostic permission management library with batching, caching, and debouncing
307 lines (300 loc) • 10.5 kB
TypeScript
/**
* Permission configuration type
*/
type PermissionConfig = {
/** Permission code, can be a single string or array of strings */
code: string | readonly string[];
/** Permission check mode: 'all' - all must be satisfied, 'any' - any one satisfied */
mode?: 'all' | 'any';
/** Business parameters, will be passed to permission service */
biz?: Record<string, unknown>;
};
/**
* Permission input type union
*/
type PermissionInput = string | readonly string[] | PermissionConfig;
/**
* Permission service function return value type
*
* Supports two formats:
* - boolean: true/false
* - number: 1/0 (1 means has permission, 0 means no permission)
*/
type PermissionResult = boolean | number;
/**
* Permission service function type
*
* Receives permission configuration array, returns corresponding permission result array
*/
type PermissionServiceFn = (configs: PermissionConfig[]) => Promise<PermissionResult[]>;
/**
* Permission service options
*/
type PermissionServiceOptions = {
batch?: {
/** Batch processing delay time (milliseconds) */
delay?: number;
/** Maximum batch size */
maxSize?: number;
};
cache?: {
/** Whether to enable cache */
enable?: boolean;
/** Cache time-to-live (milliseconds) */
ttl?: number;
};
};
/**
* checkPermission function options interface
*/
interface CheckPermissionOptions {
/** Optional temporary permission service */
permissionService?: PermissionServiceFn;
}
/**
* Cache item data structure
*
* Internal use, stores permission check results and timestamps
*/
interface CacheItem {
/** Permission check result */
result: boolean;
/** Cache timestamp */
timestamp: number;
}
/**
* Global permission configuration interface
*/
interface GlobalPermissionConfig {
/** Permission check service function */
permissionService: PermissionServiceFn;
/** Permission service configuration options */
permissionServiceOptions?: PermissionServiceOptions;
}
/**
* Configure global permission service
*
* Provides a convenient way to configure global permission service
*
* @param config Permission configuration
*
* @example
* ```typescript
* import { configurePermission } from '@seed-fe/permission';
*
* configurePermission({
* permissionService: async (configs) => {
* const response = await fetch('/api/permissions/check', {
* method: 'POST',
* body: JSON.stringify(configs)
* });
* return response.json();
* },
* permissionServiceOptions: {
* batch: { delay: 50, maxSize: 100 },
* cache: { enable: true, ttl: 300000 } // IMPORTANT: Explicitly enable caching (default is false)
* }
* });
* ```
*/
declare function configurePermission(config: GlobalPermissionConfig): void;
/**
* Default permission batch processing configuration
*/
declare const BATCH_CONFIG: {
/** Batch processing delay time (milliseconds) */
DELAY: number;
/** Maximum batch size */
MAX_SIZE: number;
};
/**
* Default cache configuration
*/
declare const CACHE_CONFIG: {
/** Whether to enable caching */
ENABLE: boolean;
/** Cache TTL (milliseconds) - 5 minutes */
TTL: number;
};
/**
* Permission check modes - defines how multiple permissions are evaluated
*/
declare const PERMISSION_CHECK_MODES: {
/** All permissions must be satisfied */
readonly ALL: "all";
/** Any one permission needs to be satisfied */
readonly ANY: "any";
};
/**
* Permission batch processing endpoint identifier
*/
declare const PERMISSION_BATCH_ENDPOINT = "permission-batch";
/**
* Register permission service
*/
declare function registerPermissionService(service: PermissionServiceFn, options?: PermissionServiceOptions): void;
/**
* Check permission
*/
declare function checkPermission$1(permission: PermissionConfig, customService?: PermissionServiceFn): Promise<boolean>;
/**
* Clear permission cache by reinitializing the batch processing system
*
* Note: This function clears cache by recreating the entire batch processing function,
* which ensures all cached results are discarded. This approach is used because
* the cache is managed internally by @seed-fe/batch-request.
*
* @example
* ```typescript
* // Clear cache when user logs out
* function handleLogout() {
* clearPermissionCache();
* // ... other logout logic
* }
* ```
*/
declare function clearPermissionCache(): void;
/**
* Get permission system status information
*
* Returns current state of the permission management system, including
* service registration status and batch processing availability.
*
* @returns {object} Permission system status
* @returns {boolean} returns.hasGlobalService - Whether a global permission service is registered
* @returns {boolean} returns.hasBatchFunction - Whether batch processing function is available
*
* @example
* ```typescript
* const status = getPermissionStats();
* console.log('Service registered:', status.hasGlobalService);
* console.log('Batch processing ready:', status.hasBatchFunction);
*
* // Check system readiness
* if (!status.hasGlobalService) {
* console.warn('Permission service not registered');
* }
* ```
*/
declare function getPermissionStats(): {
hasGlobalService: boolean;
hasBatchFunction: boolean;
};
/**
* Permission check function
*
* Provides imperative permission checking capability based on global permission manager.
* Supports batch processing and caching, suitable for permission judgment in business logic.
*
* Exception handling:
* - All exceptions will throw PermissionError
* - Exceptions will be globally caught by @seed-fe/exception-handler
* - Exceptions are not handled internally within this function
*
* @param permission Permission configuration
* @param customService Optional custom permission service
* @returns Promise<boolean> Permission check result
* @throws {PermissionError} Throws exception when permission check fails
*
* @example
* ```typescript
* // Check single permission (using example permission codes)
* const canEdit = await checkPermission('user.edit');
*
* // Check multiple permissions (all must be satisfied)
* const canManage = await checkPermission({
* code: ['user.edit', 'user.delete'],
* mode: 'all'
* });
*
* // Check multiple permissions (any one satisfied)
* const hasAnyPermission = await checkPermission({
* code: ['admin.panel', 'user.manage'],
* mode: 'any'
* });
*
* // Check with business context
* const canEditDocument = await checkPermission({
* code: 'document.edit',
* biz: { documentId: '123', ownerId: 'user456' }
* });
* ```
*
* Note: Permission codes like 'user.edit', 'admin.panel' are examples.
* Replace them with your actual permission codes from your system.
*/
declare function checkPermission(permission: PermissionInput, customService?: PermissionServiceFn): Promise<boolean>;
/**
* Permission error class
*
* Exception class specially designed for @seed-fe/exception-handler
* Contains package name information for special handling by global exception handler
*/
declare class PermissionError extends Error {
readonly packageName: string;
readonly permissionConfig?: PermissionConfig | undefined;
readonly originalError?: unknown | undefined;
constructor(message: string, packageName: string, permissionConfig?: PermissionConfig | undefined, originalError?: unknown | undefined);
}
/**
* Normalize permission input to standardized PermissionConfig format
*
* Converts various permission input formats (string, string array, or PermissionConfig)
* into a consistent PermissionConfig object with default values applied.
*
* @param {PermissionInput} permission - Permission input in any supported format
* @returns {PermissionConfig} Normalized permission configuration with default mode and optional biz params
*
* @example
* ```typescript
* // String input
* normalizePermissionConfig('user.edit')
* // Returns: { code: 'user.edit', mode: 'all' }
*
* // Array input
* normalizePermissionConfig(['user.edit', 'user.delete'])
* // Returns: { code: ['user.edit', 'user.delete'], mode: 'all' }
*
* // Full config (returned as-is)
* normalizePermissionConfig({ code: 'user.edit', mode: 'any', biz: { userId: '123' } })
* // Returns: { code: 'user.edit', mode: 'any', biz: { userId: '123' } }
* ```
*/
declare function normalizePermissionConfig(permission: PermissionInput): PermissionConfig;
/**
* Normalize permission result to boolean format
*
* Converts permission service results from various formats (boolean or number)
* to a standardized boolean value. Supports both boolean and numeric (0/1) results.
*
* @param {PermissionResult} result - Permission result from service (boolean or number)
* @returns {boolean} Normalized boolean result (true = has permission, false = no permission)
*
* @example
* ```typescript
* // Boolean inputs
* normalizePermissionResult(true) // Returns: true
* normalizePermissionResult(false) // Returns: false
*
* // Numeric inputs (commonly used by some backend APIs)
* normalizePermissionResult(1) // Returns: true
* normalizePermissionResult(0) // Returns: false
* ```
*/
declare function normalizePermissionResult(result: PermissionResult): boolean;
/**
* Batch normalize permission results
*/
declare function normalizePermissionResults(results: PermissionResult[]): boolean[];
/**
* Create permission cache key
*/
declare function createPermissionCacheKey(config: PermissionConfig): string;
/**
* Create permission error and throw
*
* Simplified exception creation function that only creates exceptions without handling
* Exceptions will be globally caught and handled by @seed-fe/exception-handler
*/
declare function createPermissionError(message: string, packageName: string, config?: PermissionConfig, originalError?: unknown): PermissionError;
export { BATCH_CONFIG, CACHE_CONFIG, type CacheItem, type CheckPermissionOptions, PERMISSION_BATCH_ENDPOINT, PERMISSION_CHECK_MODES, type PermissionConfig, PermissionError, type PermissionInput, type PermissionResult, type PermissionServiceFn, type PermissionServiceOptions, checkPermission, clearPermissionCache, configurePermission, checkPermission$1 as coreCheckPermission, createPermissionCacheKey, createPermissionError, getPermissionStats, normalizePermissionConfig, normalizePermissionResult, normalizePermissionResults, registerPermissionService };