Base classes and interfaces for the MemberJunction Actions framework. This library provides the foundational components for implementing and executing actions across both server and client environments.
The Actions framework in MemberJunction provides a flexible, metadata-driven system for executing business logic and operations. This base package contains the core classes and interfaces that enable:
npm install @memberjunction/actions-base
The singleton base class that manages all action metadata and provides the foundation for action execution.
import { ActionEngineBase } from '@memberjunction/actions-base';
// Get the singleton instance
const actionEngine = ActionEngineBase.Instance;
// Configure the engine (required before use)
await actionEngine.Config(false, userInfo);
// Access action metadata
const allActions = actionEngine.Actions;
const coreActions = actionEngine.CoreActions;
const actionParams = actionEngine.ActionParams;
const actionFilters = actionEngine.ActionFilters;
Manages entity-specific actions and their various invocation contexts (single record, view-based, list-based).
import { EntityActionEngineBase } from '@memberjunction/actions-base';
// Get the singleton instance
const entityActionEngine = EntityActionEngineBase.Instance;
// Configure the engine
await entityActionEngine.Config(false, userInfo);
// Get actions for a specific entity
const customerActions = entityActionEngine.GetActionsByEntityName('Customers', 'Active');
// Get actions by invocation type
const viewActions = entityActionEngine.GetActionsByEntityNameAndInvocationType(
'Orders',
'View',
'Active'
);
Represents input/output parameters for actions:
import { ActionParam } from '@memberjunction/actions-base';
const param: ActionParam = {
Name: 'CustomerID',
Value: '12345',
Type: 'Input' // 'Input' | 'Output' | 'Both'
};
Configuration for running an action:
import { RunActionParams } from '@memberjunction/actions-base';
const runParams: RunActionParams = {
Action: actionEntity,
ContextUser: userInfo,
SkipActionLog: false, // Optional
Filters: [], // Optional filters to run before action
Params: [
{ Name: 'Input1', Value: 'test', Type: 'Input' }
]
};
RunActionParams now supports type-safe context propagation:
import { RunActionParams } from '@memberjunction/actions-base';
// Define your context type
interface MyActionContext {
apiEndpoint: string;
apiKey: string;
environment: 'dev' | 'staging' | 'prod';
featureFlags: Record<string, boolean>;
}
// Create typed parameters
const runParams = new RunActionParams<MyActionContext>();
runParams.Action = actionEntity;
runParams.ContextUser = userInfo;
runParams.Params = [
{ Name: 'customerID', Value: 'CUST123', Type: 'Input' },
{ Name: 'orderAmount', Value: 150.00, Type: 'Input' }
];
// Set typed context
runParams.Context = {
apiEndpoint: 'https://api.example.com',
apiKey: process.env.API_KEY,
environment: 'prod',
featureFlags: {
newFeature: true,
betaAccess: false
}
};
The context object is:
The result object returned from action execution:
import { ActionResult } from '@memberjunction/actions-base';
// ActionResult contains:
// - Success: boolean indicating if action succeeded
// - Result: ActionResultCodeEntity with the specific result code
// - LogEntry: ActionExecutionLogEntity for tracking
// - Message: Optional message about the outcome
// - Params: All parameters including outputs
Parameters for invoking entity-specific actions:
import { EntityActionInvocationParams } from '@memberjunction/actions-base';
const invocationParams: EntityActionInvocationParams = {
EntityAction: entityActionExtended,
InvocationType: invocationTypeEntity,
ContextUser: userInfo,
// One of these based on invocation type:
EntityObject: customerEntity, // For single record
ViewID: 'view-123', // For view-based
ListID: 'list-456' // For list-based
};
Enhanced action entity with additional functionality:
import { ActionEntityExtended } from '@memberjunction/actions-base';
// Provides additional properties:
const action = actionEngine.Actions[0] as ActionEntityExtended;
console.log(action.IsCoreAction); // true if core MJ action
console.log(action.ProgrammaticName); // Code-friendly name
console.log(action.ResultCodes); // Possible result codes
console.log(action.Params); // Action parameters
console.log(action.Libraries); // Required libraries
Enhanced entity action with related data:
import { EntityActionEntityExtended } from '@memberjunction/actions-base';
// Provides lazy-loaded related data:
const entityAction = entityActionEngine.EntityActions[0] as EntityActionEntityExtended;
console.log(entityAction.Filters); // Associated filters
console.log(entityAction.Invocations); // Invocation configurations
console.log(entityAction.Params); // Action parameters
The framework includes support for generated code with library tracking:
import { GeneratedCode, ActionLibrary } from '@memberjunction/actions-base';
// GeneratedCode structure
const generatedCode: GeneratedCode = {
Success: true,
Code: 'function execute() { ... }',
LibrariesUsed: [
{
LibraryName: 'lodash',
ItemsUsed: ['map', 'filter']
}
],
Comments: 'Processes customer data',
ErrorMessage: undefined
};
import { ActionEngineBase } from '@memberjunction/actions-base';
import { UserInfo } from '@memberjunction/core';
async function initializeActionEngine(user: UserInfo) {
const engine = ActionEngineBase.Instance;
// Initial configuration
await engine.Config(false, user);
// Force refresh if needed
await engine.Config(true, user);
// Access loaded metadata
console.log(`Loaded ${engine.Actions.length} actions`);
console.log(`Core actions: ${engine.CoreActions.length}`);
}
import { EntityActionEngineBase } from '@memberjunction/actions-base';
async function getEntityActions(entityName: string, user: UserInfo) {
const engine = EntityActionEngineBase.Instance;
await engine.Config(false, user);
// Get all active actions for an entity
const actions = engine.GetActionsByEntityName(entityName, 'Active');
// Filter by invocation type
const singleRecordActions = actions.filter(a =>
a.Invocations.some(i => i.InvocationType === 'Single Record')
);
return singleRecordActions;
}
import { ActionParam } from '@memberjunction/actions-base';
function prepareActionParams(inputs: Record<string, any>): ActionParam[] {
return Object.entries(inputs).map(([name, value]) => ({
Name: name,
Value: value,
Type: 'Input'
}));
}
// Example usage
const params = prepareActionParams({
CustomerID: '123',
OrderDate: new Date(),
TotalAmount: 150.00
});
Context provides runtime-specific information separate from business parameters:
import { RunActionParams } from '@memberjunction/actions-base';
interface ServiceContext {
apiEndpoint: string;
apiKey: string;
timeout: number;
retryPolicy: {
maxRetries: number;
backoffMs: number;
};
}
async function executeActionWithContext(
action: ActionEntity,
businessParams: ActionParam[],
context: ServiceContext,
user: UserInfo
) {
const runParams = new RunActionParams<ServiceContext>();
runParams.Action = action;
runParams.ContextUser = user;
runParams.Params = businessParams;
runParams.Context = context;
// The action implementation can access context via this.ContextObject
// This is useful for:
// - API configurations that vary by environment
// - Runtime credentials not stored in metadata
// - Session-specific settings
// - Feature flags and toggles
const result = await actionEngine.RunAction(runParams);
return result;
}
@memberjunction/global: Global utilities and registration system@memberjunction/core: Core MemberJunction interfaces and base classes@memberjunction/core-entities: Entity definitions for MemberJunction metadataThis package serves as the foundation for:
@memberjunction/actions-server: Server-side action execution implementation@memberjunction/actions-client: Client-side action executionConfig() on the engine instances before accessing any metadata.Instance property to get engine instancesThis package is written in TypeScript and provides full type definitions. All classes and interfaces are properly typed for optimal development experience.
ISC License - see LICENSE file in the root of the repository.