Repository: ChristopheBougere/asl-validator
Pull request #132 (2023-03-27 15:20:55)

fix: added missing properties to map
Easy change to add the new properties to the Map schema and update the state checker logic

massfords: closes #121 

Patch:
diff --git a/src/schemas/map.json b/src/schemas/map.json
index 7cd4f6f..1ef9af0 100644
--- a/src/schemas/map.json
+++ b/src/schemas/map.json
@@ -156,6 +156,21 @@
         },
         "required": ["ErrorEquals", "Next"]
       }
+    },
+    "ToleratedFailureCount": {
+      "type": "integer",
+      "minimum": 0
+    },
+    "ToleratedFailurePath": {
+      "$ref": "paths.json#/definitions/asl_ref_path"
+    },
+    "ToleratedFailurePercentage": {
+      "type": "integer",
+      "minimum": 0,
+      "maximum": 100
+    },
+    "ToleratedFailurePercentagePath": {
+      "$ref": "paths.json#/definitions/asl_ref_path"
     }
   },
   "required": ["Type"],
diff --git a/src/types.ts b/src/types.ts
index b6bddf7..7a722db 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -17,7 +17,8 @@ export enum StateMachineErrorCode {
   TaskTimeoutError = 'TASK_TIMEOUT',
   TaskHeartbeatError = 'TASK_HEARTBEAT',
   MapItemProcessorError = 'MAP_ITEM_PROCESSOR',
-   MapItemSelectorError = 'MAP_ITEM_SELECTOR'
+  MapItemSelectorError = 'MAP_ITEM_SELECTOR',
+  MapToleratedFailureError = 'MAP_TOLERATED_FAILURE',
 }
 export type StateMachineError = {
   'Error code': StateMachineErrorCode;
diff --git a/src/validator.ts b/src/validator.ts
index 5af0ca0..87f7851 100644
--- a/src/validator.ts
+++ b/src/validator.ts
@@ -83,7 +83,18 @@ export = function validator(definition: StateMachine, opts?: ValidationOptions):
                     props: ['End', 'Next'],
                     errorCode: StateMachineErrorCode.TerminalStateWithNextError})
             },
-
+            {
+                filter: IsMap,
+                checker: AtMostOne({
+                    props: ["ToleratedFailureCount", "ToleratedFailureCountPath"],
+                    errorCode: StateMachineErrorCode.MapToleratedFailureError})
+            },
+            {
+                filter: IsMap,
+                checker: AtMostOne({
+                    props: ["ToleratedFailurePercentage", "ToleratedFailurePercentagePath"],
+                    errorCode: StateMachineErrorCode.MapToleratedFailureError})
+            },
         ]))
     }
 


Test patch:
diff --git a/src/__tests__/definitions/invalid-map-tolerated-value.json b/src/__tests__/definitions/invalid-map-tolerated-value.json
new file mode 100644
index 0000000..66511b0
--- /dev/null
+++ b/src/__tests__/definitions/invalid-map-tolerated-value.json
@@ -0,0 +1,29 @@
+{
+  "Comment": "Map tolerated failure percentage cannot exceed 100",
+  "StartAt": "Map",
+  "States": {
+    "Map": {
+      "Type": "Map",
+      "Next": "Final State",
+      "ToleratedFailurePercentage": 105,
+      "InputPath": "$.input",
+      "ItemsPath": "$.items",
+      "MaxConcurrency": 0,
+      "Iterator": {
+        "StartAt": "Wait 20s",
+        "States": {
+          "Wait 20s": {
+            "Type": "Wait",
+            "Seconds": 20,
+            "End": true
+          }
+        }
+      },
+      "ResultPath": "$.result"
+    },
+    "Final State": {
+      "Type": "Pass",
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/invalid-map-tolerated.json b/src/__tests__/definitions/invalid-map-tolerated.json
new file mode 100644
index 0000000..8ce0f17
--- /dev/null
+++ b/src/__tests__/definitions/invalid-map-tolerated.json
@@ -0,0 +1,30 @@
+{
+  "Comment": "Map cannot have both ToleratedFailureCount and ToleratedFailureCountPath",
+  "StartAt": "Map",
+  "States": {
+    "Map": {
+      "Type": "Map",
+      "Next": "Final State",
+      "ToleratedFailureCount": 0,
+      "ToleratedFailureCountPath": "$.foo",
+      "InputPath": "$.input",
+      "ItemsPath": "$.items",
+      "MaxConcurrency": 0,
+      "Iterator": {
+        "StartAt": "Wait 20s",
+        "States": {
+          "Wait 20s": {
+            "Type": "Wait",
+            "Seconds": 20,
+            "End": true
+          }
+        }
+      },
+      "ResultPath": "$.result"
+    },
+    "Final State": {
+      "Type": "Pass",
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-map-tolerated.json b/src/__tests__/definitions/valid-map-tolerated.json
new file mode 100644
index 0000000..7580c19
--- /dev/null
+++ b/src/__tests__/definitions/valid-map-tolerated.json
@@ -0,0 +1,30 @@
+{
+  "Comment": "Map with optional tolerated failure properties",
+  "StartAt": "Map",
+  "States": {
+    "Map": {
+      "Type": "Map",
+      "Next": "Final State",
+      "ToleratedFailureCount": 0,
+      "ToleratedFailurePercentage": 0,
+      "InputPath": "$.input",
+      "ItemsPath": "$.items",
+      "MaxConcurrency": 0,
+      "Iterator": {
+        "StartAt": "Wait 20s",
+        "States": {
+          "Wait 20s": {
+            "Type": "Wait",
+            "Seconds": 20,
+            "End": true
+          }
+        }
+      },
+      "ResultPath": "$.result"
+    },
+    "Final State": {
+      "Type": "Pass",
+      "End": true
+    }
+  }
+}