UNPKG

kitcn

Version:

kitcn - React Query integration and CLI tools for Convex

728 lines (726 loc) 96.9 kB
import { t as VRequired } from "./validators-BhsByJeg.js"; import { C as HttpProcedure, D as ProcedureMeta, R as getTransformer, S as HttpMethod, c as InferHttpInput, d as CRPCHttpRouter, j as DataTransformerOptions, l as InferHttpOutput, p as HttpRouterRecord, w as HttpProcedureBuilderDef, x as HttpHandlerOpts } from "./http-types-zsMHb_QN.js"; import { g as UnsetMarker, i as IntersectIfDefined, o as MiddlewareBuilder, p as Overwrite$1, s as MiddlewareFunction, t as AnyMiddleware } from "./types-CnTpHR1F.js"; import { ConvexError, GenericId, GenericValidator, ObjectType, OptionalProperty, PropertyValidators, VAny, VArray, VBoolean, VBytes, VFloat64, VId, VInt64, VLiteral, VNull, VObject, VOptional, VRecord, VString, VUnion, Validator, Value as Value$1 } from "convex/values"; import { ActionBuilder, ArgsArrayToObject, DefaultFunctionArgs, FunctionReference, FunctionReturnType, FunctionVisibility, GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx, MutationBuilder, QueryBuilder, RegisteredAction, RegisteredMutation, RegisteredQuery, TableNamesInDataModel } from "convex/server"; import { z } from "zod"; import * as z$1 from "zod/v4"; import * as zCore from "zod/v4/core"; //#region src/internal/upstream/index.d.ts type EmptyObject = Record<string, never>; /** * Hack! This type causes TypeScript to simplify how it renders object types. * * It is functionally the identity for object types, but in practice it can * simplify expressions like `A & B`. */ type Expand<ObjectType extends Record<any, any>> = ObjectType extends Record<any, any> ? { [Key in keyof ObjectType]: ObjectType[Key] } : never; //#endregion //#region src/internal/upstream/server/customFunctions.d.ts /** * A customization of a query, mutation, or action. * * It can specify common arguments that all defined functions take in, * as well as modify the ctx and args arguments to each function. * * Generally it's defined inline with customQuery, customMutation, etc. * But you can define the type explicitly if you want to reuse it. * * e.g. * ```ts * const myCustomization: Customization< * QueryCtx, * { sessionId: VId<"sessions"> }, * { db: DatabaseReader, user: User, session: Session }, * {}, * > = { * args: { sessionId: v.id("sessions") }, * input: async (ctx, args) => { * const user = await getUserOrNull(ctx); * const session = await db.get(sessionId); * const db = wrapDatabaseReader({ user }, ctx.db, rlsRules); * return { ctx: { db, user, session }, args: {} }; * }, * }; * * const myQueryBuilder = customQuery(query, myCustomization); * ``` * * If the required args are not returned, they will not be provided for the * modified function. All returned ctx and args will show up in the type * signature for the modified function. To remove something from `ctx`, you * can return it as `undefined`. * The `input` function can also return an `onSuccess` callback that will be * called after the function executes successfully. The `onSuccess` callback * has access to resources created during input processing via closure. */ type Customization<Ctx extends Record<string, any>, CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, ExtraArgs extends Record<string, any> = Record<string, any>> = { args: CustomArgsValidator; input: (ctx: Ctx, args: ObjectType<CustomArgsValidator>, extra: ExtraArgs) => Promise<{ ctx: CustomCtx; args: CustomMadeArgs; onSuccess?: (obj: { ctx: Ctx; args: Record<string, unknown>; result: unknown; }) => void | Promise<void>; }> | { ctx: CustomCtx; args: CustomMadeArgs; onSuccess?: (obj: { ctx: Ctx; args: Record<string, unknown>; result: unknown; }) => void | Promise<void>; }; }; /** * A Convex function (query, mutation, or action) to be registered for the API. * Convenience to specify the registration type based on function type. */ type Registration<FuncType extends 'query' | 'mutation' | 'action', Visibility extends FunctionVisibility, Args extends DefaultFunctionArgs, Output> = { query: RegisteredQuery<Visibility, Args, Output>; mutation: RegisteredMutation<Visibility, Args, Output>; action: RegisteredAction<Visibility, Args, Output>; }[FuncType]; //#endregion //#region src/internal/upstream/server/zod4.d.ts /** * zCustomQuery is like customQuery, but allows validation via zod. * You can define custom behavior on top of `query` or `internalQuery` * by passing a function that modifies the ctx and args. Or NoOp to do nothing. * * Example usage: * ```ts * const myQueryBuilder = zCustomQuery(query, { * args: { sessionId: v.id("sessions") }, * input: async (ctx, args) => { * const user = await getUserOrNull(ctx); * const session = await db.get(sessionId); * const db = wrapDatabaseReader({ user }, ctx.db, rlsRules); * return { ctx: { db, user, session }, args: {} }; * }, * }); * * // Using the custom builder * export const getSomeData = myQueryBuilder({ * args: { someArg: z.string() }, * handler: async (ctx, args) => { * const { db, user, session, scheduler } = ctx; * const { someArg } = args; * // ... * } * }); * ``` * * Simple usage only modifying ctx: * ```ts * const myInternalQuery = zCustomQuery( * internalQuery, * customCtx(async (ctx) => { * return { * // Throws an exception if the user isn't logged in * user: await getUserByTokenIdentifier(ctx), * }; * }) * ); * * // Using it * export const getUser = myInternalQuery({ * args: { email: z.string().email() }, * handler: async (ctx, args) => { * console.log(args.email); * return ctx.user; * }, * }); * * @param query The query to be modified. Usually `query` or `internalQuery` * from `_generated/server`. * @param customization The customization to be applied to the query, changing ctx and args. * @returns A new query builder using zod validation to define queries. */ declare function zCustomQuery<CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, Visibility extends FunctionVisibility, DataModel extends GenericDataModel, ExtraArgs extends Record<string, any> = object>(query: QueryBuilder<DataModel, Visibility>, customization: Customization<GenericQueryCtx<DataModel>, CustomArgsValidator, CustomCtx, CustomMadeArgs, ExtraArgs>): CustomBuilder<"query", CustomArgsValidator, CustomCtx, CustomMadeArgs, GenericQueryCtx<DataModel>, Visibility, ExtraArgs>; /** * zCustomMutation is like customMutation, but allows validation via zod. * You can define custom behavior on top of `mutation` or `internalMutation` * by passing a function that modifies the ctx and args. Or NoOp to do nothing. * * Example usage: * ```ts * const myMutationBuilder = zCustomMutation(mutation, { * args: { sessionId: v.id("sessions") }, * input: async (ctx, args) => { * const user = await getUserOrNull(ctx); * const session = await db.get(sessionId); * const db = wrapDatabaseReader({ user }, ctx.db, rlsRules); * return { ctx: { db, user, session }, args: {} }; * }, * }); * * // Using the custom builder * export const getSomeData = myMutationBuilder({ * args: { someArg: z.string() }, * handler: async (ctx, args) => { * const { db, user, session, scheduler } = ctx; * const { someArg } = args; * // ... * } * }); * ``` * * Simple usage only modifying ctx: * ```ts * const myInternalMutation = zCustomMutation( * internalMutation, * customCtx(async (ctx) => { * return { * // Throws an exception if the user isn't logged in * user: await getUserByTokenIdentifier(ctx), * }; * }) * ); * * // Using it * export const getUser = myInternalMutation({ * args: { email: z.string().email() }, * handler: async (ctx, args) => { * console.log(args.email); * return ctx.user; * }, * }); * * @param mutation The mutation to be modified. Usually `mutation` or `internalMutation` * from `_generated/server`. * @param customization The customization to be applied to the mutation, changing ctx and args. * @returns A new mutation builder using zod validation to define queries. */ declare function zCustomMutation<CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, Visibility extends FunctionVisibility, DataModel extends GenericDataModel, ExtraArgs extends Record<string, any> = object>(mutation: MutationBuilder<DataModel, Visibility>, customization: Customization<GenericMutationCtx<DataModel>, CustomArgsValidator, CustomCtx, CustomMadeArgs, ExtraArgs>): CustomBuilder<"mutation", CustomArgsValidator, CustomCtx, CustomMadeArgs, GenericMutationCtx<DataModel>, Visibility, ExtraArgs>; /** * zCustomAction is like customAction, but allows validation via zod. * You can define custom behavior on top of `action` or `internalAction` * by passing a function that modifies the ctx and args. Or NoOp to do nothing. * * Example usage: * ```ts * const myActionBuilder = zCustomAction(action, { * args: { sessionId: v.id("sessions") }, * input: async (ctx, args) => { * const user = await getUserOrNull(ctx); * const session = await db.get(sessionId); * const db = wrapDatabaseReader({ user }, ctx.db, rlsRules); * return { ctx: { db, user, session }, args: {} }; * }, * }); * * // Using the custom builder * export const getSomeData = myActionBuilder({ * args: { someArg: z.string() }, * handler: async (ctx, args) => { * const { db, user, session, scheduler } = ctx; * const { someArg } = args; * // ... * } * }); * ``` * * Simple usage only modifying ctx: * ```ts * const myInternalAction = zCustomAction( * internalAction, * customCtx(async (ctx) => { * return { * // Throws an exception if the user isn't logged in * user: await getUserByTokenIdentifier(ctx), * }; * }) * ); * * // Using it * export const getUser = myInternalAction({ * args: { email: z.string().email() }, * handler: async (ctx, args) => { * console.log(args.email); * return ctx.user; * }, * }); * * @param action The action to be modified. Usually `action` or `internalAction` * from `_generated/server`. * @param customization The customization to be applied to the action, changing ctx and args. * @returns A new action builder using zod validation to define queries. */ declare function zCustomAction<CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, Visibility extends FunctionVisibility, DataModel extends GenericDataModel, ExtraArgs extends Record<string, any> = object>(action: ActionBuilder<DataModel, Visibility>, customization: Customization<GenericActionCtx<DataModel>, CustomArgsValidator, CustomCtx, CustomMadeArgs, ExtraArgs>): CustomBuilder<"action", CustomArgsValidator, CustomCtx, CustomMadeArgs, GenericActionCtx<DataModel>, Visibility, ExtraArgs>; /** * Creates a validator for a Convex `Id`. * * - When **used within Zod**, it will only check that the ID is a string. * - When **converted to a Convex validator** (e.g. through {@link zodToConvex}), * it will check that it's for the right table. * * @param tableName - The table that the `Id` references. i.e. `Id<tableName>` * @returns A Zod schema representing a Convex `Id` */ declare const zid: <DataModel extends GenericDataModel, TableName extends TableNamesInDataModel<DataModel> = TableNamesInDataModel<DataModel>>(tableName: TableName) => Zid<TableName>; /** The type of Convex validators in Zod */ type Zid<TableName extends string> = z$1.ZodCustom<GenericId<TableName>> & zCore.$ZodRecordKey; /** * Useful to get the input context type for a custom function using Zod. */ type ZCustomCtx<Builder> = Builder extends CustomBuilder<any, any, infer CustomCtx, any, infer InputCtx, any, any> ? Overwrite<InputCtx, CustomCtx> : never; /** * Turns a Zod or Zod Mini validator into a Convex validator. * * The Convex validator will be as close to possible to the Zod validator, * but might be broader than the Zod validator: * * ```ts * zodToConvex(z.string().email()) // → v.string() * ``` * * This function is useful when running the Zod validator _after_ running the Convex validator * (i.e. the Convex validator validates the input of the Zod validator). Hence, the Convex types * will match the _input type_ of Zod transformations: * ```ts * zodToConvex(z.object({ * name: z.string().default("Nicolas"), * })) // → v.object({ name: v.optional(v.string()) }) * * zodToConvex(z.object({ * name: z.string().transform(s => s.length) * })) // → v.object({ name: v.string() }) * ```` * * This function is useful for: * * **Validating function arguments with Zod**: through {@link zCustomQuery}, * {@link zCustomMutation} and {@link zCustomAction}, you can define the argument validation logic * using Zod validators instead of Convex validators. `zodToConvex` will generate a Convex validator * from your Zod validator. This will allow you to: * - validate at run time that Convex IDs are from the right table (using {@link zid}) * - allow some features of Convex to understand the expected shape of the arguments * (e.g. argument validation/prefilling in the function runner on the Convex dashboard) * - still run the full Zod validation when the function runs * (which is useful for more advanced Zod validators like `z.string().email()`) * * **Validating data after reading it from the database**: if you want to write your DB schema * with Zod, you can run Zod whenever you read from the database to check that the data * still matches the schema. Note that this approach won’t ensure that the data stored in the DB * matches the Zod schema; see * https://stack.convex.dev/typescript-zod-function-validation#can-i-use-zod-to-define-my-database-types-too * for more details. * * Note that some values might be valid in Zod but not in Convex, * in the same way that valid JavaScript values might not be valid * Convex values for the corresponding Convex type. * (see the limits of Convex data types on https://docs.convex.dev/database/types). * * ``` * ┌─────────────────────────────────────┬─────────────────────────────────────┐ * │ **zodToConvex** │ zodOutputToConvex │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ For when the Zod validator runs │ For when the Zod validator runs │ * │ _after_ the Convex validator │ _before_ the Convex validator │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ Convex types use the _input types_ │ Convex types use the _return types_ │ * │ of Zod transformations │ of Zod transformations │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ The Convex validator can be less │ The Convex validator can be less │ * │ strict (i.e. some inputs might be │ strict (i.e. the type in Convex can │ * │ accepted by Convex then rejected │ be less precise than the type in │ * │ by Zod) │ the Zod output) │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ When using Zod schemas │ When using Zod schemas │ * │ for function definitions: │ for function definitions: │ * │ used for _arguments_ │ used for _return values_ │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ When validating contents of the │ When validating contents of the │ * │ database with a Zod schema: │ database with a Zod schema: │ * │ used to validate data │ used to validate data │ * │ _after reading_ │ _before writing_ │ * └─────────────────────────────────────┴─────────────────────────────────────┘ * ``` * * @param zod Zod validator can be a Zod object, or a Zod type like `z.string()` * @returns Convex Validator (e.g. `v.string()` from "convex/values") * @throws If there is no equivalent Convex validator for the value (e.g. `z.date()`) */ declare function zodToConvex<Z extends zCore.$ZodType>(validator: Z): ConvexValidatorFromZod<Z, 'required'>; /** * Converts a Zod or Zod Mini validator to a Convex validator that checks the value _after_ * it has been validated (and possibly transformed) by the Zod validator. * * This is similar to {@link zodToConvex}, but is meant for cases where the Convex * validator runs _after_ the Zod validator. Thus, the Convex type refers to the * _output_ type of the Zod transformations: * ```ts * zodOutputToConvex(z.object({ * name: z.string().default("Nicolas"), * })) // → v.object({ name: v.string() }) * * zodOutputToConvex(z.object({ * name: z.string().transform(s => s.length) * })) // → v.object({ name: v.number() }) * ```` * * This function can be useful for: * - **Validating function return values with Zod**: through {@link zCustomQuery}, * {@link zCustomMutation} and {@link zCustomAction}, you can define the `returns` property * of a function using Zod validators instead of Convex validators. * - **Validating data after reading it from the database**: if you want to write your DB schema * Zod validators, you can run Zod whenever you write to the database to ensure your data matches * the expected format. Note that this approach won’t ensure that the data stored in the DB * isn’t modified manually in a way that doesn’t match your Zod schema; see * https://stack.convex.dev/typescript-zod-function-validation#can-i-use-zod-to-define-my-database-types-too * for more details. * * ``` * ┌─────────────────────────────────────┬─────────────────────────────────────┐ * │ zodToConvex │ **zodOutputToConvex** │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ For when the Zod validator runs │ For when the Zod validator runs │ * │ _after_ the Convex validator │ _before_ the Convex validator │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ Convex types use the _input types_ │ Convex types use the _return types_ │ * │ of Zod transformations │ of Zod transformations │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ The Convex validator can be less │ The Convex validator can be less │ * │ strict (i.e. some inputs might be │ strict (i.e. the type in Convex can │ * │ accepted by Convex then rejected │ be less precise than the type in │ * │ by Zod) │ the Zod output) │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ When using Zod schemas │ When using Zod schemas │ * │ for function definitions: │ for function definitions: │ * │ used for _arguments_ │ used for _return values_ │ * ├─────────────────────────────────────┼─────────────────────────────────────┤ * │ When validating contents of the │ When validating contents of the │ * │ database with a Zod schema: │ database with a Zod schema: │ * │ used to validate data │ used to validate data │ * │ _after reading_ │ _before writing_ │ * └─────────────────────────────────────┴─────────────────────────────────────┘ * ``` * * @param z The zod validator * @returns Convex Validator (e.g. `v.string()` from "convex/values") * @throws If there is no equivalent Convex validator for the value (e.g. `z.date()`) */ declare function zodOutputToConvex<Z extends zCore.$ZodType>(validator: Z): ConvexValidatorFromZodOutput<Z, 'required'>; type ZodFields = Record<string, zCore.$ZodType>; /** * Like {@link zodToConvex}, but it takes in a bare object, as expected by Convex * function arguments, or the argument to {@link defineTable}. * * ```ts * zodToConvexFields({ * name: z.string().default("Nicolas"), * }) // → { name: v.optional(v.string()) } * ``` * * @param fields Object with string keys and Zod validators as values * @returns Object with the same keys, but with Convex validators as values */ declare function zodToConvexFields<Fields extends ZodFields>(fields: Fields): { [k in keyof Fields]: Fields[k] extends zCore.$ZodType ? ConvexValidatorFromZod<Fields[k], "required"> : never }; /** * Like {@link zodOutputToConvex}, but it takes in a bare object, as expected by * Convex function arguments, or the argument to {@link defineTable}. * * ```ts * zodOutputToConvexFields({ * name: z.string().default("Nicolas"), * }) // → { name: v.string() } * ``` * * This is different from {@link zodToConvexFields} because it generates the * Convex validator for the output of the Zod validator, not the input; * see the documentation of {@link zodToConvex} and {@link zodOutputToConvex} * for more details. * * @param zod Object with string keys and Zod validators as values * @returns Object with the same keys, but with Convex validators as values */ declare function zodOutputToConvexFields<Fields extends ZodFields>(fields: Fields): { [k in keyof Fields]: ConvexValidatorFromZodOutput<Fields[k], "required"> }; /** * Turns a Convex validator into a Zod validator. * * This is useful when you want to use types you defined using Convex validators * with external libraries that expect to receive a Zod validator. * * ```ts * convexToZod(v.string()) // → z.string() * ``` * * This function returns Zod validators, not Zod Mini validators. * * @param convexValidator Convex validator can be any validator from "convex/values" e.g. `v.string()` * @returns Zod validator (e.g. `z.string()`) with inferred type matching the Convex validator */ declare function convexToZod<V extends GenericValidator>(convexValidator: V): ZodValidatorFromConvex<V>; /** * Like {@link convexToZod}, but it takes in a bare object, as expected by Convex * function arguments, or the argument to {@link defineTable}. * * ```ts * convexToZodFields({ * name: v.string(), * }) // → { name: z.string() } * ``` * * @param convexValidators Object with string keys and Convex validators as values * @returns Object with the same keys, but with Zod validators as values */ declare function convexToZodFields<C extends PropertyValidators>(convexValidators: C): { [k in keyof C]: ZodValidatorFromConvex<C[k]> }; /** * Zod helper for adding Convex system fields to a record to return. * * ```ts * withSystemFields("users", { * name: z.string(), * }) * // → { * // name: z.string(), * // _id: zid("users"), * // _creationTime: z.number(), * // } * ``` * * @param tableName - The table where records are from, i.e. Doc<tableName> * @param zObject - Validators for the user-defined fields on the document. * @returns Zod shape for use with `z.object(shape)` that includes system fields. */ declare function withSystemFields<Table extends string, T extends { [key: string]: zCore.$ZodType; }>(tableName: Table, zObject: T): T & { _id: Zid<Table>; _creationTime: z$1.ZodNumber; }; /** * A builder that customizes a Convex function, whether or not it validates * arguments. If the customization requires arguments, however, the resulting * builder will require argument validation too. */ type CustomBuilder<FuncType extends 'query' | 'mutation' | 'action', CustomArgsValidator extends PropertyValidators, CustomCtx extends Record<string, any>, CustomMadeArgs extends Record<string, any>, InputCtx, Visibility extends FunctionVisibility, ExtraArgs extends Record<string, any>> = <ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void, ReturnsZodValidator extends zCore.$ZodType | ZodFields | void = void, ReturnValue extends ReturnValueInput<ReturnsZodValidator> = any>(func: ({ /** * Specify the arguments to the function as a Zod validator. */ args?: ArgsValidator; handler: (ctx: Overwrite<InputCtx, CustomCtx>, ...args: ArgsForHandlerType<ArgsOutput<ArgsValidator>, CustomMadeArgs>) => ReturnValue; /** * Validates the value returned by the function. * Note: you can't pass an object directly without wrapping it * in `z.object()`. */ returns?: ReturnsZodValidator; /** * If true, the function will not be validated by Convex, * in case you're seeing performance issues with validating twice. */ skipConvexValidation?: boolean; } & { [key in keyof ExtraArgs as key extends 'args' | 'handler' | 'skipConvexValidation' | 'returns' ? never : key]: ExtraArgs[key] }) | ((ctx: Overwrite<InputCtx, CustomCtx>, ...args: ArgsForHandlerType<ArgsOutput<ArgsValidator>, CustomMadeArgs>) => ReturnValue)) => Registration<FuncType, Visibility, ArgsArrayToObject<CustomArgsValidator extends Record<string, never> ? ArgsInput<ArgsValidator> : ArgsInput<ArgsValidator> extends [infer A] ? [Expand<A & ObjectType<CustomArgsValidator>>] : [ObjectType<CustomArgsValidator>]>, ReturnsZodValidator extends void ? ReturnValue : ReturnValueOutput<ReturnsZodValidator>>; type ArgsForHandlerType<OneOrZeroArgs extends [] | [Record<string, any>], CustomMadeArgs extends Record<string, any>> = CustomMadeArgs extends Record<string, never> ? OneOrZeroArgs : OneOrZeroArgs extends [infer A] ? [Expand<A & CustomMadeArgs>] : [CustomMadeArgs]; type NullToUndefinedOrNull<T> = T extends null ? T | undefined | void : T; type Returns<T> = Promise<NullToUndefinedOrNull<T>> | NullToUndefinedOrNull<T>; type ReturnValueInput<ReturnsValidator extends zCore.$ZodType | ZodFields | void> = [ReturnsValidator] extends [zCore.$ZodType] ? Returns<zCore.input<ReturnsValidator>> : [ReturnsValidator] extends [ZodFields] ? Returns<zCore.input<zCore.$ZodObject<ReturnsValidator>>> : any; type ReturnValueOutput<ReturnsValidator extends zCore.$ZodType | ZodFields | void> = [ReturnsValidator] extends [zCore.$ZodType] ? Returns<zCore.output<ReturnsValidator>> : [ReturnsValidator] extends [ZodFields] ? Returns<zCore.output<zCore.$ZodObject<ReturnsValidator, zCore.$strict>>> : any; type ArgsInput<ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void> = [ArgsValidator] extends [zCore.$ZodObject<any>] ? [zCore.input<ArgsValidator>] : ArgsValidator extends Record<string, never> ? [{}] : [ArgsValidator] extends [Record<string, z$1.ZodTypeAny>] ? [zCore.input<zCore.$ZodObject<ArgsValidator, zCore.$strict>>] : OneArgArray; type ArgsOutput<ArgsValidator extends ZodFields | zCore.$ZodObject<any> | void> = [ArgsValidator] extends [zCore.$ZodObject<any>] ? [zCore.output<ArgsValidator>] : [ArgsValidator] extends [ZodFields] ? [zCore.output<zCore.$ZodObject<ArgsValidator, zCore.$strict>>] : OneArgArray; type Overwrite<T, U> = Omit<T, keyof U> & U; type OneArgArray<ArgsObject extends DefaultFunctionArgs = DefaultFunctionArgs> = [ArgsObject]; /** * Return type of {@link zodToConvex}. */ type ConvexValidatorFromZod<Z extends zCore.$ZodType, IsOptional extends 'required' | 'optional'> = IsUnknownOrAny<Z> extends true ? GenericValidator : Z extends zCore.$ZodDefault<infer Inner extends zCore.$ZodType> ? VOptional<ConvexValidatorFromZod<Inner, 'optional'>> : Z extends zCore.$ZodPipe<infer Input extends zCore.$ZodType, infer _Output extends zCore.$ZodType> ? ConvexValidatorFromZod<Input, IsOptional> : ConvexValidatorFromZodCommon<Z, IsOptional>; /** * Return type of {@link zodOutputToConvex}. */ type ConvexValidatorFromZodOutput<Z extends zCore.$ZodType, IsOptional extends 'required' | 'optional'> = IsUnknownOrAny<Z> extends true ? GenericValidator : Z extends zCore.$ZodDefault<infer Inner extends zCore.$ZodType> ? VRequired<ConvexValidatorFromZodOutput<Inner, 'required'>> : Z extends zCore.$ZodPipe<infer _Input extends zCore.$ZodType, infer Output extends zCore.$ZodType> ? ConvexValidatorFromZodOutput<Output, IsOptional> : Z extends zCore.$ZodOptional<infer Inner extends zCore.$ZodType> ? VOptional<ConvexValidatorFromZodOutput<Inner, 'optional'>> : Z extends zCore.$ZodNullable<infer Inner extends zCore.$ZodType> ? ConvexValidatorFromZodOutput<Inner, IsOptional> extends Validator<any, 'optional', any> ? VUnion<ConvexValidatorFromZodOutput<Inner, IsOptional>['type'] | null | undefined, [VRequired<ConvexValidatorFromZodOutput<Inner, IsOptional>>, VNull], 'optional', ConvexValidatorFromZodOutput<Inner, IsOptional>['fieldPaths']> : VUnion<ConvexValidatorFromZodOutput<Inner, IsOptional>['type'] | null, [VRequired<ConvexValidatorFromZodOutput<Inner, IsOptional>>, VNull], IsOptional, ConvexValidatorFromZodOutput<Inner, IsOptional>['fieldPaths']> : ConvexValidatorFromZodCommon<Z, IsOptional>; type ConvexValidatorFromZodCommon<Z extends zCore.$ZodType, IsOptional extends 'required' | 'optional'> = Z extends Zid<infer TableName> ? VId<GenericId<TableName>> : Z extends zCore.$ZodString ? VString<zCore.infer<Z>, IsOptional> : Z extends zCore.$ZodNumber ? VFloat64<zCore.infer<Z>, IsOptional> : Z extends zCore.$ZodNaN ? VFloat64<zCore.infer<Z>, IsOptional> : Z extends zCore.$ZodBigInt ? VInt64<zCore.infer<Z>, IsOptional> : Z extends zCore.$ZodBoolean ? VBoolean<zCore.infer<Z>, IsOptional> : Z extends zCore.$ZodNull ? VNull<zCore.infer<Z>, IsOptional> : Z extends zCore.$ZodUnknown ? VAny<any, 'required'> : Z extends zCore.$ZodAny ? VAny<zCore.infer<Z>, 'required'> : Z extends zCore.$ZodArray<infer Inner extends zCore.$ZodType> ? ConvexValidatorFromZod<Inner, 'required'> extends GenericValidator ? VArray<ConvexValidatorFromZod<Inner, 'required'>['type'][], ConvexValidatorFromZod<Inner, 'required'>, IsOptional> : never : Z extends zCore.$ZodObject<infer Fields extends Readonly<zCore.$ZodShape>> ? VObject<zCore.infer<Z>, ConvexObjectFromZodShape<Fields>, IsOptional> : Z extends zCore.$ZodNever ? VUnion<never, [], IsOptional, never> : Z extends zCore.$ZodUnion<infer T extends readonly zCore.$ZodType[]> ? ConvexUnionValidatorFromZod<T> : Z extends zCore.$ZodTuple<infer Inner extends readonly zCore.$ZodType[], infer Rest extends null | zCore.$ZodType> ? VArray<null extends Rest ? Array<ConvexValidatorFromZod<Inner[number], 'required'>['type']> : Array<ConvexValidatorFromZod<Inner[number], 'required'>['type'] | zCore.infer<Rest>>, null extends Rest ? ConvexUnionValidatorFromZod<Inner> : ConvexUnionValidatorFromZod<[...Inner, Rest extends zCore.$ZodType ? Rest : never]>, IsOptional> : Z extends zCore.$ZodLiteral<infer Literal extends zCore.util.Literal> ? ConvexLiteralFromZod<Literal, IsOptional> : Z extends zCore.$ZodEnum<infer EnumContents extends zCore.util.EnumLike> ? VUnion<zCore.infer<Z>, keyof EnumContents extends string ? { [K in keyof EnumContents]: VLiteral<EnumContents[K], 'required'> }[keyof EnumContents][] : never, IsOptional> : Z extends zCore.$ZodOptional<infer Inner extends zCore.$ZodType> ? VOptional<ConvexValidatorFromZod<Inner, 'optional'>> : Z extends zCore.$ZodNonOptional<infer Inner extends zCore.$ZodType> ? VRequired<ConvexValidatorFromZod<Inner, 'required'>> : Z extends zCore.$ZodNullable<infer Inner extends zCore.$ZodType> ? ConvexValidatorFromZod<Inner, IsOptional> extends Validator<any, 'optional', any> ? VUnion<ConvexValidatorFromZod<Inner, IsOptional>['type'] | null | undefined, [VRequired<ConvexValidatorFromZod<Inner, IsOptional>>, VNull], 'optional', ConvexValidatorFromZod<Inner, IsOptional>['fieldPaths']> : VUnion<ConvexValidatorFromZod<Inner, IsOptional>['type'] | null, [VRequired<ConvexValidatorFromZod<Inner, IsOptional>>, VNull], IsOptional, ConvexValidatorFromZod<Inner, IsOptional>['fieldPaths']> : Z extends zCore.$ZodBranded<infer Inner extends zCore.$ZodType, infer Brand> ? Inner extends zCore.$ZodString ? VString<string & zCore.$brand<Brand>, IsOptional> : Inner extends zCore.$ZodNumber ? VFloat64<number & zCore.$brand<Brand>, IsOptional> : Inner extends zCore.$ZodBigInt ? VInt64<bigint & zCore.$brand<Brand>, IsOptional> : Inner extends zCore.$ZodObject<infer Fields extends Readonly<zCore.$ZodShape>> ? VObject<zCore.infer<Inner> & zCore.$brand<Brand>, ConvexObjectFromZodShape<Fields>, IsOptional> : ConvexValidatorFromZod<Inner, IsOptional> : Z extends zCore.$ZodRecord<infer Key extends zCore.$ZodRecordKey, infer Value extends zCore.$ZodType> ? ConvexValidatorFromZodRecord<Key, Value, IsOptional> : Z extends zCore.$ZodReadonly<infer Inner extends zCore.$ZodType> ? ConvexValidatorFromZod<Inner, IsOptional> : Z extends zCore.$ZodLazy<infer Inner extends zCore.$ZodType> ? ConvexValidatorFromZod<Inner, IsOptional> : Z extends zCore.$ZodTemplateLiteral<infer Template extends string> ? VString<Template, IsOptional> : Z extends zCore.$ZodCatch<infer T extends zCore.$ZodType> ? ConvexValidatorFromZod<T, IsOptional> : Z extends zCore.$ZodTransform<any, any> ? VAny<any, 'required'> : Z extends zCore.$ZodCustom<any> ? VAny<any, 'required'> : Z extends zCore.$ZodIntersection<any> ? VAny<any, 'required'> : IsConvexUnencodableType<Z> extends true ? never : GenericValidator; type ConvexUnionValidatorFromZod<T extends readonly zCore.$ZodType[]> = VUnion<ConvexValidatorFromZod<T[number], 'required'>['type'], T extends readonly [infer Head extends zCore.$ZodType, ...infer Tail extends zCore.$ZodType[]] ? [VRequired<ConvexValidatorFromZod<Head, 'required'>>, ...ConvexUnionValidatorFromZodMembers<Tail>] : T extends readonly [] ? [] : Validator<any, 'required', any>[], 'required', ConvexValidatorFromZod<T[number], 'required'>['fieldPaths']>; type ConvexUnionValidatorFromZodMembers<T extends readonly zCore.$ZodType[]> = T extends readonly [infer Head extends zCore.$ZodType, ...infer Tail extends zCore.$ZodType[]] ? [VRequired<ConvexValidatorFromZod<Head, 'required'>>, ...ConvexUnionValidatorFromZodMembers<Tail>] : T extends readonly [] ? [] : Validator<any, 'required', any>[]; type ConvexObjectFromZodShape<Fields extends Readonly<zCore.$ZodShape>> = Fields extends infer F ? { [K in keyof F]: F[K] extends zCore.$ZodType ? ConvexValidatorFromZod<F[K], 'required'> : Validator<any, 'required', any> } : never; type ConvexObjectValidatorFromRecord<Key extends string, Value extends zCore.$ZodType, IsOptional extends 'required' | 'optional', IsPartial extends 'partial' | 'full'> = VObject<IsPartial extends 'partial' ? { [K in Key]?: zCore.infer<Value> } : MakeUndefinedPropertiesOptional<{ [K in Key]: zCore.infer<Value> }>, IsPartial extends 'partial' ? { [K in Key]: VOptional<ConvexValidatorFromZod<Value, 'required'>> } : { [K in Key]: ConvexValidatorFromZod<Value, 'required'> }, IsOptional>; type MakeUndefinedPropertiesOptional<Obj extends object> = Expand<{ [K in keyof Obj as undefined extends Obj[K] ? never : K]: Obj[K] } & { [K in keyof Obj as undefined extends Obj[K] ? K : never]?: Obj[K] }>; type ConvexValidatorFromZodRecord<Key extends zCore.$ZodRecordKey, Value extends zCore.$ZodType, IsOptional extends 'required' | 'optional'> = Key extends zCore.$ZodString | Zid<any> | zCore.$ZodUnion<infer _Ids extends readonly Zid<any>[]> ? VRecord<Record<zCore.infer<Key>, NotUndefined<zCore.infer<Value>>>, VRequired<ConvexValidatorFromZod<Key, 'required'>>, VRequired<ConvexValidatorFromZod<Value, 'required'>>, IsOptional> : Key extends zCore.$ZodLiteral<infer Literal extends string> ? ConvexObjectValidatorFromRecord<Literal, Value, IsOptional, Key extends zCore.$partial ? 'partial' : 'full'> : Key extends zCore.$ZodUnion<infer Literals extends readonly zCore.$ZodLiteral[]> ? ConvexObjectValidatorFromRecord<zCore.infer<Literals[number]> extends string ? zCore.infer<Literals[number]> : never, Value, IsOptional, Key extends zCore.$partial ? 'partial' : 'full'> : VRecord<Record<string, NotUndefined<zCore.infer<Value>>>, VString<string, 'required'>, VRequired<ConvexValidatorFromZod<Value, 'required'>>, IsOptional>; type IsConvexUnencodableType<Z extends zCore.$ZodType> = Z extends zCore.$ZodDate | zCore.$ZodSymbol | zCore.$ZodMap | zCore.$ZodSet | zCore.$ZodPromise | zCore.$ZodFile | zCore.$ZodFunction | zCore.$ZodUndefined | zCore.$ZodVoid ? true : false; type IsUnion<T, U extends T = T> = T extends unknown ? [U] extends [T] ? false : true : false; type ConvexLiteralFromZod<Literal extends zCore.util.Literal, IsOptional extends 'required' | 'optional'> = undefined extends Literal ? never : [Literal] extends [null] ? VNull<null, IsOptional> : IsUnion<Literal> extends true ? VUnion<Literal, Array<Literal extends unknown ? ConvexLiteralFromZod<Literal, 'required'> : never>, IsOptional, never> : VLiteral<Literal, IsOptional>; type IsUnknownOrAny<T> = 0 extends 1 & T ? true : unknown extends T ? true : false; /** * Better type conversion from a Convex validator to a Zod validator * where the output is not a generic ZodType but it's more specific. * * This allows you to use methods specific to the Zod type (e.g. `.email()` for `z.ZodString`). * * ```ts * ZodValidatorFromConvex<typeof v.string()> // → z.ZodString * ``` */ type ZodValidatorFromConvex<V extends GenericValidator> = V extends Validator<any, 'optional', any> ? z$1.ZodOptional<ZodFromValidatorBase<VRequired<V>>> : ZodFromValidatorBase<V>; type ZodFromValidatorBase<V extends GenericValidator> = V extends VId<infer Type> ? Zid<TableNameFromType<NotUndefined<Type>>> : V extends VString<infer T> ? BrandIfBranded<T, z$1.ZodString> : V extends VFloat64<infer T> ? BrandIfBranded<T, z$1.ZodNumber> : V extends VInt64<any> ? z$1.ZodBigInt : V extends VBoolean<any> ? z$1.ZodBoolean : V extends VNull<any> ? z$1.ZodNull : V extends VArray<any, infer Element> ? Element extends VArray<any, any> ? z$1.ZodArray<zCore.SomeType> : z$1.ZodArray<ZodFromValidatorBase<Element>> : V extends VObject<any, infer Fields extends Record<string, GenericValidator>> ? z$1.ZodObject<ZodShapeFromConvexObject<Fields>, zCore.$strict> : V extends VBytes<any, any> ? never : V extends VLiteral<infer T extends zCore.util.Literal, OptionalProperty> ? z$1.ZodLiteral<NotUndefined<T>> : V extends VRecord<any, infer Key, infer Value, OptionalProperty, any> ? z$1.ZodRecord<ZodFromStringValidator<Key>, ZodFromValidatorBase<Value>> : V extends VUnion<any, [], OptionalProperty, any> ? z$1.ZodNever : V extends VUnion<any, [infer I extends GenericValidator], OptionalProperty, any> ? ZodValidatorFromConvex<I> : V extends VUnion<any, [infer A extends GenericValidator, ...infer Rest extends GenericValidator[]], OptionalProperty, any> ? z$1.ZodUnion<readonly [ZodValidatorFromConvex<A>, ...{ [K in keyof Rest]: ZodValidatorFromConvex<Rest[K]> }]> : V extends VAny<any, OptionalProperty, any> ? z$1.ZodAny : never; type BrandIfBranded<InnerType, Validator extends zCore.SomeType> = InnerType extends zCore.$brand<infer Brand> ? zCore.$ZodBranded<Validator, Brand> : Validator; type StringValidator = Validator<string, 'required', any>; type ZodFromStringValidator<V extends StringValidator> = V extends VId<GenericId<infer TableName extends string>> ? Zid<TableName> : V extends VString<infer T, any> ? BrandIfBranded<T, z$1.ZodString> : V extends VLiteral<infer Literal extends string> ? z$1.ZodLiteral<Literal> : V extends VUnion<any, [], any, any> ? z$1.ZodNever : V extends VUnion<any, [infer I extends GenericValidator], any, any> ? ZodFromStringValidator<I> : V extends VUnion<any, [infer A extends GenericValidator, ...infer Rest extends GenericValidator[]], any, any> ? z$1.ZodUnion<readonly [ZodFromStringValidator<A>, ...{ [K in keyof Rest]: ZodFromStringValidator<Rest[K]> }]> : never; type ZodShapeFromConvexObject<Fields extends Record<string, GenericValidator>> = Fields extends infer F ? { [K in keyof F]: F[K] extends GenericValidator ? ZodValidatorFromConvex<F[K]> : never } : never; type NotUndefined<T> = Exclude<T, undefined>; type TableNameFromType<T> = T extends GenericId<infer TableName> ? TableName : string; //#endregion //#region src/server/http-builder.d.ts declare function extractPathParams(path: string): string[]; declare function matchPathParams(template: string, pathname: string): Record<string, string> | null; declare function handleHttpError(error: unknown): Response; /** * HttpProcedureBuilder - Fluent builder for HTTP endpoints * * Uses tRPC-style interface + factory pattern for proper generic type preservation: * - Interface declares full generics with explicit return types * - Factory function creates implementation objects * - This preserves literal types like 'GET' through method chains */ interface HttpProcedureBuilder<TInitialCtx, TCtx, TInput extends UnsetMarker | z.ZodTypeAny = UnsetMarker, TOutput extends UnsetMarker | z.ZodTypeAny = UnsetMarker, TParams extends UnsetMarker | z.ZodTypeAny = UnsetMarker, TQuery extends UnsetMarker | z.ZodTypeAny = UnsetMarker, TMeta extends ProcedureMeta = ProcedureMeta, TMethod extends HttpMethod = HttpMethod, TForm extends UnsetMarker | z.ZodTypeAny = UnsetMarker> { _def: HttpProcedureBuilderDef<TCtx, TInput, TOutput, TParams, TQuery, TMeta, TMethod, TForm>; /** DELETE endpoint (Hono-style) */ delete(path: string): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, 'DELETE', TForm>; /** Define form data schema (for multipart/form-data uploads) */ form<TSchema extends z.ZodTypeAny>(schema: TSchema): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, TMethod, TSchema>; /** GET endpoint (Hono-style) */ get(path: string): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, 'GET', TForm>; /** Define request body schema (for POST/PUT/PATCH) */ input<TSchema extends z.ZodTypeAny>(schema: TSchema): HttpProcedureBuilder<TInitialCtx, TCtx, TSchema, TOutput, TParams, TQuery, TMeta, TMethod, TForm>; /** Set procedure metadata (shallow merged when chained) */ meta(value: TMeta): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, TMethod, TForm>; /** * Define the handler for POST/PUT/PATCH/DELETE endpoints (maps to useMutation on client). * Handler receives Hono Context `c` for Response helpers (c.json, c.body, c.text). * Return Response for custom responses, or plain object for auto JSON serialization. */ mutation<TResult>(handler: (opts: HttpHandlerOpts<TCtx, TInput, TParams, TQuery, TForm>) => Promise<Response | (TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult)>): HttpProcedure<TInput, TOutput, TParams, TQuery, TMethod, TForm>; /** Set a server-only procedure name for middleware/logging */ name(value: string): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, TMethod, TForm>; /** Define response schema */ output<TSchema extends z.ZodTypeAny>(schema: TSchema): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TSchema, TParams, TQuery, TMeta, TMethod, TForm>; /** Define path parameter schema (for :param in path) */ params<TSchema extends z.ZodTypeAny>(schema: TSchema): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TSchema, TQuery, TMeta, TMethod, TForm>; /** PATCH endpoint (Hono-style) */ patch(path: string): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, 'PATCH', TForm>; /** POST endpoint (Hono-style) */ post(path: string): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, 'POST', TForm>; /** PUT endpoint (Hono-style) */ put(path: string): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, 'PUT', TForm>; /** * Define the handler for GET endpoints (maps to useQuery on client). * Handler receives Hono Context `c` for Response helpers (c.json, c.body, c.text). * Return Response for custom responses, or plain object for auto JSON serialization. */ query<TResult>(handler: (opts: HttpHandlerOpts<TCtx, TInput, TParams, TQuery, TForm>) => Promise<Response | (TOutput extends z.ZodTypeAny ? z.infer<TOutput> : TResult)>): HttpProcedure<TInput, TOutput, TParams, TQuery, TMethod, TForm>; /** Define the route path and HTTP method */ route<M extends HttpMethod>(path: string, method: M): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TQuery, TMeta, M, TForm>; /** Define query parameter schema (?key=value) */ searchParams<TSchema extends z.ZodTypeAny>(schema: TSchema): HttpProcedureBuilder<TInitialCtx, TCtx, TInput, TOutput, TParams, TSchema, TMeta, TMethod, TForm>; /** Add middleware to the procedure */ use<$ContextOverridesOut extends object>(middlewareOrBuilder: MiddlewareFunction<TCtx, TMeta, UnsetMarker, $ContextOverridesOut, unknown> | MiddlewareBuilder<any, // Allow reusable middleware with any context TMeta, $ContextOverridesOut, unknown>): HttpProcedureBuilder<TInitialCtx, Overwrite$1<TCtx, $ContextOverridesOut>, TInput, TOutput, TParams, TQuery, TMeta, TMethod, TForm>; } /** * Create initial HttpProcedureBuilder */ declare function createHttpProcedureBuilder<TCtx, TMeta extends ProcedureMeta>(config: { base: HttpProcedureBuilderDef<TCtx, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, TMeta, HttpMethod, UnsetMarker>['functionConfig']['base']; createContext: (ctx: GenericActionCtx<GenericDataModel>) => TCtx; meta: TMeta; transformer?: DataTransformerOptions; }): HttpProcedureBuilder<TCtx, TCtx, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, TMeta, HttpMethod, UnsetMarker>; //#endregion //#region src/server/builder.d.ts /** * Paginated schema for type inference ONLY. * After .paginated() applies defaults, cursor and limit are always defined. * The actual runtime schema uses .default() and .transform() for validation. */ declare const paginatedSchemaForTypes: z.ZodObject<{ cursor: z.ZodUnion<readonly [z.ZodString, z.ZodNull]>; limit: z.ZodNumber; }, z.core.$strip>; /** Paginated schema type - both cursor and limit are required after .paginated() */ type PaginatedInputSchema = typeof paginatedSchemaForTypes; /** Paginated schema type for external callers - both fields are optional due defaults. */ declare const paginatedSchemaForClientTypes: z.ZodObject<{ cursor: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>; limit: z.ZodOptional<z.ZodNumber>; }, z.core.$strip>; type PaginatedClientInputSchema = typeof paginatedSchemaForClientTypes; /** * Infer input type from ZodObject schema (for handlers) */ type InferInput<T> = T extends UnsetMarker ? Record<string, never> : T extends z.ZodObject<any> ? z.infer<T> : never; /** * Infer raw client input before defaults/transforms. * Used for generated API arg typing. */ type InferClientInput<T> = T extends UnsetMarker ? Record<string, never> : T extends z.ZodObject<any> ? z.input<T> : never; /** * Infer input type for middleware (returns unknown for UnsetMarker, matching tRPC) * Middleware before .input() receives unknown input */ type InferMiddlewareInput<T> = T extends UnsetMarker ? unknown : T extends z.ZodObject<any> ? z.infer<T> : unknown; /** * Static-only type hint attached to cRPC exports. * * Convex validators can widen unsupported types (like Date) to `any`. * Codegen can read this hint from `typeof import(...).fn` to recover precise * TypeScript input/output types for generated client API refs. */ type CRPCFunctionTypeHint<TArgs, TReturns> = { readonly __kitcnTypeHint?: { readonly args: TArgs; readonly returns: TReturns; }; }; /** Base config shape for function builders */ type FunctionBuilderConfig = { /** Base function builder (query, mutation, or action from Convex) */base: unknown; /** Internal function builder (internalQuery, etc.) */ internal?: unknown; }; /** Internal config combining context creator with function builders */ type InternalFunctionConfig = FunctionBuilderConfig & { /** Transform raw Convex context to the base context for procedures */createContext: (ctx: any) => unknown; /** Wire transformer for request/response serialization. */ transformer: ReturnType<typeof getTransformer>; }; /** Context creators for each function type - all optional, defaults to passthrough */ type ContextConfig<DataModel extends GenericDataModel> = { query?: (ctx: GenericQueryCtx<DataModel>) => unknown; mutation?: (ctx: GenericMutationCtx<DataModel>) => unknown; action?: (ctx: GenericActionCtx<DataModel>) => unknown; }; /** Infer context types from config - defaults to raw Convex ctx when not specified */ type InferQueryCtx<T, DataModel extends GenericDataModel> = T extends { query: (...args: never[]) => infer R; } ? R : GenericQueryCtx<DataModel>; type InferMutationCtx<T, DataModel extends GenericDataModel> = T extends { mutation: (...args: never[]) => infer R; } ? R : GenericMutationCtx<DataModel>; type InferActionCtx<T, DataModel extends GenericDataModel> = T extends { action: (...args: never[]) => infer R; } ? R : GenericActionCtx<DataModel>; /** Function builders for each function type */ type FunctionsConfig = { query?: unknown; internalQuery?: unknown; mutation?: unknown; internalMutation?: unknown; action?: unknown; internalAction?: unknown; httpAction?: unknown; }; /** Config for create() including optional defaultMeta */ type CreateConfig<TMeta extends object> = FunctionsConfig & { defaultMeta?: TMeta; /** Optional cRPC payload transformer (always composed with built-in Date support). */ transformer?: DataTransformerOptions; }; /** * Create a middleware factory for building reusable middleware chains * * @example * ```typescript * const loggedIn = c.middleware(({ ctx, next }) => { * if (!ctx.userId) throw new CRPCError({ code: 'UNAUTHORIZED' }); * return next({ ctx }); * }); * * const isAdmin = loggedIn.pipe(({ ctx, next }) => { *