@depup/mongoose 9.3.3-depup.0 → 9.8.0-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +3 -9
  2. package/changes.json +3 -8
  3. package/eslint.config.mjs +4 -1
  4. package/lib/aggregate.js +54 -24
  5. package/lib/cast.js +1 -1
  6. package/lib/connection.js +20 -8
  7. package/lib/cursor/aggregationCursor.js +47 -16
  8. package/lib/cursor/queryCursor.js +23 -7
  9. package/lib/document.js +240 -105
  10. package/lib/drivers/node-mongodb-native/collection.js +47 -14
  11. package/lib/drivers/node-mongodb-native/connection.js +13 -0
  12. package/lib/error/cast.js +18 -9
  13. package/lib/error/divergentArray.js +1 -1
  14. package/lib/error/index.js +1 -1
  15. package/lib/error/messages.js +1 -0
  16. package/lib/helpers/clone.js +22 -5
  17. package/lib/helpers/document/applyDefaults.js +5 -0
  18. package/lib/helpers/populate/createPopulateQueryFilter.js +9 -1
  19. package/lib/helpers/populate/getModelsMapForPopulate.js +8 -6
  20. package/lib/helpers/populate/splitPopulateQuery.js +81 -0
  21. package/lib/helpers/query/castUpdate.js +4 -0
  22. package/lib/helpers/schema/getKeysInSchemaOrder.js +13 -16
  23. package/lib/helpers/update/applyTimestampsToUpdate.js +4 -2
  24. package/lib/model.js +159 -41
  25. package/lib/mongoose.js +3 -3
  26. package/lib/options/schemaTypeOptions.js +14 -0
  27. package/lib/plugins/saveSubdocs.js +16 -13
  28. package/lib/query.js +208 -102
  29. package/lib/queryHelpers.js +13 -12
  30. package/lib/schema/array.js +4 -6
  31. package/lib/schema/bigint.js +1 -3
  32. package/lib/schema/boolean.js +1 -3
  33. package/lib/schema/buffer.js +1 -3
  34. package/lib/schema/date.js +8 -8
  35. package/lib/schema/decimal128.js +1 -3
  36. package/lib/schema/documentArray.js +3 -5
  37. package/lib/schema/double.js +1 -3
  38. package/lib/schema/int32.js +1 -3
  39. package/lib/schema/map.js +1 -4
  40. package/lib/schema/number.js +2 -4
  41. package/lib/schema/objectId.js +7 -3
  42. package/lib/schema/string.js +20 -5
  43. package/lib/schema/subdocument.js +2 -4
  44. package/lib/schema/union.js +50 -0
  45. package/lib/schema/uuid.js +1 -3
  46. package/lib/schema.js +40 -14
  47. package/lib/schemaType.js +93 -12
  48. package/lib/standardSchema/convertErrorToIssues.js +20 -0
  49. package/lib/stateMachine.js +11 -6
  50. package/lib/tracing.js +38 -0
  51. package/lib/types/array/methods/index.js +4 -4
  52. package/lib/types/documentArray/methods/index.js +117 -3
  53. package/lib/types/subdocument.js +4 -2
  54. package/lib/utils.js +12 -2
  55. package/lib/validOptions.js +1 -0
  56. package/package.json +30 -33
  57. package/{tstyche.config.json → tstyche.json} +2 -1
  58. package/types/augmentations.d.ts +2 -2
  59. package/types/document.d.ts +61 -7
  60. package/types/expressions.d.ts +16 -0
  61. package/types/index.d.ts +25 -7
  62. package/types/inferhydrateddoctype.d.ts +1 -1
  63. package/types/inferrawdoctype.d.ts +6 -3
  64. package/types/inferschematype.d.ts +10 -2
  65. package/types/models.d.ts +30 -13
  66. package/types/mongooseoptions.d.ts +9 -1
  67. package/types/populate.d.ts +52 -0
  68. package/types/query.d.ts +39 -12
  69. package/types/schemaoptions.d.ts +5 -0
  70. package/types/schematypes.d.ts +10 -0
  71. package/types/tracing.d.ts +10 -0
  72. package/types/utility.d.ts +11 -2
  73. package/lib/helpers/createJSONSchemaTypeDefinition.js +0 -24
