convex
Version:
Client for the Convex Cloud
1,176 lines (1,115 loc) • 42.2 kB
TypeScript
/**
* 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 || b || ... || 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 { }