mirror of
https://github.com/stoatchat/javascript-client-sdk.git
synced 2026-07-18 16:34:27 -04:00
chore(housekeeping): format code using prettier
This commit is contained in:
@@ -2,6 +2,4 @@ module.exports = {
|
||||
tabWidth: 4,
|
||||
trailingComma: "all",
|
||||
jsxBracketSameLine: true,
|
||||
importOrder: ["/(api)", "/(maps)", "/(util)", "/(websocket)", "^[./]"],
|
||||
importOrderSeparation: true,
|
||||
};
|
||||
|
||||
@@ -9,25 +9,17 @@
|
||||
```typescript
|
||||
let client = new Client();
|
||||
|
||||
client.on('ready', async () =>
|
||||
console.info(`Logged in as ${client.user!.username}!`)
|
||||
client.on("ready", async () =>
|
||||
console.info(`Logged in as ${client.user!.username}!`),
|
||||
);
|
||||
|
||||
client.on('message', async message => {
|
||||
if (message.content === 'sus') {
|
||||
message.channel!.sendMessage('sus!');
|
||||
client.on("message", async (message) => {
|
||||
if (message.content === "sus") {
|
||||
message.channel!.sendMessage("sus!");
|
||||
}
|
||||
});
|
||||
|
||||
// To login as a bot:
|
||||
client.loginBot('..');
|
||||
|
||||
// To login as a user,
|
||||
// either create a new session:
|
||||
client.login({ email: '..', password: '..' });
|
||||
|
||||
// Or use an existing session:
|
||||
client.useExistingSession({ token: '..' });
|
||||
client.loginBot("..");
|
||||
```
|
||||
|
||||
## MobX
|
||||
|
||||
+2
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "revolt.js",
|
||||
"version": "5.1.0-alpha.8",
|
||||
"version": "5.1.0-alpha.9",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/revoltchat/revolt.js",
|
||||
"author": "Paul Makles <insrt.uk>",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ws": "^8.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "^3.1.1",
|
||||
"@types/events": "^3.0.0",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/lodash.defaultsdeep": "^4.6.6",
|
||||
@@ -38,7 +37,7 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"tsc-watch": "^4.1.0",
|
||||
"typedoc": "^0.21.4",
|
||||
"typescript": "^4.2.3"
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
|
||||
+171
-116
@@ -1,66 +1,75 @@
|
||||
import Axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||
import defaultsDeep from 'lodash.defaultsdeep';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import Axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import defaultsDeep from "lodash.defaultsdeep";
|
||||
import { makeObservable, observable } from "mobx";
|
||||
import type { Session } from "revolt-api/types/Auth";
|
||||
import type { SizeOptions } from "revolt-api/types/Autumn";
|
||||
import type { RevoltConfiguration } from "revolt-api/types/Core";
|
||||
import { MemberCompositeKey, Role } from "revolt-api/types/Servers";
|
||||
|
||||
import { WebSocketClient } from './websocket/client';
|
||||
import { Route, RoutePath, RouteMethod } from './api/routes';
|
||||
import { ClientboundNotification } from './websocket/notifications';
|
||||
import { Route, RoutePath, RouteMethod } from "./api/routes";
|
||||
|
||||
import type { RevoltConfiguration } from 'revolt-api/types/Core';
|
||||
import type { SizeOptions } from 'revolt-api/types/Autumn';
|
||||
import type { Session } from 'revolt-api/types/Auth';
|
||||
import Bots from "./maps/Bots";
|
||||
import Channels, { Channel } from "./maps/Channels";
|
||||
import Members, { Member } from "./maps/Members";
|
||||
import Messages, { Message } from "./maps/Messages";
|
||||
import Servers, { Server } from "./maps/Servers";
|
||||
import Users, { User } from "./maps/Users";
|
||||
|
||||
import Users, { User } from './maps/Users';
|
||||
import Channels, { Channel } from './maps/Channels';
|
||||
import Servers, { Server } from './maps/Servers';
|
||||
import Members, { Member } from './maps/Members';
|
||||
import Messages, { Message } from './maps/Messages';
|
||||
import Bots from './maps/Bots';
|
||||
import { WebSocketClient } from "./websocket/client";
|
||||
import { ClientboundNotification } from "./websocket/notifications";
|
||||
|
||||
import { makeObservable, observable } from 'mobx';
|
||||
import { defaultConfig } from './config';
|
||||
import { MemberCompositeKey, Role } from 'revolt-api/types/Servers';
|
||||
import { defaultConfig } from "./config";
|
||||
|
||||
/**
|
||||
* Client options object
|
||||
*/
|
||||
export interface ClientOptions {
|
||||
apiURL: string
|
||||
debug: boolean
|
||||
cache: boolean
|
||||
apiURL: string;
|
||||
debug: boolean;
|
||||
cache: boolean;
|
||||
|
||||
heartbeat: number
|
||||
autoReconnect: boolean
|
||||
heartbeat: number;
|
||||
autoReconnect: boolean;
|
||||
|
||||
ackRateLimiter: boolean
|
||||
ackRateLimiter: boolean;
|
||||
}
|
||||
|
||||
export declare interface Client {
|
||||
on(event: 'connected', listener: () => void): this;
|
||||
on(event: 'connecting', listener: () => void): this;
|
||||
on(event: 'dropped', listener: () => void): this;
|
||||
on(event: 'ready', listener: () => void): this;
|
||||
on(event: 'packet', listener: (packet: ClientboundNotification) => void): this;
|
||||
on(event: "connected", listener: () => void): this;
|
||||
on(event: "connecting", listener: () => void): this;
|
||||
on(event: "dropped", listener: () => void): this;
|
||||
on(event: "ready", listener: () => void): this;
|
||||
on(
|
||||
event: "packet",
|
||||
listener: (packet: ClientboundNotification) => void,
|
||||
): this;
|
||||
|
||||
on(event: 'message', listener: (message: Message) => void): this;
|
||||
on(event: 'message/update', listener: (message: Message) => void): this;
|
||||
on(event: 'message/delete', listener: (id: string) => void): this;
|
||||
on(event: "message", listener: (message: Message) => void): this;
|
||||
on(event: "message/update", listener: (message: Message) => void): this;
|
||||
on(event: "message/delete", listener: (id: string) => void): this;
|
||||
|
||||
on(event: 'channel/create', listener: (channel: Channel) => void): this;
|
||||
on(event: 'channel/update', listener: (channel: Channel) => void): this;
|
||||
on(event: 'channel/delete', listener: (id: string) => void): this;
|
||||
on(event: "channel/create", listener: (channel: Channel) => void): this;
|
||||
on(event: "channel/update", listener: (channel: Channel) => void): this;
|
||||
on(event: "channel/delete", listener: (id: string) => void): this;
|
||||
|
||||
on(event: 'server/update', listener: (server: Server) => void): this;
|
||||
on(event: 'server/delete', listener: (id: string) => void): this;
|
||||
on(event: "server/update", listener: (server: Server) => void): this;
|
||||
on(event: "server/delete", listener: (id: string) => void): this;
|
||||
|
||||
on(event: 'role/update', listener: (roleId: string, role: Role, serverId: string) => void): this;
|
||||
on(event: 'role/delete', listener: (id: string, serverId: string) => void): this;
|
||||
on(
|
||||
event: "role/update",
|
||||
listener: (roleId: string, role: Role, serverId: string) => void,
|
||||
): this;
|
||||
on(
|
||||
event: "role/delete",
|
||||
listener: (id: string, serverId: string) => void,
|
||||
): this;
|
||||
|
||||
on(event: 'member/join', listener: (member: Member) => void): this;
|
||||
on(event: 'member/update', listener: (member: Member) => void): this;
|
||||
on(event: 'member/leave', listener: (id: MemberCompositeKey) => void): this;
|
||||
on(event: "member/join", listener: (member: Member) => void): this;
|
||||
on(event: "member/update", listener: (member: Member) => void): this;
|
||||
on(event: "member/leave", listener: (id: MemberCompositeKey) => void): this;
|
||||
|
||||
on(event: 'user/relationship', listener: (user: User) => void): this;
|
||||
on(event: "user/relationship", listener: (user: User) => void): this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +82,11 @@ export const RE_MENTIONS = /<@([A-z0-9]{26})>/g;
|
||||
*/
|
||||
export const RE_SPOILER = /!!.+!!/g;
|
||||
|
||||
export type FileArgs = [ options?: SizeOptions, allowAnimation?: boolean, fallback?: string ];
|
||||
export type FileArgs = [
|
||||
options?: SizeOptions,
|
||||
allowAnimation?: boolean,
|
||||
fallback?: string,
|
||||
];
|
||||
|
||||
export class Client extends EventEmitter {
|
||||
heartbeat: number;
|
||||
@@ -103,15 +116,19 @@ export class Client extends EventEmitter {
|
||||
this.messages = new Messages(this);
|
||||
this.bots = new Bots(this);
|
||||
|
||||
makeObservable(this, {
|
||||
users: observable,
|
||||
channels: observable,
|
||||
servers: observable,
|
||||
members: observable,
|
||||
messages: observable
|
||||
}, {
|
||||
proxy: false
|
||||
});
|
||||
makeObservable(
|
||||
this,
|
||||
{
|
||||
users: observable,
|
||||
channels: observable,
|
||||
servers: observable,
|
||||
members: observable,
|
||||
messages: observable,
|
||||
},
|
||||
{
|
||||
proxy: false,
|
||||
},
|
||||
);
|
||||
|
||||
this.options = defaultsDeep(options, defaultConfig);
|
||||
if (this.options.cache) throw "Cache is not supported yet.";
|
||||
@@ -121,21 +138,29 @@ export class Client extends EventEmitter {
|
||||
this.heartbeat = this.options.heartbeat;
|
||||
|
||||
if (options.debug) {
|
||||
this.Axios.interceptors.request.use(request => {
|
||||
console.debug('[<]', request.method?.toUpperCase(), request.url);
|
||||
return request
|
||||
})
|
||||
|
||||
this.Axios.interceptors.response.use(response => {
|
||||
console.debug('[>] (' + response.status + ':', response.statusText + ')', JSON.stringify(response.data));
|
||||
return response
|
||||
})
|
||||
this.Axios.interceptors.request.use((request) => {
|
||||
console.debug(
|
||||
"[<]",
|
||||
request.method?.toUpperCase(),
|
||||
request.url,
|
||||
);
|
||||
return request;
|
||||
});
|
||||
|
||||
this.Axios.interceptors.response.use((response) => {
|
||||
console.debug(
|
||||
"[>] (" + response.status + ":",
|
||||
response.statusText + ")",
|
||||
JSON.stringify(response.data),
|
||||
);
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
this.on('message', async message => {
|
||||
this.on("message", async (message) => {
|
||||
let channel = message.channel;
|
||||
if (!channel) return;
|
||||
if (channel.channel_type === 'DirectMessage') {
|
||||
if (channel.channel_type === "DirectMessage") {
|
||||
channel.active = true;
|
||||
}
|
||||
|
||||
@@ -162,9 +187,16 @@ export class Client extends EventEmitter {
|
||||
/**
|
||||
* ? Axios request wrapper.
|
||||
*/
|
||||
|
||||
req<M extends RouteMethod, T extends RoutePath>(method: M, url: T): Promise<Route<M, T>["response"]>;
|
||||
req<M extends RouteMethod, T extends RoutePath>(method: M, url: T, data: Route<M, T>["data"]): Promise<Route<M, T>["response"]>;
|
||||
|
||||
req<M extends RouteMethod, T extends RoutePath>(
|
||||
method: M,
|
||||
url: T,
|
||||
): Promise<Route<M, T>["response"]>;
|
||||
req<M extends RouteMethod, T extends RoutePath>(
|
||||
method: M,
|
||||
url: T,
|
||||
data: Route<M, T>["data"],
|
||||
): Promise<Route<M, T>["response"]>;
|
||||
|
||||
/**
|
||||
* Perform an HTTP request using Axios, specifying a route data object.
|
||||
@@ -173,11 +205,15 @@ export class Client extends EventEmitter {
|
||||
* @param data Route data object
|
||||
* @returns The response body
|
||||
*/
|
||||
async req<M extends RouteMethod, T extends RoutePath>(method: M, url: T, data?: Route<M, T>["data"]): Promise<Route<M, T>["response"]> {
|
||||
async req<M extends RouteMethod, T extends RoutePath>(
|
||||
method: M,
|
||||
url: T,
|
||||
data?: Route<M, T>["data"],
|
||||
): Promise<Route<M, T>["response"]> {
|
||||
let res = await this.Axios.request({
|
||||
method,
|
||||
data,
|
||||
url
|
||||
url,
|
||||
});
|
||||
|
||||
return res.data;
|
||||
@@ -190,7 +226,11 @@ export class Client extends EventEmitter {
|
||||
* @param data Axios request config object
|
||||
* @returns The response body
|
||||
*/
|
||||
async request<M extends RouteMethod, T extends RoutePath>(method: M, url: T, data: AxiosRequestConfig): Promise<Route<M, T>["response"]> {
|
||||
async request<M extends RouteMethod, T extends RoutePath>(
|
||||
method: M,
|
||||
url: T,
|
||||
data: AxiosRequestConfig,
|
||||
): Promise<Route<M, T>["response"]> {
|
||||
let res = await this.Axios.request({
|
||||
...data,
|
||||
method,
|
||||
@@ -203,35 +243,36 @@ export class Client extends EventEmitter {
|
||||
/**
|
||||
* ? Authentication and connection.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the configuration of the server.
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* Unlike `fetchConfiguration`, this function also fetches the
|
||||
* configuration if it has already been fetched before.
|
||||
*/
|
||||
async connect() {
|
||||
this.configuration = await this.req('GET', '/');
|
||||
this.configuration = await this.req("GET", "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the configuration of the server if it has not been already fetched.
|
||||
*/
|
||||
async fetchConfiguration() {
|
||||
if (!this.configuration)
|
||||
await this.connect();
|
||||
if (!this.configuration) await this.connect();
|
||||
}
|
||||
|
||||
private $generateHeaders(session: Session | string | undefined = this.session) {
|
||||
if (typeof session === 'string') {
|
||||
private $generateHeaders(
|
||||
session: Session | string | undefined = this.session,
|
||||
) {
|
||||
if (typeof session === "string") {
|
||||
return {
|
||||
'x-bot-token': session
|
||||
}
|
||||
"x-bot-token": session,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
'x-session-token': session?.token
|
||||
}
|
||||
"x-session-token": session?.token,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,10 +281,10 @@ export class Client extends EventEmitter {
|
||||
* @param details Login data object
|
||||
* @returns An onboarding function if onboarding is required, undefined otherwise
|
||||
*/
|
||||
async login(details: Route<'POST', '/auth/session/login'>["data"]) {
|
||||
async login(details: Route<"POST", "/auth/session/login">["data"]) {
|
||||
await this.fetchConfiguration();
|
||||
this.session = await this.req('POST', '/auth/session/login', details);
|
||||
|
||||
this.session = await this.req("POST", "/auth/session/login", details);
|
||||
|
||||
return await this.$connect();
|
||||
}
|
||||
|
||||
@@ -272,7 +313,7 @@ export class Client extends EventEmitter {
|
||||
// Check onboarding status and connect to notifications service.
|
||||
private async $connect() {
|
||||
this.Axios.defaults.headers = this.$generateHeaders();
|
||||
let { onboarding } = await this.req('GET', '/onboard/hello');
|
||||
let { onboarding } = await this.req("GET", "/onboard/hello");
|
||||
if (onboarding) {
|
||||
return (username: string, loginAfterSuccess?: boolean) =>
|
||||
this.completeOnboarding({ username }, loginAfterSuccess);
|
||||
@@ -286,8 +327,11 @@ export class Client extends EventEmitter {
|
||||
* @param data Onboarding data object
|
||||
* @param loginAfterSuccess Defines whether to automatically log in and connect after onboarding finishes
|
||||
*/
|
||||
async completeOnboarding(data: Route<'POST', '/onboard/complete'>["data"], loginAfterSuccess?: boolean) {
|
||||
await this.req('POST', '/onboard/complete', data);
|
||||
async completeOnboarding(
|
||||
data: Route<"POST", "/onboard/complete">["data"],
|
||||
loginAfterSuccess?: boolean,
|
||||
) {
|
||||
await this.req("POST", "/onboard/complete", data);
|
||||
if (loginAfterSuccess) {
|
||||
await this.$connect();
|
||||
}
|
||||
@@ -303,7 +347,7 @@ export class Client extends EventEmitter {
|
||||
* @returns Invite information.
|
||||
*/
|
||||
async fetchInvite(code: string) {
|
||||
return await this.req('GET', `/invites/${code}` as '/invites/id');
|
||||
return await this.req("GET", `/invites/${code}` as "/invites/id");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,7 +356,7 @@ export class Client extends EventEmitter {
|
||||
* @returns Data provided by invite.
|
||||
*/
|
||||
async joinInvite(code: string) {
|
||||
return await this.req('POST', `/invites/${code}` as '/invites/id');
|
||||
return await this.req("POST", `/invites/${code}` as "/invites/id");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,7 +364,7 @@ export class Client extends EventEmitter {
|
||||
* @param code The invite code.
|
||||
*/
|
||||
async deleteInvite(code: string) {
|
||||
await this.req('DELETE', `/invites/${code}` as '/invites/id');
|
||||
await this.req("DELETE", `/invites/${code}` as "/invites/id");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,7 +373,7 @@ export class Client extends EventEmitter {
|
||||
* @returns Key-value object of settings.
|
||||
*/
|
||||
async syncFetchSettings(keys: string[]) {
|
||||
return await this.req('POST', '/sync/settings/fetch', { keys });
|
||||
return await this.req("POST", "/sync/settings/fetch", { keys });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,15 +381,23 @@ export class Client extends EventEmitter {
|
||||
* @param data Data to set as an object. Any non-string values will be automatically serialised.
|
||||
* @param timestamp Timestamp to use for the current revision.
|
||||
*/
|
||||
async syncSetSettings(data: { [key: string]: object | string }, timestamp?: number) {
|
||||
async syncSetSettings(
|
||||
data: { [key: string]: object | string },
|
||||
timestamp?: number,
|
||||
) {
|
||||
let requestData: { [key: string]: string } = {};
|
||||
for (let key of Object.keys(data)) {
|
||||
let value = data[key];
|
||||
requestData[key] = typeof value === 'string' ? value : JSON.stringify(value);
|
||||
requestData[key] =
|
||||
typeof value === "string" ? value : JSON.stringify(value);
|
||||
}
|
||||
|
||||
let query = timestamp ? `?timestamp=${timestamp}` : '';
|
||||
await this.req('POST', `/sync/settings/set${query}` as '/sync/settings/set', requestData);
|
||||
let query = timestamp ? `?timestamp=${timestamp}` : "";
|
||||
await this.req(
|
||||
"POST",
|
||||
`/sync/settings/set${query}` as "/sync/settings/set",
|
||||
requestData,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,7 +405,7 @@ export class Client extends EventEmitter {
|
||||
* @returns Array of channel unreads.
|
||||
*/
|
||||
async syncFetchUnreads() {
|
||||
return await this.req('GET', '/sync/unreads');
|
||||
return await this.req("GET", "/sync/unreads");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,7 +417,7 @@ export class Client extends EventEmitter {
|
||||
*/
|
||||
async logout() {
|
||||
this.websocket.disconnect();
|
||||
await this.req('POST', '/auth/session/logout');
|
||||
await this.req("POST", "/auth/session/logout");
|
||||
this.reset();
|
||||
}
|
||||
|
||||
@@ -390,8 +442,8 @@ export class Client extends EventEmitter {
|
||||
* @param data Registration data object
|
||||
* @returns A promise containing a registration response object
|
||||
*/
|
||||
register(data: Route<'POST', '/auth/account/create'>["data"]) {
|
||||
return this.request('POST', '/auth/account/create', { data });
|
||||
register(data: Route<"POST", "/auth/account/create">["data"]) {
|
||||
return this.request("POST", "/auth/account/create", { data });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -401,23 +453,17 @@ export class Client extends EventEmitter {
|
||||
*/
|
||||
markdownToText(source: string) {
|
||||
return source
|
||||
.replace(
|
||||
RE_MENTIONS,
|
||||
(sub: string, ...args: any[]) => {
|
||||
.replace(RE_MENTIONS, (sub: string, ...args: any[]) => {
|
||||
const id = args[0],
|
||||
user = this.users.get(id);
|
||||
|
||||
|
||||
if (user) {
|
||||
return `@${user.username}`;
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
)
|
||||
.replace(
|
||||
RE_SPOILER,
|
||||
'<spoiler>'
|
||||
);
|
||||
})
|
||||
.replace(RE_SPOILER, "<spoiler>");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,7 +473,9 @@ export class Client extends EventEmitter {
|
||||
*/
|
||||
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)}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,8 +487,11 @@ export class Client extends EventEmitter {
|
||||
* @param fallback Fallback URL
|
||||
* @returns Generated URL or nothing
|
||||
*/
|
||||
generateFileURL(attachment?: { tag: string, _id: string, content_type?: string }, ...args: FileArgs) {
|
||||
const [ options, allowAnimation, fallback ] = args;
|
||||
generateFileURL(
|
||||
attachment?: { tag: string; _id: string; content_type?: string },
|
||||
...args: FileArgs
|
||||
) {
|
||||
const [options, allowAnimation, fallback] = args;
|
||||
|
||||
let autumn = this.configuration?.features.autumn;
|
||||
if (!autumn?.enabled) return fallback;
|
||||
@@ -448,13 +499,17 @@ export class Client extends EventEmitter {
|
||||
|
||||
let { tag, _id, content_type } = attachment;
|
||||
|
||||
let query = '';
|
||||
let query = "";
|
||||
if (options) {
|
||||
if (!allowAnimation || content_type !== 'image/gif') {
|
||||
query = '?' + Object.keys(options).map(k => `${k}=${(options as any)[k]}`).join('&');
|
||||
if (!allowAnimation || content_type !== "image/gif") {
|
||||
query =
|
||||
"?" +
|
||||
Object.keys(options)
|
||||
.map((k) => `${k}=${(options as any)[k]}`)
|
||||
.join("&");
|
||||
}
|
||||
}
|
||||
|
||||
return `${autumn.url}/${tag}/${_id}${query}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -3,7 +3,7 @@ export const UserPermission = {
|
||||
ViewProfile: 1 << 1,
|
||||
SendMessage: 1 << 2,
|
||||
Invite: 1 << 3,
|
||||
}
|
||||
};
|
||||
|
||||
export const ChannelPermission = {
|
||||
View: 1 << 0,
|
||||
@@ -15,7 +15,7 @@ export const ChannelPermission = {
|
||||
EmbedLinks: 1 << 6,
|
||||
UploadFiles: 1 << 7,
|
||||
Masquerade: 1 << 8,
|
||||
}
|
||||
};
|
||||
|
||||
export const ServerPermission = {
|
||||
View: 1 << 0,
|
||||
@@ -28,16 +28,16 @@ export const ServerPermission = {
|
||||
ManageNicknames: 1 << 13,
|
||||
ChangeAvatar: 1 << 14,
|
||||
RemoveAvatars: 1 << 15,
|
||||
}
|
||||
};
|
||||
|
||||
export const U32_MAX = 2**32 - 1; // 4294967295
|
||||
export const U32_MAX = 2 ** 32 - 1; // 4294967295
|
||||
|
||||
export const DEFAULT_PERMISSION_DM =
|
||||
ChannelPermission.View
|
||||
+ ChannelPermission.SendMessage
|
||||
+ ChannelPermission.ManageChannel
|
||||
+ ChannelPermission.VoiceCall
|
||||
+ ChannelPermission.InviteOthers
|
||||
+ ChannelPermission.EmbedLinks
|
||||
+ ChannelPermission.UploadFiles
|
||||
+ ChannelPermission.Masquerade;
|
||||
ChannelPermission.View +
|
||||
ChannelPermission.SendMessage +
|
||||
ChannelPermission.ManageChannel +
|
||||
ChannelPermission.VoiceCall +
|
||||
ChannelPermission.InviteOthers +
|
||||
ChannelPermission.EmbedLinks +
|
||||
ChannelPermission.UploadFiles +
|
||||
ChannelPermission.Masquerade;
|
||||
|
||||
+707
-677
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -1,11 +1,11 @@
|
||||
export const LIBRARY_VERSION = '5.1.0-alpha.7';
|
||||
export const LIBRARY_VERSION = "5.1.0-alpha.7";
|
||||
|
||||
export const defaultConfig = {
|
||||
apiURL: 'https://api.revolt.chat',
|
||||
apiURL: "https://api.revolt.chat",
|
||||
autoReconnect: true,
|
||||
heartbeat: 30,
|
||||
debug: false,
|
||||
cache: false,
|
||||
|
||||
|
||||
ackRateLimiter: true,
|
||||
};
|
||||
|
||||
+7
-3
@@ -1,3 +1,7 @@
|
||||
export * from './Client';
|
||||
export * from './config';
|
||||
export { UserPermission, ChannelPermission, ServerPermission } from './api/permissions';
|
||||
export * from "./Client";
|
||||
export * from "./config";
|
||||
export {
|
||||
UserPermission,
|
||||
ChannelPermission,
|
||||
ServerPermission,
|
||||
} from "./api/permissions";
|
||||
|
||||
+36
-18
@@ -1,6 +1,8 @@
|
||||
import { runInAction } from 'mobx';
|
||||
import { Route } from '../api/routes';
|
||||
import { Client } from '../Client';
|
||||
import { runInAction } from "mobx";
|
||||
|
||||
import { Route } from "../api/routes";
|
||||
|
||||
import { Client } from "../Client";
|
||||
|
||||
export default class Bots {
|
||||
client: Client;
|
||||
@@ -15,10 +17,13 @@ export default class Bots {
|
||||
* @returns Bot and User object
|
||||
*/
|
||||
async fetch(id: string) {
|
||||
let { bot, user } = await this.client.req('GET', `/bots/${id}` as '/bots/id');
|
||||
let { bot, user } = await this.client.req(
|
||||
"GET",
|
||||
`/bots/${id}` as "/bots/id",
|
||||
);
|
||||
return {
|
||||
bot,
|
||||
user: await this.client.users.fetch(user._id, user)
|
||||
user: await this.client.users.fetch(user._id, user),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,7 +32,7 @@ export default class Bots {
|
||||
* @param id Bot ID
|
||||
*/
|
||||
async delete(id: string) {
|
||||
await this.client.req('DELETE', `/bots/${id}` as '/bots/id');
|
||||
await this.client.req("DELETE", `/bots/${id}` as "/bots/id");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +41,10 @@ export default class Bots {
|
||||
* @returns Public Bot object
|
||||
*/
|
||||
async fetchPublic(id: string) {
|
||||
return await this.client.req('GET', `/bots/${id}/invite` as '/bots/id/invite');
|
||||
return await this.client.req(
|
||||
"GET",
|
||||
`/bots/${id}/invite` as "/bots/id/invite",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,8 +52,15 @@ export default class Bots {
|
||||
* @param id Bot ID
|
||||
* @param destination The group or server to add to
|
||||
*/
|
||||
async invite(id: string, destination: Route<'POST', '/bots/id/invite'>["data"]) {
|
||||
return await this.client.req('POST', `/bots/${id}/invite` as '/bots/id/invite', destination);
|
||||
async invite(
|
||||
id: string,
|
||||
destination: Route<"POST", "/bots/id/invite">["data"],
|
||||
) {
|
||||
return await this.client.req(
|
||||
"POST",
|
||||
`/bots/${id}/invite` as "/bots/id/invite",
|
||||
destination,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,13 +69,16 @@ export default class Bots {
|
||||
* @returns Bot and User objects
|
||||
*/
|
||||
async fetchOwned() {
|
||||
const { bots, users: userObjects } = await this.client.req('GET', `/bots/@me`);
|
||||
const { bots, users: userObjects } = await this.client.req(
|
||||
"GET",
|
||||
`/bots/@me`,
|
||||
);
|
||||
|
||||
let users = [];
|
||||
for (const obj of userObjects) {
|
||||
users.push(await this.client.users.fetch(obj._id, obj));
|
||||
}
|
||||
|
||||
|
||||
return { bots, users };
|
||||
}
|
||||
|
||||
@@ -69,8 +87,8 @@ export default class Bots {
|
||||
* @param id Bot ID
|
||||
* @param data Bot edit data object
|
||||
*/
|
||||
async edit(id: string, data: Route<'PATCH', '/bots/id'>["data"]) {
|
||||
await this.client.req('PATCH', `/bots/${id}` as '/bots/id', data);
|
||||
async edit(id: string, data: Route<"PATCH", "/bots/id">["data"]) {
|
||||
await this.client.req("PATCH", `/bots/${id}` as "/bots/id", data);
|
||||
|
||||
if (data.name) {
|
||||
let user = this.client.users.get(id);
|
||||
@@ -86,19 +104,19 @@ export default class Bots {
|
||||
* Create a bot
|
||||
* @param data Bot creation data
|
||||
*/
|
||||
async create(data: Route<'POST', '/bots/create'>["data"]) {
|
||||
let bot = await this.client.req('POST', '/bots/create', data);
|
||||
async create(data: Route<"POST", "/bots/create">["data"]) {
|
||||
let bot = await this.client.req("POST", "/bots/create", data);
|
||||
let user = await this.client.users.fetch(bot._id, {
|
||||
_id: bot._id,
|
||||
username: data.name,
|
||||
bot: {
|
||||
owner: this.client.user!._id
|
||||
}
|
||||
owner: this.client.user!._id,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
bot,
|
||||
user
|
||||
user,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+196
-87
@@ -1,18 +1,25 @@
|
||||
import type { Channel as ChannelI, Message as MessageI, SystemMessage } from 'revolt-api/types/Channels';
|
||||
import type { RemoveChannelField, Route } from '../api/routes';
|
||||
import type { Attachment } from 'revolt-api/types/Autumn';
|
||||
import type { Member } from 'revolt-api/types/Servers';
|
||||
import type { User } from 'revolt-api/types/Users';
|
||||
import type {
|
||||
Channel as ChannelI,
|
||||
Message as MessageI,
|
||||
} from "revolt-api/types/Channels";
|
||||
import type { RemoveChannelField, Route } from "../api/routes";
|
||||
import type { Attachment } from "revolt-api/types/Autumn";
|
||||
import type { Member } from "revolt-api/types/Servers";
|
||||
import type { User } from "revolt-api/types/Users";
|
||||
|
||||
import { action, computed, makeAutoObservable, runInAction } from 'mobx';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { decodeTime, ulid } from 'ulid';
|
||||
import { action, computed, makeAutoObservable, runInAction } from "mobx";
|
||||
import isEqual from "lodash.isequal";
|
||||
import { decodeTime, ulid } from "ulid";
|
||||
|
||||
import { Nullable, toNullable } from '../util/null';
|
||||
import Collection from './Collection';
|
||||
import { Message } from './Messages';
|
||||
import { Client, FileArgs } from '..';
|
||||
import { DEFAULT_PERMISSION_DM, U32_MAX, UserPermission } from '../api/permissions';
|
||||
import { Nullable, toNullable } from "../util/null";
|
||||
import Collection from "./Collection";
|
||||
import { Message } from "./Messages";
|
||||
import { Client, FileArgs } from "..";
|
||||
import {
|
||||
DEFAULT_PERMISSION_DM,
|
||||
U32_MAX,
|
||||
UserPermission,
|
||||
} from "../api/permissions";
|
||||
|
||||
export class Channel {
|
||||
client: Client;
|
||||
@@ -90,7 +97,7 @@ export class Channel {
|
||||
* Users typing in channel.
|
||||
*/
|
||||
typing_ids: Set<string> = new Set();
|
||||
|
||||
|
||||
/**
|
||||
* Channel is not safe for work.
|
||||
* @requires `Group`, `TextChannel`, `VoiceChannel`
|
||||
@@ -120,7 +127,9 @@ export class Channel {
|
||||
* @requires `DM`
|
||||
*/
|
||||
get recipient() {
|
||||
const user_id = this.recipient_ids?.find(x => this.client.user!._id !== x);
|
||||
const user_id = this.recipient_ids?.find(
|
||||
(x) => this.client.user!._id !== x,
|
||||
);
|
||||
if (!user_id) return;
|
||||
|
||||
return this.client.users.get(user_id);
|
||||
@@ -133,7 +142,7 @@ export class Channel {
|
||||
get last_message() {
|
||||
const id = this.last_message_id;
|
||||
if (!id) return;
|
||||
|
||||
|
||||
return this.client.messages.get(id);
|
||||
}
|
||||
|
||||
@@ -142,14 +151,16 @@ export class Channel {
|
||||
* @requires `Group`
|
||||
*/
|
||||
get recipients() {
|
||||
return this.recipient_ids?.map(id => this.client.users.get(id));
|
||||
return this.recipient_ids?.map((id) => this.client.users.get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Users typing.
|
||||
*/
|
||||
get typing() {
|
||||
return Array.from(this.typing_ids).map(id => this.client.users.get(id));
|
||||
return Array.from(this.typing_ids).map((id) =>
|
||||
this.client.users.get(id),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,14 +218,15 @@ export class Channel {
|
||||
});
|
||||
}
|
||||
|
||||
@action update(
|
||||
data: Partial<ChannelI>,
|
||||
clear?: RemoveChannelField,
|
||||
) {
|
||||
@action update(data: Partial<ChannelI>, clear?: RemoveChannelField) {
|
||||
const apply = (key: string, target?: string) => {
|
||||
// This code has been tested.
|
||||
// @ts-expect-error
|
||||
if (typeof data[key] !== 'undefined' && !isEqual(this[target ?? key], data[key])) {
|
||||
if (
|
||||
// @ts-expect-error
|
||||
typeof data[key] !== "undefined" &&
|
||||
// @ts-expect-error
|
||||
!isEqual(this[target ?? key], data[key])
|
||||
) {
|
||||
// @ts-expect-error
|
||||
this[target ?? key] = data[key];
|
||||
}
|
||||
@@ -266,7 +278,10 @@ export class Channel {
|
||||
* @returns An array of the channel's members.
|
||||
*/
|
||||
async fetchMembers() {
|
||||
let members = await this.client.req('GET', `/channels/${this._id}/members` as '/channels/id/members');
|
||||
let members = await this.client.req(
|
||||
"GET",
|
||||
`/channels/${this._id}/members` as "/channels/id/members",
|
||||
);
|
||||
return members.map(this.client.users.createObj);
|
||||
}
|
||||
|
||||
@@ -274,8 +289,12 @@ export class Channel {
|
||||
* Edit a channel
|
||||
* @param data Channel editing route data
|
||||
*/
|
||||
async edit(data: Route<'PATCH', '/channels/id'>["data"]) {
|
||||
return await this.client.req('PATCH', `/channels/${this._id}` as '/channels/id', data);
|
||||
async edit(data: Route<"PATCH", "/channels/id">["data"]) {
|
||||
return await this.client.req(
|
||||
"PATCH",
|
||||
`/channels/${this._id}` as "/channels/id",
|
||||
data,
|
||||
);
|
||||
// ! FIXME: return $set in req
|
||||
}
|
||||
|
||||
@@ -285,18 +304,26 @@ export class Channel {
|
||||
*/
|
||||
async delete(avoidReq?: boolean) {
|
||||
if (!avoidReq)
|
||||
await this.client.req('DELETE', `/channels/${this._id}` as '/channels/id');
|
||||
await this.client.req(
|
||||
"DELETE",
|
||||
`/channels/${this._id}` as "/channels/id",
|
||||
);
|
||||
|
||||
runInAction(() => {
|
||||
if (this.channel_type === 'DirectMessage') {
|
||||
if (this.channel_type === "DirectMessage") {
|
||||
this.active = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.channel_type === 'TextChannel' || this.channel_type === 'VoiceChannel') {
|
||||
if (
|
||||
this.channel_type === "TextChannel" ||
|
||||
this.channel_type === "VoiceChannel"
|
||||
) {
|
||||
let server = this.server;
|
||||
if (server) {
|
||||
server.channel_ids = server.channel_ids.filter(x => x !== this._id);
|
||||
server.channel_ids = server.channel_ids.filter(
|
||||
(x) => x !== this._id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +336,10 @@ export class Channel {
|
||||
* @param user_id ID of the target user
|
||||
*/
|
||||
async addMember(user_id: string) {
|
||||
return await this.client.req('PUT', `/channels/${this._id}/recipients/${user_id}` as '/channels/id/recipients/id');
|
||||
return await this.client.req(
|
||||
"PUT",
|
||||
`/channels/${this._id}/recipients/${user_id}` as "/channels/id/recipients/id",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +347,10 @@ export class Channel {
|
||||
* @param user_id ID of the target user
|
||||
*/
|
||||
async removeMember(user_id: string) {
|
||||
return await this.client.req('DELETE', `/channels/${this._id}/recipients/${user_id}` as '/channels/id/recipients/id');
|
||||
return await this.client.req(
|
||||
"DELETE",
|
||||
`/channels/${this._id}/recipients/${user_id}` as "/channels/id/recipients/id",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,13 +358,23 @@ export class Channel {
|
||||
* @param data Either the message as a string or message sending route data
|
||||
* @returns The message
|
||||
*/
|
||||
async sendMessage(data: string | (Omit<Route<'POST', '/channels/id/messages'>["data"], 'nonce'> & { nonce?: string })) {
|
||||
let msg: Route<'POST', '/channels/id/messages'>["data"] = {
|
||||
async sendMessage(
|
||||
data:
|
||||
| string
|
||||
| (Omit<Route<"POST", "/channels/id/messages">["data"], "nonce"> & {
|
||||
nonce?: string;
|
||||
}),
|
||||
) {
|
||||
let msg: Route<"POST", "/channels/id/messages">["data"] = {
|
||||
nonce: ulid(),
|
||||
...(typeof data === 'string' ? { content: data } : data)
|
||||
...(typeof data === "string" ? { content: data } : data),
|
||||
};
|
||||
|
||||
let message = await this.client.req('POST', `/channels/${this._id}/messages` as '/channels/id/messages', msg);
|
||||
let message = await this.client.req(
|
||||
"POST",
|
||||
`/channels/${this._id}/messages` as "/channels/id/messages",
|
||||
msg,
|
||||
);
|
||||
return this.client.messages.createObj(message, true);
|
||||
}
|
||||
|
||||
@@ -341,7 +384,10 @@ export class Channel {
|
||||
* @returns The message
|
||||
*/
|
||||
async fetchMessage(message_id: string) {
|
||||
let message = await this.client.req('GET', `/channels/${this._id}/messages/${message_id}` as '/channels/id/messages/id');
|
||||
let message = await this.client.req(
|
||||
"GET",
|
||||
`/channels/${this._id}/messages/${message_id}` as "/channels/id/messages/id",
|
||||
);
|
||||
return this.client.messages.createObj(message);
|
||||
}
|
||||
|
||||
@@ -350,8 +396,17 @@ export class Channel {
|
||||
* @param params Message fetching route data
|
||||
* @returns The messages
|
||||
*/
|
||||
async fetchMessages(params?: Omit<Route<'GET', '/channels/id/messages'>["data"], 'include_users'>) {
|
||||
let messages = await this.client.request('GET', `/channels/${this._id}/messages` as '/channels/id/messages', { params }) as MessageI[];
|
||||
async fetchMessages(
|
||||
params?: Omit<
|
||||
Route<"GET", "/channels/id/messages">["data"],
|
||||
"include_users"
|
||||
>,
|
||||
) {
|
||||
let messages = (await this.client.request(
|
||||
"GET",
|
||||
`/channels/${this._id}/messages` as "/channels/id/messages",
|
||||
{ params },
|
||||
)) as MessageI[];
|
||||
return runInAction(() => messages.map(this.client.messages.createObj));
|
||||
}
|
||||
|
||||
@@ -360,15 +415,24 @@ export class Channel {
|
||||
* @param params Message fetching route data
|
||||
* @returns Object including messages and users
|
||||
*/
|
||||
async fetchMessagesWithUsers(params?: Omit<Route<'GET', '/channels/id/messages'>["data"], 'include_users'>) {
|
||||
let data = await this.client.request('GET', `/channels/${this._id}/messages` as '/channels/id/messages', { params: { ...params, include_users: true } }) as { messages: MessageI[], users: User[], members?: Member[] };
|
||||
async fetchMessagesWithUsers(
|
||||
params?: Omit<
|
||||
Route<"GET", "/channels/id/messages">["data"],
|
||||
"include_users"
|
||||
>,
|
||||
) {
|
||||
let data = (await this.client.request(
|
||||
"GET",
|
||||
`/channels/${this._id}/messages` as "/channels/id/messages",
|
||||
{ params: { ...params, include_users: true } },
|
||||
)) as { messages: MessageI[]; users: User[]; members?: Member[] };
|
||||
return runInAction(() => {
|
||||
return {
|
||||
messages: data.messages.map(this.client.messages.createObj),
|
||||
users: data.users.map(this.client.users.createObj),
|
||||
members: data.members?.map(this.client.members.createObj)
|
||||
}
|
||||
})
|
||||
members: data.members?.map(this.client.members.createObj),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,8 +440,17 @@ export class Channel {
|
||||
* @param params Message searching route data
|
||||
* @returns The messages
|
||||
*/
|
||||
async search(params: Omit<Route<'POST', '/channels/id/search'>["data"], 'include_users'>) {
|
||||
let messages = await this.client.req('POST', `/channels/${this._id}/search` as '/channels/id/search', params) as MessageI[];
|
||||
async search(
|
||||
params: Omit<
|
||||
Route<"POST", "/channels/id/search">["data"],
|
||||
"include_users"
|
||||
>,
|
||||
) {
|
||||
let messages = (await this.client.req(
|
||||
"POST",
|
||||
`/channels/${this._id}/search` as "/channels/id/search",
|
||||
params,
|
||||
)) as MessageI[];
|
||||
return runInAction(() => messages.map(this.client.messages.createObj));
|
||||
}
|
||||
|
||||
@@ -386,15 +459,24 @@ export class Channel {
|
||||
* @param params Message searching route data
|
||||
* @returns The messages
|
||||
*/
|
||||
async searchWithUsers(params: Omit<Route<'POST', '/channels/id/search'>["data"], 'include_users'>) {
|
||||
let data = await this.client.req('POST', `/channels/${this._id}/search` as '/channels/id/search', { ...params, include_users: true }) as { messages: MessageI[], users: User[], members?: Member[] };
|
||||
async searchWithUsers(
|
||||
params: Omit<
|
||||
Route<"POST", "/channels/id/search">["data"],
|
||||
"include_users"
|
||||
>,
|
||||
) {
|
||||
let data = (await this.client.req(
|
||||
"POST",
|
||||
`/channels/${this._id}/search` as "/channels/id/search",
|
||||
{ ...params, include_users: true },
|
||||
)) as { messages: MessageI[]; users: User[]; members?: Member[] };
|
||||
return runInAction(() => {
|
||||
return {
|
||||
messages: data.messages.map(this.client.messages.createObj),
|
||||
users: data.users.map(this.client.users.createObj),
|
||||
members: data.members?.map(this.client.members.createObj)
|
||||
}
|
||||
})
|
||||
members: data.members?.map(this.client.members.createObj),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,13 +485,19 @@ export class Channel {
|
||||
* @returns The stale messages
|
||||
*/
|
||||
async fetchStale(ids: string[]) {
|
||||
let data = await this.client.req('POST', `/channels/${this._id}/messages/stale` as '/channels/id/messages/stale', { ids });
|
||||
let data = await this.client.req(
|
||||
"POST",
|
||||
`/channels/${this._id}/messages/stale` as "/channels/id/messages/stale",
|
||||
{ ids },
|
||||
);
|
||||
|
||||
runInAction(() => {
|
||||
data.deleted.forEach(id => this.client.messages.delete(id));
|
||||
data.updated.forEach(data => this.client.messages.get(data._id)?.update(data));
|
||||
data.deleted.forEach((id) => this.client.messages.delete(id));
|
||||
data.updated.forEach((data) =>
|
||||
this.client.messages.get(data._id)?.update(data),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -418,7 +506,10 @@ export class Channel {
|
||||
* @returns Newly created invite code
|
||||
*/
|
||||
async createInvite() {
|
||||
let res = await this.client.req('POST', `/channels/${this._id}/invites` as '/channels/id/invites');
|
||||
let res = await this.client.req(
|
||||
"POST",
|
||||
`/channels/${this._id}/invites` as "/channels/id/invites",
|
||||
);
|
||||
return res.code;
|
||||
}
|
||||
|
||||
@@ -427,7 +518,10 @@ export class Channel {
|
||||
* @returns Join call response data
|
||||
*/
|
||||
async joinCall() {
|
||||
return await this.client.req('POST', `/channels/${this._id}/join_call` as '/channels/id/join_call');
|
||||
return await this.client.req(
|
||||
"POST",
|
||||
`/channels/${this._id}/join_call` as "/channels/id/join_call",
|
||||
);
|
||||
}
|
||||
|
||||
private ackTimeout?: number;
|
||||
@@ -439,24 +533,31 @@ export class Channel {
|
||||
* @param skipRateLimiter Whether to skip the internal rate limiter
|
||||
*/
|
||||
async ack(message?: Message | string, skipRateLimiter?: boolean) {
|
||||
const id = (typeof message === 'string' ? message : message?._id) ?? this.last_message_id ?? ulid();
|
||||
const id =
|
||||
(typeof message === "string" ? message : message?._id) ??
|
||||
this.last_message_id ??
|
||||
ulid();
|
||||
const performAck = () => {
|
||||
delete this.ackLimit;
|
||||
this.client.req('PUT', `/channels/${this._id}/ack/${id}` as '/channels/id/ack/id');
|
||||
}
|
||||
this.client.req(
|
||||
"PUT",
|
||||
`/channels/${this._id}/ack/${id}` as "/channels/id/ack/id",
|
||||
);
|
||||
};
|
||||
|
||||
if (!this.client.options.ackRateLimiter || skipRateLimiter)
|
||||
return performAck();
|
||||
|
||||
if (!this.client.options.ackRateLimiter || skipRateLimiter) return performAck();
|
||||
|
||||
clearTimeout(this.ackTimeout);
|
||||
if (this.ackLimit && + new Date() > this.ackLimit) {
|
||||
if (this.ackLimit && +new Date() > this.ackLimit) {
|
||||
performAck();
|
||||
}
|
||||
|
||||
|
||||
// We need to use setTimeout here for both Node.js and browser.
|
||||
this.ackTimeout = setTimeout(performAck, 5000) as unknown as number;
|
||||
|
||||
|
||||
if (!this.ackLimit) {
|
||||
this.ackLimit = + new Date() + 15e3;
|
||||
this.ackLimit = +new Date() + 15e3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,22 +566,26 @@ export class Channel {
|
||||
* @param role_id Role Id, set to 'default' to affect all users
|
||||
* @param permissions Permission number, removes permission if unset
|
||||
*/
|
||||
async setPermissions(role_id: string = 'default', permissions?: number) {
|
||||
return await this.client.req('PUT', `/channels/${this._id}/permissions/${role_id}` as '/channels/id/permissions/id', { permissions });
|
||||
async setPermissions(role_id: string = "default", permissions?: number) {
|
||||
return await this.client.req(
|
||||
"PUT",
|
||||
`/channels/${this._id}/permissions/${role_id}` as "/channels/id/permissions/id",
|
||||
{ permissions },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start typing in this channel
|
||||
*/
|
||||
startTyping() {
|
||||
this.client.websocket.send({ type: 'BeginTyping', channel: this._id });
|
||||
this.client.websocket.send({ type: "BeginTyping", channel: this._id });
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop typing in this channel
|
||||
*/
|
||||
stopTyping() {
|
||||
this.client.websocket.send({ type: 'EndTyping', channel: this._id });
|
||||
this.client.websocket.send({ type: "EndTyping", channel: this._id });
|
||||
}
|
||||
|
||||
generateIconURL(...args: FileArgs) {
|
||||
@@ -489,8 +594,9 @@ export class Channel {
|
||||
|
||||
@computed get permission() {
|
||||
switch (this.channel_type) {
|
||||
case 'SavedMessages': return U32_MAX;
|
||||
case 'DirectMessage': {
|
||||
case "SavedMessages":
|
||||
return U32_MAX;
|
||||
case "DirectMessage": {
|
||||
let user_permissions = this.recipient?.permission || 0;
|
||||
|
||||
if (user_permissions & UserPermission.SendMessage) {
|
||||
@@ -499,37 +605,38 @@ export class Channel {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case 'Group': {
|
||||
case "Group": {
|
||||
if (this.owner_id === this.client.user!._id) {
|
||||
return DEFAULT_PERMISSION_DM;
|
||||
} else {
|
||||
return this.permissions ?? DEFAULT_PERMISSION_DM;
|
||||
}
|
||||
}
|
||||
case 'TextChannel':
|
||||
case 'VoiceChannel': {
|
||||
case "TextChannel":
|
||||
case "VoiceChannel": {
|
||||
let server = this.server;
|
||||
if (typeof server === 'undefined') return 0;
|
||||
if (typeof server === "undefined") return 0;
|
||||
|
||||
if (server.owner === this.client.user?._id) {
|
||||
return U32_MAX;
|
||||
} else {
|
||||
let member = this.client.members.getKey({
|
||||
user: this.client.user!._id,
|
||||
server: server._id
|
||||
server: server._id,
|
||||
}) ?? { roles: null };
|
||||
|
||||
if (!member) return 0;
|
||||
|
||||
let perm = (
|
||||
this.default_permissions ??
|
||||
server.default_permissions[1]
|
||||
) >>> 0;
|
||||
let perm =
|
||||
(this.default_permissions ??
|
||||
server.default_permissions[1]) >>> 0;
|
||||
|
||||
if (member.roles) {
|
||||
for (let role of member.roles) {
|
||||
perm |= (this.role_permissions?.[role] ?? 0) >>> 0;
|
||||
perm |= (server.roles?.[role].permissions[1] ?? 0) >>> 0;
|
||||
perm |=
|
||||
(server.roles?.[role].permissions[1] ?? 0) >>>
|
||||
0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,7 +666,9 @@ export default class Channels extends Collection<string, Channel> {
|
||||
*/
|
||||
async fetch(id: string, data?: ChannelI) {
|
||||
if (this.has(id)) return this.$get(id);
|
||||
let res = data ?? await this.client.req('GET', `/channels/${id}` as '/channels/id');
|
||||
let res =
|
||||
data ??
|
||||
(await this.client.req("GET", `/channels/${id}` as "/channels/id"));
|
||||
return this.createObj(res);
|
||||
}
|
||||
|
||||
@@ -578,7 +687,7 @@ export default class Channels extends Collection<string, Channel> {
|
||||
this.set(data._id, channel);
|
||||
});
|
||||
|
||||
if (emit === true) this.client.emit('channel/create', channel);
|
||||
if (emit === true) this.client.emit("channel/create", channel);
|
||||
return channel;
|
||||
}
|
||||
|
||||
@@ -587,8 +696,8 @@ export default class Channels extends Collection<string, Channel> {
|
||||
* @param data Group create route data
|
||||
* @returns The newly-created group
|
||||
*/
|
||||
async createGroup(data: Route<'POST', '/channels/create'>["data"]) {
|
||||
let group = await this.client.req('POST', `/channels/create`, data);
|
||||
async createGroup(data: Route<"POST", "/channels/create">["data"]) {
|
||||
let group = await this.client.req("POST", `/channels/create`, data);
|
||||
return (await this.fetch(group._id, group))!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Client } from '../Client';
|
||||
import { ObservableMap } from 'mobx';
|
||||
import { ObservableMap } from "mobx";
|
||||
|
||||
import { Client } from "../Client";
|
||||
|
||||
export default class Collection<K, V> extends ObservableMap<K, V> {
|
||||
client: Client;
|
||||
|
||||
+29
-15
@@ -1,13 +1,16 @@
|
||||
import type { Member as MemberI, MemberCompositeKey } from 'revolt-api/types/Servers';
|
||||
import type { RemoveMemberField, Route } from '../api/routes';
|
||||
import type { Attachment } from 'revolt-api/types/Autumn';
|
||||
import type {
|
||||
Member as MemberI,
|
||||
MemberCompositeKey,
|
||||
} from "revolt-api/types/Servers";
|
||||
import type { RemoveMemberField, Route } from "../api/routes";
|
||||
import type { Attachment } from "revolt-api/types/Autumn";
|
||||
|
||||
import { makeAutoObservable, runInAction, action, computed } from 'mobx';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { makeAutoObservable, runInAction, action, computed } from "mobx";
|
||||
import isEqual from "lodash.isequal";
|
||||
|
||||
import { Nullable, toNullable } from '../util/null';
|
||||
import Collection from './Collection';
|
||||
import { Client, FileArgs } from '..';
|
||||
import { Nullable, toNullable } from "../util/null";
|
||||
import Collection from "./Collection";
|
||||
import { Client, FileArgs } from "..";
|
||||
|
||||
export class Member {
|
||||
client: Client;
|
||||
@@ -49,8 +52,12 @@ export class Member {
|
||||
@action update(data: Partial<MemberI>, clear?: RemoveMemberField) {
|
||||
const apply = (key: string) => {
|
||||
// This code has been tested.
|
||||
// @ts-expect-error
|
||||
if (typeof data[key] !== 'undefined' && !isEqual(this[key], data[key])) {
|
||||
if (
|
||||
// @ts-expect-error
|
||||
typeof data[key] !== "undefined" &&
|
||||
// @ts-expect-error
|
||||
!isEqual(this[key], data[key])
|
||||
) {
|
||||
// @ts-expect-error
|
||||
this[key] = data[key];
|
||||
}
|
||||
@@ -75,8 +82,12 @@ export class Member {
|
||||
* @param data Member editing route data
|
||||
* @returns Server member object
|
||||
*/
|
||||
async edit(data: Route<'PATCH', '/servers/id/members/id'>["data"]) {
|
||||
return await this.client.req('PATCH', `/servers/${this._id.server}/members/${this._id.user}` as '/servers/id/members/id', data);
|
||||
async edit(data: Route<"PATCH", "/servers/id/members/id">["data"]) {
|
||||
return await this.client.req(
|
||||
"PATCH",
|
||||
`/servers/${this._id.server}/members/${this._id.user}` as "/servers/id/members/id",
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +95,10 @@ export class Member {
|
||||
* @param user_id User ID
|
||||
*/
|
||||
async kick() {
|
||||
return await this.client.req('DELETE', `/servers/${this._id.server}/members/${this._id.user}` as '/servers/id/members/id');
|
||||
return await this.client.req(
|
||||
"DELETE",
|
||||
`/servers/${this._id.server}/members/${this._id.user}` as "/servers/id/members/id",
|
||||
);
|
||||
}
|
||||
|
||||
@computed generateAvatarURL(...args: FileArgs) {
|
||||
@@ -99,7 +113,7 @@ export default class Members extends Collection<string, Member> {
|
||||
}
|
||||
|
||||
static toKey(id: MemberCompositeKey) {
|
||||
return JSON.stringify(id, Object.keys(id).sort())
|
||||
return JSON.stringify(id, Object.keys(id).sort());
|
||||
}
|
||||
|
||||
hasKey(id: MemberCompositeKey) {
|
||||
@@ -140,7 +154,7 @@ export default class Members extends Collection<string, Member> {
|
||||
this.setKey(data._id, member);
|
||||
});
|
||||
|
||||
if (emit === true) this.client.emit('member/join', member);
|
||||
if (emit === true) this.client.emit("member/join", member);
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
+77
-34
@@ -1,15 +1,19 @@
|
||||
import type { Masquerade, Message as MessageI, SystemMessage } from 'revolt-api/types/Channels';
|
||||
import type { Attachment } from 'revolt-api/types/Autumn';
|
||||
import type { Embed } from 'revolt-api/types/January';
|
||||
import type { Route } from '../api/routes';
|
||||
import type {
|
||||
Masquerade,
|
||||
Message as MessageI,
|
||||
SystemMessage,
|
||||
} from "revolt-api/types/Channels";
|
||||
import type { Attachment } from "revolt-api/types/Autumn";
|
||||
import type { Embed } from "revolt-api/types/January";
|
||||
import type { Route } from "../api/routes";
|
||||
|
||||
import { makeAutoObservable, runInAction, action, computed } from 'mobx';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { makeAutoObservable, runInAction, action, computed } from "mobx";
|
||||
import isEqual from "lodash.isequal";
|
||||
|
||||
import { Nullable, toNullable, toNullableDate } from '../util/null';
|
||||
import Collection from './Collection';
|
||||
import { Nullable, toNullable, toNullableDate } from "../util/null";
|
||||
import Collection from "./Collection";
|
||||
import { Client } from "..";
|
||||
import { decodeTime } from 'ulid';
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
export class Message {
|
||||
client: Client;
|
||||
@@ -37,16 +41,16 @@ export class Message {
|
||||
|
||||
get member() {
|
||||
const channel = this.channel;
|
||||
if (channel?.channel_type === 'TextChannel') {
|
||||
if (channel?.channel_type === "TextChannel") {
|
||||
return this.client.members.getKey({
|
||||
server: channel.server_id!,
|
||||
user: this.author_id
|
||||
user: this.author_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get mentions() {
|
||||
return this.mention_ids?.map(id => this.client.users.get(id));
|
||||
return this.mention_ids?.map((id) => this.client.users.get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,21 +68,31 @@ export class Message {
|
||||
@computed
|
||||
get asSystemMessage() {
|
||||
const content = this.content;
|
||||
if (typeof content === 'string') return { type: 'text', content };
|
||||
if (typeof content === "string") return { type: "text", content };
|
||||
|
||||
const { type } = content;
|
||||
const get = (id: string) => this.client.users.get(id);
|
||||
switch (content.type) {
|
||||
case 'text': return content;
|
||||
case 'user_added': return { type, user: get(content.id), by: get(content.by) };
|
||||
case 'user_remove': return { type, user: get(content.id), by: get(content.by) };
|
||||
case 'user_joined': return { type, user: get(content.id) };
|
||||
case 'user_left': return { type, user: get(content.id) };
|
||||
case 'user_kicked': return { type, user: get(content.id) };
|
||||
case 'user_banned': return { type, user: get(content.id) };
|
||||
case 'channel_renamed': return { type, name: content.name, by: get(content.by) };
|
||||
case 'channel_description_changed': return { type, by: get(content.by) };
|
||||
case 'channel_icon_changed': return { type, by: get(content.by) };
|
||||
case "text":
|
||||
return content;
|
||||
case "user_added":
|
||||
return { type, user: get(content.id), by: get(content.by) };
|
||||
case "user_remove":
|
||||
return { type, user: get(content.id), by: get(content.by) };
|
||||
case "user_joined":
|
||||
return { type, user: get(content.id) };
|
||||
case "user_left":
|
||||
return { type, user: get(content.id) };
|
||||
case "user_kicked":
|
||||
return { type, user: get(content.id) };
|
||||
case "user_banned":
|
||||
return { type, user: get(content.id) };
|
||||
case "channel_renamed":
|
||||
return { type, name: content.name, by: get(content.by) };
|
||||
case "channel_description_changed":
|
||||
return { type, by: get(content.by) };
|
||||
case "channel_icon_changed":
|
||||
return { type, by: get(content.by) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,12 +118,24 @@ export class Message {
|
||||
}
|
||||
|
||||
@action update(data: Partial<MessageI>) {
|
||||
const apply = (key: string, target?: string, transform?: (obj: unknown) => unknown) => {
|
||||
const apply = (
|
||||
key: string,
|
||||
target?: string,
|
||||
transform?: (obj: unknown) => unknown,
|
||||
) => {
|
||||
// This code has been tested.
|
||||
// @ts-expect-error
|
||||
if (typeof data[key] !== 'undefined' && !isEqual(this[target ?? key], data[key])) {
|
||||
if (
|
||||
// @ts-expect-error
|
||||
this[target ?? key] = transform ? transform(data[key]) : data[key];
|
||||
typeof data[key] !== "undefined" &&
|
||||
// @ts-expect-error
|
||||
!isEqual(this[target ?? key], data[key])
|
||||
) {
|
||||
// @ts-expect-error
|
||||
this[target ?? key] = transform
|
||||
? // @ts-expect-error
|
||||
transform(data[key])
|
||||
: // @ts-expect-error
|
||||
data[key];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,15 +150,22 @@ export class Message {
|
||||
* Edit a message
|
||||
* @param data Message edit route data
|
||||
*/
|
||||
async edit(data: Route<'PATCH', '/channels/id/messages/id'>["data"]) {
|
||||
return await this.client.req('PATCH', `/channels/${this.channel_id}/messages/${this._id}` as '/channels/id/messages/id', data);
|
||||
async edit(data: Route<"PATCH", "/channels/id/messages/id">["data"]) {
|
||||
return await this.client.req(
|
||||
"PATCH",
|
||||
`/channels/${this.channel_id}/messages/${this._id}` as "/channels/id/messages/id",
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a message
|
||||
*/
|
||||
async delete() {
|
||||
return await this.client.req('DELETE', `/channels/${this.channel_id}/messages/${this._id}` as '/channels/id/messages/id');
|
||||
return await this.client.req(
|
||||
"DELETE",
|
||||
`/channels/${this.channel_id}/messages/${this._id}` as "/channels/id/messages/id",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,9 +178,19 @@ export class Message {
|
||||
/**
|
||||
* Reply to Message
|
||||
*/
|
||||
reply(data: string | (Omit<Route<'POST', '/channels/id/messages'>["data"], 'nonce'> & { nonce?: string }), mention = true) {
|
||||
let obj = typeof data === 'string' ? { content: data } : data;
|
||||
return this.channel?.sendMessage({ ...obj, replies: [{ id: this._id, mention }] })
|
||||
reply(
|
||||
data:
|
||||
| string
|
||||
| (Omit<Route<"POST", "/channels/id/messages">["data"], "nonce"> & {
|
||||
nonce?: string;
|
||||
}),
|
||||
mention = true,
|
||||
) {
|
||||
let obj = typeof data === "string" ? { content: data } : data;
|
||||
return this.channel?.sendMessage({
|
||||
...obj,
|
||||
replies: [{ id: this._id, mention }],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +221,7 @@ export default class Messages extends Collection<string, Message> {
|
||||
this.set(data._id, message);
|
||||
});
|
||||
|
||||
if (emit === true) this.client.emit('message', message);
|
||||
if (emit === true) this.client.emit("message", message);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
+115
-43
@@ -1,16 +1,22 @@
|
||||
import type { Category, PermissionTuple, Role, Server as ServerI, SystemMessageChannels } from 'revolt-api/types/Servers';
|
||||
import type { RemoveServerField, Route } from '../api/routes';
|
||||
import type { Attachment } from 'revolt-api/types/Autumn';
|
||||
import type {
|
||||
Category,
|
||||
PermissionTuple,
|
||||
Role,
|
||||
Server as ServerI,
|
||||
SystemMessageChannels,
|
||||
} from "revolt-api/types/Servers";
|
||||
import type { RemoveServerField, Route } from "../api/routes";
|
||||
import type { Attachment } from "revolt-api/types/Autumn";
|
||||
|
||||
import { makeAutoObservable, action, runInAction, computed } from 'mobx';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { makeAutoObservable, action, runInAction, computed } from "mobx";
|
||||
import isEqual from "lodash.isequal";
|
||||
|
||||
import { Nullable, toNullable } from '../util/null';
|
||||
import { U32_MAX } from '../api/permissions';
|
||||
import Collection from './Collection';
|
||||
import { User } from './Users';
|
||||
import { Client, FileArgs } from '..';
|
||||
import { decodeTime } from 'ulid';
|
||||
import { Nullable, toNullable } from "../util/null";
|
||||
import { U32_MAX } from "../api/permissions";
|
||||
import Collection from "./Collection";
|
||||
import { User } from "./Users";
|
||||
import { Client, FileArgs } from "..";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
export class Server {
|
||||
client: Client;
|
||||
@@ -34,7 +40,7 @@ export class Server {
|
||||
flags: Nullable<number> = null;
|
||||
|
||||
get channels() {
|
||||
return this.channel_ids.map(x => this.client.channels.get(x));
|
||||
return this.channel_ids.map((x) => this.client.channels.get(x));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +52,7 @@ export class Server {
|
||||
|
||||
constructor(client: Client, data: ServerI) {
|
||||
this.client = client;
|
||||
|
||||
|
||||
this._id = data._id;
|
||||
this.owner = data.owner;
|
||||
this.name = data.name;
|
||||
@@ -74,8 +80,12 @@ export class Server {
|
||||
@action update(data: Partial<ServerI>, clear?: RemoveServerField) {
|
||||
const apply = (key: string, target?: string) => {
|
||||
// This code has been tested.
|
||||
// @ts-expect-error
|
||||
if (typeof data[key] !== 'undefined' && !isEqual(this[target ?? key], data[key])) {
|
||||
if (
|
||||
// @ts-expect-error
|
||||
typeof data[key] !== "undefined" &&
|
||||
// @ts-expect-error
|
||||
!isEqual(this[target ?? key], data[key])
|
||||
) {
|
||||
// @ts-expect-error
|
||||
this[target ?? key] = data[key];
|
||||
}
|
||||
@@ -112,16 +122,24 @@ export class Server {
|
||||
* @param data Channel create route data
|
||||
* @returns The newly-created channel
|
||||
*/
|
||||
async createChannel(data: Route<'POST', '/servers/id/channels'>["data"]) {
|
||||
return await this.client.req('POST', `/servers/${this._id}/channels` as '/servers/id/channels', data);
|
||||
async createChannel(data: Route<"POST", "/servers/id/channels">["data"]) {
|
||||
return await this.client.req(
|
||||
"POST",
|
||||
`/servers/${this._id}/channels` as "/servers/id/channels",
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a server
|
||||
* @param data Server editing route data
|
||||
*/
|
||||
async edit(data: Route<'PATCH', '/servers/id'>["data"]) {
|
||||
return await this.client.req('PATCH', `/servers/${this._id}` as '/servers/id', data);
|
||||
async edit(data: Route<"PATCH", "/servers/id">["data"]) {
|
||||
return await this.client.req(
|
||||
"PATCH",
|
||||
`/servers/${this._id}` as "/servers/id",
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +147,10 @@ export class Server {
|
||||
*/
|
||||
async delete(avoidReq?: boolean) {
|
||||
if (!avoidReq)
|
||||
await this.client.req('DELETE', `/servers/${this._id}` as '/servers/id');
|
||||
await this.client.req(
|
||||
"DELETE",
|
||||
`/servers/${this._id}` as "/servers/id",
|
||||
);
|
||||
|
||||
runInAction(() => {
|
||||
this.client.servers.delete(this._id);
|
||||
@@ -140,15 +161,25 @@ export class Server {
|
||||
* Mark a server as read
|
||||
*/
|
||||
async ack() {
|
||||
return await this.client.req('PUT', `/servers/${this._id}/ack` as '/servers/id/ack');
|
||||
return await this.client.req(
|
||||
"PUT",
|
||||
`/servers/${this._id}/ack` as "/servers/id/ack",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ban user
|
||||
* @param user_id User ID
|
||||
*/
|
||||
async banUser(user_id: string, data: Route<'PUT', '/servers/id/bans/id'>["data"]) {
|
||||
return await this.client.req('PUT', `/servers/${this._id}/bans/${user_id}` as '/servers/id/bans/id', data);
|
||||
async banUser(
|
||||
user_id: string,
|
||||
data: Route<"PUT", "/servers/id/bans/id">["data"],
|
||||
) {
|
||||
return await this.client.req(
|
||||
"PUT",
|
||||
`/servers/${this._id}/bans/${user_id}` as "/servers/id/bans/id",
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +187,10 @@ export class Server {
|
||||
* @param user_id User ID
|
||||
*/
|
||||
async unbanUser(user_id: string) {
|
||||
return await this.client.req('DELETE', `/servers/${this._id}/bans/${user_id}` as '/servers/id/bans/id');
|
||||
return await this.client.req(
|
||||
"DELETE",
|
||||
`/servers/${this._id}/bans/${user_id}` as "/servers/id/bans/id",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +198,10 @@ export class Server {
|
||||
* @returns An array of the server's invites
|
||||
*/
|
||||
async fetchInvites() {
|
||||
return await this.client.req('GET', `/servers/${this._id}/invites` as '/servers/id/invites');
|
||||
return await this.client.req(
|
||||
"GET",
|
||||
`/servers/${this._id}/invites` as "/servers/id/invites",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,7 +209,10 @@ export class Server {
|
||||
* @returns An array of the server's bans.
|
||||
*/
|
||||
async fetchBans() {
|
||||
return await this.client.req('GET', `/servers/${this._id}/bans` as '/servers/id/bans');
|
||||
return await this.client.req(
|
||||
"GET",
|
||||
`/servers/${this._id}/bans` as "/servers/id/bans",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,8 +220,15 @@ export class Server {
|
||||
* @param role_id Role Id, set to 'default' to affect all users
|
||||
* @param permissions Permission number, removes permission if unset
|
||||
*/
|
||||
async setPermissions(role_id: string = 'default', permissions?: { server: number, channel: number }) {
|
||||
return await this.client.req('PUT', `/servers/${this._id}/permissions/${role_id}` as '/servers/id/permissions/id', { permissions });
|
||||
async setPermissions(
|
||||
role_id: string = "default",
|
||||
permissions?: { server: number; channel: number },
|
||||
) {
|
||||
return await this.client.req(
|
||||
"PUT",
|
||||
`/servers/${this._id}/permissions/${role_id}` as "/servers/id/permissions/id",
|
||||
{ permissions },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +236,11 @@ export class Server {
|
||||
* @param name Role name
|
||||
*/
|
||||
async createRole(name: string) {
|
||||
return await this.client.req('POST', `/servers/${this._id}/roles` as '/servers/id/roles', { name });
|
||||
return await this.client.req(
|
||||
"POST",
|
||||
`/servers/${this._id}/roles` as "/servers/id/roles",
|
||||
{ name },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,8 +248,15 @@ export class Server {
|
||||
* @param role_id Role ID
|
||||
* @param data Role editing route data
|
||||
*/
|
||||
async editRole(role_id: string, data: Route<'PATCH', '/servers/id/roles/id'>["data"]) {
|
||||
return await this.client.req('PATCH', `/servers/${this._id}/roles/${role_id}` as '/servers/id/roles/id', data);
|
||||
async editRole(
|
||||
role_id: string,
|
||||
data: Route<"PATCH", "/servers/id/roles/id">["data"],
|
||||
) {
|
||||
return await this.client.req(
|
||||
"PATCH",
|
||||
`/servers/${this._id}/roles/${role_id}` as "/servers/id/roles/id",
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,7 +264,10 @@ export class Server {
|
||||
* @param role_id Role ID
|
||||
*/
|
||||
async deleteRole(role_id: string) {
|
||||
return await this.client.req('DELETE', `/servers/${this._id}/roles/${role_id}` as '/servers/id/roles/id');
|
||||
return await this.client.req(
|
||||
"DELETE",
|
||||
`/servers/${this._id}/roles/${role_id}` as "/servers/id/roles/id",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,11 +276,17 @@ export class Server {
|
||||
* @returns Server member object
|
||||
*/
|
||||
async fetchMember(user: User | string) {
|
||||
const user_id = typeof user === 'string' ? user : user._id;
|
||||
const existing = this.client.members.getKey({ server: this._id, user: user_id });
|
||||
const user_id = typeof user === "string" ? user : user._id;
|
||||
const existing = this.client.members.getKey({
|
||||
server: this._id,
|
||||
user: user_id,
|
||||
});
|
||||
if (existing) return existing;
|
||||
|
||||
const member = await this.client.req('GET', `/servers/${this._id}/members/${user_id}` as '/servers/id/members/id');
|
||||
const member = await this.client.req(
|
||||
"GET",
|
||||
`/servers/${this._id}/members/${user_id}` as "/servers/id/members/id",
|
||||
);
|
||||
return this.client.members.createObj(member);
|
||||
}
|
||||
|
||||
@@ -228,12 +295,15 @@ export class Server {
|
||||
* @returns An array of the server's members and their user objects.
|
||||
*/
|
||||
async fetchMembers() {
|
||||
let data = await this.client.req('GET', `/servers/${this._id}/members` as '/servers/id/members');
|
||||
let data = await this.client.req(
|
||||
"GET",
|
||||
`/servers/${this._id}/members` as "/servers/id/members",
|
||||
);
|
||||
return runInAction(() => {
|
||||
return {
|
||||
members: data.members.map(this.client.members.createObj),
|
||||
users: data.users.map(this.client.users.createObj)
|
||||
}
|
||||
users: data.users.map(this.client.users.createObj),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -251,7 +321,7 @@ export class Server {
|
||||
} else {
|
||||
let member = this.client.members.getKey({
|
||||
user: this.client.user!._id,
|
||||
server: this._id
|
||||
server: this._id,
|
||||
}) ?? { roles: null };
|
||||
|
||||
if (!member) return 0;
|
||||
@@ -287,7 +357,9 @@ export default class Servers extends Collection<string, Server> {
|
||||
*/
|
||||
async fetch(id: string, data?: ServerI) {
|
||||
if (this.has(id)) return this.$get(id, data);
|
||||
let res = data ?? await this.client.req('GET', `/servers/${id}` as '/servers/id');
|
||||
let res =
|
||||
data ??
|
||||
(await this.client.req("GET", `/servers/${id}` as "/servers/id"));
|
||||
|
||||
return runInAction(async () => {
|
||||
for (let channel of res.channels) {
|
||||
@@ -295,7 +367,7 @@ export default class Servers extends Collection<string, Server> {
|
||||
// ! FIXME: OR the WHOLE server
|
||||
try {
|
||||
await this.client.channels.fetch(channel);
|
||||
// future proofing for when not
|
||||
// future proofing for when not
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
@@ -325,8 +397,8 @@ export default class Servers extends Collection<string, Server> {
|
||||
* @param data Server create route data
|
||||
* @returns The newly-created server
|
||||
*/
|
||||
async createServer(data: Route<'POST', '/servers/create'>["data"]) {
|
||||
let server = await this.client.req('POST', `/servers/create`, data);
|
||||
async createServer(data: Route<"POST", "/servers/create">["data"]) {
|
||||
let server = await this.client.req("POST", `/servers/create`, data);
|
||||
return this.fetch(server._id, server);
|
||||
}
|
||||
}
|
||||
|
||||
+84
-39
@@ -1,16 +1,20 @@
|
||||
import type { BotInformation, Status, User as UserI } from 'revolt-api/types/Users';
|
||||
import type { RemoveUserField, Route } from '../api/routes';
|
||||
import type { Attachment } from 'revolt-api/types/Autumn';
|
||||
import type {
|
||||
BotInformation,
|
||||
Status,
|
||||
User as UserI,
|
||||
} from "revolt-api/types/Users";
|
||||
import type { RemoveUserField, Route } from "../api/routes";
|
||||
import type { Attachment } from "revolt-api/types/Autumn";
|
||||
|
||||
import { makeAutoObservable, action, runInAction, computed } from 'mobx';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { makeAutoObservable, action, runInAction, computed } from "mobx";
|
||||
import isEqual from "lodash.isequal";
|
||||
|
||||
import { U32_MAX, UserPermission } from '../api/permissions';
|
||||
import { toNullable, Nullable } from '../util/null';
|
||||
import Collection from './Collection';
|
||||
import { Client, FileArgs } from '..';
|
||||
import _ from 'lodash';
|
||||
import { decodeTime } from 'ulid';
|
||||
import { U32_MAX, UserPermission } from "../api/permissions";
|
||||
import { toNullable, Nullable } from "../util/null";
|
||||
import Collection from "./Collection";
|
||||
import { Client, FileArgs } from "..";
|
||||
import _ from "lodash";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
enum RelationshipStatus {
|
||||
None = "None",
|
||||
@@ -19,7 +23,7 @@ enum RelationshipStatus {
|
||||
Outgoing = "Outgoing",
|
||||
Incoming = "Incoming",
|
||||
Blocked = "Blocked",
|
||||
BlockedOther = "BlockedOther"
|
||||
BlockedOther = "BlockedOther",
|
||||
}
|
||||
|
||||
export class User {
|
||||
@@ -66,13 +70,17 @@ export class User {
|
||||
@action update(data: Partial<UserI>, clear?: RemoveUserField) {
|
||||
const apply = (key: string) => {
|
||||
// This code has been tested.
|
||||
// @ts-expect-error
|
||||
if (typeof data[key] !== 'undefined' && !isEqual(this[key], data[key])) {
|
||||
if (
|
||||
// @ts-expect-error
|
||||
typeof data[key] !== "undefined" &&
|
||||
// @ts-expect-error
|
||||
!isEqual(this[key], data[key])
|
||||
) {
|
||||
// @ts-expect-error
|
||||
this[key] = data[key];
|
||||
|
||||
if (key === 'relationship') {
|
||||
this.client.emit('user/relationship', this);
|
||||
if (key === "relationship") {
|
||||
this.client.emit("user/relationship", this);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -103,7 +111,10 @@ export class User {
|
||||
* @returns DM Channel
|
||||
*/
|
||||
async openDM() {
|
||||
const dm = await this.client.req('GET', `/users/${this._id}/dm` as '/users/id/dm');
|
||||
const dm = await this.client.req(
|
||||
"GET",
|
||||
`/users/${this._id}/dm` as "/users/id/dm",
|
||||
);
|
||||
return (await this.client.channels.fetch(dm._id, dm))!;
|
||||
}
|
||||
|
||||
@@ -111,28 +122,40 @@ export class User {
|
||||
* Send a friend request to a user
|
||||
*/
|
||||
async addFriend() {
|
||||
await this.client.req('PUT', `/users/${this.username}/friend` as '/users/id/friend');
|
||||
await this.client.req(
|
||||
"PUT",
|
||||
`/users/${this.username}/friend` as "/users/id/friend",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a user from the friend list
|
||||
*/
|
||||
async removeFriend() {
|
||||
await this.client.req('DELETE', `/users/${this._id}/friend` as '/users/id/friend');
|
||||
await this.client.req(
|
||||
"DELETE",
|
||||
`/users/${this._id}/friend` as "/users/id/friend",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Block a user
|
||||
*/
|
||||
async blockUser() {
|
||||
await this.client.req('PUT', `/users/${this._id}/block` as '/users/id/block');
|
||||
await this.client.req(
|
||||
"PUT",
|
||||
`/users/${this._id}/block` as "/users/id/block",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unblock a user
|
||||
*/
|
||||
async unblockUser() {
|
||||
await this.client.req('DELETE', `/users/${this._id}/block` as '/users/id/block');
|
||||
await this.client.req(
|
||||
"DELETE",
|
||||
`/users/${this._id}/block` as "/users/id/block",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +163,10 @@ export class User {
|
||||
* @returns The profile of the user
|
||||
*/
|
||||
async fetchProfile() {
|
||||
return await this.client.req('GET', `/users/${this._id}/profile` as '/users/id/profile');
|
||||
return await this.client.req(
|
||||
"GET",
|
||||
`/users/${this._id}/profile` as "/users/id/profile",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,7 +174,10 @@ export class User {
|
||||
* @returns The mutual connections of the current user and a target user
|
||||
*/
|
||||
async fetchMutual() {
|
||||
return await this.client.req('GET', `/users/${this._id}/mutual` as '/users/id/mutual');
|
||||
return await this.client.req(
|
||||
"GET",
|
||||
`/users/${this._id}/mutual` as "/users/id/mutual",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +188,10 @@ export class User {
|
||||
}
|
||||
|
||||
@computed generateAvatarURL(...args: FileArgs) {
|
||||
return this.client.generateFileURL(this.avatar ?? undefined, ...args) ?? this.defaultAvatarURL;
|
||||
return (
|
||||
this.client.generateFileURL(this.avatar ?? undefined, ...args) ??
|
||||
this.defaultAvatarURL
|
||||
);
|
||||
}
|
||||
|
||||
@computed get permission() {
|
||||
@@ -176,12 +208,17 @@ export class User {
|
||||
permissions = UserPermission.Access;
|
||||
}
|
||||
|
||||
if ([...this.client.channels.values()].find(channel =>
|
||||
(channel.channel_type === 'Group' || channel.channel_type === 'DirectMessage')
|
||||
&& channel.recipient_ids?.includes(this.client.user!._id)
|
||||
) || [...this.client.members.values()].find(member =>
|
||||
member._id.user === this.client.user!._id
|
||||
)) {
|
||||
if (
|
||||
[...this.client.channels.values()].find(
|
||||
(channel) =>
|
||||
(channel.channel_type === "Group" ||
|
||||
channel.channel_type === "DirectMessage") &&
|
||||
channel.recipient_ids?.includes(this.client.user!._id),
|
||||
) ||
|
||||
[...this.client.members.values()].find(
|
||||
(member) => member._id.user === this.client.user!._id,
|
||||
)
|
||||
) {
|
||||
permissions |= UserPermission.Access | UserPermission.ViewProfile;
|
||||
}
|
||||
|
||||
@@ -193,10 +230,13 @@ export default class Users extends Collection<string, User> {
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.createObj = this.createObj.bind(this);
|
||||
this.set('00000000000000000000000000', new User(client, {
|
||||
_id: '00000000000000000000000000',
|
||||
username: 'Revolt'
|
||||
}));
|
||||
this.set(
|
||||
"00000000000000000000000000",
|
||||
new User(client, {
|
||||
_id: "00000000000000000000000000",
|
||||
username: "Revolt",
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@action $get(id: string, data?: UserI) {
|
||||
@@ -212,7 +252,9 @@ export default class Users extends Collection<string, User> {
|
||||
*/
|
||||
async fetch(id: string, data?: UserI) {
|
||||
if (this.has(id)) return this.$get(id, data);
|
||||
let res = data ?? await this.client.req('GET', `/users/${id}` as '/users/id');
|
||||
let res =
|
||||
data ??
|
||||
(await this.client.req("GET", `/users/${id}` as "/users/id"));
|
||||
return this.createObj(res);
|
||||
}
|
||||
|
||||
@@ -230,7 +272,7 @@ export default class Users extends Collection<string, User> {
|
||||
this.set(data._id, user);
|
||||
});
|
||||
|
||||
this.client.emit('user/relationship', user);
|
||||
this.client.emit("user/relationship", user);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -238,8 +280,8 @@ export default class Users extends Collection<string, User> {
|
||||
* Edit the current user
|
||||
* @param data User edit data object
|
||||
*/
|
||||
async edit(data: Route<'PATCH', '/users/id'>["data"]) {
|
||||
await this.client.req('PATCH', '/users/id', data);
|
||||
async edit(data: Route<"PATCH", "/users/id">["data"]) {
|
||||
await this.client.req("PATCH", "/users/id", data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,6 +290,9 @@ export default class Users extends Collection<string, User> {
|
||||
* @param password Current password
|
||||
*/
|
||||
async changeUsername(username: string, password: string) {
|
||||
return await this.client.req('PATCH', '/users/id/username', { username, password });
|
||||
return await this.client.req("PATCH", "/users/id/username", {
|
||||
username,
|
||||
password,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+53
-32
@@ -1,5 +1,7 @@
|
||||
import { config } from 'dotenv';
|
||||
import { Client } from '.';
|
||||
import { config } from "dotenv";
|
||||
|
||||
import { Client } from ".";
|
||||
|
||||
config();
|
||||
|
||||
// To run this example, you need to have a local Revolt server running and an existing account.
|
||||
@@ -8,53 +10,72 @@ config();
|
||||
function user() {
|
||||
let client = new Client({
|
||||
apiURL: process.env.API_URL,
|
||||
debug: true
|
||||
debug: true,
|
||||
});
|
||||
|
||||
client.on('ready', async () => {
|
||||
client.on("ready", async () => {
|
||||
console.info(`Logged in as ${client.user!.username}!`);
|
||||
});
|
||||
|
||||
client.on('message', async message => {
|
||||
if (message.content === 'sus') {
|
||||
message.channel!.sendMessage('sus!');
|
||||
} else if (message.content === 'bot') {
|
||||
let bot = await client.req('POST', '/bots/create', { name: 'basedbot12' });
|
||||
client.on("message", async (message) => {
|
||||
if (message.content === "sus") {
|
||||
message.channel!.sendMessage("sus!");
|
||||
} else if (message.content === "bot") {
|
||||
let bot = await client.req("POST", "/bots/create", {
|
||||
name: "basedbot12",
|
||||
});
|
||||
message.channel!.sendMessage(JSON.stringify(bot));
|
||||
} else if (message.content === 'my bots') {
|
||||
message.channel!.sendMessage(JSON.stringify(
|
||||
await client.req('GET', '/bots/@me')
|
||||
));
|
||||
} else if (message.content === 'join bot') {
|
||||
await client.req('POST', `/bots/01FCV7DCMRD9MT3JBYT5VEKVRD/invite` as '/bots/id/invite',
|
||||
{ group: message.channel_id });
|
||||
// { server: '01FATEGMHEE2M1QGPA65NS6V8K' });
|
||||
} else if (message.content === 'edit bot name') {
|
||||
await client.req('PATCH', `/bots/01FCV7DCMRD9MT3JBYT5VEKVRD` as '/bots/id',
|
||||
{ name: 'testingbkaka' });
|
||||
} else if (message.content === 'make bot public') {
|
||||
await client.req('PATCH', `/bots/01FCV7DCMRD9MT3JBYT5VEKVRD` as '/bots/id',
|
||||
{ public: true });
|
||||
} else if (message.content === 'delete bot') {
|
||||
await client.req('DELETE', `/bots/01FCV7DCMRD9MT3JBYT5VEKVRD` as '/bots/id');
|
||||
} else if (message.content === "my bots") {
|
||||
message.channel!.sendMessage(
|
||||
JSON.stringify(await client.req("GET", "/bots/@me")),
|
||||
);
|
||||
} else if (message.content === "join bot") {
|
||||
await client.req(
|
||||
"POST",
|
||||
`/bots/01FCV7DCMRD9MT3JBYT5VEKVRD/invite` as "/bots/id/invite",
|
||||
{ group: message.channel_id },
|
||||
);
|
||||
// { server: '01FATEGMHEE2M1QGPA65NS6V8K' });
|
||||
} else if (message.content === "edit bot name") {
|
||||
await client.req(
|
||||
"PATCH",
|
||||
`/bots/01FCV7DCMRD9MT3JBYT5VEKVRD` as "/bots/id",
|
||||
{ name: "testingbkaka" },
|
||||
);
|
||||
} else if (message.content === "make bot public") {
|
||||
await client.req(
|
||||
"PATCH",
|
||||
`/bots/01FCV7DCMRD9MT3JBYT5VEKVRD` as "/bots/id",
|
||||
{ public: true },
|
||||
);
|
||||
} else if (message.content === "delete bot") {
|
||||
await client.req(
|
||||
"DELETE",
|
||||
`/bots/01FCV7DCMRD9MT3JBYT5VEKVRD` as "/bots/id",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
client.login({ email: process.env.EMAIL as string, password: process.env.PASSWORD as string })
|
||||
client.login({
|
||||
email: process.env.EMAIL as string,
|
||||
password: process.env.PASSWORD as string,
|
||||
});
|
||||
}
|
||||
|
||||
function bot() {
|
||||
let client = new Client({
|
||||
apiURL: process.env.API_URL
|
||||
apiURL: process.env.API_URL,
|
||||
});
|
||||
|
||||
client.on('ready', async () => {
|
||||
console.info(`Logged in as ${client.user!.username}! [${client.user!._id}]`);
|
||||
client.on("ready", async () => {
|
||||
console.info(
|
||||
`Logged in as ${client.user!.username}! [${client.user!._id}]`,
|
||||
);
|
||||
});
|
||||
|
||||
client.on('message', async message => {
|
||||
if (message.content === 'sus') {
|
||||
message.channel!.sendMessage('sus!');
|
||||
client.on("message", async (message) => {
|
||||
if (message.content === "sus") {
|
||||
message.channel!.sendMessage("sus!");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+188
-105
@@ -1,12 +1,13 @@
|
||||
import WebSocket from 'isomorphic-ws';
|
||||
import { backOff } from 'exponential-backoff';
|
||||
import { backOff } from "exponential-backoff";
|
||||
import WebSocket from "isomorphic-ws";
|
||||
import { runInAction } from "mobx";
|
||||
import { Role } from "revolt-api/types/Servers";
|
||||
|
||||
import { Client } from '..';
|
||||
import { ServerboundNotification, ClientboundNotification } from './notifications';
|
||||
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
import { Role } from 'revolt-api/types/Servers';
|
||||
import { Client } from "..";
|
||||
import {
|
||||
ServerboundNotification,
|
||||
ClientboundNotification,
|
||||
} from "./notifications";
|
||||
|
||||
export class WebSocketClient {
|
||||
client: Client;
|
||||
@@ -33,7 +34,10 @@ export class WebSocketClient {
|
||||
this.connected = false;
|
||||
this.ready = false;
|
||||
|
||||
if (typeof this.ws !== 'undefined' && this.ws.readyState === WebSocket.OPEN) {
|
||||
if (
|
||||
typeof this.ws !== "undefined" &&
|
||||
this.ws.readyState === WebSocket.OPEN
|
||||
) {
|
||||
this.ws.close();
|
||||
}
|
||||
}
|
||||
@@ -43,10 +47,14 @@ export class WebSocketClient {
|
||||
* @param notification Serverbound notification
|
||||
*/
|
||||
send(notification: ServerboundNotification) {
|
||||
if (typeof this.ws === 'undefined' || this.ws.readyState !== WebSocket.OPEN) return;
|
||||
if (
|
||||
typeof this.ws === "undefined" ||
|
||||
this.ws.readyState !== WebSocket.OPEN
|
||||
)
|
||||
return;
|
||||
|
||||
let data = JSON.stringify(notification);
|
||||
if (this.client.debug) console.debug('[<] PACKET', data);
|
||||
if (this.client.debug) console.debug("[<] PACKET", data);
|
||||
this.ws.send(data);
|
||||
}
|
||||
|
||||
@@ -55,7 +63,7 @@ export class WebSocketClient {
|
||||
* @param disallowReconnect Whether to disallow reconnection
|
||||
*/
|
||||
connect(disallowReconnect?: boolean): Promise<void> {
|
||||
this.client.emit('connecting');
|
||||
this.client.emit("connecting");
|
||||
|
||||
return new Promise((resolve, $reject) => {
|
||||
let thrown = false;
|
||||
@@ -68,49 +76,59 @@ export class WebSocketClient {
|
||||
|
||||
this.disconnect();
|
||||
|
||||
if (typeof this.client.configuration === 'undefined') {
|
||||
throw new Error("Attempted to open WebSocket without syncing configuration from server.");
|
||||
if (typeof this.client.configuration === "undefined") {
|
||||
throw new Error(
|
||||
"Attempted to open WebSocket without syncing configuration from server.",
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof this.client.session === 'undefined') {
|
||||
throw new Error("Attempted to open WebSocket without valid session.");
|
||||
if (typeof this.client.session === "undefined") {
|
||||
throw new Error(
|
||||
"Attempted to open WebSocket without valid session.",
|
||||
);
|
||||
}
|
||||
|
||||
let ws = new WebSocket(this.client.configuration.ws);
|
||||
this.ws = ws;
|
||||
|
||||
ws.onopen = () => {
|
||||
if (typeof this.client.session === 'string') {
|
||||
this.send({ type: 'Authenticate', token: this.client.session! });
|
||||
if (typeof this.client.session === "string") {
|
||||
this.send({
|
||||
type: "Authenticate",
|
||||
token: this.client.session!,
|
||||
});
|
||||
} else {
|
||||
this.send({ type: 'Authenticate', ...this.client.session! });
|
||||
this.send({
|
||||
type: "Authenticate",
|
||||
...this.client.session!,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let timeouts: Record<string, any> = {};
|
||||
let handle = async (msg: WebSocket.MessageEvent) => {
|
||||
let data = msg.data;
|
||||
if (typeof data !== 'string') return;
|
||||
if (typeof data !== "string") return;
|
||||
|
||||
if (this.client.debug) console.debug('[>] PACKET', data);
|
||||
if (this.client.debug) console.debug("[>] PACKET", data);
|
||||
let packet = JSON.parse(data) as ClientboundNotification;
|
||||
this.client.emit('packet', packet);
|
||||
this.client.emit("packet", packet);
|
||||
switch (packet.type) {
|
||||
case 'Error': {
|
||||
case "Error": {
|
||||
reject(packet.error);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Authenticated': {
|
||||
case "Authenticated": {
|
||||
disallowReconnect = false;
|
||||
this.client.emit('connected');
|
||||
this.client.emit("connected");
|
||||
this.connected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Ready': {
|
||||
case "Ready": {
|
||||
runInAction(() => {
|
||||
if (packet.type !== 'Ready') throw 0;
|
||||
if (packet.type !== "Ready") throw 0;
|
||||
|
||||
for (let user of packet.users) {
|
||||
this.client.users.createObj(user);
|
||||
@@ -130,45 +148,60 @@ export class WebSocketClient {
|
||||
});
|
||||
|
||||
this.client.user = this.client.users.get(
|
||||
packet.users.find(x => x.relationship === 'User')!._id
|
||||
packet.users.find((x) => x.relationship === "User")!
|
||||
._id,
|
||||
)!;
|
||||
|
||||
this.client.emit('ready');
|
||||
this.client.emit("ready");
|
||||
this.ready = true;
|
||||
resolve();
|
||||
|
||||
if (this.client.heartbeat > 0) {
|
||||
this.send({ type: 'Ping', data: + new Date() });
|
||||
this.send({ type: "Ping", data: +new Date() });
|
||||
this.heartbeat = setInterval(
|
||||
() => this.send({ type: 'Ping', data: + new Date() }),
|
||||
this.client.heartbeat * 1e3
|
||||
() =>
|
||||
this.send({
|
||||
type: "Ping",
|
||||
data: +new Date(),
|
||||
}),
|
||||
this.client.heartbeat * 1e3,
|
||||
) as any;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "Message": {
|
||||
if (!this.client.messages.has(packet._id)) {
|
||||
if (packet.author === '00000000000000000000000000') {
|
||||
if (typeof packet.content === 'object') {
|
||||
if (
|
||||
packet.author === "00000000000000000000000000"
|
||||
) {
|
||||
if (typeof packet.content === "object") {
|
||||
switch (packet.content.type) {
|
||||
case 'user_added':
|
||||
case 'user_remove':
|
||||
await this.client.users.fetch(packet.content.by);
|
||||
case 'user_left':
|
||||
await this.client.users.fetch(packet.content.id);
|
||||
case "user_added":
|
||||
case "user_remove":
|
||||
await this.client.users.fetch(
|
||||
packet.content.by,
|
||||
);
|
||||
case "user_left":
|
||||
await this.client.users.fetch(
|
||||
packet.content.id,
|
||||
);
|
||||
break;
|
||||
case 'user_joined':
|
||||
case 'user_left':
|
||||
case 'user_banned':
|
||||
case 'user_kicked':
|
||||
await this.client.users.fetch(packet.content.id);
|
||||
case "user_joined":
|
||||
case "user_left":
|
||||
case "user_banned":
|
||||
case "user_kicked":
|
||||
await this.client.users.fetch(
|
||||
packet.content.id,
|
||||
);
|
||||
break;
|
||||
case 'channel_description_changed':
|
||||
case 'channel_icon_changed':
|
||||
case 'channel_renamed':
|
||||
await this.client.users.fetch(packet.content.by);
|
||||
case "channel_description_changed":
|
||||
case "channel_icon_changed":
|
||||
case "channel_renamed":
|
||||
await this.client.users.fetch(
|
||||
packet.content.by,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -176,10 +209,18 @@ export class WebSocketClient {
|
||||
await this.client.users.fetch(packet.author);
|
||||
}
|
||||
|
||||
let channel = await this.client.channels.fetch(packet.channel);
|
||||
if (channel.channel_type === 'TextChannel') {
|
||||
let server = await this.client.servers.fetch(channel.server_id!);
|
||||
if (packet.author !== '00000000000000000000000000') await server.fetchMember(packet.author);
|
||||
let channel = await this.client.channels.fetch(
|
||||
packet.channel,
|
||||
);
|
||||
if (channel.channel_type === "TextChannel") {
|
||||
let server = await this.client.servers.fetch(
|
||||
channel.server_id!,
|
||||
);
|
||||
if (
|
||||
packet.author !==
|
||||
"00000000000000000000000000"
|
||||
)
|
||||
await server.fetchMember(packet.author);
|
||||
}
|
||||
|
||||
this.client.messages.createObj(packet, true);
|
||||
@@ -191,23 +232,28 @@ export class WebSocketClient {
|
||||
let message = this.client.messages.get(packet.id);
|
||||
if (message) {
|
||||
message.update(packet.data);
|
||||
this.client.emit('message/update', message);
|
||||
this.client.emit("message/update", message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "MessageDelete": {
|
||||
this.client.messages.delete(packet.id);
|
||||
this.client.emit('message/delete', packet.id);
|
||||
this.client.emit("message/delete", packet.id);
|
||||
break;
|
||||
}
|
||||
|
||||
case "ChannelCreate": {
|
||||
runInAction(async () => {
|
||||
if (packet.type !== 'ChannelCreate') throw 0;
|
||||
if (packet.type !== "ChannelCreate") throw 0;
|
||||
|
||||
if (packet.channel_type === 'TextChannel' || packet.channel_type === 'VoiceChannel') {
|
||||
let server = await this.client.servers.fetch(packet.server);
|
||||
if (
|
||||
packet.channel_type === "TextChannel" ||
|
||||
packet.channel_type === "VoiceChannel"
|
||||
) {
|
||||
let server = await this.client.servers.fetch(
|
||||
packet.server,
|
||||
);
|
||||
server.channel_ids.push(packet._id);
|
||||
}
|
||||
|
||||
@@ -220,24 +266,28 @@ export class WebSocketClient {
|
||||
let channel = this.client.channels.get(packet.id);
|
||||
if (channel) {
|
||||
channel.update(packet.data, packet.clear);
|
||||
this.client.emit('channel/update', channel);
|
||||
this.client.emit("channel/update", channel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "ChannelDelete": {
|
||||
this.client.channels.get(packet.id)?.delete(true);
|
||||
this.client.emit('channel/delete', packet.id);
|
||||
this.client.emit("channel/delete", packet.id);
|
||||
break;
|
||||
}
|
||||
|
||||
case "ChannelGroupJoin": {
|
||||
this.client.channels.get(packet.id)?.updateGroupJoin(packet.user);
|
||||
this.client.channels
|
||||
.get(packet.id)
|
||||
?.updateGroupJoin(packet.user);
|
||||
break;
|
||||
}
|
||||
|
||||
case "ChannelGroupLeave": {
|
||||
this.client.channels.get(packet.id)?.updateGroupLeave(packet.user);
|
||||
this.client.channels
|
||||
.get(packet.id)
|
||||
?.updateGroupLeave(packet.user);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -245,14 +295,14 @@ export class WebSocketClient {
|
||||
let server = this.client.servers.get(packet.id);
|
||||
if (server) {
|
||||
server.update(packet.data, packet.clear);
|
||||
this.client.emit('server/update', server);
|
||||
this.client.emit("server/update", server);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "ServerDelete": {
|
||||
this.client.servers.get(packet.id)?.delete(true);
|
||||
this.client.emit('server/delete', packet.id);
|
||||
this.client.emit("server/delete", packet.id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -260,24 +310,27 @@ export class WebSocketClient {
|
||||
let member = this.client.members.getKey(packet.id);
|
||||
if (member) {
|
||||
member.update(packet.data, packet.clear);
|
||||
this.client.emit('member/update', member);
|
||||
this.client.emit("member/update", member);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "ServerMemberJoin": {
|
||||
runInAction(async () => {
|
||||
if (packet.type !== 'ServerMemberJoin') return 0;
|
||||
if (packet.type !== "ServerMemberJoin") return 0;
|
||||
|
||||
await this.client.servers.fetch(packet.id);
|
||||
await this.client.users.fetch(packet.user);
|
||||
|
||||
this.client.members.createObj({
|
||||
_id: {
|
||||
server: packet.id,
|
||||
user: packet.user
|
||||
}
|
||||
}, true);
|
||||
this.client.members.createObj(
|
||||
{
|
||||
_id: {
|
||||
server: packet.id,
|
||||
user: packet.user,
|
||||
},
|
||||
},
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
break;
|
||||
@@ -285,24 +338,29 @@ export class WebSocketClient {
|
||||
|
||||
case "ServerMemberLeave": {
|
||||
if (packet.user === this.client.user!._id) {
|
||||
const server_id = packet.id
|
||||
const server_id = packet.id;
|
||||
runInAction(() => {
|
||||
this.client.servers.get(server_id)?.delete(true);
|
||||
[...this.client.members.keys()]
|
||||
.forEach(key => {
|
||||
if (JSON.parse(key).server === server_id) {
|
||||
this.client.servers
|
||||
.get(server_id)
|
||||
?.delete(true);
|
||||
[...this.client.members.keys()].forEach(
|
||||
(key) => {
|
||||
if (
|
||||
JSON.parse(key).server === server_id
|
||||
) {
|
||||
this.client.members.delete(key);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.client.members.deleteKey({
|
||||
server: packet.id,
|
||||
user: packet.user
|
||||
user: packet.user,
|
||||
});
|
||||
this.client.emit('member/leave', {
|
||||
this.client.emit("member/leave", {
|
||||
server: packet.id,
|
||||
user: packet.user
|
||||
user: packet.user,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -314,13 +372,18 @@ export class WebSocketClient {
|
||||
if (server) {
|
||||
let role = {
|
||||
...server.roles?.[packet.role_id],
|
||||
...packet.data
|
||||
} as Role
|
||||
...packet.data,
|
||||
} as Role;
|
||||
server.roles = {
|
||||
...server.roles,
|
||||
[packet.role_id]: role
|
||||
}
|
||||
this.client.emit('role/update', packet.role_id, role, packet.id);
|
||||
[packet.role_id]: role,
|
||||
};
|
||||
this.client.emit(
|
||||
"role/update",
|
||||
packet.role_id,
|
||||
role,
|
||||
packet.id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -328,20 +391,27 @@ export class WebSocketClient {
|
||||
case "ServerRoleDelete": {
|
||||
let server = this.client.servers.get(packet.id);
|
||||
if (server) {
|
||||
let { [packet.role_id]: _, ...roles } = server.roles ?? {};
|
||||
let { [packet.role_id]: _, ...roles } =
|
||||
server.roles ?? {};
|
||||
server.roles = roles;
|
||||
this.client.emit('role/delete', packet.role_id, packet.id);
|
||||
this.client.emit(
|
||||
"role/delete",
|
||||
packet.role_id,
|
||||
packet.id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "UserUpdate": {
|
||||
this.client.users.get(packet.id)?.update(packet.data, packet.clear);
|
||||
this.client.users
|
||||
.get(packet.id)
|
||||
?.update(packet.data, packet.clear);
|
||||
break;
|
||||
}
|
||||
|
||||
case "UserRelationship": {
|
||||
let user = this.client.users.get(packet.user._id)
|
||||
let user = this.client.users.get(packet.user._id);
|
||||
if (user) {
|
||||
user.update({ relationship: packet.status });
|
||||
} else {
|
||||
@@ -358,8 +428,8 @@ export class WebSocketClient {
|
||||
if (channel) {
|
||||
channel.updateStartTyping(user);
|
||||
|
||||
clearInterval(timeouts[packet.id+user]);
|
||||
timeouts[packet.id+user] = setTimeout(() => {
|
||||
clearInterval(timeouts[packet.id + user]);
|
||||
timeouts[packet.id + user] = setTimeout(() => {
|
||||
channel!.updateStopTyping(user);
|
||||
}, 3000);
|
||||
}
|
||||
@@ -368,22 +438,29 @@ export class WebSocketClient {
|
||||
}
|
||||
|
||||
case "ChannelStopTyping": {
|
||||
this.client.channels.get(packet.id)?.updateStopTyping(packet.user);
|
||||
clearInterval(timeouts[packet.id+packet.user]);
|
||||
this.client.channels
|
||||
.get(packet.id)
|
||||
?.updateStopTyping(packet.user);
|
||||
clearInterval(timeouts[packet.id + packet.user]);
|
||||
break;
|
||||
}
|
||||
|
||||
case "ChannelAck": break;
|
||||
case "ChannelAck":
|
||||
break;
|
||||
|
||||
case "Pong": {
|
||||
this.ping = + new Date() - packet.data;
|
||||
this.ping = +new Date() - packet.data;
|
||||
break;
|
||||
}
|
||||
|
||||
default: this.client.debug && console.warn(`Warning: Unhandled packet! ${packet.type}`);
|
||||
default:
|
||||
this.client.debug &&
|
||||
console.warn(
|
||||
`Warning: Unhandled packet! ${packet.type}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
let processing = false;
|
||||
let queue: WebSocket.MessageEvent[] = [];
|
||||
ws.onmessage = async (data) => {
|
||||
@@ -396,22 +473,28 @@ export class WebSocketClient {
|
||||
}
|
||||
processing = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ws.onerror = (err) => {
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
this.client.emit('dropped');
|
||||
this.client.emit("dropped");
|
||||
this.connected = false;
|
||||
this.ready = false;
|
||||
|
||||
Object.keys(timeouts).map(k => timeouts[k]).forEach(clearTimeout);
|
||||
Object.keys(timeouts)
|
||||
.map((k) => timeouts[k])
|
||||
.forEach(clearTimeout);
|
||||
|
||||
runInAction(() => {
|
||||
[...this.client.users.values()].forEach(user => user.online = false);
|
||||
[...this.client.channels.values()].forEach(channel => channel.typing_ids.clear());
|
||||
[...this.client.users.values()].forEach(
|
||||
(user) => (user.online = false),
|
||||
);
|
||||
[...this.client.channels.values()].forEach((channel) =>
|
||||
channel.typing_ids.clear(),
|
||||
);
|
||||
});
|
||||
|
||||
if (!disallowReconnect && this.client.autoReconnect) {
|
||||
|
||||
@@ -1,62 +1,95 @@
|
||||
import type { Session } from "revolt-api/types/Auth";
|
||||
import type { Channel, Message } from "revolt-api/types/Channels";
|
||||
import type {
|
||||
Member,
|
||||
MemberCompositeKey,
|
||||
Role,
|
||||
Server,
|
||||
} from "revolt-api/types/Servers";
|
||||
import type { UserSettings } from "revolt-api/types/Sync";
|
||||
import type { RelationshipStatus, User } from "revolt-api/types/Users";
|
||||
|
||||
import type { Session } from 'revolt-api/types/Auth';
|
||||
import type { UserSettings } from 'revolt-api/types/Sync';
|
||||
import type { Channel, Message } from 'revolt-api/types/Channels';
|
||||
import type { RelationshipStatus, User } from 'revolt-api/types/Users';
|
||||
import type { Member, MemberCompositeKey, Role, Server } from 'revolt-api/types/Servers';
|
||||
import type { RemoveChannelField, RemoveServerField, RemoveUserField, RemoveMemberField } from '../api/routes';
|
||||
import type {
|
||||
RemoveChannelField,
|
||||
RemoveServerField,
|
||||
RemoveUserField,
|
||||
RemoveMemberField,
|
||||
} from "../api/routes";
|
||||
|
||||
type WebSocketError = {
|
||||
error: 'InternalError' | 'InvalidSession' | 'OnboardingNotFinished' | 'AlreadyAuthenticated'
|
||||
error:
|
||||
| "InternalError"
|
||||
| "InvalidSession"
|
||||
| "OnboardingNotFinished"
|
||||
| "AlreadyAuthenticated";
|
||||
};
|
||||
|
||||
export type ServerboundNotification = (
|
||||
{ type: 'Ping', data: number } |
|
||||
{ type: 'Pong', data: number } |
|
||||
({ type: 'Authenticate' } & Session) |
|
||||
({ type: 'Authenticate', token: string }) |
|
||||
({ type: 'BeginTyping', channel: string }) |
|
||||
({ type: 'EndTyping', channel: string })
|
||||
);
|
||||
export type ServerboundNotification =
|
||||
| { type: "Ping"; data: number }
|
||||
| { type: "Pong"; data: number }
|
||||
| ({ type: "Authenticate" } & Session)
|
||||
| { type: "Authenticate"; token: string }
|
||||
| { type: "BeginTyping"; channel: string }
|
||||
| { type: "EndTyping"; channel: string };
|
||||
|
||||
export type ReadyPacket = {
|
||||
type: 'Ready',
|
||||
users: User[],
|
||||
servers: Server[],
|
||||
channels: Channel[],
|
||||
members: Member[]
|
||||
}
|
||||
type: "Ready";
|
||||
users: User[];
|
||||
servers: Server[];
|
||||
channels: Channel[];
|
||||
members: Member[];
|
||||
};
|
||||
|
||||
export type ClientboundNotification = (
|
||||
{ type: 'Ping', data: number } |
|
||||
{ type: 'Pong', data: number } |
|
||||
({ type: 'Error' } & WebSocketError) |
|
||||
{ type: 'Authenticated' } |
|
||||
ReadyPacket |
|
||||
|
||||
({ type: 'Message' } & Message) |
|
||||
({ type: 'MessageUpdate', id: string, data: Partial<Message> }) |
|
||||
({ type: 'MessageDelete', id: string }) |
|
||||
|
||||
({ type: 'ChannelCreate' } & Channel) |
|
||||
{ type: 'ChannelUpdate', id: string, data: Partial<Channel>, clear?: RemoveChannelField } |
|
||||
{ type: 'ChannelDelete', id: string } |
|
||||
{ type: 'ChannelGroupJoin', id: string, user: string } |
|
||||
{ type: 'ChannelGroupLeave', id: string, user: string } |
|
||||
{ type: 'ChannelStartTyping', id: string, user: string } |
|
||||
{ type: 'ChannelStopTyping', id: string, user: string } |
|
||||
{ type: 'ChannelAck', id: string, user: string, message_id: string } |
|
||||
|
||||
({ type: 'ServerUpdate', id: string, data: Partial<Server>, clear?: RemoveServerField }) |
|
||||
({ type: 'ServerDelete', id: string }) |
|
||||
({ type: 'ServerMemberUpdate', id: MemberCompositeKey, data: Partial<Member>, clear?: RemoveMemberField }) |
|
||||
({ type: 'ServerMemberJoin', id: string, user: string }) |
|
||||
({ type: 'ServerMemberLeave', id: string, user: string }) |
|
||||
({ type: 'ServerRoleUpdate', id: string, role_id: string, data: Partial<Role> }) |
|
||||
({ type: 'ServerRoleDelete', id: string, role_id: string }) |
|
||||
|
||||
{ type: 'UserUpdate', id: string, data: Partial<User>, clear?: RemoveUserField } |
|
||||
{ type: 'UserRelationship', user: User, status: RelationshipStatus } |
|
||||
{ type: 'UserPresence', id: string, online: boolean } |
|
||||
{ type: 'UserSettingsUpdate', id: string, update: UserSettings }
|
||||
)
|
||||
export type ClientboundNotification =
|
||||
| { type: "Ping"; data: number }
|
||||
| { type: "Pong"; data: number }
|
||||
| ({ type: "Error" } & WebSocketError)
|
||||
| { type: "Authenticated" }
|
||||
| ReadyPacket
|
||||
| ({ type: "Message" } & Message)
|
||||
| { type: "MessageUpdate"; id: string; data: Partial<Message> }
|
||||
| { type: "MessageDelete"; id: string }
|
||||
| ({ type: "ChannelCreate" } & Channel)
|
||||
| {
|
||||
type: "ChannelUpdate";
|
||||
id: string;
|
||||
data: Partial<Channel>;
|
||||
clear?: RemoveChannelField;
|
||||
}
|
||||
| { type: "ChannelDelete"; id: string }
|
||||
| { type: "ChannelGroupJoin"; id: string; user: string }
|
||||
| { type: "ChannelGroupLeave"; id: string; user: string }
|
||||
| { type: "ChannelStartTyping"; id: string; user: string }
|
||||
| { type: "ChannelStopTyping"; id: string; user: string }
|
||||
| { type: "ChannelAck"; id: string; user: string; message_id: string }
|
||||
| {
|
||||
type: "ServerUpdate";
|
||||
id: string;
|
||||
data: Partial<Server>;
|
||||
clear?: RemoveServerField;
|
||||
}
|
||||
| { type: "ServerDelete"; id: string }
|
||||
| {
|
||||
type: "ServerMemberUpdate";
|
||||
id: MemberCompositeKey;
|
||||
data: Partial<Member>;
|
||||
clear?: RemoveMemberField;
|
||||
}
|
||||
| { type: "ServerMemberJoin"; id: string; user: string }
|
||||
| { type: "ServerMemberLeave"; id: string; user: string }
|
||||
| {
|
||||
type: "ServerRoleUpdate";
|
||||
id: string;
|
||||
role_id: string;
|
||||
data: Partial<Role>;
|
||||
}
|
||||
| { type: "ServerRoleDelete"; id: string; role_id: string }
|
||||
| {
|
||||
type: "UserUpdate";
|
||||
id: string;
|
||||
data: Partial<User>;
|
||||
clear?: RemoveUserField;
|
||||
}
|
||||
| { type: "UserRelationship"; user: User; status: RelationshipStatus }
|
||||
| { type: "UserPresence"; id: string; online: boolean }
|
||||
| { type: "UserSettingsUpdate"; id: string; update: UserSettings };
|
||||
|
||||
@@ -2,244 +2,6 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
|
||||
integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.16.0"
|
||||
|
||||
"@babel/compat-data@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa"
|
||||
integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew==
|
||||
|
||||
"@babel/core@7.13.10":
|
||||
version "7.13.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.10.tgz#07de050bbd8193fcd8a3c27918c0890613a94559"
|
||||
integrity sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.12.13"
|
||||
"@babel/generator" "^7.13.9"
|
||||
"@babel/helper-compilation-targets" "^7.13.10"
|
||||
"@babel/helper-module-transforms" "^7.13.0"
|
||||
"@babel/helpers" "^7.13.10"
|
||||
"@babel/parser" "^7.13.10"
|
||||
"@babel/template" "^7.12.13"
|
||||
"@babel/traverse" "^7.13.0"
|
||||
"@babel/types" "^7.13.0"
|
||||
convert-source-map "^1.7.0"
|
||||
debug "^4.1.0"
|
||||
gensync "^1.0.0-beta.2"
|
||||
json5 "^2.1.2"
|
||||
lodash "^4.17.19"
|
||||
semver "^6.3.0"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@7.13.9":
|
||||
version "7.13.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39"
|
||||
integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.13.0"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.13.0", "@babel/generator@^7.13.9", "@babel/generator@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2"
|
||||
integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-compilation-targets@^7.13.10":
|
||||
version "7.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0"
|
||||
integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==
|
||||
dependencies:
|
||||
"@babel/compat-data" "^7.16.0"
|
||||
"@babel/helper-validator-option" "^7.14.5"
|
||||
browserslist "^4.17.5"
|
||||
semver "^6.3.0"
|
||||
|
||||
"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481"
|
||||
integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==
|
||||
dependencies:
|
||||
"@babel/helper-get-function-arity" "^7.16.0"
|
||||
"@babel/template" "^7.16.0"
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa"
|
||||
integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-hoist-variables@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a"
|
||||
integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-member-expression-to-functions@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4"
|
||||
integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-module-imports@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3"
|
||||
integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-module-transforms@^7.13.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5"
|
||||
integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.16.0"
|
||||
"@babel/helper-replace-supers" "^7.16.0"
|
||||
"@babel/helper-simple-access" "^7.16.0"
|
||||
"@babel/helper-split-export-declaration" "^7.16.0"
|
||||
"@babel/helper-validator-identifier" "^7.15.7"
|
||||
"@babel/template" "^7.16.0"
|
||||
"@babel/traverse" "^7.16.0"
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-optimise-call-expression@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338"
|
||||
integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-replace-supers@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17"
|
||||
integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==
|
||||
dependencies:
|
||||
"@babel/helper-member-expression-to-functions" "^7.16.0"
|
||||
"@babel/helper-optimise-call-expression" "^7.16.0"
|
||||
"@babel/traverse" "^7.16.0"
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-simple-access@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517"
|
||||
integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438"
|
||||
integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.15.7":
|
||||
version "7.15.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
|
||||
integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
|
||||
|
||||
"@babel/helper-validator-option@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
|
||||
integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
|
||||
|
||||
"@babel/helpers@^7.13.10":
|
||||
version "7.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.3.tgz#27fc64f40b996e7074dc73128c3e5c3e7f55c43c"
|
||||
integrity sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==
|
||||
dependencies:
|
||||
"@babel/template" "^7.16.0"
|
||||
"@babel/traverse" "^7.16.3"
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/highlight@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
|
||||
integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.15.7"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@7.14.6":
|
||||
version "7.14.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.6.tgz#d85cc68ca3cac84eae384c06f032921f5227f4b2"
|
||||
integrity sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==
|
||||
|
||||
"@babel/parser@^7.13.0", "@babel/parser@^7.13.10", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3":
|
||||
version "7.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.3.tgz#271bafcb811080905a119222edbc17909c82261d"
|
||||
integrity sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==
|
||||
|
||||
"@babel/template@^7.12.13", "@babel/template@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
|
||||
integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.16.0"
|
||||
"@babel/parser" "^7.16.0"
|
||||
"@babel/types" "^7.16.0"
|
||||
|
||||
"@babel/traverse@7.13.0":
|
||||
version "7.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc"
|
||||
integrity sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.12.13"
|
||||
"@babel/generator" "^7.13.0"
|
||||
"@babel/helper-function-name" "^7.12.13"
|
||||
"@babel/helper-split-export-declaration" "^7.12.13"
|
||||
"@babel/parser" "^7.13.0"
|
||||
"@babel/types" "^7.13.0"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3":
|
||||
version "7.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787"
|
||||
integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.16.0"
|
||||
"@babel/generator" "^7.16.0"
|
||||
"@babel/helper-function-name" "^7.16.0"
|
||||
"@babel/helper-hoist-variables" "^7.16.0"
|
||||
"@babel/helper-split-export-declaration" "^7.16.0"
|
||||
"@babel/parser" "^7.16.3"
|
||||
"@babel/types" "^7.16.0"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/types@7.13.0":
|
||||
version "7.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80"
|
||||
integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.12.11"
|
||||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.13.0", "@babel/types@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba"
|
||||
integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.15.7"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@eslint/eslintrc@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.4.tgz#dfe0ff7ba270848d10c5add0715e04964c034b31"
|
||||
@@ -290,19 +52,6 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@trivago/prettier-plugin-sort-imports@^3.1.1":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-3.1.1.tgz#101e34eadb252572ec32aea6d5487d93b90a0037"
|
||||
integrity sha512-T9EJNEOugWts4WxdmpWeY+sp+2fUHhvGh9QSBCowEGJfcbnu355HQRqok5bKwejdieMaI1+uGZhuTNMZwjqOCQ==
|
||||
dependencies:
|
||||
"@babel/core" "7.13.10"
|
||||
"@babel/generator" "7.13.9"
|
||||
"@babel/parser" "7.14.6"
|
||||
"@babel/traverse" "7.13.0"
|
||||
"@babel/types" "7.13.0"
|
||||
javascript-natural-sort "0.7.1"
|
||||
lodash "4.17.21"
|
||||
|
||||
"@types/events@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||
@@ -468,13 +217,6 @@ ansi-regex@^5.0.1:
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
@@ -700,17 +442,6 @@ braces@^3.0.1:
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
browserslist@^4.17.5:
|
||||
version "4.17.6"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d"
|
||||
integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001274"
|
||||
electron-to-chromium "^1.3.886"
|
||||
escalade "^3.1.1"
|
||||
node-releases "^2.0.1"
|
||||
picocolors "^1.0.0"
|
||||
|
||||
buffer-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
|
||||
@@ -754,20 +485,6 @@ camelcase@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
|
||||
integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo=
|
||||
|
||||
caniuse-lite@^1.0.30001274:
|
||||
version "1.0.30001280"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001280.tgz#066a506046ba4be34cde5f74a08db7a396718fb7"
|
||||
integrity sha512-kFXwYvHe5rix25uwueBxC569o53J6TpnGu0BEEn+6Lhl2vsnAumRFWEBhDft1fwyo6m1r4i+RqA4+163FpeFcA==
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@^4.0.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
@@ -860,13 +577,6 @@ collection-visit@^1.0.0:
|
||||
map-visit "^1.0.0"
|
||||
object-visit "^1.0.0"
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
dependencies:
|
||||
color-name "1.1.3"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
@@ -874,11 +584,6 @@ color-convert@^2.0.1:
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
@@ -909,7 +614,7 @@ concat-stream@^1.6.0:
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
convert-source-map@^1.5.0, convert-source-map@^1.7.0:
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
|
||||
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
|
||||
@@ -958,7 +663,7 @@ debug@^2.2.0, debug@^2.3.3:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
|
||||
debug@^4.1.1, debug@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
||||
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
|
||||
@@ -1068,11 +773,6 @@ each-props@^1.3.2:
|
||||
is-plain-object "^2.0.1"
|
||||
object.defaults "^1.1.0"
|
||||
|
||||
electron-to-chromium@^1.3.886:
|
||||
version "1.3.895"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.895.tgz#9b0f8f2e32d8283bbb200156fd5d8dfd775f31ed"
|
||||
integrity sha512-9Ww3fB8CWctjqHwkOt7DQbMZMpal2x2reod+/lU4b9axO1XJEDUpPMBxs7YnjLhhqpKXIIB5SRYN/B4K0QpvyQ==
|
||||
|
||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
@@ -1130,16 +830,6 @@ es6-weak-map@^2.0.1:
|
||||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
@@ -1559,11 +1249,6 @@ functional-red-black-tree@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
gensync@^1.0.0-beta.2:
|
||||
version "1.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||
|
||||
get-caller-file@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
|
||||
@@ -1678,11 +1363,6 @@ global-prefix@^1.0.1:
|
||||
is-windows "^1.0.1"
|
||||
which "^1.2.14"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||
|
||||
globals@^13.6.0, globals@^13.9.0:
|
||||
version "13.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e"
|
||||
@@ -1778,11 +1458,6 @@ handlebars@^4.7.7:
|
||||
optionalDependencies:
|
||||
uglify-js "^3.1.4"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
@@ -2112,16 +1787,6 @@ isomorphic-ws@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc"
|
||||
integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==
|
||||
|
||||
javascript-natural-sort@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
|
||||
integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=
|
||||
|
||||
js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
@@ -2142,11 +1807,6 @@ jsdoc-regex@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz#8424428d5b563ad8c5c7fbec079b9a8b09c8dcfa"
|
||||
integrity sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po=
|
||||
|
||||
jsesc@^2.5.1:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
|
||||
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
@@ -2157,7 +1817,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
json5@^2.1.2, json5@^2.2.0:
|
||||
json5@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
||||
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
|
||||
@@ -2270,7 +1930,7 @@ lodash.merge@^4.6.2:
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.19:
|
||||
lodash@^4.17.10:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@@ -2457,11 +2117,6 @@ node-fetch@^2.6.1:
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
node-releases@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5"
|
||||
integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==
|
||||
|
||||
normalize-package-data@^2.3.2:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||
@@ -2698,11 +2353,6 @@ pause-stream@0.0.11, pause-stream@^0.0.11:
|
||||
dependencies:
|
||||
through "~2.3"
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
picomatch@^2.2.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||
@@ -3005,11 +2655,6 @@ semver-greatest-satisfied-range@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
semver@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.2.1, semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
@@ -3104,7 +2749,7 @@ source-map-url@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
|
||||
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
|
||||
|
||||
source-map@^0.5.0, source-map@^0.5.6:
|
||||
source-map@^0.5.6:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
@@ -3258,13 +2903,6 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
@@ -3319,11 +2957,6 @@ to-absolute-glob@^2.0.0:
|
||||
is-absolute "^1.0.0"
|
||||
is-negated-glob "^1.0.0"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
|
||||
|
||||
to-object-path@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
|
||||
@@ -3432,10 +3065,10 @@ typedoc@^0.21.4:
|
||||
shiki "^0.9.3"
|
||||
typedoc-default-themes "^0.12.10"
|
||||
|
||||
typescript@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
|
||||
integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
|
||||
typescript@^4.4.4:
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
|
||||
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.13.10"
|
||||
|
||||
Reference in New Issue
Block a user