using System; using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; using Elsa.Scripting.JavaScript.Messages; using Jint; using Jint.Runtime.Interop; using MediatR; using NodaTime; namespace Elsa.Scripting.JavaScript.Handlers { public class ConfigureJavaScriptEngine : INotificationHandler { public Task Handle(EvaluatingJavaScriptExpression notification, CancellationToken cancellationToken) { var activityContext = notification.ActivityExecutionContext; var workflowExecutionContext = activityContext.WorkflowExecutionContext; var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint; var workflowInstance = workflowExecutionContext.WorkflowInstance; var engine = notification.Engine; // Global functions. engine.SetValue("guid", (Func) (() => Guid.NewGuid().ToString())); // Global variables. engine.SetValue("input", activityContext.Input); engine.SetValue("correlationId", workflowInstance.CorrelationId); engine.SetValue("currentCulture", CultureInfo.InvariantCulture); // NodaTime types. RegisterType(engine); RegisterType(engine); RegisterType(engine); RegisterType(engine); RegisterType(engine); RegisterType(engine); var variables = workflowExecutionContext.WorkflowInstance.Variables; // Add workflow variables. foreach (var variable in variables.Data) engine.SetValue(variable.Key, variable.Value); // Add activity outputs. foreach (var activity in workflowBlueprint.Activities.Where(x => x.Name is not null and not "" && workflowInstance.ActivityOutput.ContainsKey(x.Name))) engine.SetValue(activity.Name, workflowInstance.ActivityOutput[activity.Name!]); return Task.CompletedTask; } private void RegisterType(Engine engine) => engine.SetValue(typeof(T).Name, TypeReference.CreateTypeReference(engine, typeof(T))); } }