diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JintObjectConverter.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JintObjectConverter.cs index 5696a48db..e9dfd69ee 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JintObjectConverter.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JintObjectConverter.cs @@ -21,6 +21,29 @@ namespace Squidex.Domain.Apps.Core.Scripting.Internal; public sealed class JintObjectConverter : IObjectConverter { + /// + /// The CLR types this converter answers for, declared at registration so the engine can keep its + /// compiled interop member-read lane for members whose declared type can never reach this converter. + /// + /// + /// Matching is by assignability, so covers every implementation. Registering the + /// converter without this set makes every wrapped CLR member read in the engine take the slow lane. + /// Enums are not listed: they are handled natively through + /// . + /// + public static readonly Type[] HandledTypes = + [ + typeof(IUser), + typeof(ClaimsPrincipal), + typeof(ScriptVars), + typeof(JsonValue), + typeof(DomainId), + typeof(Guid), + typeof(Instant), + typeof(Status), + typeof(ContentData), + ]; + public static readonly JintObjectConverter Instance = new JintObjectConverter(); private JintObjectConverter() @@ -31,12 +54,6 @@ public sealed class JintObjectConverter : IObjectConverter { result = null!; - if (value is Enum) - { - result = value.ToString(); - return true; - } - switch (value) { case IUser user: diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs index 428182cf7..faf8c20cc 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs @@ -143,8 +143,9 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions { - engineOptions.AddObjectConverter(JintObjectConverter.Instance); + engineOptions.AddObjectConverter(JintObjectConverter.Instance, JintObjectConverter.HandledTypes); engineOptions.AllowClrWrite(!options.Readonly); + engineOptions.Interop.EnumConversion = EnumConversionMode.String; engineOptions.SetTypeConverter(engine => new CustomClrConverter(engine)); engineOptions.SetReferencesResolver(NullPropagation.Instance, NullPropagation.Interests); engineOptions.Strict();