-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathutils.js
215 lines (215 loc) · 7.52 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
"use strict";
/**
* Utility functions
* @module multer-gridfs-storage/utils
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDatabase = exports.compareUris = exports.hasKeys = exports.compareBy = exports.compareArrays = exports.compare = exports.shouldListenOnDb = void 0;
const lodash_isplainobject_1 = __importDefault(require("lodash.isplainobject"));
const package_json_1 = require("mongodb/package.json");
function shouldListenOnDb(v = package_json_1.version) {
const [major, minor, patch] = v.split('.').map((vn) => Number(vn));
if (major === 3) {
if (minor <= 5) {
return true;
}
return minor === 6 && patch < 4;
}
return major < 4;
}
exports.shouldListenOnDb = shouldListenOnDb;
/**
* Compare two objects by value.
*
* This function is designed taking into account how mongodb connection parsing routines work.
* @param object1 The target object to compare
* @param object2 The second object to compare with the first
* @return Return true if both objects are equal by value
*/
function compare(object1, object2) {
let prop;
let comp;
let value1;
let value2;
let keys1 = 0;
let keys2 = 0;
// If objects are equal by identity stop testing
if (object1 === object2) {
return true;
}
// Falsey and plain objects with no properties are equivalent
if (!object1 || !object2) {
if (!object1 && !object2) {
return true;
}
return !(object1 ? hasKeys(object1) : hasKeys(object2));
}
// Check both own and inherited properties, MongoDb doesn't care where the property was defined
/* eslint-disable-next-line guard-for-in */
for (prop in object1) {
value1 = object1[prop];
value2 = object2[prop];
// If one object has one property not present in the other they are different
if (prop in object2) {
comp = compareBy(value1, value2);
switch (comp) {
case 'object':
// If both values are plain objects recursively compare its properties
if (!compare(value1, value2)) {
return false;
}
break;
case 'array':
// If both values are arrays compare buffers and strings by content and every other value by identity
if (!compareArrays(value1, value2)) {
return false;
}
break;
case 'buffer':
// If both values are buffers compare them by content
if (Buffer.compare(value1, value2) !== 0) {
return false;
}
break;
default:
// All other values are compared by identity
if (value1 !== value2) {
return false;
}
break;
}
keys1++;
}
else {
return false;
}
}
// Count all properties from the target object
/* eslint-disable-next-line guard-for-in */
for (prop in object2) {
keys2++;
}
// If the target object has more properties than source they are different
return keys1 === keys2;
}
exports.compare = compare;
/**
* Compare arrays by reference unless the values are strings or buffers
* @param array1 The source array to compare
* @param array2 The target array to compare with
* @return Returns true if both arrays are equivalent
*/
function compareArrays(array1, array2) {
let value1;
let value2;
if (array1.length !== array2.length) {
return false;
}
for (const [i, element] of array1.entries()) {
value1 = element;
value2 = array2[i];
// Types other than string or buffers are compared by reference because MongoDb only accepts those two types
// for configuration inside arrays
if (compareBy(value1, value2) === 'buffer') {
if (Buffer.compare(value1, value2) !== 0) {
return false;
}
}
else if (value1 !== value2) {
return false;
}
}
return true;
}
exports.compareArrays = compareArrays;
/**
* Indicates how objects should be compared.
* @param object1 The source object to compare
* @param object2 The target object to compare with
* @return Always returns 'identity' unless both objects have the same type and they are plain objects, arrays
* or buffers
*/
function compareBy(object1, object2) {
if ((0, lodash_isplainobject_1.default)(object1) && (0, lodash_isplainobject_1.default)(object2)) {
return 'object';
}
if (Array.isArray(object1) && Array.isArray(object2)) {
return 'array';
}
if (Buffer.isBuffer(object1) && Buffer.isBuffer(object2)) {
return 'buffer';
}
// All values are compared by identity unless they are both arrays, buffers or plain objects
return 'identity';
}
exports.compareBy = compareBy;
/**
* Return true if the object has at least one property inherited or not
* @param object The object to inspect
* @return If the object has any properties or not
*/
function hasKeys(object) {
/* eslint-disable-next-line guard-for-in, no-unreachable-loop */
for (const prop in object) {
// Stop testing if the object has at least one property
return true;
}
return false;
}
exports.hasKeys = hasKeys;
/**
* Compare two parsed uris checking if they are equivalent
* @param {*} uri1 The source parsed uri
* @param {*} uri2 The target parsed uri to compare
* @return {boolean} Return true if both uris are equivalent
*/
function compareUris(uri1, uri2) {
// Compare properties that are string values
const stringProps = ['scheme', 'username', 'password', 'database'];
const diff = stringProps.find((prop) => uri1[prop] !== uri2[prop]);
if (diff) {
return false;
}
// Compare query parameter values
if (!compare(uri1.options, uri2.options)) {
return false;
}
const hosts1 = uri1.hosts;
const hosts2 = uri2.hosts;
// Check if both uris have the same number of hosts
if (hosts1.length !== hosts2.length) {
return false;
}
// Check if every host in one array is present on the other array no matter where is positioned
for (const hostObject of hosts1) {
if (!hosts2.some((h) => h.host === hostObject.host && h.port === hostObject.port)) {
return false;
}
}
return true;
}
exports.compareUris = compareUris;
/**
* Checks if an object is a mongoose instance, a connection or a mongo Db object
* @param {*} object The object to check
* @return The database object
*/
function getDatabase(object) {
var _a;
// If the object has a db property should be a mongoose connection instance
// Mongo 2 has a db property but its a function. See issue #14
if (object.db && typeof object.db !== 'function') {
return object.db;
}
// If it has a connection property with a db property on it is a mongoose instance
if ((_a = object === null || object === void 0 ? void 0 : object.connection) === null || _a === void 0 ? void 0 : _a.db) {
return object.connection.db;
}
// If none of the above are true it should be a mongo database object
return object;
}
exports.getDatabase = getDatabase;
//# sourceMappingURL=utils.js.map