Skip to content

Commit

Permalink
feat: Add support exactOptional (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
chimame authored Jan 23, 2025
1 parent 1318941 commit 2514c54
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 22 deletions.
27 changes: 17 additions & 10 deletions coercion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,10 @@ function generateReturnSchema<
) {
if ("pipe" in originalSchema) {
if (originalSchema.async && coercionSchema.async) {
return pipeAsync(
coercionSchema,
// @ts-expect-error
...originalSchema.pipe.slice(1),
);
return pipeAsync(coercionSchema, ...originalSchema.pipe.slice(1));
}
return pipe(
coercionSchema,
// @ts-expect-error
...originalSchema.pipe.slice(1),
);
// @ts-expect-error
return pipe(coercionSchema, ...originalSchema.pipe.slice(1));
}

return coercionSchema;
Expand Down Expand Up @@ -237,6 +230,20 @@ export function enableTypeCoercion<
schema: generateReturnSchema(type, coerceArray(arraySchema)),
};
}
case "exact_optional": {
// @ts-expect-error
const { schema: wrapSchema } = enableTypeCoercion(type.wrapped);

const exactOptionalSchema = {
...type,
wrapped: wrapSchema,
};

return {
coerced: false,
schema: generateReturnSchema(type, exactOptionalSchema),
};
}
case "optional":
case "nullish":
case "nullable":
Expand Down
18 changes: 13 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"semantic-release": "^22.0.8",
"tsup": "^8.0.0",
"typescript": "^5.5.4",
"valibot": "^0.34.0",
"valibot": "^1.0.0-beta.13",
"vitest": "2.0.5"
}
}
1 change: 0 additions & 1 deletion parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export function parseWithValibot<
}

const name = formatPaths(
// @ts-expect-error
e.path?.map((d) => d.key as string | number) ?? [],
);

Expand Down
27 changes: 27 additions & 0 deletions tests/coercion/schema/exactOptional.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { exactOptional, number, object, string } from "valibot";
import { describe, expect, test } from "vitest";
import { parseWithValibot } from "../../../parse";
import { createFormData } from "../../helpers/FormData";

describe("exactOptional", () => {
test("should pass only exactOptional", () => {
const schema = object({ name: string(), age: exactOptional(number()) });
const formData1 = createFormData("name", "Jane");
expect(parseWithValibot(formData1, { schema })).toMatchObject({
status: "success",
value: { name: "Jane" },
});

formData1.append("age", "20");
expect(parseWithValibot(formData1, { schema })).toMatchObject({
status: "success",
value: { name: "Jane", age: 20 },
});

const formData2 = createFormData("name", "Jane");
formData2.append("age", "abc");
expect(parseWithValibot(formData2, { schema })).toMatchObject({
error: { age: expect.anything() },
});
});
});
30 changes: 30 additions & 0 deletions tests/coercion/schema/exactOptionalAsync.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { exactOptionalAsync, number, objectAsync, string } from "valibot";
import { describe, expect, test } from "vitest";
import { parseWithValibot } from "../../../parse";
import { createFormData } from "../../helpers/FormData";

describe("exactOptionalAsync", () => {
test("should pass only exactOptional", async () => {
const schema = objectAsync({
name: string(),
age: exactOptionalAsync(number()),
});
const formData1 = createFormData("name", "Jane");
expect(await parseWithValibot(formData1, { schema })).toMatchObject({
status: "success",
value: { name: "Jane" },
});

formData1.append("age", "20");
expect(await parseWithValibot(formData1, { schema })).toMatchObject({
status: "success",
value: { name: "Jane", age: 20 },
});

const formData2 = createFormData("name", "Jane");
formData2.append("age", "abc");
expect(await parseWithValibot(formData2, { schema })).toMatchObject({
error: { age: expect.anything() },
});
});
});
9 changes: 4 additions & 5 deletions tests/coercion/schema/undefined.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@ describe("undefined", () => {
test("should pass only undefined", () => {
const schema = object({ name: string(), age: undefined_() });
const formData1 = createFormData("name", "Jane");
expect(parseWithValibot(formData1, { schema })).toMatchObject({
status: "success",
value: { name: "Jane" },
});

formData1.append("age", "");
expect(parseWithValibot(formData1, { schema })).toMatchObject({
status: "success",
value: { name: "Jane", age: undefined },
});

const formData2 = createFormData("name", "Jane");
expect(parseWithValibot(formData2, { schema })).toMatchObject({
error: { age: expect.anything() },
});

formData2.append("age", "20");
expect(parseWithValibot(formData2, { schema })).toMatchObject({
error: { age: expect.anything() },
Expand Down

0 comments on commit 2514c54

Please sign in to comment.