diff --git a/core/src/main/java/io/kestra/core/runners/pebble/filters/JqFilter.java b/core/src/main/java/io/kestra/core/runners/pebble/filters/JqFilter.java index 0d7b8521ca7..579c6c29b9c 100644 --- a/core/src/main/java/io/kestra/core/runners/pebble/filters/JqFilter.java +++ b/core/src/main/java/io/kestra/core/runners/pebble/filters/JqFilter.java @@ -1,15 +1,12 @@ package io.kestra.core.runners.pebble.filters; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.NumericNode; -import com.fasterxml.jackson.databind.node.TextNode; +import com.fasterxml.jackson.databind.node.*; +import io.kestra.core.serializers.JacksonMapper; import io.pebbletemplates.pebble.error.PebbleException; import io.pebbletemplates.pebble.extension.Filter; import io.pebbletemplates.pebble.template.EvaluationContext; import io.pebbletemplates.pebble.template.PebbleTemplate; -import io.kestra.core.serializers.JacksonMapper; import net.thisptr.jackson.jq.BuiltinFunctionLoader; import net.thisptr.jackson.jq.JsonQuery; import net.thisptr.jackson.jq.Scope; @@ -71,17 +68,21 @@ public Object apply(Object input, Map args, PebbleTemplate self, out.add(v.numberValue()); } else if (v instanceof BooleanNode) { out.add(v.booleanValue()); + } else if (v instanceof ObjectNode) { + out.add(JacksonMapper.ofJson().convertValue(v, Map.class)); + } else if (v instanceof ArrayNode) { + out.add(JacksonMapper.ofJson().convertValue(v, List.class)); } else { out.add(v); } }); } catch (Exception e) { - throw new Exception("Failed to resolve JQ expression '" + pattern + "' and value '" + input + "'", e); + throw new Exception("Failed to resolve JQ expression '" + pattern + "' and value '" + input + "'", e); } return out; } catch (Exception e) { - throw new PebbleException(e, "Unable to parse jq value '" + input + "' with type '" + input.getClass().getName() + "'", lineNumber, self.getName()); + throw new PebbleException(e, "Unable to parse jq value '" + input + "' with type '" + input.getClass().getName() + "'", lineNumber, self.getName()); } } } diff --git a/core/src/test/java/io/kestra/core/runners/pebble/filters/JqFilterTest.java b/core/src/test/java/io/kestra/core/runners/pebble/filters/JqFilterTest.java index 886f2b2e9a3..6d85c48e3f2 100644 --- a/core/src/test/java/io/kestra/core/runners/pebble/filters/JqFilterTest.java +++ b/core/src/test/java/io/kestra/core/runners/pebble/filters/JqFilterTest.java @@ -4,6 +4,7 @@ import io.kestra.core.exceptions.IllegalVariableEvaluationException; import io.kestra.core.runners.VariableRenderer; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; import org.junit.jupiter.api.Test; import java.time.ZoneId; @@ -12,7 +13,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import jakarta.inject.Inject; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; @@ -128,4 +128,20 @@ void typed() throws IllegalVariableEvaluationException { assertThat(variableRenderer.render("{{ vars | jq(\".bool\") | first | className }}", vars), is("java.lang.Boolean")); assertThat(variableRenderer.render("{{ vars | jq(\".null\") | first | className }}", vars), is("")); } + + @Test + void object() throws IllegalVariableEvaluationException { + ImmutableMap vars = ImmutableMap.of( + "vars", ImmutableMap.of( + "object", Map.of("key", "value"), + "array", new String[]{"arrayValue"} + ) + ); + + String render = variableRenderer.render("{% set object = vars | jq(\".object\") %}{{object[0].key}}", vars); + assertThat(render, is("value")); + + render = variableRenderer.render("{% set array = vars | jq(\".array\") %}{{array[0][0]}}", vars); + assertThat(render, is("arrayValue")); + } }