diff --git a/qqq-language-support-javascript/src/main/java/com/kingsrook/qqq/languages/javascript/QJavaScriptExecutor.java b/qqq-language-support-javascript/src/main/java/com/kingsrook/qqq/languages/javascript/QJavaScriptExecutor.java index 7a708ba7..898e330f 100644 --- a/qqq-language-support-javascript/src/main/java/com/kingsrook/qqq/languages/javascript/QJavaScriptExecutor.java +++ b/qqq-language-support-javascript/src/main/java/com/kingsrook/qqq/languages/javascript/QJavaScriptExecutor.java @@ -28,6 +28,7 @@ import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.io.Serializable; import java.math.BigDecimal; +import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -35,6 +36,7 @@ import java.util.Map; import com.kingsrook.qqq.backend.core.actions.scripts.QCodeExecutor; import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface; import com.kingsrook.qqq.backend.core.exceptions.QCodeException; +import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.utils.ExceptionUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils; @@ -51,6 +53,9 @@ import org.openjdk.nashorn.internal.runtime.Undefined; *******************************************************************************/ public class QJavaScriptExecutor implements QCodeExecutor { + private static final QLogger LOG = QLogger.getLogger(QJavaScriptExecutor.class); + + /******************************************************************************* ** @@ -93,6 +98,24 @@ public class QJavaScriptExecutor implements QCodeExecutor if(object instanceof ScriptObjectMirror scriptObjectMirror) { + try + { + if("Date".equals(scriptObjectMirror.getClassName())) + { + //////////////////////////////////////////////////////////////////// + // looks like the js Date is in UTC (is that because our JVM is?) // + // so the instant being in UTC matches // + //////////////////////////////////////////////////////////////////// + Double millis = (Double) scriptObjectMirror.callMember("getTime"); + Instant instant = Instant.ofEpochMilli(millis.longValue()); + return (instant); + } + } + catch(Exception e) + { + LOG.debug("Error unwrapping javascript date", e); + } + if(scriptObjectMirror.isArray()) { List result = new ArrayList<>(); @@ -104,6 +127,9 @@ public class QJavaScriptExecutor implements QCodeExecutor } else { + /////////////////////////////////////////////////////////////////////////////////////////////////////// + // last thing we know to try (though really, there's probably some check we should have around this) // + /////////////////////////////////////////////////////////////////////////////////////////////////////// Map result = new HashMap<>(); for(String key : scriptObjectMirror.keySet()) { diff --git a/qqq-language-support-javascript/src/test/java/com/kingsrook/qqq/languages/javascript/ExecuteCodeActionTest.java b/qqq-language-support-javascript/src/test/java/com/kingsrook/qqq/languages/javascript/ExecuteCodeActionTest.java index 43338983..e48dc604 100644 --- a/qqq-language-support-javascript/src/test/java/com/kingsrook/qqq/languages/javascript/ExecuteCodeActionTest.java +++ b/qqq-language-support-javascript/src/test/java/com/kingsrook/qqq/languages/javascript/ExecuteCodeActionTest.java @@ -23,6 +23,7 @@ package com.kingsrook.qqq.languages.javascript; import java.io.Serializable; +import java.time.Instant; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,7 +39,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType; import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder; import org.assertj.core.api.Assertions; +import org.assertj.core.data.Offset; import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -263,6 +266,7 @@ class ExecuteCodeActionTest extends BaseTest converter.convertObject("flatMap", {"a": 1, "b": "c"}); converter.convertObject("flatList", ["a", 1, "b", "c"]); converter.convertObject("mixedMap", {"a": [1, {"2": "3"}], "b": {"c": ["d"]}}); + converter.convertObject("date", new Date()); """, MapBuilder.of("converter", converter)); assertEquals(1, converter.getConvertedObject("one")); @@ -273,6 +277,9 @@ class ExecuteCodeActionTest extends BaseTest assertEquals(Map.of("a", 1, "b", "c"), converter.getConvertedObject("flatMap")); assertEquals(List.of("a", 1, "b", "c"), converter.getConvertedObject("flatList")); assertEquals(Map.of("a", List.of(1, Map.of("2", "3")), "b", Map.of("c", List.of("d"))), converter.getConvertedObject("mixedMap")); + assertThat(converter.getConvertedObject("date")).isInstanceOf(Instant.class); + assertThat(((Instant) converter.getConvertedObject("date")).toEpochMilli()) + .isCloseTo(Instant.now().toEpochMilli(), Offset.offset(2500L)); }