mongoose 9.5.0 → 9.6.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.
- package/lib/error/messages.js +1 -0
- package/lib/options/schemaTypeOptions.js +14 -0
- package/lib/schemaType.js +57 -4
- package/package.json +4 -4
- package/types/index.d.ts +5 -5
- package/types/inferrawdoctype.d.ts +5 -2
- package/types/inferschematype.d.ts +9 -1
- package/types/query.d.ts +2 -2
- package/types/schematypes.d.ts +10 -0
package/lib/error/messages.js
CHANGED
|
@@ -30,6 +30,7 @@ msg.DocumentNotFoundError = null;
|
|
|
30
30
|
msg.general = {};
|
|
31
31
|
msg.general.default = 'Validator failed for path `{PATH}` with value `{VALUE}`';
|
|
32
32
|
msg.general.required = 'Path `{PATH}` is required.';
|
|
33
|
+
msg.general.allowNull = 'Path `{PATH}` does not allow null values.';
|
|
33
34
|
|
|
34
35
|
msg.Number = {};
|
|
35
36
|
msg.Number.min = 'Path `{PATH}` ({VALUE}) is less than minimum allowed value ({MIN}).';
|
|
@@ -94,6 +94,20 @@ Object.defineProperty(SchemaTypeOptions.prototype, 'cast', opts);
|
|
|
94
94
|
|
|
95
95
|
Object.defineProperty(SchemaTypeOptions.prototype, 'required', opts);
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Controls whether this path may be set to `null`. By default, Mongoose allows
|
|
99
|
+
* `null` for non-required paths. Set `allowNull: false` to allow `undefined`
|
|
100
|
+
* but disallow `null`.
|
|
101
|
+
*
|
|
102
|
+
* @api public
|
|
103
|
+
* @property allowNull
|
|
104
|
+
* @memberOf SchemaTypeOptions
|
|
105
|
+
* @type {boolean}
|
|
106
|
+
* @instance
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
Object.defineProperty(SchemaTypeOptions.prototype, 'allowNull', opts);
|
|
110
|
+
|
|
97
111
|
/**
|
|
98
112
|
* The default value for this path. If a function, Mongoose executes the function
|
|
99
113
|
* and uses the return value as the default.
|
package/lib/schemaType.js
CHANGED
|
@@ -200,15 +200,16 @@ SchemaType.prototype._createJSONSchemaTypeDefinition = function _createJSONSchem
|
|
|
200
200
|
(this.options.required == null ?
|
|
201
201
|
(options?._defaultRequired === true || this.path === '_id') :
|
|
202
202
|
this.options.required && typeof this.options.required !== 'function');
|
|
203
|
+
const allowNull = this.options.allowNull !== false;
|
|
203
204
|
|
|
204
205
|
if (useBsonType) {
|
|
205
|
-
if (isRequired) {
|
|
206
|
+
if (isRequired || !allowNull) {
|
|
206
207
|
return { bsonType };
|
|
207
208
|
}
|
|
208
209
|
return { bsonType: [bsonType, 'null'] };
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
if (isRequired) {
|
|
212
|
+
if (isRequired || !allowNull) {
|
|
212
213
|
return { type };
|
|
213
214
|
}
|
|
214
215
|
return { type: [type, 'null'] };
|
|
@@ -1142,6 +1143,12 @@ SchemaType.prototype.required = function(required, message) {
|
|
|
1142
1143
|
|
|
1143
1144
|
const _this = this;
|
|
1144
1145
|
this.isRequired = true;
|
|
1146
|
+
this.originalRequiredValue = required;
|
|
1147
|
+
|
|
1148
|
+
if (typeof this.originalRequiredValue !== 'function' &&
|
|
1149
|
+
(utils.hasUserDefinedProperty(this.options, 'allowNull') || this.allowNullValidator != null)) {
|
|
1150
|
+
throw new MongooseError('Path "' + this.path + '" may not have `allowNull` specified when `required` is true');
|
|
1151
|
+
}
|
|
1145
1152
|
|
|
1146
1153
|
this.requiredValidator = function(v) {
|
|
1147
1154
|
const cachedRequired = this?.$__?.cachedRequired;
|
|
@@ -1166,8 +1173,6 @@ SchemaType.prototype.required = function(required, message) {
|
|
|
1166
1173
|
|
|
1167
1174
|
return _this.checkRequired(v, this);
|
|
1168
1175
|
};
|
|
1169
|
-
this.originalRequiredValue = required;
|
|
1170
|
-
|
|
1171
1176
|
if (typeof required === 'string') {
|
|
1172
1177
|
message = required;
|
|
1173
1178
|
required = undefined;
|
|
@@ -1183,6 +1188,53 @@ SchemaType.prototype.required = function(required, message) {
|
|
|
1183
1188
|
return this;
|
|
1184
1189
|
};
|
|
1185
1190
|
|
|
1191
|
+
/**
|
|
1192
|
+
* Adds a validator that disallows `null` for this path without making the path
|
|
1193
|
+
* required. `undefined` values still pass validation.
|
|
1194
|
+
*
|
|
1195
|
+
* #### Example:
|
|
1196
|
+
*
|
|
1197
|
+
* const schema = new Schema({
|
|
1198
|
+
* name: { type: String, allowNull: false }
|
|
1199
|
+
* });
|
|
1200
|
+
*
|
|
1201
|
+
* new Model({ name: undefined }).validateSync(); // OK
|
|
1202
|
+
* new Model({ name: null }).validateSync(); // ValidationError
|
|
1203
|
+
*
|
|
1204
|
+
* @param {boolean} allowNull
|
|
1205
|
+
* @return {SchemaType} this
|
|
1206
|
+
* @api public
|
|
1207
|
+
*/
|
|
1208
|
+
|
|
1209
|
+
SchemaType.prototype.allowNull = function(allowNull) {
|
|
1210
|
+
if (arguments.length > 0 && this.isRequired && typeof this.originalRequiredValue !== 'function') {
|
|
1211
|
+
throw new MongooseError('Path "' + this.path + '" may not have `allowNull` specified when `required` is true');
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
this.validators = this.validators.filter(function(v) {
|
|
1215
|
+
return v.validator !== this.allowNullValidator;
|
|
1216
|
+
}, this);
|
|
1217
|
+
|
|
1218
|
+
if (allowNull !== false) {
|
|
1219
|
+
delete this.options.allowNull;
|
|
1220
|
+
delete this.allowNullValidator;
|
|
1221
|
+
return this;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
this.options.allowNull = false;
|
|
1225
|
+
this.allowNullValidator = function(v) {
|
|
1226
|
+
return v !== null;
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
this.validators.push({
|
|
1230
|
+
validator: this.allowNullValidator,
|
|
1231
|
+
message: MongooseError.messages.general.allowNull,
|
|
1232
|
+
type: 'allowNull'
|
|
1233
|
+
});
|
|
1234
|
+
|
|
1235
|
+
return this;
|
|
1236
|
+
};
|
|
1237
|
+
|
|
1186
1238
|
/**
|
|
1187
1239
|
* Set the model that this path refers to. This is the option that [populate](https://mongoosejs.com/docs/populate.html)
|
|
1188
1240
|
* looks at to determine the foreign collection it should query.
|
|
@@ -1802,6 +1854,7 @@ SchemaType.prototype.clone = function() {
|
|
|
1802
1854
|
const schematype = new this.constructor(this.path, options, this.instance, this.parentSchema);
|
|
1803
1855
|
schematype.validators = this.validators.slice();
|
|
1804
1856
|
if (this.requiredValidator !== undefined) schematype.requiredValidator = this.requiredValidator;
|
|
1857
|
+
if (this.allowNullValidator !== undefined) schematype.allowNullValidator = this.allowNullValidator;
|
|
1805
1858
|
if (this.defaultValue !== undefined) schematype.defaultValue = this.defaultValue;
|
|
1806
1859
|
if (this.$immutable !== undefined && this.options.immutable === undefined) {
|
|
1807
1860
|
schematype.$immutable = this.$immutable;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "9.
|
|
4
|
+
"version": "9.6.0",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"kareem": "3.3.0",
|
|
24
|
-
"mongodb": "~7.
|
|
24
|
+
"mongodb": "~7.2",
|
|
25
25
|
"mpath": "0.9.0",
|
|
26
26
|
"mquery": "6.0.0",
|
|
27
27
|
"ms": "2.1.3",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"markdownlint-cli2": "0.22.0",
|
|
53
53
|
"marked": "17.0.5",
|
|
54
54
|
"mkdirp": "^3.0.1",
|
|
55
|
-
"mocha": "
|
|
55
|
+
"mocha": "12.0.0-beta-9.2",
|
|
56
56
|
"moment": "2.30.1",
|
|
57
57
|
"mongodb-client-encryption": "~7.0",
|
|
58
58
|
"mongodb-memory-server": "11.0.1",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"tstyche": "^7.0.0",
|
|
64
64
|
"typescript": "5.9.3",
|
|
65
65
|
"typescript-eslint": "^8.31.1",
|
|
66
|
-
"uuid": "
|
|
66
|
+
"uuid": "14.0.0"
|
|
67
67
|
},
|
|
68
68
|
"directories": {
|
|
69
69
|
"lib": "./lib/mongoose"
|
package/types/index.d.ts
CHANGED
|
@@ -819,12 +819,12 @@ declare module 'mongoose' {
|
|
|
819
819
|
|
|
820
820
|
export type ReturnsNewDoc = { new: true } | { returnOriginal: false } | { returnDocument: 'after' };
|
|
821
821
|
|
|
822
|
-
type
|
|
822
|
+
export type ArrayProjectionOperators = { $slice: number | [number, number]; $elemMatch?: never } | { $elemMatch: Record<string, any>; $slice?: never };
|
|
823
823
|
/**
|
|
824
824
|
* This Type Assigns `Element | undefined` recursively to the `T` type.
|
|
825
825
|
* if it is an array it will do this to the element of the array, if it is an object it will do this for the properties of the object.
|
|
826
826
|
* `Element` is the truthy or falsy values that are going to be used as the value of the projection.(1 | true or 0 | false)
|
|
827
|
-
* For the elements of the array we will use: `Element | `undefined` | `
|
|
827
|
+
* For the elements of the array we will use: `Element | `undefined` | `ArrayProjectionOperators`
|
|
828
828
|
* @example
|
|
829
829
|
* type CalculatedType = Projector<{ a: string, b: number, c: { d: string }, d: string[] }, true>
|
|
830
830
|
* type CalculatedType = {
|
|
@@ -833,11 +833,11 @@ declare module 'mongoose' {
|
|
|
833
833
|
c?: true | {
|
|
834
834
|
d?: true | undefined;
|
|
835
835
|
} | undefined;
|
|
836
|
-
d?: true |
|
|
836
|
+
d?: true | ArrayProjectionOperators | undefined;
|
|
837
837
|
}
|
|
838
838
|
*/
|
|
839
|
-
type Projector<T, Element> = T extends Array<infer U>
|
|
840
|
-
? Projector<U, Element> |
|
|
839
|
+
export type Projector<T, Element> = T extends Array<infer U>
|
|
840
|
+
? Projector<U, Element> | ArrayProjectionOperators
|
|
841
841
|
: T extends TreatAsPrimitives
|
|
842
842
|
? Element
|
|
843
843
|
: T extends Record<string, any>
|
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
PathEnumOrString,
|
|
4
4
|
OptionalPaths,
|
|
5
5
|
RequiredPaths,
|
|
6
|
-
IsPathRequired
|
|
6
|
+
IsPathRequired,
|
|
7
|
+
PathAllowsNull
|
|
7
8
|
} from './inferschematype';
|
|
8
9
|
import { Binary, UUID } from 'mongodb';
|
|
9
10
|
|
|
@@ -24,7 +25,9 @@ declare module 'mongoose' {
|
|
|
24
25
|
OptionalPaths<SchemaDefinition, TSchemaOptions['typeKey']>)
|
|
25
26
|
]: IsPathRequired<SchemaDefinition[K], TSchemaOptions['typeKey']> extends true
|
|
26
27
|
? ObtainRawDocumentPathType<SchemaDefinition[K], TSchemaOptions['typeKey'], TTransformOptions>
|
|
27
|
-
:
|
|
28
|
+
: PathAllowsNull<SchemaDefinition[K]> extends true
|
|
29
|
+
? ObtainRawDocumentPathType<SchemaDefinition[K], TSchemaOptions['typeKey'], TTransformOptions> | null
|
|
30
|
+
: ObtainRawDocumentPathType<SchemaDefinition[K], TSchemaOptions['typeKey'], TTransformOptions>;
|
|
28
31
|
}, TSchemaOptions>;
|
|
29
32
|
|
|
30
33
|
export type InferRawDocType<
|
|
@@ -47,7 +47,9 @@ declare module 'mongoose' {
|
|
|
47
47
|
TSchemaOptions['typeKey']
|
|
48
48
|
> extends true ?
|
|
49
49
|
ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']>
|
|
50
|
-
:
|
|
50
|
+
: PathAllowsNull<DocDefinition[K]> extends true ?
|
|
51
|
+
ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']> | null
|
|
52
|
+
: ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']>;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -222,6 +224,12 @@ type OptionalPaths<T, TypeKey extends string = DefaultTypeKey> = Pick<
|
|
|
222
224
|
OptionalPathKeys<T, TypeKey>
|
|
223
225
|
>;
|
|
224
226
|
|
|
227
|
+
/**
|
|
228
|
+
* @summary Checks if a document path allows `null` values.
|
|
229
|
+
* @param {P} P Document path.
|
|
230
|
+
*/
|
|
231
|
+
export type PathAllowsNull<P> = P extends { allowNull: false } ? false : true;
|
|
232
|
+
|
|
225
233
|
/**
|
|
226
234
|
* @summary Allows users to optionally choose their own type for a schema field for stronger typing.
|
|
227
235
|
*/
|
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
|
package/types/schematypes.d.ts
CHANGED
|
@@ -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
|
|