From 46c9a76259ee392bef1fa2b382e5a76f22dbd652 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 22 Aug 2023 14:59:31 +0200 Subject: [PATCH] Move input accessors to Jint service to control order --- ...flowDefinitionActivityJavaScriptHandler.cs | 70 ------------------- .../Services/JintJavaScriptEvaluator.cs | 32 +++++++++ ...efinitionActivityJavaScriptHandlerTests.cs | 13 ---- 3 files changed, 32 insertions(+), 83 deletions(-) delete mode 100644 src/modules/Elsa.JavaScript/Handlers/WorkflowDefinitionActivityJavaScriptHandler.cs diff --git a/src/modules/Elsa.JavaScript/Handlers/WorkflowDefinitionActivityJavaScriptHandler.cs b/src/modules/Elsa.JavaScript/Handlers/WorkflowDefinitionActivityJavaScriptHandler.cs deleted file mode 100644 index 8881ab57b..000000000 --- a/src/modules/Elsa.JavaScript/Handlers/WorkflowDefinitionActivityJavaScriptHandler.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Elsa.Expressions.Contracts; -using Elsa.Expressions.Models; -using Elsa.Extensions; -using Elsa.JavaScript.Notifications; -using Elsa.Mediator.Contracts; -using Elsa.Workflows.Core.Contracts; -using Elsa.Workflows.Core.Memory; -using Humanizer; -using JetBrains.Annotations; -using Jint; - -namespace Elsa.JavaScript.Handlers; - -/// -/// Configures the JavaScript engine with workflow input getters. -/// -[PublicAPI] -public class WorkflowDefinitionActivityJavaScriptHandler : INotificationHandler -{ - private readonly IActivityRegistry _activityRegistry; - - /// - /// Constructor. - /// - public WorkflowDefinitionActivityJavaScriptHandler(IActivityRegistry activityRegistry, IExpressionEvaluator expressionEvaluator) - { - _activityRegistry = activityRegistry; - } - - /// - public Task HandleAsync(EvaluatingJavaScript notification, CancellationToken cancellationToken) - { - var engine = notification.Engine; - var context = notification.Context; - - // Create workflow input accessors. - CreateWorkflowInputAccessors(engine, context); - - return Task.CompletedTask; - } - - private void CreateWorkflowInputAccessors(Engine engine, ExpressionExecutionContext context) - { - if(context.TryGetWorkflowExecutionContext(out var workflowExecutionContext)) - { - var input = workflowExecutionContext.Input; - - foreach (var inputEntry in input) - { - var inputPascalName = inputEntry.Key.Pascalize(); - var inputValue = inputEntry.Value; - engine.SetValue($"get{inputPascalName}", (Func)(() => inputValue)); - } - } - else - { - // We end up here when we are evaluating an expression during trigger indexing. - // Typically, a workflow definition might have variables declared, that we want to be able to access from JavaScript expressions. - foreach(var block in context.Memory.Blocks.Values) - { - if(block.Metadata is not VariableBlockMetadata variableBlockMetadata) - continue; - - var variable = variableBlockMetadata.Variable; - var variablePascaleName = variable.Name.Pascalize(); - engine.SetValue($"get{variablePascaleName}", (Func)(() => block.Value)); - } - } - } -} \ No newline at end of file diff --git a/src/modules/Elsa.JavaScript/Services/JintJavaScriptEvaluator.cs b/src/modules/Elsa.JavaScript/Services/JintJavaScriptEvaluator.cs index 4c8a26463..a18e31c7d 100644 --- a/src/modules/Elsa.JavaScript/Services/JintJavaScriptEvaluator.cs +++ b/src/modules/Elsa.JavaScript/Services/JintJavaScriptEvaluator.cs @@ -68,6 +68,9 @@ public class JintJavaScriptEvaluator : IJavaScriptEvaluator engine.SetValue("getOutputFrom", (Func)((activityIdOrNodeId, outputName) => GetOutput(context, activityIdOrNodeId, outputName))); engine.SetValue("getLastResult", (Func)(() => GetLastResult(context))); + // Create workflow input accessors. + CreateWorkflowInputAccessors(engine, context); + // Create variable getters and setters for each variable. CreateVariableAccessors(engine, context); @@ -117,6 +120,35 @@ public class JintJavaScriptEvaluator : IJavaScriptEvaluator var outputRecord = filteredOutputRecordCandidates.FirstOrDefault(); return outputRecord?.Value; } + + private void CreateWorkflowInputAccessors(Engine engine, ExpressionExecutionContext context) + { + if(context.TryGetWorkflowExecutionContext(out var workflowExecutionContext)) + { + var input = workflowExecutionContext.Input; + + foreach (var inputEntry in input) + { + var inputPascalName = inputEntry.Key.Pascalize(); + var inputValue = inputEntry.Value; + engine.SetValue($"get{inputPascalName}", (Func)(() => inputValue)); + } + } + else + { + // We end up here when we are evaluating an expression during trigger indexing. + // The scenario being that a workflow definition might have variables declared, that we want to be able to access from JavaScript expressions. + foreach(var block in context.Memory.Blocks.Values) + { + if(block.Metadata is not VariableBlockMetadata variableBlockMetadata) + continue; + + var variable = variableBlockMetadata.Variable; + var variablePascaleName = variable.Name.Pascalize(); + engine.SetValue($"get{variablePascaleName}", (Func)(() => block.Value)); + } + } + } private static void CreateVariableAccessors(Engine engine, ExpressionExecutionContext context) { diff --git a/test/unit/Elsa.JavaScript.UnitTests/WorkflowDefinitionActivityJavaScriptHandlerTests.cs b/test/unit/Elsa.JavaScript.UnitTests/WorkflowDefinitionActivityJavaScriptHandlerTests.cs index 16d12fdf7..e809076e2 100644 --- a/test/unit/Elsa.JavaScript.UnitTests/WorkflowDefinitionActivityJavaScriptHandlerTests.cs +++ b/test/unit/Elsa.JavaScript.UnitTests/WorkflowDefinitionActivityJavaScriptHandlerTests.cs @@ -1,22 +1,9 @@ -using Elsa.Expressions.Contracts; -using Elsa.JavaScript.Handlers; -using Elsa.Workflows.Core.Contracts; -using Moq; using Xunit; namespace Elsa.JavaScript.UnitTests; public class WorkflowDefinitionActivityJavaScriptHandlerTests { - private readonly WorkflowDefinitionActivityJavaScriptHandler _handler; - - public WorkflowDefinitionActivityJavaScriptHandlerTests() - { - var activityRegistryMock = new Mock(); - var expressionEvaluatorMock = new Mock(); - _handler = new WorkflowDefinitionActivityJavaScriptHandler(activityRegistryMock.Object, expressionEvaluatorMock.Object); - } - [Fact] public void Test1() {