@memberjunction/actions 2.42.1 → 2.44.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/package.json +8 -8
- package/readme.md +341 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/actions",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.44.0",
|
|
4
4
|
"description": "Main library for MemberJunction Actions. This library is only intended to be imported on the server side.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"typescript": "^5.4.5"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@memberjunction/global": "2.
|
|
23
|
-
"@memberjunction/core": "2.
|
|
24
|
-
"@memberjunction/actions-base": "2.
|
|
25
|
-
"@memberjunction/core-entities": "2.
|
|
26
|
-
"@memberjunction/ai": "2.
|
|
27
|
-
"@memberjunction/aiengine": "2.
|
|
28
|
-
"@memberjunction/doc-utils": "2.
|
|
22
|
+
"@memberjunction/global": "2.44.0",
|
|
23
|
+
"@memberjunction/core": "2.44.0",
|
|
24
|
+
"@memberjunction/actions-base": "2.44.0",
|
|
25
|
+
"@memberjunction/core-entities": "2.44.0",
|
|
26
|
+
"@memberjunction/ai": "2.44.0",
|
|
27
|
+
"@memberjunction/aiengine": "2.44.0",
|
|
28
|
+
"@memberjunction/doc-utils": "2.44.0"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/readme.md
CHANGED
|
@@ -1,6 +1,344 @@
|
|
|
1
1
|
# @memberjunction/actions
|
|
2
2
|
|
|
3
|
-
The `@memberjunction/actions` library provides
|
|
3
|
+
The `@memberjunction/actions` library provides the core server-side infrastructure for the MemberJunction Actions Framework. It includes base classes for actions and filters, the action execution engine, and support for entity-specific actions.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Actions Framework is a powerful system for creating reusable, parameterized business logic that can be executed on demand. Actions are "verbs" in the MemberJunction ecosystem - they perform specific tasks and can be triggered through various mechanisms including entity events, API calls, or scheduled jobs.
|
|
8
|
+
|
|
9
|
+
**IMPORTANT:** This library should only be imported on the server side.
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Action Engine**: Central execution engine for running actions with parameter validation, filtering, and logging
|
|
14
|
+
- **Entity Actions**: Actions that can be triggered on entity lifecycle events (create, update, delete)
|
|
15
|
+
- **Code Generation**: AI-powered automatic code generation for actions based on natural language prompts
|
|
16
|
+
- **Action Filters**: Pre-execution filters to control when actions should run
|
|
17
|
+
- **Transaction Support**: Built-in transaction management for complex multi-step operations
|
|
18
|
+
- **Comprehensive Logging**: Automatic logging of all action executions with parameters and results
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @memberjunction/actions
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Dependencies
|
|
27
|
+
|
|
28
|
+
This package depends on several other MemberJunction packages:
|
|
29
|
+
- `@memberjunction/global` - Global utilities and class factory
|
|
30
|
+
- `@memberjunction/core` - Core MJ functionality and base classes
|
|
31
|
+
- `@memberjunction/actions-base` - Base types and interfaces for actions
|
|
32
|
+
- `@memberjunction/core-entities` - Entity definitions
|
|
33
|
+
- `@memberjunction/ai` - AI integration capabilities
|
|
34
|
+
- `@memberjunction/aiengine` - AI engine functionality
|
|
35
|
+
- `@memberjunction/doc-utils` - Documentation utilities
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Creating a Custom Action
|
|
40
|
+
|
|
41
|
+
To create a custom action, extend the `BaseAction` class and implement the `InternalRunAction` method:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
45
|
+
import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
46
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
47
|
+
|
|
48
|
+
@RegisterClass(BaseAction, 'MyCustomAction')
|
|
49
|
+
export class MyCustomAction extends BaseAction {
|
|
50
|
+
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
|
|
51
|
+
// Access input parameters
|
|
52
|
+
const inputParam = params.Params.find(p => p.Name === 'InputValue');
|
|
53
|
+
|
|
54
|
+
// Perform your action logic
|
|
55
|
+
const result = await this.performBusinessLogic(inputParam?.Value);
|
|
56
|
+
|
|
57
|
+
// Return the result
|
|
58
|
+
return {
|
|
59
|
+
Success: true,
|
|
60
|
+
ResultCode: 'SUCCESS',
|
|
61
|
+
Message: 'Action completed successfully',
|
|
62
|
+
Params: params.Params // Include any output parameters
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private async performBusinessLogic(value: any): Promise<any> {
|
|
67
|
+
// Your custom logic here
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Running Actions with ActionEngine
|
|
74
|
+
|
|
75
|
+
The `ActionEngineServer` class provides the main interface for executing actions:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { ActionEngineServer } from '@memberjunction/actions';
|
|
79
|
+
import { RunActionParams } from '@memberjunction/actions-base';
|
|
80
|
+
|
|
81
|
+
// Get the singleton instance
|
|
82
|
+
const engine = ActionEngineServer.Instance;
|
|
83
|
+
|
|
84
|
+
// Configure the engine (only needs to be done once)
|
|
85
|
+
await engine.Config(false, currentUser);
|
|
86
|
+
|
|
87
|
+
// Run an action by ID
|
|
88
|
+
const result = await engine.RunActionByID({
|
|
89
|
+
ActionID: 'your-action-id',
|
|
90
|
+
ContextUser: currentUser,
|
|
91
|
+
Params: [
|
|
92
|
+
{ Name: 'InputParam', Value: 'some value', Type: 'string' }
|
|
93
|
+
]
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Run an action with full parameters
|
|
97
|
+
const params: RunActionParams = {
|
|
98
|
+
Action: actionEntity, // ActionEntity instance
|
|
99
|
+
ContextUser: currentUser,
|
|
100
|
+
Filters: [], // Optional filters
|
|
101
|
+
Params: [
|
|
102
|
+
{ Name: 'InputParam', Value: 'some value', Type: 'string' }
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const result = await engine.RunAction(params);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Entity Actions
|
|
110
|
+
|
|
111
|
+
Entity Actions are triggered automatically during entity lifecycle events. To work with entity actions, use the `EntityActionEngineServer`:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { EntityActionEngineServer } from '@memberjunction/actions';
|
|
115
|
+
import { EntityActionInvocationParams } from '@memberjunction/actions-base';
|
|
116
|
+
|
|
117
|
+
const entityActionEngine = EntityActionEngineServer.Instance;
|
|
118
|
+
|
|
119
|
+
// Run an entity action
|
|
120
|
+
const params: EntityActionInvocationParams = {
|
|
121
|
+
EntityAction: entityActionEntity,
|
|
122
|
+
InvocationType: invocationTypeEntity, // e.g., 'BeforeCreate', 'AfterUpdate'
|
|
123
|
+
EntityObject: entityInstance,
|
|
124
|
+
ContextUser: currentUser
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const result = await entityActionEngine.RunEntityAction(params);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Creating Custom Action Filters
|
|
131
|
+
|
|
132
|
+
Action filters determine whether an action should run. Create custom filters by extending `BaseActionFilter`:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { BaseActionFilter } from '@memberjunction/actions';
|
|
136
|
+
import { RunActionParams } from '@memberjunction/actions-base';
|
|
137
|
+
import { ActionFilterEntity } from '@memberjunction/core-entities';
|
|
138
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
139
|
+
|
|
140
|
+
@RegisterClass(BaseActionFilter, 'MyCustomFilter')
|
|
141
|
+
export class MyCustomFilter extends BaseActionFilter {
|
|
142
|
+
protected async InternalRun(
|
|
143
|
+
params: RunActionParams,
|
|
144
|
+
filter: ActionFilterEntity
|
|
145
|
+
): Promise<boolean> {
|
|
146
|
+
// Implement your filter logic
|
|
147
|
+
// Return true to allow action execution, false to skip
|
|
148
|
+
return params.ContextUser.IsActive === true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## API Reference
|
|
154
|
+
|
|
155
|
+
### Classes
|
|
156
|
+
|
|
157
|
+
#### ActionEngineServer
|
|
158
|
+
|
|
159
|
+
The main engine for executing actions.
|
|
160
|
+
|
|
161
|
+
**Methods:**
|
|
162
|
+
- `RunAction(params: RunActionParams): Promise<ActionResult>` - Executes an action with full control over parameters
|
|
163
|
+
- `RunActionByID(params: RunActionByNameParams): Promise<ActionResult>` - Convenience method to run an action by its ID
|
|
164
|
+
- `Config(forceRefresh?: boolean, contextUser?: UserInfo): Promise<void>` - Configures the engine (inherited from base)
|
|
165
|
+
|
|
166
|
+
#### BaseAction
|
|
167
|
+
|
|
168
|
+
Abstract base class for all actions.
|
|
169
|
+
|
|
170
|
+
**Methods:**
|
|
171
|
+
- `Run(params: RunActionParams): Promise<ActionResultSimple>` - Public method called by the engine
|
|
172
|
+
- `InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>` - Abstract method to implement action logic
|
|
173
|
+
|
|
174
|
+
#### EntityActionEngineServer
|
|
175
|
+
|
|
176
|
+
Engine specifically for entity-related actions.
|
|
177
|
+
|
|
178
|
+
**Methods:**
|
|
179
|
+
- `RunEntityAction(params: EntityActionInvocationParams): Promise<EntityActionResult>` - Executes an entity action
|
|
180
|
+
|
|
181
|
+
#### BaseActionFilter
|
|
182
|
+
|
|
183
|
+
Abstract base class for action filters.
|
|
184
|
+
|
|
185
|
+
**Methods:**
|
|
186
|
+
- `Run(params: RunActionParams, filter: ActionFilterEntity): Promise<boolean>` - Public method called by the engine
|
|
187
|
+
- `InternalRun(params: RunActionParams, filter: ActionFilterEntity): Promise<boolean>` - Abstract method to implement filter logic
|
|
188
|
+
|
|
189
|
+
#### ActionEntityServerEntity
|
|
190
|
+
|
|
191
|
+
Server-side entity class for Actions with AI-powered code generation.
|
|
192
|
+
|
|
193
|
+
**Key Features:**
|
|
194
|
+
- Automatic code generation from natural language prompts
|
|
195
|
+
- Code validation and improvement through AI
|
|
196
|
+
- Library dependency management
|
|
197
|
+
- Transaction-safe save operations
|
|
198
|
+
|
|
199
|
+
### Types and Interfaces
|
|
200
|
+
|
|
201
|
+
The package exports all types from `@memberjunction/actions-base`, including:
|
|
202
|
+
|
|
203
|
+
- `RunActionParams` - Parameters for running an action
|
|
204
|
+
- `ActionResult` - Detailed result of action execution
|
|
205
|
+
- `ActionResultSimple` - Simplified action result
|
|
206
|
+
- `ActionParam` - Parameter definition for actions
|
|
207
|
+
- `EntityActionInvocationParams` - Parameters for entity actions
|
|
208
|
+
- `EntityActionResult` - Result of entity action execution
|
|
209
|
+
|
|
210
|
+
## Entity Action Invocation Types
|
|
211
|
+
|
|
212
|
+
The framework supports various invocation types for entity actions:
|
|
213
|
+
|
|
214
|
+
### Single Record Operations
|
|
215
|
+
- `Read` - Triggered when reading an entity
|
|
216
|
+
- `BeforeCreate` - Before creating a new record
|
|
217
|
+
- `AfterCreate` - After creating a new record
|
|
218
|
+
- `BeforeUpdate` - Before updating a record
|
|
219
|
+
- `AfterUpdate` - After updating a record
|
|
220
|
+
- `BeforeDelete` - Before deleting a record
|
|
221
|
+
- `AfterDelete` - After deleting a record
|
|
222
|
+
|
|
223
|
+
### Multiple Record Operations
|
|
224
|
+
- `List` - Actions operating on a list of records
|
|
225
|
+
- `View` - Actions operating on records from a view
|
|
226
|
+
|
|
227
|
+
### Validation
|
|
228
|
+
- `Validate` - Special invocation type for validation logic
|
|
229
|
+
|
|
230
|
+
## Code Generation
|
|
231
|
+
|
|
232
|
+
The framework includes sophisticated AI-powered code generation capabilities:
|
|
233
|
+
|
|
234
|
+
1. **Natural Language Input**: Define action behavior using plain English in the `UserPrompt` field
|
|
235
|
+
2. **Automatic Code Generation**: The system generates TypeScript code based on your prompt
|
|
236
|
+
3. **Code Validation**: Generated code is automatically validated and improved
|
|
237
|
+
4. **Library Management**: Automatic tracking and importing of required libraries
|
|
238
|
+
|
|
239
|
+
Example workflow:
|
|
240
|
+
```typescript
|
|
241
|
+
// In your database, create an Action record with:
|
|
242
|
+
// Name: "SendWelcomeEmail"
|
|
243
|
+
// Type: "Generated"
|
|
244
|
+
// UserPrompt: "Send a welcome email to a new user with their name and registration date"
|
|
245
|
+
|
|
246
|
+
// The system will automatically generate the implementation code
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Best Practices
|
|
250
|
+
|
|
251
|
+
1. **Action Naming**: Use clear, descriptive names for actions (e.g., `SendInvoiceEmail`, `CalculateOrderTotal`)
|
|
252
|
+
|
|
253
|
+
2. **Parameter Design**: Design action parameters to be reusable and flexible:
|
|
254
|
+
```typescript
|
|
255
|
+
params: [
|
|
256
|
+
{ Name: 'EmailTemplate', Type: 'string', ValueType: 'Scalar' },
|
|
257
|
+
{ Name: 'RecipientUser', Type: 'User', ValueType: 'BaseEntity Sub-Class' },
|
|
258
|
+
{ Name: 'EmailSent', Type: 'boolean', ValueType: 'Scalar', IsInput: false }
|
|
259
|
+
]
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
3. **Error Handling**: Always include proper error handling in your actions:
|
|
263
|
+
```typescript
|
|
264
|
+
try {
|
|
265
|
+
// Action logic
|
|
266
|
+
return { Success: true, ResultCode: 'SUCCESS', Message: 'Completed' };
|
|
267
|
+
} catch (error) {
|
|
268
|
+
return { Success: false, ResultCode: 'ERROR', Message: error.message };
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
4. **Logging**: The framework automatically logs action executions, but include additional logging for debugging:
|
|
273
|
+
```typescript
|
|
274
|
+
import { LogError, LogStatus } from '@memberjunction/core';
|
|
275
|
+
|
|
276
|
+
LogStatus('Starting custom action processing...');
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
5. **Transaction Management**: Use transaction groups for multi-step operations:
|
|
280
|
+
```typescript
|
|
281
|
+
const tg = await metadata.CreateTransactionGroup();
|
|
282
|
+
try {
|
|
283
|
+
// Multiple operations
|
|
284
|
+
await tg.Submit();
|
|
285
|
+
} catch (error) {
|
|
286
|
+
// Automatic rollback on error
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Integration with Other MJ Packages
|
|
291
|
+
|
|
292
|
+
This package integrates seamlessly with:
|
|
293
|
+
|
|
294
|
+
- **@memberjunction/core**: Provides base entity functionality and metadata access
|
|
295
|
+
- **@memberjunction/ai**: Enables AI-powered code generation
|
|
296
|
+
- **@memberjunction/core-entities**: Provides strongly-typed entity classes
|
|
297
|
+
- **@memberjunction/global**: Manages class registration and instantiation
|
|
298
|
+
|
|
299
|
+
## Advanced Topics
|
|
300
|
+
|
|
301
|
+
### Custom Action Engines
|
|
302
|
+
|
|
303
|
+
You can create custom action engines by extending `ActionEngineServer`:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
@RegisterClass(BaseEngine, 'ActionEngineBase', 1) // Higher priority
|
|
307
|
+
export class CustomActionEngine extends ActionEngineServer {
|
|
308
|
+
protected async ValidateInputs(params: RunActionParams): Promise<boolean> {
|
|
309
|
+
// Custom validation logic
|
|
310
|
+
return super.ValidateInputs(params);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
protected async RunFilters(params: RunActionParams): Promise<boolean> {
|
|
314
|
+
// Custom filter logic
|
|
315
|
+
return super.RunFilters(params);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Script Evaluation in Entity Actions
|
|
321
|
+
|
|
322
|
+
Entity actions support dynamic script evaluation for parameter mapping:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
// In EntityActionParam configuration:
|
|
326
|
+
{
|
|
327
|
+
ValueType: 'Script',
|
|
328
|
+
Value: `
|
|
329
|
+
const user = EntityActionContext.entityObject;
|
|
330
|
+
EntityActionContext.result = user.Email.toUpperCase();
|
|
331
|
+
`
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Troubleshooting
|
|
336
|
+
|
|
337
|
+
1. **Action Not Found**: Ensure your action class is properly registered with `@RegisterClass`
|
|
338
|
+
2. **Code Generation Fails**: Check that AI models are configured and API keys are set
|
|
339
|
+
3. **Filter Not Running**: Verify filter is associated with the action in metadata
|
|
340
|
+
4. **Entity Action Not Triggering**: Confirm invocation type matches the entity operation
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
This package is part of the MemberJunction ecosystem. See the main repository for license information.
|