This commit is contained in:
Jonasz Bigda
2023-03-25 21:51:42 +01:00
parent 0db1d5117e
commit b332e9ceb0
1044 changed files with 37502 additions and 63938 deletions

322
node_modules/mongodb/lib/utils.js generated vendored
View File

@@ -1,6 +1,5 @@
'use strict';
const MongoError = require('./core/error').MongoError;
const ReadPreference = require('./core/topologies/read_preference');
const WriteConcern = require('./write_concern');
var shallowClone = function(obj) {
@@ -9,31 +8,6 @@ var shallowClone = function(obj) {
return copy;
};
// Figure out the read preference
var translateReadPreference = function(options) {
var r = null;
if (options.readPreference) {
r = options.readPreference;
} else {
return options;
}
if (typeof r === 'string') {
options.readPreference = new ReadPreference(r);
} else if (r && !(r instanceof ReadPreference) && typeof r === 'object') {
const mode = r.mode || r.preference;
if (mode && typeof mode === 'string') {
options.readPreference = new ReadPreference(mode, r.tags, {
maxStalenessSeconds: r.maxStalenessSeconds
});
}
} else if (!(r instanceof ReadPreference)) {
throw new TypeError('Invalid read preference: ' + r);
}
return options;
};
// Set simple property
var getSingleProperty = function(obj, name, value) {
Object.defineProperty(obj, name, {
@@ -66,7 +40,7 @@ var formatSortValue = (exports.formatSortValue = function(sortDirection) {
});
var formattedOrderClause = (exports.formattedOrderClause = function(sortValue) {
var orderBy = {};
var orderBy = new Map();
if (sortValue == null) return null;
if (Array.isArray(sortValue)) {
if (sortValue.length === 0) {
@@ -75,15 +49,22 @@ var formattedOrderClause = (exports.formattedOrderClause = function(sortValue) {
for (var i = 0; i < sortValue.length; i++) {
if (sortValue[i].constructor === String) {
orderBy[sortValue[i]] = 1;
orderBy.set(`${sortValue[i]}`, 1);
} else {
orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]);
orderBy.set(`${sortValue[i][0]}`, formatSortValue(sortValue[i][1]));
}
}
} else if (sortValue != null && typeof sortValue === 'object') {
orderBy = sortValue;
if (sortValue instanceof Map) {
orderBy = sortValue;
} else {
var sortKeys = Object.keys(sortValue);
for (var k of sortKeys) {
orderBy.set(k, sortValue[k]);
}
}
} else if (typeof sortValue === 'string') {
orderBy[sortValue] = 1;
orderBy.set(`${sortValue}`, 1);
} else {
throw new Error(
'Illegal sort clause, must be of the form ' +
@@ -313,39 +294,38 @@ var filterOptions = function(options, names) {
};
// Write concern keys
var writeConcernKeys = ['w', 'j', 'wtimeout', 'fsync'];
const WRITE_CONCERN_KEYS = ['w', 'j', 'wtimeout', 'fsync', 'writeConcern'];
// Merge the write concern options
var mergeOptionsAndWriteConcern = function(targetOptions, sourceOptions, keys, mergeWriteConcern) {
// Mix in any allowed options
for (var i = 0; i < keys.length; i++) {
if (!targetOptions[keys[i]] && sourceOptions[keys[i]] !== undefined) {
targetOptions[keys[i]] = sourceOptions[keys[i]];
}
}
// No merging of write concern
if (!mergeWriteConcern) return targetOptions;
// Found no write Concern options
var found = false;
for (i = 0; i < writeConcernKeys.length; i++) {
if (targetOptions[writeConcernKeys[i]]) {
/**
* If there is no WriteConcern related options defined on target then inherit from source.
* Otherwise, do not inherit **any** options from source.
* @internal
* @param {object} target - options object conditionally receiving the writeConcern options
* @param {object} source - options object containing the potentially inherited writeConcern options
*/
function conditionallyMergeWriteConcern(target, source) {
let found = false;
for (const wcKey of WRITE_CONCERN_KEYS) {
if (wcKey in target) {
// Found a writeConcern option
found = true;
break;
}
}
if (!found) {
for (i = 0; i < writeConcernKeys.length; i++) {
if (sourceOptions[writeConcernKeys[i]]) {
targetOptions[writeConcernKeys[i]] = sourceOptions[writeConcernKeys[i]];
for (const wcKey of WRITE_CONCERN_KEYS) {
if (source[wcKey]) {
if (!('writeConcern' in target)) {
target.writeConcern = {};
}
target.writeConcern[wcKey] = source[wcKey];
}
}
}
return targetOptions;
};
return target;
}
/**
* Executes the given operation with provided arguments.
@@ -490,37 +470,6 @@ function applyWriteConcern(target, sources, options) {
return target;
}
/**
* Resolves a read preference based on well-defined inheritance rules. This method will not only
* determine the read preference (if there is one), but will also ensure the returned value is a
* properly constructed instance of `ReadPreference`.
*
* @param {Collection|Db|MongoClient} parent The parent of the operation on which to determine the read
* preference, used for determining the inherited read preference.
* @param {Object} options The options passed into the method, potentially containing a read preference
* @returns {(ReadPreference|null)} The resolved read preference
*/
function resolveReadPreference(parent, options) {
options = options || {};
const session = options.session;
const inheritedReadPreference = parent.readPreference;
let readPreference;
if (options.readPreference) {
readPreference = ReadPreference.fromOptions(options);
} else if (session && session.inTransaction() && session.transaction.options.readPreference) {
// The transactions read preference MUST override all other user configurable read preferences.
readPreference = session.transaction.options.readPreference;
} else if (inheritedReadPreference != null) {
readPreference = inheritedReadPreference;
} else {
throw new Error('No readPreference was provided or inherited.');
}
return typeof readPreference === 'string' ? new ReadPreference(readPreference) : readPreference;
}
/**
* Checks if a given value is a Promise
*
@@ -575,7 +524,28 @@ function decorateWithReadConcern(command, coll, options) {
}
}
const emitProcessWarning = msg => process.emitWarning(msg, 'DeprecationWarning');
/**
* Applies an explain to a given command.
* @internal
*
* @param {object} command - the command on which to apply the explain
* @param {Explain} explain - the options containing the explain verbosity
* @return the new command
*/
function decorateWithExplain(command, explain) {
if (command.explain) {
return command;
}
return { explain: command, verbosity: explain.verbosity };
}
const nodejsMajorVersion = +process.version.split('.')[0].substring(1);
const emitProcessWarning = msg =>
nodejsMajorVersion <= 6
? process.emitWarning(msg, 'DeprecationWarning', MONGODB_WARNING_CODE)
: process.emitWarning(msg, { type: 'DeprecationWarning', code: MONGODB_WARNING_CODE });
// eslint-disable-next-line no-console
const emitConsoleWarning = msg => console.error(msg);
const emitDeprecationWarning = process.emitWarning ? emitProcessWarning : emitConsoleWarning;
@@ -622,7 +592,10 @@ function deprecateOptions(config, fn) {
}
config.deprecatedOptions.forEach(deprecatedOption => {
if (options.hasOwnProperty(deprecatedOption) && !optionsWarned.has(deprecatedOption)) {
if (
Object.prototype.hasOwnProperty.call(options, deprecatedOption) &&
!optionsWarned.has(deprecatedOption)
) {
optionsWarned.add(deprecatedOption);
const msg = msgHandler(config.name, deprecatedOption);
emitDeprecationWarning(msg);
@@ -770,14 +743,21 @@ function makeInterruptableAsyncInterval(fn, options) {
const interval = options.interval || 1000;
const minInterval = options.minInterval || 500;
const immediate = typeof options.immediate === 'boolean' ? options.immediate : false;
const clock = typeof options.clock === 'function' ? options.clock : now;
function wake() {
const currentTime = now();
const currentTime = clock();
const timeSinceLastWake = currentTime - lastWakeTime;
const timeSinceLastCall = currentTime - lastCallTime;
const timeUntilNextCall = Math.max(interval - timeSinceLastCall, 0);
const timeUntilNextCall = interval - timeSinceLastCall;
lastWakeTime = currentTime;
// For the streaming protocol: there is nothing obviously stopping this
// interval from being woken up again while we are waiting "infinitely"
// for `fn` to be called again`. Since the function effectively
// never completes, the `timeUntilNextCall` will continue to grow
// negatively unbounded, so it will never trigger a reschedule here.
// debounce multiple calls to wake within the `minInterval`
if (timeSinceLastWake < minInterval) {
return;
@@ -788,6 +768,14 @@ function makeInterruptableAsyncInterval(fn, options) {
if (timeUntilNextCall > minInterval) {
reschedule(minInterval);
}
// This is possible in virtualized environments like AWS Lambda where our
// clock is unreliable. In these cases the timer is "running" but never
// actually completes, so we want to execute immediately and then attempt
// to reschedule.
if (timeUntilNextCall < 0) {
executeAndReschedule();
}
}
function stop() {
@@ -809,7 +797,8 @@ function makeInterruptableAsyncInterval(fn, options) {
function executeAndReschedule() {
lastWakeTime = 0;
lastCallTime = now();
lastCallTime = clock();
fn(err => {
if (err) throw err;
reschedule(interval);
@@ -819,13 +808,153 @@ function makeInterruptableAsyncInterval(fn, options) {
if (immediate) {
executeAndReschedule();
} else {
lastCallTime = now();
lastCallTime = clock();
reschedule();
}
return { wake, stop };
}
function hasAtomicOperators(doc) {
if (Array.isArray(doc)) {
return doc.reduce((err, u) => err || hasAtomicOperators(u), null);
}
return (
Object.keys(typeof doc.toBSON !== 'function' ? doc : doc.toBSON())
.map(k => k[0])
.indexOf('$') >= 0
);
}
/**
* When the driver used emitWarning the code will be equal to this.
* @public
*
* @example
* ```js
* process.on('warning', (warning) => {
* if (warning.code === MONGODB_WARNING_CODE) console.error('Ah an important warning! :)')
* })
* ```
*/
const MONGODB_WARNING_CODE = 'MONGODB DRIVER';
/**
* @internal
* @param {string} message - message to warn about
*/
function emitWarning(message) {
if (process.emitWarning) {
return nodejsMajorVersion <= 6
? process.emitWarning(message, undefined, MONGODB_WARNING_CODE)
: process.emitWarning(message, { code: MONGODB_WARNING_CODE });
} else {
// Approximate the style of print out on node versions pre 8.x
// eslint-disable-next-line no-console
return console.error(`[${MONGODB_WARNING_CODE}] Warning:`, message);
}
}
const emittedWarnings = new Set();
/**
* Will emit a warning once for the duration of the application.
* Uses the message to identify if it has already been emitted
* so using string interpolation can cause multiple emits
* @internal
* @param {string} message - message to warn about
*/
function emitWarningOnce(message) {
if (!emittedWarnings.has(message)) {
emittedWarnings.add(message);
return emitWarning(message);
}
}
function isSuperset(set, subset) {
set = Array.isArray(set) ? new Set(set) : set;
subset = Array.isArray(subset) ? new Set(subset) : subset;
for (const elem of subset) {
if (!set.has(elem)) {
return false;
}
}
return true;
}
function isRecord(value, requiredKeys) {
const toString = Object.prototype.toString;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const isObject = v => toString.call(v) === '[object Object]';
if (!isObject(value)) {
return false;
}
const ctor = value.constructor;
if (ctor && ctor.prototype) {
if (!isObject(ctor.prototype)) {
return false;
}
// Check to see if some method exists from the Object exists
if (!hasOwnProperty.call(ctor.prototype, 'isPrototypeOf')) {
return false;
}
}
if (requiredKeys) {
const keys = Object.keys(value);
return isSuperset(keys, requiredKeys);
}
return true;
}
/**
* Make a deep copy of an object
*
* NOTE: This is not meant to be the perfect implementation of a deep copy,
* but instead something that is good enough for the purposes of
* command monitoring.
*/
function deepCopy(value) {
if (value == null) {
return value;
} else if (Array.isArray(value)) {
return value.map(item => deepCopy(item));
} else if (isRecord(value)) {
const res = {};
for (const key in value) {
res[key] = deepCopy(value[key]);
}
return res;
}
const ctor = value.constructor;
if (ctor) {
switch (ctor.name.toLowerCase()) {
case 'date':
return new ctor(Number(value));
case 'map':
return new Map(value);
case 'set':
return new Set(value);
case 'buffer':
return Buffer.from(value);
}
}
return value;
}
/**
* @param {{version: string}} pkg
* @returns {{ major: number; minor: number; patch: number }}
*/
function parsePackageVersion(pkg) {
const versionParts = pkg.version.split('.').map(n => Number.parseInt(n, 10));
return { major: versionParts[0], minor: versionParts[1], patch: versionParts[2] };
}
module.exports = {
filterOptions,
mergeOptions,
@@ -842,22 +971,27 @@ module.exports = {
isObject,
debugOptions,
MAX_JS_INT: Number.MAX_SAFE_INTEGER + 1,
mergeOptionsAndWriteConcern,
translateReadPreference,
conditionallyMergeWriteConcern,
executeLegacyOperation,
applyRetryableWrites,
applyWriteConcern,
isPromiseLike,
decorateWithCollation,
decorateWithReadConcern,
decorateWithExplain,
deprecateOptions,
SUPPORTS,
MongoDBNamespace,
resolveReadPreference,
emitDeprecationWarning,
makeCounter,
maybePromise,
now,
calculateDurationInMs,
makeInterruptableAsyncInterval
makeInterruptableAsyncInterval,
hasAtomicOperators,
MONGODB_WARNING_CODE,
emitWarning,
emitWarningOnce,
deepCopy,
parsePackageVersion
};