zodvex 0.1.0

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.
@@ -0,0 +1,184 @@
1
+ import { z } from 'zod'
2
+ import { toConvexJS } from './codec'
3
+ import { getObjectShape, zodToConvex, zodToConvexFields } from './mapping'
4
+ import {
5
+ type ExtractCtx,
6
+ type InferArgs,
7
+ type InferReturns,
8
+ type PreserveReturnType,
9
+ type ZodToConvexArgs
10
+ } from './types'
11
+
12
+ export function zQuery<
13
+ Builder extends (fn: any) => any,
14
+ A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
15
+ R extends z.ZodTypeAny | undefined = undefined
16
+ >(
17
+ query: Builder,
18
+ input: A,
19
+ handler: (
20
+ ctx: ExtractCtx<Builder>,
21
+ args: InferArgs<A>
22
+ ) => Promise<InferReturns<R>> | InferReturns<R>,
23
+ options?: { returns?: R }
24
+ ): PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>> {
25
+ let zodSchema: z.ZodTypeAny
26
+ let args: Record<string, any>
27
+ if (input instanceof z.ZodObject) {
28
+ zodSchema = input
29
+ args = zodToConvexFields(getObjectShape(input))
30
+ } else if (input instanceof z.ZodType) {
31
+ zodSchema = z.object({ value: input as z.ZodTypeAny })
32
+ args = { value: zodToConvex(input as z.ZodTypeAny) }
33
+ } else {
34
+ zodSchema = z.object(input as Record<string, z.ZodTypeAny>)
35
+ args = zodToConvexFields(input as Record<string, z.ZodTypeAny>)
36
+ }
37
+ const returns = options?.returns ? zodToConvex(options.returns) : undefined
38
+
39
+ return query({
40
+ args,
41
+ returns,
42
+ handler: async (ctx: ExtractCtx<Builder>, argsObject: unknown) => {
43
+ const parsed = zodSchema.parse(argsObject) as InferArgs<A>
44
+ const raw = await handler(ctx, parsed)
45
+ if (options?.returns) {
46
+ const validated = (options.returns as z.ZodTypeAny).parse(raw)
47
+ return toConvexJS(options.returns as z.ZodTypeAny, validated)
48
+ }
49
+ return raw as any
50
+ }
51
+ }) as PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>>
52
+ }
53
+
54
+ export function zInternalQuery<
55
+ Builder extends (fn: any) => any,
56
+ A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
57
+ R extends z.ZodTypeAny | undefined = undefined
58
+ >(
59
+ internalQuery: Builder,
60
+ input: A,
61
+ handler: (
62
+ ctx: ExtractCtx<Builder>,
63
+ args: InferArgs<A>
64
+ ) => Promise<InferReturns<R>> | InferReturns<R>,
65
+ options?: { returns?: R }
66
+ ): PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>> {
67
+ return zQuery(internalQuery, input, handler, options)
68
+ }
69
+
70
+ export function zMutation<
71
+ Builder extends (fn: any) => any,
72
+ A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
73
+ R extends z.ZodTypeAny | undefined = undefined
74
+ >(
75
+ mutation: Builder,
76
+ input: A,
77
+ handler: (
78
+ ctx: ExtractCtx<Builder>,
79
+ args: InferArgs<A>
80
+ ) => Promise<InferReturns<R>> | InferReturns<R>,
81
+ options?: { returns?: R }
82
+ ): PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>> {
83
+ let zodSchema: z.ZodTypeAny
84
+ let args: Record<string, any>
85
+ if (input instanceof z.ZodObject) {
86
+ zodSchema = input
87
+ args = zodToConvexFields(getObjectShape(input))
88
+ } else if (input instanceof z.ZodType) {
89
+ zodSchema = z.object({ value: input as z.ZodTypeAny })
90
+ args = { value: zodToConvex(input as z.ZodTypeAny) }
91
+ } else {
92
+ zodSchema = z.object(input as Record<string, z.ZodTypeAny>)
93
+ args = zodToConvexFields(input as Record<string, z.ZodTypeAny>)
94
+ }
95
+ const returns = options?.returns ? zodToConvex(options.returns) : undefined
96
+
97
+ return mutation({
98
+ args,
99
+ returns,
100
+ handler: async (ctx: ExtractCtx<Builder>, argsObject: unknown) => {
101
+ const parsed = zodSchema.parse(argsObject) as InferArgs<A>
102
+ const raw = await handler(ctx, parsed)
103
+ if (options?.returns) {
104
+ const validated = (options.returns as z.ZodTypeAny).parse(raw)
105
+ return toConvexJS(options.returns as z.ZodTypeAny, validated)
106
+ }
107
+ return raw as any
108
+ }
109
+ }) as PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>>
110
+ }
111
+
112
+ export function zInternalMutation<
113
+ Builder extends (fn: any) => any,
114
+ A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
115
+ R extends z.ZodTypeAny | undefined = undefined
116
+ >(
117
+ internalMutation: Builder,
118
+ input: A,
119
+ handler: (
120
+ ctx: ExtractCtx<Builder>,
121
+ args: InferArgs<A>
122
+ ) => Promise<InferReturns<R>> | InferReturns<R>,
123
+ options?: { returns?: R }
124
+ ): PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>> {
125
+ return zMutation(internalMutation, input, handler, options)
126
+ }
127
+
128
+ export function zAction<
129
+ Builder extends (fn: any) => any,
130
+ A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
131
+ R extends z.ZodTypeAny | undefined = undefined
132
+ >(
133
+ action: Builder,
134
+ input: A,
135
+ handler: (
136
+ ctx: ExtractCtx<Builder>,
137
+ args: InferArgs<A>
138
+ ) => Promise<InferReturns<R>> | InferReturns<R>,
139
+ options?: { returns?: R }
140
+ ): PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>> {
141
+ let zodSchema: z.ZodTypeAny
142
+ let args: Record<string, any>
143
+ if (input instanceof z.ZodObject) {
144
+ zodSchema = input
145
+ args = zodToConvexFields(getObjectShape(input))
146
+ } else if (input instanceof z.ZodType) {
147
+ zodSchema = z.object({ value: input as z.ZodTypeAny })
148
+ args = { value: zodToConvex(input as z.ZodTypeAny) }
149
+ } else {
150
+ zodSchema = z.object(input as Record<string, z.ZodTypeAny>)
151
+ args = zodToConvexFields(input as Record<string, z.ZodTypeAny>)
152
+ }
153
+ const returns = options?.returns ? zodToConvex(options.returns) : undefined
154
+
155
+ return action({
156
+ args,
157
+ returns,
158
+ handler: async (ctx: ExtractCtx<Builder>, argsObject: unknown) => {
159
+ const parsed = zodSchema.parse(argsObject) as InferArgs<A>
160
+ const raw = await handler(ctx, parsed)
161
+ if (options?.returns) {
162
+ const validated = (options.returns as z.ZodTypeAny).parse(raw)
163
+ return toConvexJS(options.returns as z.ZodTypeAny, validated)
164
+ }
165
+ return raw as any
166
+ }
167
+ }) as PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>>
168
+ }
169
+
170
+ export function zInternalAction<
171
+ Builder extends (fn: any) => any,
172
+ A extends z.ZodTypeAny | Record<string, z.ZodTypeAny>,
173
+ R extends z.ZodTypeAny | undefined = undefined
174
+ >(
175
+ internalAction: Builder,
176
+ input: A,
177
+ handler: (
178
+ ctx: ExtractCtx<Builder>,
179
+ args: InferArgs<A>
180
+ ) => Promise<InferReturns<R>> | InferReturns<R>,
181
+ options?: { returns?: R }
182
+ ): PreserveReturnType<Builder, ZodToConvexArgs<A>, InferReturns<R>> {
183
+ return zAction(internalAction, input, handler, options)
184
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Minimal compatibility for convex-helpers/server/zodV4 imports
3
+ * This library itself IS the Zod v4 compatibility layer
4
+ */
5
+
6
+ import type { GenericId } from 'convex/values'
7
+ import { z } from 'zod'
8
+
9
+ // Simple registry for metadata
10
+ const metadata = new WeakMap<z.ZodTypeAny, any>()
11
+
12
+ export const registryHelpers = {
13
+ getMetadata: (type: z.ZodTypeAny) => metadata.get(type),
14
+ setMetadata: (type: z.ZodTypeAny, meta: any) => metadata.set(type, meta)
15
+ }
16
+
17
+ /**
18
+ * Create a Zod validator for a Convex Id
19
+ */
20
+ export function zid<TableName extends string>(tableName: TableName): z.ZodTypeAny {
21
+ const schema = z
22
+ .string()
23
+ .refine((val): val is GenericId<TableName> => typeof val === 'string' && val.length > 0, {
24
+ message: `Invalid ID for table "${tableName}"`
25
+ })
26
+
27
+ // Store metadata for registry lookup
28
+ registryHelpers.setMetadata(schema, {
29
+ isConvexId: true,
30
+ tableName
31
+ })
32
+
33
+ return schema as z.ZodTypeAny
34
+ }
35
+
36
+ export type Zid<TableName extends string> = ReturnType<typeof zid<TableName>>