import type { AggregateOptions, BulkWriteOptions, BulkWriteResult, Collection, CountDocumentsOptions, DeleteOptions, DeleteResult, DistinctOptions, FindCursor, FindOneAndDeleteOptions, FindOneAndUpdateOptions, FindOptions, Flatten, InsertOneOptions, UpdateOptions, UpdateResult, WithId } from 'mongodb';
import type { BaseSchema, DocumentForInsert, ModelOptions, Projection, ProjectionType } from './utils.ts';
import type { PaprBulkWriteOperation, PaprFilter, PaprUpdateFilter } from './mongodbTypes.ts';
import type { DefaultsOption, SchemaOptions, SchemaTimestampOptions } from './schema.ts';
export interface Model<TSchema extends BaseSchema, TOptions extends SchemaOptions<TSchema>> {
    collection: Collection<TSchema>;
    defaults?: DefaultsOption<TSchema>;
    defaultOptions: {
        ignoreUndefined?: boolean;
        maxTimeMS?: number;
    };
    timestamps?: SchemaTimestampOptions;
    options?: ModelOptions;
    schema: TSchema;
    type: 'plex';
    aggregate: <TResult = TSchema>(pipeline: Record<string, unknown>[], options?: AggregateOptions) => Promise<TResult[]>;
    bulkWrite: (operations: readonly PaprBulkWriteOperation<TSchema, TOptions>[], options?: BulkWriteOptions) => Promise<BulkWriteResult | void>;
    countDocuments: (filter: PaprFilter<TSchema>, options?: CountDocumentsOptions) => Promise<number>;
    deleteMany: (filter: PaprFilter<TSchema>, options?: DeleteOptions) => Promise<DeleteResult>;
    deleteOne: (filter: PaprFilter<TSchema>, options?: DeleteOptions) => Promise<DeleteResult>;
    distinct: <TKey extends keyof WithId<TSchema>>(key: TKey, filter: PaprFilter<TSchema>, options?: DistinctOptions) => Promise<Flatten<WithId<TSchema>[TKey]>[]>;
    exists: (filter: PaprFilter<TSchema>, options?: Omit<FindOptions, 'limit' | 'projection' | 'skip' | 'sort'>) => Promise<boolean>;
    find: <TProjection extends Projection<TSchema> | undefined>(filter: PaprFilter<TSchema>, options?: Omit<FindOptions, 'projection'> & {
        projection?: TProjection;
    }) => Promise<ProjectionType<TSchema, TProjection>[]>;
    findById: <TProjection extends Projection<TSchema> | undefined>(id: TSchema['_id'] | string, options?: Omit<FindOptions, 'projection'> & {
        projection?: TProjection;
    }) => Promise<ProjectionType<TSchema, TProjection> | null>;
    findCursor: <TProjection extends Projection<TSchema> | undefined>(filter: PaprFilter<TSchema>, options?: Omit<FindOptions, 'projection'> & {
        projection?: TProjection;
    }) => Promise<FindCursor<ProjectionType<TSchema, TProjection>>>;
    findOne: <TProjection extends Projection<TSchema> | undefined>(filter: PaprFilter<TSchema>, options?: Omit<FindOptions, 'projection'> & {
        projection?: TProjection;
    }) => Promise<ProjectionType<TSchema, TProjection> | null>;
    findOneAndDelete: <TProjection extends Projection<TSchema> | undefined>(filter: PaprFilter<TSchema>, options?: Omit<FindOneAndDeleteOptions, 'projection'> & {
        projection?: TProjection;
    }) => Promise<ProjectionType<TSchema, TProjection> | null>;
    findOneAndUpdate: <TProjection extends Projection<TSchema> | undefined>(filter: PaprFilter<TSchema>, update: PaprUpdateFilter<TSchema>, options?: Omit<FindOneAndUpdateOptions, 'projection'> & {
        projection?: TProjection;
    }) => Promise<ProjectionType<TSchema, TProjection> | null>;
    insertOne: (doc: DocumentForInsert<TSchema, TOptions>, options?: InsertOneOptions) => Promise<TSchema>;
    insertMany: (docs: DocumentForInsert<TSchema, TOptions>[], options?: BulkWriteOptions) => Promise<TSchema[]>;
    updateOne: (filter: PaprFilter<TSchema>, update: PaprUpdateFilter<TSchema>, options?: Omit<UpdateOptions, 'upsert'>) => Promise<UpdateResult>;
    updateMany: (filter: PaprFilter<TSchema>, update: PaprUpdateFilter<TSchema>, options?: UpdateOptions) => Promise<UpdateResult>;
    upsert: <TProjection extends Projection<TSchema> | undefined>(filter: PaprFilter<TSchema>, update: PaprUpdateFilter<TSchema>, options?: Omit<FindOneAndUpdateOptions, 'projection' | 'upsert'> & {
        projection?: TProjection;
    }) => Promise<ProjectionType<TSchema, TProjection>>;
}
type ModelMethodsNames = NonNullable<{
    [P in keyof Model<BaseSchema, object>]: Model<BaseSchema, object>[P] extends Function ? P : never;
}[keyof Model<BaseSchema, object>]>;
export type HookMethodsNames = Exclude<ModelMethodsNames, 'upsert'>;
export declare function abstract<TSchema extends BaseSchema, TOptions extends SchemaOptions<TSchema>>(schema: [TSchema, TOptions]): unknown;
/**
 * @module intro
 * @description
 *
 * A model is the public interface in `papr` for working with a MongoDB collection.
 *
 * All the examples here are using the following schema and model:
 *
 * ```js
 * const userSchema = schema({
 *   active: types.boolean(),
 *   age: types.number(),
 *   firstName: types.string({ required: true }),
 *   lastName: types.string({ required: true }),
 * });
 * const User = papr.model('users', userSchema);
 * ```
 */
export declare function build<TSchema extends BaseSchema, TOptions extends SchemaOptions<TSchema>>(schema: [TSchema, TOptions], model: Model<TSchema, TOptions>, collection: Collection<TSchema>, options?: ModelOptions): void;
export {};
