Skip to content

Commit 006eb3b

Browse files
add a TS compile time check
1 parent fd6cd38 commit 006eb3b

1 file changed

Lines changed: 73 additions & 32 deletions

File tree

src/change_stream.ts

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
MongoRuntimeError
1616
} from './error';
1717
import { MongoClient } from './mongo_client';
18-
import { type InferIdType, TypedEventEmitter } from './mongo_types';
18+
import { type Abortable, type InferIdType, TypedEventEmitter } from './mongo_types';
1919
import type { AggregateOptions } from './operations/aggregate';
2020
import type { OperationParent } from './operations/command';
2121
import type { ServerSessionId } from './sessions';
@@ -34,39 +34,12 @@ const NO_RESUME_TOKEN_ERROR =
3434
'A change stream document has been received that lacks a resume token (_id).';
3535
const CHANGESTREAM_CLOSED_ERROR = 'ChangeStream is closed';
3636

37-
const INVALID_STAGE_OPTIONS = new Set([
38-
'authdb',
39-
'batchSize',
40-
'bsonRegExp',
41-
'collation',
42-
'comment',
43-
'dbName',
44-
'enableUtf8Validation',
45-
'fieldsAsRaw',
46-
'ignoreUndefined',
47-
'maxAwaitTimeMS',
48-
'maxTimeMS',
49-
'promoteBuffers',
50-
'promoteLongs',
51-
'promoteValues',
52-
'raw',
53-
'rawData',
54-
'readPreference',
55-
'serializeFunctions',
56-
'timeoutContext',
57-
'timeoutMS',
58-
'useBigInt64',
59-
'writeConcern'
60-
]);
37+
const INVALID_STAGE_OPTIONS = buildDisallowedChangeStreamOptions();
6138

6239
export function filterOutOptions(options: AnyOptions): AnyOptions {
63-
const filterOptions: AnyOptions = {};
64-
for (const name of Object.keys(options)) {
65-
if (!INVALID_STAGE_OPTIONS.has(name)) {
66-
filterOptions[name] = options[name];
67-
}
68-
}
69-
return filterOptions;
40+
return Object.fromEntries(
41+
Object.entries(options).filter(([k, _]) => INVALID_STAGE_OPTIONS.has(k))
42+
);
7043
}
7144

7245
/**
@@ -1110,3 +1083,71 @@ export class ChangeStream<
11101083
}
11111084
}
11121085
}
1086+
1087+
/**
1088+
* This function returns a list of options that are *not* supported by the $changeStream
1089+
* aggregation stage. This is best-effort - it uses the options "officially supported" by the driver
1090+
* to derive a list of known, unsupported options for the $changeStream stage.
1091+
*
1092+
* Notably, at runtime, users can still provide options unknown to the driver and the driver will
1093+
* *not* filter them out of the options object (see NODE-5510).
1094+
*/
1095+
function buildDisallowedChangeStreamOptions(): Set<string> {
1096+
/** hard-coded list of allowed ChangeStream options */
1097+
type CSOptions =
1098+
| 'resumeAfter'
1099+
| 'startAfter'
1100+
| 'startAtOperationTime'
1101+
| 'fullDocument'
1102+
| 'fullDocumentBeforeChange'
1103+
| 'showExpandedEvents';
1104+
1105+
/**
1106+
* a type representing all known options that the driver supports that are *not* change stream stage options.
1107+
*
1108+
* each known key is mapped to a non-optional string, so that if new driver-specific options are added, the
1109+
* instantiation of `denyList` below results in a TS error.
1110+
*/
1111+
type DisallowedOptions = {
1112+
[k in Exclude<keyof ChangeStreamOptions, CSOptions>]: string;
1113+
};
1114+
1115+
const denyList: DisallowedOptions = {
1116+
explain: '',
1117+
checkKeys: '',
1118+
serializeFunctions: '',
1119+
ignoreUndefined: '',
1120+
useBigInt64: '',
1121+
promoteLongs: '',
1122+
promoteBuffers: '',
1123+
promoteValues: '',
1124+
fieldsAsRaw: '',
1125+
bsonRegExp: '',
1126+
raw: '',
1127+
readConcern: '',
1128+
collation: '',
1129+
maxTimeMS: '',
1130+
comment: '',
1131+
dbName: '',
1132+
authdb: '',
1133+
rawData: '',
1134+
session: '',
1135+
willRetryWrite: '',
1136+
readPreference: '',
1137+
bypassPinningCheck: '',
1138+
omitMaxTimeMS: '',
1139+
timeoutMS: '',
1140+
enableUtf8Validation: '',
1141+
allowDiskUse: '',
1142+
batchSize: '',
1143+
bypassDocumentValidation: '',
1144+
cursor: '',
1145+
maxAwaitTimeMS: '',
1146+
hint: '',
1147+
let: '',
1148+
out: '',
1149+
timeoutMode: ''
1150+
};
1151+
1152+
return new Set(Object.keys(denyList));
1153+
}

0 commit comments

Comments
 (0)