Add Variable Name Validation and Wrapper Control (#6117)
* Refactor directory structure and add variable wrappers option Renamed TypeDefinitions/Providers to Providers for better clarity. Added a new configuration option to disable generating variable wrappers for scenarios requiring invalid JavaScript variable names. * Add variable name validation and wrapper control Introduced methods to validate variable names and filter invalid ones. Integrated `DisableWrappers` option to control the generation of variable wrappers, enhancing flexibility in variable management. * Remove unused item group from project file The item group containing the "TypeDefinitions\Providers\" folder was removed from the Elsa.JavaScript.csproj file. This folder was not serving any purpose and its removal helps in cleaning up the project structure.
This commit is contained in:
parent
50e23ba738
commit
02f4dc9b8c
|
|
@ -71,6 +71,7 @@ const MassTransitBroker massTransitBroker = MassTransitBroker.Memory;
|
|||
const bool useMultitenancy = false;
|
||||
const bool useAgents = false;
|
||||
const bool useSecrets = true;
|
||||
const bool disableVariableWrappers = false;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var services = builder.Services;
|
||||
|
|
@ -314,6 +315,7 @@ services
|
|||
.UseJavaScript(options =>
|
||||
{
|
||||
options.AllowClrAccess = true;
|
||||
options.DisableWrappers = disableVariableWrappers;
|
||||
options.ConfigureEngine(engine =>
|
||||
{
|
||||
engine.Execute("function greet(name) { return `Hello ${name}!`; }");
|
||||
|
|
|
|||
19
src/modules/Elsa.CSharp/Extensions/VariableNameExtensions.cs
Normal file
19
src/modules/Elsa.CSharp/Extensions/VariableNameExtensions.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
namespace Elsa.CSharp.Extensions;
|
||||
|
||||
public static class VariableNameExtensions
|
||||
{
|
||||
public static bool IsValidVariableName(this string name)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(name) && name.All(char.IsLetterOrDigit);
|
||||
}
|
||||
|
||||
public static bool IsInvalidVariableName(this string name)
|
||||
{
|
||||
return !IsValidVariableName(name);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> FilterInvalidVariableNames(this IEnumerable<string> names)
|
||||
{
|
||||
return names.Where(IsValidVariableName);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
using System.Text;
|
||||
using Elsa.CSharp.Extensions;
|
||||
using Elsa.CSharp.Notifications;
|
||||
using Elsa.CSharp.Options;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.CSharp.Handlers;
|
||||
|
||||
|
|
@ -11,7 +14,7 @@ namespace Elsa.CSharp.Handlers;
|
|||
/// Configures the C# evaluator with methods to access workflow variables.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class GenerateArgumentAccessors : INotificationHandler<EvaluatingCSharp>
|
||||
public class GenerateArgumentAccessors(IOptions<CSharpOptions> options) : INotificationHandler<EvaluatingCSharp>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task HandleAsync(EvaluatingCSharp notification, CancellationToken cancellationToken)
|
||||
|
|
@ -24,17 +27,19 @@ public class GenerateArgumentAccessors : INotificationHandler<EvaluatingCSharp>
|
|||
sb.AppendLine();
|
||||
sb.AppendLine("\tpublic T? Get<T>(string name) => Arguments.TryGetValue(name, out var v) ? (T?)v : default;");
|
||||
sb.AppendLine();
|
||||
foreach (var argument in arguments)
|
||||
|
||||
if (!options.Value.DisableWrappers)
|
||||
{
|
||||
// var d = new Dictionary<string, object>();
|
||||
// d.TryGetValue("", out var f);
|
||||
var argumentName = argument.Key;
|
||||
var variableType = argument.Value.GetType();
|
||||
var friendlyTypeName = variableType.GetFriendlyTypeName(Brackets.Angle);
|
||||
sb.AppendLine($"\tpublic {friendlyTypeName} {argumentName}");
|
||||
sb.AppendLine("\t{");
|
||||
sb.AppendLine($"\t\tget => Get<{friendlyTypeName}>(\"{argumentName}\");");
|
||||
sb.AppendLine("\t}");
|
||||
foreach (var argument in arguments.Where(x => x.Key.IsValidVariableName()))
|
||||
{
|
||||
var argumentName = argument.Key;
|
||||
var variableType = argument.Value.GetType();
|
||||
var friendlyTypeName = variableType.GetFriendlyTypeName(Brackets.Angle);
|
||||
sb.AppendLine($"\tpublic {friendlyTypeName} {argumentName}");
|
||||
sb.AppendLine("\t{");
|
||||
sb.AppendLine($"\t\tget => Get<{friendlyTypeName}>(\"{argumentName}\");");
|
||||
sb.AppendLine("\t}");
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
using System.Text;
|
||||
using Elsa.CSharp.Extensions;
|
||||
using Elsa.CSharp.Notifications;
|
||||
using Elsa.CSharp.Options;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.CSharp.Handlers;
|
||||
|
||||
|
|
@ -11,13 +14,12 @@ namespace Elsa.CSharp.Handlers;
|
|||
/// Configures the C# evaluator with methods to access workflow variables.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class GenerateWorkflowInputAccessors : INotificationHandler<EvaluatingCSharp>
|
||||
public class GenerateWorkflowInputAccessors(IOptions<CSharpOptions> options) : INotificationHandler<EvaluatingCSharp>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task HandleAsync(EvaluatingCSharp notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var expressionExecutionContext = notification.Context;
|
||||
var workflowInputs = expressionExecutionContext.GetWorkflowInputs().ToList();
|
||||
|
||||
if (!expressionExecutionContext.TryGetWorkflowExecutionContext(out var workflowExecutionContext))
|
||||
return Task.CompletedTask;
|
||||
|
|
@ -31,15 +33,19 @@ public class GenerateWorkflowInputAccessors : INotificationHandler<EvaluatingCSh
|
|||
sb.AppendLine();
|
||||
sb.AppendLine("\tpublic T? Get<T>(string name) => ExecutionContext.GetInput<T>(name);");
|
||||
sb.AppendLine();
|
||||
foreach (var inputDefinition in inputDefinitions)
|
||||
|
||||
if (!options.Value.DisableWrappers)
|
||||
{
|
||||
var inputName = inputDefinition.Name;
|
||||
var variableType = inputDefinition.Type;
|
||||
var friendlyTypeName = variableType.GetFriendlyTypeName(Brackets.Angle);
|
||||
sb.AppendLine($"\tpublic {friendlyTypeName} {inputName}");
|
||||
sb.AppendLine("\t{");
|
||||
sb.AppendLine($"\t\tget => Get<{friendlyTypeName}>(\"{inputName}\");");
|
||||
sb.AppendLine("\t}");
|
||||
foreach (var inputDefinition in inputDefinitions.Where(x => x.Name.IsValidVariableName()))
|
||||
{
|
||||
var inputName = inputDefinition.Name;
|
||||
var variableType = inputDefinition.Type;
|
||||
var friendlyTypeName = variableType.GetFriendlyTypeName(Brackets.Angle);
|
||||
sb.AppendLine($"\tpublic {friendlyTypeName} {inputName}");
|
||||
sb.AppendLine("\t{");
|
||||
sb.AppendLine($"\t\tget => Get<{friendlyTypeName}>(\"{inputName}\");");
|
||||
sb.AppendLine("\t}");
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
using System.Text;
|
||||
using Elsa.CSharp.Extensions;
|
||||
using Elsa.CSharp.Notifications;
|
||||
using Elsa.CSharp.Options;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.CSharp.Handlers;
|
||||
|
||||
|
|
@ -12,7 +15,7 @@ namespace Elsa.CSharp.Handlers;
|
|||
/// Configures the C# evaluator with methods to access workflow variables.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class GenerateWorkflowVariableAccessors : INotificationHandler<EvaluatingCSharp>
|
||||
public class GenerateWorkflowVariableAccessors(IOptions<CSharpOptions> options) : INotificationHandler<EvaluatingCSharp>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task HandleAsync(EvaluatingCSharp notification, CancellationToken cancellationToken)
|
||||
|
|
@ -28,16 +31,20 @@ public class GenerateWorkflowVariableAccessors : INotificationHandler<Evaluating
|
|||
sb.AppendLine("\tpublic object? Get(string name) => ExecutionContext.GetVariable(name);");
|
||||
sb.AppendLine("\tpublic void Set(string name, object? value) => ExecutionContext.SetVariable(name, value);");
|
||||
sb.AppendLine();
|
||||
foreach (var variable in variables)
|
||||
|
||||
if (!options.Value.DisableWrappers)
|
||||
{
|
||||
var variableName = variable.Name.Pascalize();
|
||||
var variableType = variable.GetVariableType();
|
||||
var friendlyTypeName = variableType.GetFriendlyTypeName(Brackets.Angle);
|
||||
sb.AppendLine($"\tpublic {friendlyTypeName} {variableName}");
|
||||
sb.AppendLine("\t{");
|
||||
sb.AppendLine($"\t\tget => Get<{friendlyTypeName}>(\"{variableName}\");");
|
||||
sb.AppendLine($"\t\tset => Set(\"{variableName}\", value);");
|
||||
sb.AppendLine("\t}");
|
||||
foreach (var variable in variables.Where(x => x.Name.IsValidVariableName()))
|
||||
{
|
||||
var variableName = variable.Name.Pascalize();
|
||||
var variableType = variable.GetVariableType();
|
||||
var friendlyTypeName = variableType.GetFriendlyTypeName(Brackets.Angle);
|
||||
sb.AppendLine($"\tpublic {friendlyTypeName} {variableName}");
|
||||
sb.AppendLine("\t{");
|
||||
sb.AppendLine($"\t\tget => Get<{friendlyTypeName}>(\"{variableName}\");");
|
||||
sb.AppendLine($"\t\tset => Set(\"{variableName}\", value);");
|
||||
sb.AppendLine("\t}");
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ public class CSharpOptions
|
|||
typeof(JsonNode).Namespace!, // System.Text.Json.Nodes
|
||||
typeof(IDictionary<string, object>).Namespace!, // System.Collections.Generic
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Disables the generation of variable wrappers. E.g. <c>Variables.MyVariable</c> will no longer be available for variables. Instead, you can only access variables using <c>Variables.Get("MyVariable")</c> and the typed <c>Variables.Get<T>("MyVariable")</c> function.
|
||||
/// This is useful if your application requires the use of invalid JavaScript variable names.
|
||||
/// </summary>
|
||||
public bool DisableWrappers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configures the <see cref="ScriptOptions"/>.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
using Elsa.JavaScript.Helpers;
|
||||
|
||||
namespace Elsa.JavaScript.Extensions;
|
||||
|
||||
public static class VariableNameExtensions
|
||||
{
|
||||
public static bool IsValidVariableName(this string name)
|
||||
{
|
||||
return VariableNameValidator.IsValidVariableName(name);
|
||||
}
|
||||
|
||||
public static bool IsInvalidVariableName(this string name)
|
||||
{
|
||||
return !VariableNameValidator.IsValidVariableName(name);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> FilterInvalidVariableNames(this IEnumerable<string> names)
|
||||
{
|
||||
return names.Where(IsValidVariableName);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ using Elsa.JavaScript.Options;
|
|||
using Elsa.JavaScript.Providers;
|
||||
using Elsa.JavaScript.Services;
|
||||
using Elsa.JavaScript.TypeDefinitions.Contracts;
|
||||
using Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
using Elsa.JavaScript.TypeDefinitions.Services;
|
||||
using Elsa.Workflows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
|
|||
|
|
@ -1,29 +1,38 @@
|
|||
using System.Dynamic;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Extensions;
|
||||
using Elsa.JavaScript.Helpers;
|
||||
using Elsa.JavaScript.Notifications;
|
||||
using Elsa.JavaScript.Options;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Elsa.Workflows.Activities;
|
||||
using JetBrains.Annotations;
|
||||
using Jint;
|
||||
using Jint.Native;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.Handlers;
|
||||
|
||||
/// A handler that configures the Jint engine with workflow variables.
|
||||
[UsedImplicitly]
|
||||
public class ConfigureEngineWithVariables : INotificationHandler<EvaluatingJavaScript>, INotificationHandler<EvaluatedJavaScript>
|
||||
public class ConfigureEngineWithVariables(IOptions<JintOptions> options) : INotificationHandler<EvaluatingJavaScript>, INotificationHandler<EvaluatedJavaScript>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task HandleAsync(EvaluatingJavaScript notification, CancellationToken cancellationToken)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
return Task.CompletedTask;
|
||||
|
||||
CopyVariablesIntoEngine(notification);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task HandleAsync(EvaluatedJavaScript notification, CancellationToken cancellationToken)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
return Task.CompletedTask;
|
||||
|
||||
CopyVariablesIntoWorkflowExecutionContext(notification);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
|
@ -33,7 +42,7 @@ public class ConfigureEngineWithVariables : INotificationHandler<EvaluatingJavaS
|
|||
var context = notification.Context;
|
||||
var engine = notification.Engine;
|
||||
var variablesContainer = (IDictionary<string, object?>)engine.GetValue("variables").ToObject()!;
|
||||
var inputNames = GetInputNames(context).Distinct().ToList();
|
||||
var inputNames = GetInputNames(context).FilterInvalidVariableNames().Distinct().ToList();
|
||||
|
||||
foreach (var (variableName, variableValue) in variablesContainer)
|
||||
{
|
||||
|
|
@ -67,7 +76,7 @@ public class ConfigureEngineWithVariables : INotificationHandler<EvaluatingJavaS
|
|||
{
|
||||
var engine = notification.Engine;
|
||||
var context = notification.Context;
|
||||
var variableNames = context.GetVariableNamesInScope().ToList();
|
||||
var variableNames = context.GetVariableNamesInScope().FilterInvalidVariableNames().ToList();
|
||||
var variablesContainer = (IDictionary<string, object?>)new ExpandoObject();
|
||||
|
||||
foreach (var variableName in variableNames)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,31 @@
|
|||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Extensions;
|
||||
using Elsa.JavaScript.Helpers;
|
||||
using Elsa.JavaScript.Notifications;
|
||||
using Elsa.JavaScript.Options;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Jint;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.Handlers;
|
||||
|
||||
/// A handler that configures the Jint engine with workflow input and output accessors.
|
||||
[UsedImplicitly]
|
||||
public class ConfigureEngineWithVariablesAndInputOutputAccessors : INotificationHandler<EvaluatingJavaScript>
|
||||
public class ConfigureEngineWithVariablesAndInputOutputAccessors(IOptions<JintOptions> options) : INotificationHandler<EvaluatingJavaScript>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task HandleAsync(EvaluatingJavaScript notification, CancellationToken cancellationToken)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
return;
|
||||
|
||||
var engine = notification.Engine;
|
||||
var context = notification.Context;
|
||||
|
||||
// The order of the next 3 lines is important.
|
||||
// The order of the next 3 lines is important.
|
||||
CreateVariableAccessors(engine, context);
|
||||
CreateWorkflowInputAccessors(engine, context);
|
||||
await CreateActivityOutputAccessorsAsync(engine, context);
|
||||
|
|
@ -26,7 +33,7 @@ public class ConfigureEngineWithVariablesAndInputOutputAccessors : INotification
|
|||
|
||||
private void CreateVariableAccessors(Engine engine, ExpressionExecutionContext context)
|
||||
{
|
||||
var variableNames = context.GetVariableNamesInScope().ToList();
|
||||
var variableNames = context.GetVariableNamesInScope().FilterInvalidVariableNames().ToList();
|
||||
|
||||
foreach (var variableName in variableNames)
|
||||
{
|
||||
|
|
@ -43,7 +50,7 @@ public class ConfigureEngineWithVariablesAndInputOutputAccessors : INotification
|
|||
if (context.IsContainedWithinCompositeActivity())
|
||||
return;
|
||||
|
||||
var inputs = context.GetWorkflowInputs().ToDictionary(x => x.Name);
|
||||
var inputs = context.GetWorkflowInputs().Where(x => x.Name.IsValidVariableName()).ToDictionary(x => x.Name);
|
||||
|
||||
if (!context.TryGetWorkflowExecutionContext(out var workflowExecutionContext))
|
||||
return;
|
||||
|
|
@ -62,7 +69,7 @@ public class ConfigureEngineWithVariablesAndInputOutputAccessors : INotification
|
|||
var activityOutputs = context.GetActivityOutputs();
|
||||
|
||||
await foreach (var activityOutput in activityOutputs)
|
||||
foreach (var outputName in activityOutput.OutputNames)
|
||||
foreach (var outputName in activityOutput.OutputNames.FilterInvalidVariableNames())
|
||||
engine.SetValue($"get{outputName}From{activityOutput.ActivityName}", (Func<object?>)(() => context.GetOutput(activityOutput.ActivityId, outputName)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace Elsa.JavaScript.Helpers;
|
||||
|
||||
public static class VariableNameValidator
|
||||
{
|
||||
public static bool IsValidVariableName(string name)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(name) && name.All(char.IsLetterOrDigit);
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,12 @@ public class JintOptions
|
|||
/// If the value of <c>ScriptCacheTimeout</c> is <c>null</c>, the scripts are cached indefinitely. If a time value is specified, the scripts will be recompiled after the specified duration has elapsed.
|
||||
/// </remarks>
|
||||
public TimeSpan? ScriptCacheTimeout { get; set; } = TimeSpan.FromDays(1);
|
||||
|
||||
/// <summary>
|
||||
/// Disables the generation of variable wrappers. E.g. <c>getMyVariable()</c> will no longer be available for variables. Instead, you can only access variables using <c>getVariable("MyVariable")</c> function.
|
||||
/// This is useful if your application requires the use of invalid JavaScript variable names.
|
||||
/// </summary>
|
||||
public bool DisableWrappers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configures the Jint engine options.
|
||||
|
|
|
|||
|
|
@ -1,25 +1,31 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Extensions;
|
||||
using Elsa.JavaScript.Options;
|
||||
using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
using Elsa.Workflows;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
/// Produces <see cref="FunctionDefinition"/>s for common functions.
|
||||
[UsedImplicitly]
|
||||
internal class ActivityOutputFunctionsDefinitionProvider(IActivityRegistryLookupService activityRegistryLookup) : FunctionDefinitionProvider
|
||||
internal class ActivityOutputFunctionsDefinitionProvider(IActivityRegistryLookupService activityRegistryLookup, IOptions<JintOptions> options) : FunctionDefinitionProvider
|
||||
{
|
||||
protected override async ValueTask<IEnumerable<FunctionDefinition>> GetFunctionDefinitionsAsync(TypeDefinitionContext context)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
return [];
|
||||
|
||||
var nodes = context.WorkflowGraph.Nodes;
|
||||
var activitiesWithOutputs = nodes.GetActivitiesWithOutputs(activityRegistryLookup).Where(x => x.activity.Name != null);
|
||||
var activitiesWithOutputs = nodes.GetActivitiesWithOutputs(activityRegistryLookup).Where(x => x.activity.Name != null && x.activity.Name.IsValidVariableName());
|
||||
var definitions = new List<FunctionDefinition>();
|
||||
|
||||
await foreach (var (activity, activityDescriptor) in activitiesWithOutputs)
|
||||
{
|
||||
definitions.AddRange(from output in activityDescriptor.Outputs
|
||||
definitions.AddRange(from output in activityDescriptor.Outputs.Where(x => x.Name.IsValidVariableName())
|
||||
select output.Name.Pascalize()
|
||||
into outputPascalName
|
||||
let activityNamePascalName = activity.Name.Pascalize()
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Contracts;
|
||||
using Elsa.JavaScript.Extensions;
|
||||
using Elsa.JavaScript.Options;
|
||||
using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
/// Produces <see cref="FunctionDefinition"/>s for common functions.
|
||||
[UsedImplicitly]
|
||||
internal class CommonFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasRegistry) : FunctionDefinitionProvider
|
||||
internal class CommonFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasRegistry, IOptions<JintOptions> options) : FunctionDefinitionProvider
|
||||
{
|
||||
protected override IEnumerable<FunctionDefinition> GetFunctionDefinitions(TypeDefinitionContext context)
|
||||
{
|
||||
|
|
@ -124,18 +127,21 @@ internal class CommonFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasReg
|
|||
.Parameter("value", "string")
|
||||
.ReturnType("string"));
|
||||
|
||||
// Variable getter and setters.
|
||||
foreach (var variable in context.WorkflowGraph.Workflow.Variables)
|
||||
if (!options.Value.DisableWrappers)
|
||||
{
|
||||
var pascalName = variable.Name.Pascalize();
|
||||
var variableType = variable.GetVariableType();
|
||||
var typeAlias = typeAliasRegistry.TryGetAlias(variableType, out var alias) ? alias : "any";
|
||||
// Variable getter and setters.
|
||||
foreach (var variable in context.WorkflowGraph.Workflow.Variables.Where(x => x.Name.IsValidVariableName()))
|
||||
{
|
||||
var pascalName = variable.Name.Pascalize();
|
||||
var variableType = variable.GetVariableType();
|
||||
var typeAlias = typeAliasRegistry.TryGetAlias(variableType, out var alias) ? alias : "any";
|
||||
|
||||
// get{Variable}.
|
||||
yield return CreateFunctionDefinition(builder => builder.Name($"get{pascalName}").ReturnType(typeAlias));
|
||||
// get{Variable}.
|
||||
yield return CreateFunctionDefinition(builder => builder.Name($"get{pascalName}").ReturnType(typeAlias));
|
||||
|
||||
// set{Variable}.
|
||||
yield return CreateFunctionDefinition(builder => builder.Name($"set{pascalName}").Parameter("value", typeAlias));
|
||||
// set{Variable}.
|
||||
yield return CreateFunctionDefinition(builder => builder.Name($"set{pascalName}").Parameter("value", typeAlias));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
|||
using Elsa.JavaScript.TypeDefinitions.Contracts;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
|
||||
namespace Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
/// <summary>
|
||||
/// Produces <see cref="FunctionDefinition"/>s for common functions.
|
||||
|
|
@ -1,18 +1,24 @@
|
|||
using Elsa.JavaScript.Contracts;
|
||||
using Elsa.JavaScript.Helpers;
|
||||
using Elsa.JavaScript.Options;
|
||||
using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
/// Produces <see cref="FunctionDefinition"/>s for common functions.
|
||||
[UsedImplicitly]
|
||||
internal class InputFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasRegistry) : FunctionDefinitionProvider
|
||||
internal class InputFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasRegistry, IOptions<JintOptions> options) : FunctionDefinitionProvider
|
||||
{
|
||||
protected override ValueTask<IEnumerable<FunctionDefinition>> GetFunctionDefinitionsAsync(TypeDefinitionContext context)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
return ValueTask.FromResult<IEnumerable<FunctionDefinition>>([]);
|
||||
|
||||
var workflow = context.WorkflowGraph.Workflow;
|
||||
return ValueTask.FromResult(GetFunctionDefinitionsAsync(workflow));
|
||||
}
|
||||
|
|
@ -20,7 +26,7 @@ internal class InputFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasRegi
|
|||
private IEnumerable<FunctionDefinition> GetFunctionDefinitionsAsync(Workflow workflow)
|
||||
{
|
||||
// Input argument getters.
|
||||
foreach (var input in workflow.Inputs)
|
||||
foreach (var input in workflow.Inputs.Where(x => VariableNameValidator.IsValidVariableName(x.Name)))
|
||||
{
|
||||
var pascalName = input.Name.Pascalize();
|
||||
var variableType = input.Type;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
|||
using Elsa.JavaScript.TypeDefinitions.Contracts;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
|
||||
namespace Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
/// <summary>
|
||||
/// Produces <see cref="TypeDefinition"/>s for variable types.
|
||||
|
|
@ -1,15 +1,21 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Extensions;
|
||||
using Elsa.JavaScript.Options;
|
||||
using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
[UsedImplicitly]
|
||||
internal class WorkflowVariablesTypeDefinitionProvider : TypeDefinitionProvider
|
||||
internal class WorkflowVariablesTypeDefinitionProvider(IOptions<JintOptions> options) : TypeDefinitionProvider
|
||||
{
|
||||
protected override IEnumerable<TypeDefinition> GetTypeDefinitions(TypeDefinitionContext context)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
yield break;
|
||||
|
||||
var variables = context.WorkflowGraph.Workflow.Variables;
|
||||
|
||||
var workflowTypeDefinition = new TypeDefinition
|
||||
|
|
@ -18,7 +24,7 @@ internal class WorkflowVariablesTypeDefinitionProvider : TypeDefinitionProvider
|
|||
DeclarationKeyword = "class"
|
||||
};
|
||||
|
||||
foreach (var variable in variables)
|
||||
foreach (var variable in variables.Where(x => x.Name.IsValidVariableName()))
|
||||
{
|
||||
var variableType = variable.GetVariableType();
|
||||
workflowTypeDefinition.Properties.Add(new PropertyDefinition
|
||||
|
|
@ -1,14 +1,19 @@
|
|||
using Elsa.JavaScript.Options;
|
||||
using Elsa.JavaScript.TypeDefinitions.Abstractions;
|
||||
using Elsa.JavaScript.TypeDefinitions.Models;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.JavaScript.TypeDefinitions.Providers;
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
||||
[UsedImplicitly]
|
||||
internal class WorkflowVariablesVariableProvider : VariableDefinitionProvider
|
||||
internal class WorkflowVariablesVariableProvider(IOptions<JintOptions> options) : VariableDefinitionProvider
|
||||
{
|
||||
protected override IEnumerable<VariableDefinition> GetVariableDefinitions(TypeDefinitionContext context)
|
||||
{
|
||||
if(options.Value.DisableWrappers)
|
||||
yield break;
|
||||
|
||||
yield return CreateVariableDefinition(x => x.Name("variables").Type("WorkflowVariables"));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue