From f8cede03e6de70ab3337d77deb20fa6055868802 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 25 Nov 2022 16:55:19 -0500 Subject: [PATCH 1/5] feat(schema+types): add `{ errorHandler: true }` option to Schema `post()` for better TypeScript support Fix #12595 --- package.json | 2 +- test/types/middleware.test.ts | 20 ++++++++++++++++++++ types/index.d.ts | 5 +++++ types/middlewares.d.ts | 7 ++++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 48899d57b59..24ec752128d 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "license": "MIT", "dependencies": { "bson": "^4.7.0", - "kareem": "2.4.1", + "kareem": "file:../kareem/kareem-2.4.1.tgz", "mongodb": "4.11.0", "mpath": "0.9.0", "mquery": "4.0.3", diff --git a/test/types/middleware.test.ts b/test/types/middleware.test.ts index 4b7b07d3437..7f1464375a4 100644 --- a/test/types/middleware.test.ts +++ b/test/types/middleware.test.ts @@ -135,3 +135,23 @@ function gh11480(): void { next(); }); } + +function gh12583() { + interface IUser { + name: string; + email: string; + avatar?: string; + } + + const userSchema = new Schema({ + name: { type: String, required: true }, + email: { type: String, required: true }, + avatar: String + }); + + userSchema.post('save', { errorHandler: true }, function(error, doc, next) { + expectType(error); + console.log(error.name); + console.log(doc.name); + }); +} diff --git a/types/index.d.ts b/types/index.d.ts index b1ce3eabffb..974366e0d26 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -274,6 +274,11 @@ declare module 'mongoose' { plugin, POptions extends Parameters[1] = Parameters[1]>(fn: PFunc, opts?: POptions): this; /** Defines a post hook for the model. */ + post>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption): this; + post>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption): this; + post>(method: 'aggregate' | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption>): this; + post(method: 'insertMany' | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption): this; + post>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, fn: PostMiddlewareFunction>): this; post>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction>): this; post>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PostMiddlewareFunction): this; diff --git a/types/middlewares.d.ts b/types/middlewares.d.ts index b8e604f2dad..06c4ac6ca09 100644 --- a/types/middlewares.d.ts +++ b/types/middlewares.d.ts @@ -3,7 +3,11 @@ 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 MiddlewareOptions = { document?: boolean, query?: boolean }; + type MiddlewareOptions = { + document?: boolean, + query?: boolean, + errorHandler?: boolean + }; type SchemaPreOptions = MiddlewareOptions; type SchemaPostOptions = MiddlewareOptions; @@ -11,4 +15,5 @@ declare module 'mongoose' { type PreSaveMiddlewareFunction = (this: ThisType, next: CallbackWithoutResultAndOptionalError, opts: SaveOptions) => void | Promise; type PostMiddlewareFunction = (this: ThisType, res: ResType, next: CallbackWithoutResultAndOptionalError) => void | Promise; type ErrorHandlingMiddlewareFunction = (this: ThisType, err: NativeError, res: ResType, next: CallbackWithoutResultAndOptionalError) => void; + type ErrorHandlingMiddlewareWithOption = (this: ThisType, err: NativeError, res: ResType | null, next: CallbackWithoutResultAndOptionalError) => void | Promise; } From 07069f3b6a6f9af3d10adfe3af88be910c2f08e4 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 30 Nov 2022 11:05:20 -0500 Subject: [PATCH 2/5] fix(types): support using `UpdateQuery` in `bulkWrite()` Fix #12595 Re: #11911 --- types/index.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/index.d.ts b/types/index.d.ts index 4c843d940fa..4c35c5200d4 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -501,7 +501,12 @@ declare module 'mongoose' { $pullAll?: AnyKeys & AnyObject; /** @see https://docs.mongodb.com/manual/reference/operator/update-bitwise/ */ - $bit?: Record; + // Needs to be `AnyKeys` for now, because anything stricter makes us incompatible + // with the MongoDB Node driver's `UpdateFilter` interface (see gh-12595, gh-11911) + // and using the Node driver's `$bit` definition breaks because their `OnlyFieldsOfType` + // interface breaks on Mongoose Document class due to circular references. + // Re-evaluate this when we drop `extends Document` support in document interfaces. + $bit?: AnyKeys; }; export type UpdateWithAggregationPipeline = UpdateAggregationStage[]; From d1a20d7eecdecbcf334229e8fef7ded2b02ea5e4 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Thu, 1 Dec 2022 21:43:25 -0500 Subject: [PATCH 3/5] feat: upgrade to kareem@2.5.0 for mongoosejs/kareem#34 re: #12583 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd22ea7a5cc..cb0047cb9ce 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "license": "MIT", "dependencies": { "bson": "^4.7.0", - "kareem": "2.4.1", + "kareem": "2.5.0", "mongodb": "4.12.1", "mpath": "0.9.0", "mquery": "4.0.3", From dd95d22d7515f1f9c4ceacb812df0831bc436e37 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Thu, 1 Dec 2022 21:49:37 -0500 Subject: [PATCH 4/5] Update types/middlewares.d.ts Co-authored-by: hasezoey --- types/middlewares.d.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/types/middlewares.d.ts b/types/middlewares.d.ts index 06c4ac6ca09..cf28439f3fb 100644 --- a/types/middlewares.d.ts +++ b/types/middlewares.d.ts @@ -4,8 +4,20 @@ declare module 'mongoose' { type MongooseQueryMiddleware = 'count' | 'estimatedDocumentCount' | 'countDocuments' | 'deleteMany' | 'deleteOne' | 'distinct' | 'find' | 'findOne' | 'findOneAndDelete' | 'findOneAndRemove' | 'findOneAndReplace' | 'findOneAndUpdate' | 'remove' | 'replaceOne' | 'update' | 'updateOne' | 'updateMany'; type MiddlewareOptions = { + /** + * Enable this Hook for the Document Methods + * @default true + */ document?: boolean, + /** + * Enable this Hook for the Query Methods + * @default true + */ query?: boolean, + /** + * Explicitly set this function to be a Error handler instead of based on how many arguments are used + * @default false + */ errorHandler?: boolean }; type SchemaPreOptions = MiddlewareOptions; From 4bedc7a456e8253fbfaa4e3b1a1b1a619a88aceb Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Thu, 1 Dec 2022 21:52:39 -0500 Subject: [PATCH 5/5] style: fix lint --- types/middlewares.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/types/middlewares.d.ts b/types/middlewares.d.ts index cf28439f3fb..7aa28b6753f 100644 --- a/types/middlewares.d.ts +++ b/types/middlewares.d.ts @@ -4,18 +4,18 @@ declare module 'mongoose' { type MongooseQueryMiddleware = 'count' | 'estimatedDocumentCount' | 'countDocuments' | 'deleteMany' | 'deleteOne' | 'distinct' | 'find' | 'findOne' | 'findOneAndDelete' | 'findOneAndRemove' | 'findOneAndReplace' | 'findOneAndUpdate' | 'remove' | 'replaceOne' | 'update' | 'updateOne' | 'updateMany'; type MiddlewareOptions = { - /** + /** * Enable this Hook for the Document Methods * @default true */ document?: boolean, - /** + /** * Enable this Hook for the Query Methods * @default true */ query?: boolean, - /** - * Explicitly set this function to be a Error handler instead of based on how many arguments are used + /** + * Explicitly set this function to be a Error handler instead of based on how many arguments are used * @default false */ errorHandler?: boolean