diff --git a/packages/taco/src/conditions/sequential.ts b/packages/taco/src/conditions/sequential.ts index ae45bc2d..2f996eb2 100644 --- a/packages/taco/src/conditions/sequential.ts +++ b/packages/taco/src/conditions/sequential.ts @@ -36,6 +36,25 @@ export const sequentialConditionSchema: z.ZodSchema = baseConditionSchema message: 'Exceeded max nested depth of 2 for multi-condition type', path: ['conditionVariables'], }, // Max nested depth of 2 + ) + .refine( + // check for duplicate var names + (condition) => { + const seen = new Set(); + return condition.conditionVariables.every( + (child: ConditionVariableProps) => { + if (seen.has(child.varName)) { + return false; + } + seen.add(child.varName); + return true; + }, + ); + }, + { + message: 'Duplicate variable names are not allowed', + path: ['conditionVariables'], + }, ); export type ConditionVariableProps = z.infer; diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 1fde2859..08ad8397 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -62,6 +62,33 @@ describe('validation', () => { }); }); + it('rejects duplication variable names', () => { + const result = SequentialCondition.validate(sequentialConditionSchema, { + conditionVariables: [ + { + varName: 'var1', + condition: testRpcConditionObj, + }, + { + varName: 'var2', + condition: testTimeConditionObj, + }, + { + varName: 'var1', + condition: testContractConditionObj, + }, + ], + }); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + conditionVariables: { + _errors: ['Duplicate variable names are not allowed'], + }, + }); + }); + it('rejects > max number of condition variables', () => { const tooManyConditionVariables = new Array(6); for (let i = 0; i < tooManyConditionVariables.length; i++) { @@ -78,7 +105,7 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ conditionVariables: { - _errors: [`Array must contain at most 5 element(s)`], + _errors: ['Array must contain at most 5 element(s)'], }, }); });