diff --git a/util/src/dtos/DmChannelDTO.ts b/util/src/dtos/DmChannelDTO.ts
index 8b7a18fd..226b2f9d 100644
--- a/util/src/dtos/DmChannelDTO.ts
+++ b/util/src/dtos/DmChannelDTO.ts
@@ -12,24 +12,30 @@ export class DmChannelDTO {
type: number;
static async from(channel: Channel, excluded_recipients: string[] = [], origin_channel_id?: string) {
- const obj = new DmChannelDTO()
- obj.icon = channel.icon || null
- obj.id = channel.id
- obj.last_message_id = channel.last_message_id || null
- obj.name = channel.name || null
- obj.origin_channel_id = origin_channel_id || null
- obj.owner_id = channel.owner_id
- obj.type = channel.type
- obj.recipients = (await Promise.all(channel.recipients!.filter(r => !excluded_recipients.includes(r.user_id)).map(async r => {
- return await User.findOneOrFail({ where: { id: r.user_id }, select: PublicUserProjection })
- }))).map(u => new MinimalPublicUserDTO(u))
- return obj
+ const obj = new DmChannelDTO();
+ obj.icon = channel.icon || null;
+ obj.id = channel.id;
+ obj.last_message_id = channel.last_message_id || null;
+ obj.name = channel.name || null;
+ obj.origin_channel_id = origin_channel_id || null;
+ obj.owner_id = channel.owner_id;
+ obj.type = channel.type;
+ obj.recipients = (
+ await Promise.all(
+ channel
+ .recipients!.filter((r) => !excluded_recipients.includes(r.user_id))
+ .map(async (r) => {
+ return await User.findOneOrFail({ where: { id: r.user_id }, select: PublicUserProjection });
+ })
+ )
+ ).map((u) => new MinimalPublicUserDTO(u));
+ return obj;
}
excludedRecipients(excluded_recipients: string[]): DmChannelDTO {
return {
...this,
- recipients: this.recipients.filter(r => !excluded_recipients.includes(r.id))
- }
+ recipients: this.recipients.filter((r) => !excluded_recipients.includes(r.id)),
+ };
}
-}
\ No newline at end of file
+}
diff --git a/util/src/dtos/UserDTO.ts b/util/src/dtos/UserDTO.ts
index f09b5f4e..ee2752a4 100644
--- a/util/src/dtos/UserDTO.ts
+++ b/util/src/dtos/UserDTO.ts
@@ -8,10 +8,10 @@ export class MinimalPublicUserDTO {
username: string;
constructor(user: User) {
- this.avatar = user.avatar
- this.discriminator = user.discriminator
- this.id = user.id
- this.public_flags = user.public_flags
- this.username = user.username
+ this.avatar = user.avatar;
+ this.discriminator = user.discriminator;
+ this.id = user.id;
+ this.public_flags = user.public_flags;
+ this.username = user.username;
}
-}
\ No newline at end of file
+}
diff --git a/util/src/dtos/index.ts b/util/src/dtos/index.ts
index 13702342..0e8f8459 100644
--- a/util/src/dtos/index.ts
+++ b/util/src/dtos/index.ts
@@ -1,2 +1,2 @@
export * from "./DmChannelDTO";
-export * from "./UserDTO";
\ No newline at end of file
+export * from "./UserDTO";
diff --git a/util/src/entities/Invite.ts b/util/src/entities/Invite.ts
index b3e00957..6ac64ddc 100644
--- a/util/src/entities/Invite.ts
+++ b/util/src/entities/Invite.ts
@@ -71,7 +71,7 @@ export class Invite extends BaseClassWithoutId {
@Column({ nullable: true })
target_user_type?: number;
- @Column({ nullable: true})
+ @Column({ nullable: true })
vanity_url?: boolean;
static async joinGuild(user_id: string, code: string) {
diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts
index a4d38315..20a44ca3 100644
--- a/util/src/entities/Message.ts
+++ b/util/src/entities/Message.ts
@@ -9,6 +9,7 @@ import {
CreateDateColumn,
Entity,
FindConditions,
+ Index,
JoinColumn,
JoinTable,
ManyToMany,
@@ -45,9 +46,11 @@ export enum MessageType {
}
@Entity("messages")
+@Index(["channel_id", "id"], { unique: true })
export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.channel)
+ @Index()
channel_id: string;
@JoinColumn({ name: "channel_id" })
@@ -68,10 +71,13 @@ export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.author)
+ @Index()
author_id: string;
@JoinColumn({ name: "author_id", referencedColumnName: "id" })
- @ManyToOne(() => User)
+ @ManyToOne(() => User, {
+ onDelete: "CASCADE",
+ })
author?: User;
@Column({ nullable: true })
diff --git a/util/src/entities/Migration.ts b/util/src/entities/Migration.ts
index 7393496f..3f39ae72 100644
--- a/util/src/entities/Migration.ts
+++ b/util/src/entities/Migration.ts
@@ -10,7 +10,7 @@ export class Migration extends BaseClassWithoutId {
@PrimaryIdAutoGenerated()
id: number;
- @Column({ type: 'bigint' })
+ @Column({ type: "bigint" })
timestamp: number;
@Column()
diff --git a/util/src/util/ApiError.ts b/util/src/util/ApiError.ts
index c133e6e7..f1a9b4f6 100644
--- a/util/src/util/ApiError.ts
+++ b/util/src/util/ApiError.ts
@@ -9,7 +9,8 @@ export class ApiError extends Error {
}
withDefaultParams(): ApiError {
- if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
+ if (this.defaultParams)
+ return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
return this;
}
diff --git a/util/src/util/Array.ts b/util/src/util/Array.ts
index 27f7c961..5a45d1b5 100644
--- a/util/src/util/Array.ts
+++ b/util/src/util/Array.ts
@@ -1,3 +1,3 @@
export function containsAll(arr: any[], target: any[]) {
- return target.every(v => arr.includes(v));
-}
\ No newline at end of file
+ return target.every((v) => arr.includes(v));
+}
diff --git a/util/src/util/AutoUpdate.ts b/util/src/util/AutoUpdate.ts
index cafc7bdb..531bd8b7 100644
--- a/util/src/util/AutoUpdate.ts
+++ b/util/src/util/AutoUpdate.ts
@@ -1,5 +1,6 @@
import "missing-native-js-functions";
import fetch from "node-fetch";
+import ProxyAgent from 'proxy-agent';
import readline from "readline";
import fs from "fs/promises";
import path from "path";
@@ -52,7 +53,8 @@ async function download(url: string, dir: string) {
try {
// TODO: use file stream instead of buffer (to prevent crash because of high memory usage for big files)
// TODO check file hash
- const response = await fetch(url);
+ const agent = new ProxyAgent();
+ const response = await fetch(url, { agent });
const buffer = await response.buffer();
const tempDir = await fs.mkdtemp("fosscord");
fs.writeFile(path.join(tempDir, "Fosscord.zip"), buffer);
@@ -72,7 +74,8 @@ async function getCurrentVersion(dir: string) {
async function getLatestVersion(url: string) {
try {
- const response = await fetch(url);
+ const agent = new ProxyAgent();
+ const response = await fetch(url, { agent });
const content = await response.json();
return content.version;
} catch (error) {
diff --git a/util/src/util/Config.ts b/util/src/util/Config.ts
index 704f3f2f..31b8d97c 100644
--- a/util/src/util/Config.ts
+++ b/util/src/util/Config.ts
@@ -1,5 +1,10 @@
import "missing-native-js-functions";
import { ConfigValue, ConfigEntity, DefaultConfigOptions } from "../entities/Config";
+import path from "path";
+import fs from "fs";
+
+// TODO: yaml instead of json
+// const overridePath = path.join(process.cwd(), "config.json");
var config: ConfigValue;
var pairs: ConfigEntity[];
@@ -12,8 +17,16 @@ export const Config = {
if (config) return config;
pairs = await ConfigEntity.find();
config = pairsToConfig(pairs);
+ config = (config || {}).merge(DefaultConfigOptions);
+
+ // try {
+ // const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" }));
+ // config = overrideConfig.merge(config);
+ // } catch (error) {
+ // fs.writeFileSync(overridePath, JSON.stringify(config, null, 4));
+ // }
- return this.set((config || {}).merge(DefaultConfigOptions));
+ return this.set(config);
},
get: function get() {
return config;
@@ -38,6 +51,7 @@ function applyConfig(val: ConfigValue) {
pair.value = obj;
return pair.save();
}
+ // fs.writeFileSync(overridePath, JSON.stringify(val, null, 4));
return apply(val);
}
diff --git a/util/src/util/Event.ts b/util/src/util/Event.ts
index 8ed009d5..bb624051 100644
--- a/util/src/util/Event.ts
+++ b/util/src/util/Event.ts
@@ -15,6 +15,8 @@ export async function emitEvent(payload: Omit<Event, "created_at">) {
// assertQueue isn't needed, because a queue will automatically created if it doesn't exist
const successful = RabbitMQ.channel?.publish(id, "", Buffer.from(`${data}`), { type: payload.event });
if (!successful) throw new Error("failed to send event");
+ } else if (process.env.EVENT_TRANSMISSION === "process") {
+ process.send?.({ type: "event", event: payload, id } as ProcessEvent);
} else {
events.emit(id, payload);
}
@@ -25,6 +27,7 @@ export async function initEvent() {
if (RabbitMQ.connection) {
} else {
// use event emitter
+ // use process messages
}
}
@@ -39,17 +42,38 @@ export interface ListenEventOpts {
acknowledge?: boolean;
}
+export interface ProcessEvent {
+ type: "event";
+ event: Event;
+ id: string;
+}
+
export async function listenEvent(event: string, callback: (event: EventOpts) => any, opts?: ListenEventOpts) {
if (RabbitMQ.connection) {
// @ts-ignore
return rabbitListen(opts?.channel || RabbitMQ.channel, event, callback, { acknowledge: opts?.acknowledge });
+ } else if (process.env.EVENT_TRANSMISSION === "process") {
+ const cancel = () => {
+ process.removeListener("message", listener);
+ process.setMaxListeners(process.getMaxListeners() - 1);
+ };
+
+ const listener = (msg: ProcessEvent) => {
+ msg.type === "event" && msg.id === event && callback({ ...msg.event, cancel });
+ };
+
+ process.addListener("message", listener);
+ process.setMaxListeners(process.getMaxListeners() + 1);
+
+ return cancel;
} else {
+ const listener = (opts: any) => callback({ ...opts, cancel });
const cancel = () => {
- events.removeListener(event, callback);
+ events.removeListener(event, listener);
events.setMaxListeners(events.getMaxListeners() - 1);
};
events.setMaxListeners(events.getMaxListeners() + 1);
- events.addListener(event, (opts) => callback({ ...opts, cancel }));
+ events.addListener(event, listener);
return cancel;
}
diff --git a/util/src/util/FieldError.ts b/util/src/util/FieldError.ts
index 0b3f93d2..406b33e8 100644
--- a/util/src/util/FieldError.ts
+++ b/util/src/util/FieldError.ts
@@ -8,9 +8,9 @@ export function FieldErrors(fields: Record<string, { code?: string; message: str
_errors: [
{
message,
- code: code || "BASE_TYPE_INVALID"
- }
- ]
+ code: code || "BASE_TYPE_INVALID",
+ },
+ ],
}))
);
}
diff --git a/util/src/util/Rights.ts b/util/src/util/Rights.ts
index 5edd9142..f0d00baf 100644
--- a/util/src/util/Rights.ts
+++ b/util/src/util/Rights.ts
@@ -56,7 +56,7 @@ export class Rights extends BitField {
INVITE_USERS: BitFlag(29), // can create user-specific invites in the guilds that they have INVITE_USERS
SELF_DELETE_DISABLE: BitFlag(30), // can disable/delete own account
DEBTABLE: BitFlag(31), // can use pay-to-use features
- CREDITABLE: BitFlag(32) // can receive money from monetisation related features
+ CREDITABLE: BitFlag(32), // can receive money from monetisation related features
};
any(permission: RightResolvable, checkOperator = true) {
|