You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

mongodb

Package Overview
Dependencies
Maintainers
5
Versions
694
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mongodb - npm Package Compare versions

Comparing version

to
6.18.0-dev.20250731.sha.c5365347

51

lib/bulk/common.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BulkOperationBase = exports.BulkWriteShimOperation = exports.FindOperators = exports.MongoBulkWriteError = exports.WriteError = exports.WriteConcernError = exports.BulkWriteResult = exports.Batch = exports.BatchType = void 0;
exports.BulkOperationBase = exports.FindOperators = exports.MongoBulkWriteError = exports.WriteError = exports.WriteConcernError = exports.BulkWriteResult = exports.Batch = exports.BatchType = void 0;
exports.mergeBatchResults = mergeBatchResults;

@@ -10,4 +10,4 @@ const bson_1 = require("../bson");

const insert_1 = require("../operations/insert");
const operation_1 = require("../operations/operation");
const update_1 = require("../operations/update");
const timeout_1 = require("../timeout");
const utils_1 = require("../utils");

@@ -499,29 +499,2 @@ const write_concern_1 = require("../write_concern");

exports.FindOperators = FindOperators;
/**
* TODO(NODE-4063)
* BulkWrites merge complexity is implemented in executeCommands
* This provides a vehicle to treat bulkOperations like any other operation (hence "shim")
* We would like this logic to simply live inside the BulkWriteOperation class
* @internal
*/
class BulkWriteShimOperation extends operation_1.AbstractOperation {
constructor(bulkOperation, options) {
super(options);
this.bulkOperation = bulkOperation;
}
get commandName() {
return 'bulkWrite';
}
async execute(_server, session, timeoutContext) {
if (this.options.session == null) {
// An implicit session could have been created by 'executeOperation'
// So if we stick it on finalOptions here, each bulk operation
// will use this same session, it'll be passed in the same way
// an explicit session would be
this.options.session = session;
}
return await executeCommands(this.bulkOperation, { ...this.options, timeoutContext });
}
}
exports.BulkWriteShimOperation = BulkWriteShimOperation;
/** @public */

@@ -806,5 +779,19 @@ class BulkOperationBase {

this.s.executed = true;
const finalOptions = { ...this.s.options, ...options };
const operation = new BulkWriteShimOperation(this, finalOptions);
return await (0, execute_operation_1.executeOperation)(this.s.collection.client, operation, finalOptions.timeoutContext);
const finalOptions = (0, utils_1.resolveOptions)(this.collection, { ...this.s.options, ...options });
// if there is no timeoutContext provided, create a timeoutContext and use it for
// all batches in the bulk operation
finalOptions.timeoutContext ??= timeout_1.TimeoutContext.create({
session: finalOptions.session,
timeoutMS: finalOptions.timeoutMS,
serverSelectionTimeoutMS: this.collection.client.s.options.serverSelectionTimeoutMS,
waitQueueTimeoutMS: this.collection.client.s.options.waitQueueTimeoutMS
});
if (finalOptions.session == null) {
// if there is not an explicit session provided to `execute()`, create
// an implicit session and use that for all batches in the bulk operation
return await this.collection.client.withSession({ explicit: false }, async (session) => {
return await executeCommands(this, { ...finalOptions, session });
});
}
return await executeCommands(this, { ...finalOptions });
}

