mongoose 7.3.3 → 7.4.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/dist/browser.umd.js +1 -1
- package/lib/cast.js +2 -2
- package/lib/connection.js +32 -200
- package/lib/document.js +30 -34
- package/lib/drivers/node-mongodb-native/connection.js +247 -0
- package/lib/error/cast.js +10 -9
- package/lib/error/messages.js +1 -1
- package/lib/helpers/schema/getPath.js +0 -1
- package/lib/helpers/schema/idGetter.js +12 -1
- package/lib/model.js +45 -16
- package/lib/query.js +36 -21
- package/lib/schema/SubdocumentPath.js +10 -4
- package/lib/schema/array.js +2 -0
- package/lib/schema/bigint.js +2 -0
- package/lib/schema/boolean.js +2 -0
- package/lib/schema/buffer.js +2 -0
- package/lib/schema/date.js +2 -0
- package/lib/schema/decimal128.js +2 -0
- package/lib/schema/documentarray.js +2 -0
- package/lib/schema/mixed.js +2 -0
- package/lib/schema/number.js +2 -0
- package/lib/schema/objectid.js +2 -0
- package/lib/schema/string.js +2 -0
- package/lib/schema/uuid.js +2 -0
- package/lib/schema.js +5 -3
- package/lib/schematype.js +20 -4
- package/package.json +3 -3
- package/types/augmentations.d.ts +9 -0
- package/types/index.d.ts +1 -0
- package/types/models.d.ts +7 -2
- package/types/query.d.ts +1 -1
- package/types/schemaoptions.d.ts +3 -0
- package/types/schematypes.d.ts +5 -1
- package/types/types.d.ts +0 -1
- package/lib/helpers/path/flattenObjectWithDottedPaths.js +0 -39
package/lib/cast.js
CHANGED
|
@@ -10,12 +10,12 @@ const Types = require('./schema/index');
|
|
|
10
10
|
const cast$expr = require('./helpers/query/cast$expr');
|
|
11
11
|
const castTextSearch = require('./schema/operators/text');
|
|
12
12
|
const get = require('./helpers/get');
|
|
13
|
-
const getConstructorName = require('./helpers/getConstructorName');
|
|
14
13
|
const getSchemaDiscriminatorByValue = require('./helpers/discriminator/getSchemaDiscriminatorByValue');
|
|
15
14
|
const isOperator = require('./helpers/query/isOperator');
|
|
16
15
|
const util = require('util');
|
|
17
16
|
const isObject = require('./helpers/isObject');
|
|
18
17
|
const isMongooseObject = require('./helpers/isMongooseObject');
|
|
18
|
+
const utils = require('./utils');
|
|
19
19
|
|
|
20
20
|
const ALLOWED_GEOWITHIN_GEOJSON_TYPES = ['Polygon', 'MultiPolygon'];
|
|
21
21
|
|
|
@@ -291,7 +291,7 @@ module.exports = function cast(schema, obj, options, context) {
|
|
|
291
291
|
}
|
|
292
292
|
} else if (val == null) {
|
|
293
293
|
continue;
|
|
294
|
-
} else if (
|
|
294
|
+
} else if (utils.isPOJO(val)) {
|
|
295
295
|
any$conditionals = Object.keys(val).some(isOperator);
|
|
296
296
|
|
|
297
297
|
if (!any$conditionals) {
|
package/lib/connection.js
CHANGED
|
@@ -16,10 +16,7 @@ const clone = require('./helpers/clone');
|
|
|
16
16
|
const driver = require('./driver');
|
|
17
17
|
const get = require('./helpers/get');
|
|
18
18
|
const immediate = require('./helpers/immediate');
|
|
19
|
-
const mongodb = require('mongodb');
|
|
20
|
-
const pkg = require('../package.json');
|
|
21
19
|
const utils = require('./utils');
|
|
22
|
-
const processConnectionOptions = require('./helpers/processConnectionOptions');
|
|
23
20
|
const CreateCollectionsError = require('./error/createCollectionsError');
|
|
24
21
|
|
|
25
22
|
const arrayAtomicsSymbol = require('./helpers/symbols').arrayAtomicsSymbol;
|
|
@@ -738,7 +735,7 @@ Connection.prototype.openUri = async function openUri(uri, options) {
|
|
|
738
735
|
throw err;
|
|
739
736
|
}
|
|
740
737
|
|
|
741
|
-
this.$initialConnection =
|
|
738
|
+
this.$initialConnection = this.createClient(uri, options).
|
|
742
739
|
then(() => this).
|
|
743
740
|
catch(err => {
|
|
744
741
|
this.readyState = STATES.disconnected;
|
|
@@ -795,184 +792,6 @@ function _handleConnectionErrors(err) {
|
|
|
795
792
|
return err;
|
|
796
793
|
}
|
|
797
794
|
|
|
798
|
-
/*!
|
|
799
|
-
* ignore
|
|
800
|
-
*/
|
|
801
|
-
|
|
802
|
-
async function _createMongoClient(conn, uri, options) {
|
|
803
|
-
if (typeof uri !== 'string') {
|
|
804
|
-
throw new MongooseError('The `uri` parameter to `openUri()` must be a ' +
|
|
805
|
-
`string, got "${typeof uri}". Make sure the first parameter to ` +
|
|
806
|
-
'`mongoose.connect()` or `mongoose.createConnection()` is a string.');
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
if (conn._destroyCalled) {
|
|
810
|
-
throw new MongooseError(
|
|
811
|
-
'Connection has been closed and destroyed, and cannot be used for re-opening the connection. ' +
|
|
812
|
-
'Please create a new connection with `mongoose.createConnection()` or `mongoose.connect()`.'
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
if (conn.readyState === STATES.connecting || conn.readyState === STATES.connected) {
|
|
817
|
-
if (conn._connectionString !== uri) {
|
|
818
|
-
throw new MongooseError('Can\'t call `openUri()` on an active connection with ' +
|
|
819
|
-
'different connection strings. Make sure you aren\'t calling `mongoose.connect()` ' +
|
|
820
|
-
'multiple times. See: https://mongoosejs.com/docs/connections.html#multiple_connections');
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
options = processConnectionOptions(uri, options);
|
|
825
|
-
|
|
826
|
-
if (options) {
|
|
827
|
-
|
|
828
|
-
const autoIndex = options.config && options.config.autoIndex != null ?
|
|
829
|
-
options.config.autoIndex :
|
|
830
|
-
options.autoIndex;
|
|
831
|
-
if (autoIndex != null) {
|
|
832
|
-
conn.config.autoIndex = autoIndex !== false;
|
|
833
|
-
delete options.config;
|
|
834
|
-
delete options.autoIndex;
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
if ('autoCreate' in options) {
|
|
838
|
-
conn.config.autoCreate = !!options.autoCreate;
|
|
839
|
-
delete options.autoCreate;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
if ('sanitizeFilter' in options) {
|
|
843
|
-
conn.config.sanitizeFilter = options.sanitizeFilter;
|
|
844
|
-
delete options.sanitizeFilter;
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
// Backwards compat
|
|
848
|
-
if (options.user || options.pass) {
|
|
849
|
-
options.auth = options.auth || {};
|
|
850
|
-
options.auth.username = options.user;
|
|
851
|
-
options.auth.password = options.pass;
|
|
852
|
-
|
|
853
|
-
conn.user = options.user;
|
|
854
|
-
conn.pass = options.pass;
|
|
855
|
-
}
|
|
856
|
-
delete options.user;
|
|
857
|
-
delete options.pass;
|
|
858
|
-
|
|
859
|
-
if (options.bufferCommands != null) {
|
|
860
|
-
conn.config.bufferCommands = options.bufferCommands;
|
|
861
|
-
delete options.bufferCommands;
|
|
862
|
-
}
|
|
863
|
-
} else {
|
|
864
|
-
options = {};
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
conn._connectionOptions = options;
|
|
868
|
-
const dbName = options.dbName;
|
|
869
|
-
if (dbName != null) {
|
|
870
|
-
conn.$dbName = dbName;
|
|
871
|
-
}
|
|
872
|
-
delete options.dbName;
|
|
873
|
-
|
|
874
|
-
if (!utils.hasUserDefinedProperty(options, 'driverInfo')) {
|
|
875
|
-
options.driverInfo = {
|
|
876
|
-
name: 'Mongoose',
|
|
877
|
-
version: pkg.version
|
|
878
|
-
};
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
conn.readyState = STATES.connecting;
|
|
882
|
-
conn._connectionString = uri;
|
|
883
|
-
|
|
884
|
-
let client;
|
|
885
|
-
try {
|
|
886
|
-
client = new mongodb.MongoClient(uri, options);
|
|
887
|
-
} catch (error) {
|
|
888
|
-
conn.readyState = STATES.disconnected;
|
|
889
|
-
throw error;
|
|
890
|
-
}
|
|
891
|
-
conn.client = client;
|
|
892
|
-
|
|
893
|
-
client.setMaxListeners(0);
|
|
894
|
-
await client.connect();
|
|
895
|
-
|
|
896
|
-
_setClient(conn, client, options, dbName);
|
|
897
|
-
|
|
898
|
-
for (const db of conn.otherDbs) {
|
|
899
|
-
_setClient(db, client, {}, db.name);
|
|
900
|
-
}
|
|
901
|
-
return conn;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
/*!
|
|
905
|
-
* ignore
|
|
906
|
-
*/
|
|
907
|
-
|
|
908
|
-
function _setClient(conn, client, options, dbName) {
|
|
909
|
-
const db = dbName != null ? client.db(dbName) : client.db();
|
|
910
|
-
conn.db = db;
|
|
911
|
-
conn.client = client;
|
|
912
|
-
conn.host = client &&
|
|
913
|
-
client.s &&
|
|
914
|
-
client.s.options &&
|
|
915
|
-
client.s.options.hosts &&
|
|
916
|
-
client.s.options.hosts[0] &&
|
|
917
|
-
client.s.options.hosts[0].host || void 0;
|
|
918
|
-
conn.port = client &&
|
|
919
|
-
client.s &&
|
|
920
|
-
client.s.options &&
|
|
921
|
-
client.s.options.hosts &&
|
|
922
|
-
client.s.options.hosts[0] &&
|
|
923
|
-
client.s.options.hosts[0].port || void 0;
|
|
924
|
-
conn.name = dbName != null ? dbName : client && client.s && client.s.options && client.s.options.dbName || void 0;
|
|
925
|
-
conn._closeCalled = client._closeCalled;
|
|
926
|
-
|
|
927
|
-
const _handleReconnect = () => {
|
|
928
|
-
// If we aren't disconnected, we assume this reconnect is due to a
|
|
929
|
-
// socket timeout. If there's no activity on a socket for
|
|
930
|
-
// `socketTimeoutMS`, the driver will attempt to reconnect and emit
|
|
931
|
-
// this event.
|
|
932
|
-
if (conn.readyState !== STATES.connected) {
|
|
933
|
-
conn.readyState = STATES.connected;
|
|
934
|
-
conn.emit('reconnect');
|
|
935
|
-
conn.emit('reconnected');
|
|
936
|
-
conn.onOpen();
|
|
937
|
-
}
|
|
938
|
-
};
|
|
939
|
-
|
|
940
|
-
const type = client &&
|
|
941
|
-
client.topology &&
|
|
942
|
-
client.topology.description &&
|
|
943
|
-
client.topology.description.type || '';
|
|
944
|
-
|
|
945
|
-
if (type === 'Single') {
|
|
946
|
-
client.on('serverDescriptionChanged', ev => {
|
|
947
|
-
const newDescription = ev.newDescription;
|
|
948
|
-
if (newDescription.type === 'Unknown') {
|
|
949
|
-
conn.readyState = STATES.disconnected;
|
|
950
|
-
} else {
|
|
951
|
-
_handleReconnect();
|
|
952
|
-
}
|
|
953
|
-
});
|
|
954
|
-
} else if (type.startsWith('ReplicaSet')) {
|
|
955
|
-
client.on('topologyDescriptionChanged', ev => {
|
|
956
|
-
// Emit disconnected if we've lost connectivity to the primary
|
|
957
|
-
const description = ev.newDescription;
|
|
958
|
-
if (conn.readyState === STATES.connected && description.type !== 'ReplicaSetWithPrimary') {
|
|
959
|
-
// Implicitly emits 'disconnected'
|
|
960
|
-
conn.readyState = STATES.disconnected;
|
|
961
|
-
} else if (conn.readyState === STATES.disconnected && description.type === 'ReplicaSetWithPrimary') {
|
|
962
|
-
_handleReconnect();
|
|
963
|
-
}
|
|
964
|
-
});
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
conn.onOpen();
|
|
968
|
-
|
|
969
|
-
for (const i in conn.collections) {
|
|
970
|
-
if (utils.object.hasOwnProperty(conn.collections, i)) {
|
|
971
|
-
conn.collections[i].onOpen();
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
795
|
/**
|
|
977
796
|
* Destroy the connection. Similar to [`.close`](https://mongoosejs.com/docs/api/connection.html#Connection.prototype.close()),
|
|
978
797
|
* but also removes the connection from Mongoose's `connections` list and prevents the
|
|
@@ -1525,26 +1344,16 @@ Connection.prototype.getClient = function getClient() {
|
|
|
1525
1344
|
* @return {Connection} this
|
|
1526
1345
|
*/
|
|
1527
1346
|
|
|
1528
|
-
Connection.prototype.setClient = function setClient(
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
}
|
|
1532
|
-
if (this.readyState !== STATES.disconnected) {
|
|
1533
|
-
throw new MongooseError('Cannot call `setClient()` on a connection that is already connected.');
|
|
1534
|
-
}
|
|
1535
|
-
if (client.topology == null) {
|
|
1536
|
-
throw new MongooseError('Cannot call `setClient()` with a MongoClient that you have not called `connect()` on yet.');
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
|
-
this._connectionString = client.s.url;
|
|
1540
|
-
_setClient(this, client, {}, client.s.options.dbName);
|
|
1347
|
+
Connection.prototype.setClient = function setClient() {
|
|
1348
|
+
throw new MongooseError('Connection#setClient not implemented by driver');
|
|
1349
|
+
};
|
|
1541
1350
|
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
}
|
|
1351
|
+
/*!
|
|
1352
|
+
* Called internally by `openUri()` to create a MongoClient instance.
|
|
1353
|
+
*/
|
|
1546
1354
|
|
|
1547
|
-
|
|
1355
|
+
Connection.prototype.createClient = function createClient() {
|
|
1356
|
+
throw new MongooseError('Connection#createClient not implemented by driver');
|
|
1548
1357
|
};
|
|
1549
1358
|
|
|
1550
1359
|
/**
|
|
@@ -1609,6 +1418,29 @@ Connection.prototype.syncIndexes = async function syncIndexes(options = {}) {
|
|
|
1609
1418
|
* @api public
|
|
1610
1419
|
*/
|
|
1611
1420
|
|
|
1421
|
+
/**
|
|
1422
|
+
* Removes the database connection with the given name created with with `useDb()`.
|
|
1423
|
+
*
|
|
1424
|
+
* Throws an error if the database connection was not found.
|
|
1425
|
+
*
|
|
1426
|
+
* #### Example:
|
|
1427
|
+
*
|
|
1428
|
+
* // Connect to `initialdb` first
|
|
1429
|
+
* const conn = await mongoose.createConnection('mongodb://127.0.0.1:27017/initialdb').asPromise();
|
|
1430
|
+
*
|
|
1431
|
+
* // Creates an un-cached connection to `mydb`
|
|
1432
|
+
* const db = conn.useDb('mydb');
|
|
1433
|
+
*
|
|
1434
|
+
* // Closes `db`, and removes `db` from `conn.relatedDbs` and `conn.otherDbs`
|
|
1435
|
+
* await conn.removeDb('mydb');
|
|
1436
|
+
*
|
|
1437
|
+
* @method removeDb
|
|
1438
|
+
* @memberOf Connection
|
|
1439
|
+
* @param {String} name The database name
|
|
1440
|
+
* @return {Connection} this
|
|
1441
|
+
* @api public
|
|
1442
|
+
*/
|
|
1443
|
+
|
|
1612
1444
|
/*!
|
|
1613
1445
|
* Module exports.
|
|
1614
1446
|
*/
|
package/lib/document.js
CHANGED
|
@@ -22,7 +22,6 @@ const clone = require('./helpers/clone');
|
|
|
22
22
|
const compile = require('./helpers/document/compile').compile;
|
|
23
23
|
const defineKey = require('./helpers/document/compile').defineKey;
|
|
24
24
|
const flatten = require('./helpers/common').flatten;
|
|
25
|
-
const flattenObjectWithDottedPaths = require('./helpers/path/flattenObjectWithDottedPaths');
|
|
26
25
|
const get = require('./helpers/get');
|
|
27
26
|
const getEmbeddedDiscriminatorPath = require('./helpers/document/getEmbeddedDiscriminatorPath');
|
|
28
27
|
const getKeysInSchemaOrder = require('./helpers/schema/getKeysInSchemaOrder');
|
|
@@ -473,8 +472,6 @@ function $applyDefaultsToNested(val, path, doc) {
|
|
|
473
472
|
return;
|
|
474
473
|
}
|
|
475
474
|
|
|
476
|
-
flattenObjectWithDottedPaths(val);
|
|
477
|
-
|
|
478
475
|
const paths = Object.keys(doc.$__schema.paths);
|
|
479
476
|
const plen = paths.length;
|
|
480
477
|
|
|
@@ -1079,9 +1076,11 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1079
1076
|
return this;
|
|
1080
1077
|
}
|
|
1081
1078
|
|
|
1079
|
+
options = Object.assign({}, options, { _skipMinimizeTopLevel: false });
|
|
1080
|
+
|
|
1082
1081
|
for (let i = 0; i < len; ++i) {
|
|
1083
1082
|
key = keys[i];
|
|
1084
|
-
const pathName = prefix + key;
|
|
1083
|
+
const pathName = prefix ? prefix + key : key;
|
|
1085
1084
|
pathtype = this.$__schema.pathType(pathName);
|
|
1086
1085
|
const valForKey = path[key];
|
|
1087
1086
|
|
|
@@ -1093,20 +1092,15 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1093
1092
|
pathtype === 'nested' &&
|
|
1094
1093
|
this._doc[key] != null) {
|
|
1095
1094
|
delete this._doc[key];
|
|
1096
|
-
// Make sure we set `{}` back even if we minimize re: gh-8565
|
|
1097
|
-
options = Object.assign({}, options, { _skipMinimizeTopLevel: true });
|
|
1098
|
-
} else {
|
|
1099
|
-
// Make sure we set `{_skipMinimizeTopLevel: false}` if don't have overwrite: gh-10441
|
|
1100
|
-
options = Object.assign({}, options, { _skipMinimizeTopLevel: false });
|
|
1101
1095
|
}
|
|
1102
1096
|
|
|
1103
1097
|
if (utils.isNonBuiltinObject(valForKey) && pathtype === 'nested') {
|
|
1104
|
-
this.$set(
|
|
1105
|
-
$applyDefaultsToNested(this.$get(
|
|
1098
|
+
this.$set(pathName, valForKey, constructing, Object.assign({}, options, { _skipMarkModified: true }));
|
|
1099
|
+
$applyDefaultsToNested(this.$get(pathName), pathName, this);
|
|
1106
1100
|
continue;
|
|
1107
1101
|
} else if (strict) {
|
|
1108
1102
|
// Don't overwrite defaults with undefined keys (gh-3981) (gh-9039)
|
|
1109
|
-
if (constructing &&
|
|
1103
|
+
if (constructing && valForKey === void 0 &&
|
|
1110
1104
|
this.$get(pathName) !== void 0) {
|
|
1111
1105
|
continue;
|
|
1112
1106
|
}
|
|
@@ -1116,20 +1110,19 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1116
1110
|
}
|
|
1117
1111
|
|
|
1118
1112
|
if (pathtype === 'real' || pathtype === 'virtual') {
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
path[key].toObject({ transform: false }), constructing, options);
|
|
1113
|
+
this.$set(pathName, valForKey, constructing, options);
|
|
1114
|
+
} else if (pathtype === 'nested' && valForKey instanceof Document) {
|
|
1115
|
+
this.$set(pathName,
|
|
1116
|
+
valForKey.toObject({ transform: false }), constructing, options);
|
|
1124
1117
|
} else if (strict === 'throw') {
|
|
1125
1118
|
if (pathtype === 'nested') {
|
|
1126
|
-
throw new ObjectExpectedError(key,
|
|
1119
|
+
throw new ObjectExpectedError(key, valForKey);
|
|
1127
1120
|
} else {
|
|
1128
1121
|
throw new StrictModeError(key);
|
|
1129
1122
|
}
|
|
1130
1123
|
}
|
|
1131
|
-
} else if (
|
|
1132
|
-
this.$set(
|
|
1124
|
+
} else if (valForKey !== void 0) {
|
|
1125
|
+
this.$set(pathName, valForKey, constructing, options);
|
|
1133
1126
|
}
|
|
1134
1127
|
}
|
|
1135
1128
|
|
|
@@ -2217,16 +2210,17 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
|
|
|
2217
2210
|
|
|
2218
2211
|
Document.prototype.isModified = function(paths, modifiedPaths) {
|
|
2219
2212
|
if (paths) {
|
|
2220
|
-
if (!Array.isArray(paths)) {
|
|
2221
|
-
paths = paths.indexOf(' ') === -1 ? [paths] : paths.split(' ');
|
|
2222
|
-
}
|
|
2223
|
-
|
|
2224
2213
|
const directModifiedPathsObj = this.$__.activePaths.states.modify;
|
|
2225
2214
|
if (directModifiedPathsObj == null) {
|
|
2226
2215
|
return false;
|
|
2227
2216
|
}
|
|
2217
|
+
|
|
2218
|
+
if (typeof paths === 'string') {
|
|
2219
|
+
paths = [paths];
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2228
2222
|
for (const path of paths) {
|
|
2229
|
-
if (
|
|
2223
|
+
if (directModifiedPathsObj[path] != null) {
|
|
2230
2224
|
return true;
|
|
2231
2225
|
}
|
|
2232
2226
|
}
|
|
@@ -2652,14 +2646,14 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
|
|
|
2652
2646
|
const modifiedPaths = doc.modifiedPaths();
|
|
2653
2647
|
for (const subdoc of subdocs) {
|
|
2654
2648
|
if (subdoc.$basePath) {
|
|
2655
|
-
// Remove child paths for now, because we'll be validating the whole
|
|
2656
|
-
// subdoc
|
|
2657
2649
|
const fullPathToSubdoc = subdoc.$__fullPathWithIndexes();
|
|
2658
2650
|
|
|
2659
|
-
for
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2651
|
+
// Remove child paths for now, because we'll be validating the whole
|
|
2652
|
+
// subdoc.
|
|
2653
|
+
// The following is a faster take on looping through every path in `paths`
|
|
2654
|
+
// and checking if the path starts with `fullPathToSubdoc` re: gh-13191
|
|
2655
|
+
for (const modifiedPath of subdoc.modifiedPaths()) {
|
|
2656
|
+
paths.delete(fullPathToSubdoc + '.' + modifiedPath);
|
|
2663
2657
|
}
|
|
2664
2658
|
|
|
2665
2659
|
if (doc.$isModified(fullPathToSubdoc, modifiedPaths) &&
|
|
@@ -3336,12 +3330,13 @@ Document.prototype.$__reset = function reset() {
|
|
|
3336
3330
|
if (subdoc.$isDocumentArrayElement) {
|
|
3337
3331
|
resetArrays.add(subdoc.parentArray());
|
|
3338
3332
|
} else {
|
|
3339
|
-
|
|
3333
|
+
const parent = subdoc.$parent();
|
|
3334
|
+
if (parent === this) {
|
|
3340
3335
|
this.$__.activePaths.clearPath(subdoc.$basePath);
|
|
3341
|
-
} else if (
|
|
3336
|
+
} else if (parent != null && parent.$isSubdocument) {
|
|
3342
3337
|
// If map path underneath subdocument, may end up with a case where
|
|
3343
3338
|
// map path is modified but parent still needs to be reset. See gh-10295
|
|
3344
|
-
|
|
3339
|
+
parent.$__reset();
|
|
3345
3340
|
}
|
|
3346
3341
|
}
|
|
3347
3342
|
}
|
|
@@ -4074,6 +4069,7 @@ function applyGetters(self, json, options) {
|
|
|
4074
4069
|
path = paths[i];
|
|
4075
4070
|
|
|
4076
4071
|
const parts = path.split('.');
|
|
4072
|
+
|
|
4077
4073
|
const plen = parts.length;
|
|
4078
4074
|
const last = plen - 1;
|
|
4079
4075
|
let branch = json;
|