Add ObjectArrayHelper and update array detection method

A new ObjectArrayHelper class has been added into the Elsa.JavaScript module to improve array detection. The previous IsArrayLike method used in JintJavaScriptEvaluator and integration tests has been replaced by the DetermineIfObjectIsArrayLikeClrCollection method from this helper. These changes also provoked an update of the Jint package version from 3.0.0-beta-2057 to 3.0.0.
This commit is contained in:
Sipke Schoorstra 2024-01-31 21:10:13 +01:00
parent 7575b78d8b
commit a1c30facba
4 changed files with 48 additions and 9 deletions

View file

@ -19,7 +19,7 @@
<ItemGroup>
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="Jint" Version="3.0.0-beta-2057" />
<PackageReference Include="Jint" Version="3.0.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,39 @@
using System.Collections;
namespace Elsa.JavaScript.Helpers;
/// <summary>
/// Contains helper methods for working with object arrays.
/// </summary>
public static class ObjectArrayHelper
{
/// <summary>
/// Determines if the specified object is an array-like CLR collection.
/// </summary>
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;
}
}

View file

@ -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;
});

View file

@ -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;
})