From c8aa1c9b76d90dae944766a2e08e0c42b7295ef7 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sun, 6 Mar 2022 03:49:02 +0100 Subject: [PATCH 1/5] extract aggregationcursor and querycursor --- types/aggregationcursor.d.ts | 41 ++++++++++++++++++ types/index.d.ts | 82 +----------------------------------- types/querycursor.d.ts | 48 +++++++++++++++++++++ 3 files changed, 91 insertions(+), 80 deletions(-) create mode 100644 types/aggregationcursor.d.ts create mode 100644 types/querycursor.d.ts diff --git a/types/aggregationcursor.d.ts b/types/aggregationcursor.d.ts new file mode 100644 index 00000000000..180b98fbf6b --- /dev/null +++ b/types/aggregationcursor.d.ts @@ -0,0 +1,41 @@ + +import stream = require('stream'); + +declare module 'mongoose' { + class AggregationCursor extends stream.Readable { + /** + * Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag). + * Useful for setting the `noCursorTimeout` and `tailable` flags. + */ + addCursorFlag(flag: string, value: boolean): this; + + /** + * Marks this cursor as closed. Will stop streaming and subsequent calls to + * `next()` will error. + */ + close(): Promise; + close(callback: CallbackWithoutResult): void; + + /** + * Execute `fn` for every document(s) in the cursor. If batchSize is provided + * `fn` will be executed for each batch of documents. If `fn` returns a promise, + * will wait for the promise to resolve before iterating on to the next one. + * Returns a promise that resolves when done. + */ + eachAsync(fn: (doc: any) => any, options?: { parallel?: number, batchSize?: number }): Promise; + eachAsync(fn: (doc: any) => any, options?: { parallel?: number, batchSize?: number }, cb?: CallbackWithoutResult): void; + + /** + * Registers a transform function which subsequently maps documents retrieved + * via the streams interface or `.next()` + */ + map(fn: (res: any) => any): this; + + /** + * Get the next document from this cursor. Will return `null` when there are + * no documents left. + */ + next(): Promise; + next(callback: Callback): void; + } +} \ No newline at end of file diff --git a/types/index.d.ts b/types/index.d.ts index 8ed68eaf039..de06f477fa5 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,6 +1,8 @@ /// +/// /// /// +/// import events = require('events'); import mongodb = require('mongodb'); @@ -2618,49 +2620,6 @@ declare module 'mongoose' { T extends Document ? RawDocType : T; - class QueryCursor extends stream.Readable { - [Symbol.asyncIterator](): AsyncIterableIterator; - - /** - * Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag). - * Useful for setting the `noCursorTimeout` and `tailable` flags. - */ - addCursorFlag(flag: string, value: boolean): this; - - /** - * Marks this cursor as closed. Will stop streaming and subsequent calls to - * `next()` will error. - */ - close(): Promise; - close(callback: CallbackWithoutResult): void; - - /** - * Execute `fn` for every document(s) in the cursor. If batchSize is provided - * `fn` will be executed for each batch of documents. If `fn` returns a promise, - * will wait for the promise to resolve before iterating on to the next one. - * Returns a promise that resolves when done. - */ - eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number }): Promise; - eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }): Promise; - eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number, batchSize?: number }, cb?: CallbackWithoutResult): void; - eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }, cb?: CallbackWithoutResult): void; - - /** - * Registers a transform function which subsequently maps documents retrieved - * via the streams interface or `.next()` - */ - map(fn: (res: DocType) => ResultType): QueryCursor; - - /** - * Get the next document from this cursor. Will return `null` when there are - * no documents left. - */ - next(): Promise; - next(callback: Callback): void; - - options: any; - } - class Aggregate { /** * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js @@ -2808,43 +2767,6 @@ declare module 'mongoose' { unwind(...args: PipelineStage.Unwind['$unwind'][]): this; } - class AggregationCursor extends stream.Readable { - /** - * Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag). - * Useful for setting the `noCursorTimeout` and `tailable` flags. - */ - addCursorFlag(flag: string, value: boolean): this; - - /** - * Marks this cursor as closed. Will stop streaming and subsequent calls to - * `next()` will error. - */ - close(): Promise; - close(callback: CallbackWithoutResult): void; - - /** - * Execute `fn` for every document(s) in the cursor. If batchSize is provided - * `fn` will be executed for each batch of documents. If `fn` returns a promise, - * will wait for the promise to resolve before iterating on to the next one. - * Returns a promise that resolves when done. - */ - eachAsync(fn: (doc: any) => any, options?: { parallel?: number, batchSize?: number }): Promise; - eachAsync(fn: (doc: any) => any, options?: { parallel?: number, batchSize?: number }, cb?: CallbackWithoutResult): void; - - /** - * Registers a transform function which subsequently maps documents retrieved - * via the streams interface or `.next()` - */ - map(fn: (res: any) => any): this; - - /** - * Get the next document from this cursor. Will return `null` when there are - * no documents left. - */ - next(): Promise; - next(callback: Callback): void; - } - class SchemaType { /** SchemaType constructor */ constructor(path: string, options?: AnyObject, instance?: string); diff --git a/types/querycursor.d.ts b/types/querycursor.d.ts new file mode 100644 index 00000000000..8e80fb61368 --- /dev/null +++ b/types/querycursor.d.ts @@ -0,0 +1,48 @@ + +import stream = require('stream'); + +declare module 'mongoose' { + + class QueryCursor extends stream.Readable { + [Symbol.asyncIterator](): AsyncIterableIterator; + + /** + * Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag). + * Useful for setting the `noCursorTimeout` and `tailable` flags. + */ + addCursorFlag(flag: string, value: boolean): this; + + /** + * Marks this cursor as closed. Will stop streaming and subsequent calls to + * `next()` will error. + */ + close(): Promise; + close(callback: CallbackWithoutResult): void; + + /** + * Execute `fn` for every document(s) in the cursor. If batchSize is provided + * `fn` will be executed for each batch of documents. If `fn` returns a promise, + * will wait for the promise to resolve before iterating on to the next one. + * Returns a promise that resolves when done. + */ + eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number }): Promise; + eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }): Promise; + eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number, batchSize?: number }, cb?: CallbackWithoutResult): void; + eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }, cb?: CallbackWithoutResult): void; + + /** + * Registers a transform function which subsequently maps documents retrieved + * via the streams interface or `.next()` + */ + map(fn: (res: DocType) => ResultType): QueryCursor; + + /** + * Get the next document from this cursor. Will return `null` when there are + * no documents left. + */ + next(): Promise; + next(callback: Callback): void; + + options: any; + } +} \ No newline at end of file From 4164bd2c1dc184f4b3a36fe0e4f161134189eef6 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sun, 6 Mar 2022 04:22:00 +0100 Subject: [PATCH 2/5] improve typings of cursor --- test/types/aggregate.test.ts | 7 +++++ test/types/queries.test.ts | 5 ++-- types/aggregationcursor.d.ts | 41 --------------------------- types/{querycursor.d.ts => cursor.ts} | 23 ++++++++------- types/index.d.ts | 7 ++--- 5 files changed, 24 insertions(+), 59 deletions(-) delete mode 100644 types/aggregationcursor.d.ts rename types/{querycursor.d.ts => cursor.ts} (60%) diff --git a/test/types/aggregate.test.ts b/test/types/aggregate.test.ts index ef27643b052..5beaa8dca0c 100644 --- a/test/types/aggregate.test.ts +++ b/test/types/aggregate.test.ts @@ -32,6 +32,13 @@ async function run() { obj.name; } + function eachAsync(): void { + Test.aggregate().cursor().eachAsync((doc) => {expectType(doc);}); + Test.aggregate().cursor().eachAsync((docs) => {expectType(docs);}, { batchSize: 2 }); + Test.aggregate().cursor().eachAsync((doc) => {expectType(doc);}); + Test.aggregate().cursor().eachAsync((docs) => {expectType(docs);}, { batchSize: 2 }); + } + // Aggregate.prototype.sort() expectType(await Test.aggregate().sort('-name')); expectType(await Test.aggregate().sort({ name: 1 })); diff --git a/test/types/queries.test.ts b/test/types/queries.test.ts index 79e56648d6c..ebb8e9da097 100644 --- a/test/types/queries.test.ts +++ b/test/types/queries.test.ts @@ -141,9 +141,8 @@ function testGenericQuery(): void { } function eachAsync(): void { - Test.find().cursor().eachAsync((doc: ITest) => console.log(doc.name)); - - Test.find().cursor().eachAsync((docs: ITest[]) => console.log(docs[0].name), { batchSize: 2 }); + Test.find().cursor().eachAsync((doc) => {expectType<(ITest & { _id: any; })>(doc);}); + Test.find().cursor().eachAsync((docs) => {expectType<(ITest & { _id: any; })[]>(docs);}, { batchSize: 2 }); } async function gh10617(): Promise { diff --git a/types/aggregationcursor.d.ts b/types/aggregationcursor.d.ts deleted file mode 100644 index 180b98fbf6b..00000000000 --- a/types/aggregationcursor.d.ts +++ /dev/null @@ -1,41 +0,0 @@ - -import stream = require('stream'); - -declare module 'mongoose' { - class AggregationCursor extends stream.Readable { - /** - * Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag). - * Useful for setting the `noCursorTimeout` and `tailable` flags. - */ - addCursorFlag(flag: string, value: boolean): this; - - /** - * Marks this cursor as closed. Will stop streaming and subsequent calls to - * `next()` will error. - */ - close(): Promise; - close(callback: CallbackWithoutResult): void; - - /** - * Execute `fn` for every document(s) in the cursor. If batchSize is provided - * `fn` will be executed for each batch of documents. If `fn` returns a promise, - * will wait for the promise to resolve before iterating on to the next one. - * Returns a promise that resolves when done. - */ - eachAsync(fn: (doc: any) => any, options?: { parallel?: number, batchSize?: number }): Promise; - eachAsync(fn: (doc: any) => any, options?: { parallel?: number, batchSize?: number }, cb?: CallbackWithoutResult): void; - - /** - * Registers a transform function which subsequently maps documents retrieved - * via the streams interface or `.next()` - */ - map(fn: (res: any) => any): this; - - /** - * Get the next document from this cursor. Will return `null` when there are - * no documents left. - */ - next(): Promise; - next(callback: Callback): void; - } -} \ No newline at end of file diff --git a/types/querycursor.d.ts b/types/cursor.ts similarity index 60% rename from types/querycursor.d.ts rename to types/cursor.ts index 8e80fb61368..29e3485c0fc 100644 --- a/types/querycursor.d.ts +++ b/types/cursor.ts @@ -2,22 +2,23 @@ import stream = require('stream'); declare module 'mongoose' { + type CursorFlag = 'tailable' | 'oplogReplay' | 'noCursorTimeout' | 'awaitData' | 'partial'; - class QueryCursor extends stream.Readable { + class Cursor extends stream.Readable { [Symbol.asyncIterator](): AsyncIterableIterator; /** * Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag). * Useful for setting the `noCursorTimeout` and `tailable` flags. */ - addCursorFlag(flag: string, value: boolean): this; + addCursorFlag(flag: CursorFlag, value: boolean): this; /** * Marks this cursor as closed. Will stop streaming and subsequent calls to * `next()` will error. */ - close(): Promise; close(callback: CallbackWithoutResult): void; + close(): Promise; /** * Execute `fn` for every document(s) in the cursor. If batchSize is provided @@ -25,24 +26,24 @@ declare module 'mongoose' { * will wait for the promise to resolve before iterating on to the next one. * Returns a promise that resolves when done. */ - eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number }): Promise; - eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }): Promise; - eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number, batchSize?: number }, cb?: CallbackWithoutResult): void; - eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }, cb?: CallbackWithoutResult): void; + eachAsync(fn: (doc: DocType[]) => void, options: { parallel?: number, batchSize: number }, callback: CallbackWithoutResult): void; + eachAsync(fn: (doc: DocType) => void, options: { parallel?: number }, callback: CallbackWithoutResult): void; + eachAsync(fn: (doc: DocType[]) => void, options: { parallel?: number, batchSize: number }): Promise; + eachAsync(fn: (doc: DocType) => void, options?: { parallel?: number }): Promise; /** * Registers a transform function which subsequently maps documents retrieved * via the streams interface or `.next()` */ - map(fn: (res: DocType) => ResultType): QueryCursor; + map(fn: (res: DocType) => ResultType): Cursor; /** * Get the next document from this cursor. Will return `null` when there are * no documents left. */ - next(): Promise; next(callback: Callback): void; + next(): Promise; - options: any; + options: Options; } -} \ No newline at end of file +} diff --git a/types/index.d.ts b/types/index.d.ts index de06f477fa5..d1ab3780929 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,8 +1,7 @@ /// -/// +/// /// /// -/// import events = require('events'); import mongodb = require('mongodb'); @@ -2055,7 +2054,7 @@ declare module 'mongoose' { * Returns a wrapper around a [mongodb driver cursor](http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html). * A QueryCursor exposes a Streams3 interface, as well as a `.next()` function. */ - cursor(options?: any): QueryCursor; + cursor(options?: QueryOptions): Cursor; /** * Declare and/or execute this query as a `deleteMany()` operation. Works like @@ -2661,7 +2660,7 @@ declare module 'mongoose' { /** * Sets the cursor option for the aggregation query (ignored for < 2.6.0). */ - cursor(options?: Record): AggregationCursor; + cursor(options?: Record): Cursor; /** Executes the aggregate pipeline on the currently bound Model. */ exec(callback?: Callback): Promise; From a62de71c0859154e5b9c9b01a525eff7837b9d06 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sun, 6 Mar 2022 04:27:49 +0100 Subject: [PATCH 3/5] use any --- types/cursor.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/types/cursor.ts b/types/cursor.ts index 29e3485c0fc..3e40b09324e 100644 --- a/types/cursor.ts +++ b/types/cursor.ts @@ -26,10 +26,10 @@ declare module 'mongoose' { * will wait for the promise to resolve before iterating on to the next one. * Returns a promise that resolves when done. */ - eachAsync(fn: (doc: DocType[]) => void, options: { parallel?: number, batchSize: number }, callback: CallbackWithoutResult): void; - eachAsync(fn: (doc: DocType) => void, options: { parallel?: number }, callback: CallbackWithoutResult): void; - eachAsync(fn: (doc: DocType[]) => void, options: { parallel?: number, batchSize: number }): Promise; - eachAsync(fn: (doc: DocType) => void, options?: { parallel?: number }): Promise; + eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }, callback: CallbackWithoutResult): void; + eachAsync(fn: (doc: DocType) => any, options: { parallel?: number }, callback: CallbackWithoutResult): void; + eachAsync(fn: (doc: DocType[]) => any, options: { parallel?: number, batchSize: number }): Promise; + eachAsync(fn: (doc: DocType) => any, options?: { parallel?: number }): Promise; /** * Registers a transform function which subsequently maps documents retrieved From d8719714cc1f018ba20d2f17591f8e1d3fad4b82 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sun, 6 Mar 2022 04:29:09 +0100 Subject: [PATCH 4/5] passthrough options --- types/cursor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/cursor.ts b/types/cursor.ts index 3e40b09324e..1000d878f7b 100644 --- a/types/cursor.ts +++ b/types/cursor.ts @@ -35,7 +35,7 @@ declare module 'mongoose' { * Registers a transform function which subsequently maps documents retrieved * via the streams interface or `.next()` */ - map(fn: (res: DocType) => ResultType): Cursor; + map(fn: (res: DocType) => ResultType): Cursor; /** * Get the next document from this cursor. Will return `null` when there are From 8d69a62423eee4c76b646bc380ab9dc2f19d4c37 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sun, 6 Mar 2022 04:54:28 +0100 Subject: [PATCH 5/5] remove newline --- types/cursor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/types/cursor.ts b/types/cursor.ts index 1000d878f7b..7c63211d5d3 100644 --- a/types/cursor.ts +++ b/types/cursor.ts @@ -1,4 +1,3 @@ - import stream = require('stream'); declare module 'mongoose' {