mirror of
https://github.com/stoatchat/javascript-client-sdk.git
synced 2026-07-20 01:23:33 -04:00
merge: remote-tracking branch 'origin/main' into explicit-returns-and-imports
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["solid", "spellcheck"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:solid/typescript",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"spellcheck/spell-checker": [
|
||||
"warn",
|
||||
{
|
||||
"lang": "en_GB",
|
||||
"strings": false,
|
||||
"identifiers": false,
|
||||
"templates": false,
|
||||
"skipWords": ["uri", "webhook", "webhooks", "unreads"],
|
||||
"minLength": 3
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"varsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"varsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"require-jsdoc": [
|
||||
"warn",
|
||||
{
|
||||
"require": {
|
||||
"FunctionDeclaration": true,
|
||||
"MethodDefinition": true,
|
||||
"ClassDeclaration": true,
|
||||
"ArrowFunctionExpression": true,
|
||||
"FunctionExpression": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import eslint from "@eslint/js";
|
||||
import prettier from "eslint-plugin-prettier/recommended";
|
||||
import solid from "eslint-plugin-solid/configs/typescript";
|
||||
import { defineConfig } from "eslint/config";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
export default defineConfig([
|
||||
eslint.configs.recommended,
|
||||
tseslint.configs.recommended,
|
||||
solid,
|
||||
{
|
||||
rules: {
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
caughtErrors: "all",
|
||||
varsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
prettier,
|
||||
]);
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
+19
-30
@@ -1,16 +1,14 @@
|
||||
{
|
||||
"name": "revolt.js",
|
||||
"version": "7.0.5",
|
||||
"main": "lib/cjs/index.js",
|
||||
"module": "lib/esm/index.js",
|
||||
"types": "lib/esm/index.d.ts",
|
||||
"type": "module",
|
||||
"module": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"repository": "https://github.com/revoltchat/revolt.js",
|
||||
"author": "Paul Makles <insrt.uk>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "pnpm run build:esm && pnpm run build:cjs",
|
||||
"build:esm": "tsc && cp package-esm.json lib/esm/package.json",
|
||||
"build:cjs": "tsc -p tsconfig.cjs.json",
|
||||
"build": "tsc",
|
||||
"build:watch": "tsc-watch --onSuccess \"node .\"",
|
||||
"lint": "eslint --ext .ts,.tsx src/",
|
||||
"lint:fix": "eslint --fix --ext .ts,.tsx src/",
|
||||
@@ -26,32 +24,23 @@
|
||||
"description": "Library for interacting with the Revolt API.",
|
||||
"packageManager": "pnpm@9.4.0",
|
||||
"dependencies": {
|
||||
"@solid-primitives/map": "^0.4.11",
|
||||
"@solid-primitives/set": "^0.4.11",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"isomorphic-ws": "^5.0.0",
|
||||
"long": "^5.2.3",
|
||||
"@solid-primitives/map": "^0.6.0",
|
||||
"@solid-primitives/set": "^0.6.0",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"revolt-api": "0.8.3",
|
||||
"solid-js": "^1.8.15",
|
||||
"ulid": "^2.3.0",
|
||||
"ws": "^8.16.0"
|
||||
"ulid": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mxssfd/typedoc-theme": "^1.1.3",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@types/node": "^18.19.24",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-solid": "^0.12.1",
|
||||
"eslint-plugin-spellcheck": "^0.0.20",
|
||||
"prettier": "^2.8.8",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"typedoc": "^0.25.1",
|
||||
"typescript": "^5.4.2"
|
||||
"@mxssfd/typedoc-theme": "^1.1.7",
|
||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||
"@types/node": "^22.13.10",
|
||||
"eslint-plugin-prettier": "^5.2.3",
|
||||
"eslint-plugin-solid": "^0.14.5",
|
||||
"eslint": "^9.22.0",
|
||||
"prettier": "^3.5.3",
|
||||
"typedoc": "^0.27.9",
|
||||
"typescript-eslint": "^8.26.1",
|
||||
"typescript": "^5.8.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1196
-1991
File diff suppressed because it is too large
Load Diff
+47
-50
@@ -1,9 +1,9 @@
|
||||
import type { Accessor, Setter } from "solid-js";
|
||||
import { batch, createSignal } from "solid-js";
|
||||
|
||||
import EventEmitter from "eventemitter3";
|
||||
import type { DataLogin, RevoltConfig, Role } from "revolt-api";
|
||||
import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter";
|
||||
import { API } from "revolt-api";
|
||||
import type { DataLogin, RevoltConfig, Role } from "revolt-api";
|
||||
|
||||
import type { Channel } from "./classes/Channel.js";
|
||||
import type { Emoji } from "./classes/Emoji.js";
|
||||
@@ -43,55 +43,52 @@ export type Session = { _id: string; token: string; user_id: string } | string;
|
||||
*/
|
||||
export type Events = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
error(error: any): void;
|
||||
error: [error: any];
|
||||
|
||||
connected(): void;
|
||||
connecting(): void;
|
||||
disconnected(): void;
|
||||
ready(): void;
|
||||
logout(): void;
|
||||
connected: [];
|
||||
connecting: [];
|
||||
disconnected: [];
|
||||
ready: [];
|
||||
logout: [];
|
||||
|
||||
messageCreate(message: Message): void;
|
||||
messageUpdate(message: Message, previousMessage: HydratedMessage): void;
|
||||
messageDelete(message: HydratedMessage): void;
|
||||
messageDeleteBulk(messages: HydratedMessage[], channel?: Channel): void;
|
||||
messageReactionAdd(message: Message, userId: string, emoji: string): void;
|
||||
messageReactionRemove(message: Message, userId: string, emoji: string): void;
|
||||
messageReactionRemoveEmoji(message: Message, emoji: string): void;
|
||||
messageCreate: [message: Message];
|
||||
messageUpdate: [message: Message, previousMessage: HydratedMessage];
|
||||
messageDelete: [message: HydratedMessage];
|
||||
messageDeleteBulk: [messages: HydratedMessage[], channel?: Channel];
|
||||
messageReactionAdd: [message: Message, userId: string, emoji: string];
|
||||
messageReactionRemove: [message: Message, userId: string, emoji: string];
|
||||
messageReactionRemoveEmoji: [message: Message, emoji: string];
|
||||
|
||||
channelCreate(channel: Channel): void;
|
||||
channelUpdate(channel: Channel, previousChannel: HydratedChannel): void;
|
||||
channelDelete(channel: HydratedChannel): void;
|
||||
channelGroupJoin(channel: Channel, user: User): void;
|
||||
channelGroupLeave(channel: Channel, user?: User): void;
|
||||
channelStartTyping(channel: Channel, user?: User): void;
|
||||
channelStopTyping(channel: Channel, user?: User): void;
|
||||
channelAcknowledged(channel: Channel, messageId: string): void;
|
||||
channelCreate: [channel: Channel];
|
||||
channelUpdate: [channel: Channel, previousChannel: HydratedChannel];
|
||||
channelDelete: [channel: HydratedChannel];
|
||||
channelGroupJoin: [channel: Channel, user: User];
|
||||
channelGroupLeave: [channel: Channel, user?: User];
|
||||
channelStartTyping: [channel: Channel, user?: User];
|
||||
channelStopTyping: [channel: Channel, user?: User];
|
||||
channelAcknowledged: [channel: Channel, messageId: string];
|
||||
|
||||
serverCreate(server: Server): void;
|
||||
serverUpdate(server: Server, previousServer: HydratedServer): void;
|
||||
serverDelete(server: HydratedServer): void;
|
||||
serverLeave(server: HydratedServer): void;
|
||||
serverRoleUpdate(server: Server, roleId: string, previousRole: Role): void;
|
||||
serverRoleDelete(server: Server, roleId: string, role: Role): void;
|
||||
serverCreate: [server: Server];
|
||||
serverUpdate: [server: Server, previousServer: HydratedServer];
|
||||
serverDelete: [server: HydratedServer];
|
||||
serverLeave: [server: HydratedServer];
|
||||
serverRoleUpdate: [server: Server, roleId: string, previousRole: Role];
|
||||
serverRoleDelete: [server: Server, roleId: string, role: Role];
|
||||
|
||||
serverMemberUpdate(
|
||||
serverMemberUpdate: [
|
||||
member: ServerMember,
|
||||
previousMember: HydratedServerMember
|
||||
): void;
|
||||
serverMemberJoin(member: ServerMember): void;
|
||||
serverMemberLeave(member: HydratedServerMember): void;
|
||||
previousMember: HydratedServerMember,
|
||||
];
|
||||
serverMemberJoin: [member: ServerMember];
|
||||
serverMemberLeave: [member: HydratedServerMember];
|
||||
|
||||
userUpdate(user: User, previousUser: HydratedUser): void;
|
||||
// ^ userRelationshipChanged(user: User, previousRelationship: RelationshipStatus): void;
|
||||
// ^ userPresenceChanged(user: User, previousPresence: boolean): void;
|
||||
userSettingsUpdate(
|
||||
id: string,
|
||||
update: Record<string, [number, string]>
|
||||
): void;
|
||||
userUpdate: [user: User, previousUser: HydratedUser];
|
||||
// ^ userRelationshipChanged: [user: User, previousRelationship: RelationshipStatus];
|
||||
// ^ userPresenceChanged: [user: User, previousPresence: boolean];
|
||||
userSettingsUpdate: [id: string, update: Record<string, [number, string]>];
|
||||
|
||||
emojiCreate(emoji: Emoji): void;
|
||||
emojiDelete(emoji: HydratedEmoji): void;
|
||||
emojiCreate: [emoji: Emoji];
|
||||
emojiDelete: [emoji: HydratedEmoji];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -154,7 +151,7 @@ export type ClientOptions = Partial<EventClientOptions> & {
|
||||
/**
|
||||
* Revolt.js Clients
|
||||
*/
|
||||
export class Client extends EventEmitter<Events> {
|
||||
export class Client extends AsyncEventEmitter<Events> {
|
||||
readonly account;
|
||||
readonly bots;
|
||||
readonly channels;
|
||||
@@ -260,7 +257,7 @@ export class Client extends EventEmitter<Events> {
|
||||
this.#reconnectTimeout = setTimeout(
|
||||
() => this.connect(),
|
||||
this.options.retryDelayFunction(this.connectionFailureCount()) *
|
||||
1e3
|
||||
1e3,
|
||||
) as never;
|
||||
|
||||
this.#setConnectionFailureCount((count) => count + 1);
|
||||
@@ -270,7 +267,7 @@ export class Client extends EventEmitter<Events> {
|
||||
});
|
||||
|
||||
this.events.on("event", (event) =>
|
||||
handleEvent(this, event, this.#setReady)
|
||||
handleEvent(this, event, this.#setReady),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -299,7 +296,7 @@ export class Client extends EventEmitter<Events> {
|
||||
this.#setReady(false);
|
||||
this.events.connect(
|
||||
this.configuration?.ws ?? "wss://ws.revolt.chat",
|
||||
typeof this.#session === "string" ? this.#session : this.#session!.token
|
||||
typeof this.#session === "string" ? this.#session : this.#session!.token,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -394,9 +391,9 @@ export class Client extends EventEmitter<Events> {
|
||||
*/
|
||||
proxyFile(url: string): string | undefined {
|
||||
if (this.configuration?.features.january.enabled) {
|
||||
return `${
|
||||
this.configuration.features.january.url
|
||||
}/proxy?url=${encodeURIComponent(url)}`;
|
||||
return `${this.configuration.features.january.url}/proxy?url=${encodeURIComponent(
|
||||
url,
|
||||
)}`;
|
||||
} else {
|
||||
return url;
|
||||
}
|
||||
|
||||
+62
-50
@@ -15,7 +15,8 @@ import type {
|
||||
import type { APIRoutes } from "revolt-api/dist/routes";
|
||||
import { decodeTime, ulid } from "ulid";
|
||||
|
||||
import type { ChannelCollection } from "../collections/ChannelCollection.js";
|
||||
import { ChannelCollection } from "../collections/index.js";
|
||||
import { hydrate } from "../hydration/index.js";
|
||||
import {
|
||||
bitwiseAndEq,
|
||||
calculatePermission,
|
||||
@@ -107,8 +108,8 @@ export class Channel {
|
||||
return this.type === "SavedMessages"
|
||||
? this.user?.username
|
||||
: this.type === "DirectMessage"
|
||||
? this.recipient?.username
|
||||
: this.name;
|
||||
? this.recipient?.username
|
||||
: this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +145,7 @@ export class Channel {
|
||||
*/
|
||||
get typing(): User[] {
|
||||
return [...this.typingIds.values()].map(
|
||||
(id) => this.#collection.client.users.get(id)!
|
||||
(id) => this.#collection.client.users.get(id)!,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -170,7 +171,7 @@ export class Channel {
|
||||
get recipient(): User | undefined {
|
||||
return this.type === "DirectMessage"
|
||||
? this.recipients?.find(
|
||||
(user) => user?.id !== this.#collection.client.user!.id
|
||||
(user) => user?.id !== this.#collection.client.user!.id,
|
||||
)
|
||||
: undefined;
|
||||
}
|
||||
@@ -187,7 +188,7 @@ export class Channel {
|
||||
*/
|
||||
get user(): User | undefined {
|
||||
return this.#collection.client.users.get(
|
||||
this.#collection.getUnderlyingObject(this.id).userId!
|
||||
this.#collection.getUnderlyingObject(this.id).userId!,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -203,7 +204,7 @@ export class Channel {
|
||||
*/
|
||||
get owner(): User | undefined {
|
||||
return this.#collection.client.users.get(
|
||||
this.#collection.getUnderlyingObject(this.id).ownerId!
|
||||
this.#collection.getUnderlyingObject(this.id).ownerId!,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -219,7 +220,7 @@ export class Channel {
|
||||
*/
|
||||
get server(): Server | undefined {
|
||||
return this.#collection.client.servers.get(
|
||||
this.#collection.getUnderlyingObject(this.id).serverId!
|
||||
this.#collection.getUnderlyingObject(this.id).serverId!,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -338,12 +339,12 @@ export class Channel {
|
||||
(role) =>
|
||||
bitwiseAndEq(
|
||||
this.rolePermissions?.[role]?.d ?? 0,
|
||||
Permission.ViewChannel
|
||||
Permission.ViewChannel,
|
||||
) ||
|
||||
bitwiseAndEq(
|
||||
this.server?.roles.get(role)?.permissions.d ?? 0,
|
||||
Permission.ViewChannel
|
||||
)
|
||||
Permission.ViewChannel,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -363,7 +364,7 @@ export class Channel {
|
||||
havePermission(...permission: (keyof typeof Permission)[]): boolean {
|
||||
return bitwiseAndEq(
|
||||
this.permission,
|
||||
...permission.map((x) => Permission[x])
|
||||
...permission.map((x) => Permission[x]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -375,7 +376,7 @@ export class Channel {
|
||||
orPermission(...permission: (keyof typeof Permission)[]): boolean {
|
||||
return (
|
||||
permission.findIndex((x) =>
|
||||
bitwiseAndEq(this.permission, Permission[x])
|
||||
bitwiseAndEq(this.permission, Permission[x]),
|
||||
) !== -1
|
||||
);
|
||||
}
|
||||
@@ -387,13 +388,13 @@ export class Channel {
|
||||
*/
|
||||
async fetchMembers(): Promise<User[]> {
|
||||
const members = await this.#collection.client.api.get(
|
||||
`/channels/${this.id as ""}/members`
|
||||
`/channels/${this.id as ""}/members`,
|
||||
);
|
||||
|
||||
return batch(() =>
|
||||
members.map((user) =>
|
||||
this.#collection.client.users.getOrCreate(user._id, user)
|
||||
)
|
||||
this.#collection.client.users.getOrCreate(user._id, user),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -404,13 +405,16 @@ export class Channel {
|
||||
*/
|
||||
async fetchWebhooks(): Promise<ChannelWebhook[]> {
|
||||
const webhooks = await this.#collection.client.api.get(
|
||||
`/channels/${this.id as ""}/webhooks`
|
||||
`/channels/${this.id as ""}/webhooks`,
|
||||
);
|
||||
|
||||
return batch(() =>
|
||||
webhooks.map((webhook) =>
|
||||
this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook)
|
||||
)
|
||||
this.#collection.client.channelWebhooks.getOrCreate(
|
||||
webhook.id,
|
||||
webhook,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -418,8 +422,16 @@ export class Channel {
|
||||
* Edit a channel
|
||||
* @param data Changes
|
||||
*/
|
||||
async edit(data: DataEditChannel): Promise<void> {
|
||||
await this.#collection.client.api.patch(`/channels/${this.id as ""}`, data);
|
||||
async edit(data: DataEditChannel) {
|
||||
const channel = await this.#collection.client.api.patch(
|
||||
`/channels/${this.id as ""}`,
|
||||
data,
|
||||
);
|
||||
|
||||
this.#collection.updateUnderlyingObject(
|
||||
this.id,
|
||||
hydrate("channel", channel, this.#collection.client, false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -447,7 +459,7 @@ export class Channel {
|
||||
*/
|
||||
async addMember(user_id: string): Promise<void> {
|
||||
return await this.#collection.client.api.put(
|
||||
`/channels/${this.id as ""}/recipients/${user_id as ""}`
|
||||
`/channels/${this.id as ""}/recipients/${user_id as ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -458,7 +470,7 @@ export class Channel {
|
||||
*/
|
||||
async removeMember(user_id: string): Promise<void> {
|
||||
return await this.#collection.client.api.delete(
|
||||
`/channels/${this.id as ""}/recipients/${user_id as ""}`
|
||||
`/channels/${this.id as ""}/recipients/${user_id as ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -470,7 +482,7 @@ export class Channel {
|
||||
*/
|
||||
async sendMessage(
|
||||
data: string | DataMessageSend,
|
||||
idempotencyKey: string = ulid()
|
||||
idempotencyKey: string = ulid(),
|
||||
): Promise<Message> {
|
||||
const msg: DataMessageSend =
|
||||
typeof data === "string" ? { content: data } : data;
|
||||
@@ -489,13 +501,13 @@ export class Channel {
|
||||
headers: {
|
||||
"Idempotency-Key": idempotencyKey,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return this.#collection.client.messages.getOrCreate(
|
||||
message._id,
|
||||
message,
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -507,7 +519,7 @@ export class Channel {
|
||||
*/
|
||||
async fetchMessage(messageId: string): Promise<Message> {
|
||||
const message = await this.#collection.client.api.get(
|
||||
`/channels/${this.id as ""}/messages/${messageId as ""}`
|
||||
`/channels/${this.id as ""}/messages/${messageId as ""}`,
|
||||
);
|
||||
|
||||
return this.#collection.client.messages.getOrCreate(message._id, message);
|
||||
@@ -526,15 +538,15 @@ export class Channel {
|
||||
path: "/channels/{target}/messages";
|
||||
})["params"],
|
||||
"include_users"
|
||||
>
|
||||
>,
|
||||
): Promise<Message[]> {
|
||||
const messages = (await this.#collection.client.api.get(
|
||||
`/channels/${this.id as ""}/messages`,
|
||||
{ ...params }
|
||||
{ ...params },
|
||||
)) as APIMessage[];
|
||||
|
||||
return messages.map((message) =>
|
||||
this.#collection.client.messages.getOrCreate(message._id, message)
|
||||
this.#collection.client.messages.getOrCreate(message._id, message),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -551,7 +563,7 @@ export class Channel {
|
||||
path: "/channels/{target}/messages";
|
||||
})["params"],
|
||||
"include_users"
|
||||
>
|
||||
>,
|
||||
): Promise<{
|
||||
messages: Message[];
|
||||
users: User[];
|
||||
@@ -559,18 +571,18 @@ export class Channel {
|
||||
}> {
|
||||
const data = (await this.#collection.client.api.get(
|
||||
`/channels/${this.id as ""}/messages`,
|
||||
{ ...params, include_users: true }
|
||||
{ ...params, include_users: true },
|
||||
)) as { messages: APIMessage[]; users: APIUser[]; members?: APIMember[] };
|
||||
|
||||
return batch(() => ({
|
||||
messages: data.messages.map((message) =>
|
||||
this.#collection.client.messages.getOrCreate(message._id, message)
|
||||
this.#collection.client.messages.getOrCreate(message._id, message),
|
||||
),
|
||||
users: data.users.map((user) =>
|
||||
this.#collection.client.users.getOrCreate(user._id, user)
|
||||
this.#collection.client.users.getOrCreate(user._id, user),
|
||||
),
|
||||
members: data.members?.map((member) =>
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member)
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member),
|
||||
),
|
||||
}));
|
||||
}
|
||||
@@ -582,17 +594,17 @@ export class Channel {
|
||||
* @returns Messages
|
||||
*/
|
||||
async search(
|
||||
params: Omit<DataMessageSearch, "include_users">
|
||||
params: Omit<DataMessageSearch, "include_users">,
|
||||
): Promise<Message[]> {
|
||||
const messages = (await this.#collection.client.api.post(
|
||||
`/channels/${this.id as ""}/search`,
|
||||
params
|
||||
params,
|
||||
)) as APIMessage[];
|
||||
|
||||
return batch(() =>
|
||||
messages.map((message) =>
|
||||
this.#collection.client.messages.getOrCreate(message._id, message)
|
||||
)
|
||||
this.#collection.client.messages.getOrCreate(message._id, message),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -603,7 +615,7 @@ export class Channel {
|
||||
* @returns Object including messages and users
|
||||
*/
|
||||
async searchWithUsers(
|
||||
params: Omit<DataMessageSearch, "include_users">
|
||||
params: Omit<DataMessageSearch, "include_users">,
|
||||
): Promise<{
|
||||
messages: Message[];
|
||||
users: User[];
|
||||
@@ -614,18 +626,18 @@ export class Channel {
|
||||
{
|
||||
...params,
|
||||
include_users: true,
|
||||
}
|
||||
},
|
||||
)) as { messages: APIMessage[]; users: APIUser[]; members?: APIMember[] };
|
||||
|
||||
return batch(() => ({
|
||||
messages: data.messages.map((message) =>
|
||||
this.#collection.client.messages.getOrCreate(message._id, message)
|
||||
this.#collection.client.messages.getOrCreate(message._id, message),
|
||||
),
|
||||
users: data.users.map((user) =>
|
||||
this.#collection.client.users.getOrCreate(user._id, user)
|
||||
this.#collection.client.users.getOrCreate(user._id, user),
|
||||
),
|
||||
members: data.members?.map((member) =>
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member)
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member),
|
||||
),
|
||||
}));
|
||||
}
|
||||
@@ -640,7 +652,7 @@ export class Channel {
|
||||
`/channels/${this.id as ""}/messages/bulk`,
|
||||
{
|
||||
ids,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -651,7 +663,7 @@ export class Channel {
|
||||
*/
|
||||
async createInvite(): Promise<Invite> {
|
||||
return await this.#collection.client.api.post(
|
||||
`/channels/${this.id as ""}/invites`
|
||||
`/channels/${this.id as ""}/invites`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -671,7 +683,7 @@ export class Channel {
|
||||
message?: Message | string,
|
||||
skipRateLimiter?: boolean,
|
||||
skipRequest?: boolean,
|
||||
skipNextMarking?: boolean
|
||||
skipNextMarking?: boolean,
|
||||
): Promise<void> {
|
||||
if (!message && this.#manuallyMarked) {
|
||||
this.#manuallyMarked = false;
|
||||
@@ -708,7 +720,7 @@ export class Channel {
|
||||
const performAck = (): void => {
|
||||
this.#ackLimit = undefined;
|
||||
this.#collection.client.api.put(
|
||||
`/channels/${this.id}/ack/${lastMessageId as ""}`
|
||||
`/channels/${this.id}/ack/${lastMessageId as ""}`,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -735,11 +747,11 @@ export class Channel {
|
||||
*/
|
||||
async setPermissions(
|
||||
role_id = "default",
|
||||
permissions: Override
|
||||
permissions: Override,
|
||||
): Promise<APIChannel> {
|
||||
return await this.#collection.client.api.put(
|
||||
`/channels/${this.id as ""}/permissions/${role_id as ""}`,
|
||||
{ permissions }
|
||||
{ permissions },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import * as APITmp from "revolt-api";
|
||||
|
||||
import type { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.js";
|
||||
import { hydrate } from "../hydration/index.js";
|
||||
|
||||
@@ -63,7 +65,7 @@ export class ChannelWebhook {
|
||||
*/
|
||||
get channel(): Channel | undefined {
|
||||
return this.#collection.client.channels.get(
|
||||
this.#collection.getUnderlyingObject(this.id).channelId
|
||||
this.#collection.getUnderlyingObject(this.id).channelId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -78,17 +80,28 @@ export class ChannelWebhook {
|
||||
* Edit this webhook
|
||||
* TODO: not in production
|
||||
*/
|
||||
async edit(data: any /*: DataEditWebhook*/): Promise<void> {
|
||||
async edit(
|
||||
data: Partial<{
|
||||
name: string;
|
||||
avatar: string;
|
||||
permissions: number;
|
||||
remove: ["Icon"];
|
||||
}>,
|
||||
): Promise<void> {
|
||||
// @ts-expect-error this should error once edit webhook is stable
|
||||
// eslint-disable-next-line
|
||||
type TodoUseThisDefinitionOnceItExists = APITmp.DataEditWebhook;
|
||||
|
||||
const webhook = await this.#collection.client.api.patch(
|
||||
// @ts-expect-error not in prod
|
||||
`/webhooks/${this.id as ""}/${this.token as ""}`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
|
||||
this.#collection.updateUnderlyingObject(
|
||||
this.id,
|
||||
// @ts-expect-error not in prod
|
||||
hydrate("channelWebhook", webhook, this.#collection.client)
|
||||
hydrate("channelWebhook", webhook, this.#collection.client),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,7 +112,7 @@ export class ChannelWebhook {
|
||||
async delete(): Promise<void> {
|
||||
await this.#collection.client.api.delete(
|
||||
// @ts-expect-error not in prod
|
||||
`/webhooks/${this.id}/${this.token}`
|
||||
`/webhooks/${this.id}/${this.token}`,
|
||||
);
|
||||
|
||||
this.#collection.delete(this.id);
|
||||
|
||||
@@ -56,7 +56,7 @@ export class Emoji {
|
||||
*/
|
||||
get creator(): User | undefined {
|
||||
return this.#collection.client.users.get(
|
||||
this.#collection.getUnderlyingObject(this.id).creatorId
|
||||
this.#collection.getUnderlyingObject(this.id).creatorId,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ export class File {
|
||||
*/
|
||||
constructor(
|
||||
client: Client,
|
||||
file: Pick<APIFile, "_id" | "tag" | "metadata"> & Partial<APIFile>
|
||||
file: Pick<APIFile, "_id" | "tag" | "metadata"> & Partial<APIFile>,
|
||||
) {
|
||||
this.#client = client;
|
||||
this.id = file._id;
|
||||
|
||||
+2
-2
@@ -93,7 +93,7 @@ export class MFATicket {
|
||||
constructor(
|
||||
client: Client,
|
||||
ticket: TicketType,
|
||||
mutate: SetStoreFunction<MultiFactorStatus>
|
||||
mutate: SetStoreFunction<MultiFactorStatus>,
|
||||
) {
|
||||
this.#client = client;
|
||||
this.#ticket = ticket;
|
||||
@@ -142,7 +142,7 @@ export class MFATicket {
|
||||
headers: {
|
||||
"X-MFA-Ticket": this.token,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.#mutate("recovery_active", true);
|
||||
|
||||
+14
-12
@@ -84,7 +84,7 @@ export class Message {
|
||||
*/
|
||||
get channel(): Channel | undefined {
|
||||
return this.#collection.client.channels.get(
|
||||
this.#collection.getUnderlyingObject(this.id).channelId
|
||||
this.#collection.getUnderlyingObject(this.id).channelId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ export class Message {
|
||||
*/
|
||||
get author(): User | undefined {
|
||||
return this.#collection.client.users.get(
|
||||
this.#collection.getUnderlyingObject(this.id).authorId!
|
||||
this.#collection.getUnderlyingObject(this.id).authorId!,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,9 @@ export class Message {
|
||||
|
||||
return (
|
||||
this.masquerade?.name ??
|
||||
(webhook ? webhook.name : this.member?.nickname ?? this.author?.username)
|
||||
(webhook
|
||||
? webhook.name
|
||||
: (this.member?.nickname ?? this.author?.username))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -241,7 +243,7 @@ export class Message {
|
||||
this.masqueradeAvatarURL ??
|
||||
(webhook
|
||||
? webhook.avatarURL
|
||||
: this.member?.avatarURL ?? this.author?.avatarURL)
|
||||
: (this.member?.avatarURL ?? this.author?.avatarURL))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -256,8 +258,8 @@ export class Message {
|
||||
(webhook
|
||||
? webhook.avatarURL
|
||||
: this.member
|
||||
? this.member?.animatedAvatarURL
|
||||
: this.author?.animatedAvatarURL)
|
||||
? this.member?.animatedAvatarURL
|
||||
: this.author?.animatedAvatarURL)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -283,7 +285,7 @@ export class Message {
|
||||
async edit(data: DataEditMessage): Promise<APIMessage> {
|
||||
return await this.#collection.client.api.patch(
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -292,7 +294,7 @@ export class Message {
|
||||
*/
|
||||
async delete(): Promise<void> {
|
||||
return await this.#collection.client.api.delete(
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}`
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -312,7 +314,7 @@ export class Message {
|
||||
| (Omit<DataMessageSend, "nonce"> & {
|
||||
nonce?: string;
|
||||
}),
|
||||
mention = true
|
||||
mention = true,
|
||||
): Promise<Message> | undefined {
|
||||
const obj = typeof data === "string" ? { content: data } : data;
|
||||
return this.channel?.sendMessage({
|
||||
@@ -326,7 +328,7 @@ export class Message {
|
||||
*/
|
||||
async clearReactions(): Promise<void> {
|
||||
return await this.#collection.client.api.delete(
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions`
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -338,7 +340,7 @@ export class Message {
|
||||
return await this.#collection.client.api.put(
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${
|
||||
emoji as ""
|
||||
}`
|
||||
}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -350,7 +352,7 @@ export class Message {
|
||||
return await this.#collection.client.api.delete(
|
||||
`/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${
|
||||
emoji as ""
|
||||
}`
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ export class WebsiteEmbed extends MessageEmbed {
|
||||
*/
|
||||
constructor(
|
||||
client: Client,
|
||||
embed: Omit<Embed & { type: "Website" }, "type">
|
||||
embed: Omit<Embed & { type: "Website" }, "type">,
|
||||
) {
|
||||
super(client, "Website");
|
||||
|
||||
@@ -177,7 +177,7 @@ export class WebsiteEmbed extends MessageEmbed {
|
||||
return `https://open.spotify.com/embed/${this.specialContent.content_type}/${this.specialContent.id}`;
|
||||
case "Soundcloud":
|
||||
return `https://w.soundcloud.com/player/?url=${encodeURIComponent(
|
||||
this.url!
|
||||
this.url!,
|
||||
)}&color=%23FF7F50&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true`;
|
||||
case "Bandcamp": {
|
||||
return `https://bandcamp.com/EmbeddedPlayer/${this.specialContent.content_type.toLowerCase()}=${
|
||||
|
||||
@@ -113,7 +113,7 @@ export class ServerPublicInvite extends PublicChannelInvite {
|
||||
return this.client!.servers.getOrCreate(
|
||||
invite.server._id,
|
||||
invite.server,
|
||||
true
|
||||
true,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
|
||||
+46
-46
@@ -85,7 +85,7 @@ export class Server {
|
||||
*/
|
||||
get owner(): User | undefined {
|
||||
return this.#collection.client.users.get(
|
||||
this.#collection.getUnderlyingObject(this.id).ownerId
|
||||
this.#collection.getUnderlyingObject(this.id).ownerId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ export class Server {
|
||||
|
||||
if (uncategorised.size > 0) {
|
||||
const channels = [...uncategorised].map(
|
||||
(key) => this.#collection.client.channels.get(key)!
|
||||
(key) => this.#collection.client.channels.get(key)!,
|
||||
);
|
||||
|
||||
if (defaultCategory) {
|
||||
@@ -299,7 +299,7 @@ export class Server {
|
||||
*/
|
||||
get mentions(): string[] {
|
||||
const arr = this.channels.map((channel) =>
|
||||
Array.from(channel.mentions?.values() ?? [])
|
||||
Array.from(channel.mentions?.values() ?? []),
|
||||
);
|
||||
|
||||
return ([] as string[]).concat(...arr);
|
||||
@@ -351,7 +351,7 @@ export class Server {
|
||||
havePermission(...permission: (keyof typeof Permission)[]): boolean {
|
||||
return bitwiseAndEq(
|
||||
this.permission,
|
||||
...permission.map((x) => Permission[x])
|
||||
...permission.map((x) => Permission[x]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ export class Server {
|
||||
orPermission(...permission: (keyof typeof Permission)[]): boolean {
|
||||
return (
|
||||
permission.findIndex((x) =>
|
||||
bitwiseAndEq(this.permission, Permission[x])
|
||||
bitwiseAndEq(this.permission, Permission[x]),
|
||||
) !== -1
|
||||
);
|
||||
}
|
||||
@@ -388,7 +388,7 @@ export class Server {
|
||||
async createChannel(data: DataCreateServerChannel): Promise<Channel> {
|
||||
const channel = await this.#collection.client.api.post(
|
||||
`/servers/${this.id as ""}/channels`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
|
||||
return this.#collection.client.channels.getOrCreate(channel._id, channel);
|
||||
@@ -405,11 +405,11 @@ export class Server {
|
||||
"server",
|
||||
await this.#collection.client.api.patch(
|
||||
`/servers/${this.id as ""}`,
|
||||
data
|
||||
data,
|
||||
),
|
||||
this.#collection.client,
|
||||
false
|
||||
)
|
||||
false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -420,14 +420,14 @@ export class Server {
|
||||
$delete(leaveEvent?: boolean): void {
|
||||
batch(() => {
|
||||
const server = this.#collection.client.servers.getUnderlyingObject(
|
||||
this.id
|
||||
this.id,
|
||||
);
|
||||
|
||||
// Avoid race conditions
|
||||
if (server.id) {
|
||||
this.#collection.client.emit(
|
||||
leaveEvent ? "serverLeave" : "serverDelete",
|
||||
server
|
||||
server,
|
||||
);
|
||||
|
||||
for (const channel of this.channelIds) {
|
||||
@@ -472,18 +472,18 @@ export class Server {
|
||||
*/
|
||||
async banUser(
|
||||
user: string | User | ServerMember,
|
||||
options: DataBanCreate = {}
|
||||
options: DataBanCreate = {},
|
||||
): Promise<ServerBan> {
|
||||
const userId =
|
||||
user instanceof User
|
||||
? user.id
|
||||
: user instanceof ServerMember
|
||||
? user.id.user
|
||||
: user;
|
||||
? user.id.user
|
||||
: user;
|
||||
|
||||
const ban = await this.#collection.client.api.put(
|
||||
`/servers/${this.id as ""}/bans/${userId as ""}`,
|
||||
options
|
||||
options,
|
||||
);
|
||||
|
||||
return new ServerBan(this.#collection.client, ban);
|
||||
@@ -499,9 +499,9 @@ export class Server {
|
||||
typeof user === "string"
|
||||
? user
|
||||
: user instanceof User
|
||||
? user.id
|
||||
: user.id.user
|
||||
}`
|
||||
? user.id
|
||||
: user.id.user
|
||||
}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ export class Server {
|
||||
async unbanUser(user: string | User): Promise<void> {
|
||||
const userId = user instanceof User ? user.id : user;
|
||||
return await this.#collection.client.api.delete(
|
||||
`/servers/${this.id as ""}/bans/${userId}`
|
||||
`/servers/${this.id as ""}/bans/${userId}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -522,11 +522,11 @@ export class Server {
|
||||
*/
|
||||
async fetchInvites(): Promise<ChannelInvite[]> {
|
||||
const invites = await this.#collection.client.api.get(
|
||||
`/servers/${this.id as ""}/invites`
|
||||
`/servers/${this.id as ""}/invites`,
|
||||
);
|
||||
|
||||
return invites.map((invite) =>
|
||||
ChannelInvite.from(this.#collection.client, invite)
|
||||
ChannelInvite.from(this.#collection.client, invite),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -536,17 +536,17 @@ export class Server {
|
||||
*/
|
||||
async fetchBans(): Promise<ServerBan[]> {
|
||||
const { users, bans } = await this.#collection.client.api.get(
|
||||
`/servers/${this.id as ""}/bans`
|
||||
`/servers/${this.id as ""}/bans`,
|
||||
);
|
||||
|
||||
const userDict = users.reduce(
|
||||
(d, c) => ({ ...d, [c._id]: c }),
|
||||
{} as Record<string, BannedUser>
|
||||
{} as Record<string, BannedUser>,
|
||||
);
|
||||
|
||||
return bans.map(
|
||||
(ban) =>
|
||||
new ServerBan(this.#collection.client, ban, userDict[ban._id.user])
|
||||
new ServerBan(this.#collection.client, ban, userDict[ban._id.user]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -557,11 +557,11 @@ export class Server {
|
||||
*/
|
||||
async setPermissions(
|
||||
roleId = "default",
|
||||
permissions: Override | number
|
||||
permissions: Override | number,
|
||||
): Promise<APIServer> {
|
||||
return await this.#collection.client.api.put(
|
||||
`/servers/${this.id as ""}/permissions/${roleId as ""}`,
|
||||
{ permissions: permissions as Override }
|
||||
{ permissions: permissions as Override },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ export class Server {
|
||||
`/servers/${this.id as ""}/roles`,
|
||||
{
|
||||
name,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -586,7 +586,7 @@ export class Server {
|
||||
async editRole(roleId: string, data: DataEditRole): Promise<Role> {
|
||||
return await this.#collection.client.api.patch(
|
||||
`/servers/${this.id as ""}/roles/${roleId as ""}`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -596,7 +596,7 @@ export class Server {
|
||||
*/
|
||||
async deleteRole(roleId: string): Promise<void> {
|
||||
return await this.#collection.client.api.delete(
|
||||
`/servers/${this.id as ""}/roles/${roleId as ""}`
|
||||
`/servers/${this.id as ""}/roles/${roleId as ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -627,7 +627,7 @@ export class Server {
|
||||
|
||||
const data = await this.#collection.client.api.get(
|
||||
`/servers/${this.id as ""}/members`,
|
||||
{ exclude_offline: excludeOffline }
|
||||
{ exclude_offline: excludeOffline },
|
||||
);
|
||||
|
||||
batch(() => {
|
||||
@@ -638,7 +638,7 @@ export class Server {
|
||||
this.#collection.client.users.getOrCreate(user._id, user);
|
||||
this.#collection.client.serverMembers.getOrCreate(
|
||||
data.members[i]._id,
|
||||
data.members[i]
|
||||
data.members[i],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -646,11 +646,11 @@ export class Server {
|
||||
for (let i = 0; i < data.users.length; i++) {
|
||||
this.#collection.client.users.getOrCreate(
|
||||
data.users[i]._id,
|
||||
data.users[i]
|
||||
data.users[i],
|
||||
);
|
||||
this.#collection.client.serverMembers.getOrCreate(
|
||||
data.members[i]._id,
|
||||
data.members[i]
|
||||
data.members[i],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -671,15 +671,15 @@ export class Server {
|
||||
async fetchMembers(): Promise<{ members: ServerMember[]; users: User[] }> {
|
||||
const data = (await this.#collection.client.api.get(
|
||||
// @ts-expect-error TODO weird typing issue
|
||||
`/servers/${this.id as ""}/members`
|
||||
`/servers/${this.id as ""}/members`,
|
||||
)) as AllMemberResponse;
|
||||
|
||||
return batch(() => ({
|
||||
members: data.members.map((member) =>
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member)
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member),
|
||||
),
|
||||
users: data.users.map((user) =>
|
||||
this.#collection.client.users.getOrCreate(user._id, user)
|
||||
this.#collection.client.users.getOrCreate(user._id, user),
|
||||
),
|
||||
}));
|
||||
}
|
||||
@@ -690,22 +690,22 @@ export class Server {
|
||||
* @returns List of the server's members and their user objects
|
||||
*/
|
||||
async queryMembersExperimental(
|
||||
query: string
|
||||
query: string,
|
||||
): Promise<{ members: ServerMember[]; users: User[] }> {
|
||||
const data = (await this.#collection.client.api.get(
|
||||
`/servers/${
|
||||
this.id as ""
|
||||
}/members_experimental_query?experimental_api=true&query=${encodeURIComponent(
|
||||
query
|
||||
)}` as never
|
||||
query,
|
||||
)}` as never,
|
||||
)) as AllMemberResponse;
|
||||
|
||||
return batch(() => ({
|
||||
members: data.members.map((member) =>
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member)
|
||||
this.#collection.client.serverMembers.getOrCreate(member._id, member),
|
||||
),
|
||||
users: data.users.map((user) =>
|
||||
this.#collection.client.users.getOrCreate(user._id, user)
|
||||
this.#collection.client.users.getOrCreate(user._id, user),
|
||||
),
|
||||
}));
|
||||
}
|
||||
@@ -717,7 +717,7 @@ export class Server {
|
||||
*/
|
||||
async createEmoji(
|
||||
autumnId: string,
|
||||
options: Omit<DataCreateEmoji, "parent">
|
||||
options: Omit<DataCreateEmoji, "parent">,
|
||||
): Promise<Emoji> {
|
||||
const emoji = await this.#collection.client.api.put(
|
||||
`/custom/emoji/${autumnId as ""}`,
|
||||
@@ -727,7 +727,7 @@ export class Server {
|
||||
id: this.id,
|
||||
},
|
||||
...options,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return this.#collection.client.emojis.getOrCreate(emoji._id, emoji, true);
|
||||
@@ -739,13 +739,13 @@ export class Server {
|
||||
*/
|
||||
async fetchEmojis(): Promise<Emoji[]> {
|
||||
const emojis = await this.#collection.client.api.get(
|
||||
`/servers/${this.id as ""}/emojis`
|
||||
`/servers/${this.id as ""}/emojis`,
|
||||
);
|
||||
|
||||
return batch(() =>
|
||||
emojis.map((emoji) =>
|
||||
this.#collection.client.emojis.getOrCreate(emoji._id, emoji)
|
||||
)
|
||||
this.#collection.client.emojis.getOrCreate(emoji._id, emoji),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ export class ServerBan {
|
||||
*/
|
||||
async pardon(): Promise<void> {
|
||||
await this.client.api.delete(
|
||||
`/servers/${this.id.server as ""}/bans/${this.id.user as ""}`
|
||||
`/servers/${this.id.server as ""}/bans/${this.id.user as ""}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ export class ServerMember {
|
||||
): boolean {
|
||||
return bitwiseAndEq(
|
||||
this.getPermissions(target),
|
||||
...permission.map((x) => Permission[x])
|
||||
...permission.map((x) => Permission[x]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ export class ServerMember {
|
||||
async edit(data: DataMemberEdit): Promise<void> {
|
||||
await this.#collection.client.api.patch(
|
||||
`/servers/${this.id.server as ""}/members/${this.id.user as ""}`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ export class TextSystemMessage extends SystemMessage {
|
||||
*/
|
||||
constructor(
|
||||
client: Client,
|
||||
systemMessage: APISystemMessage & { type: "text" }
|
||||
systemMessage: APISystemMessage & { type: "text" },
|
||||
) {
|
||||
super(client, systemMessage.type);
|
||||
this.content = systemMessage.content;
|
||||
@@ -96,7 +96,7 @@ export class UserSystemMessage extends SystemMessage {
|
||||
| "user_left"
|
||||
| "user_kicked"
|
||||
| "user_banned";
|
||||
}
|
||||
},
|
||||
) {
|
||||
super(client, systemMessage.type);
|
||||
this.userId = systemMessage.id;
|
||||
@@ -125,7 +125,7 @@ export class UserModeratedSystemMessage extends UserSystemMessage {
|
||||
client: Client,
|
||||
systemMessage: APISystemMessage & {
|
||||
type: "user_added" | "user_remove";
|
||||
}
|
||||
},
|
||||
) {
|
||||
super(client, systemMessage);
|
||||
this.byId = systemMessage.by;
|
||||
@@ -157,7 +157,7 @@ export class ChannelEditSystemMessage extends SystemMessage {
|
||||
| "channel_renamed"
|
||||
| "channel_description_changed"
|
||||
| "channel_icon_changed";
|
||||
}
|
||||
},
|
||||
) {
|
||||
super(client, systemMessage.type);
|
||||
this.byId = systemMessage.by;
|
||||
@@ -186,7 +186,7 @@ export class ChannelRenamedSystemMessage extends ChannelEditSystemMessage {
|
||||
client: Client,
|
||||
systemMessage: APISystemMessage & {
|
||||
type: "channel_renamed";
|
||||
}
|
||||
},
|
||||
) {
|
||||
super(client, systemMessage);
|
||||
this.name = systemMessage.name;
|
||||
@@ -209,7 +209,7 @@ export class ChannelOwnershipChangeSystemMessage extends SystemMessage {
|
||||
client: Client,
|
||||
systemMessage: APISystemMessage & {
|
||||
type: "channel_ownership_changed";
|
||||
}
|
||||
},
|
||||
) {
|
||||
super(client, systemMessage.type);
|
||||
this.fromId = systemMessage.from;
|
||||
|
||||
+12
-12
@@ -166,7 +166,7 @@ export class User {
|
||||
* Presence
|
||||
*/
|
||||
get presence(): Presence {
|
||||
return this.online ? this.status?.presence ?? "Online" : "Invisible";
|
||||
return this.online ? (this.status?.presence ?? "Online") : "Invisible";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,11 +175,11 @@ export class User {
|
||||
* @returns Status message
|
||||
*/
|
||||
statusMessage(
|
||||
translate: (presence: Presence) => string = (a) => a
|
||||
translate: (presence: Presence) => string = (a) => a,
|
||||
): string | undefined {
|
||||
return this.online
|
||||
? this.status?.text ??
|
||||
(this.presence === "Focus" ? translate("Focus") : undefined)
|
||||
? (this.status?.text ??
|
||||
(this.presence === "Focus" ? translate("Focus") : undefined))
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -204,10 +204,10 @@ export class User {
|
||||
this.#collection.client.channels.find(
|
||||
(channel) =>
|
||||
(channel.type === "Group" || channel.type === "DirectMessage") &&
|
||||
channel.recipientIds.has(this.id)
|
||||
channel.recipientIds.has(this.id),
|
||||
) ||
|
||||
this.#collection.client.serverMembers.find(
|
||||
(member) => member.id.user === this.id
|
||||
(member) => member.id.user === this.id,
|
||||
)
|
||||
) {
|
||||
if (this.#collection.client.user?.bot || this.bot) {
|
||||
@@ -229,7 +229,7 @@ export class User {
|
||||
`/users/${
|
||||
this.id === this.#collection.client.user?.id ? "@me" : this.id
|
||||
}`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ export class User {
|
||||
*/
|
||||
async openDM(): Promise<Channel> {
|
||||
let dm = [...this.#collection.client.channels.values()].find(
|
||||
(x) => x.type === "DirectMessage" && x.recipient == this
|
||||
(x) => x.type === "DirectMessage" && x.recipient == this,
|
||||
);
|
||||
|
||||
if (dm) {
|
||||
@@ -259,12 +259,12 @@ export class User {
|
||||
this.#collection.client.channels.updateUnderlyingObject(
|
||||
dm.id,
|
||||
"active",
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const data = await this.#collection.client.api.get(
|
||||
`/users/${this.id as ""}/dm`
|
||||
`/users/${this.id as ""}/dm`,
|
||||
);
|
||||
|
||||
dm = this.#collection.client.channels.getOrCreate(data._id, data)!;
|
||||
@@ -312,7 +312,7 @@ export class User {
|
||||
async fetchProfile(): Promise<UserProfile> {
|
||||
return new UserProfile(
|
||||
this.#collection.client,
|
||||
await this.#collection.client.api.get(`/users/${this.id as ""}/profile`)
|
||||
await this.#collection.client.api.get(`/users/${this.id as ""}/profile`),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ export class User {
|
||||
*/
|
||||
async fetchMutual(): Promise<{ users: string[]; servers: string[] }> {
|
||||
return await this.#collection.client.api.get(
|
||||
`/users/${this.id as ""}/mutual`
|
||||
`/users/${this.id as ""}/mutual`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ export class AccountCollection {
|
||||
confirmPasswordReset(
|
||||
token: string,
|
||||
newPassword: string,
|
||||
removeSessions: boolean
|
||||
removeSessions: boolean,
|
||||
): Promise<void> {
|
||||
return this.client.api.patch("/auth/account/reset_password", {
|
||||
token,
|
||||
@@ -138,7 +138,7 @@ export class AccountCollection {
|
||||
*/
|
||||
setSettings(
|
||||
settings: Record<string, any>,
|
||||
timestamp = +new Date()
|
||||
timestamp = +new Date(),
|
||||
): Promise<void> {
|
||||
return this.client.api.post("/sync/settings/set", {
|
||||
...settings,
|
||||
|
||||
@@ -33,7 +33,7 @@ export class BotCollection extends ClassCollection<Bot, HydratedBot> {
|
||||
const data = (await this.client.api.get("/bots/@me")) as OwnedBotsResponse;
|
||||
return batch(() => {
|
||||
data.users.forEach((user) =>
|
||||
this.client.users.getOrCreate(user._id, user)
|
||||
this.client.users.getOrCreate(user._id, user),
|
||||
);
|
||||
return data.bots.map((bot) => this.getOrCreate(bot._id, bot));
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ export class ChannelCollection extends ClassCollection<
|
||||
} else {
|
||||
const instance = new Channel(this, id);
|
||||
this.create(id, "channel", instance, this.client, data);
|
||||
isNew && this.client.emit("channelCreate", instance);
|
||||
if (isNew) this.client.emit("channelCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export class ChannelWebhookCollection extends ClassCollection<
|
||||
if (webhook) return webhook;
|
||||
const data = await this.client.api.get(
|
||||
// @ts-expect-error not in prod
|
||||
`/webhooks/${id as ""}/${token as ""}`
|
||||
`/webhooks/${id as ""}/${token as ""}`,
|
||||
);
|
||||
// @ts-expect-error not in prod
|
||||
return this.getOrCreate(data.id, data);
|
||||
|
||||
@@ -59,7 +59,7 @@ export abstract class Collection<T> {
|
||||
* @param cb Callback for each pair
|
||||
*/
|
||||
abstract forEach(
|
||||
cb: (value: T, key: string, map: Map<string, T>) => void
|
||||
cb: (value: T, key: string, map: Map<string, T>) => void,
|
||||
): void;
|
||||
|
||||
/**
|
||||
@@ -169,7 +169,7 @@ export abstract class StoreCollection<T, V> extends Collection<T> {
|
||||
type: keyof Hydrators,
|
||||
instance: T,
|
||||
context: unknown,
|
||||
data?: unknown
|
||||
data?: unknown,
|
||||
): void {
|
||||
this.#storage.hydrate(id, type, context, data);
|
||||
this.#objects.set(id, instance);
|
||||
|
||||
@@ -33,7 +33,7 @@ export class EmojiCollection extends ClassCollection<Emoji, HydratedEmoji> {
|
||||
} else {
|
||||
const instance = new Emoji(this, id);
|
||||
this.create(id, "emoji", instance, this.client, data);
|
||||
isNew && this.client.emit("emojiCreate", instance);
|
||||
if (isNew) this.client.emit("emojiCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export class MessageCollection extends ClassCollection<
|
||||
if (message && !this.isPartial(messageId)) return message;
|
||||
|
||||
const data = await this.client.api.get(
|
||||
`/channels/${channelId as ""}/messages/${messageId as ""}`
|
||||
`/channels/${channelId as ""}/messages/${messageId as ""}`,
|
||||
);
|
||||
|
||||
return this.getOrCreate(data._id, data, false);
|
||||
@@ -41,7 +41,7 @@ export class MessageCollection extends ClassCollection<
|
||||
} else {
|
||||
const instance = new Message(this, id);
|
||||
this.create(id, "message", instance, this.client, data);
|
||||
isNew && this.client.emit("messageCreate", instance);
|
||||
if (isNew) this.client.emit("messageCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export class ServerCollection extends ClassCollection<Server, HydratedServer> {
|
||||
} else {
|
||||
const instance = new Server(this, id);
|
||||
this.create(id, "server", instance, this.client, data);
|
||||
isNew && this.client.emit("serverCreate", instance);
|
||||
if (isNew) this.client.emit("serverCreate", instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ export class ServerCollection extends ClassCollection<Server, HydratedServer> {
|
||||
async createServer(data: DataCreateServer): Promise<Server> {
|
||||
const { server, channels } = await this.client.api.post(
|
||||
`/servers/create`,
|
||||
data
|
||||
data,
|
||||
);
|
||||
|
||||
return batch(() => {
|
||||
|
||||
@@ -53,7 +53,7 @@ export class ServerMemberCollection extends ClassCollection<
|
||||
`/servers/${serverId as ""}/members/${userId as ""}`,
|
||||
{
|
||||
roles: false,
|
||||
}
|
||||
},
|
||||
// TODO: fix typings in revolt-api
|
||||
)) as Member;
|
||||
|
||||
@@ -75,7 +75,7 @@ export class ServerMemberCollection extends ClassCollection<
|
||||
"serverMember",
|
||||
instance,
|
||||
this.client,
|
||||
data
|
||||
data,
|
||||
);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export class SessionCollection extends ClassCollection<
|
||||
async fetch(): Promise<Session[]> {
|
||||
const data = await this.client.api.get("/auth/session/all");
|
||||
return batch(() =>
|
||||
data.map((session) => this.getOrCreate(session._id, session))
|
||||
data.map((session) => this.getOrCreate(session._id, session)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+15
-20
@@ -1,8 +1,7 @@
|
||||
import type { Accessor, Setter } from "solid-js";
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
import EventEmitter from "eventemitter3";
|
||||
import WebSocket from "isomorphic-ws";
|
||||
import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter";
|
||||
import type { Error } from "revolt-api";
|
||||
|
||||
import type { ProtocolV1 } from "./v1.js";
|
||||
@@ -67,17 +66,17 @@ export interface EventClientOptions {
|
||||
* Events provided by the client.
|
||||
*/
|
||||
type Events<T extends AvailableProtocols, P extends EventProtocol<T>> = {
|
||||
error: (error: Error) => void;
|
||||
event: (event: P["server"]) => void;
|
||||
state: (state: ConnectionState) => void;
|
||||
error: [error: Error];
|
||||
event: [event: P["server"]];
|
||||
state: [state: ConnectionState];
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple wrapper around the Revolt websocket service.
|
||||
*/
|
||||
export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
Events<T, EventProtocol<T>>
|
||||
> {
|
||||
export class EventClient<
|
||||
T extends AvailableProtocols,
|
||||
> extends AsyncEventEmitter<Events<T, EventProtocol<T>>> {
|
||||
readonly options: EventClientOptions;
|
||||
|
||||
#protocolVersion: T;
|
||||
@@ -106,7 +105,7 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
constructor(
|
||||
protocolVersion: T,
|
||||
transportFormat: "json" = "json",
|
||||
options?: Partial<EventClientOptions>
|
||||
options?: Partial<EventClientOptions>,
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -153,13 +152,11 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
|
||||
this.#connectTimeoutReference = setTimeout(
|
||||
() => this.disconnect(),
|
||||
this.options.pongTimeout * 1e3
|
||||
this.options.pongTimeout * 1e3,
|
||||
) as never;
|
||||
|
||||
this.#socket = new WebSocket(
|
||||
`${uri}?version=${this.#protocolVersion}&format=${
|
||||
this.#transportFormat
|
||||
}&token=${token}`
|
||||
`${uri}?version=${this.#protocolVersion}&format=${this.#transportFormat}&token=${token}`,
|
||||
);
|
||||
|
||||
this.#socket.onopen = () => {
|
||||
@@ -167,7 +164,7 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
this.send({ type: "Ping", data: +new Date() });
|
||||
this.#pongTimeoutReference = setTimeout(
|
||||
() => this.disconnect(),
|
||||
this.options.pongTimeout * 1e3
|
||||
this.options.pongTimeout * 1e3,
|
||||
) as never;
|
||||
}, this.options.heartbeatInterval * 1e3) as never;
|
||||
};
|
||||
@@ -215,7 +212,7 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
* @param event Event
|
||||
*/
|
||||
send(event: EventProtocol<T>["client"]): void {
|
||||
this.options.debug && console.debug("[C->S]", event);
|
||||
if (this.options.debug) console.debug("[C->S]", event);
|
||||
if (!this.#socket) throw "Socket closed, trying to send.";
|
||||
this.#socket.send(JSON.stringify(event));
|
||||
}
|
||||
@@ -225,7 +222,7 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
* @param event Event
|
||||
*/
|
||||
handle(event: EventProtocol<T>["server"]): void {
|
||||
this.options.debug && console.debug("[S->C]", event);
|
||||
if (this.options.debug) console.debug("[S->C]", event);
|
||||
switch (event.type) {
|
||||
case "Ping":
|
||||
this.send({
|
||||
@@ -236,7 +233,7 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
case "Pong":
|
||||
clearTimeout(this.#pongTimeoutReference);
|
||||
this.#setPing(+new Date() - event.data);
|
||||
this.options.debug && console.debug(`[ping] ${this.ping()}ms`);
|
||||
if (this.options.debug) console.debug(`[ping] ${this.ping()}ms`);
|
||||
return;
|
||||
case "Error":
|
||||
this.#lastError = {
|
||||
@@ -267,9 +264,7 @@ export class EventClient<T extends AvailableProtocols> extends EventEmitter<
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw `Unreachable code. Received ${
|
||||
event.type
|
||||
} in state ${this.state()}.`;
|
||||
throw `Unreachable code. Received ${event.type} in state ${this.state()}.`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-22
@@ -190,7 +190,7 @@ type ReadyData = {
|
||||
export async function handleEvent(
|
||||
client: Client,
|
||||
event: ServerMessage,
|
||||
setReady: Setter<boolean>
|
||||
setReady: Setter<boolean>,
|
||||
): Promise<void> {
|
||||
if (client.options.debug) {
|
||||
console.debug("[S->C]", event);
|
||||
@@ -257,7 +257,7 @@ export async function handleEvent(
|
||||
client.channels.updateUnderlyingObject(
|
||||
event.channel,
|
||||
"lastMessageId",
|
||||
event._id
|
||||
event._id,
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -276,7 +276,7 @@ export async function handleEvent(
|
||||
"message",
|
||||
{ ...event.data, channel: event.channel },
|
||||
client,
|
||||
false
|
||||
false,
|
||||
),
|
||||
editedAt: new Date(),
|
||||
});
|
||||
@@ -296,14 +296,14 @@ export async function handleEvent(
|
||||
client.messages.updateUnderlyingObject(event.id, "embeds", (embeds) => [
|
||||
...(embeds ?? []),
|
||||
...(event.append.embeds?.map((embed) =>
|
||||
MessageEmbed.from(client, embed)
|
||||
MessageEmbed.from(client, embed),
|
||||
) ?? []),
|
||||
]);
|
||||
|
||||
client.messages.updateUnderlyingObject(
|
||||
event.id,
|
||||
"channelId",
|
||||
event.channel
|
||||
event.channel,
|
||||
);
|
||||
|
||||
client.emit("messageUpdate", message, previousMessage);
|
||||
@@ -333,8 +333,8 @@ export async function handleEvent(
|
||||
return undefined!;
|
||||
})
|
||||
.filter((x) => x),
|
||||
client.channels.get(event.channel)
|
||||
)
|
||||
client.channels.get(event.channel),
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -354,7 +354,7 @@ export async function handleEvent(
|
||||
"messageReactionAdd",
|
||||
message,
|
||||
event.user_id,
|
||||
event.emoji_id
|
||||
event.emoji_id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -373,7 +373,7 @@ export async function handleEvent(
|
||||
"messageReactionRemove",
|
||||
message,
|
||||
event.user_id,
|
||||
event.emoji_id
|
||||
event.emoji_id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -448,7 +448,7 @@ export async function handleEvent(
|
||||
client.emit(
|
||||
"channelGroupJoin",
|
||||
channel,
|
||||
await client.users.fetch(event.user)
|
||||
await client.users.fetch(event.user),
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -465,7 +465,7 @@ export async function handleEvent(
|
||||
client.emit(
|
||||
"channelGroupLeave",
|
||||
channel,
|
||||
client.users.getOrPartial(event.user)!
|
||||
client.users.getOrPartial(event.user)!,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -482,7 +482,7 @@ export async function handleEvent(
|
||||
client.emit(
|
||||
"channelStartTyping",
|
||||
channel,
|
||||
client.users.getOrPartial(event.user)!
|
||||
client.users.getOrPartial(event.user)!,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -499,7 +499,7 @@ export async function handleEvent(
|
||||
client.emit(
|
||||
"channelStopTyping",
|
||||
channel,
|
||||
client.users.getOrPartial(event.user)!
|
||||
client.users.getOrPartial(event.user)!,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -614,7 +614,7 @@ export async function handleEvent(
|
||||
client.serverMembers.getOrCreate(id, {
|
||||
_id: id,
|
||||
joined_at: new Date().toUTCString(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -624,7 +624,7 @@ export async function handleEvent(
|
||||
if (member) {
|
||||
const previousMember = {
|
||||
...client.serverMembers.getUnderlyingObject(
|
||||
event.id.server + event.id.user
|
||||
event.id.server + event.id.user,
|
||||
),
|
||||
};
|
||||
|
||||
@@ -651,7 +651,7 @@ export async function handleEvent(
|
||||
|
||||
client.serverMembers.updateUnderlyingObject(
|
||||
event.id.server + event.id.user,
|
||||
changes as never
|
||||
changes as never,
|
||||
);
|
||||
|
||||
client.emit("serverMemberUpdate", member, previousMember);
|
||||
@@ -666,7 +666,7 @@ export async function handleEvent(
|
||||
type: "ServerDelete",
|
||||
id: event.id,
|
||||
},
|
||||
setReady
|
||||
setReady,
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -679,7 +679,7 @@ export async function handleEvent(
|
||||
|
||||
if (client.serverMembers.getOrPartial(id)) {
|
||||
const member = client.serverMembers.getUnderlyingObject(
|
||||
id.server + id.user
|
||||
id.server + id.user,
|
||||
);
|
||||
|
||||
client.emit("serverMemberLeave", member);
|
||||
@@ -735,7 +735,7 @@ export async function handleEvent(
|
||||
relationship: event.user.relationship!,
|
||||
},
|
||||
},
|
||||
setReady
|
||||
setReady,
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -749,7 +749,7 @@ export async function handleEvent(
|
||||
online: event.online,
|
||||
},
|
||||
},
|
||||
setReady
|
||||
setReady,
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -769,7 +769,7 @@ export async function handleEvent(
|
||||
.filter((message) => message.authorId === event.user_id)
|
||||
.map((message) => message.id),
|
||||
},
|
||||
setReady
|
||||
setReady,
|
||||
);
|
||||
|
||||
handleEvent(
|
||||
@@ -786,7 +786,7 @@ export async function handleEvent(
|
||||
},
|
||||
clear: ["Avatar", "StatusPresence", "StatusText"],
|
||||
},
|
||||
setReady
|
||||
setReady,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -40,19 +40,20 @@ export type Hydrate<Input, Output> = {
|
||||
function hydrateInternal<Input extends object, Output>(
|
||||
hydration: Hydrate<Input, Output>,
|
||||
input: Input,
|
||||
context: unknown
|
||||
context: unknown,
|
||||
): Output {
|
||||
return (Object.keys(input) as (keyof Input)[]).reduce((acc, key) => {
|
||||
let targetKey, value;
|
||||
try {
|
||||
targetKey = hydration.keyMapping[key] ?? key;
|
||||
value = hydration.functions[targetKey as keyof Output](input, context);
|
||||
} catch (err) {
|
||||
if (key === "partial")
|
||||
} catch {
|
||||
if (key === "partial") {
|
||||
return {
|
||||
...acc,
|
||||
partial: input["partial" as never],
|
||||
};
|
||||
}
|
||||
if (key === "type") return acc;
|
||||
console.debug(`Skipping key ${String(key)} during hydration!`);
|
||||
return acc;
|
||||
@@ -97,11 +98,11 @@ export function hydrate<T extends keyof Hydrators>(
|
||||
type: T,
|
||||
input: Partial<ExtractInput<Hydrators[T]>>,
|
||||
context: unknown,
|
||||
initial?: boolean
|
||||
initial?: boolean,
|
||||
): ExtractOutput<Hydrators[T]> {
|
||||
return hydrateInternal(
|
||||
hydrators[type] as never,
|
||||
initial ? { ...hydrators[type].initialHydration(), ...input } : input,
|
||||
context
|
||||
context,
|
||||
) as ExtractOutput<Hydrators[T]>;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ export const serverHydration: Hydrate<APIServer, HydratedServer> = {
|
||||
systemMessages: (server) => server.system_messages ?? {},
|
||||
roles: (server) =>
|
||||
new ReactiveMap(
|
||||
Object.keys(server.roles!).map((id) => [id, server.roles![id]])
|
||||
Object.keys(server.roles!).map((id) => [id, server.roles![id]]),
|
||||
),
|
||||
defaultPermissions: (server) => server.default_permissions,
|
||||
icon: (server, ctx) => new File(ctx as Client, server.icon!),
|
||||
|
||||
+2
-3
@@ -5,9 +5,8 @@ export type Merge<T extends object> = {
|
||||
[k in NonCommonKeys<T>]?: PickTypeOf<T, k>;
|
||||
};
|
||||
|
||||
type PickTypeOf<T, K extends string | number | symbol> = K extends AllKeys<T>
|
||||
? PickType<T, K>
|
||||
: never;
|
||||
type PickTypeOf<T, K extends string | number | symbol> =
|
||||
K extends AllKeys<T> ? PickType<T, K> : never;
|
||||
|
||||
// eslint-disable-next-line
|
||||
type PickType<T, K extends AllKeys<T>> = T extends { [k in K]?: any }
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import Long from "long";
|
||||
|
||||
import type { Client } from "../Client.js";
|
||||
import type { Channel } from "../classes/Channel.js";
|
||||
import { Server } from "../classes/Server.js";
|
||||
import type { ServerMember } from "../classes/ServerMember.js";
|
||||
import { Channel, Client, Server, ServerMember } from "../index.js";
|
||||
|
||||
import {
|
||||
ALLOW_IN_TIMEOUT,
|
||||
@@ -19,8 +14,8 @@ import {
|
||||
* @param b Inputs (OR'd together)
|
||||
*/
|
||||
export function bitwiseAndEq(a: number, ...b: number[]): boolean {
|
||||
const value = b.reduce((prev, cur) => prev.or(cur), Long.fromNumber(0));
|
||||
return value.and(a).eq(value);
|
||||
const value = b.reduce((prev, cur) => prev | BigInt(cur), 0n);
|
||||
return (value & BigInt(a)) === value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +31,7 @@ export function calculatePermission(
|
||||
* Pretend to be another ServerMember
|
||||
*/
|
||||
member?: ServerMember;
|
||||
}
|
||||
},
|
||||
): number {
|
||||
const user = options?.member ? options?.member.user : client.user;
|
||||
if (user?.privileged) {
|
||||
@@ -58,26 +53,26 @@ export function calculatePermission(
|
||||
if (!member) return 0;
|
||||
|
||||
// 3. Apply allows from default_permissions.
|
||||
let perm = Long.fromNumber(target.defaultPermissions);
|
||||
let perm = BigInt(target.defaultPermissions);
|
||||
|
||||
// 4. If user has roles, iterate in order.
|
||||
if (member.roles && target.roles) {
|
||||
// 5. Apply allows and denies from roles.
|
||||
const permissions = member.orderedRoles.map(
|
||||
(role) => role.permissions ?? { a: 0, d: 0 }
|
||||
(role) => role.permissions ?? { a: 0, d: 0 },
|
||||
);
|
||||
|
||||
for (const permission of permissions) {
|
||||
perm = perm.or(permission.a).and(Long.fromNumber(permission.d).not());
|
||||
perm = (perm | BigInt(permission.a)) & ~BigInt(permission.d);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Revoke permissions if ServerMember is timed out.
|
||||
if (member.timeout && member.timeout > new Date()) {
|
||||
perm = perm.and(ALLOW_IN_TIMEOUT);
|
||||
perm = perm & BigInt(ALLOW_IN_TIMEOUT);
|
||||
}
|
||||
|
||||
return perm.toNumber();
|
||||
return Number(perm);
|
||||
}
|
||||
} else {
|
||||
// 1. Check channel type.
|
||||
@@ -124,15 +119,13 @@ export function calculatePermission(
|
||||
if (!member) return 0;
|
||||
|
||||
// 5. Calculate server base permissions.
|
||||
let perm = Long.fromNumber(
|
||||
calculatePermission(client, server, options)
|
||||
);
|
||||
let perm = BigInt(calculatePermission(client, server, options));
|
||||
|
||||
// 6. Apply default allows and denies for channel.
|
||||
if (target.defaultPermissions) {
|
||||
perm = perm
|
||||
.or(target.defaultPermissions.a)
|
||||
.and(Long.fromNumber(target.defaultPermissions.d).not());
|
||||
perm =
|
||||
(perm | BigInt(target.defaultPermissions.a)) &
|
||||
~BigInt(target.defaultPermissions.d);
|
||||
}
|
||||
|
||||
// 7. If user has roles, iterate in order.
|
||||
@@ -143,19 +136,17 @@ export function calculatePermission(
|
||||
for (const id of roles) {
|
||||
const override = target.rolePermissions[id];
|
||||
if (override) {
|
||||
perm = perm
|
||||
.or(override.a)
|
||||
.and(Long.fromNumber(override.d).not());
|
||||
perm = (perm | BigInt(override.a)) & ~BigInt(override.d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Revoke permissions if ServerMember is timed out.
|
||||
if (member.timeout && member.timeout > new Date()) {
|
||||
perm = perm.and(ALLOW_IN_TIMEOUT);
|
||||
perm = perm & BigInt(ALLOW_IN_TIMEOUT);
|
||||
}
|
||||
|
||||
return perm.toNumber();
|
||||
return Number(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
require("dotenv").config();
|
||||
|
||||
const { Client } = require(".");
|
||||
|
||||
const client = new Client({ debug: true });
|
||||
|
||||
client.on("ready", () => console.info(`Logged in as ${client.user.username}!`));
|
||||
client.on("disconnected", () => console.info("Disconnected."));
|
||||
|
||||
client.on("messageCreate", (message) => console.info(message.content));
|
||||
|
||||
client.loginBot(process.env.TOKEN);
|
||||
@@ -1,6 +1,7 @@
|
||||
import "dotenv/config";
|
||||
#!/usr/bin/env -S node --env-file
|
||||
import { env } from "node:process";
|
||||
|
||||
import { Client } from "./lib/esm/index.js";
|
||||
import { Client } from "./lib/index.js";
|
||||
|
||||
const client = new Client({ debug: true });
|
||||
|
||||
@@ -9,4 +10,4 @@ client.on("disconnected", () => console.info("Disconnected."));
|
||||
|
||||
client.on("messageCreate", (message) => console.info(message.content));
|
||||
|
||||
client.loginBot(process.env.TOKEN);
|
||||
client.loginBot(env.TOKEN);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"outDir": "./lib/cjs"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"outDir": "./lib/esm",
|
||||
"outDir": "./lib",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
|
||||
Reference in New Issue
Block a user