@@ -8,6 +8,50 @@ declare module 'mongoose' {
8
8
  RawId extends RefType = (PopulatedType extends { _id?: RefType; } ? NonNullable<PopulatedType['_id']> : Types.ObjectId) | undefined
9
9
  > = PopulatedType | RawId;
10
10
 
11
+ const mongoosePopulatedDocumentMarker: unique symbol;
12
+
13
+ type ExtractDocumentObjectType<T> = T extends infer ObjectType & Document ? FlatRecord<ObjectType> : T;
14
+
15
+ type PopulatePathToRawDocType<T> =
16
+ T extends Types.DocumentArray<any, infer ItemType>
17
+ ? PopulatePathToRawDocType<ItemType>[]
18
+ : T extends Array<infer ItemType>
19
+ ? PopulatePathToRawDocType<ItemType>[]
20
+ : T extends Document
21
+ ? SubdocsToPOJOs<ExtractDocumentObjectType<T>>
22
+ : T extends Record<string, any>
23
+ ? { [K in keyof T]: PopulatePathToRawDocType<T[K]> }
24
+ : T;
25
+
26
+ type PopulatedPathsDocumentType<RawDocType, Paths> = UnpackedIntersection<RawDocType, PopulatePathToRawDocType<Paths>>;
27
+
28
+ type PopulatedDocumentMarker<
29
+ PopulatedRawDocType,
30
+ DepopulatedRawDocType,
31
+ > = {
32
+ [mongoosePopulatedDocumentMarker]?: {
33
+ populated: PopulatedRawDocType,
34
+ depopulated: DepopulatedRawDocType
35
+ }
36
+ };
37
+
38
+ type ResolvePopulatedRawDocType<
39
+ ThisType,
40
+ FallbackRawDocType,
41
+ O = never
42
+ > = ThisType extends PopulatedDocumentMarker<infer PopulatedRawDocType, infer DepopulatedRawDocType>
43
+ ? O extends { depopulate: true }
44
+ ? DepopulatedRawDocType
45
+ : PopulatedRawDocType
46
+ : FallbackRawDocType;
47
+
48
+ type PopulateDocumentResult<
49
+ Doc,
50
+ Paths,
51
+ PopulatedRawDocType,
52
+ DepopulatedRawDocType = PopulatedRawDocType
53
+ > = MergeType<Doc, Paths> & PopulatedDocumentMarker<PopulatedRawDocType, DepopulatedRawDocType>;
54
+
11
55
  interface PopulateOptions {
12
56
  /** space delimited path(s) to populate */
13
57
  path: string;
@@ -17,6 +61,14 @@ declare module 'mongoose' {
17
61
  match?: any;
18
62
  /** optional model to use for population */
19
63
  model?: string | Model<any>;
64
+ /** by default, Mongoose removes null and undefined values from populated arrays. Use this option to make `populate()` retain `null` and `undefined` array entries. */
65
+ retainNullValues?: boolean;
66
+ /** if true, Mongoose will call any getters defined on the `localField`. By default, Mongoose gets the raw value of `localField`. */
67
+ getters?: boolean;
68
+ /** if true, Mongoose will clone populated docs before assigning them, so docs that are populated onto multiple parents don't share 1 copy. */
69
+ clone?: boolean;
70
+ /** By default, Mongoose throws a cast error if `localField` and `foreignField` schemas don't line up. If you enable this option, Mongoose will instead filter out any `localField` properties that cannot be casted to `foreignField`'s schema type. */
71
+ skipInvalidIds?: boolean;
20
72
  /** optional query options like sort, limit, etc */
21
73
  options?: QueryOptions;
22
74
  /** correct limit on populated array */
package/types/query.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  declare module 'mongoose' {
2
2
  import mongodb = require('mongodb');
3
3
 
4
- type StringQueryTypeCasting = string | RegExp;
4
+ type StringQueryTypeCasting<T> = string extends T ? string | RegExp : T | RegExp;
5
5
  type ObjectIdQueryTypeCasting = Types.ObjectId | string;
6
6
  type DateQueryTypeCasting = string | number | NativeDate;
7
7
  type UUIDQueryTypeCasting = Types.UUID | string;
8
8
  type BufferQueryCasting = Buffer | mongodb.Binary | number[] | string | { $binary: string | mongodb.Binary };
9
9
  type QueryTypeCasting<T> = T extends string
10
- ? StringQueryTypeCasting
10
+ ? StringQueryTypeCasting<T>
11
11
  : T extends Types.ObjectId
12
12
  ? ObjectIdQueryTypeCasting
13
13
  : T extends Types.UUID
@@ -18,22 +18,40 @@ declare module 'mongoose' {
18
18
  ? DateQueryTypeCasting
19
19
  : T;
20
20
 
21
- export type ApplyBasicQueryCasting<T> = QueryTypeCasting<T> | QueryTypeCasting<T[]> | (T extends (infer U)[] ? QueryTypeCasting<U> : T) | null;
21
+ export type ApplyBasicQueryCasting<T> = QueryTypeCasting<T> | QueryTypeCasting<T>[] | (T extends (infer U)[] ? QueryTypeCasting<U> : T) | null;
22
+
23
+ type RemoveIndexSignature<T> = {
24
+ [K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K];
25
+ };
26
+
27
+ type StrictFilterOperators<TValue> = RemoveIndexSignature<mongodb.FilterOperators<TValue>>;
28
+
29
+ type StrictCondition<T> = mongodb.AlternativeType<T> | StrictFilterOperators<mongodb.AlternativeType<T>>;
30
+
31
+ type _StrictFilter<TSchema> = {
32
+ [P in keyof TSchema]?: StrictCondition<ApplyBasicQueryCasting<TSchema[P]>>;
33
+ } & StrictRootFilterOperators<TSchema>;
34
+
35
+ type StrictRootFilterOperators<TSchema> = Omit<mongodb.RootFilterOperators<TSchema>, '$and' | '$or' | '$nor'> & {
36
+ $and?: _StrictFilter<TSchema>[];
37
+ $or?: _StrictFilter<TSchema>[];
38
+ $nor?: _StrictFilter<TSchema>[];
39
+ };
22
40
 
23
41
  type _QueryFilter<T> = (
24
- { [P in keyof T]?: mongodb.Condition<ApplyBasicQueryCasting<T[P]>>; } &
25
- mongodb.RootFilterOperators<{ [P in keyof mongodb.WithId<T>]?: ApplyBasicQueryCasting<mongodb.WithId<T>[P]>; }>
42
+ { [P in keyof T]?: StrictCondition<ApplyBasicQueryCasting<T[P]>>; } &
43
+ StrictRootFilterOperators<{ [P in keyof mongodb.WithId<T>]?: ApplyBasicQueryCasting<mongodb.WithId<T>[P]>; }>
26
44
  );
27
45
  type _QueryFilterLooseId<T> = (
28
- { [P in keyof T]?: mongodb.Condition<ApplyBasicQueryCasting<T[P]>>; } &
29
- mongodb.RootFilterOperators<
30
- { [P in keyof T]?: ApplyBasicQueryCasting<T[P]>; } &
31
- { _id?: any; }
46
+ { [P in keyof T]?: StrictCondition<ApplyBasicQueryCasting<T[P]>>; } &
47
+ StrictRootFilterOperators<
48
+ { [P in keyof T]?: ApplyBasicQueryCasting<T[P]>; }
32
49
  >
33
50
  );
34
51
  type QueryFilter<T> = IsItRecordAndNotAny<T> extends true ? _QueryFilter<WithLevel1NestedPaths<T>> : _QueryFilterLooseId<Record<string, any>>;
35
52
 
36
53
  type MongooseBaseQueryOptionKeys =
54
+ | 'cloneUpdate'
37
55
  | 'context'
38
56
  | 'middleware'
39
57
  | 'multipleCastError'
@@ -91,6 +109,10 @@ declare module 'mongoose' {
91
109
  collation?: mongodb.CollationOptions;
92
110
  comment?: any;
93
111
  context?: string;
112
+ /**
113
+ * If `false`, Mongoose will not clone the update before executing the query.
114
+ */
115
+ cloneUpdate?: boolean;
94
116
  explain?: mongodb.ExplainVerbosityLike;
95
117
  fields?: any | string;
96
118
  hint?: mongodb.Hint;
@@ -112,6 +134,11 @@ declare module 'mongoose' {
112
134
  */
113
135
  new?: boolean;
114
136
 
137
+ /**
138
+ * If `false`, skip applying default schema values to the returned document(s).
139
+ * @default true
140
+ */
141
+ defaults?: boolean;
115
142
  overwriteDiscriminatorKey?: boolean;
116
143
  /**
117
144
  * Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert).
@@ -201,10 +228,10 @@ declare module 'mongoose' {
201
228
  ? ResultType
202
229
  : ResultType extends (infer U)[]
203
230
  ? U extends Document
204
- ? HydratedDocument<MergeType<RawDocType, Paths>, TDocOverrides, TQueryHelpers>[]
231
+ ? PopulateDocumentResult<U, Paths, MergeType<RawDocType, Paths>, RawDocType>[]
205
232
  : (MergeType<U, Paths>)[]
206
233
  : ResultType extends Document
207
- ? HydratedDocument<MergeType<RawDocType, Paths>, TDocOverrides, TQueryHelpers>
234
+ ? PopulateDocumentResult<ResultType, Paths, MergeType<RawDocType, Paths>, RawDocType>
208
235
  : MergeType<ResultType, Paths>
209
236
  : MergeType<ResultType, Paths>;
210
237
 
@@ -867,7 +894,7 @@ declare module 'mongoose' {
867
894
  setQuery(val: QueryFilter<RawDocType> | null): void;
868
895
  setQuery(val: Query<any, any> | null): void;
869
896
 
870
- setUpdate(update: UpdateQuery<RawDocType> | UpdateWithAggregationPipeline): void;
897
+ setUpdate(update: UpdateQuery<RawDocType> | UpdateWithAggregationPipeline, cloneUpdate?: boolean): void;
871
898
 
872
899
  /** Specifies an `$size` query condition. When called with one argument, the most recent path passed to `where()` is used. */
873
900
  size(path: string, val: number): this;
@@ -158,6 +158,11 @@ declare module 'mongoose' {
158
158
  * [strictQuery](https://mongoosejs.com/docs/guide.html#strictQuery) mode for schemas.
159
159
  */
160
160
  strictQuery?: boolean | 'throw';
161
+ /**
162
+ * May be `false`, `true`, or `'throw'`. Sets the default
163
+ * [strictRead](https://mongoosejs.com/docs/guide.html#strictRead) mode for schemas.
164
+ */
165
+ strictRead?: boolean | 'throw';
161
166
  /** Exactly the same as the toObject option but only applies when the document's toJSON method is called. */
162
167
  toJSON?: ToObjectOptions<DocType, THydratedDocumentType>;
163
168
  /**
@@ -104,6 +104,13 @@ declare module 'mongoose' {
104
104
  | [boolean, string]
105
105
  | [(this: THydratedDocumentType) => boolean, string];
106
106
 
107
+ /**
108
+ * Controls whether this path may be set to `null`. By default, Mongoose allows
109
+ * `null` for non-required paths. Set `allowNull: false` to allow `undefined`
110
+ * but disallow `null`.
111
+ */
112
+ allowNull?: boolean;
113
+
107
114
  /**
108
115
  * The default value for this path. If a function, Mongoose executes the function
109
116
  * and uses the return value as the default.
@@ -355,6 +362,9 @@ declare module 'mongoose' {
355
362
  */
356
363
  required(required: boolean, message?: string): this;
357
364
 
365
+ /** Adds or removes a validator that disallows `null` without making this path required. */
366
+ allowNull(allowNull: boolean): this;
367
+
358
368
  /** If the SchemaType is a subdocument or document array, this is the schema of that subdocument */
359
369
  schema?: Schema<any>;
360
370
 
@@ -0,0 +1,10 @@
1
+ declare module 'mongoose' {
2
+ interface TracingContext {
3
+ operation: string;
4
+ collection: string;
5
+ database: string;
6
+ serverAddress: string;
7
+ serverPort: number;
8
+ args: Record<string, any>;
9
+ }
10
+ }
@@ -98,10 +98,10 @@ declare module 'mongoose' {
98
98
  type UnpackedIntersection<T, U> = T extends null
99
99
  ? null
100
100
  : T extends (infer A)[]
101
- ? (Omit<A, keyof U> & U)[]
101
+ ? (A extends any ? (Omit<A, keyof U> & U) : never)[]
102
102
  : keyof U extends never
103
103
  ? T
104
- : Omit<T, keyof U> & U;
104
+ : T extends any ? (Omit<T, keyof U> & U) : never;
105
105
 
106
106
  type MergeType<A, B> = A extends unknown ? Omit<A, keyof B> & B : never;
107
107
 
@@ -161,6 +161,15 @@ declare module 'mongoose' {
161
161
  : T[K];
162
162
  };
163
163
 
164
+ type OmitThisParameterIfFunction<T> = T extends (...args: any[]) => any ? OmitThisParameter<T> : T;
165
+
166
+ // Strip explicit `this` parameter from methods in schema type options. The `this` parameter
167
+ // is just for type-checking the function body. Keeping the explicit 'this' typing can cause
168
+ // compiler errors on the method calls, so remove it for the hydrated document definition.
169
+ type HydratedDocumentOverrides<T> = {
170
+ [K in keyof T]: OmitThisParameterIfFunction<T[K]>;
171
+ };
172
+
164
173
  /**
165
174
  * @summary Adds timestamp fields to a type
166
175
  * @description Adds createdAt and updatedAt fields of type Date, or custom timestamp fields if specified
@@ -1,24 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Handles creating `{ type: 'object' }` vs `{ bsonType: 'object' }` vs `{ bsonType: ['object', 'null'] }`
5
- *
6
- * @param {string} type
7
- * @param {string} bsonType
8
- * @param {boolean} useBsonType
9
- * @param {boolean} isRequired
10
- */
11
-
12
- module.exports = function createJSONSchemaTypeArray(type, bsonType, useBsonType, isRequired) {
13
- if (useBsonType) {
14
- if (isRequired) {
15
- return { bsonType };
16
- }
17
- return { bsonType: [bsonType, 'null'] };
18
- } else {
19
- if (isRequired) {
20
- return { type };
21
- }
22
- return { type: [type, 'null'] };
23
- }
24
- };