import { Schema, InferSchemaType, SchemaType, SchemaTypeOptions, TypeKeyBaseType, Types, NumberSchemaDefinition, StringSchemaDefinition, BooleanSchemaDefinition, DateSchemaDefinition, ObtainDocumentType, DefaultTypeKey, ObjectIdSchemaDefinition, IfEquals, DefaultSchemaOptions, IsItRecordAndNotAny } from 'mongoose'; declare module 'mongoose' { /** * @summary Obtains document schema type. * @description Obtains document schema type from document Definition OR returns enforced schema type if it's provided. * @param {DocDefinition} DocDefinition A generic equals to the type of document definition "provided in as first parameter in Schema constructor". * @param {EnforcedDocType} EnforcedDocType A generic type enforced by user "provided before schema constructor". * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". */ type ObtainDocumentType< DocDefinition, EnforcedDocType = any, TSchemaOptions extends Record = DefaultSchemaOptions > = IsItRecordAndNotAny extends true ? EnforcedDocType : { [ K in keyof (RequiredPaths & OptionalPaths) ]: IsPathRequired extends true ? ObtainDocumentPathType : ObtainDocumentPathType | null; }; /** * @summary Obtains document schema type from Schema instance. * @param {Schema} TSchema `typeof` a schema instance. * @example * const userSchema = new Schema({userName:String}); * type UserType = InferSchemaType; * // result * type UserType = {userName?: string} */ export type InferSchemaType = IfAny>; /** * @summary Obtains schema Generic type by using generic alias. * @param {TSchema} TSchema A generic of schema type instance. * @param {alias} alias Targeted generic alias. */ type ObtainSchemaGeneric = TSchema extends Schema ? { EnforcedDocType: EnforcedDocType; M: M; TInstanceMethods: TInstanceMethods; TQueryHelpers: TQueryHelpers; TVirtuals: TVirtuals; TStaticMethods: TStaticMethods; TSchemaOptions: TSchemaOptions; DocType: DocType; }[alias] : unknown; type ResolveSchemaOptions = MergeType; type ApplySchemaOptions = ResolveTimestamps; type ResolveTimestamps = O extends { timestamps: true } // For some reason, TypeScript sets all the document properties to unknown // if we use methods, statics, or virtuals. So avoid inferring timestamps // if any of these are set for now. See gh-12807 ? O extends { methods: any } | { statics: any } | { virtuals: any } ? T : { createdAt: NativeDate; updatedAt: NativeDate; } & T : T; } type IsPathDefaultUndefined = PathType extends { default: undefined } ? true : PathType extends { default: (...args: any[]) => undefined } ? true : false; /** * @summary Checks if a document path is required or optional. * @param {P} P Document path. * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". */ type IsPathRequired = P extends { required: true | [true, string | undefined] | { isRequired: true } } | ArrayConstructor | any[] ? true : P extends { required: boolean } ? P extends { required: false } ? false : true : P extends (Record) ? IsPathDefaultUndefined

extends true ? false : true : P extends (Record) ? P extends { default: any } ? IfEquals : false : false; /** * @summary Path base type defined by using TypeKey * @description It helps to check if a path is defined by TypeKey OR not. * @param {TypeKey} TypeKey A literal string refers to path type property key. */ type PathWithTypePropertyBaseType = { [k in TypeKey]: any }; /** * @summary A Utility to obtain schema's required path keys. * @param {T} T A generic refers to document definition. * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns required paths keys of document definition. */ type RequiredPathKeys = { [K in keyof T]: IsPathRequired extends true ? IfEquals : never; }[keyof T]; /** * @summary A Utility to obtain schema's required paths. * @param {T} T A generic refers to document definition. * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns a record contains required paths with the corresponding type. */ type RequiredPaths = { [K in RequiredPathKeys]: T[K]; }; /** * @summary A Utility to obtain schema's optional path keys. * @param {T} T A generic refers to document definition. * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns optional paths keys of document definition. */ type OptionalPathKeys = { [K in keyof T]: IsPathRequired extends true ? never : K; }[keyof T]; /** * @summary A Utility to obtain schema's optional paths. * @param {T} T A generic refers to document definition. * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns a record contains optional paths with the corresponding type. */ type OptionalPaths = { [K in OptionalPathKeys]?: T[K]; }; /** * @summary Allows users to optionally choose their own type for a schema field for stronger typing. */ type TypeHint = T extends { __typehint: infer U } ? U: never; /** * @summary Obtains schema Path type. * @description Obtains Path type by separating path type from other options and calling {@link ResolvePathType} * @param {PathValueType} PathValueType Document definition path type. * @param {TypeKey} TypeKey A generic refers to document definition. */ type ObtainDocumentPathType = ResolvePathType< PathValueType extends PathWithTypePropertyBaseType ? PathValueType[TypeKey] : PathValueType, PathValueType extends PathWithTypePropertyBaseType ? Omit : {}, TypeKey, TypeHint >; /** * @param {T} T A generic refers to string path enums. * @returns Path enum values type as literal strings or string. */ type PathEnumOrString['enum']> = T extends ReadonlyArray ? E : T extends { values: any } ? PathEnumOrString : string; type IsSchemaTypeFromBuiltinClass = T extends (typeof String) ? true : T extends (typeof Number) ? true : T extends (typeof Boolean) ? true : T extends (typeof Buffer) ? true : T extends (typeof Schema.Types.ObjectId) ? true : T extends (typeof Schema.Types.UUID) ? true : T extends (typeof Schema.Types.Decimal128) ? true : T extends (typeof Schema.Types.String) ? true : T extends (typeof Schema.Types.Number) ? true : T extends (typeof Schema.Types.Date) ? true : T extends (typeof Schema.Types.Boolean) ? true : T extends (typeof Schema.Types.Buffer) ? true : T extends Types.ObjectId ? true : T extends Types.Decimal128 ? true : T extends Buffer ? true : T extends NativeDate ? true : T extends (typeof Schema.Types.Mixed) ? true : IfEquals; /** * @summary Resolve path type by returning the corresponding type. * @param {PathValueType} PathValueType Document definition path type. * @param {Options} Options Document definition path options except path type. * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns Number, "Number" or "number" will be resolved to number type. */ type ResolvePathType = {}, TypeKey extends string = DefaultSchemaOptions['typeKey'], TypeHint = never> = IfEquals : PathValueType extends (infer Item)[] ? IfEquals> : Item extends Record ? Item[TypeKey] extends Function | String ? // If Item has a type key that's a string or a callable, it must be a scalar, // so we can directly obtain its path type. ObtainDocumentPathType[] : // If the type key isn't callable, then this is an array of objects, in which case // we need to call ObtainDocumentType to correctly infer its type. Types.DocumentArray> : IsSchemaTypeFromBuiltinClass extends true ? ObtainDocumentPathType[] : IsItRecordAndNotAny extends true ? Item extends Record ? ObtainDocumentPathType[] : Types.DocumentArray> : ObtainDocumentPathType[] >: PathValueType extends ReadonlyArray ? IfEquals> : Item extends Record ? Item[TypeKey] extends Function | String ? ObtainDocumentPathType[] : ObtainDocumentType[]: IsSchemaTypeFromBuiltinClass extends true ? ObtainDocumentPathType[] : IsItRecordAndNotAny extends true ? Item extends Record ? ObtainDocumentPathType[] : Types.DocumentArray> : ObtainDocumentPathType[] >: PathValueType extends StringSchemaDefinition ? PathEnumOrString : IfEquals extends true ? PathEnumOrString : IfEquals extends true ? PathEnumOrString : PathValueType extends NumberSchemaDefinition ? Options['enum'] extends ReadonlyArray ? Options['enum'][number] : number : IfEquals extends true ? number : PathValueType extends DateSchemaDefinition ? Date : IfEquals extends true ? Date : PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer : PathValueType extends BooleanSchemaDefinition ? boolean : IfEquals extends true ? boolean : PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId : IfEquals extends true ? Types.ObjectId : IfEquals extends true ? Types.ObjectId : PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 : IfEquals extends true ? Types.Decimal128 : IfEquals extends true ? Types.Decimal128 : IfEquals extends true ? bigint : IfEquals extends true ? bigint : PathValueType extends 'bigint' | 'BigInt' | typeof Schema.Types.BigInt | typeof BigInt ? bigint : PathValueType extends 'uuid' | 'UUID' | typeof Schema.Types.UUID ? Buffer : IfEquals extends true ? Buffer : PathValueType extends MapConstructor | 'Map' ? Map> : IfEquals extends true ? Map> : PathValueType extends ArrayConstructor ? any[] : PathValueType extends typeof Schema.Types.Mixed ? any: IfEquals extends true ? any: IfEquals extends true ? any: PathValueType extends typeof SchemaType ? PathValueType['prototype'] : PathValueType extends Record ? ObtainDocumentType : unknown, TypeHint>;