import { GenericId } from '@convex-dev/common';
import { NumericValue } from '@convex-dev/common';
import { Value } from '@convex-dev/common';

/**
 * 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>;
}

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;
    /* Excluded from this release type: __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>>;
}

/**
 * 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;

/**
 * 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;
    /* Excluded from this release type: __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
 * `["channel", "_creationTime"]`, a range searching for "messages in `channel`
 * created 1-2 minutes ago" would look like:
 * ```ts
 * q.eq("channel", channelId)
 *   .gt("_creationTime", Date.now() - 2 * 60000)
 *   .lt("_creationTime", Date.now() - 60000)
 * ```
 *
 * **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]>): IndexRangeBuilder<Document, IndexFields, PlusOne<FieldNum>>;
}

/**
 * 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>;

/**
 * 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];

/**
 * 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];

/**
 * 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>;
    /* Excluded from this release type: limit */
    /* Excluded from this release type: paginate */
    /**
     * 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.
     *
     * @returns - The single result returned from the query.
     * @throws  Will throw an error if the query returns no results or more than
     * one result.
     */
    unique(): Promise<DocumentByInfo<TableInfo>>;
}

/* Excluded from this release type: PaginationOptions */

/* Excluded from this release type: PaginationResult */

/**
 * 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];

/**
 * 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;
    /* Excluded from this release type: invokeMutation */
};

/**
 * 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;
    /* Excluded from this release type: invokeQuery */
};

/**
 * 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 are no results or 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>;
    /* Excluded from this release type: count */
}

/**
 * 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 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 { }
