Skip to content

Commit 6f1b139

Browse files
fix(valibotResolver): infinite loop (#655)
* update valibot version New version includes new methods. In particular for this branch `variant()` which can cause an infinite loop * this is a not a zod test * add new fixtures and tests to prove the issue * ensure exit condition is always met
1 parent 3805d3e commit 6f1b139

File tree

6 files changed

+65
-13
lines changed

6 files changed

+65
-13
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@
249249
"superstruct": "^1.0.3",
250250
"typanion": "^3.14.0",
251251
"typescript": "^5.1.6",
252-
"valibot": "^0.12.0",
252+
"valibot": "^0.24.1",
253253
"vest": "^4.6.11",
254254
"vite": "^4.4.9",
255255
"vite-tsconfig-paths": "^4.2.0",

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

valibot/src/__tests__/Form-native-validation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function TestComponent({ onSubmit }: Props) {
4242
);
4343
}
4444

45-
test("form's native validation with Zod", async () => {
45+
test("form's native validation with Valibot", async () => {
4646
const handleSubmit = vi.fn();
4747
render(<TestComponent onSubmit={handleSubmit} />);
4848

valibot/src/__tests__/__fixtures__/data.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import {
1212
array,
1313
boolean,
1414
required,
15-
union
15+
union,
16+
variant,
17+
literal,
1618
} from 'valibot';
1719

1820
export const schema = required(
@@ -29,7 +31,13 @@ export const schema = required(
2931
minLength(8, 'Must be at least 8 characters in length'),
3032
]),
3133
repeatPassword: string('Repeat Password is required'),
32-
accessToken: union([string('Access token should be a string'), number('Access token should be a number')], "access token is required"),
34+
accessToken: union(
35+
[
36+
string('Access token should be a string'),
37+
number('Access token should be a number'),
38+
],
39+
'access token is required',
40+
),
3341
birthYear: number('Please enter your birth year', [
3442
minValue(1900),
3543
maxValue(2013),
@@ -46,6 +54,14 @@ export const schema = required(
4654
}),
4755
);
4856

57+
export const schemaError = variant('type', [
58+
object({ type: literal('a') }),
59+
object({ type: literal('b') }),
60+
]);
61+
62+
export const validSchemaErrorData = { type: 'a' };
63+
export const invalidSchemaErrorData = { type: 'c' };
64+
4965
export const validData = {
5066
username: 'Doe',
5167
password: 'Password123_',

valibot/src/__tests__/valibot.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
/* eslint-disable no-console, @typescript-eslint/ban-ts-comment */
22
import { valibotResolver } from '..';
3-
import { schema, validData, fields, invalidData } from './__fixtures__/data';
3+
import {
4+
schema,
5+
validData,
6+
fields,
7+
invalidData,
8+
schemaError,
9+
validSchemaErrorData,
10+
invalidSchemaErrorData,
11+
} from './__fixtures__/data';
412
import * as valibot from 'valibot';
513

614
const shouldUseNativeValidation = false;
@@ -98,4 +106,34 @@ describe('valibotResolver', () => {
98106

99107
expect(result).toMatchSnapshot();
100108
});
109+
110+
it('should be able to validate variants', async () => {
111+
const result = await valibotResolver(schemaError, undefined, {
112+
mode: 'sync',
113+
})(validSchemaErrorData, undefined, {
114+
fields,
115+
shouldUseNativeValidation,
116+
});
117+
118+
expect(result).toEqual({
119+
errors: {},
120+
values: {
121+
type: 'a',
122+
},
123+
});
124+
});
125+
126+
it('should exit issue resolution if no path is set', async () => {
127+
const result = await valibotResolver(schemaError, undefined, {
128+
mode: 'sync',
129+
})(invalidSchemaErrorData, undefined, {
130+
fields,
131+
shouldUseNativeValidation,
132+
});
133+
134+
expect(result).toEqual({
135+
errors: {},
136+
values: {},
137+
});
138+
});
101139
});

valibot/src/valibot.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const parseErrors = (
1313
validateAllFieldCriteria: boolean,
1414
): FieldErrors => {
1515
const errors: Record<string, FieldError> = {};
16-
for (; valiErrors.issues.length; ) {
17-
const error = valiErrors.issues[0];
16+
17+
for (const error of valiErrors.issues) {
1818
if (!error.path) {
1919
continue;
2020
}
@@ -38,8 +38,6 @@ const parseErrors = (
3838
: error.message,
3939
) as FieldError;
4040
}
41-
42-
valiErrors.issues.shift();
4341
}
4442

4543
return errors;

0 commit comments

Comments
 (0)