fluent-convex 0.11.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,403 @@
1
+ ![logo](apps/docs/public/logo-128.png)
2
+
3
+ # Fluent Convex
4
+
5
+ A fluent API builder for Convex functions with middleware support, inspired by [oRPC](https://orpc.unnoq.com/).
6
+
7
+ **[Live Docs & Interactive Showcase](https://friendly-zebra-716.convex.site)** -- see every feature in action with live demos and real source code.
8
+
9
+ ## Features
10
+
11
+ - **Middleware support** - Compose reusable middleware for authentication, logging, and more ([docs](https://friendly-zebra-716.convex.site/middleware))
12
+ - **Callable builders** - Define logic once, call it directly from other handlers, and register it multiple ways ([docs](https://friendly-zebra-716.convex.site/reusable-chains))
13
+ - **Type-safe** - Full TypeScript support with type inference
14
+ - **Fluent API** - Chain methods for a clean, readable syntax ([docs](https://friendly-zebra-716.convex.site/basics))
15
+ - **Plugin system** - Extend with plugins like `fluent-convex/zod` for Zod schema support ([docs](https://friendly-zebra-716.convex.site/zod-plugin))
16
+ - **Extensible** - Build your own plugins with the `_clone()` factory pattern ([docs](https://friendly-zebra-716.convex.site/custom-plugins))
17
+ - **Works with Convex** - Built on top of Convex's function system
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install fluent-convex
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ > For a complete walkthrough with live demos, see the **[Getting Started guide](https://friendly-zebra-716.convex.site/)**.
28
+
29
+ **Important:** All functions must end with `.public()` or `.internal()` to be registered with Convex.
30
+
31
+ ```ts
32
+ import { createBuilder } from "fluent-convex";
33
+ import { v } from "convex/values";
34
+ import type { DataModel } from "./_generated/dataModel";
35
+
36
+ const convex = createBuilder<DataModel>();
37
+
38
+ // Simple query
39
+ export const listNumbers = convex
40
+ .query()
41
+ .input({ count: v.number() })
42
+ .handler(async (context, input) => {
43
+ const numbers = await context.db
44
+ .query("numbers")
45
+ .order("desc")
46
+ .take(input.count);
47
+
48
+ return { numbers: numbers.map((n) => n.value) };
49
+ })
50
+ .public(); // Must end with .public() or .internal()
51
+
52
+ // With middleware
53
+ const authMiddleware = convex.query().createMiddleware(async (context, next) => {
54
+ const identity = await context.auth.getUserIdentity();
55
+ if (!identity) {
56
+ throw new Error("Unauthorized");
57
+ }
58
+
59
+ return next({
60
+ ...context,
61
+ user: {
62
+ id: identity.subject,
63
+ name: identity.name ?? "Unknown",
64
+ },
65
+ });
66
+ });
67
+
68
+ export const listNumbersAuth = convex
69
+ .query()
70
+ .use(authMiddleware)
71
+ .input({ count: v.number() })
72
+ .handler(async (context, input) => {
73
+ const numbers = await context.db
74
+ .query("numbers")
75
+ .order("desc")
76
+ .take(input.count);
77
+
78
+ return {
79
+ viewer: context.user.name, // user is available from middleware!
80
+ numbers: numbers.map((n) => n.value),
81
+ };
82
+ })
83
+ .public();
84
+ ```
85
+
86
+ ## Validation
87
+
88
+ > See the **[Validation docs](https://friendly-zebra-716.convex.site/validation)** for a side-by-side comparison of all three approaches with live demos.
89
+
90
+ fluent-convex supports three flavors of input validation through the same `.input()` API:
91
+
92
+ 1. **Property validators** -- `{ count: v.number() }` (simplest)
93
+ 2. **Object validators** -- `v.object({ count: v.number() })` (with `.returns()` support)
94
+ 3. **Zod schemas** -- `z.object({ count: z.number().min(1) })` (via the Zod plugin)
95
+
96
+ ## Middleware
97
+
98
+ > See the **[Middleware docs](https://friendly-zebra-716.convex.site/middleware)** for detailed examples of both patterns.
99
+
100
+ There are two main middleware patterns:
101
+
102
+ - **Context-enrichment** -- adds new properties to the context (e.g. `ctx.user`)
103
+ - **Onion (wrap)** -- runs code before *and* after the handler (e.g. timing, error handling)
104
+
105
+ ## Reusable Chains & Callables
106
+
107
+ > See the **[Reusable Chains docs](https://friendly-zebra-716.convex.site/reusable-chains)** for full examples with live demos.
108
+
109
+ Because the builder is immutable, you can stop the chain at any point and reuse that partial builder later. A builder with a `.handler()` but no `.public()` / `.internal()` is called a **callable** -- a fully-typed function you can:
110
+
111
+ 1. **Call directly** from inside other handlers (no additional Convex function invocation)
112
+ 2. **Register** as a standalone Convex endpoint
113
+ 3. **Extend** with more middleware and register multiple ways
114
+
115
+ ```ts
116
+ // 1. Define a callable - NOT yet registered with Convex
117
+ const getNumbers = convex
118
+ .query()
119
+ .input({ count: v.number() })
120
+ .handler(async (ctx, args) => {
121
+ const rows = await ctx.db.query("numbers").order("desc").take(args.count);
122
+ return rows.map((r) => r.value);
123
+ });
124
+
125
+ // 2. Register it as a public query
126
+ export const listNumbers = getNumbers.public();
127
+
128
+ // 3. Call it directly from inside another handler - no additional function invocation!
129
+ export const getNumbersWithTimestamp = convex
130
+ .query()
131
+ .input({ count: v.number() })
132
+ .handler(async (ctx, args) => {
133
+ const numbers = await getNumbers(ctx, args); // <-- direct call
134
+ return { numbers, fetchedAt: Date.now() };
135
+ })
136
+ .public();
137
+
138
+ // 4. Register the same callable with different middleware
139
+ export const listNumbersProtected = getNumbers.use(authMiddleware).public();
140
+ export const listNumbersLogged = getNumbers.use(withLogging("logged")).public();
141
+ ```
142
+
143
+ The callable syntax is `callable(ctx, args)` -- the first argument passes the context (so the middleware chain runs with the right ctx), the second passes the validated arguments.
144
+
145
+ ## Plugins
146
+
147
+ ### Zod Plugin (`fluent-convex/zod`)
148
+
149
+ > See the **[Zod Plugin docs](https://friendly-zebra-716.convex.site/zod-plugin)** for live demos including refinement validation.
150
+
151
+ The Zod plugin adds Zod schema support for `.input()` and `.returns()`, with **full runtime validation** including refinements (`.min()`, `.max()`, `.email()`, etc.).
152
+
153
+ ```bash
154
+ npm install zod convex-helpers
155
+ ```
156
+
157
+ > **Note:** `zod` and `convex-helpers` are optional peer dependencies of `fluent-convex`. They're only needed if you use the Zod plugin.
158
+
159
+ Usage:
160
+
161
+ ```ts
162
+ import { createBuilder } from "fluent-convex";
163
+ import { WithZod } from "fluent-convex/zod";
164
+ import { z } from "zod";
165
+ import type { DataModel } from "./_generated/dataModel";
166
+
167
+ const convex = createBuilder<DataModel>();
168
+
169
+ export const listNumbers = convex
170
+ .query()
171
+ .extend(WithZod) // Enable Zod support
172
+ .input(
173
+ z.object({
174
+ count: z.number().int().min(1).max(100), // Refinements enforced at runtime!
175
+ })
176
+ )
177
+ .returns(z.object({ numbers: z.array(z.number()) }))
178
+ .handler(async (context, input) => {
179
+ const numbers = await context.db.query("numbers").take(input.count);
180
+ return { numbers: numbers.map((n) => n.value) };
181
+ })
182
+ .public();
183
+ ```
184
+
185
+ Key features:
186
+ - **Full runtime validation** - Zod refinements (`.min()`, `.max()`, `.email()`, `.regex()`, etc.) are enforced server-side. Args are validated before the handler runs; return values after.
187
+ - **Structural conversion** - Zod schemas are automatically converted to Convex validators for Convex's built-in validation.
188
+ - **Composable** - `.extend(WithZod)` preserves the `WithZod` type through `.use()`, `.input()`, and `.returns()` chains.
189
+ - **Plain validators still work** - You can mix Zod and Convex validators in the same builder chain.
190
+
191
+ ## Extensibility
192
+
193
+ > See the **[Custom Plugins docs](https://friendly-zebra-716.convex.site/custom-plugins)** for a complete worked example with live demo.
194
+
195
+ You can extend the builder with your own plugins by subclassing `ConvexBuilderWithFunctionKind` and overriding the `_clone()` factory method.
196
+
197
+ ### Writing a Plugin
198
+
199
+ The `_clone()` method is called internally by `.use()`, `.input()`, and `.returns()` to create new builder instances. By overriding it, your plugin's type is preserved through the entire builder chain.
200
+
201
+ ```ts
202
+ import {
203
+ ConvexBuilderWithFunctionKind,
204
+ type GenericDataModel,
205
+ type FunctionType,
206
+ type Context,
207
+ type EmptyObject,
208
+ type ConvexArgsValidator,
209
+ type ConvexReturnsValidator,
210
+ type ConvexBuilderDef,
211
+ } from "fluent-convex";
212
+
213
+ class MyPlugin<
214
+ TDataModel extends GenericDataModel = GenericDataModel,
215
+ TFunctionType extends FunctionType = FunctionType,
216
+ TCurrentContext extends Context = EmptyObject,
217
+ TArgsValidator extends ConvexArgsValidator | undefined = undefined,
218
+ TReturnsValidator extends ConvexReturnsValidator | undefined = undefined,
219
+ > extends ConvexBuilderWithFunctionKind<
220
+ TDataModel,
221
+ TFunctionType,
222
+ TCurrentContext,
223
+ TArgsValidator,
224
+ TReturnsValidator
225
+ > {
226
+ // Accept both builder instances (from .extend()) and raw defs (from _clone())
227
+ constructor(builderOrDef: any) {
228
+ const def =
229
+ builderOrDef instanceof ConvexBuilderWithFunctionKind
230
+ ? (builderOrDef as any).def
231
+ : builderOrDef;
232
+ super(def);
233
+ }
234
+
235
+ // Override _clone() to preserve MyPlugin through the chain
236
+ protected _clone(def: ConvexBuilderDef<any, any, any>): any {
237
+ return new MyPlugin(def);
238
+ }
239
+
240
+ // Add custom methods
241
+ myCustomMethod(param: string) {
242
+ console.log("Custom method called with:", param);
243
+ return this;
244
+ }
245
+ }
246
+ ```
247
+
248
+ Usage:
249
+
250
+ ```ts
251
+ export const myQuery = convex
252
+ .query()
253
+ .extend(MyPlugin)
254
+ .myCustomMethod("hello") // Custom method from plugin
255
+ .use(authMiddleware) // .use() preserves MyPlugin type
256
+ .input({ count: v.number() })
257
+ .handler(async (ctx, input) => { ... })
258
+ .public();
259
+ ```
260
+
261
+ ### Composing Multiple Plugins
262
+
263
+ Plugins can be composed with `.extend()`:
264
+
265
+ ```ts
266
+ export const myQuery = convex
267
+ .query()
268
+ .extend(MyPlugin)
269
+ .extend(WithZod) // WithZod overrides .input()/.returns() from MyPlugin
270
+ .myCustomMethod("hello")
271
+ .input(z.object({ count: z.number() }))
272
+ .handler(async (ctx, input) => { ... })
273
+ .public();
274
+ ```
275
+
276
+ ## Flexible Method Ordering
277
+
278
+ The builder API is flexible about method ordering, allowing you to structure your code in the way that makes the most sense for your use case.
279
+
280
+ ### Middleware After Handler
281
+
282
+ You can add middleware **after** defining the handler, which is useful when you want to wrap existing handlers with additional functionality:
283
+
284
+ ```ts
285
+ export const getNumbers = convex
286
+ .query()
287
+ .input({ count: v.number() })
288
+ .handler(async (context, input) => {
289
+ return await context.db.query("numbers").take(input.count);
290
+ })
291
+ .use(authMiddleware) // Middleware added after handler
292
+ .public();
293
+ ```
294
+
295
+ ### Callable Builders
296
+
297
+ Before registering a function with `.public()` or `.internal()`, the builder is **callable** -- you can invoke it directly from other handlers (see [Reusable Chains](#reusable-chains--callables) above) or use it in tests:
298
+
299
+ ```ts
300
+ // A callable (not yet registered)
301
+ const getDouble = convex
302
+ .query()
303
+ .input({ count: v.number() })
304
+ .handler(async (context, input) => {
305
+ return { doubled: input.count * 2 };
306
+ });
307
+
308
+ // Call it from another handler
309
+ export const tripled = convex
310
+ .query()
311
+ .input({ count: v.number() })
312
+ .handler(async (ctx, input) => {
313
+ const { doubled } = await getDouble(ctx, input);
314
+ return { tripled: doubled + input.count };
315
+ })
316
+ .public();
317
+
318
+ // Or call it directly in tests
319
+ const mockContext = {} as any;
320
+ const result = await getDouble(mockContext, { count: 5 });
321
+ console.log(result); // { doubled: 10 }
322
+
323
+ // Register it when you also need it as a standalone endpoint
324
+ export const doubleNumber = getDouble.public();
325
+ ```
326
+
327
+ ### Method Ordering Rules
328
+
329
+ - **`.returns()`** must be called **before** `.handler()`
330
+ - **`.use()`** can be called **before or after** `.handler()`
331
+ - **`.public()`** or **`.internal()`** must be called **after** `.handler()` and is **required** to register the function
332
+ - Functions are **callable** before registration, **non-callable** after registration
333
+ - **All exported functions must end with `.public()` or `.internal()`** - functions without registration will not be available in your Convex API
334
+
335
+ ## API
336
+
337
+ ### Methods
338
+
339
+ - `.query()` - Define a Convex query
340
+ - `.mutation()` - Define a Convex mutation
341
+ - `.action()` - Define a Convex action
342
+ - `.public()` - Register the function as public (required to register)
343
+ - `.internal()` - Register the function as internal/private (required to register)
344
+ - `.input(validator)` - Set input validation (Convex validators)
345
+ - `.returns(validator)` - Set return validation (Convex validators)
346
+ - `.use(middleware)` - Apply middleware
347
+ - `.createMiddleware(fn)` - Create a middleware function
348
+ - `.handler(fn)` - Define the function handler
349
+ - `.extend(plugin)` - Extend the builder with a plugin class
350
+
351
+ ## Caveats
352
+
353
+ ### Circular types when calling `api.*` in the same file
354
+
355
+ When a function calls other functions via `api.*` in the same file, and those functions don't have explicit `.returns()` validators, TypeScript may report circular initializer errors (TS7022). This is a standard Convex/TypeScript limitation, not specific to fluent-convex. Workarounds:
356
+ 1. Add `.returns()` to the **called** functions -- this gives them explicit return types, breaking the cycle
357
+ 2. Move the calling function to a separate file
358
+ 3. Use `internal.*` from a different module
359
+
360
+ ## Development
361
+
362
+ This is a monorepo using npm workspaces:
363
+
364
+ - `/packages/fluent-convex` - The core library (includes the Zod plugin at `fluent-convex/zod`)
365
+ - `/apps/example` - Example Convex app
366
+ - `/apps/docs` - Interactive docs & showcase site ([live](https://friendly-zebra-716.convex.site))
367
+
368
+ ### Setup
369
+
370
+ ```bash
371
+ npm install
372
+ ```
373
+
374
+ This will install dependencies for all workspaces.
375
+
376
+ ### Building
377
+
378
+ ```bash
379
+ npm run build
380
+ ```
381
+
382
+ ### Running tests
383
+
384
+ ```bash
385
+ npm test
386
+ ```
387
+
388
+ ### Running the example
389
+
390
+ ```bash
391
+ cd apps/example
392
+ npm run dev
393
+ ```
394
+
395
+ ### Running the docs locally
396
+
397
+ ```bash
398
+ npm run docs:dev
399
+ ```
400
+
401
+ ## Credits
402
+
403
+ Borrowed heavily from [oRPC](https://orpc.unnoq.com/learn-and-contribute/overview) and helped out by AI.
@@ -1 +1 @@
1
- {"version":3,"file":"ConvexBuilderWithHandler.d.ts","sourceRoot":"","sources":["../src/ConvexBuilderWithHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConvexBuilderWithHandler.d.ts","sourceRoot":"","sources":["../src/ConvexBuilderWithHandler.ts"],"names":[],"mappings":"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"}
@@ -5,8 +5,8 @@ export class ConvexBuilderWithHandler {
5
5
  constructor(def) {
6
6
  this.def = def;
7
7
  // Create a callable function that delegates to _call
8
- const callable = ((context) => {
9
- return this._call(context);
8
+ const callable = ((context, args) => {
9
+ return this._call(context, args);
10
10
  });
11
11
  // Copy properties from prototype to the callable function
12
12
  // This is a bit of a hack to make the function behave like an instance of the class
@@ -28,14 +28,12 @@ export class ConvexBuilderWithHandler {
28
28
  return extendBuilder(this, fnOrCls);
29
29
  }
30
30
  // Internal method to handle the call
31
- _call(context) {
31
+ async _call(context, args) {
32
32
  const { handler, middlewares } = this.def;
33
33
  if (!handler) {
34
34
  throw new Error("Handler not set.");
35
35
  }
36
- return async (args) => {
37
- return this._executeWithMiddleware(middlewares, context, handler, args);
38
- };
36
+ return this._executeWithMiddleware(middlewares, context, handler, args);
39
37
  }
40
38
  /**
41
39
  * Execute middleware as an onion: each middleware's `next()` runs the rest
@@ -1 +1 @@
1
- {"version":3,"file":"ConvexBuilderWithHandler.js","sourceRoot":"","sources":["../src/ConvexBuilderWithHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConvexBuilderWithHandler.js","sourceRoot":"","sources":["../src/ConvexBuilderWithHandler.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -28,7 +28,7 @@ export type ActionCtx<DataModel extends GenericDataModel = GenericDataModel> = G
28
28
  export type FunctionType = "query" | "mutation" | "action";
29
29
  export type Visibility = "public" | "internal";
30
30
  export type CallableBuilder<TCurrentContext extends Context, TArgsValidator extends ConvexArgsValidator | undefined, THandlerReturn> = {
31
- (context: TCurrentContext): (args: InferredArgs<TArgsValidator>) => Promise<THandlerReturn>;
31
+ (context: TCurrentContext, args: InferredArgs<TArgsValidator>): Promise<THandlerReturn>;
32
32
  };
33
33
  export interface ConvexBuilderDef<TFunctionType extends FunctionType | undefined = undefined, TArgsValidator extends ConvexArgsValidator | undefined = undefined, TReturnsValidator extends ConvexReturnsValidator | undefined = undefined> {
34
34
  functionType?: TFunctionType;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluent-convex",
3
- "version": "0.11.1",
3
+ "version": "0.12.3",
4
4
  "description": "A fluent API builder for Convex functions with middleware support, inspired by oRPC",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "typecheck": "tsc --noEmit",
29
29
  "test": "vitest run --typecheck",
30
30
  "dev:test": "vitest --typecheck",
31
- "prepublishOnly": "npm run build"
31
+ "prepublishOnly": "node -e \"require('fs').copyFileSync('../../README.md','README.md')\" && npm run build"
32
32
  },
33
33
  "keywords": [
34
34
  "convex",
@@ -44,6 +44,7 @@
44
44
  "publishConfig": {
45
45
  "access": "public"
46
46
  },
47
+ "homepage": "https://friendly-zebra-716.convex.site/",
47
48
  "repository": {
48
49
  "type": "git",
49
50
  "url": "git+https://github.com/mikecann/fluent-convex.git"
@@ -65,8 +65,11 @@ export class ConvexBuilderWithHandler<
65
65
  this.def = def;
66
66
 
67
67
  // Create a callable function that delegates to _call
68
- const callable = ((context: TCurrentContext) => {
69
- return this._call(context);
68
+ const callable = ((
69
+ context: TCurrentContext,
70
+ args: InferredArgs<TArgsValidator>
71
+ ) => {
72
+ return this._call(context, args);
70
73
  }) as any;
71
74
 
72
75
  // Copy properties from prototype to the callable function
@@ -98,23 +101,22 @@ export class ConvexBuilderWithHandler<
98
101
  }
99
102
 
100
103
  // Internal method to handle the call
101
- private _call(
102
- context: TCurrentContext
103
- ): (args: InferredArgs<TArgsValidator>) => Promise<THandlerReturn> {
104
+ private async _call(
105
+ context: TCurrentContext,
106
+ args: InferredArgs<TArgsValidator>
107
+ ): Promise<THandlerReturn> {
104
108
  const { handler, middlewares } = this.def;
105
109
 
106
110
  if (!handler) {
107
111
  throw new Error("Handler not set.");
108
112
  }
109
113
 
110
- return async (args: InferredArgs<TArgsValidator>) => {
111
- return this._executeWithMiddleware(
112
- middlewares,
113
- context as Context,
114
- handler,
115
- args
116
- );
117
- };
114
+ return this._executeWithMiddleware(
115
+ middlewares,
116
+ context as Context,
117
+ handler,
118
+ args
119
+ );
118
120
  }
119
121
 
120
122
  /**
@@ -222,7 +222,7 @@ describe("Builder Core", () => {
222
222
 
223
223
  // Should be callable
224
224
  assertType<
225
- (context: any) => (args: { count: number }) => Promise<string>
225
+ (context: any, args: { count: number }) => Promise<string>
226
226
  >(nonRegisteredQuery);
227
227
  });
228
228
 
@@ -308,10 +308,9 @@ describe("Builder Core", () => {
308
308
  // Should still be callable after middleware
309
309
  assertType<
310
310
  (
311
- context: any
312
- ) => (args: {
313
- count: number;
314
- }) => Promise<{ count: number; userId: string }>
311
+ context: any,
312
+ args: { count: number }
313
+ ) => Promise<{ count: number; userId: string }>
315
314
  >(callableQuery);
316
315
  });
317
316
 
@@ -348,8 +347,9 @@ describe("Builder Core", () => {
348
347
  // Should still be callable after multiple middleware
349
348
  assertType<
350
349
  (
351
- context: any
352
- ) => (args: { count: number }) => Promise<{ count: number }>
350
+ context: any,
351
+ args: { count: number }
352
+ ) => Promise<{ count: number }>
353
353
  >(callableQuery);
354
354
  });
355
355
 
@@ -362,7 +362,7 @@ describe("Builder Core", () => {
362
362
  });
363
363
 
364
364
  // Should be callable
365
- assertType<(context: any) => (args: { value: number }) => Promise<any>>(
365
+ assertType<(context: any, args: { value: number }) => Promise<any>>(
366
366
  callableMutation
367
367
  );
368
368
  });
@@ -377,7 +377,7 @@ describe("Builder Core", () => {
377
377
 
378
378
  // Should be callable
379
379
  assertType<
380
- (context: any) => (args: { url: string }) => Promise<{ url: string }>
380
+ (context: any, args: { url: string }) => Promise<{ url: string }>
381
381
  >(callableAction);
382
382
  });
383
383
 
@@ -398,11 +398,12 @@ describe("Builder Core", () => {
398
398
  // Should be callable
399
399
  assertType<
400
400
  (
401
- context: any
402
- ) => (args: {
403
- name?: string;
404
- count?: number;
405
- }) => Promise<{ name?: string; count?: number }>
401
+ context: any,
402
+ args: {
403
+ name?: string;
404
+ count?: number;
405
+ }
406
+ ) => Promise<{ name?: string; count?: number }>
406
407
  >(callableQuery);
407
408
  });
408
409
 
@@ -422,8 +423,9 @@ describe("Builder Core", () => {
422
423
  // Should be callable
423
424
  assertType<
424
425
  (
425
- context: any
426
- ) => (args: { count: number }) => Promise<{ numbers: number[] }>
426
+ context: any,
427
+ args: { count: number }
428
+ ) => Promise<{ numbers: number[] }>
427
429
  >(callableQuery);
428
430
  });
429
431
 
@@ -435,8 +437,9 @@ describe("Builder Core", () => {
435
437
  // Should be callable
436
438
  assertType<
437
439
  (
438
- context: any
439
- ) => (args: Record<never, never>) => Promise<{ success: boolean }>
440
+ context: any,
441
+ args: Record<never, never>
442
+ ) => Promise<{ success: boolean }>
440
443
  >(callableQuery);
441
444
  });
442
445
 
@@ -451,8 +454,9 @@ describe("Builder Core", () => {
451
454
  // Before .public(), should be callable
452
455
  assertType<
453
456
  (
454
- context: any
455
- ) => (args: { count: number }) => Promise<{ count: number }>
457
+ context: any,
458
+ args: { count: number }
459
+ ) => Promise<{ count: number }>
456
460
  >(callableQuery);
457
461
 
458
462
  const registeredQuery = callableQuery.public();
@@ -471,7 +475,7 @@ describe("Builder Core", () => {
471
475
  });
472
476
 
473
477
  // Before .internal(), should be callable
474
- assertType<(context: any) => (args: { value: number }) => Promise<any>>(
478
+ assertType<(context: any, args: { value: number }) => Promise<any>>(
475
479
  callableMutation
476
480
  );
477
481
 
@@ -58,7 +58,7 @@ describe("$context() consistency", () => {
58
58
  return context.user.name;
59
59
  });
60
60
 
61
- const result = await fn({} as any)({});
61
+ const result = await fn({} as any, {});
62
62
  expect(result).toBe("Alice");
63
63
  });
64
64
  });
@@ -107,7 +107,7 @@ describe("middleware error propagation", () => {
107
107
  .use(failing)
108
108
  .handler(async () => "should not reach");
109
109
 
110
- await expect(fn({} as any)({})).rejects.toThrow(
110
+ await expect(fn({} as any, {})).rejects.toThrow(
111
111
  "middleware failed before next"
112
112
  );
113
113
  });
@@ -123,7 +123,7 @@ describe("middleware error propagation", () => {
123
123
  .use(failsAfter)
124
124
  .handler(async () => "handler ran");
125
125
 
126
- await expect(fn({} as any)({})).rejects.toThrow(
126
+ await expect(fn({} as any, {})).rejects.toThrow(
127
127
  "middleware failed after next"
128
128
  );
129
129
  });
@@ -159,7 +159,7 @@ describe("middleware error propagation", () => {
159
159
  throw new Error("boom");
160
160
  });
161
161
 
162
- await expect(fn({} as any)({})).rejects.toThrow("boom");
162
+ await expect(fn({} as any, {})).rejects.toThrow("boom");
163
163
 
164
164
  // Both middleware should have caught the error in reverse order
165
165
  expect(order).toEqual([
@@ -188,7 +188,7 @@ describe("middleware skipping next()", () => {
188
188
  return "handler result";
189
189
  });
190
190
 
191
- await fn({} as any)({});
191
+ await fn({} as any, {});
192
192
 
193
193
  // Handler should NOT have executed
194
194
  expect(handlerRan.value).toBe(false);
@@ -204,7 +204,7 @@ describe("handler called with correct context and args", () => {
204
204
  return { name: args.name, count: args.count };
205
205
  });
206
206
 
207
- const result = await fn({} as any)({ name: "test", count: 42 });
207
+ const result = await fn({} as any, { name: "test", count: 42 });
208
208
  expect(result).toEqual({ name: "test", count: 42 });
209
209
  });
210
210
 
@@ -224,7 +224,7 @@ describe("handler called with correct context and args", () => {
224
224
  return { a: ctx.a, b: ctx.b };
225
225
  });
226
226
 
227
- const result = await fn({} as any)({});
227
+ const result = await fn({} as any, {});
228
228
  expect(result).toEqual({ a: 1, b: 2 });
229
229
  });
230
230
  });
@@ -235,7 +235,7 @@ describe("empty middleware chain", () => {
235
235
  .query()
236
236
  .handler(async () => "no middleware");
237
237
 
238
- const result = await fn({} as any)({});
238
+ const result = await fn({} as any, {});
239
239
  expect(result).toBe("no middleware");
240
240
  });
241
241
  });
@@ -173,7 +173,7 @@ describe("Extensibility", () => {
173
173
  console.log("Keys:", Object.keys(handlerBuilder));
174
174
 
175
175
  // The result should be callable
176
- const result = await handlerBuilder({} as any)({ message: "hello" });
176
+ const result = await handlerBuilder({} as any, { message: "hello" });
177
177
  expect(result).toBe("LOG: hello");
178
178
  });
179
179
 
@@ -187,7 +187,7 @@ describe("Extensibility", () => {
187
187
  return args.defaultField;
188
188
  });
189
189
 
190
- const result = await chained({} as any)({ defaultField: "test" });
190
+ const result = await chained({} as any, { defaultField: "test" });
191
191
  expect(result).toBe("test");
192
192
  });
193
193
 
@@ -209,7 +209,7 @@ describe("Extensibility", () => {
209
209
  return `${args.defaultField}-${ctx.extra}`;
210
210
  });
211
211
 
212
- const result = await chained({} as any)({ defaultField: "value" });
212
+ const result = await chained({} as any, { defaultField: "value" });
213
213
  expect(result).toBe("value-data");
214
214
  });
215
215
 
@@ -40,7 +40,7 @@ describe("Onion middleware composition", () => {
40
40
  return { done: true };
41
41
  });
42
42
 
43
- await fn({} as any)({});
43
+ await fn({} as any, {});
44
44
 
45
45
  // Onion order: outer wraps inner wraps handler
46
46
  expect(order).toEqual([
@@ -71,7 +71,7 @@ describe("Onion middleware composition", () => {
71
71
  throw new Error("handler exploded");
72
72
  });
73
73
 
74
- await expect(fn({} as any)({})).rejects.toThrow("handler exploded");
74
+ await expect(fn({} as any, {})).rejects.toThrow("handler exploded");
75
75
 
76
76
  // The middleware should have intercepted the error
77
77
  expect(caughtError).toBe("handler exploded");
@@ -95,7 +95,7 @@ describe("Onion middleware composition", () => {
95
95
  return { done: true };
96
96
  });
97
97
 
98
- await fn({} as any)({});
98
+ await fn({} as any, {});
99
99
 
100
100
  // next() should block until the handler completes,
101
101
  // so measured duration should include the 50ms sleep
@@ -122,7 +122,7 @@ describe("Onion middleware composition", () => {
122
122
  };
123
123
  });
124
124
 
125
- const result = await fn({} as any)({});
125
+ const result = await fn({} as any, {});
126
126
  expect(result).toEqual({ user: "alice", timestamp: 12345 });
127
127
  });
128
128
  });
package/src/types.ts CHANGED
@@ -70,8 +70,9 @@ export type CallableBuilder<
70
70
  THandlerReturn,
71
71
  > = {
72
72
  (
73
- context: TCurrentContext
74
- ): (args: InferredArgs<TArgsValidator>) => Promise<THandlerReturn>;
73
+ context: TCurrentContext,
74
+ args: InferredArgs<TArgsValidator>
75
+ ): Promise<THandlerReturn>;
75
76
  };
76
77
  export interface ConvexBuilderDef<
77
78
  TFunctionType extends FunctionType | undefined = undefined,
@@ -201,8 +201,9 @@ describe("WithZod Callable Builder", () => {
201
201
  // Should be callable
202
202
  assertType<
203
203
  (
204
- context: any
205
- ) => (args: { count: number }) => Promise<{ count: number }>
204
+ context: any,
205
+ args: { count: number }
206
+ ) => Promise<{ count: number }>
206
207
  >(callableQuery);
207
208
  });
208
209
  });
@@ -83,7 +83,7 @@ describe("WithZod plugin", () => {
83
83
  return { result: input.count * 2 };
84
84
  });
85
85
 
86
- const result = await fn({} as any)({ count: 5 });
86
+ const result = await fn({} as any, { count: 5 });
87
87
  expect(result).toEqual({ result: 10 });
88
88
  });
89
89
 
@@ -96,7 +96,7 @@ describe("WithZod plugin", () => {
96
96
  return { numbers: [1, 2, 3] };
97
97
  });
98
98
 
99
- const result = await fn({} as any)({});
99
+ const result = await fn({} as any, {});
100
100
  expect(result).toEqual({ numbers: [1, 2, 3] });
101
101
  });
102
102
 
@@ -110,11 +110,11 @@ describe("WithZod plugin", () => {
110
110
  });
111
111
 
112
112
  // Valid input should pass
113
- const result = await fn({} as any)({ count: 5 });
113
+ const result = await fn({} as any, { count: 5 });
114
114
  expect(result).toBe(5);
115
115
 
116
116
  // Invalid input should throw
117
- await expect(fn({} as any)({ count: -1 })).rejects.toThrow();
117
+ await expect(fn({} as any, { count: -1 })).rejects.toThrow();
118
118
  });
119
119
 
120
120
  it("should validate Zod returns refinements at runtime", async () => {
@@ -126,7 +126,7 @@ describe("WithZod plugin", () => {
126
126
  return -1; // This should fail validation
127
127
  });
128
128
 
129
- await expect(fn({} as any)({})).rejects.toThrow();
129
+ await expect(fn({} as any, {})).rejects.toThrow();
130
130
  });
131
131
 
132
132
  it("should work with plain Convex validators when using WithZod", async () => {
@@ -138,7 +138,7 @@ describe("WithZod plugin", () => {
138
138
  return input.count;
139
139
  });
140
140
 
141
- const result = await fn({} as any)({ count: 42 });
141
+ const result = await fn({} as any, { count: 42 });
142
142
  expect(result).toBe(42);
143
143
  });
144
144
 
@@ -157,7 +157,7 @@ describe("WithZod plugin", () => {
157
157
  return `${input.name}-${ctx.extra}`;
158
158
  });
159
159
 
160
- const result = await fn({} as any)({ name: "test" });
160
+ const result = await fn({} as any, { name: "test" });
161
161
  expect(result).toBe("test-data");
162
162
  });
163
163
 
@@ -175,6 +175,6 @@ describe("WithZod plugin", () => {
175
175
  return input.name;
176
176
  });
177
177
 
178
- await expect(fn({} as any)({ name: "" })).rejects.toThrow();
178
+ await expect(fn({} as any, { name: "" })).rejects.toThrow();
179
179
  });
180
180
  });