asl-validator
Version:
Amazon States Language validator
44 lines (40 loc) • 1.6 kB
text/typescript
import { JSONPath } from "jsonpath-plus";
import { AslChecker, StateMachineError, StateMachineErrorCode } from "../types";
// From the ASL spec:
// > A JSON object MUST NOT have duplicate field names after fields
// > ending with the characters ".$" are renamed to strip the ".$" suffix.
export const mustNotHaveDuplicateFieldNamesAfterEvaluation: AslChecker = (
definition
) => {
// find each `Parameters` or `ResultSelector` field
// for each one, examine each node's children for field names
// that will be in conflict after evaluation.
const errorMessages: StateMachineError[] = [];
const valuesToInspect: Record<string, unknown>[] = JSONPath<
Record<string, unknown>[]
>({
json: definition,
path: `$..[Parameters,ResultSelector]`,
});
const inspectKeys = (parent: Record<string, unknown>): void => {
const keys: Record<string, number> = {};
Object.keys(parent).forEach((key) => {
const keyPostEval = key.endsWith(".$")
? key.substring(0, key.length - 2)
: key;
const current = keys[keyPostEval];
if (current) {
errorMessages.push({
"Error code": StateMachineErrorCode.DuplicateFieldName,
Message: `A duplicate field will exist after renaming to strip the ".$" suffix from: ${key}.$`,
});
}
keys[keyPostEval] = current ? current + 1 : 1;
if (!!parent[key] && typeof parent[key] === "object") {
inspectKeys(parent[key] as Record<string, unknown>);
}
});
};
valuesToInspect.forEach((parent) => inspectKeys(parent));
return errorMessages;
};