mongodb 6.7.0-dev.20240613.sha.c1af6adc → 6.7.0-dev.20240614.sha.3ed6a2ad
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/lib/bson.js.map +1 -1
- package/lib/client-side-encryption/auto_encrypter.js +8 -61
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js +5 -5
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/client-side-encryption/state_machine.js +15 -11
- package/lib/client-side-encryption/state_machine.js.map +1 -1
- package/lib/cmap/connection.js +22 -20
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/wire_protocol/on_demand/document.js +8 -5
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
- package/lib/cmap/wire_protocol/responses.js +116 -40
- package/lib/cmap/wire_protocol/responses.js.map +1 -1
- package/lib/constants.js +9 -1
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +24 -60
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +2 -3
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/change_stream_cursor.js +6 -8
- package/lib/cursor/change_stream_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +5 -17
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/cursor/list_collections_cursor.js +0 -1
- package/lib/cursor/list_collections_cursor.js.map +1 -1
- package/lib/cursor/list_indexes_cursor.js +0 -1
- package/lib/cursor/list_indexes_cursor.js.map +1 -1
- package/lib/cursor/run_command_cursor.js +4 -6
- package/lib/cursor/run_command_cursor.js.map +1 -1
- package/lib/error.js +6 -21
- package/lib/error.js.map +1 -1
- package/lib/operations/aggregate.js +2 -2
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js +1 -2
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/command.js +2 -3
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/count_documents.js +1 -7
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +2 -1
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/get_more.js +1 -1
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +2 -1
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/list_collections.js +2 -1
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/run_command.js +1 -1
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/update.js +2 -1
- package/lib/operations/update.js.map +1 -1
- package/lib/sdam/server.js +7 -2
- package/lib/sdam/server.js.map +1 -1
- package/lib/utils.js +45 -1
- package/lib/utils.js.map +1 -1
- package/lib/write_concern.js +17 -1
- package/lib/write_concern.js.map +1 -1
- package/mongodb.d.ts +17 -8
- package/package.json +1 -1
- package/src/bson.ts +1 -0
- package/src/client-side-encryption/auto_encrypter.ts +9 -70
- package/src/client-side-encryption/client_encryption.ts +6 -6
- package/src/client-side-encryption/state_machine.ts +18 -16
- package/src/cmap/connection.ts +46 -50
- package/src/cmap/wire_protocol/on_demand/document.ts +13 -6
- package/src/cmap/wire_protocol/responses.ts +140 -45
- package/src/constants.ts +9 -0
- package/src/cursor/abstract_cursor.ts +51 -71
- package/src/cursor/aggregation_cursor.ts +13 -12
- package/src/cursor/change_stream_cursor.ts +20 -34
- package/src/cursor/find_cursor.ts +17 -25
- package/src/cursor/list_collections_cursor.ts +3 -4
- package/src/cursor/list_indexes_cursor.ts +3 -4
- package/src/cursor/run_command_cursor.ts +13 -19
- package/src/error.ts +16 -28
- package/src/index.ts +6 -7
- package/src/operations/aggregate.ts +12 -5
- package/src/operations/bulk_write.ts +1 -2
- package/src/operations/command.ts +17 -3
- package/src/operations/count_documents.ts +7 -11
- package/src/operations/delete.ts +2 -2
- package/src/operations/execute_operation.ts +0 -13
- package/src/operations/find.ts +7 -3
- package/src/operations/find_and_modify.ts +1 -1
- package/src/operations/get_more.ts +6 -10
- package/src/operations/indexes.ts +7 -3
- package/src/operations/list_collections.ts +8 -3
- package/src/operations/run_command.ts +16 -6
- package/src/operations/update.ts +2 -1
- package/src/sdam/server.ts +7 -2
- package/src/utils.ts +52 -2
- package/src/write_concern.ts +18 -0
package/src/error.ts
CHANGED
|
@@ -750,8 +750,8 @@ export class MongoUnexpectedServerResponseError extends MongoRuntimeError {
|
|
|
750
750
|
*
|
|
751
751
|
* @public
|
|
752
752
|
**/
|
|
753
|
-
constructor(message: string) {
|
|
754
|
-
super(message);
|
|
753
|
+
constructor(message: string, options?: { cause?: Error }) {
|
|
754
|
+
super(message, options);
|
|
755
755
|
}
|
|
756
756
|
|
|
757
757
|
override get name(): string {
|
|
@@ -1157,27 +1157,14 @@ export class MongoServerSelectionError extends MongoSystemError {
|
|
|
1157
1157
|
}
|
|
1158
1158
|
}
|
|
1159
1159
|
|
|
1160
|
-
function makeWriteConcernResultObject(input: any) {
|
|
1161
|
-
const output = Object.assign({}, input);
|
|
1162
|
-
|
|
1163
|
-
if (output.ok === 0) {
|
|
1164
|
-
output.ok = 1;
|
|
1165
|
-
delete output.errmsg;
|
|
1166
|
-
delete output.code;
|
|
1167
|
-
delete output.codeName;
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
return output;
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
1160
|
/**
|
|
1174
1161
|
* An error thrown when the server reports a writeConcernError
|
|
1175
1162
|
* @public
|
|
1176
1163
|
* @category Error
|
|
1177
1164
|
*/
|
|
1178
1165
|
export class MongoWriteConcernError extends MongoServerError {
|
|
1179
|
-
/** The result document
|
|
1180
|
-
result
|
|
1166
|
+
/** The result document */
|
|
1167
|
+
result: Document;
|
|
1181
1168
|
|
|
1182
1169
|
/**
|
|
1183
1170
|
* **Do not use this constructor!**
|
|
@@ -1190,17 +1177,18 @@ export class MongoWriteConcernError extends MongoServerError {
|
|
|
1190
1177
|
*
|
|
1191
1178
|
* @public
|
|
1192
1179
|
**/
|
|
1193
|
-
constructor(
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1180
|
+
constructor(result: {
|
|
1181
|
+
writeConcernError: {
|
|
1182
|
+
code: number;
|
|
1183
|
+
errmsg: string;
|
|
1184
|
+
codeName?: string;
|
|
1185
|
+
errInfo?: Document;
|
|
1186
|
+
};
|
|
1187
|
+
errorLabels?: string[];
|
|
1188
|
+
}) {
|
|
1189
|
+
super({ ...result, ...result.writeConcernError });
|
|
1190
|
+
this.errInfo = result.writeConcernError.errInfo;
|
|
1191
|
+
this.result = result;
|
|
1204
1192
|
}
|
|
1205
1193
|
|
|
1206
1194
|
override get name(): string {
|
package/src/index.ts
CHANGED
|
@@ -160,7 +160,7 @@ export { SrvPollingEvent } from './sdam/srv_polling';
|
|
|
160
160
|
|
|
161
161
|
// type only exports below, these are removed from emitted JS
|
|
162
162
|
export type { AdminPrivate } from './admin';
|
|
163
|
-
export type { BSONSerializeOptions, Document } from './bson';
|
|
163
|
+
export type { BSONElement, BSONSerializeOptions, Document } from './bson';
|
|
164
164
|
export type { deserialize, serialize } from './bson';
|
|
165
165
|
export type {
|
|
166
166
|
BulkResult,
|
|
@@ -342,12 +342,12 @@ export type {
|
|
|
342
342
|
CursorFlag,
|
|
343
343
|
CursorStreamOptions
|
|
344
344
|
} from './cursor/abstract_cursor';
|
|
345
|
-
export type { InternalAbstractCursorOptions } from './cursor/abstract_cursor';
|
|
346
|
-
export type { AggregationCursorOptions } from './cursor/aggregation_cursor';
|
|
347
345
|
export type {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
} from './cursor/
|
|
346
|
+
InitialCursorResponse,
|
|
347
|
+
InternalAbstractCursorOptions
|
|
348
|
+
} from './cursor/abstract_cursor';
|
|
349
|
+
export type { AggregationCursorOptions } from './cursor/aggregation_cursor';
|
|
350
|
+
export type { ChangeStreamCursorOptions } from './cursor/change_stream_cursor';
|
|
351
351
|
export type {
|
|
352
352
|
ListSearchIndexesCursor,
|
|
353
353
|
ListSearchIndexesOptions
|
|
@@ -473,7 +473,6 @@ export type { DeleteOptions, DeleteResult, DeleteStatement } from './operations/
|
|
|
473
473
|
export type { DistinctOptions } from './operations/distinct';
|
|
474
474
|
export type { DropCollectionOptions, DropDatabaseOptions } from './operations/drop';
|
|
475
475
|
export type { EstimatedDocumentCountOptions } from './operations/estimated_document_count';
|
|
476
|
-
export type { ExecutionResult } from './operations/execute_operation';
|
|
477
476
|
export type { FindOptions } from './operations/find';
|
|
478
477
|
export type {
|
|
479
478
|
FindOneAndDeleteOptions,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Document } from '../bson';
|
|
2
|
+
import { CursorResponse, ExplainedCursorResponse } from '../cmap/wire_protocol/responses';
|
|
2
3
|
import { MongoInvalidArgumentError } from '../error';
|
|
3
|
-
import { type TODO_NODE_3286 } from '../mongo_types';
|
|
4
4
|
import type { Server } from '../sdam/server';
|
|
5
5
|
import type { ClientSession } from '../sessions';
|
|
6
6
|
import { maxWireVersion, type MongoDBNamespace } from '../utils';
|
|
@@ -37,7 +37,7 @@ export interface AggregateOptions extends CommandOperationOptions {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/** @internal */
|
|
40
|
-
export class AggregateOperation
|
|
40
|
+
export class AggregateOperation extends CommandOperation<CursorResponse> {
|
|
41
41
|
override options: AggregateOptions;
|
|
42
42
|
target: string | typeof DB_AGGREGATE_COLLECTION;
|
|
43
43
|
pipeline: Document[];
|
|
@@ -94,7 +94,10 @@ export class AggregateOperation<T = Document> extends CommandOperation<T> {
|
|
|
94
94
|
this.pipeline.push(stage);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
override async execute(
|
|
97
|
+
override async execute(
|
|
98
|
+
server: Server,
|
|
99
|
+
session: ClientSession | undefined
|
|
100
|
+
): Promise<CursorResponse> {
|
|
98
101
|
const options: AggregateOptions = this.options;
|
|
99
102
|
const serverWireVersion = maxWireVersion(server);
|
|
100
103
|
const command: Document = { aggregate: this.target, pipeline: this.pipeline };
|
|
@@ -134,8 +137,12 @@ export class AggregateOperation<T = Document> extends CommandOperation<T> {
|
|
|
134
137
|
command.cursor.batchSize = options.batchSize;
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
return await super.executeCommand(
|
|
141
|
+
server,
|
|
142
|
+
session,
|
|
143
|
+
command,
|
|
144
|
+
this.explain ? ExplainedCursorResponse : CursorResponse
|
|
145
|
+
);
|
|
139
146
|
}
|
|
140
147
|
}
|
|
141
148
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BSONSerializeOptions, Document } from '../bson';
|
|
2
|
+
import { type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses';
|
|
2
3
|
import { MongoInvalidArgumentError } from '../error';
|
|
3
4
|
import { Explain, type ExplainOptions } from '../explain';
|
|
4
5
|
import { ReadConcern } from '../read_concern';
|
|
@@ -106,12 +107,25 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
|
|
|
106
107
|
return true;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
async executeCommand(
|
|
110
|
+
public async executeCommand<T extends MongoDBResponseConstructor>(
|
|
111
|
+
server: Server,
|
|
112
|
+
session: ClientSession | undefined,
|
|
113
|
+
cmd: Document,
|
|
114
|
+
responseType: T | undefined
|
|
115
|
+
): Promise<typeof responseType extends undefined ? Document : InstanceType<T>>;
|
|
116
|
+
|
|
117
|
+
public async executeCommand(
|
|
110
118
|
server: Server,
|
|
111
119
|
session: ClientSession | undefined,
|
|
112
120
|
cmd: Document
|
|
121
|
+
): Promise<Document>;
|
|
122
|
+
|
|
123
|
+
async executeCommand(
|
|
124
|
+
server: Server,
|
|
125
|
+
session: ClientSession | undefined,
|
|
126
|
+
cmd: Document,
|
|
127
|
+
responseType?: MongoDBResponseConstructor
|
|
113
128
|
): Promise<Document> {
|
|
114
|
-
// TODO: consider making this a non-enumerable property
|
|
115
129
|
this.server = server;
|
|
116
130
|
|
|
117
131
|
const options = {
|
|
@@ -152,6 +166,6 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
|
|
|
152
166
|
cmd = decorateWithExplain(cmd, this.explain);
|
|
153
167
|
}
|
|
154
168
|
|
|
155
|
-
return await server.command(this.ns, cmd, options);
|
|
169
|
+
return await server.command(this.ns, cmd, options, responseType);
|
|
156
170
|
}
|
|
157
171
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Document } from '../bson';
|
|
2
2
|
import type { Collection } from '../collection';
|
|
3
|
+
import { type TODO_NODE_3286 } from '../mongo_types';
|
|
3
4
|
import type { Server } from '../sdam/server';
|
|
4
5
|
import type { ClientSession } from '../sessions';
|
|
5
6
|
import { AggregateOperation, type AggregateOptions } from './aggregate';
|
|
@@ -13,7 +14,7 @@ export interface CountDocumentsOptions extends AggregateOptions {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/** @internal */
|
|
16
|
-
export class CountDocumentsOperation extends AggregateOperation
|
|
17
|
+
export class CountDocumentsOperation extends AggregateOperation {
|
|
17
18
|
constructor(collection: Collection, query: Document, options: CountDocumentsOptions) {
|
|
18
19
|
const pipeline = [];
|
|
19
20
|
pipeline.push({ $match: query });
|
|
@@ -31,16 +32,11 @@ export class CountDocumentsOperation extends AggregateOperation<number> {
|
|
|
31
32
|
super(collection.s.namespace, pipeline, options);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
override async execute(
|
|
35
|
+
override async execute(
|
|
36
|
+
server: Server,
|
|
37
|
+
session: ClientSession | undefined
|
|
38
|
+
): Promise<TODO_NODE_3286> {
|
|
35
39
|
const result = await super.execute(server, session);
|
|
36
|
-
|
|
37
|
-
// NOTE: We're avoiding creating a cursor here to reduce the callstack.
|
|
38
|
-
const response = result as unknown as Document;
|
|
39
|
-
if (response.cursor == null || response.cursor.firstBatch == null) {
|
|
40
|
-
return 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const docs = response.cursor.firstBatch;
|
|
44
|
-
return docs.length ? docs[0].n : 0;
|
|
40
|
+
return result.shift()?.n ?? 0;
|
|
45
41
|
}
|
|
46
42
|
}
|
package/src/operations/delete.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { MongoCompatibilityError, MongoServerError } from '../error';
|
|
|
4
4
|
import { type TODO_NODE_3286 } from '../mongo_types';
|
|
5
5
|
import type { Server } from '../sdam/server';
|
|
6
6
|
import type { ClientSession } from '../sessions';
|
|
7
|
-
import type
|
|
8
|
-
import type
|
|
7
|
+
import { type MongoDBNamespace } from '../utils';
|
|
8
|
+
import { type WriteConcernOptions } from '../write_concern';
|
|
9
9
|
import { type CollationOptions, CommandOperation, type CommandOperationOptions } from './command';
|
|
10
10
|
import { Aspect, defineAspects, type Hint } from './operation';
|
|
11
11
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { Document } from '../bson';
|
|
2
|
-
import { type CursorResponse } from '../cmap/wire_protocol/responses';
|
|
3
1
|
import {
|
|
4
2
|
isRetryableReadError,
|
|
5
3
|
isRetryableWriteError,
|
|
@@ -18,7 +16,6 @@ import {
|
|
|
18
16
|
} from '../error';
|
|
19
17
|
import type { MongoClient } from '../mongo_client';
|
|
20
18
|
import { ReadPreference } from '../read_preference';
|
|
21
|
-
import type { Server } from '../sdam/server';
|
|
22
19
|
import type { ServerDescription } from '../sdam/server_description';
|
|
23
20
|
import {
|
|
24
21
|
sameServerSelector,
|
|
@@ -38,16 +35,6 @@ type ResultTypeFromOperation<TOperation> = TOperation extends AbstractOperation<
|
|
|
38
35
|
? K
|
|
39
36
|
: never;
|
|
40
37
|
|
|
41
|
-
/** @internal */
|
|
42
|
-
export interface ExecutionResult {
|
|
43
|
-
/** The server selected for the operation */
|
|
44
|
-
server: Server;
|
|
45
|
-
/** The session used for this operation, may be implicitly created */
|
|
46
|
-
session?: ClientSession;
|
|
47
|
-
/** The raw server response for the operation */
|
|
48
|
-
response: Document | CursorResponse;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
38
|
/**
|
|
52
39
|
* Executes the given operation with provided arguments.
|
|
53
40
|
* @internal
|
package/src/operations/find.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Document } from '../bson';
|
|
2
|
+
import { CursorResponse, ExplainedCursorResponse } from '../cmap/wire_protocol/responses';
|
|
2
3
|
import { MongoInvalidArgumentError } from '../error';
|
|
3
4
|
import { ReadConcern } from '../read_concern';
|
|
4
5
|
import type { Server } from '../sdam/server';
|
|
@@ -65,7 +66,7 @@ export interface FindOptions<TSchema extends Document = Document>
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/** @internal */
|
|
68
|
-
export class FindOperation extends CommandOperation<
|
|
69
|
+
export class FindOperation extends CommandOperation<CursorResponse> {
|
|
69
70
|
/**
|
|
70
71
|
* @remarks WriteConcern can still be present on the options because
|
|
71
72
|
* we inherit options from the client/db/collection. The
|
|
@@ -95,7 +96,10 @@ export class FindOperation extends CommandOperation<Document> {
|
|
|
95
96
|
return 'find' as const;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
override async execute(
|
|
99
|
+
override async execute(
|
|
100
|
+
server: Server,
|
|
101
|
+
session: ClientSession | undefined
|
|
102
|
+
): Promise<CursorResponse> {
|
|
99
103
|
this.server = server;
|
|
100
104
|
|
|
101
105
|
const options = this.options;
|
|
@@ -114,7 +118,7 @@ export class FindOperation extends CommandOperation<Document> {
|
|
|
114
118
|
documentsReturnedIn: 'firstBatch',
|
|
115
119
|
session
|
|
116
120
|
},
|
|
117
|
-
|
|
121
|
+
this.explain ? ExplainedCursorResponse : CursorResponse
|
|
118
122
|
);
|
|
119
123
|
}
|
|
120
124
|
}
|
|
@@ -6,7 +6,7 @@ import type { Server } from '../sdam/server';
|
|
|
6
6
|
import type { ClientSession } from '../sessions';
|
|
7
7
|
import { formatSort, type Sort, type SortForCmd } from '../sort';
|
|
8
8
|
import { decorateWithCollation, hasAtomicOperators, maxWireVersion } from '../utils';
|
|
9
|
-
import type
|
|
9
|
+
import { type WriteConcern, type WriteConcernSettings } from '../write_concern';
|
|
10
10
|
import { CommandOperation, type CommandOperationOptions } from './command';
|
|
11
11
|
import { Aspect, defineAspects } from './operation';
|
|
12
12
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Long } from '../bson';
|
|
2
2
|
import { CursorResponse } from '../cmap/wire_protocol/responses';
|
|
3
3
|
import { MongoRuntimeError } from '../error';
|
|
4
4
|
import type { Server } from '../sdam/server';
|
|
@@ -20,8 +20,6 @@ export interface GetMoreOptions extends OperationOptions {
|
|
|
20
20
|
maxTimeMS?: number;
|
|
21
21
|
/** TODO(NODE-4413): Address bug with maxAwaitTimeMS not being passed in from the cursor correctly */
|
|
22
22
|
maxAwaitTimeMS?: number;
|
|
23
|
-
|
|
24
|
-
useCursorResponse: boolean;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
/**
|
|
@@ -58,7 +56,10 @@ export class GetMoreOperation extends AbstractOperation {
|
|
|
58
56
|
* Although there is a server already associated with the get more operation, the signature
|
|
59
57
|
* for execute passes a server so we will just use that one.
|
|
60
58
|
*/
|
|
61
|
-
override async execute(
|
|
59
|
+
override async execute(
|
|
60
|
+
server: Server,
|
|
61
|
+
_session: ClientSession | undefined
|
|
62
|
+
): Promise<CursorResponse> {
|
|
62
63
|
if (server !== this.server) {
|
|
63
64
|
throw new MongoRuntimeError('Getmore must run on the same server operation began on');
|
|
64
65
|
}
|
|
@@ -99,12 +100,7 @@ export class GetMoreOperation extends AbstractOperation {
|
|
|
99
100
|
...this.options
|
|
100
101
|
};
|
|
101
102
|
|
|
102
|
-
return await server.command(
|
|
103
|
-
this.ns,
|
|
104
|
-
getMoreCmd,
|
|
105
|
-
commandOptions,
|
|
106
|
-
this.options.useCursorResponse ? CursorResponse : undefined
|
|
107
|
-
);
|
|
103
|
+
return await server.command(this.ns, getMoreCmd, commandOptions, CursorResponse);
|
|
108
104
|
}
|
|
109
105
|
}
|
|
110
106
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Document } from '../bson';
|
|
2
|
+
import { CursorResponse } from '../cmap/wire_protocol/responses';
|
|
2
3
|
import type { Collection } from '../collection';
|
|
3
4
|
import { type AbstractCursorOptions } from '../cursor/abstract_cursor';
|
|
4
5
|
import { MongoCompatibilityError } from '../error';
|
|
@@ -353,7 +354,7 @@ export class DropIndexOperation extends CommandOperation<Document> {
|
|
|
353
354
|
export type ListIndexesOptions = AbstractCursorOptions;
|
|
354
355
|
|
|
355
356
|
/** @internal */
|
|
356
|
-
export class ListIndexesOperation extends CommandOperation<
|
|
357
|
+
export class ListIndexesOperation extends CommandOperation<CursorResponse> {
|
|
357
358
|
/**
|
|
358
359
|
* @remarks WriteConcern can still be present on the options because
|
|
359
360
|
* we inherit options from the client/db/collection. The
|
|
@@ -376,7 +377,10 @@ export class ListIndexesOperation extends CommandOperation<Document> {
|
|
|
376
377
|
return 'listIndexes' as const;
|
|
377
378
|
}
|
|
378
379
|
|
|
379
|
-
override async execute(
|
|
380
|
+
override async execute(
|
|
381
|
+
server: Server,
|
|
382
|
+
session: ClientSession | undefined
|
|
383
|
+
): Promise<CursorResponse> {
|
|
380
384
|
const serverWireVersion = maxWireVersion(server);
|
|
381
385
|
|
|
382
386
|
const cursor = this.options.batchSize ? { batchSize: this.options.batchSize } : {};
|
|
@@ -389,7 +393,7 @@ export class ListIndexesOperation extends CommandOperation<Document> {
|
|
|
389
393
|
command.comment = this.options.comment;
|
|
390
394
|
}
|
|
391
395
|
|
|
392
|
-
return await super.executeCommand(server, session, command);
|
|
396
|
+
return await super.executeCommand(server, session, command, CursorResponse);
|
|
393
397
|
}
|
|
394
398
|
}
|
|
395
399
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Binary, Document } from '../bson';
|
|
2
|
+
import { CursorResponse } from '../cmap/wire_protocol/responses';
|
|
2
3
|
import type { Db } from '../db';
|
|
3
4
|
import type { Server } from '../sdam/server';
|
|
4
5
|
import type { ClientSession } from '../sessions';
|
|
@@ -17,7 +18,7 @@ export interface ListCollectionsOptions extends Omit<CommandOperationOptions, 'w
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/** @internal */
|
|
20
|
-
export class ListCollectionsOperation extends CommandOperation<
|
|
21
|
+
export class ListCollectionsOperation extends CommandOperation<CursorResponse> {
|
|
21
22
|
/**
|
|
22
23
|
* @remarks WriteConcern can still be present on the options because
|
|
23
24
|
* we inherit options from the client/db/collection. The
|
|
@@ -51,11 +52,15 @@ export class ListCollectionsOperation extends CommandOperation<Document> {
|
|
|
51
52
|
return 'listCollections' as const;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
override async execute(
|
|
55
|
+
override async execute(
|
|
56
|
+
server: Server,
|
|
57
|
+
session: ClientSession | undefined
|
|
58
|
+
): Promise<CursorResponse> {
|
|
55
59
|
return await super.executeCommand(
|
|
56
60
|
server,
|
|
57
61
|
session,
|
|
58
|
-
this.generateCommand(maxWireVersion(server))
|
|
62
|
+
this.generateCommand(maxWireVersion(server)),
|
|
63
|
+
CursorResponse
|
|
59
64
|
);
|
|
60
65
|
}
|
|
61
66
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BSONSerializeOptions, Document } from '../bson';
|
|
2
|
+
import { type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses';
|
|
2
3
|
import { type Db } from '../db';
|
|
3
4
|
import { type TODO_NODE_3286 } from '../mongo_types';
|
|
4
5
|
import type { ReadPreferenceLike } from '../read_preference';
|
|
@@ -17,7 +18,11 @@ export type RunCommandOptions = {
|
|
|
17
18
|
|
|
18
19
|
/** @internal */
|
|
19
20
|
export class RunCommandOperation<T = Document> extends AbstractOperation<T> {
|
|
20
|
-
constructor(
|
|
21
|
+
constructor(
|
|
22
|
+
parent: Db,
|
|
23
|
+
public command: Document,
|
|
24
|
+
public override options: RunCommandOptions & { responseType?: MongoDBResponseConstructor }
|
|
25
|
+
) {
|
|
21
26
|
super(options);
|
|
22
27
|
this.ns = parent.s.namespace.withCollection('$cmd');
|
|
23
28
|
}
|
|
@@ -28,11 +33,16 @@ export class RunCommandOperation<T = Document> extends AbstractOperation<T> {
|
|
|
28
33
|
|
|
29
34
|
override async execute(server: Server, session: ClientSession | undefined): Promise<T> {
|
|
30
35
|
this.server = server;
|
|
31
|
-
const res: TODO_NODE_3286 = await server.command(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const res: TODO_NODE_3286 = await server.command(
|
|
37
|
+
this.ns,
|
|
38
|
+
this.command,
|
|
39
|
+
{
|
|
40
|
+
...this.options,
|
|
41
|
+
readPreference: this.readPreference,
|
|
42
|
+
session
|
|
43
|
+
},
|
|
44
|
+
this.options.responseType
|
|
45
|
+
);
|
|
36
46
|
return res;
|
|
37
47
|
}
|
|
38
48
|
}
|
package/src/operations/update.ts
CHANGED
package/src/sdam/server.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
type MongoDBNamespace,
|
|
49
49
|
supportsRetryableWrites
|
|
50
50
|
} from '../utils';
|
|
51
|
+
import { throwIfWriteConcernError } from '../write_concern';
|
|
51
52
|
import {
|
|
52
53
|
type ClusterTime,
|
|
53
54
|
STATE_CLOSED,
|
|
@@ -323,7 +324,9 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
323
324
|
|
|
324
325
|
try {
|
|
325
326
|
try {
|
|
326
|
-
|
|
327
|
+
const res = await conn.command(ns, cmd, finalOptions, responseType);
|
|
328
|
+
throwIfWriteConcernError(res);
|
|
329
|
+
return res;
|
|
327
330
|
} catch (commandError) {
|
|
328
331
|
throw this.decorateCommandError(conn, cmd, finalOptions, commandError);
|
|
329
332
|
}
|
|
@@ -334,7 +337,9 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
334
337
|
) {
|
|
335
338
|
await this.pool.reauthenticate(conn);
|
|
336
339
|
try {
|
|
337
|
-
|
|
340
|
+
const res = await conn.command(ns, cmd, finalOptions, responseType);
|
|
341
|
+
throwIfWriteConcernError(res);
|
|
342
|
+
return res;
|
|
338
343
|
} catch (commandError) {
|
|
339
344
|
throw this.decorateCommandError(conn, cmd, finalOptions, commandError);
|
|
340
345
|
}
|
package/src/utils.ts
CHANGED
|
@@ -8,11 +8,11 @@ import * as url from 'url';
|
|
|
8
8
|
import { URL } from 'url';
|
|
9
9
|
import { promisify } from 'util';
|
|
10
10
|
|
|
11
|
-
import { type Document, ObjectId, resolveBSONOptions } from './bson';
|
|
11
|
+
import { deserialize, type Document, ObjectId, resolveBSONOptions } from './bson';
|
|
12
12
|
import type { Connection } from './cmap/connection';
|
|
13
13
|
import { MAX_SUPPORTED_WIRE_VERSION } from './cmap/wire_protocol/constants';
|
|
14
14
|
import type { Collection } from './collection';
|
|
15
|
-
import { LEGACY_HELLO_COMMAND } from './constants';
|
|
15
|
+
import { kDecoratedKeys, LEGACY_HELLO_COMMAND } from './constants';
|
|
16
16
|
import type { AbstractCursor } from './cursor/abstract_cursor';
|
|
17
17
|
import type { FindCursor } from './cursor/find_cursor';
|
|
18
18
|
import type { Db } from './db';
|
|
@@ -1366,3 +1366,53 @@ export async function fileIsAccessible(fileName: string, mode?: number) {
|
|
|
1366
1366
|
export function noop() {
|
|
1367
1367
|
return;
|
|
1368
1368
|
}
|
|
1369
|
+
|
|
1370
|
+
/**
|
|
1371
|
+
* Recurse through the (identically-shaped) `decrypted` and `original`
|
|
1372
|
+
* objects and attach a `decryptedKeys` property on each sub-object that
|
|
1373
|
+
* contained encrypted fields. Because we only call this on BSON responses,
|
|
1374
|
+
* we do not need to worry about circular references.
|
|
1375
|
+
*
|
|
1376
|
+
* @internal
|
|
1377
|
+
*/
|
|
1378
|
+
export function decorateDecryptionResult(
|
|
1379
|
+
decrypted: Document & { [kDecoratedKeys]?: Array<string> },
|
|
1380
|
+
original: Document,
|
|
1381
|
+
isTopLevelDecorateCall = true
|
|
1382
|
+
): void {
|
|
1383
|
+
if (isTopLevelDecorateCall) {
|
|
1384
|
+
// The original value could have been either a JS object or a BSON buffer
|
|
1385
|
+
if (Buffer.isBuffer(original)) {
|
|
1386
|
+
original = deserialize(original);
|
|
1387
|
+
}
|
|
1388
|
+
if (Buffer.isBuffer(decrypted)) {
|
|
1389
|
+
throw new MongoRuntimeError('Expected result of decryption to be deserialized BSON object');
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
if (!decrypted || typeof decrypted !== 'object') return;
|
|
1394
|
+
for (const k of Object.keys(decrypted)) {
|
|
1395
|
+
const originalValue = original[k];
|
|
1396
|
+
|
|
1397
|
+
// An object was decrypted by libmongocrypt if and only if it was
|
|
1398
|
+
// a BSON Binary object with subtype 6.
|
|
1399
|
+
if (originalValue && originalValue._bsontype === 'Binary' && originalValue.sub_type === 6) {
|
|
1400
|
+
if (!decrypted[kDecoratedKeys]) {
|
|
1401
|
+
Object.defineProperty(decrypted, kDecoratedKeys, {
|
|
1402
|
+
value: [],
|
|
1403
|
+
configurable: true,
|
|
1404
|
+
enumerable: false,
|
|
1405
|
+
writable: false
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
// this is defined in the preceding if-statement
|
|
1409
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1410
|
+
decrypted[kDecoratedKeys]!.push(k);
|
|
1411
|
+
// Do not recurse into this decrypted value. It could be a sub-document/array,
|
|
1412
|
+
// in which case there is no original value associated with its subfields.
|
|
1413
|
+
continue;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
decorateDecryptionResult(decrypted[k], originalValue, false);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
package/src/write_concern.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type Document } from './bson';
|
|
2
|
+
import { MongoDBResponse } from './cmap/wire_protocol/responses';
|
|
3
|
+
import { MongoWriteConcernError } from './error';
|
|
2
4
|
|
|
3
5
|
/** @public */
|
|
4
6
|
export type W = number | 'majority';
|
|
@@ -159,3 +161,19 @@ export class WriteConcern {
|
|
|
159
161
|
return undefined;
|
|
160
162
|
}
|
|
161
163
|
}
|
|
164
|
+
|
|
165
|
+
/** Called with either a plain object or MongoDBResponse */
|
|
166
|
+
export function throwIfWriteConcernError(response: unknown): void {
|
|
167
|
+
if (typeof response === 'object' && response != null) {
|
|
168
|
+
const writeConcernError: object | null =
|
|
169
|
+
MongoDBResponse.is(response) && response.has('writeConcernError')
|
|
170
|
+
? response.toObject()
|
|
171
|
+
: !MongoDBResponse.is(response) && 'writeConcernError' in response
|
|
172
|
+
? response
|
|
173
|
+
: null;
|
|
174
|
+
|
|
175
|
+
if (writeConcernError != null) {
|
|
176
|
+
throw new MongoWriteConcernError(writeConcernError as any);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|