Reputation: 11
res.locals.user
and i wrote a function that will act like a middleware between the method call and DB query so for exampleconst { Document, Model, default: mongoose } = require('mongoose');
//store reference to original
const findOriginalMethod = Model.find;
// override the mongoose methods to accept response as the first parameter
UsersSchema.statics.find = async function (res,...args) {
let self = this;
const result = await findOriginalMethod.call(self, ...args);
const historyData = {
user: res.locals.user.userName,
userId: res.locals.user._id,
action: 'find',
collectionName: 'Users',
};
historyData.data = result;
historyData.documentId = result._id;
// historyEmitter.emit('saveLog', historyData);
return result;
}
import express from 'express';
import { Document, Model, default as mongoose } from 'mongoose';
//store reference to original
const findOriginalMethod = Model.find;
//get the return type of the accessed method
type findReturnType = ReturnType<typeof findOriginalMethod>;
//get the type parameters of the accessed method
type findParamsType = Parameters<typeof findOriginalMethod>;
// override the mongoose methods to accept response as the first parameter
UsersSchema.statics.find = async function (res: express.Response, ...args: findParamsType): Promise<findReturnType> {
let self = this;
const result = await findOriginalMethod.call(self, ...args) as any;
const historyData: any = {
user: res.locals.user.userName,
userId: res.locals.user._id,
// db: res.locals.db,
source: res.locals.payload.role,
action: 'find',
collectionName: 'Users',
};
historyData.data = result;
historyData.documentId = result._id;
return result;
}
export interface IUserMethods extends Model<IUser> {
find(res: express.Response, ...args: findParamsType): Promise<findReturnType>;
}
// const Users = connection.model('Users') || connection.model('Users', UsersSchema);
const Users = connection.models.Users
? connection.model<IUser, IUserMethods>('Users')
: connection.model<IUser, IUserMethods>(
'Users',
UsersSchema,
);
export default Users;
IUserMethods
interface but got the following errorInterface 'IUserMethods' incorrectly extends interface 'Model<IUser, {}, {}, {}, Document<unknown, {}, IUser> & IUser & { _id: ObjectId; }, any>'.
The types returned by 'find(...)' are incompatible between these types.
Type 'Promise<Query<unknown[], unknown, {}, any, "find">>' is missing the following properties from type 'Query<(FlattenMaps<IUser> & { _id: ObjectId; })[], any, {}, IUser, "find">': _mongooseOptions, exec, $where, all, and 86 more.
global.d.ts
but it's also doesn't workimport mongoose from "mongoose";
import express from 'express';
declare global {
namespace mongoose {
interface Model<T> {
find(res: express.Response, ...args: Parameters<typeof mongoose.Model.find>): Promise<ReturnType<typeof mongoose.Model.find>>
}
}
}
Can anyone help me to override the typeof original mongoose model methods to aceept response as the first parameter then the other parameters next ?
Or if there's any other better way to accept response and act like a middleware between the method calls and pre
/ post
method execution because mongoose middlewares couldn't get anything new except the things passed to the method like query, projection, etc..
Upvotes: 1
Views: 72