@@ -21,9 +21,11 @@ import type {
2121 GenericId ,
2222 Infer ,
2323 Validator ,
24+ VObject ,
25+ VUnion ,
2426} from "convex/values" ;
2527import { v } from "convex/values" ;
26- import { doc , partial } from "../validators.js" ;
28+ import { doc , partial , systemFields } from "../validators.js" ;
2729/**
2830 * Create CRUD operations for a table.
2931 * You can expose these operations in your API. For example, in convex/users.ts:
@@ -71,52 +73,40 @@ export function crud<
7173 > = internalMutationGeneric as any ,
7274) {
7375 type DataModel = DataModelFromSchemaDefinition < SchemaDefinition < Schema , any > > ;
74-
75- const validator = schema . tables [ table ] ?. validator
76+ const validator = schema . tables [ table ] ?. validator ;
7677 if ( ! validator ) {
7778 throw new Error (
7879 `Table ${ table } not found in schema. Did you define it in defineSchema?` ,
7980 ) ;
8081 }
82+ if ( validator . kind !== "object" && validator . kind !== "union" ) {
83+ throw new Error ( "Validator must be an object or union" ) ;
84+ }
8185
82- const systemFields = v . object ( {
83- _id : v . id ( table ) ,
84- _creationTime : v . number ( ) ,
85- } ) ;
86-
87- const partialSystemFields = partial ( systemFields ) . fields ;
88-
89-
90- const makeSystemFieldsOptional = (
91- validator : Validator < any , any , any > ,
92- ) : Validator < any , any , any > => {
86+ const makeSystemFieldsOptional = < V extends Validator < any , any , any > > (
87+ validator : V ,
88+ ) : V => {
9389 if ( validator . kind === "object" ) {
9490 return v . object ( {
9591 ...validator . fields ,
96- ...partialSystemFields ,
92+ ...partial ( systemFields ( table ) ) ,
9793 } ) as any ;
9894 } else if ( validator . kind === "union" ) {
9995 return v . union (
100- ...validator . members . map ( ( value ) => makeSystemFieldsOptional ( value ) as any ) ,
96+ ...validator . members . map ( ( value ) => makeSystemFieldsOptional ( value ) ) ,
10197 ) as any ;
10298 } else {
103- return validator ;
99+ throw new Error ( "Validator must be an object or union" ) ;
104100 }
105101 } ;
106102
107-
108103 return {
109104 create : mutation ( {
110105 args : makeSystemFieldsOptional ( validator ) ,
111106 handler : async ( ctx , args ) => {
112107 if ( "_id" in args ) delete args . _id ;
113108 if ( "_creationTime" in args ) delete args . _creationTime ;
114- const id = await ctx . db . insert (
115- table ,
116- args as unknown as WithoutSystemFields <
117- DocumentByName < DataModel , TableName >
118- > ,
119- ) ;
109+ const id = await ctx . db . insert ( table , args ) ;
120110 return ( await ctx . db . get ( id ) ) ! ;
121111 } ,
122112 } ) as RegisteredMutation <
@@ -151,7 +141,9 @@ export function crud<
151141 id : v . id ( table ) ,
152142 // this could be partial(table.withSystemFields) but keeping
153143 // the api less coupled to Table
154- patch : partial ( v . union ( doc ( schema , table ) ) )
144+ patch : partial (
145+ doc ( schema , table ) as VObject < any , any , any > | VUnion < any , any , any > ,
146+ ) ,
155147 } ,
156148 handler : async ( ctx , args ) => {
157149 await ctx . db . patch (
0 commit comments