1 | import {
|
2 | Schema,
|
3 | InferSchemaType,
|
4 | SchemaType,
|
5 | SchemaTypeOptions,
|
6 | TypeKeyBaseType,
|
7 | Types,
|
8 | NumberSchemaDefinition,
|
9 | StringSchemaDefinition,
|
10 | BooleanSchemaDefinition,
|
11 | DateSchemaDefinition,
|
12 | ObtainDocumentType,
|
13 | DefaultTypeKey,
|
14 | ObjectIdSchemaDefinition,
|
15 | IfEquals,
|
16 | DefaultSchemaOptions,
|
17 | IsItRecordAndNotAny
|
18 | } from 'mongoose';
|
19 |
|
20 | declare module 'mongoose' {
|
21 | |
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | type ObtainDocumentType<
|
29 | DocDefinition,
|
30 | EnforcedDocType = any,
|
31 | TSchemaOptions extends Record<any, any> = DefaultSchemaOptions
|
32 | > = IsItRecordAndNotAny<EnforcedDocType> extends true ?
|
33 | EnforcedDocType :
|
34 | {
|
35 | [
|
36 | K in keyof (RequiredPaths<DocDefinition, TSchemaOptions['typeKey']> &
|
37 | OptionalPaths<DocDefinition, TSchemaOptions['typeKey']>)
|
38 | ]: IsPathRequired<DocDefinition[K], TSchemaOptions['typeKey']> extends true ?
|
39 | ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']> :
|
40 | ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']> | null;
|
41 | };
|
42 |
|
43 | |
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | export type InferSchemaType<TSchema> = IfAny<TSchema, any, ObtainSchemaGeneric<TSchema, 'DocType'>>;
|
53 |
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 | type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TSchemaOptions' | 'DocType'> =
|
60 | TSchema extends Schema<infer EnforcedDocType, infer M, infer TInstanceMethods, infer TQueryHelpers, infer TVirtuals, infer TStaticMethods, infer TSchemaOptions, infer DocType>
|
61 | ? {
|
62 | EnforcedDocType: EnforcedDocType;
|
63 | M: M;
|
64 | TInstanceMethods: TInstanceMethods;
|
65 | TQueryHelpers: TQueryHelpers;
|
66 | TVirtuals: TVirtuals;
|
67 | TStaticMethods: TStaticMethods;
|
68 | TSchemaOptions: TSchemaOptions;
|
69 | DocType: DocType;
|
70 | }[alias]
|
71 | : unknown;
|
72 |
|
73 | type ResolveSchemaOptions<T> = MergeType<DefaultSchemaOptions, T>;
|
74 |
|
75 | type ApplySchemaOptions<T, O = DefaultSchemaOptions> = ResolveTimestamps<T, O>;
|
76 |
|
77 | type ResolveTimestamps<T, O> = O extends { methods: any } | { statics: any } | { virtuals: any } | { timestamps?: false } ? T
|
78 |
|
79 |
|
80 |
|
81 | : O extends { timestamps: infer TimestampOptions } ? TimestampOptions extends true
|
82 | ? { createdAt: NativeDate; updatedAt: NativeDate; } & T
|
83 | : TimestampOptions extends SchemaTimestampsConfig
|
84 | ? {
|
85 | -readonly [K in keyof Pick<
|
86 | TimestampOptions,
|
87 | 'createdAt' | 'updatedAt'
|
88 | > as TimestampOptions[K] extends true
|
89 | ? K
|
90 | : TimestampOptions[K] extends string
|
91 | ? TimestampOptions[K]
|
92 | : never]: NativeDate;
|
93 | } & T
|
94 | : T
|
95 | : T;
|
96 | }
|
97 |
|
98 | type IsPathDefaultUndefined<PathType> = PathType extends { default: undefined } ?
|
99 | true :
|
100 | PathType extends { default: (...args: any[]) => undefined } ?
|
101 | true :
|
102 | false;
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 | type IsPathRequired<P, TypeKey extends string = DefaultTypeKey> =
|
110 | P extends { required: true | [true, string | undefined] | { isRequired: true } } | ArrayConstructor | any[]
|
111 | ? true
|
112 | : P extends { required: boolean }
|
113 | ? P extends { required: false }
|
114 | ? false
|
115 | : true
|
116 | : P extends (Record<TypeKey, ArrayConstructor | any[]>)
|
117 | ? IsPathDefaultUndefined<P> extends true
|
118 | ? false
|
119 | : true
|
120 | : P extends (Record<TypeKey, any>)
|
121 | ? P extends { default: any }
|
122 | ? IfEquals<P['default'], undefined, false, true>
|
123 | : false
|
124 | : false;
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | type PathWithTypePropertyBaseType<TypeKey extends string = DefaultTypeKey> = { [k in TypeKey]: any };
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | type RequiredPathKeys<T, TypeKey extends string = DefaultTypeKey> = {
|
140 | [K in keyof T]: IsPathRequired<T[K], TypeKey> extends true ? IfEquals<T[K], any, never, K> : never;
|
141 | }[keyof T];
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | type RequiredPaths<T, TypeKey extends string = DefaultTypeKey> = {
|
150 | [K in RequiredPathKeys<T, TypeKey>]: T[K];
|
151 | };
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 | type OptionalPathKeys<T, TypeKey extends string = DefaultTypeKey> = {
|
160 | [K in keyof T]: IsPathRequired<T[K], TypeKey> extends true ? never : K;
|
161 | }[keyof T];
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | type OptionalPaths<T, TypeKey extends string = DefaultTypeKey> = {
|
170 | [K in OptionalPathKeys<T, TypeKey>]?: T[K];
|
171 | };
|
172 |
|
173 |
|
174 |
|
175 |
|
176 | type TypeHint<T> = T extends { __typehint: infer U } ? U: never;
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 | type ObtainDocumentPathType<PathValueType, TypeKey extends string = DefaultTypeKey> = ResolvePathType<
|
186 | PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? PathValueType[TypeKey] : PathValueType,
|
187 | PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? Omit<PathValueType, TypeKey> : {},
|
188 | TypeKey,
|
189 | TypeHint<PathValueType>
|
190 | >;
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 | type PathEnumOrString<T extends SchemaTypeOptions<string>['enum']> = T extends ReadonlyArray<infer E> ? E : T extends { values: any } ? PathEnumOrString<T['values']> : string;
|
197 |
|
198 | type IsSchemaTypeFromBuiltinClass<T> = T extends (typeof String)
|
199 | ? true
|
200 | : T extends (typeof Number)
|
201 | ? true
|
202 | : T extends (typeof Boolean)
|
203 | ? true
|
204 | : T extends (typeof Buffer)
|
205 | ? true
|
206 | : T extends (typeof Schema.Types.ObjectId)
|
207 | ? true
|
208 | : T extends (typeof Schema.Types.UUID)
|
209 | ? true
|
210 | : T extends (typeof Schema.Types.Decimal128)
|
211 | ? true
|
212 | : T extends (typeof Schema.Types.String)
|
213 | ? true
|
214 | : T extends (typeof Schema.Types.Number)
|
215 | ? true
|
216 | : T extends (typeof Schema.Types.Date)
|
217 | ? true
|
218 | : T extends (typeof Schema.Types.Boolean)
|
219 | ? true
|
220 | : T extends (typeof Schema.Types.Buffer)
|
221 | ? true
|
222 | : T extends Types.ObjectId
|
223 | ? true
|
224 | : T extends Types.Decimal128
|
225 | ? true
|
226 | : T extends Buffer
|
227 | ? true
|
228 | : T extends NativeDate
|
229 | ? true
|
230 | : T extends (typeof Schema.Types.Mixed)
|
231 | ? true
|
232 | : IfEquals<T, Schema.Types.ObjectId, true, false>;
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 | type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueType> = {}, TypeKey extends string = DefaultSchemaOptions['typeKey'], TypeHint = never> =
|
242 | IfEquals<TypeHint, never,
|
243 | PathValueType extends Schema ? InferSchemaType<PathValueType> :
|
244 | PathValueType extends (infer Item)[] ?
|
245 | IfEquals<Item, never, any[], Item extends Schema ?
|
246 |
|
247 | Types.DocumentArray<InferSchemaType<Item>> :
|
248 | Item extends Record<TypeKey, any> ?
|
249 | Item[TypeKey] extends Function | String ?
|
250 |
|
251 |
|
252 | ObtainDocumentPathType<Item, TypeKey>[] :
|
253 |
|
254 |
|
255 | Types.DocumentArray<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
|
256 | IsSchemaTypeFromBuiltinClass<Item> extends true ?
|
257 | ObtainDocumentPathType<Item, TypeKey>[] :
|
258 | IsItRecordAndNotAny<Item> extends true ?
|
259 | Item extends Record<string, never> ?
|
260 | ObtainDocumentPathType<Item, TypeKey>[] :
|
261 | Types.DocumentArray<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
|
262 | ObtainDocumentPathType<Item, TypeKey>[]
|
263 | >:
|
264 | PathValueType extends ReadonlyArray<infer Item> ?
|
265 | IfEquals<Item, never, any[], Item extends Schema ?
|
266 | Types.DocumentArray<InferSchemaType<Item>> :
|
267 | Item extends Record<TypeKey, any> ?
|
268 | Item[TypeKey] extends Function | String ?
|
269 | ObtainDocumentPathType<Item, TypeKey>[] :
|
270 | ObtainDocumentType<Item, any, { typeKey: TypeKey }>[]:
|
271 | IsSchemaTypeFromBuiltinClass<Item> extends true ?
|
272 | ObtainDocumentPathType<Item, TypeKey>[] :
|
273 | IsItRecordAndNotAny<Item> extends true ?
|
274 | Item extends Record<string, never> ?
|
275 | ObtainDocumentPathType<Item, TypeKey>[] :
|
276 | Types.DocumentArray<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
|
277 | ObtainDocumentPathType<Item, TypeKey>[]
|
278 | >:
|
279 | PathValueType extends StringSchemaDefinition ? PathEnumOrString<Options['enum']> :
|
280 | IfEquals<PathValueType, Schema.Types.String> extends true ? PathEnumOrString<Options['enum']> :
|
281 | IfEquals<PathValueType, String> extends true ? PathEnumOrString<Options['enum']> :
|
282 | PathValueType extends NumberSchemaDefinition ? Options['enum'] extends ReadonlyArray<any> ? Options['enum'][number] : number :
|
283 | IfEquals<PathValueType, Schema.Types.Number> extends true ? number :
|
284 | PathValueType extends DateSchemaDefinition ? Date :
|
285 | IfEquals<PathValueType, Schema.Types.Date> extends true ? Date :
|
286 | PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
|
287 | PathValueType extends BooleanSchemaDefinition ? boolean :
|
288 | IfEquals<PathValueType, Schema.Types.Boolean> extends true ? boolean :
|
289 | PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId :
|
290 | IfEquals<PathValueType, Types.ObjectId> extends true ? Types.ObjectId :
|
291 | IfEquals<PathValueType, Schema.Types.ObjectId> extends true ? Types.ObjectId :
|
292 | PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 :
|
293 | IfEquals<PathValueType, Schema.Types.Decimal128> extends true ? Types.Decimal128 :
|
294 | IfEquals<PathValueType, Types.Decimal128> extends true ? Types.Decimal128 :
|
295 | IfEquals<PathValueType, Schema.Types.BigInt> extends true ? bigint :
|
296 | IfEquals<PathValueType, BigInt> extends true ? bigint :
|
297 | PathValueType extends 'bigint' | 'BigInt' | typeof Schema.Types.BigInt | typeof BigInt ? bigint :
|
298 | PathValueType extends 'uuid' | 'UUID' | typeof Schema.Types.UUID ? Buffer :
|
299 | IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
|
300 | PathValueType extends MapConstructor | 'Map' ? Map<string, ResolvePathType<Options['of']>> :
|
301 | IfEquals<PathValueType, typeof Schema.Types.Map> extends true ? Map<string, ResolvePathType<Options['of']>> :
|
302 | PathValueType extends ArrayConstructor ? any[] :
|
303 | PathValueType extends typeof Schema.Types.Mixed ? any:
|
304 | IfEquals<PathValueType, ObjectConstructor> extends true ? any:
|
305 | IfEquals<PathValueType, {}> extends true ? any:
|
306 | PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
|
307 | PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, { typeKey: TypeKey }> :
|
308 | unknown,
|
309 | TypeHint>;
|