Add JS functions (#3492)

This commit is contained in:
Sipke Schoorstra 2022-11-30 21:52:41 +01:00 committed by GitHub
parent 6f429e9867
commit 1f3b849e68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 55 deletions

View file

@ -6,11 +6,9 @@ using Elsa.Features.Attributes;
using Elsa.Features.Services;
using Elsa.JavaScript.Activities;
using Elsa.JavaScript.Expressions;
using Elsa.JavaScript.Handlers;
using Elsa.JavaScript.Implementations;
using Elsa.JavaScript.Providers;
using Elsa.JavaScript.Services;
using Elsa.Mediator.Extensions;
using Elsa.Mediator.Features;
using Elsa.Workflows.Management.Implementations;
using Microsoft.Extensions.DependencyInjection;
@ -25,13 +23,13 @@ public class JavaScriptFeature : FeatureBase
{
}
/// <inheritdoc />
public override void Configure()
{
Services
.AddSingleton<IExpressionSyntaxProvider, JavaScriptExpressionSyntaxProvider>()
.AddSingleton<IJavaScriptEvaluator, JintJavaScriptEvaluator>()
.AddSingleton<IActivityPropertyOptionsProvider, RunJavaScriptOptionsProvider>()
.AddNotificationHandlersFrom<ConfigureJavaScriptEngineWithActivityOutput>()
.AddExpressionHandler<JavaScriptExpressionHandler, JavaScriptExpression>();
}
}

View file

@ -1,45 +0,0 @@
using Elsa.JavaScript.Notifications;
using Elsa.Mediator.Services;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Services;
namespace Elsa.JavaScript.Handlers;
/// <summary>
/// Makes available activity output to the JavaScript runtime environment.
/// </summary>
public class ConfigureJavaScriptEngineWithActivityOutput : INotificationHandler<EvaluatingJavaScript>
{
private readonly IActivityWalker _activityWalker;
public ConfigureJavaScriptEngineWithActivityOutput(IActivityWalker activityWalker)
{
_activityWalker = activityWalker;
}
public async Task HandleAsync(EvaluatingJavaScript notification, CancellationToken cancellationToken)
{
var engine = notification.Engine;
var workflow = notification.Context.GetWorkflowExecutionContext().Workflow;
var nodes = await _activityWalker.WalkAsync(workflow.Root, cancellationToken);
var graph = nodes.Flatten();
var register = notification.Context.Memory;
var jsActivities = new Dictionary<string, object>();
foreach (var node in graph)
{
var properties = node.Activity.GetOutputs().ToList();
var jsActivity = new Dictionary<string, object?>();
foreach (var property in properties)
{
if (register.TryGetBlock(property.Value.MemoryBlockReference().Id, out var location))
jsActivity[property.Name] = location.Value;
}
jsActivities[node.NodeId] = jsActivity;
}
engine.SetValue("activities", jsActivities);
}
}

View file

@ -1,4 +1,6 @@
using Elsa.Expressions.Models;
using System.Dynamic;
using System.Text.Json;
using Elsa.Expressions.Models;
using Elsa.JavaScript.Extensions;
using Elsa.JavaScript.Notifications;
using Elsa.JavaScript.Options;
@ -10,17 +12,24 @@ using Microsoft.Extensions.Options;
namespace Elsa.JavaScript.Implementations
{
/// <summary>
/// Provides a JavaScript evaluator using Jint.
/// </summary>
public class JintJavaScriptEvaluator : IJavaScriptEvaluator
{
private readonly IEventPublisher _mediator;
private readonly JintOptions _jintOptions;
/// <summary>
/// Constructor.
/// </summary>
public JintJavaScriptEvaluator(IEventPublisher mediator, IOptions<JintOptions> scriptOptions)
{
_mediator = mediator;
_jintOptions = scriptOptions.Value;
}
/// <inheritdoc />
public async Task<object?> EvaluateAsync(string expression,
Type returnType,
ExpressionExecutionContext context,
@ -43,11 +52,14 @@ namespace Elsa.JavaScript.Implementations
configureEngine?.Invoke(engine);
// Add workflow variables.
var variables = context.GetVariableValues();
// Add common functions.
engine.SetValue("setVariable", (Action<string, object>)((name, value) => context.SetVariable(name, value)));
foreach (var variable in variables)
engine.SetValue(variable.Key, variable.Value);
// ReSharper disable once ConvertClosureToMethodGroup (Jint will not understand).
engine.SetValue("getVariable", (Func<string, object?>)(name => context.GetVariable(name)));
engine.SetValue("isNullOrWhiteSpace", (Func<string, bool>)string.IsNullOrWhiteSpace);
engine.SetValue("isNullOrEmpty", (Func<string, bool>)string.IsNullOrEmpty);
// Add common .NET types.
engine.RegisterType<DateTime>();
@ -61,8 +73,8 @@ namespace Elsa.JavaScript.Implementations
private static object? ExecuteExpressionAndGetResult(Engine engine, string expression)
{
var result = engine.Execute(expression).GetCompletionValue();
return result?.ToObject();
var result = engine.Evaluate(expression);
return result.ToObject();
}
}
}