Repository: ChristopheBougere/asl-validator
Pull request #176 (2025-05-20 03:36:46)

additional updates to schema definitions to support jsonata language
closes: #173 
closes: #174 




Patch:
diff --git a/src/schemas/map.json b/src/schemas/map.json
index 9f3e9e4..c86281e 100644
--- a/src/schemas/map.json
+++ b/src/schemas/map.json
@@ -25,6 +25,9 @@
     "ResultPath": {
       "$ref": "paths.json#/definitions/asl_result_path"
     },
+    "Items": {
+      "type": ["array", "string"]
+    },
     "ItemsPath": {
       "$ref": "paths.json#/definitions/asl_ref_path"
     },
diff --git a/src/schemas/wait.json b/src/schemas/wait.json
index 01baf01..79e7fe9 100644
--- a/src/schemas/wait.json
+++ b/src/schemas/wait.json
@@ -23,8 +23,15 @@
       "$ref": "paths.json#/definitions/asl_path"
     },
     "Seconds": {
-      "type": "number",
-      "minimum": 0
+      "oneOf": [
+        {
+          "type": "number",
+          "minimum": 0
+        },
+        {
+          "type": "string"
+        }
+      ]
     },
     "Timestamp": {
       "type": "string"
diff --git a/src/types.ts b/src/types.ts
index 022e9be..493b060 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -17,6 +17,7 @@ export enum StateMachineErrorCode {
   WaitDurationError = "WAIT_DURATION",
   TaskTimeoutError = "TASK_TIMEOUT",
   TaskHeartbeatError = "TASK_HEARTBEAT",
+  MapItemsError = "MAP_ITEMS_ERROR",
   MapItemProcessorError = "MAP_ITEM_PROCESSOR",
   MapItemSelectorError = "MAP_ITEM_SELECTOR",
   MapItemBatcherError = "MAP_ITEM_BATCHER",
diff --git a/src/validator.ts b/src/validator.ts
index 59aaf08..aee50d4 100644
--- a/src/validator.ts
+++ b/src/validator.ts
@@ -142,6 +142,13 @@ export = function validator(
             errorCode: StateMachineErrorCode.MapMaxConcurrencyError,
           }),
         },
+        {
+          filter: IsMap,
+          checker: AtMostOne({
+            props: ["Items", "ItemsPath"],
+            errorCode: StateMachineErrorCode.MapItemsError,
+          }),
+        },
         {
           filter: IsMap,
           checker: AtMostOne({


Test patch:
diff --git a/src/__tests__/definitions/invalid-map-items.asl.json b/src/__tests__/definitions/invalid-map-items.asl.json
new file mode 100644
index 0000000..ad07dbc
--- /dev/null
+++ b/src/__tests__/definitions/invalid-map-items.asl.json
@@ -0,0 +1,35 @@
+{
+  "QueryLanguage": "JSONata",
+  "Comment": "Items and ItemsPath are mutually exclusive in Map state.",
+  "StartAt": "SetupAnimals",
+  "States": {
+    "SetupAnimals": {
+      "Type": "Pass",
+      "Output": {
+        "animals": ["Lion", "Cheetah", "Elephant"]
+      },
+      "Next": "ProcessAnimals"
+    },
+    "ProcessAnimals": {
+      "Type": "Map",
+      "Items": "{% $states.input.animals %}",
+      "ItemsPath": "$.foo",
+      "ItemSelector": {
+        "animalName": "{% $states.context.Map.Item.Value %}"
+      },
+      "ItemProcessor": {
+        "StartAt": "NoOp",
+        "States": {
+          "NoOp": {
+            "Type": "Pass",
+            "End": true
+          }
+        }
+      },
+      "Output": {
+        "processResults": "{% $states.result %}"
+      },
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-map-items.asl.json b/src/__tests__/definitions/valid-map-items.asl.json
new file mode 100644
index 0000000..708caf1
--- /dev/null
+++ b/src/__tests__/definitions/valid-map-items.asl.json
@@ -0,0 +1,34 @@
+{
+  "QueryLanguage": "JSONata",
+  "Comment": "A test for valid map items in JSONata",
+  "StartAt": "SetupAnimals",
+  "States": {
+    "SetupAnimals": {
+      "Type": "Pass",
+      "Output": {
+        "animals": ["Lion", "Cheetah", "Elephant"]
+      },
+      "Next": "ProcessAnimals"
+    },
+    "ProcessAnimals": {
+      "Type": "Map",
+      "Items": "{% $states.input.animals %}",
+      "ItemSelector": {
+        "animalName": "{% $states.context.Map.Item.Value %}"
+      },
+      "ItemProcessor": {
+        "StartAt": "NoOp",
+        "States": {
+          "NoOp": {
+            "Type": "Pass",
+            "End": true
+          }
+        }
+      },
+      "Output": {
+        "processResults": "{% $states.result %}"
+      },
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-wait-jsonata.asl.json b/src/__tests__/definitions/valid-wait-jsonata.asl.json
new file mode 100644
index 0000000..6909e60
--- /dev/null
+++ b/src/__tests__/definitions/valid-wait-jsonata.asl.json
@@ -0,0 +1,16 @@
+{
+  "QueryLanguage": "JSONata",
+  "StartAt": "SetupWait",
+  "States": {
+    "SetupWait": {
+      "Type": "Pass",
+      "Next": "DoWait",
+      "Output": { "waitTime": "{% $round($random() * 10) %}" }
+    },
+    "DoWait": {
+      "Type": "Wait",
+      "Seconds": "{% $states.input.waitTime %}",
+      "End": true
+    }
+  }
+}