From 2a927bd10fe3fc0dc602962bb846cc0f1622e472 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 7 Dec 2022 19:27:41 -0500 Subject: [PATCH 1/5] fix(types): correctly infer `this` when using `pre('updateOne')` with `{ document: true, query: false }` Fix #11257 --- test/types/middleware.test.ts | 32 ++++++++++++++++++++++++++------ types/index.d.ts | 10 ++++++++++ types/middlewares.d.ts | 1 + 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/test/types/middleware.test.ts b/test/types/middleware.test.ts index 7f1464375a4..f1234c81b80 100644 --- a/test/types/middleware.test.ts +++ b/test/types/middleware.test.ts @@ -117,12 +117,6 @@ schema.post>('findOneAndDelete', function(res, next) { const Test = model('Test', schema); -function gh11257(): void { - schema.pre('save', { document: true }, function() { - expectType>(this); - }); -} - function gh11480(): void { type IUserSchema = { name: string; @@ -155,3 +149,29 @@ function gh12583() { console.log(doc.name); }); } + +function gh11257() { + interface User { + name: string; + email: string; + avatar?: string; + } + + const schema = new Schema({ + name: { type: String, required: true }, + email: { type: String, required: true }, + avatar: String + }); + + schema.pre('save', { document: true }, function() { + expectType>(this); + }); + + schema.pre('updateOne', { document: true, query: false }, function() { + this.isNew; + }); + + schema.pre('updateOne', { document: false, query: true }, function() { + this.find(); + }); +} diff --git a/types/index.d.ts b/types/index.d.ts index b2973fd8aad..14a0e79feac 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -305,6 +305,16 @@ declare module 'mongoose' { post(method: 'insertMany' | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction): this; /** Defines a pre hook for the model. */ + pre>( + method: DocumentOrQueryMiddleware | DocumentOrQueryMiddleware[], + options: SchemaPreOptions & { document: true; query: false; }, + fn: PreMiddlewareFunction + ): this; + pre>( + method: DocumentOrQueryMiddleware | DocumentOrQueryMiddleware[], + options: SchemaPreOptions & { document: false; query: true; }, + fn: PreMiddlewareFunction + ): this; pre>(method: 'save', fn: PreSaveMiddlewareFunction): this; pre>(method: 'save', options: SchemaPreOptions, fn: PreSaveMiddlewareFunction): this; pre>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, fn: PreMiddlewareFunction): this; diff --git a/types/middlewares.d.ts b/types/middlewares.d.ts index 7aa28b6753f..270524f5519 100644 --- a/types/middlewares.d.ts +++ b/types/middlewares.d.ts @@ -2,6 +2,7 @@ declare module 'mongoose' { type MongooseDocumentMiddleware = 'validate' | 'save' | 'remove' | 'updateOne' | 'deleteOne' | 'init'; type MongooseQueryMiddleware = 'count' | 'estimatedDocumentCount' | 'countDocuments' | 'deleteMany' | 'deleteOne' | 'distinct' | 'find' | 'findOne' | 'findOneAndDelete' | 'findOneAndRemove' | 'findOneAndReplace' | 'findOneAndUpdate' | 'remove' | 'replaceOne' | 'update' | 'updateOne' | 'updateMany'; + type DocumentOrQueryMiddleware = 'updateOne' | 'deleteOne' | 'remove'; type MiddlewareOptions = { /** From bb803b7d4259b27b88d99c3f71b6864db2090bc9 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Thu, 8 Dec 2022 10:31:17 -0700 Subject: [PATCH 2/5] try undoing $fill to see if that fixes benchmark --- types/aggregate.d.ts | 2 +- types/expressions.d.ts | 22 ---------------------- types/pipelinestage.d.ts | 14 +------------- 3 files changed, 2 insertions(+), 36 deletions(-) diff --git a/types/aggregate.d.ts b/types/aggregate.d.ts index 5352e22d0f6..e0a4a93249d 100644 --- a/types/aggregate.d.ts +++ b/types/aggregate.d.ts @@ -134,7 +134,7 @@ declare module 'mongoose' { facet(options: PipelineStage.Facet['$facet']): this; /** Appends a new $fill operator to this aggregate pipeline */ - fill(arg: PipelineStage.Fill['$fill']): this; + //fill(arg: PipelineStage.Fill['$fill']): this; /** Appends new custom $graphLookup operator(s) to this aggregate pipeline, performing a recursive search on a collection. */ graphLookup(options: PipelineStage.GraphLookup['$graphLookup']): this; diff --git a/types/expressions.d.ts b/types/expressions.d.ts index b17659528c6..ecd7b3e6b79 100644 --- a/types/expressions.d.ts +++ b/types/expressions.d.ts @@ -1190,26 +1190,6 @@ declare module 'mongoose' { $last: Expression; } - export interface LinearFill { - /** - * Fills null and missing fields in a window using linear interpolation based on surrounding field values. - * - * @version 5.3 - * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearFill - */ - $linearFill: Expression - } - - export interface Locf { - /** - * Last observation carried forward. Sets values for null and missing fields in a window to the last non-null value for the field. - * - * @version 5.2 - * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf - */ - $locf: Expression - } - export interface Map { /** * Applies a subexpression to each element of an array and returns the array of resulting values in order. Accepts named parameters. @@ -2765,8 +2745,6 @@ declare module 'mongoose' { Expression.First | Expression.Integral | Expression.Last | - Expression.LinearFill | - Expression.Locf | Expression.Max | Expression.Min | Expression.Push | diff --git a/types/pipelinestage.d.ts b/types/pipelinestage.d.ts index 37d228ff1b7..9086a4afb30 100644 --- a/types/pipelinestage.d.ts +++ b/types/pipelinestage.d.ts @@ -8,9 +8,7 @@ declare module 'mongoose' { | PipelineStage.BucketAuto | PipelineStage.CollStats | PipelineStage.Count - | PipelineStage.Densify | PipelineStage.Facet - | PipelineStage.Fill | PipelineStage.GeoNear | PipelineStage.GraphLookup | PipelineStage.Group @@ -91,16 +89,6 @@ declare module 'mongoose' { } } - export interface Fill { - /** [`$fill` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/fill/) */ - $fill: { - partitionBy?: Expression, - partitionByFields?: string[], - sortBy?: Record, - output: Record - } - } - export interface Facet { /** [`$facet` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/facet/) */ $facet: Record; @@ -213,7 +201,7 @@ declare module 'mongoose' { export interface ReplaceWith { /** [`$replaceWith` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/replaceWith/) */ - $replaceWith: ObjectExpressionOperator | { [field: string]: Expression } | `$${string}`; + $replaceWith: ObjectExpressionOperator; } export interface Sample { From 5c92365335e3fa9535d3b57383d5f89eb6a127d6 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Thu, 8 Dec 2022 10:34:30 -0700 Subject: [PATCH 3/5] Revert "try undoing $fill to see if that fixes benchmark" This reverts commit bb803b7d4259b27b88d99c3f71b6864db2090bc9. --- types/aggregate.d.ts | 2 +- types/expressions.d.ts | 22 ++++++++++++++++++++++ types/pipelinestage.d.ts | 14 +++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/types/aggregate.d.ts b/types/aggregate.d.ts index e0a4a93249d..5352e22d0f6 100644 --- a/types/aggregate.d.ts +++ b/types/aggregate.d.ts @@ -134,7 +134,7 @@ declare module 'mongoose' { facet(options: PipelineStage.Facet['$facet']): this; /** Appends a new $fill operator to this aggregate pipeline */ - //fill(arg: PipelineStage.Fill['$fill']): this; + fill(arg: PipelineStage.Fill['$fill']): this; /** Appends new custom $graphLookup operator(s) to this aggregate pipeline, performing a recursive search on a collection. */ graphLookup(options: PipelineStage.GraphLookup['$graphLookup']): this; diff --git a/types/expressions.d.ts b/types/expressions.d.ts index ecd7b3e6b79..b17659528c6 100644 --- a/types/expressions.d.ts +++ b/types/expressions.d.ts @@ -1190,6 +1190,26 @@ declare module 'mongoose' { $last: Expression; } + export interface LinearFill { + /** + * Fills null and missing fields in a window using linear interpolation based on surrounding field values. + * + * @version 5.3 + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearFill + */ + $linearFill: Expression + } + + export interface Locf { + /** + * Last observation carried forward. Sets values for null and missing fields in a window to the last non-null value for the field. + * + * @version 5.2 + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf + */ + $locf: Expression + } + export interface Map { /** * Applies a subexpression to each element of an array and returns the array of resulting values in order. Accepts named parameters. @@ -2745,6 +2765,8 @@ declare module 'mongoose' { Expression.First | Expression.Integral | Expression.Last | + Expression.LinearFill | + Expression.Locf | Expression.Max | Expression.Min | Expression.Push | diff --git a/types/pipelinestage.d.ts b/types/pipelinestage.d.ts index 9086a4afb30..37d228ff1b7 100644 --- a/types/pipelinestage.d.ts +++ b/types/pipelinestage.d.ts @@ -8,7 +8,9 @@ declare module 'mongoose' { | PipelineStage.BucketAuto | PipelineStage.CollStats | PipelineStage.Count + | PipelineStage.Densify | PipelineStage.Facet + | PipelineStage.Fill | PipelineStage.GeoNear | PipelineStage.GraphLookup | PipelineStage.Group @@ -89,6 +91,16 @@ declare module 'mongoose' { } } + export interface Fill { + /** [`$fill` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/fill/) */ + $fill: { + partitionBy?: Expression, + partitionByFields?: string[], + sortBy?: Record, + output: Record + } + } + export interface Facet { /** [`$facet` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/facet/) */ $facet: Record; @@ -201,7 +213,7 @@ declare module 'mongoose' { export interface ReplaceWith { /** [`$replaceWith` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/replaceWith/) */ - $replaceWith: ObjectExpressionOperator; + $replaceWith: ObjectExpressionOperator | { [field: string]: Expression } | `$${string}`; } export interface Sample { From 69f53923405e454d81d7cb9ce92a75971394bcbe Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 19 Dec 2022 16:50:15 -0500 Subject: [PATCH 4/5] chore: bump ts-benchmark limit slightly to make benchmark pass --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50942427dad..25c2ae169ff 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "test-tsd": "node ./test/types/check-types-filename && tsd", "tdd": "mocha ./test/*.test.js --inspect --watch --recursive --watch-files ./**/*.{js,ts}", "test-coverage": "nyc --reporter=html --reporter=text npm test", - "ts-benchmark": "ts-benchmark -p ./benchmarks/typescript/simple -f 17/100000 18 29 32", + "ts-benchmark": "ts-benchmark -p ./benchmarks/typescript/simple -f 17/110000 18 29 32", "ts-benchmark-watch": "ts-benchmark -p ./benchmarks/typescript/simple -w ./types -i -s -f 17/100000 18 29 32 -b master" }, "main": "./index.js", From e1259922e602eeb1470456c9e7d695ee3e43d4de Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 19 Dec 2022 16:56:57 -0500 Subject: [PATCH 5/5] chore: correctly bump benchmark limit --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 131200b6b03..589bab7e8a4 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -37,7 +37,7 @@ jobs: - run: npm install working-directory: benchmarks/typescript/simple - - run: npx ts-benchmark -p ./ -f 17/100000 18 29 32 -b master -g -t --colors + - run: npx ts-benchmark -p ./ -f 17/110000 18 29 32 -b master -g -t --colors working-directory: benchmarks/typescript/simple env: DB_URL: ${{ secrets.DB_URL }}