@@ -811,0 +798,0 @@ /**

@@ -13,3 +13,2 @@ "use strict";

const error_1 = require("./error");
const bulk_write_1 = require("./operations/bulk_write");
const count_1 = require("./operations/count");

@@ -24,4 +23,2 @@ const delete_1 = require("./operations/delete");

const insert_1 = require("./operations/insert");
const is_capped_1 = require("./operations/is_capped");
const options_operation_1 = require("./operations/options_operation");
const rename_1 = require("./operations/rename");

@@ -170,3 +167,21 @@ const create_1 = require("./operations/search_indexes/create");

async insertMany(docs, options) {
return await (0, execute_operation_1.executeOperation)(this.client, new insert_1.InsertManyOperation(this, docs, (0, utils_1.resolveOptions)(this, options ?? { ordered: true })));
if (!Array.isArray(docs)) {
throw new error_1.MongoInvalidArgumentError('Argument "docs" must be an array of documents');
}
options = (0, utils_1.resolveOptions)(this, options ?? {});
const acknowledged = write_concern_1.WriteConcern.fromOptions(options)?.w !== 0;
try {
const res = await this.bulkWrite(docs.map(doc => ({ insertOne: { document: doc } })), options);
return {
acknowledged,
insertedCount: res.insertedCount,
insertedIds: res.insertedIds
};
}
catch (err) {
if (err && err.message === 'Operation must be an object with an operation key') {
throw new error_1.MongoInvalidArgumentError('Collection.insertMany() cannot be called with an array that has null/undefined values');
}
throw err;
}
}

@@ -196,3 +211,19 @@ /**

}
return await (0, execute_operation_1.executeOperation)(this.client, new bulk_write_1.BulkWriteOperation(this, operations, (0, utils_1.resolveOptions)(this, options ?? { ordered: true })));
options = (0, utils_1.resolveOptions)(this, options ?? {});
// TODO(NODE-7071): remove once the client doesn't need to be connected to construct
// bulk operations
const isConnected = this.client.topology != null;
if (!isConnected) {
await (0, execute_operation_1.autoConnect)(this.client);
}
// Create the bulk operation
const bulk = options.ordered === false
? this.initializeUnorderedBulkOp(options)
: this.initializeOrderedBulkOp(options);
// for each op go through and add to the bulk
for (const operation of operations) {
bulk.raw(operation);
}
// Execute the bulk
return await bulk.execute({ ...options });
}

@@ -294,3 +325,10 @@ /**

async options(options) {
return await (0, execute_operation_1.executeOperation)(this.client, new options_operation_1.OptionsOperation(this, (0, utils_1.resolveOptions)(this, options)));
options = (0, utils_1.resolveOptions)(this, options);
const [collection] = await this.s.db
.listCollections({ name: this.collectionName }, { ...options, nameOnly: false })
.toArray();
if (collection == null || collection.options == null) {
throw new error_1.MongoAPIError(`collection ${this.namespace} not found`);
}
return collection.options;
}

@@ -303,3 +341,4 @@ /**

async isCapped(options) {
return await (0, execute_operation_1.executeOperation)(this.client, new is_capped_1.IsCappedOperation(this, (0, utils_1.resolveOptions)(this, options)));
const { capped } = await this.options(options);
return Boolean(capped);
}

@@ -306,0 +345,0 @@ /**

@@ -13,3 +13,2 @@ "use strict";

const error_1 = require("./error");
const collections_1 = require("./operations/collections");
const create_collection_1 = require("./operations/create_collection");

@@ -277,3 +276,9 @@ const drop_1 = require("./operations/drop");

async collections(options) {
return await (0, execute_operation_1.executeOperation)(this.client, new collections_1.CollectionsOperation(this, (0, utils_1.resolveOptions)(this, options)));
options = (0, utils_1.resolveOptions)(this, options);
const collections = await this.listCollections({}, { ...options, nameOnly: true }).toArray();
return collections
.filter(
// Filter collections removing any illegal ones
({ name }) => !name.includes('$'))
.map(({ name }) => new collection_1.Collection(this, name, this.s.options));
}

@@ -280,0 +285,0 @@ /**

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeOperation = executeOperation;
exports.autoConnect = autoConnect;
const error_1 = require("../error");

@@ -5,0 +6,0 @@ const read_preference_1 = require("../read_preference");

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InsertManyOperation = exports.InsertOneOperation = exports.InsertOperation = void 0;
exports.InsertOneOperation = exports.InsertOperation = void 0;
const error_1 = require("../error");
const utils_1 = require("../utils");
const write_concern_1 = require("../write_concern");
const bulk_write_1 = require("./bulk_write");
const command_1 = require("./command");

@@ -43,3 +41,3 @@ const operation_1 = require("./operation");

constructor(collection, doc, options) {
super(collection.s.namespace, (0, utils_1.maybeAddIdToDocuments)(collection, [doc], options), options);
super(collection.s.namespace, [(0, utils_1.maybeAddIdToDocuments)(collection, doc, options)], options);
}

@@ -61,43 +59,4 @@ async execute(server, session, timeoutContext) {

exports.InsertOneOperation = InsertOneOperation;
/** @internal */
class InsertManyOperation extends operation_1.AbstractOperation {
constructor(collection, docs, options) {
super(options);
if (!Array.isArray(docs)) {
throw new error_1.MongoInvalidArgumentError('Argument "docs" must be an array of documents');
}
this.options = options;
this.collection = collection;
this.docs = docs;
}
get commandName() {
return 'insert';
}
async execute(server, session, timeoutContext) {
const coll = this.collection;
const options = { ...this.options, ...this.bsonOptions, readPreference: this.readPreference };
const writeConcern = write_concern_1.WriteConcern.fromOptions(options);
const bulkWriteOperation = new bulk_write_1.BulkWriteOperation(coll, this.docs.map(document => ({
insertOne: { document }
})), options);
try {
const res = await bulkWriteOperation.execute(server, session, timeoutContext);
return {
acknowledged: writeConcern?.w !== 0,
insertedCount: res.insertedCount,
insertedIds: res.insertedIds
};
}
catch (err) {
if (err && err.message === 'Operation must be an object with an operation key') {
throw new error_1.MongoInvalidArgumentError('Collection.insertMany() cannot be called with an array that has null/undefined values');
}
throw err;
}
}
}
exports.InsertManyOperation = InsertManyOperation;
(0, operation_1.defineAspects)(InsertOperation, [operation_1.Aspect.RETRYABLE, operation_1.Aspect.WRITE_OPERATION]);
(0, operation_1.defineAspects)(InsertOneOperation, [operation_1.Aspect.RETRYABLE, operation_1.Aspect.WRITE_OPERATION]);
(0, operation_1.defineAspects)(InsertManyOperation, [operation_1.Aspect.WRITE_OPERATION]);
//# sourceMappingURL=insert.js.map

