UNPKG

convex

Version:

Client for the Convex Cloud

1,176 lines (1,115 loc) 42.2 kB
/** * Internal type helper used by Convex code generation. * * Used to give {@link actionGeneric} a type specific to your data model. * @public */ export declare type ActionBuilderForAPI<API extends GenericAPI> = <Args extends any[], Output>(func: (ctx: ActionCtx<API>, ...args: Args) => Output) => PublicAction<API, Args, Output>; /** * A set of services for use within Convex action. * * The context is passed as the first argument to any Convex action * run on the server. * * If you're using code generation, use the `ActionCtx` type in * `convex/_generated/server.d.ts` which is typed for your data model. * * @public */ export declare type ActionCtx<API extends GenericAPI> = { query<Name extends QueryNames<API>>(name: Name, ...args: Parameters<NamedQuery<API, Name>>): Promise<ReturnType<NamedQuery<API, Name>>>; mutation<Name extends MutationNames<API>>(name: Name, ...args: Parameters<NamedMutation<API, Name>>): Promise<ReturnType<NamedMutation<API, Name>>>; auth: Auth; }; /** * Define function in this Convex app's public API. * * @param func - The function. It receives a {@link ActionCtx} as its first argument. * @returns The wrapped function. Include this as an `export` to name it and make it accessible. * * @public */ export declare const actionGeneric: <API extends GenericAPI, Args extends any[], Output>(func: (ctx: ActionCtx<API>, ...args: Args) => Output) => PublicAction<API, Args, Output>; /** * A {@link GenericDataModel} that considers documents to be `any` and does not * support indexes. * * This is the default before a schema is defined. * @public */ export declare type AnyDataModel = Record<string, { document: any; fieldPaths: GenericFieldPaths; indexes: {}; }>; /** * An interface to access information about the currently authenticated user * within Convex query and mutation functions. * * @public */ export declare interface Auth { /** * Get details about the currently authenticated user. * * @returns A promise that resolves to a {@link UserIdentity} if the Convex * client was configured with a valid ID token and `null` otherwise. */ getUserIdentity(): Promise<UserIdentity | null>; } /** * An opaque identifier used for paginating a database query. * * Cursors are returned from {@link OrderedQuery.paginate} and represent the * point of the query where the page of results ended. * * To continue paginating, pass the cursor back into * {@link OrderedQuery.paginate} in the {@link PaginationOptions} object to * fetch another page of results. * * Note: Cursors can only be passed to _exactly_ the same database query that * they were generated from. You may not reuse a cursor between different * database queries. * * @public */ export declare type Cursor = string; /** * An interface to read from the database within Convex query functions. * * The two entry points are {@link DatabaseReader.get}, which fetches a single * document by its {@link values.GenericId}, or {@link DatabaseReader.query}, which starts * building a query. * * If you're using code generation, use the `DatabaseReader` type in * `convex/_generated/server.d.ts` which is typed for your data model. * * @public */ export declare interface DatabaseReader<DataModel extends GenericDataModel> { /** * Fetch a single document from the database by its {@link values.GenericId}. * * @param id - The {@link values.GenericId} of the document to fetch from the database. * @returns - The {@link GenericDocument} of the document at the given {@link values.GenericId}, or `null` if it no longer exists. */ get<TableName extends TableNamesInDataModel<DataModel>>(id: GenericId<TableName>): Promise<DocumentByName<DataModel, TableName> | null>; /** * Begin a query for the given table name. * * Queries don't execute immediately, so calling this method and extending its * query are free until the results are actually used. * * @param tableName - The name of the table to query. * @returns - A {@link QueryInitializer} object to start building a query. */ query<TableName extends TableNamesInDataModel<DataModel>>(tableName: TableName): QueryInitializer<NamedTableInfo<DataModel, TableName>>; } /** * An interface to read from and write to the database within Convex mutation * functions. * * Convex guarantees that all writes within a single mutation are * executed atomically, so you never have to worry about partial writes leaving * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) * for the guarantees Convex provides your functions. * * If you're using code generation, use the `DatabaseReader` type in * `convex/_generated/server.d.ts` which is typed for your data model. * * @public */ export declare interface DatabaseWriter<DataModel extends GenericDataModel> extends DatabaseReader<DataModel> { /** * Insert a new document into a table. * * @param table - The name of the table to insert a new document into. * @param value - The {@link values.Value} to insert into the given table. * @returns - {@link values.GenericId} of the new document. */ insert<TableName extends TableNamesInDataModel<DataModel>>(table: TableName, value: WithoutSystemFields<DocumentByName<DataModel, TableName>>): Promise<GenericId<TableName>>; /** * Patch an existing document, merging its value with a new values. * * Any overlapping fields in the two documents will be overwritten with * their new value. * * @param id - The {@link values.GenericId} of the document to patch. * @param value - The partial {@link GenericDocument} to merge into the specified document. If this new value * specifies system fields like `_id`, they must match the document's existing field values. */ patch<TableName extends TableNamesInDataModel<DataModel>>(id: GenericId<TableName>, value: Partial<DocumentByName<DataModel, TableName>>): Promise<void>; /** * Replace the value of an existing document, overwriting its old value. * * @param id - The {@link values.GenericId} of the document to replace. * @param value - The new {@link GenericDocument} for the document. This value can omit the system fields, * and the database will fill them in. */ replace<TableName extends TableNamesInDataModel<DataModel>>(id: GenericId<TableName>, value: WithOptionalSystemFields<DocumentByName<DataModel, TableName>>): Promise<void>; /** * Delete an existing document. * * @param id - The {@link values.GenericId} of the document to remove. */ delete(id: GenericId<TableNamesInDataModel<DataModel>>): Promise<void>; } /** * Apply `Omit<>` to each element of a union. */ declare type DistributiveOmit<T, K extends keyof T> = T extends any ? Omit<T, K> : never; /** * The type of a document in a table for a given {@link GenericTableInfo}. * @public */ export declare type DocumentByInfo<TableInfo extends GenericTableInfo> = TableInfo["document"]; /** * The type of a document in a {@link GenericDataModel} by table name. * @public */ export declare type DocumentByName<DataModel extends GenericDataModel, TableName extends TableNamesInDataModel<DataModel>> = DataModel[TableName]["document"]; /** * Common utilities for manipulating TypeScript types. * @module */ /** * 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`. */ declare type Expand<ObjectType extends Record<any, any>> = ObjectType extends Record<any, any> ? { [Key in keyof ObjectType]: ObjectType[Key]; } : never; /** * Expressions are evaluated to produce a {@link values.Value} in the course of executing a query. * * To construct an expression, use the {@link FilterBuilder} provided within * {@link OrderedQuery.filter}. * * @typeParam T - The type that this expression evaluates to. * @public */ export declare abstract class Expression<T extends Value> { private _isExpression; private _value; /** * @internal */ constructor(); } /** * An {@link Expression} or a constant {@link values.Value} * * @public */ export declare type ExpressionOrValue<T extends Value> = Expression<T> | T; /** * The field paths in a table for a given {@link GenericTableInfo}. * * These can either be field names (like "name") or references to fields on * nested objects (like "properties.name"). * @public */ export declare type FieldPaths<TableInfo extends GenericTableInfo> = TableInfo["fieldPaths"]; /** * The type of a field in a document. * * Note that this supports both simple fields like "name" and nested fields like * "properties.name". * * If the field is not present in the document it is considered to be `null`. * * @public */ export declare type FieldTypeFromFieldPath<Document extends GenericDocument, FieldPath extends string> = FieldPath extends `${infer First}.${infer Second}` ? First extends keyof Document ? Document[First] extends GenericDocument ? FieldTypeFromFieldPath<Document[First], Second> : null : null : FieldPath extends keyof Document ? Document[FieldPath] : null; /** * An interface for defining filters in queries. * * `FilterBuilder` has various methods that produce {@link Expression}s. * These expressions can be nested together along with constants to express * a filter predicate. * * `FilterBuilder` is used within {@link OrderedQuery.filter} to create query * filters. * * Here are the available methods: * * | | | * |-------------------------------|-----------------------------------------------| * | **Comparisons** | Error when `l` and `r` are not the same type. | * | [`eq(l, r)`](#eq) | `l === r` | * | [`neq(l, r)`](#neq) | `l !== r` | * | [`lt(l, r)`](#lt) | `l < r` | * | [`lte(l, r)`](#lte) | `l <= r` | * | [`gt(l, r)`](#gt) | `l > r` | * | [`gte(l, r)`](#gte) | `l >= r` | * | | | * | **Arithmetic** | Error when `l` and `r` are not the same type. | * | [`add(l, r)`](#add) | `l + r` | * | [`sub(l, r)`](#sub) | `l - r` | * | [`mul(l, r)`](#mul) | `l * r` | * | [`div(l, r)`](#div) | `l / r` | * | [`mod(l, r)`](#mod) | `l % r` | * | [`neg(x)`](#neg) | `-x` | * | | | * | **Logic** | Error if any param is not a `bool`. | * | [`not(x)`](#not) | `!x` | * | [`and(a, b, ..., z)`](#and) | `a && b && ... && z` | * | [`or(a, b, ..., z)`](#or) | <code>a &#124;&#124; b &#124;&#124; ... &#124;&#124; z</code> | * | | | * | **Other** | | * | [`field(fieldPath)`](#field) | Evaluates to the field at `fieldPath`. | * @public */ export declare interface FilterBuilder<TableInfo extends GenericTableInfo> { /** * `l === r` * * @public * */ eq<T extends Value>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<boolean>; /** * `l !== r` * * @public * */ neq<T extends Value>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<boolean>; /** * `l < r` * * @public */ lt<T extends Value>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<boolean>; /** * `l <= r` * * @public */ lte<T extends Value>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<boolean>; /** * `l > r` * * @public */ gt<T extends Value>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<boolean>; /** * `l >= r` * * @public */ gte<T extends Value>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<boolean>; /** * `l + r` * * @public */ add<T extends NumericValue>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<T>; /** * `l - r` * * @public */ sub<T extends NumericValue>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<T>; /** * `l * r` * * @public */ mul<T extends NumericValue>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<T>; /** * `l / r` * * @public */ div<T extends NumericValue>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<T>; /** * `l % r` * * @public */ mod<T extends NumericValue>(l: ExpressionOrValue<T>, r: ExpressionOrValue<T>): Expression<T>; /** * `-x` * * @public */ neg<T extends NumericValue>(x: ExpressionOrValue<T>): Expression<T>; /** * `exprs[0] && exprs[1] && ... && exprs[n]` * * @public */ and(...exprs: Array<ExpressionOrValue<boolean>>): Expression<boolean>; /** * `exprs[0] || exprs[1] || ... || exprs[n]` * * @public */ or(...exprs: Array<ExpressionOrValue<boolean>>): Expression<boolean>; /** * `!x` * * @public */ not(x: ExpressionOrValue<boolean>): Expression<boolean>; /** * Evaluates to the field at the given `fieldPath`. * * For example, in {@link OrderedQuery.filter} this can be used to examine the values being filtered. * * #### Example * * On this object: * ``` * { * "user": { * "isActive": true * } * } * ``` * * `field("user.isActive")` evaluates to `true`. * * @public */ field<FieldPath extends FieldPaths<TableInfo>>(fieldPath: FieldPath): Expression<FieldTypeFromFieldPath<DocumentByInfo<TableInfo>, FieldPath>>; } /** * 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 */ declare type GenericAPI = { queries: Record<string, (...args: any[]) => any>; mutations: Record<string, (...args: any[]) => any>; actions: Record<string, (...args: any[]) => any>; }; /** * A type describing the tables in a Convex project. * * This is designed to be code generated with `npx convex codegen`. * @public */ export declare type GenericDataModel = Record<string, GenericTableInfo>; /** * A document stored in Convex. * @public */ export declare type GenericDocument = Record<string, Value>; /** * A type describing all of the document fields in a table. * * These can either be field names (like "name") or references to fields on * nested objects (like "properties.name"). * @public */ export declare type GenericFieldPaths = string; /** * An identifier for a document in Convex. * * Convex documents are uniquely identified by their `GenericId`, which is accessible * on the `_id` field. To learn more, see [Data Modeling](https://docs.convex.dev/using/data-modeling). * * Documents can be loaded using `db.get(id)` in query and mutation functions. * * **Important**: Use `myId.equals(otherId)` to check for equality. * Using `===` will not work because two different instances of `GenericId` can refer * to the same document. * * `GenericId`s are 17 bytes long and consist of: * - A 15-byte random value. * - A 2-byte timestamp representing the document's creation, in days since the Unix epoch. * This is encoded in base 62 ([0-9A-Za-z]). * * If you're using code generation, use the `Id` class typed for your data model in * `convex/_generated/dataModel.js`. * * @typeParam TableName - A string literal type of the table name (like "users"). * * @public */ declare class GenericId<TableName extends string> { /** * The table name this {@link GenericId} references. */ readonly tableName: TableName; /** * The identifier string. * * This contains the characters `[0-9A-Za-z]`. */ readonly id: string; constructor(tableName: TableName, id: string); /** * Check if this {@link GenericId} refers to the same document as another {@link GenericId}. * * @param other - The other {@link GenericId} to compare to. * @returns `true` if the objects refer to the same document. */ equals(other: unknown): boolean; /** * Parse a {@link GenericId} from its JSON representation. */ static fromJSON(obj: any): GenericId<string>; /** * Convert a {@link GenericId} into its JSON representation. */ toJSON(): JSONValue; /** * Convert a {@link GenericId} into its string representation. * * This includes the identifier but not the table name. */ toString(): string; /** * Pretty-print this {@link GenericId} for debugging. */ inspect(): string; } /** * A type describing the ordered fields in an index. * * These can either be field names (like "name") or references to fields on * nested objects (like "properties.name"). * @public */ export declare type GenericIndexFields = string[]; /** * A type describing the indexes in a table. * * It's a map from index name to fields in the index. * @public */ export declare type GenericTableIndexes = Record<string, GenericIndexFields>; /** * A type describing the document type and indexes in a table. * @public */ export declare type GenericTableInfo = { document: GenericDocument; fieldPaths: GenericFieldPaths; indexes: GenericTableIndexes; }; /** * The names of indexes in a table for a given {@link GenericTableInfo}. * @public */ export declare type IndexNames<TableInfo extends GenericTableInfo> = keyof TableInfo["indexes"]; /** * An expression representing an index range created by * {@link IndexRangeBuilder}. * @public */ export declare abstract class IndexRange { private _isIndexRange; /** * @internal */ constructor(); } /** * Builder to define an index range to query. * * An index range is a description of which documents Convex should consider * when running the query. * * An index range is always a chained list of: * 1. 0 or more equality expressions defined with `.eq`. * 2. [Optionally] A lower bound expression defined with `.gt` or `.gte`. * 3. [Optionally] An upper bound expression defined with `.lt` or `.lte`. * * **You must step through fields in index order.** * * Each equality expression must compare a different index field, starting from * the beginning and in order. The upper and lower bounds must follow the * equality expressions and compare the next field. * * For example, if there is an index of messages on * `["projectId", "priority"]`, a range searching for "messages in 'myProjectId' * with priority at least 100" would look like: * ```ts * q.eq("projectId", myProjectId) * .gte("priority", 100) * ``` * * **The performance of your query is based on the specificity of the range.** * * This class is designed to only allow you to specify ranges that Convex can * efficiently use your index to find. For all other filtering use * {@link Query.filter}. * * To learn about indexes, see [Indexes](https://docs.convex.dev/using/indexes). * @public */ export declare interface IndexRangeBuilder<Document extends GenericDocument, IndexFields extends GenericIndexFields, FieldNum extends number = 0> extends LowerBoundIndexRangeBuilder<Document, IndexFields[FieldNum]> { /** * Restrict this range to documents where `doc[fieldName] === value`. * * @param fieldName - The name of the field to compare. Must be the next field * in the index. * @param value - The value to compare against. */ eq(fieldName: IndexFields[FieldNum], value: FieldTypeFromFieldPath<Document, IndexFields[FieldNum]>): NextIndexRangeBuilder<Document, IndexFields, FieldNum>; } /** * The type of JavaScript values serializable to JSON. * * @public */ declare type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue; }; /** * Builder to define the lower bound of an index range. * * See {@link IndexRangeBuilder}. * * @public */ declare interface LowerBoundIndexRangeBuilder<Document extends GenericDocument, IndexFieldName extends string> extends UpperBoundIndexRangeBuilder<Document, IndexFieldName> { /** * Restrict this range to documents where `doc[fieldName] > value`. * * @param fieldName - The name of the field to compare. Must be the next field * in the index. * @param value - The value to compare against. */ gt(fieldName: IndexFieldName, value: FieldTypeFromFieldPath<Document, IndexFieldName>): UpperBoundIndexRangeBuilder<Document, IndexFieldName>; /** * Restrict this range to documents where `doc[fieldName] >= value`. * * @param fieldName - The name of the field to compare. Must be the next field * in the index. * @param value - The value to compare against. */ gte(fieldName: IndexFieldName, value: FieldTypeFromFieldPath<Document, IndexFieldName>): UpperBoundIndexRangeBuilder<Document, IndexFieldName>; } /** * Internal type helper used by Convex code generation. * * Used to give {@link mutationGeneric} a type specific to your data model. * @public */ export declare type MutationBuilderForDataModel<DataModel extends GenericDataModel> = <Args extends any[], Output>(func: (ctx: MutationCtx<DataModel>, ...args: Args) => Output) => PublicMutation<DataModel, Args, Output>; /** * A set of services for use within Convex mutation functions. * * The mutation context is passed as the first argument to any Convex mutation * function run on the server. * * If you're using code generation, use the `MutationCtx` type in * `convex/_generated/server.d.ts` which is typed for your data model. * * @public */ export declare type MutationCtx<DataModel extends GenericDataModel> = { db: DatabaseWriter<DataModel>; auth: Auth; }; /** * Define a mutation in this Convex app's public API. * * This function will be allowed to modify your Convex database and will be accessible from the client. * * If you're using code generation, use the `mutation` function in * `convex/_generated/server.d.ts` which is typed for your data model. * * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. * * @public */ export declare const mutationGeneric: <DataModel extends GenericDataModel, Args extends any[], Output>(func: (ctx: MutationCtx<DataModel>, ...args: Args) => Output) => PublicMutation<DataModel, Args, Output>; /** * The names of mutation functions in a Convex API. * * @public */ declare type MutationNames<API extends GenericAPI> = keyof API["mutations"] & string; /** * Extract the fields of an index from a {@link GenericTableInfo} by name. * @public */ export declare type NamedIndex<TableInfo extends GenericTableInfo, IndexName extends IndexNames<TableInfo>> = TableInfo["indexes"][IndexName]; /** * The type of a mutation function in a Convex API. * * @public */ declare type NamedMutation<API extends GenericAPI, Name extends MutationNames<API>> = API["mutations"][Name]; /** * The type of a query function in a Convex API. * * @public */ declare type NamedQuery<API extends GenericAPI, Name extends QueryNames<API>> = API["queries"][Name]; /** * Extract the `TableInfo` for a table in a {@link GenericDataModel} by table * name. * * @public */ export declare type NamedTableInfo<DataModel extends GenericDataModel, TableName extends keyof DataModel> = DataModel[TableName]; /** * An {@link IndexRangeBuilder} for the next field of the index. * * This type is careful to check if adding one to the `FieldNum` will exceed * the length of the `IndexFields`. */ declare type NextIndexRangeBuilder<Document extends GenericDocument, IndexFields extends GenericIndexFields, FieldNum extends number> = PlusOne<FieldNum> extends IndexFields["length"] ? IndexRange : IndexRangeBuilder<Document, IndexFields, PlusOne<FieldNum>>; /** * The types of {@link Value} that can be used to represent numbers. * * @public */ declare type NumericValue = bigint | number; /** * A {@link Query} with an order that has already been defined. * * @public */ export declare interface OrderedQuery<TableInfo extends GenericTableInfo> extends AsyncIterable<DocumentByInfo<TableInfo>> { /** * Filter the query output, returning only the values for which `predicate` evaluates to true. * * @param predicate - An {@link Expression} constructed with the supplied {@link FilterBuilder} that specifies which documents to keep. * @returns - A new {@link OrderedQuery} with the given filter predicate applied. * */ filter(predicate: (q: FilterBuilder<TableInfo>) => Expression<boolean>): OrderedQuery<TableInfo>; /** * Take only the first `n` results from the pipeline so far. * * @param n - Limit for the number of results at this stage of the query pipeline. * @returns - A new {@link OrderedQuery} with the specified limit applied. * * @internal */ limit(n: number): OrderedQuery<TableInfo>; /** * Load a page of `n` results and obtain a {@link Cursor} for loading more. * * Note: If this is called from a reactive query function the number of * results may not match `options.numItems`! * * `options.numItems` is only an initial value. After the first invocation, * `paginate` will return all items in the original query range. This ensures * that all pages will remain adjacent and non-overlapping. * * @param options - A {@link PaginationOptions} object containing the number * of items to load and the cursor to start at. * @returns A {@link PaginationResult} containing the page of results and a * cursor to continue paginating. */ paginate(options: PaginationOptions): Promise<PaginationResult<DocumentByInfo<TableInfo>>>; /** * Execute the query and return all of the results as an array. * * Note: when processing a query with a lot of results, it's often better to use the `Query` as an * `AsyncIterable` instead. * * @returns - An array of all of the query's results. */ collect(): Promise<Array<DocumentByInfo<TableInfo>>>; /** * Execute the query and return the first `n` results. * * @param n - The number of items to take. * @returns - An array of the first `n` results of the query (or less if the * query doesn't have `n` results). */ take(n: number): Promise<Array<DocumentByInfo<TableInfo>>>; /** * Execute the query and return the first result if there is one. * * @returns - The first value of the query or `null` if the query returned no results. * */ first(): Promise<DocumentByInfo<TableInfo> | null>; /** * Execute the query and return the singular result if there is one. * * @returns - The single result returned from the query or null if none exists. * @throws Will throw an error if the query returns more than one result. */ unique(): Promise<DocumentByInfo<TableInfo> | null>; } /** * The options passed to {@link OrderedQuery.paginate}. * * @public */ export declare interface PaginationOptions { /** * Number of items to load in this page of results. * * Note: This is only an initial value! * * If you are running this paginated query in a reactive query function, you * may receive more or less items than this if items were added to or removed * from the query range. */ numItems: number; /** * A {@link Cursor} representing the start of this page or `null` to start * at the beginning of the query results. */ cursor: Cursor | null; /** * What is the maximum number of rows that should be read from the database? This option * is different from `numItems` in that it controls the number of rows entering a query's * pipeline, where `numItems` controls the number of rows coming out. For example, a `filter` * may disqualify most of the rows coming in, so setting a low `numItems` would not help * bound its execution time. Instead, set a low `maximumRowsRead` to efficiently paginate * through the filter. * * @internal */ maximumRowsRead?: number; } /** * The result of paginating using {@link OrderedQuery.paginate}. * * @public */ export declare interface PaginationResult<T> { /** * The page of results. */ page: T[]; /** * Have we reached the end of the results? */ isDone: boolean; /** * A {@link Cursor} to continue loading more results. */ continueCursor: Cursor; } /** * A type that adds 1 to a number literal type (up to 14). * * This is necessary to step through the fields in an index. */ declare type PlusOne<N extends number> = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ][N]; /** * An action that is part of this app's public API. * * You can create public action by wrapping your function in * {@link actionGeneric} and exporting it. * * @public */ export declare type PublicAction<API extends GenericAPI, Args extends any[], Output> = { args: Args; output: Output; (ctx: ActionCtx<API>, ...args: Args): Output; isAction: true; isRegistered?: true; /** @internal */ invokeAction(requestId: string, argsStr: string): Promise<string>; }; /** * A mutation function that is part of this app's public API. * * You can create public mutations by wrapping your function in * {@link mutationGeneric} and exporting it. * * @public */ export declare type PublicMutation<DataModel extends GenericDataModel, Args extends any[], Output> = { args: Args; output: Output; (ctx: MutationCtx<DataModel>, ...args: Args): Output; isMutation: true; isRegistered?: true; /** @internal */ invokeMutation(argsStr: string): Promise<string>; }; /** * A query function that is part of this app's public API. * * You can create public queries by wrapping your function in * {@link queryGeneric} and exporting it. * * @public */ export declare type PublicQuery<DataModel extends GenericDataModel, Args extends any[], Output> = { args: Args; output: Output; (ctx: QueryCtx<DataModel>, ...args: Args): Output; isQuery: true; isRegistered?: true; /** @internal */ invokeQuery(argsStr: string): Promise<string>; }; /** * The {@link Query} interface allows functions to read values out of the database. * * **If you only need to load an object by ID, use `db.get(id)` instead.** * * Executing a query consists of calling * 1. (Optional) {@link Query.order} to define the order * 2. (Optional) {@link Query.filter} to refine the results * 3. A *consumer* method to obtain the results * * Queries are lazily evaluated. No work is done until iteration begins, so constructing and * extending a query is free. The query is executed incrementally as the results are iterated over, * so early terminating also reduces the cost of the query. * * It is more efficient to use `filter` expression rather than executing JavaScript to filter. * * | | | * |----------------------------------------------|-| * | **Ordering** | | * | [`order("asc")`](#order) | Define the order of query results. | * | | | * | **Filtering** | | * | [`filter(...)`](#filter) | Filter the query results to only the values that match some condition. | * | | | * | **Consuming** | Execute a query and return results in different ways. | * | [`[Symbol.asyncIterator]()`](#asynciterator) | The query's results can be iterated over using a `for await..of` loop. | * | [`collect()`](#collect) | Return all of the results as an array. | * | [`take(n: number)`](#take) | Return the first `n` results as an array. | * | [`first()`](#first) | Return the first result. | * | [`unique()`](#unique) | Return the only result, and throw if there is more than one result. | * * To learn more about how to write queries, see [Querying the Database](https://docs.convex.dev/using/database-queries). * * @public */ export declare interface Query<TableInfo extends GenericTableInfo> extends OrderedQuery<TableInfo> { /** * Define the order of the query output. * * Use `"asc"` for an ascending order and `"desc"` for a descending order. If not specified, the order defaults to ascending. * @param order - The order to return results in. */ order(order: "asc" | "desc"): OrderedQuery<TableInfo>; } /** * Internal type helper used by Convex code generation. * * Used to give {@link queryGeneric} a type specific to your data model. * @public */ export declare type QueryBuilderForDataModel<DataModel extends GenericDataModel> = <Args extends any[], Output>(func: (ctx: QueryCtx<DataModel>, ...args: Args) => Output) => PublicQuery<DataModel, Args, Output>; /** * A set of services for use within Convex query functions. * * The query context is passed as the first argument to any Convex query * function run on the server. * * This differs from the {@link MutationCtx} because all of the services are * read-only. * * If you're using code generation, use the `QueryCtx` type in * `convex/_generated/server.d.ts` which is typed for your data model. * * @public */ export declare type QueryCtx<DataModel extends GenericDataModel> = { db: DatabaseReader<DataModel>; auth: Auth; }; /** * Define a query in this Convex app's public API. * * This function will be allowed to read your Convex database and will be accessible from the client. * * If you're using code generation, use the `query` function in * `convex/_generated/server.d.ts` which is typed for your data model. * * @param func - The query function. It receives a {@link QueryCtx} as its first argument. * @returns The wrapped query. Include this as an `export` to name it and make it accessible. * * @public */ export declare const queryGeneric: <DataModel extends GenericDataModel, Args extends any[], Output>(func: (ctx: QueryCtx<DataModel>, ...args: Args) => Output) => PublicQuery<DataModel, Args, Output>; /** * The {@link QueryInitializer} interface is the entry point for building a {@link Query} * over a Convex database table. * * There are two types of queries: * 1. Full table scans: Queries created with {@link QueryInitializer.fullTableScan} which * iterate over all of the documents in the table in insertion order. * 2. Indexed Queries: Queries created with {@link QueryInitializer.withIndex} which iterate * over an index range in index order. * * For convenience, {@link QueryInitializer} extends the {@link Query} interface, implicitly * starting a full table scan. * * @public */ export declare interface QueryInitializer<TableInfo extends GenericTableInfo> extends Query<TableInfo> { /** * Query by reading all of the values out of this table. * * This query's cost is relative to the size of the entire table, so this * should only be used on tables that will stay very small (say between a few * hundred and a few thousand documents) and are updated infrequently. * * @returns - The {@link Query} that iterates over every document of the table. */ fullTableScan(): Query<TableInfo>; /** * Query by reading documents from an index on this table. * * This query's cost is relative to the number of documents that match the * index range expression. * * Results will be returned in index order. * * To learn about indexes, see [Indexes](https://docs.convex.dev/using/indexes). * * @param indexName - The name of the index to query. * @param indexRange - An index range constructed with the supplied * {@link IndexRangeBuilder}. An index range is a description of which * documents Convex should consider when running the query. * @returns - The query that searches for documents in an index. */ withIndex<IndexName extends IndexNames<TableInfo>>(indexName: IndexName, indexRange: (q: IndexRangeBuilder<DocumentByInfo<TableInfo>, NamedIndex<TableInfo, IndexName>>) => IndexRange): Query<TableInfo>; /** * The number of documents in the table. * * @internal */ count(): Promise<number>; } /** * Helper types for interacting with the overall API type */ /** * The names of query functions in a Convex API. * * @public */ declare type QueryNames<API extends GenericAPI> = keyof API["queries"] & string; /** * The fields that Convex automatically adds to documents, not including `_id`. * * This is an object type mapping field name to field type. * @public */ declare type SystemFields = { _creationTime: number; }; /** * A type of all of the table names defined in a {@link GenericDataModel}. * @public */ export declare type TableNamesInDataModel<DataModel extends GenericDataModel> = keyof DataModel & string; /** * Builder to define the upper bound of an index range. * * See {@link IndexRangeBuilder}. * * @public */ declare interface UpperBoundIndexRangeBuilder<Document extends GenericDocument, IndexFieldName extends string> extends IndexRange { /** * Restrict this range to documents where `doc[fieldName] < value`. * * @param fieldName - The name of the field to compare. Must be the same index * field used in the lower bound (`.gt` or `.gte`) or the next field if no * lower bound was specified. * @param value - The value to compare against. */ lt(fieldName: IndexFieldName, value: FieldTypeFromFieldPath<Document, IndexFieldName>): IndexRange; /** * Restrict this range to documents where `doc[fieldName] <= value`. * * @param fieldName - The name of the field to compare. Must be the same index * field used in the lower bound (`.gt` or `.gte`) or the next field if no * lower bound was specified. * @param value - The value to compare against. */ lte(fieldName: IndexFieldName, value: FieldTypeFromFieldPath<Document, IndexFieldName>): IndexRange; } /** * Information about an authenticated user. * * The only fields guaranteed to be present are * {@link UserIdentity.tokenIdentifier} and {@link UserIdentity.issuer}. All * remaining fields may or may not be present depending on the information given * by the identity provider. * * See the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) * for more information on these fields. * * @public */ export declare interface UserIdentity { /** * A stable and globally unique string for this identity (i.e. no other * user, even from a different identity provider, will have the same string.) */ readonly tokenIdentifier: string; /** * The hostname of the identity provider used to authenticate this user. */ readonly issuer: string; readonly name?: string; readonly givenName?: string; readonly familyName?: string; readonly nickname?: string; readonly preferredUsername?: string; readonly profileUrl?: string; readonly pictureUrl?: string; readonly email?: string; readonly emailVerified?: boolean; readonly gender?: string; readonly birthday?: string; readonly timezone?: string; readonly language?: string; readonly phoneNumber?: string; readonly phoneNumberVerified?: boolean; readonly address?: string; readonly updatedAt?: Date; } /** * A value supported by Convex. * * Values can be: * - stored inside of documents. * - used as arguments and return types to queries and mutation functions. * * You can see the full set of supported types at * [Types](https://docs.convex.dev/using/types). * * @public */ declare type Value = GenericId<string> | null | bigint | number | boolean | string | ArrayBuffer | Value[] | Set<Value> | Map<Value, Value> | { [key: string]: Value; }; /** * A Convex document with the system fields like `_id` and `_creationTime` optional. * * @public */ declare type WithOptionalSystemFields<Document extends GenericDocument> = Expand<WithoutSystemFields<Document> & Partial<Pick<Document, keyof SystemFields | "_id">>>; /** * A Convex document with the system fields like `_id` and `_creationTime` omitted. * * @public */ export declare type WithoutSystemFields<Document extends GenericDocument> = Expand<DistributiveOmit<Document, keyof SystemFields | "_id">>; export { }