@mbiondo/actions-manager
v1.0.9
Published
This library is designed to manage user actions on entities based on context, leveraging the power of TypeScript generics.
Downloads
14
Maintainers
Readme
Actions Manager
A TypeScript library designed to manage user actions on entities, with policies that define whether an action can be executed based on the current context.
Features
- Policy-based action management.
- Add, remove, and set actions dynamically.
- Execute actions based on user context and policies.
Installation
Install the package via npm:
npm install @mbiondo/actions-manager
Or via yarn:
yarn add @mbiondo/actions-manager
Basic Usage
1. Defining the Context and Action Parameters
First, define your app-specific context and action parameters by extending IContext
and IActionParam
:
import { IContext, IActionParam } from '@mbiondo/actions-manager';
interface AppContext extends IContext {
user: { role: string; permissions: string[] };
document: { ownerId: number; status: string };
}
interface AppActionParams extends IActionParam {
docId: number;
}
2. Defining Actions and Policies
Actions must be associated with one or more policies that test the current context. Here’s an example of how to define actions and set policies:
import { ActionManager, IAction, IPolicy } from '@mbiondo/actions-manager';
const editPolicy: IPolicy<AppContext> = {
test: async (context) => context.user.permissions.includes('edit')
};
const deletePolicy: IPolicy<AppContext> = {
test: async (context) => context.user.role === 'admin'
};
const actions: IAction<AppContext, AppActionParams>[] = [
{ id: 'edit', name: 'Edit Document', policies: editPolicy, exec: async (params) => {/* logic */} },
{ id: 'delete', name: 'Delete Document', policies: deletePolicy, exec: async (params) => {/* logic */} }
];
3. Setting Up the Action Manager
Create an instance of the ActionManager
, passing your custom context and action parameters types:
const context: AppContext = {
user: { role: 'admin', permissions: ['edit', 'delete'] },
document: { ownerId: 1, status: 'draft' }
};
const actionManager = new ActionManager<AppContext, AppActionParams>();
actionManager.setActions(actions);
actionManager.setContext(context);
4. Checking Permissions
You can verify whether an action can be executed based on the associated policies by using canExecute
:
const canEdit = await actionManager.canExecute('edit');
console.log(canEdit); // true if the context passes the 'edit' policy
5. Executing Actions
To execute an action, you call the execute
method, passing the action ID and the necessary parameters:
const params: AppActionParams = { docId: 123 };
const result = await actionManager.execute('edit', params);
console.log('Edit action executed:', result);
API Reference
ActionManager<T extends IContext, V extends IActionParam>
Properties:
actions: IAction<T, V>[]
- The list of available actions.context: T
- The current context, which is used by the policies to validate actions.
Methods:
setContext(context: T): void
- Sets the current context.getContext(): T
- Returns the current context.addAction(action: IAction<T, V>): void
- Adds a new action.setActions(actions: IAction<T, V>[]): void
- Sets the list of available actions.getActions(): IAction<T, V>[]
- Returns the list of actions.canExecute(actionID: string): Promise<boolean>
- Checks if the action can be executed based on policies.execute<R>(actionID: string, params: V): Promise<R>
- Executes an action and returns the result.
IAction<T extends IContext, V extends IActionParam>
Represents an action that can be executed.
interface IAction<T extends IContext = IContext, V extends IActionParam = IActionParam> {
id: unknown;
name?: string;
policies: IPolicy<T> | IPolicy<T>[] | IPolicy<T>[][] | null;
exec: (params: V) => Promise<unknown>;
}
IPolicy<T extends IContext>
Defines a policy that tests the context to determine if an action can be executed.
interface IPolicy<T extends IContext = IContext> {
test(context: T): Promise<boolean>;
}
Contributing
Feel free to submit issues or pull requests to improve the library.
License
This project is licensed under the MIT License - see the LICENSE file for details.