Move input accessors to Jint service to control order
This commit is contained in:
parent
9416461f78
commit
46c9a76259
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Configures the JavaScript engine with workflow input getters.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class WorkflowDefinitionActivityJavaScriptHandler : INotificationHandler<EvaluatingJavaScript>
|
||||
{
|
||||
private readonly IActivityRegistry _activityRegistry;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public WorkflowDefinitionActivityJavaScriptHandler(IActivityRegistry activityRegistry, IExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
_activityRegistry = activityRegistry;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<object?>)(() => 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<object?>)(() => block.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,6 +68,9 @@ public class JintJavaScriptEvaluator : IJavaScriptEvaluator
|
|||
engine.SetValue("getOutputFrom", (Func<string, string?, object?>)((activityIdOrNodeId, outputName) => GetOutput(context, activityIdOrNodeId, outputName)));
|
||||
engine.SetValue("getLastResult", (Func<object?>)(() => 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<object?>)(() => 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<object?>)(() => block.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateVariableAccessors(Engine engine, ExpressionExecutionContext context)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<IActivityRegistry>();
|
||||
var expressionEvaluatorMock = new Mock<IExpressionEvaluator>();
|
||||
_handler = new WorkflowDefinitionActivityJavaScriptHandler(activityRegistryMock.Object, expressionEvaluatorMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue