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.
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/index.d.mts +128 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +518 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +496 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +66 -0
- package/src/codec.ts +145 -0
- package/src/custom.ts +155 -0
- package/src/mapping.ts +190 -0
- package/src/tables.ts +58 -0
- package/src/types.ts +78 -0
- package/src/utils.ts +10 -0
- package/src/wrappers.ts +184 -0
- package/src/zodV4Compat.ts +36 -0
package/src/wrappers.ts
ADDED
|
@@ -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>>
|