UNPKG

2.53 kBJavaScriptView Raw
1'use strict';
2
3/*!
4 * Module dependencies.
5 */
6
7const Binary = require('../driver').get().Binary;
8const Decimal128 = require('../types/decimal128');
9const ObjectId = require('../types/objectid');
10const isMongooseObject = require('./isMongooseObject');
11
12exports.flatten = flatten;
13exports.modifiedPaths = modifiedPaths;
14
15/*!
16 * ignore
17 */
18
19function flatten(update, path, options, schema) {
20 let keys;
21 if (update && isMongooseObject(update) && !Buffer.isBuffer(update)) {
22 keys = Object.keys(update.toObject({ transform: false, virtuals: false }));
23 } else {
24 keys = Object.keys(update || {});
25 }
26
27 const numKeys = keys.length;
28 const result = {};
29 path = path ? path + '.' : '';
30
31 for (let i = 0; i < numKeys; ++i) {
32 const key = keys[i];
33 const val = update[key];
34 result[path + key] = val;
35
36 // Avoid going into mixed paths if schema is specified
37 const keySchema = schema && schema.path && schema.path(path + key);
38 const isNested = schema && schema.nested && schema.nested[path + key];
39 if (keySchema && keySchema.instance === 'Mixed') continue;
40
41 if (shouldFlatten(val)) {
42 if (options && options.skipArrays && Array.isArray(val)) {
43 continue;
44 }
45 const flat = flatten(val, path + key, options, schema);
46 for (const k in flat) {
47 result[k] = flat[k];
48 }
49 if (Array.isArray(val)) {
50 result[path + key] = val;
51 }
52 }
53
54 if (isNested) {
55 const paths = Object.keys(schema.paths);
56 for (const p of paths) {
57 if (p.startsWith(path + key + '.') && !result.hasOwnProperty(p)) {
58 result[p] = void 0;
59 }
60 }
61 }
62 }
63
64 return result;
65}
66
67/*!
68 * ignore
69 */
70
71function modifiedPaths(update, path, result) {
72 const keys = Object.keys(update || {});
73 const numKeys = keys.length;
74 result = result || {};
75 path = path ? path + '.' : '';
76
77 for (let i = 0; i < numKeys; ++i) {
78 const key = keys[i];
79 let val = update[key];
80
81 result[path + key] = true;
82 if (isMongooseObject(val) && !Buffer.isBuffer(val)) {
83 val = val.toObject({ transform: false, virtuals: false });
84 }
85 if (shouldFlatten(val)) {
86 modifiedPaths(val, path + key, result);
87 }
88 }
89
90 return result;
91}
92
93/*!
94 * ignore
95 */
96
97function shouldFlatten(val) {
98 return val &&
99 typeof val === 'object' &&
100 !(val instanceof Date) &&
101 !(val instanceof ObjectId) &&
102 (!Array.isArray(val) || val.length > 0) &&
103 !(val instanceof Buffer) &&
104 !(val instanceof Decimal128) &&
105 !(val instanceof Binary);
106}