@@ -1079,17 +1079,12 @@ "use strict";

}
function maybeAddIdToDocuments(coll, docOrDocs, options) {
const forceServerObjectId = typeof options.forceServerObjectId === 'boolean'
? options.forceServerObjectId
: coll.s.db.options?.forceServerObjectId;
function maybeAddIdToDocuments(collection, document, options) {
const forceServerObjectId = options.forceServerObjectId ?? collection.s.db.options?.forceServerObjectId ?? false;
// no need to modify the docs if server sets the ObjectId
if (forceServerObjectId === true) {
return docOrDocs;
if (forceServerObjectId) {
return document;
}
const transform = (doc) => {
if (doc._id == null) {
doc._id = coll.s.pkFactory.createPk();
}
return doc;
};
return Array.isArray(docOrDocs) ? docOrDocs.map(transform) : transform(docOrDocs);
if (document._id == null) {
document._id = collection.s.pkFactory.createPk();
}
return document;
}

@@ -1096,0 +1091,0 @@ async function fileIsAccessible(fileName, mode) {

{
"name": "mongodb",
"version": "6.18.0-dev.20250730.sha.2ef6c10c",
"version": "6.18.0-dev.20250731.sha.c5365347",
"description": "The official MongoDB driver for Node.js",

@@ -97,3 +97,3 @@ "main": "lib/index.js",

"js-yaml": "^4.1.0",
"mocha": "^10.8.2",
"mocha": "^11.7.1",
"mocha-sinon": "^2.1.2",

@@ -100,0 +100,0 @@ "mongodb-client-encryption": "^6.4.0",

@@ -17,9 +17,7 @@ import { type BSONSerializeOptions, type Document, EJSON, resolveBSONOptions } from '../bson';

import { InsertOperation } from '../operations/insert';
import { AbstractOperation, type Hint } from '../operations/operation';
import { type Hint } from '../operations/operation';
import { makeUpdateStatement, UpdateOperation, type UpdateStatement } from '../operations/update';
import type { Server } from '../sdam/server';
import type { Topology } from '../sdam/topology';
import type { ClientSession } from '../sessions';
import { type Sort } from '../sort';
import { type TimeoutContext } from '../timeout';
import { TimeoutContext } from '../timeout';
import {

@@ -858,36 +856,2 @@ applyRetryableWrites,

/**
* TODO(NODE-4063)
* BulkWrites merge complexity is implemented in executeCommands
* This provides a vehicle to treat bulkOperations like any other operation (hence "shim")
* We would like this logic to simply live inside the BulkWriteOperation class
* @internal
*/
export class BulkWriteShimOperation extends AbstractOperation {
bulkOperation: BulkOperationBase;
constructor(bulkOperation: BulkOperationBase, options: BulkWriteOptions) {
super(options);
this.bulkOperation = bulkOperation;
}
get commandName(): string {
return 'bulkWrite' as const;
}
async execute(
_server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<any> {
if (this.options.session == null) {
// An implicit session could have been created by 'executeOperation'
// So if we stick it on finalOptions here, each bulk operation
// will use this same session, it'll be passed in the same way
// an explicit session would be
this.options.session = session;
}
return await executeCommands(this.bulkOperation, { ...this.options, timeoutContext });
}
}
/** @public */

@@ -1213,6 +1177,22 @@ export abstract class BulkOperationBase {

this.s.executed = true;
const finalOptions = { ...this.s.options, ...options };
const operation = new BulkWriteShimOperation(this, finalOptions);
const finalOptions = resolveOptions(this.collection, { ...this.s.options, ...options });
return await executeOperation(this.s.collection.client, operation, finalOptions.timeoutContext);
// if there is no timeoutContext provided, create a timeoutContext and use it for
// all batches in the bulk operation
finalOptions.timeoutContext ??= TimeoutContext.create({
session: finalOptions.session,
timeoutMS: finalOptions.timeoutMS,
serverSelectionTimeoutMS: this.collection.client.s.options.serverSelectionTimeoutMS,
waitQueueTimeoutMS: this.collection.client.s.options.waitQueueTimeoutMS
});
if (finalOptions.session == null) {
// if there is not an explicit session provided to `execute()`, create
// an implicit session and use that for all batches in the bulk operation
return await this.collection.client.withSession({ explicit: false }, async session => {
return await executeCommands(this, { ...finalOptions, session });
});
}
return await executeCommands(this, { ...finalOptions });
}

@@ -1219,0 +1199,0 @@

import { type BSONSerializeOptions, type Document, resolveBSONOptions } from './bson';
import type { AnyBulkWriteOperation, BulkWriteOptions, BulkWriteResult } from './bulk/common';
import type {
AnyBulkWriteOperation,
BulkOperationBase,
BulkWriteOptions,
BulkWriteResult
} from './bulk/common';
import { OrderedBulkOperation } from './bulk/ordered';

@@ -14,3 +19,3 @@ import { UnorderedBulkOperation } from './bulk/unordered';

import type { Db } from './db';
import { MongoInvalidArgumentError, MongoOperationTimeoutError } from './error';
import { MongoAPIError, MongoInvalidArgumentError, MongoOperationTimeoutError } from './error';
import type { MongoClient, PkFactory } from './mongo_client';

@@ -28,3 +33,2 @@ import type {

import type { AggregateOptions } from './operations/aggregate';
import { BulkWriteOperation } from './operations/bulk_write';
import { CountOperation, type CountOptions } from './operations/count';

@@ -43,3 +47,3 @@ import {

} from './operations/estimated_document_count';
import { executeOperation } from './operations/execute_operation';
import { autoConnect, executeOperation } from './operations/execute_operation';
import type { FindOptions } from './operations/find';

@@ -67,3 +71,2 @@ import {

import {
InsertManyOperation,
type InsertManyResult,

@@ -74,5 +77,3 @@ InsertOneOperation,

} from './operations/insert';
import { IsCappedOperation } from './operations/is_capped';
import type { Hint, OperationOptions } from './operations/operation';
import { OptionsOperation } from './operations/options_operation';
import { RenameOperation, type RenameOptions } from './operations/rename';

@@ -313,10 +314,27 @@ import {

): Promise<InsertManyResult<TSchema>> {
return await executeOperation(
this.client,
new InsertManyOperation(
this as TODO_NODE_3286,
docs,
resolveOptions(this, options ?? { ordered: true })
) as TODO_NODE_3286
);
if (!Array.isArray(docs)) {
throw new MongoInvalidArgumentError('Argument "docs" must be an array of documents');
}
options = resolveOptions(this, options ?? {});
const acknowledged = WriteConcern.fromOptions(options)?.w !== 0;
try {
const res = await this.bulkWrite(
docs.map(doc => ({ insertOne: { document: doc } })),
options
);
return {
acknowledged,
insertedCount: res.insertedCount,
insertedIds: res.insertedIds
};
} catch (err) {
if (err && err.message === 'Operation must be an object with an operation key') {
throw new MongoInvalidArgumentError(
'Collection.insertMany() cannot be called with an array that has null/undefined values'
);
}
throw err;
}
}

@@ -351,10 +369,24 @@

return await executeOperation(
this.client,
new BulkWriteOperation(
this as TODO_NODE_3286,
operations,
resolveOptions(this, options ?? { ordered: true })
)
);
options = resolveOptions(this, options ?? {});
// TODO(NODE-7071): remove once the client doesn't need to be connected to construct
// bulk operations
const isConnected = this.client.topology != null;
if (!isConnected) {
await autoConnect(this.client);
}
// Create the bulk operation
const bulk: BulkOperationBase =
options.ordered === false
? this.initializeUnorderedBulkOp(options)
: this.initializeOrderedBulkOp(options);
// for each op go through and add to the bulk
for (const operation of operations) {
bulk.raw(operation);
}
// Execute the bulk
return await bulk.execute({ ...options });
}

@@ -567,6 +599,12 @@

async options(options?: OperationOptions): Promise<Document> {
return await executeOperation(
this.client,
new OptionsOperation(this as TODO_NODE_3286, resolveOptions(this, options))
);
options = resolveOptions(this, options);
const [collection] = await this.s.db
.listCollections({ name: this.collectionName }, { ...options, nameOnly: false })
.toArray();
if (collection == null || collection.options == null) {
throw new MongoAPIError(`collection ${this.namespace} not found`);
}
return collection.options;
}

@@ -580,6 +618,4 @@

async isCapped(options?: OperationOptions): Promise<boolean> {
return await executeOperation(
this.client,
new IsCappedOperation(this as TODO_NODE_3286, resolveOptions(this, options))
);
const { capped } = await this.options(options);
return Boolean(capped);
}

@@ -586,0 +622,0 @@

@@ -13,3 +13,2 @@ import { Admin } from './admin';

import type { AggregateOptions } from './operations/aggregate';
import { CollectionsOperation } from './operations/collections';
import {

@@ -439,6 +438,11 @@ CreateCollectionOperation,

async collections(options?: ListCollectionsOptions): Promise<Collection[]> {
return await executeOperation(
this.client,
new CollectionsOperation(this, resolveOptions(this, options))
);
options = resolveOptions(this, options);
const collections = await this.listCollections({}, { ...options, nameOnly: true }).toArray();
return collections
.filter(
// Filter collections removing any illegal ones
({ name }) => !name.includes('$')
)
.map(({ name }) => new Collection(this, name, this.s.options));
}

@@ -445,0 +449,0 @@

@@ -132,3 +132,3 @@ import {

*/
async function autoConnect(client: MongoClient): Promise<Topology> {
export async function autoConnect(client: MongoClient): Promise<Topology> {
if (client.topology == null) {

@@ -135,0 +135,0 @@ if (client.s.hasBeenClosed) {

import type { Document } from '../bson';
import type { BulkWriteOptions } from '../bulk/common';
import type { Collection } from '../collection';
import { MongoInvalidArgumentError, MongoServerError } from '../error';
import { MongoServerError } from '../error';
import type { InferIdType } from '../mongo_types';

@@ -10,6 +10,4 @@ import type { Server } from '../sdam/server';

import { maybeAddIdToDocuments, type MongoDBNamespace } from '../utils';
import { WriteConcern } from '../write_concern';
import { BulkWriteOperation } from './bulk_write';
import { CommandOperation, type CommandOperationOptions } from './command';
import { AbstractOperation, Aspect, defineAspects } from './operation';
import { Aspect, defineAspects } from './operation';

@@ -77,3 +75,3 @@ /** @internal */

constructor(collection: Collection, doc: Document, options: InsertOneOptions) {
super(collection.s.namespace, maybeAddIdToDocuments(collection, [doc], options), options);
super(collection.s.namespace, [maybeAddIdToDocuments(collection, doc, options)], options);
}

@@ -110,60 +108,3 @@

/** @internal */
export class InsertManyOperation extends AbstractOperation<InsertManyResult> {
override options: BulkWriteOptions;
collection: Collection;
docs: ReadonlyArray<Document>;
constructor(collection: Collection, docs: ReadonlyArray<Document>, options: BulkWriteOptions) {
super(options);
if (!Array.isArray(docs)) {
throw new MongoInvalidArgumentError('Argument "docs" must be an array of documents');
}
this.options = options;
this.collection = collection;
this.docs = docs;
}
override get commandName() {
return 'insert' as const;
}
override async execute(
server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<InsertManyResult> {
const coll = this.collection;
const options = { ...this.options, ...this.bsonOptions, readPreference: this.readPreference };
const writeConcern = WriteConcern.fromOptions(options);
const bulkWriteOperation = new BulkWriteOperation(
coll,
this.docs.map(document => ({
insertOne: { document }
})),
options
);
try {
const res = await bulkWriteOperation.execute(server, session, timeoutContext);
return {
acknowledged: writeConcern?.w !== 0,
insertedCount: res.insertedCount,
insertedIds: res.insertedIds
};
} catch (err) {
if (err && err.message === 'Operation must be an object with an operation key') {
throw new MongoInvalidArgumentError(
'Collection.insertMany() cannot be called with an array that has null/undefined values'
);
}
throw err;
}
}
}
defineAspects(InsertOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
defineAspects(InsertOneOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
defineAspects(InsertManyOperation, [Aspect.WRITE_OPERATION]);

@@ -1360,34 +1360,19 @@ import * as crypto from 'crypto';

export function maybeAddIdToDocuments(
coll: Collection,
docs: Document[],
collection: Collection,
document: Document,
options: { forceServerObjectId?: boolean }
): Document[];
export function maybeAddIdToDocuments(
coll: Collection,
docs: Document,
options: { forceServerObjectId?: boolean }
): Document;
export function maybeAddIdToDocuments(
coll: Collection,
docOrDocs: Document[] | Document,
options: { forceServerObjectId?: boolean }
): Document[] | Document {
): Document {
const forceServerObjectId =
typeof options.forceServerObjectId === 'boolean'
? options.forceServerObjectId
: coll.s.db.options?.forceServerObjectId;
options.forceServerObjectId ?? collection.s.db.options?.forceServerObjectId ?? false;
// no need to modify the docs if server sets the ObjectId
if (forceServerObjectId === true) {
return docOrDocs;
if (forceServerObjectId) {
return document;
}
const transform = (doc: Document): Document => {
if (doc._id == null) {
doc._id = coll.s.pkFactory.createPk();
}
if (document._id == null) {
document._id = collection.s.pkFactory.createPk();
}
return doc;
};
return Array.isArray(docOrDocs) ? docOrDocs.map(transform) : transform(docOrDocs);
return document;
}

@@ -1394,0 +1379,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.