zodvex 0.2.0 → 0.2.2

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/src/wrappers.ts CHANGED
@@ -1,13 +1,5 @@
1
1
  import type {
2
- ActionBuilder,
3
- DefaultFunctionArgs,
4
2
  FunctionVisibility,
5
- GenericActionCtx,
6
- GenericDataModel,
7
- GenericMutationCtx,
8
- GenericQueryCtx,
9
- MutationBuilder,
10
- QueryBuilder,
11
3
  RegisteredAction,
12
4
  RegisteredMutation,
13
5
  RegisteredQuery
@@ -17,33 +9,49 @@ import { z } from 'zod'
17
9
  import { fromConvexJS, toConvexJS } from './codec'
18
10
  import { getObjectShape, zodToConvex, zodToConvexFields } from './mapping'
19
11
  // Typing helpers to keep handler args/returns precise without deep remapping
20
- import type { InferHandlerReturns, InferReturns, ZodToConvexArgs } from './types'
12
+ import type {
13
+ ExtractCtx,
14
+ ExtractVisibility,
15
+ InferHandlerReturns,
16
+ InferReturns,
17
+ ZodToConvexArgs
18
+ } from './types'
21
19
  import { handleZodValidationError } from './utils'
22
20
 
23
21
  // Cache to avoid re-checking the same schema
24
22
  const customCheckCache = new WeakMap<z.ZodTypeAny, boolean>()
25
23
 
26
- // Check if a schema contains z.custom types (runtime check)
27
- function containsCustom(schema: z.ZodTypeAny): boolean {
24
+ /**
25
+ * Check if a schema contains z.custom types (runtime check).
26
+ * Includes depth limit to prevent stack overflow on deeply nested schemas.
27
+ */
28
+ function containsCustom(schema: z.ZodTypeAny, maxDepth = 50, currentDepth = 0): boolean {
28
29
  // Check cache first
29
30
  const cached = customCheckCache.get(schema)
30
31
  if (cached !== undefined) {
31
32
  return cached
32
33
  }
33
34
 
35
+ // Prevent stack overflow on deeply nested schemas
36
+ if (currentDepth > maxDepth) {
37
+ return false
38
+ }
39
+
34
40
  let result = false
35
41
 
36
42
  // Use _def.typeName instead of instanceof since ZodCustom is not exported in Zod v4
37
43
  if ((schema as any)._def?.typeName === 'ZodCustom') {
38
44
  result = true
39
45
  } else if (schema instanceof z.ZodUnion) {
40
- result = (schema.options as z.ZodTypeAny[]).some(containsCustom)
46
+ result = (schema.options as z.ZodTypeAny[]).some(opt =>
47
+ containsCustom(opt, maxDepth, currentDepth + 1)
48
+ )
41
49
  } else if (schema instanceof z.ZodOptional) {
42
- result = containsCustom(schema.unwrap() as z.ZodTypeAny)
50
+ result = containsCustom(schema.unwrap() as z.ZodTypeAny, maxDepth, currentDepth + 1)
43
51
  } else if (schema instanceof z.ZodNullable) {
44
- result = containsCustom(schema.unwrap() as z.ZodTypeAny)
52
+ result = containsCustom(schema.unwrap() as z.ZodTypeAny, maxDepth, currentDepth + 1)
45
53
  } else if (schema instanceof z.ZodDefault) {
46
- result = containsCustom(schema.removeDefault() as z.ZodTypeAny)
54
+ result = containsCustom(schema.removeDefault() as z.ZodTypeAny, maxDepth, currentDepth + 1)
47
55
  }
48
56
 
49
57
  customCheckCache.set(schema, result)
@@ -51,15 +59,15 @@ function containsCustom(schema: z.ZodTypeAny): boolean {
51
59
  }
52
60
 
53
61
  export function zQuery<
54
- DataModel extends GenericDataModel,
55
- Visibility extends FunctionVisibility,
62
+ Builder extends (fn: any) => any,
56
63
  A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
57
- R extends z.ZodTypeAny | undefined = undefined
64
+ R extends z.ZodTypeAny | undefined = undefined,
65
+ Visibility extends FunctionVisibility = ExtractVisibility<Builder>
58
66
  >(
59
- query: QueryBuilder<DataModel, Visibility>,
67
+ query: Builder,
60
68
  input: A,
61
69
  handler: (
62
- ctx: GenericQueryCtx<DataModel>,
70
+ ctx: ExtractCtx<Builder>,
63
71
  args: ZodToConvexArgs<A>
64
72
  ) => InferHandlerReturns<R> | Promise<InferHandlerReturns<R>>,
65
73
  options?: { returns?: R }
@@ -85,7 +93,7 @@ export function zQuery<
85
93
  return query({
86
94
  args,
87
95
  returns,
88
- handler: async (ctx: GenericQueryCtx<DataModel>, argsObject: unknown) => {
96
+ handler: async (ctx: any, argsObject: unknown) => {
89
97
  const decoded = fromConvexJS(argsObject, zodSchema)
90
98
  let parsed: any
91
99
  try {
@@ -105,19 +113,19 @@ export function zQuery<
105
113
  // Fallback: ensure Convex-safe return values (e.g., Date → timestamp)
106
114
  return toConvexJS(raw) as any
107
115
  }
108
- }) as RegisteredQuery<Visibility, ZodToConvexArgs<A>, Promise<InferReturns<R>>>
116
+ }) as any
109
117
  }
110
118
 
111
119
  export function zInternalQuery<
112
- DataModel extends GenericDataModel,
113
- Visibility extends FunctionVisibility,
120
+ Builder extends (fn: any) => any,
114
121
  A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
115
- R extends z.ZodTypeAny | undefined = undefined
122
+ R extends z.ZodTypeAny | undefined = undefined,
123
+ Visibility extends FunctionVisibility = ExtractVisibility<Builder>
116
124
  >(
117
- internalQuery: QueryBuilder<DataModel, Visibility>,
125
+ internalQuery: Builder,
118
126
  input: A,
119
127
  handler: (
120
- ctx: GenericQueryCtx<DataModel>,
128
+ ctx: ExtractCtx<Builder>,
121
129
  args: ZodToConvexArgs<A>
122
130
  ) => InferHandlerReturns<R> | Promise<InferHandlerReturns<R>>,
123
131
  options?: { returns?: R }
@@ -126,15 +134,15 @@ export function zInternalQuery<
126
134
  }
127
135
 
128
136
  export function zMutation<
129
- DataModel extends GenericDataModel,
130
- Visibility extends FunctionVisibility,
137
+ Builder extends (fn: any) => any,
131
138
  A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
132
- R extends z.ZodTypeAny | undefined = undefined
139
+ R extends z.ZodTypeAny | undefined = undefined,
140
+ Visibility extends FunctionVisibility = ExtractVisibility<Builder>
133
141
  >(
134
- mutation: MutationBuilder<DataModel, Visibility>,
142
+ mutation: Builder,
135
143
  input: A,
136
144
  handler: (
137
- ctx: GenericMutationCtx<DataModel>,
145
+ ctx: ExtractCtx<Builder>,
138
146
  args: ZodToConvexArgs<A>
139
147
  ) => InferHandlerReturns<R> | Promise<InferHandlerReturns<R>>,
140
148
  options?: { returns?: R }
@@ -159,7 +167,7 @@ export function zMutation<
159
167
  return mutation({
160
168
  args,
161
169
  returns,
162
- handler: async (ctx: GenericMutationCtx<DataModel>, argsObject: unknown) => {
170
+ handler: async (ctx: any, argsObject: unknown) => {
163
171
  const decoded = fromConvexJS(argsObject, zodSchema)
164
172
  let parsed: any
165
173
  try {
@@ -179,19 +187,19 @@ export function zMutation<
179
187
  // Fallback: ensure Convex-safe return values (e.g., Date → timestamp)
180
188
  return toConvexJS(raw) as any
181
189
  }
182
- }) as RegisteredMutation<Visibility, ZodToConvexArgs<A>, Promise<InferReturns<R>>>
190
+ }) as any
183
191
  }
184
192
 
185
193
  export function zInternalMutation<
186
- DataModel extends GenericDataModel,
187
- Visibility extends FunctionVisibility,
194
+ Builder extends (fn: any) => any,
188
195
  A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
189
- R extends z.ZodTypeAny | undefined = undefined
196
+ R extends z.ZodTypeAny | undefined = undefined,
197
+ Visibility extends FunctionVisibility = ExtractVisibility<Builder>
190
198
  >(
191
- internalMutation: MutationBuilder<DataModel, Visibility>,
199
+ internalMutation: Builder,
192
200
  input: A,
193
201
  handler: (
194
- ctx: GenericMutationCtx<DataModel>,
202
+ ctx: ExtractCtx<Builder>,
195
203
  args: ZodToConvexArgs<A>
196
204
  ) => InferHandlerReturns<R> | Promise<InferHandlerReturns<R>>,
197
205
  options?: { returns?: R }
@@ -200,15 +208,15 @@ export function zInternalMutation<
200
208
  }
201
209
 
202
210
  export function zAction<
203
- DataModel extends GenericDataModel,
204
- Visibility extends FunctionVisibility,
211
+ Builder extends (fn: any) => any,
205
212
  A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
206
- R extends z.ZodTypeAny | undefined = undefined
213
+ R extends z.ZodTypeAny | undefined = undefined,
214
+ Visibility extends FunctionVisibility = ExtractVisibility<Builder>
207
215
  >(
208
- action: ActionBuilder<DataModel, Visibility>,
216
+ action: Builder,
209
217
  input: A,
210
218
  handler: (
211
- ctx: GenericActionCtx<DataModel>,
219
+ ctx: ExtractCtx<Builder>,
212
220
  args: ZodToConvexArgs<A>
213
221
  ) => InferHandlerReturns<R> | Promise<InferHandlerReturns<R>>,
214
222
  options?: { returns?: R }
@@ -233,7 +241,7 @@ export function zAction<
233
241
  return action({
234
242
  args,
235
243
  returns,
236
- handler: async (ctx: GenericActionCtx<DataModel>, argsObject: unknown) => {
244
+ handler: async (ctx: any, argsObject: unknown) => {
237
245
  const decoded = fromConvexJS(argsObject, zodSchema)
238
246
  let parsed: any
239
247
  try {
@@ -253,22 +261,22 @@ export function zAction<
253
261
  // Fallback: ensure Convex-safe return values (e.g., Date → timestamp)
254
262
  return toConvexJS(raw) as any
255
263
  }
256
- }) as RegisteredAction<Visibility, ZodToConvexArgs<A>, Promise<InferReturns<R>>>
264
+ }) as any
257
265
  }
258
266
 
259
267
  export function zInternalAction<
260
- DataModel extends GenericDataModel,
261
- Visibility extends FunctionVisibility,
268
+ Builder extends (fn: any) => any,
262
269
  A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
263
- R extends z.ZodTypeAny | undefined = undefined
270
+ R extends z.ZodTypeAny | undefined = undefined,
271
+ Visibility extends FunctionVisibility = ExtractVisibility<Builder>
264
272
  >(
265
- internalAction: ActionBuilder<DataModel, Visibility>,
273
+ internalAction: Builder,
266
274
  input: A,
267
275
  handler: (
268
- ctx: GenericActionCtx<DataModel>,
276
+ ctx: ExtractCtx<Builder>,
269
277
  args: ZodToConvexArgs<A>
270
278
  ) => InferHandlerReturns<R> | Promise<InferHandlerReturns<R>>,
271
279
  options?: { returns?: R }
272
280
  ): RegisteredAction<Visibility, ZodToConvexArgs<A>, Promise<InferReturns<R>>> {
273
- return zAction(internalAction, input, handler, options)
281
+ return zAction(internalAction, input, handler, options) as any
274
282
  }