convex
Version:
Client for the Convex Cloud
160 lines (143 loc) • 3.85 kB
text/typescript
/**
* All of the utility types to describe a Convex API of queries and mutations
*/
import { Expand, PickByValue, UnionToIntersection } from "../type_utils.js";
/**
* Description of the Convex functions available to an application.
*
* This is a generic type that expresses the shape of API types created by
* `npx convex codegen`. It's used to make the Convex clients type-safe.
*
* @public
*/
export type GenericAPI = {
queries: Record<string, (...args: any[]) => any>;
mutations: Record<string, (...args: any[]) => any>;
actions: Record<string, (...args: any[]) => any>;
};
/**
* Helper types for interacting with the overall API type
*/
/**
* The names of query functions in a Convex API.
*
* @public
*/
export type QueryNames<API extends GenericAPI> = keyof API["queries"] & string;
/**
* The names of mutation functions in a Convex API.
*
* @public
*/
export type MutationNames<API extends GenericAPI> = keyof API["mutations"] &
string;
/**
* The names of actions in a Convex API.
*
* @public
*/
export type ActionNames<API extends GenericAPI> = keyof API["actions"] & string;
/**
* The type of a query function in a Convex API.
*
* @public
*/
export type NamedQuery<
API extends GenericAPI,
Name extends QueryNames<API>
> = API["queries"][Name];
/**
* The type of a mutation function in a Convex API.
*
* @public
*/
export type NamedMutation<
API extends GenericAPI,
Name extends MutationNames<API>
> = API["mutations"][Name];
/**
* The type of an action in a Convex API.
*
* @public
*/
export type NamedAction<
API extends GenericAPI,
Name extends MutationNames<API>
> = API["actions"][Name];
/**
* Internal Codegen Type Helpers
*/
/**
* Generate the fully-qualified query/mutation name of an export.
*
* This is `path/to/module:export` or `path/to/module` for the default export.
*/
type FunctionName<
FilePath extends string,
ExportName extends string
> = ExportName extends "default" ? FilePath : `${FilePath}:${ExportName}`;
/**
* Generate a type of this module where each export is renamed to its
* fully-qualified {@link FunctionName}.
*/
type NameModule<FilePath extends string, Module extends Record<string, any>> = {
[ExportName in keyof Module as FunctionName<
FilePath,
ExportName & string
>]: Module[ExportName];
};
/**
* Name and merge together all of the exports in the `convex/` directory into
* a flat object type.
*/
type MergeAllExports<Modules extends Record<string, Record<string, any>>> =
UnionToIntersection<
{
[FilePath in keyof Modules]: NameModule<
FilePath & string,
Modules[FilePath]
>;
}[keyof Modules]
>;
type UndefinedToNull<T> = T extends void ? null : T;
/**
* Converts a map of query and mutation types into their client form.
*
* This is done by:
* - Unwrapping `Promise` if it's in the output.
* - Switching functions that output `undefined` to `null`.
*
*/
type ConvertToClientFunctions<FunctionsByName extends Record<string, any>> = {
[Name in keyof FunctionsByName]: (
...args: FunctionsByName[Name]["args"]
) => UndefinedToNull<Awaited<FunctionsByName[Name]["output"]>>;
};
/**
* Create the API type from the types of all of the modules.
*
* Input is an object mapping file paths to the type of each module.
*
* For internal use by Convex code generation.
*
* @public
*/
export type ApiFromModules<
Modules extends Record<string, Record<string, any>>
> = {
queries: Expand<
ConvertToClientFunctions<
PickByValue<MergeAllExports<Modules>, { isQuery: true }>
>
>;
mutations: Expand<
ConvertToClientFunctions<
PickByValue<MergeAllExports<Modules>, { isMutation: true }>
>
>;
actions: Expand<
ConvertToClientFunctions<
PickByValue<MergeAllExports<Modules>, { isAction: true }>
>
>;
};