zodvex 0.3.2 → 0.4.1
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 +75 -0
- package/dist/__type-tests__/infer-returns.d.ts +2 -0
- package/dist/__type-tests__/infer-returns.d.ts.map +1 -0
- package/dist/__type-tests__/zodTable-inference.d.ts +2 -0
- package/dist/__type-tests__/zodTable-inference.d.ts.map +1 -0
- package/dist/builders.d.ts +173 -0
- package/dist/builders.d.ts.map +1 -0
- package/dist/codec.d.ts +11 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/custom.d.ts +147 -0
- package/dist/custom.d.ts.map +1 -0
- package/dist/ids.d.ts +23 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/index.d.ts +11 -599
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +203 -58
- package/dist/index.js.map +1 -1
- package/dist/mapping/core.d.ts +5 -0
- package/dist/mapping/core.d.ts.map +1 -0
- package/dist/mapping/handlers/enum.d.ts +4 -0
- package/dist/mapping/handlers/enum.d.ts.map +1 -0
- package/dist/mapping/handlers/index.d.ts +5 -0
- package/dist/mapping/handlers/index.d.ts.map +1 -0
- package/dist/mapping/handlers/nullable.d.ts +7 -0
- package/dist/mapping/handlers/nullable.d.ts.map +1 -0
- package/dist/mapping/handlers/record.d.ts +4 -0
- package/dist/mapping/handlers/record.d.ts.map +1 -0
- package/dist/mapping/handlers/union.d.ts +5 -0
- package/dist/mapping/handlers/union.d.ts.map +1 -0
- package/dist/mapping/index.d.ts +4 -0
- package/dist/mapping/index.d.ts.map +1 -0
- package/dist/mapping/types.d.ts +43 -0
- package/dist/mapping/types.d.ts.map +1 -0
- package/dist/mapping/utils.d.ts +6 -0
- package/dist/mapping/utils.d.ts.map +1 -0
- package/dist/registry.d.ts +110 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/results.d.ts +126 -0
- package/dist/results.d.ts.map +1 -0
- package/dist/tables.d.ts +214 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/transform/index.d.ts +26 -0
- package/dist/transform/index.d.ts.map +1 -0
- package/dist/transform/index.js +442 -0
- package/dist/transform/index.js.map +1 -0
- package/dist/transform/transform.d.ts +47 -0
- package/dist/transform/transform.d.ts.map +1 -0
- package/dist/transform/traverse.d.ts +62 -0
- package/dist/transform/traverse.d.ts.map +1 -0
- package/dist/transform/types.d.ts +115 -0
- package/dist/transform/types.d.ts.map +1 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +55 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/wrappers.d.ts +22 -0
- package/dist/wrappers.d.ts.map +1 -0
- package/package.json +13 -6
- package/src/__type-tests__/infer-returns.ts +24 -0
- package/src/__type-tests__/zodTable-inference.ts +5 -5
- package/src/custom.ts +205 -28
- package/src/index.ts +1 -0
- package/src/mapping/core.ts +23 -11
- package/src/mapping/types.ts +6 -2
- package/src/results.ts +110 -0
- package/src/tables.ts +306 -28
- package/src/transform/index.ts +38 -0
- package/src/transform/transform.ts +409 -0
- package/src/transform/traverse.ts +320 -0
- package/src/transform/types.ts +128 -0
- package/src/types.ts +3 -2
- package/src/utils.ts +35 -0
- package/src/wrappers.ts +10 -19
package/src/tables.ts
CHANGED
|
@@ -5,6 +5,13 @@ import { z } from 'zod'
|
|
|
5
5
|
import { zid } from './ids'
|
|
6
6
|
import { type ConvexValidatorFromZodFieldsAuto, zodToConvex, zodToConvexFields } from './mapping'
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Makes all properties of a Zod object shape optional.
|
|
10
|
+
*/
|
|
11
|
+
type PartialShape<Shape extends z.ZodRawShape> = {
|
|
12
|
+
[K in keyof Shape]: z.ZodOptional<Shape[K]>
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
/**
|
|
9
16
|
* Helper type for Convex system fields added to documents
|
|
10
17
|
*/
|
|
@@ -23,6 +30,77 @@ type MapSystemFields<TableName extends string, Options extends readonly z.ZodTyp
|
|
|
23
30
|
: Options[K]
|
|
24
31
|
}
|
|
25
32
|
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Union Helpers - Type-safe utilities for working with Zod unions
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Type guard to check if a schema is a union type (ZodUnion or ZodDiscriminatedUnion).
|
|
39
|
+
*/
|
|
40
|
+
export function isZodUnion(
|
|
41
|
+
schema: z.ZodTypeAny
|
|
42
|
+
): schema is
|
|
43
|
+
| z.ZodUnion<readonly z.ZodTypeAny[]>
|
|
44
|
+
| z.ZodDiscriminatedUnion<readonly z.ZodObject<z.ZodRawShape>[], string> {
|
|
45
|
+
return schema instanceof z.ZodUnion || schema instanceof z.ZodDiscriminatedUnion
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Extracts the options array from a ZodUnion or ZodDiscriminatedUnion.
|
|
50
|
+
* Both union types have an `.options` property, but TypeScript doesn't
|
|
51
|
+
* create a common accessor after instanceof checks.
|
|
52
|
+
*
|
|
53
|
+
* @param schema - A ZodUnion or ZodDiscriminatedUnion schema
|
|
54
|
+
* @returns The array of union variant schemas
|
|
55
|
+
*/
|
|
56
|
+
export function getUnionOptions(
|
|
57
|
+
schema:
|
|
58
|
+
| z.ZodUnion<readonly z.ZodTypeAny[]>
|
|
59
|
+
| z.ZodDiscriminatedUnion<readonly z.ZodObject<z.ZodRawShape>[], string>
|
|
60
|
+
): readonly z.ZodTypeAny[] {
|
|
61
|
+
// Both ZodUnion and ZodDiscriminatedUnion have .options getter
|
|
62
|
+
// This is safe because we've constrained the input type
|
|
63
|
+
return schema.options
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Minimum tuple type required by z.union() - at least 2 elements.
|
|
68
|
+
*/
|
|
69
|
+
type UnionTuple<T extends z.ZodTypeAny = z.ZodTypeAny> = readonly [T, T, ...T[]]
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Asserts that an array has at least 2 elements, as required by z.union().
|
|
73
|
+
* Throws an error if the array has fewer than 2 elements.
|
|
74
|
+
*
|
|
75
|
+
* @param options - Array of Zod schemas
|
|
76
|
+
* @throws Error if array has fewer than 2 elements
|
|
77
|
+
*/
|
|
78
|
+
export function assertUnionOptions<T extends z.ZodTypeAny>(
|
|
79
|
+
options: readonly T[]
|
|
80
|
+
): asserts options is UnionTuple<T> {
|
|
81
|
+
if (options.length < 2) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`z.union() requires at least 2 options, but received ${options.length}. ` +
|
|
84
|
+
'This indicates an invalid union schema was passed to zodTable().'
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Creates a z.union() from an array of options with runtime validation.
|
|
91
|
+
* Ensures the array has at least 2 elements as required by Zod.
|
|
92
|
+
*
|
|
93
|
+
* @param options - Array of Zod schemas (must have at least 2 elements)
|
|
94
|
+
* @returns A ZodUnion schema
|
|
95
|
+
* @throws Error if array has fewer than 2 elements
|
|
96
|
+
*/
|
|
97
|
+
export function createUnionFromOptions<T extends z.ZodTypeAny>(
|
|
98
|
+
options: readonly T[]
|
|
99
|
+
): z.ZodUnion<UnionTuple<T>> {
|
|
100
|
+
assertUnionOptions(options)
|
|
101
|
+
return z.union(options)
|
|
102
|
+
}
|
|
103
|
+
|
|
26
104
|
/**
|
|
27
105
|
* Adds Convex system fields (_id, _creationTime) to a Zod schema.
|
|
28
106
|
*
|
|
@@ -68,8 +146,9 @@ export function addSystemFields<TableName extends string>(
|
|
|
68
146
|
schema: z.ZodTypeAny
|
|
69
147
|
): z.ZodTypeAny {
|
|
70
148
|
// Handle union schemas - add system fields to each variant
|
|
71
|
-
if (schema
|
|
72
|
-
const
|
|
149
|
+
if (isZodUnion(schema)) {
|
|
150
|
+
const originalOptions = getUnionOptions(schema)
|
|
151
|
+
const extendedOptions = originalOptions.map((variant: z.ZodTypeAny) => {
|
|
73
152
|
if (variant instanceof z.ZodObject) {
|
|
74
153
|
return variant.extend({
|
|
75
154
|
_id: zid(tableName),
|
|
@@ -79,7 +158,7 @@ export function addSystemFields<TableName extends string>(
|
|
|
79
158
|
// Non-object variants are returned as-is (shouldn't happen in practice)
|
|
80
159
|
return variant
|
|
81
160
|
})
|
|
82
|
-
return
|
|
161
|
+
return createUnionFromOptions(extendedOptions)
|
|
83
162
|
}
|
|
84
163
|
|
|
85
164
|
// Handle object schemas
|
|
@@ -94,25 +173,57 @@ export function addSystemFields<TableName extends string>(
|
|
|
94
173
|
return schema
|
|
95
174
|
}
|
|
96
175
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
176
|
+
/**
|
|
177
|
+
* System fields added to Convex documents.
|
|
178
|
+
*/
|
|
179
|
+
type DocSystemFields<TableName extends string> = {
|
|
180
|
+
_id: ReturnType<typeof zid<TableName>>
|
|
181
|
+
_creationTime: z.ZodNumber
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Type for validators that can be used with Convex's defineTable.
|
|
185
|
+
*
|
|
186
|
+
* Convex's defineTable expects Validator<Record<string, any>, "required", any>,
|
|
187
|
+
* but zodToConvex returns more specific types that TypeScript can't verify are
|
|
188
|
+
* compatible. This type represents validators that produce object documents.
|
|
189
|
+
*
|
|
190
|
+
* @internal
|
|
191
|
+
*/
|
|
192
|
+
type TableValidator = Parameters<typeof defineTable>[0]
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Asserts that a Convex validator can be used to define a table.
|
|
196
|
+
*
|
|
197
|
+
* This is needed because zodToConvex returns a specific validator type (like VUnion)
|
|
198
|
+
* that TypeScript can't verify is assignable to defineTable's expected input type,
|
|
199
|
+
* even though all union variants are objects that produce Record<string, any>.
|
|
200
|
+
*
|
|
201
|
+
* The runtime behavior is correct - Convex supports union validators in tables.
|
|
202
|
+
* This is purely a TypeScript limitation with complex mapped types.
|
|
203
|
+
*
|
|
204
|
+
* @internal
|
|
205
|
+
*/
|
|
206
|
+
function asTableValidator<V extends { kind: string }>(validator: V): TableValidator {
|
|
207
|
+
return validator as unknown as TableValidator
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Creates a Zod schema for a Convex document with system fields.
|
|
212
|
+
* Uses .extend() to preserve object-level options like .passthrough(), .strict(),
|
|
213
|
+
* .catchall(), and object-level refinements.
|
|
214
|
+
*
|
|
215
|
+
* @param tableName - The Convex table name
|
|
216
|
+
* @param schema - The Zod object schema for user fields
|
|
217
|
+
* @returns A Zod object schema with _id and _creationTime added
|
|
218
|
+
*/
|
|
219
|
+
export function zodDoc<TableName extends string, Shape extends z.ZodRawShape>(
|
|
103
220
|
tableName: TableName,
|
|
104
|
-
schema:
|
|
105
|
-
): z.ZodObject<
|
|
106
|
-
Shape & {
|
|
107
|
-
_id: ReturnType<typeof zid<TableName>>
|
|
108
|
-
_creationTime: z.ZodNumber
|
|
109
|
-
}
|
|
110
|
-
> {
|
|
111
|
-
// Use extend to preserve the original schema's type information
|
|
221
|
+
schema: z.ZodObject<Shape>
|
|
222
|
+
): z.ZodObject<Shape & DocSystemFields<TableName>> {
|
|
112
223
|
return schema.extend({
|
|
113
224
|
_id: zid(tableName),
|
|
114
225
|
_creationTime: z.number()
|
|
115
|
-
}) as
|
|
226
|
+
}) as z.ZodObject<Shape & DocSystemFields<TableName>>
|
|
116
227
|
}
|
|
117
228
|
|
|
118
229
|
// Helper to create nullable doc schema
|
|
@@ -213,6 +324,45 @@ type AddSystemFieldsResult<
|
|
|
213
324
|
? z.ZodDiscriminatedUnion<MapSystemFields<TableName, Options>, Disc>
|
|
214
325
|
: Schema
|
|
215
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Update schema shape: _id required, _creationTime optional, user fields partial
|
|
329
|
+
*/
|
|
330
|
+
type UpdateShape<TableName extends string, Shape extends z.ZodRawShape> = {
|
|
331
|
+
_id: ReturnType<typeof zid<TableName>>
|
|
332
|
+
_creationTime: z.ZodOptional<z.ZodNumber>
|
|
333
|
+
} & PartialShape<Shape>
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Maps over union options for update schema.
|
|
337
|
+
* Each variant gets _id required, _creationTime optional, and user fields partial.
|
|
338
|
+
*/
|
|
339
|
+
type MapUpdateVariants<TableName extends string, Options extends readonly z.ZodTypeAny[]> = {
|
|
340
|
+
[K in keyof Options]: Options[K] extends z.ZodObject<infer Shape extends z.ZodRawShape>
|
|
341
|
+
? z.ZodObject<UpdateShape<TableName, Shape>>
|
|
342
|
+
: Options[K]
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Computes the update schema type for a given schema.
|
|
347
|
+
* Includes _id (required), _creationTime (optional), and partial user fields.
|
|
348
|
+
* For unions: each variant gets update shape
|
|
349
|
+
* For objects: the whole object gets update shape
|
|
350
|
+
* For other types: returns as-is
|
|
351
|
+
*/
|
|
352
|
+
type UpdateSchemaType<
|
|
353
|
+
TableName extends string,
|
|
354
|
+
Schema extends z.ZodTypeAny
|
|
355
|
+
> = Schema extends z.ZodUnion<infer Options extends readonly z.ZodTypeAny[]>
|
|
356
|
+
? z.ZodUnion<MapUpdateVariants<TableName, Options>>
|
|
357
|
+
: Schema extends z.ZodDiscriminatedUnion<
|
|
358
|
+
infer Options extends readonly z.ZodObject<z.ZodRawShape>[],
|
|
359
|
+
infer _Disc extends string
|
|
360
|
+
>
|
|
361
|
+
? z.ZodUnion<MapUpdateVariants<TableName, Options>>
|
|
362
|
+
: Schema extends z.ZodObject<infer Shape extends z.ZodRawShape>
|
|
363
|
+
? z.ZodObject<UpdateShape<TableName, Shape>>
|
|
364
|
+
: Schema
|
|
365
|
+
|
|
216
366
|
// Overload 1: Object shape (most common case)
|
|
217
367
|
export function zodTable<TableName extends string, Shape extends Record<string, z.ZodTypeAny>>(
|
|
218
368
|
name: TableName,
|
|
@@ -233,6 +383,28 @@ export function zodTable<TableName extends string, Shape extends Record<string,
|
|
|
233
383
|
}
|
|
234
384
|
>
|
|
235
385
|
>
|
|
386
|
+
schema: {
|
|
387
|
+
doc: z.ZodObject<
|
|
388
|
+
Shape & {
|
|
389
|
+
_id: ReturnType<typeof zid<TableName>>
|
|
390
|
+
_creationTime: z.ZodNumber
|
|
391
|
+
}
|
|
392
|
+
>
|
|
393
|
+
docArray: z.ZodArray<
|
|
394
|
+
z.ZodObject<
|
|
395
|
+
Shape & {
|
|
396
|
+
_id: ReturnType<typeof zid<TableName>>
|
|
397
|
+
_creationTime: z.ZodNumber
|
|
398
|
+
}
|
|
399
|
+
>
|
|
400
|
+
>
|
|
401
|
+
/** The base schema - user fields without system fields */
|
|
402
|
+
base: z.ZodObject<Shape>
|
|
403
|
+
/** Alias for base - user fields for insert operations */
|
|
404
|
+
insert: z.ZodObject<Shape>
|
|
405
|
+
/** Update schema - _id required, _creationTime optional, user fields partial */
|
|
406
|
+
update: z.ZodObject<UpdateShape<TableName, Shape>>
|
|
407
|
+
}
|
|
236
408
|
}
|
|
237
409
|
|
|
238
410
|
// Overload 2: Union/schema types
|
|
@@ -243,7 +415,16 @@ export function zodTable<TableName extends string, Schema extends z.ZodTypeAny>(
|
|
|
243
415
|
table: ReturnType<typeof defineTable>
|
|
244
416
|
tableName: TableName
|
|
245
417
|
validator: ReturnType<typeof zodToConvex<Schema>>
|
|
246
|
-
schema:
|
|
418
|
+
schema: {
|
|
419
|
+
doc: AddSystemFieldsResult<TableName, Schema>
|
|
420
|
+
docArray: z.ZodArray<AddSystemFieldsResult<TableName, Schema>>
|
|
421
|
+
/** The base schema - user fields without system fields */
|
|
422
|
+
base: Schema
|
|
423
|
+
/** Alias for base - user fields for insert operations */
|
|
424
|
+
insert: Schema
|
|
425
|
+
/** Update schema - _id required, _creationTime optional, user fields partial */
|
|
426
|
+
update: UpdateSchemaType<TableName, Schema>
|
|
427
|
+
}
|
|
247
428
|
docArray: z.ZodArray<AddSystemFieldsResult<TableName, Schema>>
|
|
248
429
|
withSystemFields: () => AddSystemFieldsResult<TableName, Schema>
|
|
249
430
|
}
|
|
@@ -272,12 +453,63 @@ export function zodTable<
|
|
|
272
453
|
// Create docArray helper for return types
|
|
273
454
|
const docArray = z.array(zDoc)
|
|
274
455
|
|
|
456
|
+
// Create base schema (user fields only, no system fields)
|
|
457
|
+
const baseSchema = z.object(shape)
|
|
458
|
+
|
|
459
|
+
// Create partial shape for user fields
|
|
460
|
+
const partialShape: Record<string, z.ZodTypeAny> = {}
|
|
461
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
462
|
+
partialShape[key] = value.optional()
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Create update schema: _id required, _creationTime optional, user fields partial
|
|
466
|
+
const updateSchema = z.object({
|
|
467
|
+
_id: zid(name),
|
|
468
|
+
_creationTime: z.number().optional(),
|
|
469
|
+
...partialShape
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
// Create schema namespace
|
|
473
|
+
const schema = {
|
|
474
|
+
doc: zDoc,
|
|
475
|
+
docArray,
|
|
476
|
+
base: baseSchema,
|
|
477
|
+
insert: baseSchema, // alias for base
|
|
478
|
+
update: updateSchema
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Track if we've warned about deprecated properties
|
|
482
|
+
const warned = { zDoc: false, docArray: false }
|
|
483
|
+
|
|
275
484
|
// Attach everything for comprehensive usage
|
|
276
|
-
|
|
485
|
+
const result = Object.assign(table, {
|
|
277
486
|
shape,
|
|
278
|
-
|
|
279
|
-
|
|
487
|
+
schema
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
Object.defineProperty(result, 'zDoc', {
|
|
491
|
+
get() {
|
|
492
|
+
if (!warned.zDoc) {
|
|
493
|
+
console.warn('zodvex: `zDoc` is deprecated, use `schema.doc` instead')
|
|
494
|
+
warned.zDoc = true
|
|
495
|
+
}
|
|
496
|
+
return schema.doc
|
|
497
|
+
},
|
|
498
|
+
enumerable: true
|
|
280
499
|
})
|
|
500
|
+
|
|
501
|
+
Object.defineProperty(result, 'docArray', {
|
|
502
|
+
get() {
|
|
503
|
+
if (!warned.docArray) {
|
|
504
|
+
console.warn('zodvex: `docArray` is deprecated, use `schema.docArray` instead')
|
|
505
|
+
warned.docArray = true
|
|
506
|
+
}
|
|
507
|
+
return schema.docArray
|
|
508
|
+
},
|
|
509
|
+
enumerable: true
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
return result
|
|
281
513
|
} else {
|
|
282
514
|
// Union or other schema type logic
|
|
283
515
|
const schema = schemaOrShape as z.ZodTypeAny
|
|
@@ -286,14 +518,60 @@ export function zodTable<
|
|
|
286
518
|
const convexValidator = zodToConvex(schema)
|
|
287
519
|
|
|
288
520
|
// For unions, use defineTable directly (not Table helper which expects object fields)
|
|
289
|
-
//
|
|
290
|
-
const table = defineTable(convexValidator
|
|
521
|
+
// Convex supports union validators in tables, but TypeScript can't verify the types
|
|
522
|
+
const table = defineTable(asTableValidator(convexValidator))
|
|
291
523
|
|
|
292
524
|
// Create document schema with system fields
|
|
293
|
-
const
|
|
525
|
+
const docSchema = addSystemFields(name, schema)
|
|
294
526
|
|
|
295
527
|
// Create docArray helper
|
|
296
|
-
const docArray = z.array(
|
|
528
|
+
const docArray = z.array(docSchema)
|
|
529
|
+
|
|
530
|
+
// Create update schema: _id required, _creationTime optional, user fields partial
|
|
531
|
+
let updateSchema: z.ZodTypeAny
|
|
532
|
+
if (isZodUnion(schema)) {
|
|
533
|
+
const originalOptions = getUnionOptions(schema)
|
|
534
|
+
const updateOptions = originalOptions.map((variant: z.ZodTypeAny) => {
|
|
535
|
+
if (variant instanceof z.ZodObject) {
|
|
536
|
+
// Create partial shape for user fields
|
|
537
|
+
const partialShape: Record<string, z.ZodTypeAny> = {}
|
|
538
|
+
for (const [key, value] of Object.entries(variant.shape)) {
|
|
539
|
+
partialShape[key] = (value as z.ZodTypeAny).optional()
|
|
540
|
+
}
|
|
541
|
+
// Add system fields: _id required, _creationTime optional
|
|
542
|
+
return z.object({
|
|
543
|
+
_id: zid(name),
|
|
544
|
+
_creationTime: z.number().optional(),
|
|
545
|
+
...partialShape
|
|
546
|
+
})
|
|
547
|
+
}
|
|
548
|
+
return variant
|
|
549
|
+
})
|
|
550
|
+
updateSchema = createUnionFromOptions(updateOptions)
|
|
551
|
+
} else if (schema instanceof z.ZodObject) {
|
|
552
|
+
// Create partial shape for user fields
|
|
553
|
+
const partialShape: Record<string, z.ZodTypeAny> = {}
|
|
554
|
+
for (const [key, value] of Object.entries(schema.shape)) {
|
|
555
|
+
partialShape[key] = (value as z.ZodTypeAny).optional()
|
|
556
|
+
}
|
|
557
|
+
// Add system fields: _id required, _creationTime optional
|
|
558
|
+
updateSchema = z.object({
|
|
559
|
+
_id: zid(name),
|
|
560
|
+
_creationTime: z.number().optional(),
|
|
561
|
+
...partialShape
|
|
562
|
+
})
|
|
563
|
+
} else {
|
|
564
|
+
updateSchema = schema
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Create schema namespace
|
|
568
|
+
const schemaNamespace = {
|
|
569
|
+
doc: docSchema,
|
|
570
|
+
docArray,
|
|
571
|
+
base: schema,
|
|
572
|
+
insert: schema, // alias for base
|
|
573
|
+
update: updateSchema
|
|
574
|
+
}
|
|
297
575
|
|
|
298
576
|
// Attach helpers for union tables
|
|
299
577
|
// Return structure similar to Table() but without fields-based helpers
|
|
@@ -301,8 +579,8 @@ export function zodTable<
|
|
|
301
579
|
table,
|
|
302
580
|
tableName: name,
|
|
303
581
|
validator: convexValidator,
|
|
304
|
-
schema,
|
|
305
|
-
docArray,
|
|
582
|
+
schema: schemaNamespace,
|
|
583
|
+
docArray, // deprecated
|
|
306
584
|
withSystemFields: () => addSystemFields(name, schema)
|
|
307
585
|
}
|
|
308
586
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform layer - General-purpose schema traversal and value transformation utilities.
|
|
3
|
+
*
|
|
4
|
+
* This module provides primitives for:
|
|
5
|
+
* - Walking Zod schemas (walkSchema, findFieldsWithMeta)
|
|
6
|
+
* - Extracting metadata from schemas (getMetadata, hasMetadata)
|
|
7
|
+
* - Recursively transforming values based on schema structure (transformBySchema, transformBySchemaAsync)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { findFieldsWithMeta, transformBySchema } from 'zodvex/transform'
|
|
12
|
+
*
|
|
13
|
+
* // Find all fields with custom metadata
|
|
14
|
+
* const sensitiveFields = findFieldsWithMeta(schema, meta => meta?.sensitive === true)
|
|
15
|
+
*
|
|
16
|
+
* // Transform values based on metadata
|
|
17
|
+
* const masked = transformBySchema(value, schema, ctx, (val, info) => {
|
|
18
|
+
* if (info.meta?.pii) return '[REDACTED]'
|
|
19
|
+
* return val
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Transformation
|
|
25
|
+
export { transformBySchema, transformBySchemaAsync } from './transform'
|
|
26
|
+
|
|
27
|
+
// Traversal
|
|
28
|
+
export { findFieldsWithMeta, getMetadata, hasMetadata, walkSchema } from './traverse'
|
|
29
|
+
// Types
|
|
30
|
+
export type {
|
|
31
|
+
AsyncTransformFn,
|
|
32
|
+
FieldInfo,
|
|
33
|
+
SchemaVisitor,
|
|
34
|
+
TransformContext,
|
|
35
|
+
TransformFn,
|
|
36
|
+
TransformOptions,
|
|
37
|
+
WalkSchemaOptions
|
|
38
|
+
} from './types'
|