diff --git a/backend/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs b/backend/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs index dd9d6de8e..147fbbe6e 100644 --- a/backend/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs +++ b/backend/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs @@ -70,28 +70,28 @@ namespace Squidex.Infrastructure.Json.Objects switch (value) { - case string s: - return Create(s); - case bool b: - return Create(b); - case float f: - return Create(f); - case double d: - return Create(d); - case int i: - return Create(i); - case long l: - return Create(l); - case Guid g: - return Create(g); - case DomainId i: - return Create(i); - case Instant i: - return Create(i); - case object[] array: - return Array(array); - case IReadOnlyDictionary obj: - return Object(obj); + case string typed: + return Create(typed); + case bool typed: + return Create(typed); + case float typed: + return Create(typed); + case double typed: + return Create(typed); + case int typed: + return Create(typed); + case long typed: + return Create(typed); + case Guid typed: + return Create(typed); + case DomainId typed: + return Create(typed); + case Instant typed: + return Create(typed); + case object[] typed: + return Array(typed); + case IReadOnlyDictionary typed: + return Object(typed); } throw new ArgumentException("Invalid json type", nameof(value)); diff --git a/backend/src/Squidex.Infrastructure/Queries/ClrValue.cs b/backend/src/Squidex.Infrastructure/Queries/ClrValue.cs index 0993a4faf..9faedab4c 100644 --- a/backend/src/Squidex.Infrastructure/Queries/ClrValue.cs +++ b/backend/src/Squidex.Infrastructure/Queries/ClrValue.cs @@ -64,6 +64,11 @@ namespace Squidex.Infrastructure.Queries return value != null ? new ClrValue(value, ClrValueType.String, false) : Null; } + public static implicit operator ClrValue(List value) + { + return value != null ? new ClrValue(value, ClrValueType.Sphere, true) : Null; + } + public static implicit operator ClrValue(List value) { return value != null ? new ClrValue(value, ClrValueType.Instant, true) : Null; @@ -109,6 +114,45 @@ namespace Squidex.Infrastructure.Queries return value != null ? new ClrValue(value, ClrValueType.Dynamic, true) : Null; } + public ClrValue ToList() + { + var value = Value; + + if (IsList || ValueType == ClrValueType.Null || value == null) + { + return this; + } + + ClrValue BuildList(T value) + { + return new ClrValue(new List { value }, ValueType, true); + } + + switch (value) + { + case FilterSphere typed: + return BuildList(typed); + case Instant typed: + return BuildList(typed); + case Guid typed: + return BuildList(typed); + case bool typed: + return BuildList(typed); + case float typed: + return BuildList(typed); + case double typed: + return BuildList(typed); + case int typed: + return BuildList(typed); + case long typed: + return BuildList(typed); + case string typed: + return BuildList(typed); + } + + return this; + } + public override string ToString() { if (Value is IList list) diff --git a/backend/src/Squidex.Infrastructure/Queries/Json/JsonFilterVisitor.cs b/backend/src/Squidex.Infrastructure/Queries/Json/JsonFilterVisitor.cs index 8fa15407b..8177f85aa 100644 --- a/backend/src/Squidex.Infrastructure/Queries/Json/JsonFilterVisitor.cs +++ b/backend/src/Squidex.Infrastructure/Queries/Json/JsonFilterVisitor.cs @@ -73,9 +73,19 @@ namespace Squidex.Infrastructure.Queries.Json if (value != null && isValidOperator) { - if (value.IsList && nodeIn.Operator != CompareOperator.In) + if (nodeIn.Operator == CompareOperator.In) { - args.Errors.Add($"Array value is not allowed for '{nodeIn.Operator}' operator and path '{nodeIn.Path}'."); + if (!value.IsList) + { + value = value.ToList(); + } + } + else + { + if (value.IsList) + { + args.Errors.Add($"Array value is not allowed for '{nodeIn.Operator}' operator and path '{nodeIn.Path}'."); + } } if (nodeIn.Operator == CompareOperator.Matchs && value.Value?.ToString()?.IsValidRegex() != true) diff --git a/backend/tests/Squidex.Infrastructure.Tests/Queries/QueryFromJsonTests.cs b/backend/tests/Squidex.Infrastructure.Tests/Queries/QueryFromJsonTests.cs index bd5f791de..2dfbdacf8 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/Queries/QueryFromJsonTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/Queries/QueryFromJsonTests.cs @@ -491,6 +491,14 @@ namespace Squidex.Infrastructure.Queries AssertErrors(json, "Array value is not allowed for 'Equals' operator and path 'string'."); } + + [Fact] + public void Should_convert_single_value_to_list_for_in_operator() + { + var json = new { path = "string", op = "in", value = "Hello" }; + + AssertFilter(json, "string in ['Hello']"); + } } [Fact]