nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: ChristopheBougere/asl-validator
Pull request #46 (2020-02-21 11:49:56)

feat: expose text format errors
Give users a way to get humanized errors as string.

Leverage [`ajv's errorsText() method`](https://github.com/epoberezkin/ajv#errorstextarrayobject-errors--object-options---string)

- expose `errorsText` function
- use `errorsText` in the cli output



Patch:
diff --git a/bin/asl-validator.js b/bin/asl-validator.js
index c90073b..12da26c 100755
--- a/bin/asl-validator.js
+++ b/bin/asl-validator.js
@@ -18,7 +18,7 @@ function doneValid() {
 
 function doneInvalid(errors) {
   if (!program.silent) {
-    console.error('✕ State machine definition is invalid:', errors);
+    console.error('✕ State machine definition is invalid:\n', errors);
   }
   process.exit(1);
 }
@@ -56,7 +56,7 @@ try {
   if (result.isValid) {
     doneValid();
   } else {
-    doneInvalid(result.errors);
+    doneInvalid(result.errorsText());
   }
 } catch (e) {
   fail(`Validator exception: ${e}`);
diff --git a/src/validator.js b/src/validator.js
index 65bb87b..be94990 100644
--- a/src/validator.js
+++ b/src/validator.js
@@ -41,6 +41,7 @@ function validator(definition) {
   return {
     isValid: isJsonSchemaValid && !jsonPathErrors.length && !missingTransitionTargetErrors.length,
     errors: jsonPathErrors.concat(ajv.errors || []).concat(missingTransitionTargetErrors || []),
+    errorsText: (separator = '\n') => `${jsonPathErrors.map((e) => `${e.Code}: ${e.Message}`).join(separator)}${separator}${ajv.errorsText(ajv.errors, { separator })}${separator}${missingTransitionTargetErrors.map((e) => `${e.Code}: ${e.Message}`).join(separator)}`,
   };
 }
 


Test patch:
diff --git a/src/__tests__/validator.test.js b/src/__tests__/validator.test.js
index 5f98e85..a902d4e 100644
--- a/src/__tests__/validator.test.js
+++ b/src/__tests__/validator.test.js
@@ -11,15 +11,18 @@ describe('validator', () => {
     if (match) {
       it(`${match[1]}-${match[2]}`, () => {
         const definition = JSON.parse(fs.readFileSync(path.join(__dirname, 'definitions', files[i])));
-        const { isValid, errors } = validator(definition);
+        const { isValid, errors, errorsText } = validator(definition);
+        const textErrors = errorsText();
         if (match[1] === 'valid') {
           expect(isValid).toBeTruthy();
           expect(Array.isArray(errors)).toBeTruthy();
           expect(errors.length).toEqual(0);
+          expect(typeof textErrors).toBe('string');
         } else if (match[1] === 'invalid') {
           expect(isValid).toBeFalsy();
           expect(Array.isArray(errors)).toBeTruthy();
           expect(errors.length).toBeGreaterThan(0);
+          expect(typeof textErrors).toBe('string');
         }
       });
     }
Repository: ChristopheBougere/asl-validator
Pull request #58 (2020-10-14 21:01:30)

Add InputPath and OutputPath to the succeed state


Patch:
diff --git a/src/schemas/succeed.json b/src/schemas/succeed.json
index 5882f23..28c1ff1 100644
--- a/src/schemas/succeed.json
+++ b/src/schemas/succeed.json
@@ -9,6 +9,12 @@
     },
     "Comment": {
       "type": "string"
+    },
+    "OutputPath": {
+      "type": ["string", "null"]
+    },
+    "InputPath": {
+      "type": ["string", "null"]
     }
   },
   "required": ["Type"],


Test patch:
diff --git a/src/__tests__/definitions/valid-succeed.json b/src/__tests__/definitions/valid-succeed.json
new file mode 100644
index 0000000..db07a60
--- /dev/null
+++ b/src/__tests__/definitions/valid-succeed.json
@@ -0,0 +1,11 @@
+{
+    "Comment": "A simple example of the Amazon States Language using Succeed states",
+    "StartAt": "Hello",
+    "States": {
+        "Hello": {
+            "InputPath": "$.input",
+            "OutputPath": "$.output",
+            "Type": "Succeed"
+        }
+    }
+}
\ No newline at end of file
Repository: ChristopheBougere/asl-validator
Pull request #62 (2020-12-08 18:45:33)

Add Parameters to the parallel state


Patch:
diff --git a/src/schemas/parallel.json b/src/schemas/parallel.json
index d772909..b0bfcca 100644
--- a/src/schemas/parallel.json
+++ b/src/schemas/parallel.json
@@ -7,6 +7,9 @@
       "type": "string",
       "pattern": "^Parallel$"
     },
+    "Parameters": {
+      "type": "object"
+    },
     "Next": {
       "type": "string"
     },


Test patch:
diff --git a/src/__tests__/definitions/valid-parallel-parameters.json b/src/__tests__/definitions/valid-parallel-parameters.json
new file mode 100644
index 0000000..ace90ff
--- /dev/null
+++ b/src/__tests__/definitions/valid-parallel-parameters.json
@@ -0,0 +1,23 @@
+{
+  "StartAt": "Parallel State",
+  "States": {
+    "Parallel State": {
+      "Type": "Parallel",
+      "Branches": [
+        {
+          "StartAt": "Pass",
+          "States": {
+            "Pass": {
+              "Type": "Pass",
+              "End": true
+            }
+          }
+        }
+      ],
+      "Parameters": {
+        "stateName.$": "$$.State.Name"
+      },
+      "End": true
+    }
+  }
+}
\ No newline at end of file
Repository: ChristopheBougere/asl-validator
Pull request #63 (2020-12-09 20:19:48)

Add ResultSelector in map and parallel state


Patch:
diff --git a/src/schemas/map.json b/src/schemas/map.json
index c13ee3b..31fdd72 100644
--- a/src/schemas/map.json
+++ b/src/schemas/map.json
@@ -38,6 +38,9 @@
     "Parameters": {
       "type": "object"
     },
+    "ResultSelector": {
+      "type": "object"
+    },
     "Retry": {
       "type": "array",
       "items": {
diff --git a/src/schemas/parallel.json b/src/schemas/parallel.json
index b0bfcca..ed1c2b2 100644
--- a/src/schemas/parallel.json
+++ b/src/schemas/parallel.json
@@ -10,6 +10,9 @@
     "Parameters": {
       "type": "object"
     },
+    "ResultSelector": {
+      "type": "object"
+    },
     "Next": {
       "type": "string"
     },


Test patch:
diff --git a/src/__tests__/definitions/valid-map-resultSelector.json b/src/__tests__/definitions/valid-map-resultSelector.json
new file mode 100644
index 0000000..c297758
--- /dev/null
+++ b/src/__tests__/definitions/valid-map-resultSelector.json
@@ -0,0 +1,22 @@
+{
+    "StartAt": "Map State",
+    "States": {
+      "Map State": {
+        "Type": "Map",
+        "MaxConcurrency": 0,
+        "ResultSelector": {
+            "output.$": "$"
+        },
+        "Iterator": {
+          "StartAt": "Pass State",
+          "States": {
+            "Pass State": {
+              "Type": "Pass",
+              "End": true
+            }
+          }
+        },
+        "End": true
+      }
+    }
+}
\ No newline at end of file
diff --git a/src/__tests__/definitions/valid-parameters-resultSelector.json b/src/__tests__/definitions/valid-parameters-resultSelector.json
new file mode 100644
index 0000000..2e1e95c
--- /dev/null
+++ b/src/__tests__/definitions/valid-parameters-resultSelector.json
@@ -0,0 +1,23 @@
+{
+    "StartAt": "Parallel State",
+    "States": {
+      "Parallel State": {
+        "Type": "Parallel",
+        "ResultSelector": {
+          "output.$": "$"
+        },
+        "Branches": [
+          {
+            "StartAt": "State",
+            "States": {
+              "State": {
+                "Type": "Pass",
+                "End": true
+              }
+            }
+          }
+        ],
+        "End": true
+      }
+    }
+}
\ No newline at end of file
Repository: ChristopheBougere/asl-validator
Pull request #70 (2021-02-24 14:57:09)

Added support for CFN definitionSubstitutions
Related Issue: https://github.com/ChristopheBougere/asl-validator/issues/54 


Patch:
diff --git a/src/schemas/task.json b/src/schemas/task.json
index e60fecc..fa03445 100644
--- a/src/schemas/task.json
+++ b/src/schemas/task.json
@@ -25,7 +25,7 @@
     "Resource": {
       "oneOf": [{
         "type": "string",
-        "pattern": "^arn:aws:([a-z]|-)+:([a-z]|[0-9]|-)*:[0-9]*:([a-z]|-)+:[a-zA-Z0-9-_.]+(:(\\$LATEST|[a-zA-Z0-9-_]+))?$"
+        "pattern": "^(arn:aws:([a-z]|-)+:([a-z]|[0-9]|-)*:[0-9]*:([a-z]|-)+:[a-zA-Z0-9-_.]+(:(\\$LATEST|[a-zA-Z0-9-_]+))?$)|(\\${.*\\})"
       }, {
         "type": "object"
       }]


Test patch:
diff --git a/src/__tests__/definitions/invalid-cfn-definition-substitutions.json b/src/__tests__/definitions/invalid-cfn-definition-substitutions.json
new file mode 100644
index 0000000..9bdd23b
--- /dev/null
+++ b/src/__tests__/definitions/invalid-cfn-definition-substitutions.json
@@ -0,0 +1,18 @@
+{
+  "Comment": "https://states-language.net/spec.html#parameters",
+  "StartAt": "X",
+  "States": {
+    "X": {
+      "Type": "Task",
+      "Resource": "${lambdaArn",
+      "Parameters": {
+        "flagged": true,
+        "parts": {
+          "first.$": "$.vals[0]",
+          "last3.$": "$.vals[3:]"
+        }
+      },
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-cfn-definition-substitutions.json b/src/__tests__/definitions/valid-cfn-definition-substitutions.json
new file mode 100644
index 0000000..7bc55cb
--- /dev/null
+++ b/src/__tests__/definitions/valid-cfn-definition-substitutions.json
@@ -0,0 +1,18 @@
+{
+  "Comment": "https://states-language.net/spec.html#parameters",
+  "StartAt": "X",
+  "States": {
+    "X": {
+      "Type": "Task",
+      "Resource": "${lambdaArn}",
+      "Parameters": {
+        "flagged": true,
+        "parts": {
+          "first.$": "$.vals[0]",
+          "last3.$": "$.vals[3:]"
+        }
+      },
+      "End": true
+    }
+  }
+}
Repository: ChristopheBougere/asl-validator
Pull request #112 (2022-09-02 15:00:47)

fix: choice statements must have a Next in first level operators
As described in the [AWS Choice step documentation](https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-choice-state.html)

> Choice states don't support the End field. In addition, they use Next only inside their Choices field.


Patch:
diff --git a/src/schemas/choice.json b/src/schemas/choice.json
index 876a1ee..7721d9c 100644
--- a/src/schemas/choice.json
+++ b/src/schemas/choice.json
@@ -8,9 +8,6 @@
         "Variable": {
           "type": "string"
         },
-        "Next": {
-          "type": "string"
-        },
         "And": {
           "type": "array",
           "items": {
@@ -297,7 +294,17 @@
     "Choices": {
       "type": "array",
       "items": {
-        "$ref": "#/definitions/Operator"
+        "allOf": [{
+          "type": "object",
+          "properties": {
+            "Next": {
+              "type": "string"
+            }
+          },
+          "required": ["Next"]
+        }, {
+          "$ref": "#/definitions/Operator"
+        }]
       }
     },
     "Default": {


Test patch:
diff --git a/src/__tests__/definitions/invalid-choice-state.json b/src/__tests__/definitions/invalid-choice-state.json
new file mode 100644
index 0000000..4e2a7ce
--- /dev/null
+++ b/src/__tests__/definitions/invalid-choice-state.json
@@ -0,0 +1,20 @@
+{
+  "Comment": "An example showing that choice states are not allowed to go directly to the end of state machine",
+  "StartAt": "ChoiceState",
+  "States": {
+    "ChoiceState": {
+      "Type": "Choice",
+      "Choices": [{
+          "Variable": "$.foo",
+          "NumericEquals": 1,
+          "End": true
+        }
+      ],
+      "Default": "DefaultState"
+    },
+    "DefaultState": {
+      "Type": "Pass",
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-choice-state.json b/src/__tests__/definitions/valid-choice-state.json
index d0d5fdd..f29a6a4 100644
--- a/src/__tests__/definitions/valid-choice-state.json
+++ b/src/__tests__/definitions/valid-choice-state.json
@@ -15,8 +15,13 @@
           "Next": "FirstMatchState"
         },
         {
-          "Variable": "$.foo",
-          "NumericEquals": 2,
+          "Or": [{
+            "Variable": "$.foo",
+            "NumericEquals": 2
+          }, {
+            "Variable": "$.foo",
+            "NumericEquals": 3
+          }],
           "Next": "SecondMatchState"
         }
       ],
Repository: ChristopheBougere/asl-validator
Pull request #113 (2022-09-05 16:50:23)

Handle null values in `Parameters` and `ResultSelector`
When a `Parameters`/`ResultSelector` block has a `null` value somewhere inside it's identified as an object and so gets checked, resulting in a `TypeError`

Example error before the fix:

```
   TypeError: Cannot convert undefined or null to object
        at Function.keys (<anonymous>)

      17 |     const inspectKeys = (parent: Record<string, unknown>): void => {
      18 |         const keys: Record<string, number> = {};
    > 19 |         Object.keys(parent).forEach((key) => {
         |                ^
      20 |             const keyPostEval = key.endsWith(".$") ? key.substring(0, key.length - 2) : key;
      21 |             const current = keys[keyPostEval];
      22 |             if (current) {
```


Patch:
diff --git a/src/checks/duplicate-payload-template-fields.ts b/src/checks/duplicate-payload-template-fields.ts
index 045deca..ad85ebd 100644
--- a/src/checks/duplicate-payload-template-fields.ts
+++ b/src/checks/duplicate-payload-template-fields.ts
@@ -26,7 +26,7 @@ export const mustNotHaveDuplicateFieldNamesAfterEvaluation: AslChecker = (defini
                 });
             }
             keys[keyPostEval] = current ? current + 1 : 1;
-            if (typeof parent[key] === "object") {
+            if (!!parent[key] && typeof parent[key] === "object") {
                 inspectKeys(parent[key] as Record<string, unknown>);
             }
         });


Test patch:
diff --git a/src/__tests__/definitions/valid-null-parameter.json b/src/__tests__/definitions/valid-null-parameter.json
new file mode 100644
index 0000000..4216d89
--- /dev/null
+++ b/src/__tests__/definitions/valid-null-parameter.json
@@ -0,0 +1,16 @@
+{
+    "StartAt": "Hello",
+    "States": {
+        "Hello": {
+            "Type": "Task",
+            "Resource": "arn:aws:lambda:us-east-1:123456789012:function:foo",
+            "Parameters": {
+                "foo": null
+            },
+            "Next": "Goodbye"
+        },
+        "Goodbye": {
+            "Type": "Succeed"
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/__tests__/definitions/valid-null-resultSelector.json b/src/__tests__/definitions/valid-null-resultSelector.json
new file mode 100644
index 0000000..a73e01e
--- /dev/null
+++ b/src/__tests__/definitions/valid-null-resultSelector.json
@@ -0,0 +1,20 @@
+{
+    "StartAt": "Hello",
+    "States": {
+        "Hello": {
+            "Type": "Task",
+            "Resource": "arn:aws:lambda:us-east-1:123456789012:function:foo",
+            "Parameters": {
+                "foo": "abc"
+            },
+            "ResultSelector": {
+                "absurd": null,
+                "output.$": "$"
+            },
+            "Next": "Goodbye"
+        },
+        "Goodbye": {
+            "Type": "Succeed"
+        }
+    }
+}
\ No newline at end of file
Repository: ChristopheBougere/asl-validator
Pull request #117 (2023-01-25 21:02:07)

fix: add `credentials` field to the `task` schema
Add the `Credentials` field as per the ASL specification for the `Task` state.

> A Task State MAY include a "Credentials" field, whose value MUST be a JSON object whose value is defined by the interpreter. The States language does not constrain the value of the "Credentials" field. The interpreter will use the specified credentials to execute the work identified by the state's "Resource" field.


Patch:
diff --git a/src/schemas/task.json b/src/schemas/task.json
index 420d0db..643755a 100644
--- a/src/schemas/task.json
+++ b/src/schemas/task.json
@@ -120,6 +120,9 @@
     },
     "Parameters": {
       "$ref": "paths.json#/definitions/asl_payload_template"
+    },
+    "Credentials": {
+      "$ref": "paths.json#/definitions/asl_payload_template"
     }
   },
   "oneOf": [{


Test patch:
diff --git a/src/__tests__/definitions/invalid-task-credentials-null.json b/src/__tests__/definitions/invalid-task-credentials-null.json
new file mode 100644
index 0000000..1b77788
--- /dev/null
+++ b/src/__tests__/definitions/invalid-task-credentials-null.json
@@ -0,0 +1,12 @@
+{
+  "Comment": "https://states-language.net/spec.html#task-state",
+  "StartAt": "X",
+  "States": {
+    "X": {
+      "Type": "Task",
+      "Resource": "arn:aws:swf:us-east-1:123456789012:task:X",
+      "Credentials": null,
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/invalid-task-credentials-object.json b/src/__tests__/definitions/invalid-task-credentials-object.json
new file mode 100644
index 0000000..578ed64
--- /dev/null
+++ b/src/__tests__/definitions/invalid-task-credentials-object.json
@@ -0,0 +1,16 @@
+{
+  "Comment": "https://states-language.net/spec.html#task-state",
+  "StartAt": "X",
+  "States": {
+    "X": {
+      "Type": "Task",
+      "Resource": "arn:aws:swf:us-east-1:123456789012:task:X",
+      "Credentials": {
+        "flag": true,
+        "expectPath.$": "not a path",
+        "baz": 5
+      },
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-task-credentials.json b/src/__tests__/definitions/valid-task-credentials.json
new file mode 100644
index 0000000..1e88546
--- /dev/null
+++ b/src/__tests__/definitions/valid-task-credentials.json
@@ -0,0 +1,19 @@
+{
+  "Comment": "https://states-language.net/spec.html#task-state",
+  "StartAt": "X",
+  "States": {
+    "X": {
+      "Type": "Task",
+      "Resource": "arn:aws:swf:us-east-1:123456789012:task:X",
+      "Credentials": {
+        "flag": true,
+        "parts": {
+          "foo.$": "$.vals[0]",
+          "bar.$": "$.vals[3]"
+        },
+        "baz": 5
+      },
+      "End": true
+    }
+  }
+}