seyfert 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/api.js +13 -7
- package/lib/builders/Attachment.d.ts +1 -4
- package/lib/builders/Attachment.js +4 -4
- package/lib/cache/adapters/workeradapter.js +7 -3
- package/lib/cache/resources/default/base.d.ts +1 -2
- package/lib/cache/resources/default/guild-based.d.ts +1 -2
- package/lib/client/base.d.ts +26 -4
- package/lib/client/base.js +42 -2
- package/lib/client/client.d.ts +3 -3
- package/lib/client/client.js +18 -6
- package/lib/client/httpclient.d.ts +7 -8
- package/lib/client/httpclient.js +92 -13
- package/lib/client/oninteractioncreate.d.ts +2 -2
- package/lib/client/oninteractioncreate.js +15 -7
- package/lib/client/onmessagecreate.js +74 -66
- package/lib/client/workerclient.d.ts +1 -1
- package/lib/client/workerclient.js +18 -7
- package/lib/commands/applications/chat.d.ts +1 -1
- package/lib/commands/applications/chat.js +2 -1
- package/lib/commands/applications/chatcontext.d.ts +1 -1
- package/lib/commands/applications/chatcontext.js +2 -2
- package/lib/commands/applications/menu.js +0 -48
- package/lib/commands/applications/menucontext.d.ts +1 -1
- package/lib/commands/applications/menucontext.js +3 -3
- package/lib/commands/applications/options.d.ts +3 -1
- package/lib/commands/basecontext.d.ts +26 -0
- package/lib/commands/{basecontex.js → basecontext.js} +24 -0
- package/lib/commands/handler.d.ts +6 -1
- package/lib/commands/handler.js +125 -3
- package/lib/common/bot/watcher.d.ts +1 -2
- package/lib/common/bot/watcher.js +9 -4
- package/lib/common/it/logger.d.ts +1 -1
- package/lib/common/it/logger.js +9 -8
- package/lib/common/it/utils.d.ts +2 -0
- package/lib/common/it/utils.js +19 -5
- package/lib/common/shorters/interaction.js +3 -3
- package/lib/common/shorters/messages.js +2 -2
- package/lib/common/shorters/webhook.js +2 -2
- package/lib/components/componentcommand.d.ts +21 -0
- package/lib/components/{command.js → componentcommand.js} +2 -5
- package/lib/components/componentcontext.d.ts +20 -16
- package/lib/components/componentcontext.js +27 -9
- package/lib/components/handler.d.ts +10 -5
- package/lib/components/handler.js +94 -17
- package/lib/components/index.d.ts +3 -1
- package/lib/components/index.js +3 -1
- package/lib/components/modalcommand.d.ts +15 -0
- package/lib/components/modalcommand.js +9 -0
- package/lib/components/modalcontext.d.ts +104 -0
- package/lib/components/modalcontext.js +132 -0
- package/lib/events/handler.d.ts +4 -1
- package/lib/events/handler.js +2 -7
- package/lib/events/hooks/application_command.d.ts +2 -2
- package/lib/events/hooks/auto_moderation.d.ts +5 -5
- package/lib/events/hooks/channel.d.ts +5 -5
- package/lib/events/hooks/custom.d.ts +3 -3
- package/lib/events/hooks/dispatch.d.ts +4 -4
- package/lib/events/hooks/entitlement.d.ts +4 -4
- package/lib/events/hooks/guild.d.ts +23 -23
- package/lib/events/hooks/guild.js +6 -6
- package/lib/events/hooks/integration.d.ts +4 -4
- package/lib/events/hooks/interactions.d.ts +2 -2
- package/lib/events/hooks/invite.d.ts +3 -3
- package/lib/events/hooks/message.d.ts +13 -13
- package/lib/events/hooks/message.js +1 -1
- package/lib/events/hooks/presence.d.ts +7 -3
- package/lib/events/hooks/presence.js +2 -2
- package/lib/events/hooks/stage.d.ts +7 -13
- package/lib/events/hooks/stage.js +2 -2
- package/lib/events/hooks/thread.d.ts +7 -7
- package/lib/events/hooks/thread.js +2 -2
- package/lib/events/hooks/typing.d.ts +2 -2
- package/lib/events/hooks/user.d.ts +2 -2
- package/lib/events/hooks/user.js +2 -2
- package/lib/events/hooks/voice.d.ts +5 -45
- package/lib/events/hooks/voice.js +4 -7
- package/lib/events/hooks/webhook.d.ts +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +9 -4
- package/lib/langs/handler.d.ts +4 -1
- package/lib/langs/handler.js +3 -3
- package/lib/structures/Interaction.d.ts +3 -3
- package/lib/structures/Interaction.js +11 -6
- package/lib/structures/VoiceState.d.ts +6 -5
- package/lib/structures/VoiceState.js +6 -3
- package/lib/structures/channels.d.ts +1 -1
- package/lib/structures/channels.js +2 -1
- package/lib/websocket/discord/sharder.js +10 -3
- package/lib/websocket/discord/shared.d.ts +1 -0
- package/lib/websocket/discord/workermanager.d.ts +2 -3
- package/lib/websocket/discord/workermanager.js +4 -2
- package/package.json +3 -3
- package/lib/commands/basecontex.d.ts +0 -15
- package/lib/components/command.d.ts +0 -24
package/lib/api/api.js
CHANGED
|
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ApiHandler = void 0;
|
|
4
4
|
const magic_bytes_js_1 = require("magic-bytes.js");
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
|
-
const promises_1 = require("node:timers/promises");
|
|
7
|
-
const node_worker_threads_1 = require("node:worker_threads");
|
|
8
6
|
const common_1 = require("../common");
|
|
9
7
|
const functions_1 = require("../structures/extra/functions");
|
|
10
8
|
const Router_1 = require("./Router");
|
|
11
9
|
const bucket_1 = require("./bucket");
|
|
12
10
|
const shared_1 = require("./shared");
|
|
13
11
|
const utils_1 = require("./utils/utils");
|
|
12
|
+
let parentPort;
|
|
13
|
+
let workerData;
|
|
14
14
|
class ApiHandler {
|
|
15
15
|
options;
|
|
16
16
|
globalBlock = false;
|
|
@@ -32,10 +32,16 @@ class ApiHandler {
|
|
|
32
32
|
name: '[API]',
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
const worker_threads = (0, common_1.lazyLoadPackage)('node:worker_threads');
|
|
36
|
+
if (options.workerProxy && !worker_threads?.parentPort)
|
|
36
37
|
throw new Error('Cannot use workerProxy without a parent.');
|
|
37
38
|
if (options.workerProxy)
|
|
38
39
|
this.workerPromises = new Map();
|
|
40
|
+
if (worker_threads) {
|
|
41
|
+
workerData = worker_threads.workerData;
|
|
42
|
+
if (worker_threads.parentPort)
|
|
43
|
+
parentPort = worker_threads.parentPort;
|
|
44
|
+
}
|
|
39
45
|
}
|
|
40
46
|
globalUnblock() {
|
|
41
47
|
this.globalBlock = false;
|
|
@@ -53,11 +59,11 @@ class ApiHandler {
|
|
|
53
59
|
async request(method, url, { auth = true, ...request } = {}) {
|
|
54
60
|
if (this.options.workerProxy) {
|
|
55
61
|
const nonce = this.#randomUUID();
|
|
56
|
-
|
|
62
|
+
parentPort.postMessage({
|
|
57
63
|
method,
|
|
58
64
|
url,
|
|
59
65
|
type: 'WORKER_API_REQUEST',
|
|
60
|
-
workerId:
|
|
66
|
+
workerId: workerData.workerId,
|
|
61
67
|
nonce,
|
|
62
68
|
requestOptions: { auth, ...request },
|
|
63
69
|
}, request.files
|
|
@@ -182,7 +188,7 @@ class ApiHandler {
|
|
|
182
188
|
const wait = Math.floor(Math.random() * 1900 + 100);
|
|
183
189
|
this.debugger?.warn(`Handling a 50X status, retrying in ${wait}ms`);
|
|
184
190
|
next();
|
|
185
|
-
await (0,
|
|
191
|
+
await (0, common_1.delay)(wait);
|
|
186
192
|
return this.request(method, url, {
|
|
187
193
|
body: request.body,
|
|
188
194
|
auth: request.auth,
|
|
@@ -204,7 +210,7 @@ class ApiHandler {
|
|
|
204
210
|
}
|
|
205
211
|
this.debugger?.info(`${response.headers.get('x-ratelimit-global') ? 'Global' : 'Unexpected'} 429: ${result}\n${content} ${now} ${route} ${response.status}: ${this.ratelimits.get(route).remaining}/${this.ratelimits.get(route).limit} left | Reset ${retryAfter} (${this.ratelimits.get(route).reset - now}ms left) | Scope ${response.headers.get('x-ratelimit-scope')}`);
|
|
206
212
|
if (retryAfter) {
|
|
207
|
-
await (0,
|
|
213
|
+
await (0, common_1.delay)(retryAfter);
|
|
208
214
|
next();
|
|
209
215
|
return this.request(method, url, {
|
|
210
216
|
body: request.body,
|
|
@@ -94,10 +94,7 @@ export declare function resolveFiles(resources: (AttachmentBuilder | RawFile | A
|
|
|
94
94
|
*/
|
|
95
95
|
export declare function resolveAttachmentData(data: AttachmentResolvable, type: AttachmentDataType): Promise<{
|
|
96
96
|
data: AttachmentResolvable;
|
|
97
|
-
contentType?:
|
|
98
|
-
} | {
|
|
99
|
-
data: Buffer;
|
|
100
|
-
contentType: string | null;
|
|
97
|
+
contentType?: string | null;
|
|
101
98
|
}>;
|
|
102
99
|
/**
|
|
103
100
|
* Resolves a base64 data to a data URL.
|
|
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.resolveImage = exports.resolveBase64 = exports.resolveAttachmentData = exports.resolveFiles = exports.resolveAttachment = exports.AttachmentBuilder = exports.Attachment = void 0;
|
|
7
7
|
const node_crypto_1 = require("node:crypto");
|
|
8
|
-
const promises_1 = require("node:fs/promises");
|
|
9
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
9
|
const __1 = require("..");
|
|
11
10
|
const Base_1 = require("../structures/extra/Base");
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
12
|
class Attachment extends Base_1.Base {
|
|
13
13
|
data;
|
|
14
14
|
constructor(client, data) {
|
|
@@ -24,7 +24,7 @@ class AttachmentBuilder {
|
|
|
24
24
|
* Creates a new Attachment instance.
|
|
25
25
|
* @param data - The partial attachment data.
|
|
26
26
|
*/
|
|
27
|
-
constructor(data = { name: `${(0, node_crypto_1.randomBytes)(8)
|
|
27
|
+
constructor(data = { name: `${((0, node_crypto_1.randomBytes)?.(8))?.toString('base64url') || 'default'}.jpg` }) {
|
|
28
28
|
this.data = data;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
@@ -163,10 +163,10 @@ async function resolveAttachmentData(data, type) {
|
|
|
163
163
|
}
|
|
164
164
|
case 'path': {
|
|
165
165
|
const file = node_path_1.default.resolve(data);
|
|
166
|
-
const stats = await
|
|
166
|
+
const stats = await node_fs_1.promises.stat(file);
|
|
167
167
|
if (!stats.isFile())
|
|
168
168
|
return (0, __1.throwError)(`The attachment type has been expressed as ${type.toUpperCase()} but cannot be resolved as one.`);
|
|
169
|
-
return { data: await
|
|
169
|
+
return { data: await node_fs_1.promises.readFile(file) };
|
|
170
170
|
}
|
|
171
171
|
case 'buffer': {
|
|
172
172
|
if (Buffer.isBuffer(data))
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkerAdapter = void 0;
|
|
4
4
|
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const
|
|
5
|
+
const common_1 = require("../../common");
|
|
6
|
+
let parentPort;
|
|
6
7
|
class WorkerAdapter {
|
|
7
8
|
workerData;
|
|
8
9
|
isAsync = true;
|
|
9
10
|
promises = new Map();
|
|
10
11
|
constructor(workerData) {
|
|
11
12
|
this.workerData = workerData;
|
|
13
|
+
const worker_threads = (0, common_1.lazyLoadPackage)('node:worker_threads');
|
|
14
|
+
if (worker_threads?.parentPort)
|
|
15
|
+
parentPort = worker_threads.parentPort;
|
|
12
16
|
}
|
|
13
17
|
postMessage(body) {
|
|
14
|
-
if (
|
|
15
|
-
return
|
|
18
|
+
if (parentPort)
|
|
19
|
+
return parentPort.postMessage(body);
|
|
16
20
|
return process.send(body);
|
|
17
21
|
}
|
|
18
22
|
send(method, ...args) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { GatewayIntentBits } from 'discord-api-types/v10';
|
|
2
|
-
import type { BaseClient } from '../../../client/base';
|
|
3
2
|
import type { UsingClient } from '../../../commands';
|
|
4
3
|
import type { Cache, ReturnCache } from '../../index';
|
|
5
4
|
export declare class BaseResource<T = any> {
|
|
6
5
|
protected cache: Cache;
|
|
7
|
-
client:
|
|
6
|
+
client: UsingClient;
|
|
8
7
|
namespace: string;
|
|
9
8
|
constructor(cache: Cache, client?: UsingClient);
|
|
10
9
|
filter(data: any, id: string): boolean;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { GatewayIntentBits } from 'discord-api-types/v10';
|
|
2
|
-
import type { BaseClient } from '../../../client/base';
|
|
3
2
|
import type { UsingClient } from '../../../commands';
|
|
4
3
|
import type { Cache, ReturnCache } from '../../index';
|
|
5
4
|
export declare class GuildBasedResource<T = any> {
|
|
6
5
|
protected cache: Cache;
|
|
7
|
-
client:
|
|
6
|
+
client: UsingClient;
|
|
8
7
|
namespace: string;
|
|
9
8
|
constructor(cache: Cache, client?: UsingClient);
|
|
10
9
|
filter(data: any, id: string, guild_id: string): boolean;
|
package/lib/client/base.d.ts
CHANGED
|
@@ -5,11 +5,12 @@ import type { Command, RegisteredMiddlewares } from '../commands';
|
|
|
5
5
|
import { type InferWithPrefix, type MiddlewareContext } from '../commands/applications/shared';
|
|
6
6
|
import { CommandHandler } from '../commands/handler';
|
|
7
7
|
import { ChannelShorter, EmojiShorter, GuildShorter, InteractionShorter, Logger, MemberShorter, MessageShorter, ReactionShorter, RoleShorter, TemplateShorter, ThreadShorter, UsersShorter, WebhookShorter, type MakeRequired } from '../common';
|
|
8
|
-
import type { LocaleString } from 'discord-api-types/rest/v10';
|
|
8
|
+
import type { LocaleString, RESTPostAPIChannelMessageJSONBody } from 'discord-api-types/rest/v10';
|
|
9
9
|
import type { DeepPartial, IntentStrings, OmitInsert, When } from '../common/types/util';
|
|
10
10
|
import { ComponentHandler } from '../components/handler';
|
|
11
11
|
import { LangsHandler } from '../langs/handler';
|
|
12
|
-
import type { ChatInputCommandInteraction, ComponentInteraction, Message, MessageCommandInteraction, UserCommandInteraction } from '../structures';
|
|
12
|
+
import type { ChatInputCommandInteraction, ComponentInteraction, Message, MessageCommandInteraction, ModalSubmitInteraction, UserCommandInteraction } from '../structures';
|
|
13
|
+
import type { ComponentCommand, ModalCommand } from '../components';
|
|
13
14
|
export declare class BaseClient {
|
|
14
15
|
rest: ApiHandler;
|
|
15
16
|
cache: Cache;
|
|
@@ -35,7 +36,7 @@ export declare class BaseClient {
|
|
|
35
36
|
middlewares?: Record<string, MiddlewareContext>;
|
|
36
37
|
protected static assertString(value: unknown, message?: string): asserts value is string;
|
|
37
38
|
protected static getBotIdFromToken(token: string): string;
|
|
38
|
-
options: BaseClientOptions
|
|
39
|
+
options: BaseClientOptions;
|
|
39
40
|
constructor(options?: BaseClientOptions);
|
|
40
41
|
set botId(id: string);
|
|
41
42
|
get botId(): string;
|
|
@@ -46,6 +47,7 @@ export declare class BaseClient {
|
|
|
46
47
|
protected execute(..._options: unknown[]): Promise<void>;
|
|
47
48
|
start(options?: Pick<DeepPartial<StartOptions>, 'langsDir' | 'commandsDir' | 'connection' | 'token' | 'componentsDir'>): Promise<void>;
|
|
48
49
|
protected onPacket(..._packet: unknown[]): Promise<void>;
|
|
50
|
+
shouldUploadCommands(cachePath: string): Promise<boolean>;
|
|
49
51
|
uploadCommands(applicationId?: string): Promise<void>;
|
|
50
52
|
loadCommands(dir?: string): Promise<void>;
|
|
51
53
|
loadComponents(dir?: string): Promise<void>;
|
|
@@ -66,7 +68,7 @@ export declare class BaseClient {
|
|
|
66
68
|
}>;
|
|
67
69
|
}
|
|
68
70
|
export interface BaseClientOptions {
|
|
69
|
-
context?: (interaction: ChatInputCommandInteraction<boolean> | UserCommandInteraction<boolean> | MessageCommandInteraction<boolean> | ComponentInteraction | When<InferWithPrefix, Message, never>) => {};
|
|
71
|
+
context?: (interaction: ChatInputCommandInteraction<boolean> | UserCommandInteraction<boolean> | MessageCommandInteraction<boolean> | ComponentInteraction | ModalSubmitInteraction | When<InferWithPrefix, Message, never>) => {};
|
|
70
72
|
globalMiddlewares?: readonly (keyof RegisteredMiddlewares)[];
|
|
71
73
|
commands?: {
|
|
72
74
|
defaults?: {
|
|
@@ -79,6 +81,25 @@ export interface BaseClientOptions {
|
|
|
79
81
|
onAfterRun?: Command['onAfterRun'];
|
|
80
82
|
};
|
|
81
83
|
};
|
|
84
|
+
components?: {
|
|
85
|
+
defaults?: {
|
|
86
|
+
onRunError?: ComponentCommand['onRunError'];
|
|
87
|
+
onInternalError?: ComponentCommand['onInternalError'];
|
|
88
|
+
onMiddlewaresError?: ComponentCommand['onMiddlewaresError'];
|
|
89
|
+
onAfterRun?: ComponentCommand['onAfterRun'];
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
modals?: {
|
|
93
|
+
defaults?: {
|
|
94
|
+
onRunError?: ModalCommand['onRunError'];
|
|
95
|
+
onInternalError?: ModalCommand['onInternalError'];
|
|
96
|
+
onMiddlewaresError?: ModalCommand['onMiddlewaresError'];
|
|
97
|
+
onAfterRun?: ModalCommand['onAfterRun'];
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
allowedMentions?: Omit<NonNullable<RESTPostAPIChannelMessageJSONBody['allowed_mentions']>, 'parse'> & {
|
|
101
|
+
parse?: ('everyone' | 'roles' | 'users')[];
|
|
102
|
+
};
|
|
82
103
|
}
|
|
83
104
|
export interface StartOptions {
|
|
84
105
|
eventsDir: string;
|
|
@@ -91,6 +112,7 @@ export interface StartOptions {
|
|
|
91
112
|
httpConnection: {
|
|
92
113
|
publicKey: string;
|
|
93
114
|
port: number;
|
|
115
|
+
useUWS: boolean;
|
|
94
116
|
};
|
|
95
117
|
token: string;
|
|
96
118
|
}
|
package/lib/client/base.js
CHANGED
|
@@ -9,6 +9,7 @@ const handler_1 = require("../commands/handler");
|
|
|
9
9
|
const common_1 = require("../common");
|
|
10
10
|
const handler_2 = require("../components/handler");
|
|
11
11
|
const handler_3 = require("../langs/handler");
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
12
13
|
class BaseClient {
|
|
13
14
|
rest;
|
|
14
15
|
cache;
|
|
@@ -43,6 +44,8 @@ class BaseClient {
|
|
|
43
44
|
return Buffer.from(token.split('.')[0], 'base64').toString('ascii');
|
|
44
45
|
}
|
|
45
46
|
options;
|
|
47
|
+
/**@internal */
|
|
48
|
+
static _seyferHttpConfig;
|
|
46
49
|
constructor(options) {
|
|
47
50
|
this.options = (0, common_1.MergeOptions)({
|
|
48
51
|
commands: {
|
|
@@ -67,6 +70,32 @@ class BaseClient {
|
|
|
67
70
|
},
|
|
68
71
|
},
|
|
69
72
|
},
|
|
73
|
+
components: {
|
|
74
|
+
defaults: {
|
|
75
|
+
onRunError(context, error) {
|
|
76
|
+
context.client.logger.fatal('ComponentCommand.<onRunError>', context.author.id, error);
|
|
77
|
+
},
|
|
78
|
+
onMiddlewaresError(context, error) {
|
|
79
|
+
context.client.logger.fatal('ComponentCommand.<onMiddlewaresError>', context.author.id, error);
|
|
80
|
+
},
|
|
81
|
+
onInternalError(client, error) {
|
|
82
|
+
client.logger.fatal(error);
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
modals: {
|
|
87
|
+
defaults: {
|
|
88
|
+
onRunError(context, error) {
|
|
89
|
+
context.client.logger.fatal('ComponentCommand.<onRunError>', context.author.id, error);
|
|
90
|
+
},
|
|
91
|
+
onMiddlewaresError(context, error) {
|
|
92
|
+
context.client.logger.fatal('ComponentCommand.<onMiddlewaresError>', context.author.id, error);
|
|
93
|
+
},
|
|
94
|
+
onInternalError(client, error) {
|
|
95
|
+
client.logger.fatal(error);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
70
99
|
}, options);
|
|
71
100
|
}
|
|
72
101
|
set botId(id) {
|
|
@@ -178,6 +207,13 @@ class BaseClient {
|
|
|
178
207
|
async onPacket(..._packet) {
|
|
179
208
|
throw new Error('Function not implemented');
|
|
180
209
|
}
|
|
210
|
+
shouldUploadCommands(cachePath) {
|
|
211
|
+
return this.commands.shouldUpload(cachePath).then(async (should) => {
|
|
212
|
+
if (should)
|
|
213
|
+
await node_fs_1.promises.writeFile(cachePath, JSON.stringify(this.commands.values.map(x => x.toJSON())));
|
|
214
|
+
return should;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
181
217
|
async uploadCommands(applicationId) {
|
|
182
218
|
applicationId ??= await this.getRC().then(x => x.applicationId ?? this.applicationId);
|
|
183
219
|
BaseClient.assertString(applicationId, 'applicationId is not a string');
|
|
@@ -228,8 +264,10 @@ class BaseClient {
|
|
|
228
264
|
return this.langs.get(locale);
|
|
229
265
|
}
|
|
230
266
|
async getRC() {
|
|
231
|
-
const
|
|
232
|
-
|
|
267
|
+
const seyfertConfig = (BaseClient._seyferHttpConfig ||
|
|
268
|
+
(await (0, common_1.magicImport)((0, node_path_1.join)(process.cwd(), 'seyfert.config.js')).then(x => x.default ?? x)));
|
|
269
|
+
const { locations, debug, ...env } = seyfertConfig;
|
|
270
|
+
const obj = {
|
|
233
271
|
debug: !!debug,
|
|
234
272
|
...env,
|
|
235
273
|
templates: locations.templates ? (0, node_path_1.join)(process.cwd(), locations.base, locations.templates) : undefined,
|
|
@@ -240,6 +278,8 @@ class BaseClient {
|
|
|
240
278
|
base: (0, node_path_1.join)(process.cwd(), locations.base),
|
|
241
279
|
output: (0, node_path_1.join)(process.cwd(), locations.output),
|
|
242
280
|
};
|
|
281
|
+
BaseClient._seyferHttpConfig = seyfertConfig;
|
|
282
|
+
return obj;
|
|
243
283
|
}
|
|
244
284
|
}
|
|
245
285
|
exports.BaseClient = BaseClient;
|
package/lib/client/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type GatewayDispatchPayload, type GatewayPresenceUpdateData } from 'discord-api-types/v10';
|
|
2
2
|
import type { Command, CommandContext, Message, SubCommand } from '..';
|
|
3
|
-
import type
|
|
3
|
+
import { type DeepPartial, type If } from '../common';
|
|
4
4
|
import { EventHandler } from '../events';
|
|
5
5
|
import { ClientUser } from '../structures';
|
|
6
6
|
import { ShardManager, type ShardManagerOptions } from '../websocket';
|
|
@@ -13,7 +13,7 @@ export declare class Client<Ready extends boolean = boolean> extends BaseClient
|
|
|
13
13
|
gateway: ShardManager;
|
|
14
14
|
events?: EventHandler | undefined;
|
|
15
15
|
me: If<Ready, ClientUser>;
|
|
16
|
-
options: ClientOptions
|
|
16
|
+
options: ClientOptions;
|
|
17
17
|
memberUpdateHandler: MemberUpdateHandler;
|
|
18
18
|
presenceUpdateHandler: PresenceUpdateHandler;
|
|
19
19
|
constructor(options?: ClientOptions);
|
|
@@ -46,7 +46,7 @@ export interface ClientOptions extends BaseClientOptions {
|
|
|
46
46
|
prefix?: (message: Message) => Promise<string[]> | string[];
|
|
47
47
|
deferReplyResponse?: (ctx: CommandContext) => Parameters<Message['write']>[0];
|
|
48
48
|
reply?: (ctx: CommandContext) => boolean;
|
|
49
|
-
argsParser?: (content: string, command: SubCommand | Command) => Record<string, string>;
|
|
49
|
+
argsParser?: (content: string, command: SubCommand | Command, message: Message) => Record<string, string>;
|
|
50
50
|
};
|
|
51
51
|
handlePayload?: ShardManagerOptions['handlePayload'];
|
|
52
52
|
}
|
package/lib/client/client.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Client = void 0;
|
|
4
4
|
const v10_1 = require("discord-api-types/v10");
|
|
5
|
-
const
|
|
5
|
+
const common_1 = require("../common");
|
|
6
6
|
const events_1 = require("../events");
|
|
7
7
|
const structures_1 = require("../structures");
|
|
8
8
|
const websocket_1 = require("../websocket");
|
|
@@ -11,6 +11,7 @@ const presenceUpdate_1 = require("../websocket/discord/events/presenceUpdate");
|
|
|
11
11
|
const base_1 = require("./base");
|
|
12
12
|
const oninteractioncreate_1 = require("./oninteractioncreate");
|
|
13
13
|
const onmessagecreate_1 = require("./onmessagecreate");
|
|
14
|
+
let parentPort;
|
|
14
15
|
class Client extends base_1.BaseClient {
|
|
15
16
|
__handleGuilds = new Set();
|
|
16
17
|
gateway;
|
|
@@ -56,11 +57,15 @@ class Client extends base_1.BaseClient {
|
|
|
56
57
|
}
|
|
57
58
|
async execute(options = {}) {
|
|
58
59
|
await super.execute(options);
|
|
59
|
-
|
|
60
|
+
const worker_threads = (0, common_1.lazyLoadPackage)('node:worker_threads');
|
|
61
|
+
if (worker_threads?.parentPort) {
|
|
62
|
+
parentPort = worker_threads.parentPort;
|
|
63
|
+
}
|
|
64
|
+
if (!worker_threads?.workerData?.__USING_WATCHER__) {
|
|
60
65
|
await this.gateway.spawnShards();
|
|
61
66
|
}
|
|
62
67
|
else {
|
|
63
|
-
|
|
68
|
+
parentPort?.on('message', (data) => {
|
|
64
69
|
switch (data.type) {
|
|
65
70
|
case 'PAYLOAD':
|
|
66
71
|
this.gateway.options.handlePayload(data.shardId, data.payload);
|
|
@@ -126,12 +131,19 @@ class Client extends base_1.BaseClient {
|
|
|
126
131
|
case 'MESSAGE_UPDATE':
|
|
127
132
|
case 'MESSAGE_DELETE_BULK':
|
|
128
133
|
case 'MESSAGE_DELETE':
|
|
129
|
-
await this.events?.execute(packet.t, packet, this, shardId);
|
|
130
|
-
await this.cache.onPacket(packet);
|
|
131
|
-
break;
|
|
132
134
|
case 'GUILD_DELETE':
|
|
133
135
|
case 'CHANNEL_UPDATE':
|
|
136
|
+
case 'GUILD_EMOJIS_UPDATE':
|
|
137
|
+
case 'GUILD_UPDATE':
|
|
138
|
+
case 'GUILD_ROLE_UPDATE':
|
|
139
|
+
case 'GUILD_ROLE_DELETE':
|
|
140
|
+
case 'THREAD_UPDATE':
|
|
141
|
+
case 'USER_UPDATE':
|
|
142
|
+
case 'VOICE_STATE_UPDATE':
|
|
143
|
+
case 'STAGE_INSTANCE_UPDATE':
|
|
144
|
+
case 'GUILD_STICKERS_UPDATE':
|
|
134
145
|
await this.events?.execute(packet.t, packet, this, shardId);
|
|
146
|
+
await this.cache.onPacket(packet);
|
|
135
147
|
break;
|
|
136
148
|
//rest of the events
|
|
137
149
|
default: {
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { type APIInteraction } from 'discord-api-types/v10';
|
|
3
3
|
import type { HttpRequest, HttpResponse } from 'uWebSockets.js';
|
|
4
|
-
import type
|
|
4
|
+
import { type DeepPartial } from '../common';
|
|
5
5
|
import type { BaseClientOptions, StartOptions } from './base';
|
|
6
6
|
import { BaseClient } from './base';
|
|
7
7
|
export declare class HttpClient extends BaseClient {
|
|
8
|
-
app
|
|
8
|
+
app?: ReturnType<typeof import('uWebSockets.js').App>;
|
|
9
9
|
publicKey: string;
|
|
10
10
|
publicKeyHex: Buffer;
|
|
11
11
|
constructor(options?: BaseClientOptions);
|
|
12
12
|
protected static readJson<T extends Record<string, any>>(res: HttpResponse): Promise<T>;
|
|
13
|
-
protected execute(options
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}): Promise<void>;
|
|
17
|
-
start(options?: DeepPartial<Omit<StartOptions, 'connection'>>): Promise<void>;
|
|
13
|
+
protected execute(options: DeepPartial<StartOptions['httpConnection']>): Promise<void>;
|
|
14
|
+
start(options?: DeepPartial<Omit<StartOptions, 'connection' | 'eventsDir'>>): Promise<void>;
|
|
15
|
+
protected verifySignatureGenericRequest(req: Request): Promise<APIInteraction | undefined>;
|
|
18
16
|
protected verifySignature(res: HttpResponse, req: HttpRequest): Promise<APIInteraction | undefined>;
|
|
19
|
-
|
|
17
|
+
fetch(req: Request): Promise<Response>;
|
|
18
|
+
protected onPacket(res: HttpResponse, req: HttpRequest): Promise<void>;
|
|
20
19
|
}
|
package/lib/client/httpclient.js
CHANGED
|
@@ -5,6 +5,7 @@ const v10_1 = require("discord-api-types/v10");
|
|
|
5
5
|
const magic_bytes_js_1 = require("magic-bytes.js");
|
|
6
6
|
const api_1 = require("../api");
|
|
7
7
|
const utils_1 = require("../api/utils/utils");
|
|
8
|
+
const common_1 = require("../common");
|
|
8
9
|
const base_1 = require("./base");
|
|
9
10
|
const oninteractioncreate_1 = require("./oninteractioncreate");
|
|
10
11
|
let UWS;
|
|
@@ -27,9 +28,9 @@ class HttpClient extends base_1.BaseClient {
|
|
|
27
28
|
publicKeyHex;
|
|
28
29
|
constructor(options) {
|
|
29
30
|
super(options);
|
|
30
|
-
if (!UWS) {
|
|
31
|
-
|
|
32
|
-
}
|
|
31
|
+
// if (!UWS) {
|
|
32
|
+
// throw new Error('No uws installed.');
|
|
33
|
+
// }
|
|
33
34
|
if (!nacl) {
|
|
34
35
|
throw new Error('No tweetnacl installed.');
|
|
35
36
|
}
|
|
@@ -60,8 +61,8 @@ class HttpClient extends base_1.BaseClient {
|
|
|
60
61
|
async execute(options) {
|
|
61
62
|
await super.execute();
|
|
62
63
|
const { publicKey: publicKeyRC, port: portRC, applicationId: applicationIdRC, } = await this.getRC();
|
|
63
|
-
const publicKey = options
|
|
64
|
-
const port = options
|
|
64
|
+
const publicKey = options.publicKey ?? publicKeyRC;
|
|
65
|
+
const port = options.port ?? portRC;
|
|
65
66
|
if (!publicKey) {
|
|
66
67
|
throw new Error('Expected a publicKey, check your config file');
|
|
67
68
|
}
|
|
@@ -73,17 +74,33 @@ class HttpClient extends base_1.BaseClient {
|
|
|
73
74
|
}
|
|
74
75
|
this.publicKey = publicKey;
|
|
75
76
|
this.publicKeyHex = Buffer.from(this.publicKey, 'hex');
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.
|
|
82
|
-
|
|
77
|
+
if (UWS && options.useUWS) {
|
|
78
|
+
this.app = UWS.App();
|
|
79
|
+
this.app.post('/interactions', (res, req) => {
|
|
80
|
+
return this.onPacket(res, req);
|
|
81
|
+
});
|
|
82
|
+
this.app.listen(port, () => {
|
|
83
|
+
this.logger.info(`Listening to <url>:${port}/interactions`);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
if (options.useUWS)
|
|
88
|
+
return this.logger.warn('No uWebSockets installed.');
|
|
89
|
+
this.logger.info('Use your preferred http server and invoke <HttpClient>.fetch(<Request>) to get started');
|
|
90
|
+
}
|
|
83
91
|
}
|
|
84
92
|
async start(options = {}) {
|
|
85
93
|
await super.start(options);
|
|
86
|
-
return this.execute(options.httpConnection);
|
|
94
|
+
return this.execute((0, common_1.MergeOptions)({ useUWS: true }, options.httpConnection));
|
|
95
|
+
}
|
|
96
|
+
async verifySignatureGenericRequest(req) {
|
|
97
|
+
const timestamp = req.headers.get('x-signature-timestamp');
|
|
98
|
+
const ed25519 = req.headers.get('x-signature-ed25519') ?? '';
|
|
99
|
+
const body = (await req.json());
|
|
100
|
+
if (nacl.sign.detached.verify(Buffer.from(timestamp + JSON.stringify(body)), Buffer.from(ed25519, 'hex'), this.publicKeyHex)) {
|
|
101
|
+
return body;
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
87
104
|
}
|
|
88
105
|
// https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
|
|
89
106
|
async verifySignature(res, req) {
|
|
@@ -95,6 +112,68 @@ class HttpClient extends base_1.BaseClient {
|
|
|
95
112
|
}
|
|
96
113
|
return;
|
|
97
114
|
}
|
|
115
|
+
async fetch(req) {
|
|
116
|
+
const rawBody = await this.verifySignatureGenericRequest(req);
|
|
117
|
+
if (!rawBody) {
|
|
118
|
+
this.debugger?.debug('Invalid request/No info, returning 418 status.');
|
|
119
|
+
// I'm a teapot
|
|
120
|
+
return new Response('', { status: 418 });
|
|
121
|
+
}
|
|
122
|
+
switch (rawBody.type) {
|
|
123
|
+
case v10_1.InteractionType.Ping:
|
|
124
|
+
this.debugger?.debug('Ping interaction received, responding.');
|
|
125
|
+
return Response.json({ type: v10_1.InteractionResponseType.Pong }, {
|
|
126
|
+
headers: {
|
|
127
|
+
'Content-Type': 'application/json',
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
default:
|
|
131
|
+
return new Promise(r => {
|
|
132
|
+
if ((0, common_1.isCloudfareWorker)())
|
|
133
|
+
return (0, oninteractioncreate_1.onInteractionCreate)(this, rawBody, -1)
|
|
134
|
+
.then(() => r(new Response()))
|
|
135
|
+
.catch(() => r(new Response()));
|
|
136
|
+
return (0, oninteractioncreate_1.onInteractionCreate)(this, rawBody, -1, async ({ body, files }) => {
|
|
137
|
+
let response;
|
|
138
|
+
const headers = {};
|
|
139
|
+
if (files) {
|
|
140
|
+
response = new FormData();
|
|
141
|
+
for (const [index, file] of files.entries()) {
|
|
142
|
+
const fileKey = file.key ?? `files[${index}]`;
|
|
143
|
+
if ((0, utils_1.isBufferLike)(file.data)) {
|
|
144
|
+
let contentType = file.contentType;
|
|
145
|
+
if (!contentType) {
|
|
146
|
+
const [parsedType] = (0, magic_bytes_js_1.filetypeinfo)(file.data);
|
|
147
|
+
if (parsedType) {
|
|
148
|
+
contentType =
|
|
149
|
+
api_1.OverwrittenMimeTypes[parsedType.mime] ??
|
|
150
|
+
parsedType.mime ??
|
|
151
|
+
'application/octet-stream';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
response.append(fileKey, new Blob([file.data], { type: contentType }), file.name);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
response.append(fileKey, new Blob([`${file.data}`], { type: file.contentType }), file.name);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (body) {
|
|
161
|
+
response.append('payload_json', JSON.stringify(body));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
response = body ?? {};
|
|
166
|
+
headers['Content-Type'] = 'application/json';
|
|
167
|
+
}
|
|
168
|
+
r(response instanceof FormData
|
|
169
|
+
? new Response(response, { headers })
|
|
170
|
+
: Response.json(response, {
|
|
171
|
+
headers,
|
|
172
|
+
}));
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
98
177
|
async onPacket(res, req) {
|
|
99
178
|
const rawBody = await this.verifySignature(res, req);
|
|
100
179
|
if (!rawBody) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type APIInteraction } from 'discord-api-types/v10';
|
|
2
|
+
import { type UsingClient } from '../commands';
|
|
2
3
|
import type { __InternalReplyFunction } from '../structures';
|
|
3
|
-
|
|
4
|
-
export declare function onInteractionCreate(self: BaseClient, body: APIInteraction, shardId: number, __reply?: __InternalReplyFunction): Promise<any>;
|
|
4
|
+
export declare function onInteractionCreate(self: UsingClient, body: APIInteraction, shardId: number, __reply?: __InternalReplyFunction): Promise<any>;
|