import { AsyncLocalStorage } from 'async_hooks'; export interface ContextData { eventId: string; eventType: string; } export interface ExecutionContext extends ContextData { startTime: string; } /** * SandboxContext manages the execution context for sandboxed code execution * using AsyncLocalStorage to maintain correlation between event and site information */ export class SandboxContext { private asyncLocalStorage: AsyncLocalStorage; constructor() { this.asyncLocalStorage = new AsyncLocalStorage(); } /** * Creates a new execution context with event and site information * @param {Object} contextData - The context data containing event and site information * @param {string} contextData.eventId - The unique identifier for the event * @param {string} contextData.eventType - The type of the event (e.g., 'customer_created') * @param {string} contextData.site - The site/tenant identifier in Chargebee * @param {Function} callback - The function to execute within this context * @returns {Promise} The result of the callback execution */ async run(contextData: ContextData, callback: () => Promise): Promise { const context: ExecutionContext = { eventId: contextData.eventId || 'unknown', eventType: contextData.eventType || 'unknown', startTime: new Date().toISOString(), }; return this.asyncLocalStorage.run(context, () => callback()); } /** * Gets the current execution context * @returns {Object|null} The current context or null if not in an execution context */ getCurrentContext(): ExecutionContext | undefined { return this.asyncLocalStorage.getStore(); } /** * Checks if there is an active execution context * @returns {boolean} True if there is an active context, false otherwise */ hasContext(): boolean { return this.asyncLocalStorage.getStore() !== undefined; } } // Create a singleton instance export const sandboxContext = new SandboxContext(); export default sandboxContext;