diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index 3f1f8f2..44af366 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -79,6 +79,12 @@ export declare const components: { {}, any >; + mutationWithNumberArg: FunctionReference< + "mutation", + "internal", + { a: number }, + any + >; schedule: FunctionReference< "mutation", "internal", diff --git a/convex/argumentsValidation.test.ts b/convex/argumentsValidation.test.ts index b67edb9..be20676 100644 --- a/convex/argumentsValidation.test.ts +++ b/convex/argumentsValidation.test.ts @@ -2,6 +2,10 @@ import { expect, test } from "vitest"; import { convexTest } from "../index"; import { api } from "./_generated/api"; import schema from "./schema"; +import counterSchema from "../counter/component/schema"; + +const counterModules = import.meta.glob("../counter/component/**/*.ts"); + test("query arguments validation", async () => { const t = convexTest(schema); @@ -43,3 +47,29 @@ test("optional fields", async () => { ); expect(result).toEqual("ok"); }); + +function testWithCounter() { + const t = convexTest(schema); + t.registerComponent( + "counter", + counterSchema, + counterModules + ); + return t; +} + +test("component mutation arguments validation", async () => { + const t = testWithCounter(); + expect( + await t.mutation(api.argumentsValidation.componentMutationWithNumberArg, { a: 42 }) + ).toEqual(42); + await expect( + t.mutation(api.argumentsValidation.componentMutationWithNumberArg, { + a: "bad" as any, + }), + ).rejects.toThrowError(/Validator error/); + expect(await t.mutation(api.argumentsValidation.componentMutationWithNumberArg, { + a: Number.POSITIVE_INFINITY, + }), + ).toEqual(Number.POSITIVE_INFINITY); +}); diff --git a/convex/argumentsValidation.ts b/convex/argumentsValidation.ts index 14e7e84..dced37a 100644 --- a/convex/argumentsValidation.ts +++ b/convex/argumentsValidation.ts @@ -1,5 +1,6 @@ import { v } from "convex/values"; import { action, mutation, query } from "./_generated/server"; +import { components } from "./_generated/api"; export const queryWithArgs = query({ args: { @@ -42,3 +43,13 @@ export const queryWithOptionalArgs = query({ return "ok"; }, }); + +export const componentMutationWithNumberArg = mutation({ + args: { a: v.any() }, + handler: (ctx, args) => { + const result = ctx.runMutation(components.counter.public.mutationWithNumberArg, { + a: args.a, + }); + return result; + }, +}); diff --git a/counter/component/_generated/api.d.ts b/counter/component/_generated/api.d.ts index 9926990..c70a7b3 100644 --- a/counter/component/_generated/api.d.ts +++ b/counter/component/_generated/api.d.ts @@ -38,6 +38,12 @@ export type Mounts = { >; count: FunctionReference<"query", "public", { name: string }, number>; mutationWithNestedQuery: FunctionReference<"mutation", "public", {}, any>; + mutationWithNumberArg: FunctionReference< + "mutation", + "public", + { a: number }, + any + >; schedule: FunctionReference<"mutation", "public", { name: string }, any>; }; }; diff --git a/counter/component/public.ts b/counter/component/public.ts index 81ce929..95b01a4 100644 --- a/counter/component/public.ts +++ b/counter/component/public.ts @@ -63,3 +63,10 @@ export const mutationWithNestedQuery = mutation({ return doc!.value; }, }); + +export const mutationWithNumberArg = mutation({ + args: { a: v.number() }, + handler: async (_ctx, args) => { + return args.a; + }, +}); diff --git a/index.ts b/index.ts index 4078b8f..dea3d14 100644 --- a/index.ts +++ b/index.ts @@ -1093,8 +1093,9 @@ function asyncSyscallImpl() { name, reference, functionHandle, - args: udfArgs, + args: udfArgsJson, } = args; + const udfArgs = jsonToConvex(udfArgsJson); const functionPath = await getFunctionPathFromAddress({ name, reference,