diff --git a/package-lock.json b/package-lock.json index 9f5a780e27b..c3dbd5b1c0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,8 +59,8 @@ "socks": "^2.8.1", "source-map-support": "^0.5.21", "ts-node": "^10.9.2", - "tsd": "^0.31.2", - "typescript": "5.5", + "tsd": "^0.32.0", + "typescript": "5.8.3", "typescript-cached-transpile": "^0.0.6", "v8-heapsnapshot": "^1.3.1", "yargs": "^17.7.2" @@ -2740,9 +2740,9 @@ "license": "MIT" }, "node_modules/@tsd/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-saiCxzHRhUrRxQV2JhH580aQUZiKQUXI38FcAcikcfOomAil4G4lxT0RfrrKywoAYP/rqAdYXYmNRLppcd+hQQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-oKarNCN1QUhG148M88mtZdOlBZWWGcInquef+U8QL7gwJkRuNo5WS45Fjsd+3hM9cDJWGpqSZ4Oo097KDx4IWA==", "dev": true, "license": "MIT", "engines": { @@ -8892,13 +8892,13 @@ } }, "node_modules/tsd": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.31.2.tgz", - "integrity": "sha512-VplBAQwvYrHzVihtzXiUVXu5bGcr7uH1juQZ1lmKgkuGNGT+FechUCqmx9/zk7wibcqR2xaNEwCkDyKh+VVZnQ==", + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.32.0.tgz", + "integrity": "sha512-R5lBZCbxGBowOcW0gpQaiIjGYrG5NmU+PfFDKcc3zbtzWjML1o/zAwzdDnS2ZheSlPu9GW51azpFqEPUBq9DoQ==", "dev": true, "license": "MIT", "dependencies": { - "@tsd/typescript": "~5.4.3", + "@tsd/typescript": "~5.8.3", "eslint-formatter-pretty": "^4.1.0", "globby": "^11.0.1", "jest-diff": "^29.0.3", @@ -8992,9 +8992,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 2033effd862..5e3fdd48e48 100644 --- a/package.json +++ b/package.json @@ -107,8 +107,8 @@ "socks": "^2.8.1", "source-map-support": "^0.5.21", "ts-node": "^10.9.2", - "tsd": "^0.31.2", - "typescript": "5.5", + "tsd": "^0.32.0", + "typescript": "5.8.3", "typescript-cached-transpile": "^0.0.6", "v8-heapsnapshot": "^1.3.1", "yargs": "^17.7.2" diff --git a/src/bulk/common.ts b/src/bulk/common.ts index 782b4041e39..6acd1ba13c4 100644 --- a/src/bulk/common.ts +++ b/src/bulk/common.ts @@ -894,16 +894,14 @@ export abstract class BulkOperationBase { /** @internal */ s: BulkOperationPrivate; operationId?: number; + private collection: Collection; /** * Create a new OrderedBulkOperation or UnorderedBulkOperation instance * @internal */ - constructor( - private collection: Collection, - options: BulkWriteOptions, - isOrdered: boolean - ) { + constructor(collection: Collection, options: BulkWriteOptions, isOrdered: boolean) { + this.collection = collection; // determine whether bulkOperation is ordered or unordered this.isOrdered = isOrdered; diff --git a/src/client-side-encryption/state_machine.ts b/src/client-side-encryption/state_machine.ts index b60756935e7..fd5a393ea84 100644 --- a/src/client-side-encryption/state_machine.ts +++ b/src/client-side-encryption/state_machine.ts @@ -186,10 +186,13 @@ export type StateMachineOptions = { */ // TODO(DRIVERS-2671): clarify CSOT behavior for FLE APIs export class StateMachine { - constructor( - private options: StateMachineOptions, - private bsonOptions = pluckBSONSerializeOptions(options) - ) {} + private options: StateMachineOptions; + private bsonOptions: BSONSerializeOptions; + + constructor(options: StateMachineOptions, bsonOptions = pluckBSONSerializeOptions(options)) { + this.options = options; + this.bsonOptions = bsonOptions; + } /** * Executes the state machine according to the specification diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index f14c3f5de4c..bdd080a37bf 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -76,12 +76,10 @@ export class OpQueryRequest { partial: boolean; /** moreToCome is an OP_MSG only concept */ moreToCome = false; + databaseName: string; + query: Document; - constructor( - public databaseName: string, - public query: Document, - options: OpQueryOptions - ) { + constructor(databaseName: string, query: Document, options: OpQueryOptions) { // Basic options needed to be passed in // TODO(NODE-3483): Replace with MongoCommandError const ns = `${databaseName}.$cmd`; @@ -97,7 +95,9 @@ export class OpQueryRequest { throw new MongoRuntimeError('Namespace cannot contain a null character'); } - // Basic options + // Basic optionsa + this.databaseName = databaseName; + this.query = query; this.ns = ns; // Additional options @@ -496,17 +496,18 @@ export class OpMsgRequest { checksumPresent: boolean; moreToCome: boolean; exhaustAllowed: boolean; + databaseName: string; + command: Document; + options: OpQueryOptions; - constructor( - public databaseName: string, - public command: Document, - public options: OpQueryOptions - ) { + constructor(databaseName: string, command: Document, options: OpQueryOptions) { // Basic options needed to be passed in if (command == null) throw new MongoInvalidArgumentError('Query document must be specified for query'); - // Basic options + // Basic optionsa + this.databaseName = databaseName; + this.command = command; this.command.$db = databaseName; // Ensure empty options @@ -730,10 +731,19 @@ const COMPRESSION_DETAILS_SIZE = 9; // originalOpcode + uncompressedSize, compre * An OP_COMPRESSED request wraps either an OP_QUERY or OP_MSG message. */ export class OpCompressedRequest { + private command: WriteProtocolMessageType; + private options: { zLibCompressionLevel: number; agreedCompressor: CompressorName }; + constructor( - private command: WriteProtocolMessageType, - private options: { zlibCompressionLevel: number; agreedCompressor: CompressorName } - ) {} + command: WriteProtocolMessageType, + options: { zlibCompressionLevel: number; agreedCompressor: CompressorName } + ) { + this.command = command; + this.options = { + zLibCompressionLevel: options.zlibCompressionLevel, + agreedCompressor: options.agreedCompressor + }; + } // Return whether a command contains an uncompressible command term // Will return true if command contains no uncompressible command terms @@ -752,7 +762,13 @@ export class OpCompressedRequest { const originalCommandOpCode = concatenatedOriginalCommandBuffer.readInt32LE(12); // Compress the message body - const compressedMessage = await compress(this.options, messageToBeCompressed); + const compressedMessage = await compress( + { + zlibCompressionLevel: this.options.zLibCompressionLevel, + agreedCompressor: this.options.agreedCompressor + }, + messageToBeCompressed + ); // Create the msgHeader of OP_COMPRESSED const msgHeader = Buffer.alloc(MESSAGE_HEADER_SIZE); msgHeader.writeInt32LE( diff --git a/src/cmap/handshake/client_metadata.ts b/src/cmap/handshake/client_metadata.ts index 1e825ed2bf7..9a633a72aac 100644 --- a/src/cmap/handshake/client_metadata.ts +++ b/src/cmap/handshake/client_metadata.ts @@ -53,7 +53,11 @@ export class LimitedSizeDocument { private document = new Map(); /** BSON overhead: Int32 + Null byte */ private documentSize = 5; - constructor(private maxSize: number) {} + private maxSize: number; + + constructor(maxSize: number) { + this.maxSize = maxSize; + } /** Only adds key/value if the bsonByteLength is less than MAX_SIZE */ public ifItFitsItSits(key: string, value: Record | string): boolean { diff --git a/src/cmap/wire_protocol/on_data.ts b/src/cmap/wire_protocol/on_data.ts index 82dd7b40dbe..51be4d8d8c1 100644 --- a/src/cmap/wire_protocol/on_data.ts +++ b/src/cmap/wire_protocol/on_data.ts @@ -87,6 +87,10 @@ export function onData( [Symbol.asyncIterator]() { return this; + }, + + [Symbol.asyncDispose]: function (): PromiseLike { + return closeHandler().then(() => undefined); } }; diff --git a/src/cmap/wire_protocol/on_demand/document.ts b/src/cmap/wire_protocol/on_demand/document.ts index 54a28a083c8..2454b034f3b 100644 --- a/src/cmap/wire_protocol/on_demand/document.ts +++ b/src/cmap/wire_protocol/on_demand/document.ts @@ -14,14 +14,13 @@ import { toUTF8 } from '../../../bson'; -// eslint-disable-next-line no-restricted-syntax -const enum BSONElementOffset { - type = 0, - nameOffset = 1, - nameLength = 2, - offset = 3, - length = 4 -} +const BSONElementOffset = { + type: 0, + nameOffset: 1, + nameLength: 2, + offset: 3, + length: 4 +} as const; /** @internal */ export type JSTypeOf = { @@ -67,17 +66,23 @@ export class OnDemandDocument { /** All bson elements in this document */ private readonly elements: ReadonlyArray; + /** BSON bytes, this document begins at offset */ + protected readonly bson: Uint8Array; + /** The start of the document */ + private readonly offset: number; + /** If this is an embedded document, indicates if this was a BSON array */ + public readonly isArray: boolean; constructor( - /** BSON bytes, this document begins at offset */ - protected readonly bson: Uint8Array, - /** The start of the document */ - private readonly offset = 0, - /** If this is an embedded document, indicates if this was a BSON array */ - public readonly isArray = false, + bson: Uint8Array, + offset = 0, + isArray = false, /** If elements was already calculated */ elements?: BSONElement[] ) { + this.bson = bson; + this.offset = offset; + this.isArray = isArray; this.elements = elements ?? parseToElementsToArray(this.bson, offset); } diff --git a/src/cmap/wire_protocol/responses.ts b/src/cmap/wire_protocol/responses.ts index f5b0bad99e1..d5549aea545 100644 --- a/src/cmap/wire_protocol/responses.ts +++ b/src/cmap/wire_protocol/responses.ts @@ -20,14 +20,14 @@ import { type OnDemandDocumentDeserializeOptions } from './on_demand/document'; -// eslint-disable-next-line no-restricted-syntax -const enum BSONElementOffset { - type = 0, - nameOffset = 1, - nameLength = 2, - offset = 3, - length = 4 -} +const BSONElementOffset = { + type: 0, + nameOffset: 1, + nameLength: 2, + offset: 3, + length: 4 +} as const; + /** * Accepts a BSON payload and checks for na "ok: 0" element. * This utility is intended to prevent calling response class constructors diff --git a/src/connection_string.ts b/src/connection_string.ts index e07783e3758..a32c1e155f1 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -605,6 +605,8 @@ function setOption( if (values[0] == null) { break; } + // The value should always be a string here, but since the array is typed as unknown + // there still needs to be an explicit cast. // eslint-disable-next-line @typescript-eslint/no-base-to-string mongoOptions[name] = String(values[0]); break; diff --git a/src/cursor/abstract_cursor.ts b/src/cursor/abstract_cursor.ts index 791fab6f584..af688ebfb62 100644 --- a/src/cursor/abstract_cursor.ts +++ b/src/cursor/abstract_cursor.ts @@ -1213,11 +1213,13 @@ configureResourceManagement(AbstractCursor.prototype); * All timeout behavior is exactly the same as the wrapped timeout context's. */ export class CursorTimeoutContext extends TimeoutContext { - constructor( - public timeoutContext: TimeoutContext, - public owner: symbol | AbstractCursor - ) { + timeoutContext: TimeoutContext; + owner: symbol | AbstractCursor; + + constructor(timeoutContext: TimeoutContext, owner: symbol | AbstractCursor) { super(); + this.timeoutContext = timeoutContext; + this.owner = owner; } override get serverSelectionTimeout(): Timeout | null { return this.timeoutContext.serverSelectionTimeout; diff --git a/src/operations/distinct.ts b/src/operations/distinct.ts index 5c2c6c6a23d..cb6891fc475 100644 --- a/src/operations/distinct.ts +++ b/src/operations/distinct.ts @@ -96,6 +96,7 @@ export class DistinctOperation extends CommandOperation { const result = await super.executeCommand(server, session, cmd, timeoutContext); + // @ts-expect-error: Explain always returns a document return this.explain ? result : result.values; } } diff --git a/src/operations/rename.ts b/src/operations/rename.ts index 883be282b64..62659a7bafb 100644 --- a/src/operations/rename.ts +++ b/src/operations/rename.ts @@ -17,12 +17,15 @@ export interface RenameOptions extends CommandOperationOptions { /** @internal */ export class RenameOperation extends CommandOperation { - constructor( - public collection: Collection, - public newName: string, - public override options: RenameOptions - ) { + collection: Collection; + newName: string; + override options: RenameOptions; + + constructor(collection: Collection, newName: string, options: RenameOptions) { super(collection, options); + this.collection = collection; + this.newName = newName; + this.options = options; this.ns = new MongoDBNamespace('admin', '$cmd'); } diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index db5c5a7c169..4b967ee3cd5 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -26,12 +26,17 @@ export type RunCommandOptions = { /** @internal */ export class RunCommandOperation extends AbstractOperation { + command: Document; + override options: RunCommandOptions & { responseType?: MongoDBResponseConstructor }; + constructor( parent: Db, - public command: Document, - public override options: RunCommandOptions & { responseType?: MongoDBResponseConstructor } + command: Document, + options: RunCommandOptions & { responseType?: MongoDBResponseConstructor } ) { super(options); + this.command = command; + this.options = options; this.ns = parent.s.namespace.withCollection('$cmd'); } @@ -62,14 +67,22 @@ export class RunCommandOperation extends AbstractOperation { } export class RunAdminCommandOperation extends AbstractOperation { + command: Document; + override options: RunCommandOptions & { + noResponse?: boolean; + bypassPinningCheck?: boolean; + }; + constructor( - public command: Document, - public override options: RunCommandOptions & { + command: Document, + options: RunCommandOptions & { noResponse?: boolean; bypassPinningCheck?: boolean; } ) { super(options); + this.command = command; + this.options = options; this.ns = new MongoDBNamespace('admin', '$cmd'); } diff --git a/src/operations/search_indexes/create.ts b/src/operations/search_indexes/create.ts index 2870868bc91..95f91c2d19f 100644 --- a/src/operations/search_indexes/create.ts +++ b/src/operations/search_indexes/create.ts @@ -21,11 +21,13 @@ export interface SearchIndexDescription extends Document { /** @internal */ export class CreateSearchIndexesOperation extends AbstractOperation { - constructor( - private readonly collection: Collection, - private readonly descriptions: ReadonlyArray - ) { + private readonly collection: Collection; + private readonly descriptions: ReadonlyArray; + + constructor(collection: Collection, descriptions: ReadonlyArray) { super(); + this.collection = collection; + this.descriptions = descriptions; } override get commandName() { diff --git a/src/operations/search_indexes/drop.ts b/src/operations/search_indexes/drop.ts index 28870d3220e..3b87bfad442 100644 --- a/src/operations/search_indexes/drop.ts +++ b/src/operations/search_indexes/drop.ts @@ -8,11 +8,13 @@ import { AbstractOperation } from '../operation'; /** @internal */ export class DropSearchIndexOperation extends AbstractOperation { - constructor( - private readonly collection: Collection, - private readonly name: string - ) { + private readonly collection: Collection; + private readonly name: string; + + constructor(collection: Collection, name: string) { super(); + this.collection = collection; + this.name = name; } override get commandName() { diff --git a/src/operations/search_indexes/update.ts b/src/operations/search_indexes/update.ts index e8701d2802e..dfc2c848db3 100644 --- a/src/operations/search_indexes/update.ts +++ b/src/operations/search_indexes/update.ts @@ -7,12 +7,15 @@ import { AbstractOperation } from '../operation'; /** @internal */ export class UpdateSearchIndexOperation extends AbstractOperation { - constructor( - private readonly collection: Collection, - private readonly name: string, - private readonly definition: Document - ) { + private readonly collection: Collection; + private readonly name: string; + private readonly definition: Document; + + constructor(collection: Collection, name: string, definition: Document) { super(); + this.collection = collection; + this.name = name; + this.definition = definition; } override get commandName() { diff --git a/src/utils.ts b/src/utils.ts index 09e86b7349c..22cda4092ba 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -281,16 +281,16 @@ export function ns(ns: string): MongoDBNamespace { /** @public */ export class MongoDBNamespace { + db: string; + collection?: string; /** * Create a namespace object * * @param db - database name * @param collection - collection name */ - constructor( - public db: string, - public collection?: string - ) { + constructor(db: string, collection?: string) { + this.db = db; this.collection = collection === '' ? undefined : collection; } @@ -322,11 +322,11 @@ export class MongoDBNamespace { * used in scenarios where this can be guaranteed. */ export class MongoDBCollectionNamespace extends MongoDBNamespace { - constructor( - db: string, - override collection: string - ) { + override collection: string; + + constructor(db: string, collection: string) { super(db, collection); + this.collection = collection; } static override fromString(namespace?: string): MongoDBCollectionNamespace { diff --git a/src/write_concern.ts b/src/write_concern.ts index 6326f15d588..622460fa79a 100644 --- a/src/write_concern.ts +++ b/src/write_concern.ts @@ -143,6 +143,7 @@ export class WriteConcern { const parentOpts: WriteConcern | WriteConcernSettings | undefined = inherit instanceof WriteConcern ? inherit : inherit.writeConcern; + const mergedOpts = { ...parentOpts, ...opts } as WriteConcernSettings; const { w = undefined, wtimeout = undefined, @@ -150,10 +151,7 @@ export class WriteConcern { fsync = undefined, journal = undefined, wtimeoutMS = undefined - } = { - ...parentOpts, - ...opts - }; + } = mergedOpts; if ( w != null || wtimeout != null || diff --git a/test/benchmarks/driver_bench/tsconfig.json b/test/benchmarks/driver_bench/tsconfig.json index d7eb0f5c29e..f8e4d6d94cf 100644 --- a/test/benchmarks/driver_bench/tsconfig.json +++ b/test/benchmarks/driver_bench/tsconfig.json @@ -8,6 +8,7 @@ "verbatimModuleSyntax": true, "module": "NodeNext", "moduleResolution": "NodeNext", + "erasableSyntaxOnly": true, "skipLibCheck": true, // We don't make use of tslib helpers, all syntax used is supported by target engine "importHelpers": false, diff --git a/test/types/community/slow-model.test-d.ts b/test/types/community/slow-model.test-d.ts index 5f024863234..96a356af3a6 100644 --- a/test/types/community/slow-model.test-d.ts +++ b/test/types/community/slow-model.test-d.ts @@ -108,8 +108,6 @@ export interface SlowModelBase { prop10: boolean; prop11: string | null; prop12: string[]; - prop13: ExtraType4 | null; - prop14: ExtraType5 | null; prop15: ExtraType6 | null; prop16: string[]; prop17: string | null; @@ -253,13 +251,15 @@ export interface ExtraType2 { export type ExtraType9 = ExtraType6; -export enum UnitType3 { - unit_ = 'unit_', - unit__ = 'unit__', - unit___ = 'unit___', - unit____ = 'unit____', - unit_____ = 'unit_____' -} +const UnitType3 = { + unit_: 'unit_', + unit__: 'unit__', + unit___: 'unit___', + unit____: 'unit____', + unit_____: 'unit_____' +} as const; + +export type UnitType3 = (typeof UnitType3)[keyof typeof UnitType3]; export interface ExtraType10 { prop34?: UnitType3; @@ -308,54 +308,6 @@ export interface SpecialType extends SlowModel { prop51: string; } -export enum ExtraType17 { - Key16 = 'key16', - Key17 = 'key17' -} - -export interface IType1 { - type: ExtraType17; -} -export interface Key17IType1 extends IType1 { - type: ExtraType17.Key17; - prop52: string; - prop53?: string; - prop54?: string; -} -export interface Key16IType1 extends IType1 { - type: ExtraType17.Key16; - prop55: string; - prop56: string | null; -} - -export type ExtraType4 = Key17IType1 | Key16IType1; - -export enum ExtraType18 { - Key18 = 'key18', - Key19 = 'key19' -} - -interface IType2 { - type: ExtraType18; -} -export type ExtraType5 = Key18IType2 | Key19IType2; - -export interface Key18IType2 extends IType2 { - type: ExtraType18.Key18; - prop57: string; - prop58: string; - prop59: boolean; - prop60: string | null; - prop61: boolean; - prop62?: string; -} -export interface Key19IType2 extends IType2 { - type: ExtraType18.Key19; - prop63: string; - prop64?: string; - prop65: boolean; -} - export type ExtraType19 = ExtraType15[] | ExtraType20; export interface ExtraType7 { id: UUID; diff --git a/tsconfig.json b/tsconfig.json index 942a6b869ad..1a8678d7a6e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,10 +8,12 @@ "module": "commonJS", "moduleResolution": "node", "skipLibCheck": true, + "erasableSyntaxOnly": true, "lib": [ "es2021", "ES2022.Error", - "ES2022.Object" + "ES2022.Object", + "esnext.disposable" ], // We don't make use of tslib helpers, all syntax used is supported by target engine "importHelpers": false,