Skip to content

Commit da4c1d2

Browse files
POC with response type
1 parent 3480fbd commit da4c1d2

File tree

5 files changed

+42
-19
lines changed

5 files changed

+42
-19
lines changed

src/operations/drop.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { Document } from '../bson';
22
import { CursorTimeoutContext } from '../cursor/abstract_cursor';
33
import type { Db } from '../db';
4-
import { MONGODB_ERROR_CODES, MongoServerError } from '../error';
54
import type { Server } from '../sdam/server';
65
import type { ClientSession } from '../sessions';
76
import { TimeoutContext } from '../timeout';

src/operations/execute_operation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ async function tryOperation<
291291

292292
try {
293293
const result = await server.modernCommand(operation, timeoutContext);
294-
return operation.handleOk(result) as TResult;
294+
return operation.handleOk(result);
295295
} catch (error) {
296296
operation.handleError(error);
297297
}

src/operations/operation.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type Connection, type MongoError } from '..';
1+
import { type Connection, type MongoDBResponse, type MongoError } from '..';
22
import { type BSONSerializeOptions, type Document, resolveBSONOptions } from '../bson';
33
import { type Abortable } from '../mongo_types';
44
import { ReadPreference, type ReadPreferenceLike } from '../read_preference';
@@ -130,13 +130,18 @@ export abstract class AbstractOperation<TResult = any> {
130130
}
131131
}
132132

133-
export abstract class ModernOperation<T> extends AbstractOperation<T> {
133+
export abstract class ModernOperation<
134+
TResponse extends typeof MongoDBResponse | undefined,
135+
TResult
136+
> extends AbstractOperation<TResult> {
137+
abstract RESPONSE_TYPE: TResponse;
138+
134139
/** this will never be used - but we must implement it to satisfy AbstractOperation's interface */
135140
override execute(
136141
_server: Server,
137142
_session: ClientSession | undefined,
138143
_timeoutContext: TimeoutContext
139-
): Promise<T> {
144+
): Promise<TResult> {
140145
throw new Error('cannot execute!!');
141146
}
142147

@@ -148,9 +153,9 @@ export abstract class ModernOperation<T> extends AbstractOperation<T> {
148153
* Optional - if the operation performs error handling, such as wrapping or renaming the error,
149154
* this method can be overridden.
150155
*/
151-
handleOk(response: Document) {
152-
return response;
153-
}
156+
abstract handleOk(
157+
response: TResponse extends typeof MongoDBResponse ? InstanceType<TResponse> : Document
158+
): TResult;
154159

155160
/**
156161
* Optional - if the operation performs post-processing

src/operations/search_indexes/drop.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { type Connection, type MongoError } from '../..';
22
import type { Document } from '../../bson';
33
import type { Collection } from '../../collection';
44
import { MONGODB_ERROR_CODES, MongoServerError } from '../../error';
5-
import type { Server, ServerCommandOptions } from '../../sdam/server';
5+
import type { ServerCommandOptions } from '../../sdam/server';
66
import type { ClientSession } from '../../sessions';
77
import { type TimeoutContext } from '../../timeout';
8-
import { AbstractOperation, ModernOperation } from '../operation';
8+
import { ModernOperation } from '../operation';
99

1010
/** @internal */
11-
export class DropSearchIndexOperation extends ModernOperation<void> {
11+
export class DropSearchIndexOperation extends ModernOperation<undefined, void> {
12+
override RESPONSE_TYPE: undefined;
13+
1214
private readonly collection: Collection;
1315
private readonly name: string;
1416

@@ -36,6 +38,10 @@ export class DropSearchIndexOperation extends ModernOperation<void> {
3638
return command;
3739
}
3840

41+
override handleOk(_response: Document): void {
42+
// do nothing
43+
}
44+
3945
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
4046
return { session: this.session, timeoutContext };
4147
}

src/sdam/server.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {
77
type ConnectionPoolOptions
88
} from '../cmap/connection_pool';
99
import { PoolClearedError } from '../cmap/errors';
10-
import { type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses';
10+
import {
11+
type MongoDBResponse,
12+
type MongoDBResponseConstructor
13+
} from '../cmap/wire_protocol/responses';
1114
import {
1215
APM_EVENTS,
1316
CLOSED,
@@ -40,7 +43,7 @@ import { type Abortable, TypedEventEmitter } from '../mongo_types';
4043
import type { GetMoreOptions } from '../operations/get_more';
4144
import { type ModernOperation } from '../operations/operation';
4245
import type { ClientSession } from '../sessions';
43-
import { Timeout, type TimeoutContext } from '../timeout';
46+
import { type TimeoutContext } from '../timeout';
4447
import { isTransactionCommand } from '../transactions';
4548
import {
4649
abortable,
@@ -278,10 +281,14 @@ export class Server extends TypedEventEmitter<ServerEvents> {
278281
}
279282
}
280283

281-
public async modernCommand(
282-
operation: ModernOperation<any>,
284+
public async modernCommand<TResponse extends typeof MongoDBResponse | undefined, TResult>(
285+
operation: ModernOperation<TResponse, TResult>,
283286
timeoutContext: TimeoutContext
284-
): Promise<Document> {
287+
): Promise<
288+
typeof operation.RESPONSE_TYPE extends typeof MongoDBResponse
289+
? InstanceType<TResponse>
290+
: Document
291+
> {
285292
if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {
286293
throw new MongoServerClosedError();
287294
}
@@ -326,9 +333,12 @@ export class Server extends TypedEventEmitter<ServerEvents> {
326333

327334
try {
328335
try {
329-
const res = await conn.command(ns, cmd, options);
336+
const res = await conn.command(ns, cmd, options, operation.RESPONSE_TYPE);
330337
throwIfWriteConcernError(res);
331-
return res;
338+
// TODO: figure out why casting is necessary
339+
return res as typeof operation.RESPONSE_TYPE extends typeof MongoDBResponse
340+
? InstanceType<TResponse>
341+
: Document;
332342
} catch (commandError) {
333343
throw this.decorateCommandError(conn, cmd, options, commandError);
334344
}
@@ -349,7 +359,10 @@ export class Server extends TypedEventEmitter<ServerEvents> {
349359
try {
350360
const res = await conn.command(ns, cmd, options);
351361
throwIfWriteConcernError(res);
352-
return res;
362+
// TODO: figure out why casting is necessary
363+
return res as typeof operation.RESPONSE_TYPE extends typeof MongoDBResponse
364+
? InstanceType<TResponse>
365+
: Document;
353366
} catch (commandError) {
354367
throw this.decorateCommandError(conn, cmd, options, commandError);
355368
}

0 commit comments

Comments
 (0)