diff --git a/src/modules/Elsa.JavaScript/Elsa.JavaScript.csproj b/src/modules/Elsa.JavaScript/Elsa.JavaScript.csproj index fcc2b11b8..26dc246fa 100644 --- a/src/modules/Elsa.JavaScript/Elsa.JavaScript.csproj +++ b/src/modules/Elsa.JavaScript/Elsa.JavaScript.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/modules/Elsa.JavaScript/Helpers/ObjectArrayHelper.cs b/src/modules/Elsa.JavaScript/Helpers/ObjectArrayHelper.cs new file mode 100644 index 000000000..059a7b49e --- /dev/null +++ b/src/modules/Elsa.JavaScript/Helpers/ObjectArrayHelper.cs @@ -0,0 +1,39 @@ +using System.Collections; + +namespace Elsa.JavaScript.Helpers; + +/// +/// Contains helper methods for working with object arrays. +/// +public static class ObjectArrayHelper +{ + /// + /// Determines if the specified object is an array-like CLR collection. + /// + public static bool DetermineIfObjectIsArrayLikeClrCollection(Type type) + { + var isDictionary = typeof(IDictionary).IsAssignableFrom(type); + + if (isDictionary) + return false; + + if (typeof(ICollection).IsAssignableFrom(type)) + return true; + + foreach (var interfaceType in type.GetInterfaces()) + { + if (!interfaceType.IsGenericType) + { + continue; + } + + if (interfaceType.GetGenericTypeDefinition() == typeof(IReadOnlyCollection<>) + || interfaceType.GetGenericTypeDefinition() == typeof(ICollection<>)) + { + return true; + } + } + + return false; + } +} \ 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 fbae349f6..c7d733d65 100644 --- a/src/modules/Elsa.JavaScript/Services/JintJavaScriptEvaluator.cs +++ b/src/modules/Elsa.JavaScript/Services/JintJavaScriptEvaluator.cs @@ -5,6 +5,7 @@ using Elsa.Expressions.Helpers; using Elsa.Expressions.Models; using Elsa.Extensions; using Elsa.JavaScript.Contracts; +using Elsa.JavaScript.Helpers; using Elsa.JavaScript.Notifications; using Elsa.JavaScript.Options; using Elsa.Mediator.Contracts; @@ -61,10 +62,9 @@ public class JintJavaScriptEvaluator : IJavaScriptEvaluator opts.SetWrapObjectHandler((engine, target, type) => { var instance = new ObjectWrapper(engine, target); - if (instance.IsArrayLike) - { - instance.SetPrototypeOf(engine.Realm.Intrinsics.Array.PrototypeObject); - } + + if (ObjectArrayHelper.DetermineIfObjectIsArrayLikeClrCollection(target.GetType())) + instance.Prototype = engine.Intrinsics.Array.PrototypeObject; return instance; }); diff --git a/test/integration/Elsa.IntegrationTests/Scenarios/JavaScriptListAndArray/Tests.cs b/test/integration/Elsa.IntegrationTests/Scenarios/JavaScriptListAndArray/Tests.cs index 12e9ba714..d1ef1c657 100644 --- a/test/integration/Elsa.IntegrationTests/Scenarios/JavaScriptListAndArray/Tests.cs +++ b/test/integration/Elsa.IntegrationTests/Scenarios/JavaScriptListAndArray/Tests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Dynamic; +using Elsa.JavaScript.Helpers; using Jint; using Jint.Runtime.Interop; using Xunit; @@ -19,10 +20,9 @@ public class Tests .SetWrapObjectHandler((engine, target, type) => { var instance = new ObjectWrapper(engine, target); - if (instance.IsArrayLike) - { - instance.SetPrototypeOf(engine.Realm.Intrinsics.Array.PrototypeObject); - } + + if (ObjectArrayHelper.DetermineIfObjectIsArrayLikeClrCollection(target.GetType())) + instance.Prototype = engine.Intrinsics.Array.PrototypeObject; return instance; })