import type { BSONRegExp, BSONType } from "bson"; export type Document = { [key: string]: any; }; export type WithId = { id: string; } & TSchema; export type Filter = { [P in keyof TSchema]?: Condition; } & RootFilterOperators & Record; export type UpdateFilter = { $inc?: OnlyFieldsOfType; $set?: MatchKeysAndValues | MatchKeysToFunctionValues | Record; $unset?: OnlyFieldsOfType; $pull?: PullOperator; $push?: PushOperator; }; type RootFilterOperators = { $and?: Filter[]; $nor?: Filter[]; $or?: Filter[]; $text?: { $search: string; $language?: string; $caseSensitive?: boolean; $diacriticSensitive?: boolean; }; $where?: string | ((this: TSchema) => boolean); $comment?: string | Document; }; type Condition = AlternativeType | FilterOperators>; type AlternativeType = T extends ReadonlyArray ? T | RegExpOrString : RegExpOrString; type RegExpOrString = T extends string ? BSONRegExp | RegExp | T : T; type FilterOperators = { $eq?: TValue; $gt?: TValue; $gte?: TValue; $in?: ReadonlyArray; $lt?: TValue; $lte?: TValue; $ne?: TValue; $nin?: ReadonlyArray; $not?: TValue extends string ? FilterOperators | RegExp : FilterOperators; /** * When `true`, `$exists` matches the documents that contain the field, * including documents where the field value is null. */ $exists?: boolean; $type?: BSONType | BSONTypeAlias; $expr?: Record; $jsonSchema?: Record; $mod?: TValue extends number ? [number, number] : never; $regex?: TValue extends string ? RegExp | string : never; $options?: TValue extends string ? string : never; $geoIntersects?: { $geometry: Document; }; $geoWithin?: Document; $near?: Document; $nearSphere?: Document; $maxDistance?: number; $all?: ReadonlyArray; $elemMatch?: Document; $size?: TValue extends ReadonlyArray ? number : never; $bitsAllClear?: BitwiseFilter; $bitsAllSet?: BitwiseFilter; $bitsAnyClear?: BitwiseFilter; $bitsAnySet?: BitwiseFilter; $rand?: Record; }; type BSONTypeAlias = keyof typeof BSONType; type BitwiseFilter = number | ReadonlyArray; type OnlyFieldsOfType = IsAny< TSchema[keyof TSchema], Record, AcceptedFields & NotAcceptedFields & Record >; type MatchKeysAndValues = Readonly>; type MatchKeysToFunctionValues = { readonly [key in keyof TSchema]?: (this: TSchema, value: TSchema[key]) => TSchema[key]; }; type PullOperator = ({ readonly [key in KeysOfAType>]?: | Partial> | FilterOperations>; } & NotAcceptedFields>) & { readonly [key: string]: FilterOperators | any; }; type PushOperator = ({ readonly [key in KeysOfAType>]?: | Flatten | ArrayOperator>>; } & NotAcceptedFields>) & { readonly [key: string]: ArrayOperator | any; }; type KeysOfAType = { [key in keyof TSchema]: NonNullable extends Type ? key : never; }[keyof TSchema]; type AcceptedFields = { readonly [key in KeysOfAType]?: AssignableType; }; type NotAcceptedFields = { readonly [key in KeysOfOtherType]?: never; }; type Flatten = Type extends ReadonlyArray ? Item : Type; type IsAny = true extends false & Type ? ResultIfAny : ResultIfNotAny; type FilterOperations = T extends Record ? { [key in keyof T]?: FilterOperators; } : FilterOperators; type ArrayOperator = { $each?: Array>; $slice?: number; $position?: number; $sort?: Sort; }; type Sort = | string | Exclude< SortDirection, { $meta: string; } > | string[] | { [key: string]: SortDirection; } | Map | [string, SortDirection][] | [string, SortDirection]; type SortDirection = | 1 | -1 | "asc" | "desc" | "ascending" | "descending" | { $meta: string; }; type KeysOfOtherType = { [key in keyof TSchema]: NonNullable extends Type ? never : key; }[keyof TSchema];