using System.Collections.Generic; using System.Dynamic; using System.Threading; using System.Threading.Tasks; using Elsa.Models; using Elsa.Scripting.Liquid.Helpers; using Elsa.Scripting.Liquid.Messages; using Elsa.Services.Models; using Fluid; using Fluid.Values; using MediatR; using Newtonsoft.Json.Linq; namespace Elsa.Scripting.Liquid.Handlers { public class ConfigureLiquidEngine : INotificationHandler { static ConfigureLiquidEngine() { FluidValue.SetTypeMapping(x => new ObjectValue(x)); FluidValue.SetTypeMapping(o => new ObjectValue(o)); FluidValue.SetTypeMapping(o => FluidValue.Create(o.Value)); } public Task Handle(EvaluatingLiquidExpression notification, CancellationToken cancellationToken) { var context = notification.TemplateContext; context.MemberAccessStrategy.Register(); context.MemberAccessStrategy.Register((x, name) => x.GetValueAsync(name)); context.MemberAccessStrategy.Register("Input", x => ToFluidValue(x.Input)); context.MemberAccessStrategy.Register("CorrelationId", x => ToFluidValue(x.CorrelationId)); context.MemberAccessStrategy.Register("Variables", x => new LiquidPropertyAccessor(name => ToFluidValue(x.WorkflowExecutionContext.WorkflowInstance.Variables, name))); context.MemberAccessStrategy.Register("Activities", x => new LiquidPropertyAccessor(name => ToFluidValue(GetActivityModelAsync(x, name)))); context.MemberAccessStrategy.Register("Output", GetActivityOutput); context.MemberAccessStrategy.Register, object>((x, name) => x.GetValueAsync(name)); context.MemberAccessStrategy.Register((x, name) => ((IDictionary) x)[name]); context.MemberAccessStrategy.Register((source, name) => source[name]); return Task.CompletedTask; } private Task ToFluidValue(object? input) => Task.FromResult(FluidValue.Create(input)); private Task ToFluidValue(Variables dictionary, string key) => Task.FromResult(!dictionary.Has(key) ? default : FluidValue.Create(dictionary.Get(key))); private LiquidActivityModel GetActivityModelAsync(ActivityExecutionContext context, string name) => new(context, name); private Task GetActivityOutput(LiquidActivityModel activityModel) { var output = activityModel.ActivityExecutionContext.GetOutputFrom(activityModel.ActivityName); return Task.FromResult(output); } } }