From 7d9cc0efbf536bcf9bf596360bd8a12652d85b95 Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Tue, 6 Apr 2021 22:06:53 +0200 Subject: :art: remove _id and __v from response --- src/models/index.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/models/index.ts (limited to 'src/models/index.ts') diff --git a/src/models/index.ts b/src/models/index.ts new file mode 100644 index 00000000..bb6024fe --- /dev/null +++ b/src/models/index.ts @@ -0,0 +1,28 @@ +import mongoose from "mongoose"; + +export * from "./Ban"; +export * from "./Channel"; +export * from "./Emoji"; +export * from "./Guild"; +export * from "./Invite"; +export * from "./Member"; +export * from "./Role"; +export * from "./User"; +export * from "./Activity"; +export * from "./Application"; +export * from "./Interaction"; +export * from "./Message"; +export * from "./Status"; +export * from "./VoiceState"; +export * from "./Event"; + +mongoose.plugin((schema: any) => { + schema.options.toJSON = { + virtuals: true, + versionKey: false, + transform(doc: any, ret: any) { + delete ret._id; + delete ret.__v; + }, + }; +}); -- cgit 1.5.1 From f48127f8a4881afc6dfb9b066b4eb357f1ef6c63 Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Wed, 7 Apr 2021 03:02:13 +0200 Subject: :bug: fix lean not working with virtuals --- package-lock.json | 39 +++++++++++++++++++++++ package.json | 1 + src/index.ts | 4 +-- src/models/Message.ts | 86 +++++++++++++++++++++++++-------------------------- src/models/index.ts | 27 +++++++++------- src/util/Database.ts | 9 ++++++ 6 files changed, 109 insertions(+), 57 deletions(-) (limited to 'src/models/index.ts') diff --git a/package-lock.json b/package-lock.json index 0e721c0c..902566ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ }, "devDependencies": { "@types/jsonwebtoken": "^8.5.0", + "@types/mongoose-lean-virtuals": "^0.5.1", "@types/node": "^14.14.25", "typescript": "^4.1.3" } @@ -47,6 +48,25 @@ "@types/node": "*" } }, + "node_modules/@types/mongoose": { + "version": "5.10.4", + "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.10.4.tgz", + "integrity": "sha512-U7fNDcTcdaSGzQ3+mlSBeebiYr6eaacJi330LTLOEh8Sm6mXfuec70ag/UXkL+alFm7pfAjFqfc7jEaJEJvAHQ==", + "dev": true, + "dependencies": { + "@types/mongodb": "*", + "@types/node": "*" + } + }, + "node_modules/@types/mongoose-lean-virtuals": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/mongoose-lean-virtuals/-/mongoose-lean-virtuals-0.5.1.tgz", + "integrity": "sha512-bNk+QLjP5VZU4EsJag4xQsjLAa8CEm/SKZDyiC2kM208wIrGum6daD7j45Oqs50bWNGfqZYRuEhh8xZ17D7aEw==", + "dev": true, + "dependencies": { + "@types/mongoose": "*" + } + }, "node_modules/@types/node": { "version": "14.14.25", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz", @@ -1164,6 +1184,25 @@ "@types/node": "*" } }, + "@types/mongoose": { + "version": "5.10.4", + "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.10.4.tgz", + "integrity": "sha512-U7fNDcTcdaSGzQ3+mlSBeebiYr6eaacJi330LTLOEh8Sm6mXfuec70ag/UXkL+alFm7pfAjFqfc7jEaJEJvAHQ==", + "dev": true, + "requires": { + "@types/mongodb": "*", + "@types/node": "*" + } + }, + "@types/mongoose-lean-virtuals": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/mongoose-lean-virtuals/-/mongoose-lean-virtuals-0.5.1.tgz", + "integrity": "sha512-bNk+QLjP5VZU4EsJag4xQsjLAa8CEm/SKZDyiC2kM208wIrGum6daD7j45Oqs50bWNGfqZYRuEhh8xZ17D7aEw==", + "dev": true, + "requires": { + "@types/mongoose": "*" + } + }, "@types/node": { "version": "14.14.25", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz", diff --git a/package.json b/package.json index 7900d301..b92228ff 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "devDependencies": { "@types/jsonwebtoken": "^8.5.0", + "@types/mongoose-lean-virtuals": "^0.5.1", "@types/node": "^14.14.25", "typescript": "^4.1.3" } diff --git a/src/index.ts b/src/index.ts index 914431d8..343a7496 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,6 @@ export * from "./models/index"; export * from "./util/index"; import Config, { DefaultOptions } from "./util/Config"; -import db, { MongooseCache } from "./util/Database"; +import db, { MongooseCache, toObject } from "./util/Database"; -export { Config, db, DefaultOptions, MongooseCache }; +export { Config, db, DefaultOptions, MongooseCache, toObject }; diff --git a/src/models/Message.ts b/src/models/Message.ts index 15f00cf4..ee038f97 100644 --- a/src/models/Message.ts +++ b/src/models/Message.ts @@ -1,8 +1,9 @@ import { Schema, Types, Document } from "mongoose"; import db from "../util/Database"; -import { UserModel } from "./User"; -import { MemberModel } from "./Member"; -import { RoleModel } from "./Role"; +import { PublicUser, UserModel } from "./User"; +import { MemberModel, PublicMember } from "./Member"; +import { Role, RoleModel } from "./Role"; +import { Channel } from "./Channel"; export interface Message { id: string; @@ -36,6 +37,12 @@ export interface Message { channel_id?: string; guild_id?: string; }; + // mongoose virtuals: + author?: PublicUser; + member?: PublicMember; + mentions?: PublicUser[]; + mention_roles?: Role[]; + mention_channels?: Channel[]; } export interface MessageDocument extends Document, Message { @@ -190,50 +197,39 @@ export const Embed = { ], }; -export const MessageSchema = new Schema( - { - id: String, +export const MessageSchema = new Schema({ + id: String, + channel_id: String, + author_id: String, + webhook_id: String, + guild_id: String, + application_id: String, + content: String, + timestamp: Date, + edited_timestamp: Date, + tts: Boolean, + mention_everyone: Boolean, + mention_user_ids: [String], + mention_role_ids: [String], + mention_channel_ids: [String], + attachments: [Attachment], + embeds: [Embed], + reactions: [Reaction], + nonce: Schema.Types.Mixed, // can be a long or a string + pinned: Boolean, + type: { type: Number }, + activity: { + type: Number, + party_id: String, + }, + flags: Types.Long, + stickers: [], + message_reference: { + message_id: String, channel_id: String, - author_id: String, - webhook_id: String, guild_id: String, - application_id: String, - content: String, - timestamp: Date, - edited_timestamp: Date, - tts: Boolean, - mention_everyone: Boolean, - mention_user_ids: [String], - mention_role_ids: [String], - mention_channel_ids: [String], - attachments: [Attachment], - embeds: [Embed], - reactions: [Reaction], - nonce: Schema.Types.Mixed, // can be a long or a string - pinned: Boolean, - type: { type: Number }, - activity: { - type: Number, - party_id: String, - }, - flags: Types.Long, - stickers: [], - message_reference: { - message_id: String, - channel_id: String, - guild_id: String, - }, }, - { - toJSON: { - transform: function (doc, ret) { - delete ret.mention_channel_ids; - delete ret.mention_user_ids; - delete ret.mention_role_ids; - }, - }, - } -); +}); MessageSchema.virtual("author", { ref: UserModel, @@ -270,6 +266,8 @@ MessageSchema.virtual("mention_channels", { justOne: false, }); +MessageSchema.set("removeResponse", ["mention_channel_ids", "mention_role_ids", "mention_user_ids", "author_id"]); + // TODO: missing Application Model // MessageSchema.virtual("application", { // ref: Application, diff --git a/src/models/index.ts b/src/models/index.ts index bb6024fe..03b9fe70 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -1,4 +1,20 @@ import mongoose from "mongoose"; +import { Schema } from "mongoose"; + +mongoose.plugin((schema: Schema, opts: any) => { + schema.set("toObject", { + virtuals: true, + versionKey: false, + transform(doc: any, ret: any) { + delete ret._id; + delete ret.__v; + const props = schema.get("removeResponse") || []; + props.forEach((prop: string) => { + delete ret[prop]; + }); + }, + }); +}); export * from "./Ban"; export * from "./Channel"; @@ -15,14 +31,3 @@ export * from "./Message"; export * from "./Status"; export * from "./VoiceState"; export * from "./Event"; - -mongoose.plugin((schema: any) => { - schema.options.toJSON = { - virtuals: true, - versionKey: false, - transform(doc: any, ret: any) { - delete ret._id; - delete ret.__v; - }, - }; -}); diff --git a/src/util/Database.ts b/src/util/Database.ts index 883c8dcd..e17eeccb 100644 --- a/src/util/Database.ts +++ b/src/util/Database.ts @@ -2,6 +2,7 @@ import "./MongoBigInt"; import mongoose, { Collection, Connection } from "mongoose"; import { ChangeStream, ChangeEvent, Long } from "mongodb"; import EventEmitter from "events"; +import { Document } from "mongoose"; const uri = process.env.MONGO_URL || "mongodb://localhost:27017/fosscord?readPreference=secondaryPreferred"; console.log(`[DB] connect: ${uri}`); @@ -10,6 +11,14 @@ const connection = mongoose.createConnection(uri, { autoIndex: true, useNewUrlPa export default connection; +function transform(document: T) { + return document.toObject({ virtuals: true }); +} + +export function toObject(document: T | T[]) { + return Array.isArray(document) ? document.map((x) => transform(x)) : transform(document); +} + export interface MongooseCache { on(event: "delete", listener: (id: string) => void): this; on(event: "change", listener: (data: any) => void): this; -- cgit 1.5.1 From a6d82b466f61c1b60b1058d75b0647f2c0ac91a0 Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Wed, 7 Apr 2021 20:26:19 +0200 Subject: :zap: use mongoose autopopulate --- package-lock.json | 36 +++++++++++++++++++++++++++++++++++- package.json | 4 +++- src/models/Guild.ts | 4 +++- src/models/Member.ts | 17 ++++++++++++++++- src/models/Message.ts | 16 ++++++++++++++-- src/models/Role.ts | 1 + src/models/User.ts | 7 +++++++ src/models/index.ts | 3 +++ 8 files changed, 82 insertions(+), 6 deletions(-) (limited to 'src/models/index.ts') diff --git a/package-lock.json b/package-lock.json index 902566ed..17d70c4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,10 +13,12 @@ "lambert-db": "^1.1.7", "missing-native-js-functions": "^1.2.2", "mongodb": "^3.6.6", - "mongoose": "^5.12.3" + "mongoose": "^5.12.3", + "mongoose-autopopulate": "^0.12.3" }, "devDependencies": { "@types/jsonwebtoken": "^8.5.0", + "@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-lean-virtuals": "^0.5.1", "@types/node": "^14.14.25", "typescript": "^4.1.3" @@ -58,6 +60,15 @@ "@types/node": "*" } }, + "node_modules/@types/mongoose-autopopulate": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@types/mongoose-autopopulate/-/mongoose-autopopulate-0.10.1.tgz", + "integrity": "sha512-L67MAIE3WEoTtt7a7/spRYk+76lgp67FAP6I38Y9NcC1kQuzwqnukTaJzodfb8180wxHZM4qt68u6x6ptuDRaQ==", + "dev": true, + "dependencies": { + "@types/mongoose": "*" + } + }, "node_modules/@types/mongoose-lean-virtuals": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@types/mongoose-lean-virtuals/-/mongoose-lean-virtuals-0.5.1.tgz", @@ -720,6 +731,14 @@ "url": "https://opencollective.com/mongoose" } }, + "node_modules/mongoose-autopopulate": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/mongoose-autopopulate/-/mongoose-autopopulate-0.12.3.tgz", + "integrity": "sha512-yNmYsfi6OpS/GQ+48mkB0KQ199ExHmmPrt3wt3fyxPHPMtEBGts7yq3wBQR6VgKCPOQaKvCI1URbJCPOtrPeLw==", + "peerDependencies": { + "mongoose": "4.x || 5.x" + } + }, "node_modules/mongoose-legacy-pluralize": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", @@ -1194,6 +1213,15 @@ "@types/node": "*" } }, + "@types/mongoose-autopopulate": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@types/mongoose-autopopulate/-/mongoose-autopopulate-0.10.1.tgz", + "integrity": "sha512-L67MAIE3WEoTtt7a7/spRYk+76lgp67FAP6I38Y9NcC1kQuzwqnukTaJzodfb8180wxHZM4qt68u6x6ptuDRaQ==", + "dev": true, + "requires": { + "@types/mongoose": "*" + } + }, "@types/mongoose-lean-virtuals": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@types/mongoose-lean-virtuals/-/mongoose-lean-virtuals-0.5.1.tgz", @@ -1694,6 +1722,12 @@ } } }, + "mongoose-autopopulate": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/mongoose-autopopulate/-/mongoose-autopopulate-0.12.3.tgz", + "integrity": "sha512-yNmYsfi6OpS/GQ+48mkB0KQ199ExHmmPrt3wt3fyxPHPMtEBGts7yq3wBQR6VgKCPOQaKvCI1URbJCPOtrPeLw==", + "requires": {} + }, "mongoose-legacy-pluralize": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", diff --git a/package.json b/package.json index b92228ff..9bf8cd16 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,12 @@ "lambert-db": "^1.1.7", "missing-native-js-functions": "^1.2.2", "mongodb": "^3.6.6", - "mongoose": "^5.12.3" + "mongoose": "^5.12.3", + "mongoose-autopopulate": "^0.12.3" }, "devDependencies": { "@types/jsonwebtoken": "^8.5.0", + "@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-lean-virtuals": "^0.5.1", "@types/node": "^14.14.25", "typescript": "^4.1.3" diff --git a/src/models/Guild.ts b/src/models/Guild.ts index d3f098ea..aa520329 100644 --- a/src/models/Guild.ts +++ b/src/models/Guild.ts @@ -96,12 +96,14 @@ GuildSchema.virtual("channels", { localField: "id", foreignField: "guild_id", justOne: false, + autopopulate: true, }); GuildSchema.virtual("roles", { ref: RoleModel, localField: "id", foreignField: "guild_id", justOne: false, + autopopulate: true, }); // nested populate is needed for member users: https://gist.github.com/yangsu/5312204 @@ -117,6 +119,7 @@ GuildSchema.virtual("emojis", { localField: "id", foreignField: "guild_id", justOne: false, + autopopulate: true, }); GuildSchema.virtual("joined_at", { @@ -125,7 +128,6 @@ GuildSchema.virtual("joined_at", { foreignField: "guild_id", justOne: true, }).get((member: any, virtual: any, doc: any) => { - console.log("get", member, this); return member.joined_at; }); diff --git a/src/models/Member.ts b/src/models/Member.ts index fc9d5b99..52151235 100644 --- a/src/models/Member.ts +++ b/src/models/Member.ts @@ -1,7 +1,19 @@ -import { PublicUser, User, UserModel } from "./User"; +import { PublicUser, PublicUserProjection, User, UserModel } from "./User"; import { Schema, Types, Document } from "mongoose"; import db from "../util/Database"; +export const PublicMemberProjection = { + id: true, + guild_id: true, + nick: true, + roles: true, + joined_at: true, + pending: true, + deaf: true, + mute: true, + premium_since: true, +}; + export interface Member { id: string; guild_id: string; @@ -80,6 +92,9 @@ MemberSchema.virtual("user", { localField: "id", foreignField: "id", justOne: true, + autopopulate: { + select: PublicUserProjection, + }, }); // @ts-ignore diff --git a/src/models/Message.ts b/src/models/Message.ts index ee038f97..15ff57d3 100644 --- a/src/models/Message.ts +++ b/src/models/Message.ts @@ -1,7 +1,7 @@ import { Schema, Types, Document } from "mongoose"; import db from "../util/Database"; -import { PublicUser, UserModel } from "./User"; -import { MemberModel, PublicMember } from "./Member"; +import { PublicUser, PublicUserProjection, UserModel } from "./User"; +import { MemberModel, PublicMember, PublicMemberProjection } from "./Member"; import { Role, RoleModel } from "./Role"; import { Channel } from "./Channel"; @@ -229,6 +229,14 @@ export const MessageSchema = new Schema({ channel_id: String, guild_id: String, }, + // virtual: + // author: { + // ref: UserModel, + // localField: "author_id", + // foreignField: "id", + // justOne: true, + // autopopulate: { select: { id: true, user_data: false } }, + // }, }); MessageSchema.virtual("author", { @@ -236,6 +244,7 @@ MessageSchema.virtual("author", { localField: "author_id", foreignField: "id", justOne: true, + autopopulate: { select: PublicUserProjection }, }); MessageSchema.virtual("member", { @@ -250,6 +259,7 @@ MessageSchema.virtual("mentions", { localField: "mention_user_ids", foreignField: "id", justOne: false, + autopopulate: { select: PublicUserProjection }, }); MessageSchema.virtual("mention_roles", { @@ -257,6 +267,7 @@ MessageSchema.virtual("mention_roles", { localField: "mention_role_ids", foreignField: "id", justOne: false, + autopopulate: true, }); MessageSchema.virtual("mention_channels", { @@ -264,6 +275,7 @@ MessageSchema.virtual("mention_channels", { localField: "mention_channel_ids", foreignField: "id", justOne: false, + autopopulate: { select: { id: true, guild_id: true, type: true, name: true } }, }); MessageSchema.set("removeResponse", ["mention_channel_ids", "mention_role_ids", "mention_user_ids", "author_id"]); diff --git a/src/models/Role.ts b/src/models/Role.ts index adb75b0a..84ad55d0 100644 --- a/src/models/Role.ts +++ b/src/models/Role.ts @@ -34,6 +34,7 @@ export const RoleSchema = new Schema({ bot_id: String, }, }); +RoleSchema.set("removeResponse", ["guild_id"]); // @ts-ignore export const RoleModel = db.model("Role", RoleSchema, "roles"); diff --git a/src/models/User.ts b/src/models/User.ts index 76251e09..1f01e837 100644 --- a/src/models/User.ts +++ b/src/models/User.ts @@ -3,6 +3,13 @@ import { ClientStatus, Status } from "./Status"; import { Schema, Types, Document } from "mongoose"; import db from "../util/Database"; +export const PublicUserProjection = { + username: true, + discriminator: true, + id: true, + public_flags: true, + avatar: true, +}; export interface User { id: string; username: string; // username max length 32, min 2 diff --git a/src/models/index.ts b/src/models/index.ts index 03b9fe70..876e5984 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -1,5 +1,8 @@ import mongoose from "mongoose"; import { Schema } from "mongoose"; +import mongooseAutoPopulate from "mongoose-autopopulate"; + +mongoose.plugin(mongooseAutoPopulate); mongoose.plugin((schema: Schema, opts: any) => { schema.set("toObject", { -- cgit 1.5.1