refactor: change mongoose models to use ES6 classes

This commit is contained in:
Paul Bienkowski 2020-11-25 15:55:56 +01:00
parent c5b5dda0b4
commit b75ba42969
4 changed files with 132 additions and 129 deletions

View file

@ -1,6 +1,6 @@
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const CommentSchema = new mongoose.Schema( const schema = new mongoose.Schema(
{ {
body: String, body: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
@ -9,14 +9,17 @@ const CommentSchema = new mongoose.Schema(
{ timestamps: true }, { timestamps: true },
); );
// Requires population of author class Comment extends mongoose.Model {
CommentSchema.methods.toJSONFor = function (user) { toJSONFor(user) {
return { return {
id: this._id, id: this._id,
body: this.body, body: this.body,
createdAt: this.createdAt, createdAt: this.createdAt,
author: this.author.toProfileJSONFor(user), author: this.author.toProfileJSONFor(user),
}; };
}; }
}
mongoose.model('Comment', CommentSchema); mongoose.model(Comment, schema);
module.exports = Comment;

View file

@ -2,7 +2,7 @@ const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator'); const uniqueValidator = require('mongoose-unique-validator');
const slug = require('slug'); const slug = require('slug');
const TrackSchema = new mongoose.Schema( const schema = new mongoose.Schema(
{ {
slug: { type: String, lowercase: true, unique: true }, slug: { type: String, lowercase: true, unique: true },
title: String, title: String,
@ -18,9 +18,9 @@ const TrackSchema = new mongoose.Schema(
{ timestamps: true }, { timestamps: true },
); );
TrackSchema.plugin(uniqueValidator, { message: 'is already taken' }); schema.plugin(uniqueValidator, { message: 'is already taken' });
TrackSchema.pre('validate', function (next) { schema.pre('validate', function (next) {
if (!this.slug) { if (!this.slug) {
this.slugify(); this.slugify();
} }
@ -28,38 +28,42 @@ TrackSchema.pre('validate', function (next) {
next(); next();
}); });
TrackSchema.methods.slugify = function () { class Track extends mongoose.Model {
this.slug = slug(this.title) + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36); slugify() {
}; this.slug = slug(this.title) + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36);
TrackSchema.methods.isVisibleTo = function (user) {
if (this.visible) {
return true;
} }
if (!user) { isVisibleTo(user) {
if (this.visible) {
return true;
}
if (!user) {
return false;
}
if (user._id.toString() === this.author._id.toString()) {
return true;
}
return false; return false;
} }
if (user._id.toString() === this.author._id.toString()) { toJSONFor(user, include) {
return true; return {
slug: this.slug,
title: this.title,
description: this.description,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
visibleForAll: this.author ? this.author.areTracksVisibleForAll : false,
visible: this.visible,
author: this.author.toProfileJSONFor(user),
...(include && include.body ? { body: this.body } : {}),
};
} }
}
return false; mongoose.model(Track, schema);
};
TrackSchema.methods.toJSONFor = function (user, include) { module.exports = Track;
return {
slug: this.slug,
title: this.title,
description: this.description,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
visibleForAll: this.author ? this.author.areTracksVisibleForAll : false,
visible: this.visible,
author: this.author.toProfileJSONFor(user),
...(include && include.body ? { body: this.body } : {}),
};
};
mongoose.model('Track', TrackSchema);

View file

@ -2,7 +2,7 @@ const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator'); const uniqueValidator = require('mongoose-unique-validator');
const slug = require('slug'); const slug = require('slug');
const TrackDataSchema = new mongoose.Schema( const schema = new mongoose.Schema(
{ {
slug: { type: String, lowercase: true, unique: true }, slug: { type: String, lowercase: true, unique: true },
points: [ points: [
@ -23,17 +23,21 @@ const TrackDataSchema = new mongoose.Schema(
{ timestamps: true }, { timestamps: true },
); );
TrackDataSchema.plugin(uniqueValidator, { message: 'is already taken' }); schema.plugin(uniqueValidator, { message: 'is already taken' });
TrackDataSchema.pre('validate', function (next) { schema.pre('validate', function (next) {
if (!this.slug) { if (!this.slug) {
this.slugify(); this.slugify();
} }
next(); next();
}); });
TrackDataSchema.methods.slugify = function () { class TrackData extends mongoose.Model {
this.slug = slug('td') + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36); slugify() {
}; this.slug = 'td-' + String((Math.random() * Math.pow(36, 6)) | 0).toString(36);
}
}
mongoose.model('TrackData', TrackDataSchema); mongoose.model(TrackData, schema);
module.exports = TrackData;

View file

@ -4,7 +4,7 @@ const crypto = require('crypto');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const secret = require('../config').secret; const secret = require('../config').secret;
const UserSchema = new mongoose.Schema( const schema = new mongoose.Schema(
{ {
username: { username: {
type: String, type: String,
@ -39,96 +39,88 @@ const UserSchema = new mongoose.Schema(
{ timestamps: true }, { timestamps: true },
); );
UserSchema.plugin(uniqueValidator, { message: 'ist bereits vergeben. Sorry!' }); schema.plugin(uniqueValidator, { message: 'ist bereits vergeben. Sorry!' });
UserSchema.methods.validPassword = function (password) { class User extends mongoose.Model {
const hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex'); validPassword(password) {
return this.hash === hash; const hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
}; return this.hash === hash;
}
UserSchema.methods.setPassword = function (password) { setPassword(password) {
this.salt = crypto.randomBytes(16).toString('hex'); this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex'); this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
}; }
UserSchema.methods.generateJWT = function () { generateJWT() {
const today = new Date(); const today = new Date();
const exp = new Date(today); const exp = new Date(today);
exp.setDate(today.getDate() + 60); exp.setDate(today.getDate() + 60);
return jwt.sign( return jwt.sign(
{ {
id: this._id, id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
},
secret,
);
}
toAuthJSON() {
return {
username: this.username, username: this.username,
exp: parseInt(exp.getTime() / 1000), email: this.email,
}, token: this.generateJWT(),
secret, bio: this.bio,
); image: this.image,
}; areTracksVisibleForAll: this.areTracksVisibleForAll,
apiKey: this._id,
UserSchema.methods.toAuthJSON = function () { };
return {
username: this.username,
email: this.email,
token: this.generateJWT(),
bio: this.bio,
image: this.image,
areTracksVisibleForAll: this.areTracksVisibleForAll,
apiKey: this._id,
};
};
UserSchema.methods.toProfileJSONFor = function (user) {
return {
username: this.username,
bio: this.bio,
image: this.image || 'https://static.productionready.io/images/smiley-cyrus.jpg',
following: user ? user.isFollowing(this._id) : false,
};
};
UserSchema.methods.favorite = function (id) {
if (this.favorites.indexOf(id) === -1) {
this.favorites.push(id);
} }
return this.save(); toProfileJSONFor(user) {
}; return {
username: this.username,
UserSchema.methods.unfavorite = function (id) { bio: this.bio,
this.favorites.remove(id); image: this.image || 'https://static.productionready.io/images/smiley-cyrus.jpg',
return this.save(); following: user ? user.isFollowing(this._id) : false,
}; };
UserSchema.methods.isFavorite = function (id) {
return this.favorites.some(function (favoriteId) {
return favoriteId.toString() === id.toString();
});
};
UserSchema.methods.isTrackVisible = function (id) {
return this.areTracksVisibleForAll();
};
UserSchema.methods.follow = function (id) {
if (this.following.indexOf(id) === -1) {
this.following.push(id);
} }
return this.save(); async favorite(id) {
}; if (this.favorites.indexOf(id) === -1) {
this.favorites.push(id);
}
UserSchema.methods.unfollow = function (id) { return await this.save();
this.following.remove(id); }
return this.save();
};
UserSchema.methods.isFollowing = function (id) { async unfavorite(id) {
return this.following.some(function (followId) { this.favorites.remove(id);
return followId.toString() === id.toString(); return await this.save();
}); }
};
mongoose.model('User', UserSchema); follow(id) {
if (this.following.indexOf(id) === -1) {
this.following.push(id);
}
module.exports = mongoose.model('User'); return this.save();
}
unfollow(id) {
this.following.remove(id);
return this.save();
}
isFollowing(id) {
return this.following.some(function (followId) {
return followId.toString() === id.toString();
});
}
}
mongoose.model(User, schema);
module.exports = User;