this is my PostModel
import mongoose, { Document, Model, Schema } from “mongoose”;
import { User, UserType } from “./userModel”;
import { catchAsync } from “…/utils/catchAsync”;
import slugify from “slugify”;
interface PostType extends Document {
title: string;
detail: string;
author: any;
createAt: Date;
slug: string;
image: string;
_doc?: any;
likes: number;
}
const postSchema = new mongoose.Schema(
{
title: {
type: “string”,
required: [true, “must have a tittle”],
},
detail: {
type: “string”,
// required: [true, “must have a post detail”],
},
author: { type: mongoose.Schema.ObjectId, ref: “User” },
createAt: {
type: Date,
default: Date.now,
},
slug: { type: "string" },
image: [String],
likes: { type: "Number", default: 0 },
},
{
toJSON: {
virtuals: true,
},
toObject: {
virtuals: true,
},
},
);
postSchema.pre(“save”, function (next) {
this.slug = slugify(${this.title}-${this._id}
, { lower: true });
next();
});
// postSchema.pre(/^find/, function (next) {
// console.log(“Middleware triggered!”);
// this.populate({
// path: “author”,
// strictPopulate: false,
// });
// next();
// });
// postSchema.statics.calcPost = async function (userId) {
// const numPosts = await this.aggregate([
// {
// $match: { author: userId },
// },
// {
// $count: “totalPosts”,
// },
// ]);
// return numPosts.length > 0 ? numPosts[0].totalPosts : 0;
// };
// postSchema.post(“save”, async function (doc: PostType) {
// await this.constructor.calcPost(doc.author);
// });
export const Post: Model = mongoose.model(
“Post”,
postSchema,
);
this is my User Model import mongoose, { Document, Model, Query } from “mongoose”;
import bcrypt from “bcryptjs”;
import validator from “validator”;
import * as crypto from “crypto”;
export interface UserType extends Document {
email: string;
name: string;
password: string;
passwordConfirmed: string | undefined;
profileImage: string;
active: boolean;
posts: any;
passwordChangedAt: Date;
passwordResetToken: string | undefined;
passwordResetExpired: Date | undefined;
changedPasswordAfter: (JWTtimestamp: number) => boolean;
createPasswordResetToken: () => string;
comparePassword: (
inputPassword: string,
passFromDB: string,
) => Promise;
}
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, “name is required”],
minlength: 5,
},
email: {
type: String,
unique: true,
required: [true, “email is required”],
validate: [validator.isEmail, “must be a valid email”],
},
password: {
type: String,
required: [true, “password is required”],
minlength: 8,
},
posts: [{ type: mongoose.Schema.ObjectId, ref: “Post” }],
passwordConfirmed: String,
profileImage: { type: String, default: "defaultUser.svg" },
active: { type: Boolean, default: true, select: false },
passwordChangedAt: Date,
passwordResetToken: String,
passwordResetExpired: Date,
},
{
toJSON: {
virtuals: true,
},
toObject: {
virtuals: true,
},
},
);
// Define the comparePassword method
userSchema.pre(“save”, async function (next) {
// Hash password before saving
if (!this.isModified(“password”)) return next(); //this will check if there is no a change for the password
this.password = await bcrypt.hash(this.password, 12); //this will hash the password
this.passwordConfirmed = undefined; //this will set the passwordConfirmed to undefined after saving
next();
});
userSchema.pre(“save”, function (next) {
// This middleware will run when the password is modified, except when a new user is created.
// It updates the passwordChangedAt field to the current date and time minus 1000 milliseconds.
if (!this.isModified(“password”) || this.isNew) return next(); //if there is no change to the password
this.passwordChangedAt = new Date(Date.now() - 1000);
next();
});
userSchema.methods.comparePassword = async function (
inputPassword: string,
passFromDB: string,
) {
return bcrypt.compare(inputPassword, passFromDB);
};
// Explicitly type the ‘this’ context as a Mongoose query object for query middleware hooks
userSchema.pre<Query<any, UserType>>(/^find/, function (next) {
this.populate({
path: “posts”,
});
next();
});
userSchema.pre<Query<any, UserType>>(/^find/, function (next) {
//use type Query for query middleware
this.find({ active: { $ne: false } });
next();
});
userSchema.methods.changedPasswordAfter = function (JWTtimestamp: number) {
//this will update the password after change time
if (this.passwordChangedAt) {
//if the the current document has the passwordChangedAt property
const chnagedTimeStamp = parseInt(
(this.passwordChangedAt.getTime() / 1000).toString(), //this will gert the change time in milliseconds
10,
);
return JWTtimestamp < chnagedTimeStamp; //this
}
return false;
};
userSchema.methods.createPasswordResetToken = function (this: UserType) {
const randRestToken = crypto.randomBytes(32).toString(“hex”);
this.passwordResetToken = crypto
.createHash(“sha256”)
.update(randRestToken)
.digest(“hex”);
console.log(this.passwordResetToken, “in model”);
this.passwordResetExpired = new Date(Date.now() + 10 * 60 * 1000);
return randRestToken;
};
export const User: Model = mongoose.model(
“User”,
userSchema,
);
pls help me