seyfert 4.4.0 → 5.0.1-dev-27861043347.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/Routes/cdn.d.ts +1 -1
- package/lib/api/Routes/guilds.d.ts +2 -2
- package/lib/api/api.d.ts +16 -4
- package/lib/api/api.js +153 -30
- package/lib/api/shared.d.ts +30 -1
- package/lib/api/utils/constants.d.ts +1 -1
- package/lib/api/utils/constants.js +1 -1
- package/lib/api/utils/utils.d.ts +2 -1
- package/lib/api/utils/utils.js +1 -1
- package/lib/builders/MediaGallery.d.ts +1 -1
- package/lib/builders/MediaGallery.js +10 -0
- package/lib/builders/Modal.d.ts +18 -8
- package/lib/builders/Modal.js +36 -7
- package/lib/builders/Poll.js +18 -0
- package/lib/builders/RadioGroup.d.ts +4 -3
- package/lib/builders/RadioGroup.js +24 -3
- package/lib/builders/SelectMenu.d.ts +8 -6
- package/lib/builders/SelectMenu.js +24 -3
- package/lib/builders/types.d.ts +3 -2
- package/lib/cache/adapters/limited.js +1 -1
- package/lib/cache/index.d.ts +16 -22
- package/lib/cache/index.js +38 -2
- package/lib/cache/resources/bans.d.ts +1 -1
- package/lib/cache/resources/channels.d.ts +1 -1
- package/lib/cache/resources/default/base.js +1 -1
- package/lib/cache/resources/default/guild-based.d.ts +4 -4
- package/lib/cache/resources/default/guild-based.js +1 -1
- package/lib/cache/resources/default/guild-related.d.ts +4 -4
- package/lib/cache/resources/default/guild-related.js +1 -1
- package/lib/cache/resources/emojis.d.ts +1 -1
- package/lib/cache/resources/members.d.ts +1 -1
- package/lib/cache/resources/messages.d.ts +2 -2
- package/lib/cache/resources/overwrites.d.ts +1 -1
- package/lib/cache/resources/roles.d.ts +1 -1
- package/lib/cache/resources/stickers.d.ts +1 -1
- package/lib/cache/resources/voice-states.d.ts +1 -1
- package/lib/client/base.d.ts +77 -21
- package/lib/client/base.js +583 -34
- package/lib/client/client.d.ts +26 -3
- package/lib/client/client.js +33 -9
- package/lib/client/collectors.d.ts +9 -8
- package/lib/client/collectors.js +16 -43
- package/lib/client/httpclient.d.ts +3 -0
- package/lib/client/index.d.ts +3 -1
- package/lib/client/index.js +4 -0
- package/lib/client/intents.d.ts +3 -0
- package/lib/client/intents.js +9 -0
- package/lib/client/plugins/api.d.ts +4 -0
- package/lib/client/plugins/api.js +550 -0
- package/lib/client/plugins/errors.d.ts +25 -0
- package/lib/client/plugins/errors.js +79 -0
- package/lib/client/plugins/order.d.ts +10 -0
- package/lib/client/plugins/order.js +32 -0
- package/lib/client/plugins/registry.d.ts +273 -0
- package/lib/client/plugins/registry.js +868 -0
- package/lib/client/plugins/shared.d.ts +23 -0
- package/lib/client/plugins/shared.js +193 -0
- package/lib/client/plugins/types.d.ts +402 -0
- package/lib/client/plugins/types.js +8 -0
- package/lib/client/plugins.d.ts +78 -0
- package/lib/client/plugins.js +558 -0
- package/lib/client/workerclient.d.ts +10 -1
- package/lib/client/workerclient.js +21 -13
- package/lib/collection.d.ts +10 -8
- package/lib/collection.js +19 -25
- package/lib/commands/applications/chat.d.ts +18 -16
- package/lib/commands/applications/chat.js +56 -6
- package/lib/commands/applications/chatcontext.d.ts +23 -13
- package/lib/commands/applications/chatcontext.js +23 -2
- package/lib/commands/applications/entryPoint.d.ts +4 -3
- package/lib/commands/applications/entryPoint.js +1 -1
- package/lib/commands/applications/entrycontext.d.ts +7 -7
- package/lib/commands/applications/entrycontext.js +3 -1
- package/lib/commands/applications/menu.d.ts +4 -3
- package/lib/commands/applications/menucontext.d.ts +7 -7
- package/lib/commands/applications/menucontext.js +3 -1
- package/lib/commands/applications/options.d.ts +12 -12
- package/lib/commands/applications/shared.d.ts +31 -12
- package/lib/commands/decorators.d.ts +48 -36
- package/lib/commands/decorators.js +13 -3
- package/lib/commands/handle.d.ts +15 -4
- package/lib/commands/handle.js +224 -142
- package/lib/commands/handler.d.ts +21 -7
- package/lib/commands/handler.js +149 -62
- package/lib/commands/index.d.ts +1 -0
- package/lib/commands/optionresolver.d.ts +2 -2
- package/lib/common/it/error.d.ts +8 -0
- package/lib/common/it/error.js +7 -0
- package/lib/common/it/formatter.d.ts +14 -11
- package/lib/common/it/formatter.js +4 -3
- package/lib/common/it/logger.d.ts +6 -1
- package/lib/common/it/logger.js +17 -3
- package/lib/common/it/utils.d.ts +4 -4
- package/lib/common/it/utils.js +11 -5
- package/lib/common/shorters/application.d.ts +2 -2
- package/lib/common/shorters/bans.d.ts +7 -3
- package/lib/common/shorters/bans.js +12 -4
- package/lib/common/shorters/channels.d.ts +1 -1
- package/lib/common/shorters/channels.js +1 -1
- package/lib/common/shorters/interaction.d.ts +1 -1
- package/lib/common/shorters/members.d.ts +6 -6
- package/lib/common/shorters/members.js +7 -7
- package/lib/common/shorters/messages.d.ts +1 -1
- package/lib/common/shorters/users.d.ts +1 -1
- package/lib/common/shorters/webhook.d.ts +3 -2
- package/lib/common/shorters/webhook.js +0 -7
- package/lib/common/types/options.d.ts +4 -0
- package/lib/common/types/util.d.ts +8 -0
- package/lib/common/types/write.d.ts +2 -1
- package/lib/components/StringSelectMenuComponent.d.ts +1 -1
- package/lib/components/componentcommand.d.ts +8 -7
- package/lib/components/componentcontext.d.ts +21 -20
- package/lib/components/componentcontext.js +7 -2
- package/lib/components/handler.d.ts +18 -6
- package/lib/components/handler.js +102 -43
- package/lib/components/modalcommand.d.ts +5 -4
- package/lib/components/modalcontext.d.ts +35 -15
- package/lib/components/modalcontext.js +54 -1
- package/lib/events/event.d.ts +9 -3
- package/lib/events/handler.d.ts +51 -6
- package/lib/events/handler.js +163 -34
- package/lib/events/hooks/interactions.d.ts +1 -1
- package/lib/events/hooks/voice.d.ts +1 -2
- package/lib/events/hooks/voice.js +2 -1
- package/lib/events/utils.d.ts +4 -0
- package/lib/events/utils.js +59 -0
- package/lib/index.d.ts +9 -4
- package/lib/index.js +12 -7
- package/lib/langs/handler.d.ts +14 -9
- package/lib/langs/handler.js +45 -8
- package/lib/structures/Application.d.ts +1 -1
- package/lib/structures/Emoji.d.ts +2 -2
- package/lib/structures/Emoji.js +2 -2
- package/lib/structures/Guild.d.ts +3 -3
- package/lib/structures/GuildBan.d.ts +3 -3
- package/lib/structures/GuildBan.js +3 -3
- package/lib/structures/GuildMember.d.ts +8 -8
- package/lib/structures/GuildMember.js +28 -7
- package/lib/structures/GuildRole.d.ts +1 -1
- package/lib/structures/GuildRole.js +2 -2
- package/lib/structures/Interaction.d.ts +10 -8
- package/lib/structures/Interaction.js +28 -9
- package/lib/structures/Message.d.ts +10 -3
- package/lib/structures/Message.js +22 -10
- package/lib/structures/VoiceState.d.ts +4 -0
- package/lib/structures/VoiceState.js +12 -0
- package/lib/structures/Webhook.d.ts +9 -1
- package/lib/structures/Webhook.js +4 -1
- package/lib/structures/channels.d.ts +16 -9
- package/lib/structures/channels.js +22 -21
- package/lib/structures/extra/BitField.d.ts +2 -2
- package/lib/structures/extra/BitField.js +2 -1
- package/lib/structures/extra/DiscordBase.js +1 -1
- package/lib/structures/extra/Permissions.d.ts +2 -3
- package/lib/structures/extra/Permissions.js +6 -1
- package/lib/types/payloads/_interactions/responses.d.ts +2 -2
- package/lib/types/payloads/components.d.ts +4 -4
- package/lib/websocket/constants/index.js +2 -1
- package/lib/websocket/discord/shard.d.ts +2 -2
- package/lib/websocket/discord/sharder.d.ts +8 -7
- package/lib/websocket/discord/sharder.js +25 -5
- package/lib/websocket/discord/shared.d.ts +19 -6
- package/lib/websocket/discord/workermanager.d.ts +21 -7
- package/lib/websocket/discord/workermanager.js +28 -4
- package/package.json +5 -3
package/lib/api/Routes/cdn.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Identify, OmitInsert } from '../../common';
|
|
2
2
|
import type { APIThreadChannel, RESTDeleteAPIAutoModerationRuleResult, RESTDeleteAPIGuildBanResult, RESTDeleteAPIGuildEmojiResult, RESTDeleteAPIGuildIntegrationResult, RESTDeleteAPIGuildMemberResult, RESTDeleteAPIGuildMemberRoleResult, RESTDeleteAPIGuildResult, RESTDeleteAPIGuildRoleResult, RESTDeleteAPIGuildScheduledEventResult, RESTDeleteAPIGuildStickerResult, RESTDeleteAPIGuildTemplateResult, RESTGetAPIAuditLogQuery, RESTGetAPIAuditLogResult, RESTGetAPIAutoModerationRuleResult, RESTGetAPIAutoModerationRulesResult, RESTGetAPIGuildBanResult, RESTGetAPIGuildBansQuery, RESTGetAPIGuildBansResult, RESTGetAPIGuildChannelsResult, RESTGetAPIGuildEmojiResult, RESTGetAPIGuildEmojisResult, RESTGetAPIGuildIntegrationsResult, RESTGetAPIGuildInvitesResult, RESTGetAPIGuildMemberResult, RESTGetAPIGuildMembersQuery, RESTGetAPIGuildMembersResult, RESTGetAPIGuildMembersSearchQuery, RESTGetAPIGuildMembersSearchResult, RESTGetAPIGuildMessagesSearchQuery, RESTGetAPIGuildMessagesSearchResult, RESTGetAPIGuildPreviewResult, RESTGetAPIGuildPruneCountQuery, RESTGetAPIGuildPruneCountResult, RESTGetAPIGuildQuery, RESTGetAPIGuildResult, RESTGetAPIGuildRoleMemberCountsResult, RESTGetAPIGuildRoleResult, RESTGetAPIGuildRolesResult, RESTGetAPIGuildScheduledEventQuery, RESTGetAPIGuildScheduledEventResult, RESTGetAPIGuildScheduledEventsQuery, RESTGetAPIGuildScheduledEventsResult, RESTGetAPIGuildScheduledEventUsersQuery, RESTGetAPIGuildScheduledEventUsersResult, RESTGetAPIGuildSoundboardSoundsResult, RESTGetAPIGuildStickerResult, RESTGetAPIGuildStickersResult, RESTGetAPIGuildTemplatesResult, RESTGetAPIGuildThreadsResult, RESTGetAPIGuildVanityUrlResult, RESTGetAPIGuildVoiceRegionsResult, RESTGetAPIGuildVoiceStateCurrentMemberResult, RESTGetAPIGuildVoiceStateUserResult, RESTGetAPIGuildWebhooksResult, RESTGetAPIGuildWelcomeScreenResult, RESTGetAPIGuildWidgetImageQuery, RESTGetAPIGuildWidgetImageResult, RESTGetAPIGuildWidgetJSONResult, RESTGetAPIGuildWidgetSettingsResult, RESTGetAPITemplateResult, RESTPatchAPIAutoModerationRuleJSONBody, RESTPatchAPIAutoModerationRuleResult, RESTPatchAPICurrentGuildMemberJSONBody, RESTPatchAPIGuildChannelPositionsJSONBody, RESTPatchAPIGuildChannelPositionsResult, RESTPatchAPIGuildEmojiJSONBody, RESTPatchAPIGuildEmojiResult, RESTPatchAPIGuildJSONBody, RESTPatchAPIGuildMemberJSONBody, RESTPatchAPIGuildMemberResult, RESTPatchAPIGuildResult, RESTPatchAPIGuildRoleJSONBody, RESTPatchAPIGuildRolePositionsJSONBody, RESTPatchAPIGuildRolePositionsResult, RESTPatchAPIGuildRoleResult, RESTPatchAPIGuildScheduledEventJSONBody, RESTPatchAPIGuildScheduledEventResult, RESTPatchAPIGuildSoundboardSoundJSONBody, RESTPatchAPIGuildSoundboardSoundResult, RESTPatchAPIGuildStickerJSONBody, RESTPatchAPIGuildStickerResult, RESTPatchAPIGuildTemplateJSONBody, RESTPatchAPIGuildTemplateResult, RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody, RESTPatchAPIGuildVoiceStateCurrentMemberResult, RESTPatchAPIGuildVoiceStateUserJSONBody, RESTPatchAPIGuildVoiceStateUserResult, RESTPatchAPIGuildWelcomeScreenJSONBody, RESTPatchAPIGuildWelcomeScreenResult, RESTPatchAPIGuildWidgetSettingsJSONBody, RESTPatchAPIGuildWidgetSettingsResult, RESTPostAPIAutoModerationRuleJSONBody, RESTPostAPIAutoModerationRuleResult, RESTPostAPIGuildBulkBanJSONBody, RESTPostAPIGuildBulkBanResult, RESTPostAPIGuildChannelJSONBody, RESTPostAPIGuildChannelResult, RESTPostAPIGuildEmojiJSONBody, RESTPostAPIGuildEmojiResult, RESTPostAPIGuildPruneJSONBody, RESTPostAPIGuildPruneResult, RESTPostAPIGuildRoleJSONBody, RESTPostAPIGuildRoleResult, RESTPostAPIGuildScheduledEventJSONBody, RESTPostAPIGuildScheduledEventResult, RESTPostAPIGuildSoundboardSoundJSONBody, RESTPostAPIGuildSoundboardSoundResult, RESTPostAPIGuildStickerFormDataBody, RESTPostAPIGuildStickerResult, RESTPostAPIGuildsMFAJSONBody, RESTPostAPIGuildsMFAResult, RESTPostAPIGuildTemplatesJSONBody, RESTPostAPIGuildTemplatesResult, RESTPostAPITemplateCreateGuildJSONBody, RESTPostAPITemplateCreateGuildResult, RESTPutAPIGuildBanJSONBody, RESTPutAPIGuildBanResult, RESTPutAPIGuildMemberJSONBody, RESTPutAPIGuildMemberResult, RESTPutAPIGuildMemberRoleResult, RESTPutAPIGuildTemplateSyncResult } from '../../types';
|
|
3
|
-
import type { RestArguments, RestArgumentsNoBody } from '../api';
|
|
3
|
+
import type { RestArguments, RestArgumentsNoBody, RestArgumentsRequiredQuery } from '../api';
|
|
4
4
|
import type { RawFile } from '../shared';
|
|
5
5
|
export interface GuildRoutes {
|
|
6
6
|
guilds: {
|
|
@@ -40,7 +40,7 @@ export interface GuildRoutes {
|
|
|
40
40
|
members: {
|
|
41
41
|
get(args?: RestArgumentsNoBody<RESTGetAPIGuildMembersQuery>): Promise<RESTGetAPIGuildMembersResult>;
|
|
42
42
|
search: {
|
|
43
|
-
get(args:
|
|
43
|
+
get(args: RestArgumentsRequiredQuery<RESTGetAPIGuildMembersSearchQuery>): Promise<RESTGetAPIGuildMembersSearchResult>;
|
|
44
44
|
};
|
|
45
45
|
'@me': {
|
|
46
46
|
patch(args: RestArguments<RESTPatchAPICurrentGuildMemberJSONBody>): Promise<RESTGetAPIGuildMemberResult>;
|
package/lib/api/api.d.ts
CHANGED
|
@@ -3,14 +3,15 @@ import { type Awaitable, Logger, SeyfertError } from '../common';
|
|
|
3
3
|
import type { WorkerSendApiRequest } from '../websocket/discord/worker';
|
|
4
4
|
import { Bucket } from './bucket';
|
|
5
5
|
import type { APIRoutes } from './Routes';
|
|
6
|
-
import { type ApiHandlerInternalOptions, type ApiHandlerOptions, type ApiRequestOptions, type HttpMethods, type RawFile, type RequestHeaders } from './shared';
|
|
7
|
-
export
|
|
6
|
+
import { type ApiHandlerInternalOptions, type ApiHandlerOptions, type ApiRequestOptions, type HttpMethods, type RawFile, type RequestHeaders, type RestObserveOptions, type RestObserver, type RestObserverDisposer, type RestObserverEntry } from './shared';
|
|
7
|
+
export type { RestObserveOptions, RestObserver, RestObserverDisposer, RestObserverEntry, RestObserverFailPayload, RestObserverRatelimitPayload, RestObserverRequestPayload, RestObserverSuccessPayload, } from './shared';
|
|
8
|
+
export interface ApiHandler<TClient = unknown> {
|
|
8
9
|
debugger?: Logger;
|
|
9
10
|
}
|
|
10
11
|
export type OnRatelimitCallback = (response: Response, request: ApiRequestOptions) => Awaitable<any>;
|
|
11
12
|
export type OnSuccessRequestCallback = (method: HttpMethods, url: `/${string}`, response: Response) => Awaitable<any>;
|
|
12
13
|
export type OnFailRequestCallback = (method: HttpMethods, url: `/${string}`, error: unknown, statusCode?: number) => Awaitable<any>;
|
|
13
|
-
export declare class ApiHandler {
|
|
14
|
+
export declare class ApiHandler<TClient = unknown> {
|
|
14
15
|
options: ApiHandlerInternalOptions;
|
|
15
16
|
globalBlock: boolean;
|
|
16
17
|
ratelimits: Map<string, Bucket>;
|
|
@@ -23,22 +24,30 @@ export declare class ApiHandler {
|
|
|
23
24
|
onRatelimit?: OnRatelimitCallback;
|
|
24
25
|
onSuccessRequest?: OnSuccessRequestCallback;
|
|
25
26
|
onFailRequest?: OnFailRequestCallback;
|
|
27
|
+
pluginRestObserverProvider?: () => readonly RestObserverEntry[];
|
|
28
|
+
pluginRestObserverClient?: TClient;
|
|
29
|
+
private restObservers;
|
|
26
30
|
constructor(options: ApiHandlerOptions);
|
|
31
|
+
observe(observer: RestObserver<TClient>, _opts?: RestObserveOptions): RestObserverDisposer;
|
|
27
32
|
set debug(active: boolean);
|
|
28
33
|
get proxy(): APIRoutes;
|
|
29
34
|
globalUnblock(): void;
|
|
30
35
|
randomUUID(): UUID;
|
|
31
36
|
protected sendMessage(_body: WorkerSendApiRequest): void;
|
|
32
37
|
protected postMessage<T = unknown>(body: WorkerSendApiRequest): Promise<T>;
|
|
38
|
+
private notifyRequest;
|
|
33
39
|
private notifySuccessRequest;
|
|
34
40
|
private notifyFailRequest;
|
|
41
|
+
private notifyRatelimit;
|
|
42
|
+
private notifyRestObservers;
|
|
43
|
+
private notifyRestObserverEntries;
|
|
35
44
|
request<T = unknown>(method: HttpMethods, url: `/${string}`, { auth, ...request }?: ApiRequestOptions): Promise<T>;
|
|
36
45
|
parseError(method: HttpMethods, route: `/${string}`, response: Response, result: string | Record<string, any>, originTrace?: {
|
|
37
46
|
stack?: string;
|
|
38
47
|
}): SeyfertError;
|
|
39
48
|
parseValidationError(data: Record<string, any>, path?: string, errors?: string[]): string[];
|
|
40
49
|
handle50X(method: HttpMethods, url: `/${string}`, request: ApiRequestOptions, next: () => void): Promise<unknown>;
|
|
41
|
-
handle429(route: string, method: HttpMethods, url: `/${string}`, request: ApiRequestOptions, response: Response, result: string, next: () => void, reject: (err: unknown) => void, now: number): Promise<unknown>;
|
|
50
|
+
handle429(route: string, method: HttpMethods, url: `/${string}`, request: ApiRequestOptions, response: Response, result: string, next: () => void, reject: (err: unknown) => void, now: number, notifyUrl: `/${string}`): Promise<unknown>;
|
|
42
51
|
clearResetInterval(route: string): void;
|
|
43
52
|
setResetBucket(route: string, resp: Response, now: number, headerNow: number): void;
|
|
44
53
|
setRatelimitsBucket(route: string, resp: Response): void;
|
|
@@ -63,3 +72,6 @@ export type RestArgumentsNoBody<Q extends never | Record<string, any> = never> =
|
|
|
63
72
|
query?: Q;
|
|
64
73
|
files?: RawFile[];
|
|
65
74
|
} & RequestOptions;
|
|
75
|
+
export type RestArgumentsRequiredQuery<Q extends Record<string, any>> = Omit<RestArgumentsNoBody<Q>, 'query'> & {
|
|
76
|
+
query: Q;
|
|
77
|
+
};
|
package/lib/api/api.js
CHANGED
|
@@ -18,6 +18,9 @@ class ApiHandler {
|
|
|
18
18
|
onRatelimit;
|
|
19
19
|
onSuccessRequest;
|
|
20
20
|
onFailRequest;
|
|
21
|
+
pluginRestObserverProvider;
|
|
22
|
+
pluginRestObserverClient;
|
|
23
|
+
restObservers = new Map();
|
|
21
24
|
constructor(options) {
|
|
22
25
|
this.options = {
|
|
23
26
|
baseUrl: 'api/v10',
|
|
@@ -59,6 +62,17 @@ class ApiHandler {
|
|
|
59
62
|
};
|
|
60
63
|
}
|
|
61
64
|
}
|
|
65
|
+
observe(observer, _opts) {
|
|
66
|
+
const id = Symbol('rest-observer');
|
|
67
|
+
this.restObservers.set(id, { observer });
|
|
68
|
+
let disposed = false;
|
|
69
|
+
return () => {
|
|
70
|
+
if (disposed)
|
|
71
|
+
return;
|
|
72
|
+
disposed = true;
|
|
73
|
+
this.restObservers.delete(id);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
62
76
|
set debug(active) {
|
|
63
77
|
this.debugger = active
|
|
64
78
|
? new common_1.Logger({
|
|
@@ -91,7 +105,22 @@ class ApiHandler {
|
|
|
91
105
|
this.workerPromises.set(body.nonce, { reject: rej, resolve: res });
|
|
92
106
|
});
|
|
93
107
|
}
|
|
94
|
-
async
|
|
108
|
+
async notifyRequest(method, url, request) {
|
|
109
|
+
await this.notifyRestObservers('onRequest', () => freezeRestPayload({
|
|
110
|
+
client: this.pluginRestObserverClient,
|
|
111
|
+
method,
|
|
112
|
+
url,
|
|
113
|
+
request: readonlyRequestOptions(request),
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
async notifySuccessRequest(method, url, response, request) {
|
|
117
|
+
await this.notifyRestObservers('onSuccess', () => freezeRestPayload({
|
|
118
|
+
client: this.pluginRestObserverClient,
|
|
119
|
+
method,
|
|
120
|
+
url,
|
|
121
|
+
request: readonlyRequestOptions(request),
|
|
122
|
+
response,
|
|
123
|
+
}));
|
|
95
124
|
try {
|
|
96
125
|
await this.onSuccessRequest?.(method, url, response);
|
|
97
126
|
}
|
|
@@ -99,7 +128,15 @@ class ApiHandler {
|
|
|
99
128
|
this.debugger?.warn('onSuccessRequest callback error', error);
|
|
100
129
|
}
|
|
101
130
|
}
|
|
102
|
-
async notifyFailRequest(method, url, error, statusCode) {
|
|
131
|
+
async notifyFailRequest(method, url, error, statusCode, request) {
|
|
132
|
+
await this.notifyRestObservers('onFail', () => freezeRestPayload({
|
|
133
|
+
client: this.pluginRestObserverClient,
|
|
134
|
+
method,
|
|
135
|
+
url,
|
|
136
|
+
request: readonlyRequestOptions(request),
|
|
137
|
+
error,
|
|
138
|
+
statusCode,
|
|
139
|
+
}));
|
|
103
140
|
try {
|
|
104
141
|
await this.onFailRequest?.(method, url, error, statusCode);
|
|
105
142
|
}
|
|
@@ -107,6 +144,49 @@ class ApiHandler {
|
|
|
107
144
|
this.debugger?.warn('onFailRequest callback error', callbackError);
|
|
108
145
|
}
|
|
109
146
|
}
|
|
147
|
+
async notifyRatelimit(response, request, method, url) {
|
|
148
|
+
await this.notifyRestObservers('onRatelimit', () => freezeRestPayload({
|
|
149
|
+
client: this.pluginRestObserverClient,
|
|
150
|
+
method,
|
|
151
|
+
url,
|
|
152
|
+
request: readonlyRequestOptions(request),
|
|
153
|
+
response,
|
|
154
|
+
}));
|
|
155
|
+
try {
|
|
156
|
+
await this.onRatelimit?.(response, request);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
this.debugger?.warn('onRatelimit callback error', error);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async notifyRestObservers(name, createPayload) {
|
|
163
|
+
let payload;
|
|
164
|
+
let hasPayload = false;
|
|
165
|
+
const getPayload = () => {
|
|
166
|
+
if (!hasPayload) {
|
|
167
|
+
payload = createPayload();
|
|
168
|
+
hasPayload = true;
|
|
169
|
+
}
|
|
170
|
+
return payload;
|
|
171
|
+
};
|
|
172
|
+
await this.notifyRestObserverEntries(name, getPayload, this.pluginRestObserverProvider?.() ?? []);
|
|
173
|
+
await this.notifyRestObserverEntries(name, getPayload, this.restObservers.values());
|
|
174
|
+
}
|
|
175
|
+
async notifyRestObserverEntries(name, getPayload, entries) {
|
|
176
|
+
for (const entry of entries) {
|
|
177
|
+
const observer = entry.observer[name];
|
|
178
|
+
if (!observer)
|
|
179
|
+
continue;
|
|
180
|
+
const payload = getPayload();
|
|
181
|
+
try {
|
|
182
|
+
await observer(payload);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
const source = entry.plugin ? `[plugin:${entry.plugin}] ` : '';
|
|
186
|
+
this.debugger?.warn(`${source}REST observer "${name}" callback error`, error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
110
190
|
async request(method, url, { auth = true, ...request } = {}) {
|
|
111
191
|
const originTrace = {};
|
|
112
192
|
Error.captureStackTrace(originTrace, this.request);
|
|
@@ -127,14 +207,24 @@ class ApiHandler {
|
|
|
127
207
|
const headers = {
|
|
128
208
|
'User-Agent': this.options.userAgent,
|
|
129
209
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
210
|
+
let data;
|
|
211
|
+
let finalUrl;
|
|
212
|
+
try {
|
|
213
|
+
({ data, finalUrl } = this.parseRequest({
|
|
214
|
+
url,
|
|
215
|
+
headers,
|
|
216
|
+
request: { ...request, auth },
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
next();
|
|
221
|
+
reject(err);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
135
224
|
let response;
|
|
136
225
|
try {
|
|
137
226
|
const requestUrl = `${this.options.domain}/${this.options.baseUrl}${finalUrl}`;
|
|
227
|
+
await this.notifyRequest(method, finalUrl, { ...request, auth });
|
|
138
228
|
this.debugger?.debug(`Sending, Method: ${method} | Url: [${finalUrl}](${route}) | Auth: ${auth}`);
|
|
139
229
|
response = await fetch(requestUrl, {
|
|
140
230
|
method,
|
|
@@ -145,7 +235,7 @@ class ApiHandler {
|
|
|
145
235
|
}
|
|
146
236
|
catch (err) {
|
|
147
237
|
this.debugger?.debug('Fetch error', err);
|
|
148
|
-
await this.notifyFailRequest(method, finalUrl, err);
|
|
238
|
+
await this.notifyFailRequest(method, finalUrl, err, undefined, { ...request, auth });
|
|
149
239
|
next();
|
|
150
240
|
reject(err);
|
|
151
241
|
return;
|
|
@@ -154,13 +244,14 @@ class ApiHandler {
|
|
|
154
244
|
const headerNow = Date.parse(response.headers.get('date') ?? '');
|
|
155
245
|
this.setRatelimitsBucket(route, response);
|
|
156
246
|
this.setResetBucket(route, response, now, headerNow);
|
|
247
|
+
const observerResponse = response.clone();
|
|
157
248
|
let result = await response.text();
|
|
158
249
|
if (response.status >= 300) {
|
|
159
250
|
if (response.status === 429) {
|
|
160
|
-
const result429 = await this.handle429(route, method, url, request,
|
|
251
|
+
const result429 = await this.handle429(route, method, url, { ...request, auth }, observerResponse, result, next, reject, now, finalUrl);
|
|
161
252
|
if (result429 !== false)
|
|
162
253
|
return resolve(result429);
|
|
163
|
-
await this.notifyFailRequest(method, finalUrl, result, response.status);
|
|
254
|
+
await this.notifyFailRequest(method, finalUrl, result, response.status, { ...request, auth });
|
|
164
255
|
return this.clearResetInterval(route);
|
|
165
256
|
}
|
|
166
257
|
if ([502, 503].includes(response.status) && ++attempts < 4) {
|
|
@@ -176,7 +267,7 @@ class ApiHandler {
|
|
|
176
267
|
}
|
|
177
268
|
catch (err) {
|
|
178
269
|
this.debugger?.warn('SeyfertError parsing result error (', result, ')', err);
|
|
179
|
-
await this.notifyFailRequest(method, finalUrl, err, response.status);
|
|
270
|
+
await this.notifyFailRequest(method, finalUrl, err, response.status, { ...request, auth });
|
|
180
271
|
reject(err);
|
|
181
272
|
return;
|
|
182
273
|
}
|
|
@@ -184,7 +275,7 @@ class ApiHandler {
|
|
|
184
275
|
}
|
|
185
276
|
const parsedError = this.parseError(method, route, response, result, originTrace);
|
|
186
277
|
this.debugger?.warn(parsedError.message);
|
|
187
|
-
await this.notifyFailRequest(method, finalUrl, parsedError, response.status);
|
|
278
|
+
await this.notifyFailRequest(method, finalUrl, parsedError, response.status, { ...request, auth });
|
|
188
279
|
reject(parsedError);
|
|
189
280
|
return;
|
|
190
281
|
}
|
|
@@ -195,14 +286,14 @@ class ApiHandler {
|
|
|
195
286
|
}
|
|
196
287
|
catch (err) {
|
|
197
288
|
this.debugger?.warn('Failed parsing result (', result, ')', err);
|
|
198
|
-
await this.notifyFailRequest(method, finalUrl, err, response.status);
|
|
289
|
+
await this.notifyFailRequest(method, finalUrl, err, response.status, { ...request, auth });
|
|
199
290
|
next();
|
|
200
291
|
reject(err);
|
|
201
292
|
return;
|
|
202
293
|
}
|
|
203
294
|
}
|
|
204
295
|
}
|
|
205
|
-
await this.notifySuccessRequest(method, finalUrl,
|
|
296
|
+
await this.notifySuccessRequest(method, finalUrl, observerResponse, { ...request, auth });
|
|
206
297
|
next();
|
|
207
298
|
return resolve(result || undefined);
|
|
208
299
|
};
|
|
@@ -285,15 +376,12 @@ class ApiHandler {
|
|
|
285
376
|
next();
|
|
286
377
|
await (0, common_1.delay)(wait);
|
|
287
378
|
return this.request(method, url, {
|
|
288
|
-
|
|
289
|
-
auth: request.auth,
|
|
290
|
-
reason: request.reason,
|
|
291
|
-
route: request.route,
|
|
379
|
+
...request,
|
|
292
380
|
unshift: true,
|
|
293
381
|
});
|
|
294
382
|
}
|
|
295
|
-
async handle429(route, method, url, request, response, result, next, reject, now) {
|
|
296
|
-
await this.
|
|
383
|
+
async handle429(route, method, url, request, response, result, next, reject, now, notifyUrl) {
|
|
384
|
+
await this.notifyRatelimit(response, request, method, notifyUrl);
|
|
297
385
|
const bucket = this.ratelimits.get(route);
|
|
298
386
|
let retryAfter;
|
|
299
387
|
const data = JSON.parse(result);
|
|
@@ -325,19 +413,13 @@ class ApiHandler {
|
|
|
325
413
|
await (0, common_1.delay)(retryAfter);
|
|
326
414
|
next();
|
|
327
415
|
return this.request(method, url, {
|
|
328
|
-
|
|
329
|
-
auth: request.auth,
|
|
330
|
-
reason: request.reason,
|
|
331
|
-
route: request.route,
|
|
416
|
+
...request,
|
|
332
417
|
unshift: true,
|
|
333
418
|
});
|
|
334
419
|
}
|
|
335
420
|
next();
|
|
336
421
|
return this.request(method, url, {
|
|
337
|
-
|
|
338
|
-
auth: request.auth,
|
|
339
|
-
reason: request.reason,
|
|
340
|
-
route: request.route,
|
|
422
|
+
...request,
|
|
341
423
|
unshift: true,
|
|
342
424
|
});
|
|
343
425
|
}
|
|
@@ -389,7 +471,11 @@ class ApiHandler {
|
|
|
389
471
|
let finalUrl = options.url;
|
|
390
472
|
let data;
|
|
391
473
|
if (options.request.auth) {
|
|
392
|
-
|
|
474
|
+
const token = options.request.token || this.options.token;
|
|
475
|
+
if (token === 'INVALID' || typeof token !== 'string' || token.length === 0) {
|
|
476
|
+
throw new common_1.SeyfertError('INVALID_TOKEN', { metadata: { detail: 'token is not a string' } });
|
|
477
|
+
}
|
|
478
|
+
options.headers.Authorization = `${this.options.type} ${token}`;
|
|
393
479
|
}
|
|
394
480
|
if (options.request.query) {
|
|
395
481
|
const params = new URLSearchParams();
|
|
@@ -449,7 +535,7 @@ class ApiHandler {
|
|
|
449
535
|
.replace(/^\/webhooks\/(\d+)\/[A-Za-z0-9-_]{64,}/, '/webhooks/$1/:token');
|
|
450
536
|
if (method === 'DELETE' && route.endsWith('/messages/:id')) {
|
|
451
537
|
const messageID = url.slice(url.lastIndexOf('/') + 1);
|
|
452
|
-
const createdAt =
|
|
538
|
+
const createdAt = (0, common_1.snowflakeToTimestamp)(messageID);
|
|
453
539
|
if (Date.now() - createdAt >= 1000 * 60 * 60 * 24 * 14) {
|
|
454
540
|
method += '_OLD';
|
|
455
541
|
}
|
|
@@ -471,3 +557,40 @@ class ApiHandler {
|
|
|
471
557
|
}
|
|
472
558
|
}
|
|
473
559
|
exports.ApiHandler = ApiHandler;
|
|
560
|
+
function freezeRestPayload(payload) {
|
|
561
|
+
return Object.freeze(payload);
|
|
562
|
+
}
|
|
563
|
+
function readonlyRequestOptions(request) {
|
|
564
|
+
const clone = deepClonePlain({
|
|
565
|
+
...request,
|
|
566
|
+
body: request.body ? deepClonePlain(request.body) : undefined,
|
|
567
|
+
query: request.query ? deepClonePlain(request.query) : undefined,
|
|
568
|
+
files: request.files?.map(file => deepClonePlain(file)),
|
|
569
|
+
});
|
|
570
|
+
return deepFreezePlain(clone);
|
|
571
|
+
}
|
|
572
|
+
function deepClonePlain(value) {
|
|
573
|
+
if (Array.isArray(value))
|
|
574
|
+
return value.map(deepClonePlain);
|
|
575
|
+
if (!isPlainObject(value))
|
|
576
|
+
return value;
|
|
577
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, deepClonePlain(entry)]));
|
|
578
|
+
}
|
|
579
|
+
function deepFreezePlain(value) {
|
|
580
|
+
if (Array.isArray(value)) {
|
|
581
|
+
for (const entry of value)
|
|
582
|
+
deepFreezePlain(entry);
|
|
583
|
+
return Object.freeze(value);
|
|
584
|
+
}
|
|
585
|
+
if (!isPlainObject(value))
|
|
586
|
+
return value;
|
|
587
|
+
for (const entry of Object.values(value))
|
|
588
|
+
deepFreezePlain(entry);
|
|
589
|
+
return Object.freeze(value);
|
|
590
|
+
}
|
|
591
|
+
function isPlainObject(value) {
|
|
592
|
+
if (typeof value !== 'object' || value === null)
|
|
593
|
+
return false;
|
|
594
|
+
const prototype = Object.getPrototypeOf(value);
|
|
595
|
+
return prototype === Object.prototype || prototype === null;
|
|
596
|
+
}
|
package/lib/api/shared.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MakeRequired } from '../common';
|
|
1
|
+
import type { Awaitable, MakeRequired } from '../common';
|
|
2
2
|
export * from './api';
|
|
3
3
|
export * from './utils/constants';
|
|
4
4
|
export * from './utils/types';
|
|
@@ -34,3 +34,32 @@ export interface ApiRequestOptions {
|
|
|
34
34
|
token?: string;
|
|
35
35
|
}
|
|
36
36
|
export type HttpMethods = 'GET' | 'DELETE' | 'PUT' | 'POST' | 'PATCH';
|
|
37
|
+
export interface RestObserverRequestPayload<TClient = unknown> {
|
|
38
|
+
readonly client: TClient;
|
|
39
|
+
readonly method: HttpMethods;
|
|
40
|
+
readonly url: `/${string}`;
|
|
41
|
+
readonly request: Readonly<ApiRequestOptions>;
|
|
42
|
+
}
|
|
43
|
+
export interface RestObserverSuccessPayload<TClient = unknown> extends RestObserverRequestPayload<TClient> {
|
|
44
|
+
readonly response: Response;
|
|
45
|
+
}
|
|
46
|
+
export interface RestObserverFailPayload<TClient = unknown> extends RestObserverRequestPayload<TClient> {
|
|
47
|
+
readonly error: unknown;
|
|
48
|
+
readonly statusCode?: number;
|
|
49
|
+
}
|
|
50
|
+
export interface RestObserverRatelimitPayload<TClient = unknown> extends RestObserverRequestPayload<TClient> {
|
|
51
|
+
readonly response: Response;
|
|
52
|
+
}
|
|
53
|
+
export interface RestObserver<TClient = unknown> {
|
|
54
|
+
onRequest?(payload: RestObserverRequestPayload<TClient>): Awaitable<unknown>;
|
|
55
|
+
onSuccess?(payload: RestObserverSuccessPayload<TClient>): Awaitable<unknown>;
|
|
56
|
+
onFail?(payload: RestObserverFailPayload<TClient>): Awaitable<unknown>;
|
|
57
|
+
onRatelimit?(payload: RestObserverRatelimitPayload<TClient>): Awaitable<unknown>;
|
|
58
|
+
}
|
|
59
|
+
export interface RestObserverEntry<TClient = unknown> {
|
|
60
|
+
readonly plugin?: string;
|
|
61
|
+
readonly observer: RestObserver<TClient>;
|
|
62
|
+
}
|
|
63
|
+
export interface RestObserveOptions {
|
|
64
|
+
}
|
|
65
|
+
export type RestObserverDisposer = () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DefaultUserAgent: "DiscordBot (https://seyfert.dev, v4.
|
|
1
|
+
export declare const DefaultUserAgent: "DiscordBot (https://seyfert.dev, v4.0.0)";
|
|
2
2
|
export declare const ALLOWED_EXTENSIONS: readonly ["webp", "png", "jpg", "jpeg", "gif"];
|
|
3
3
|
export declare const ALLOWED_STICKER_EXTENSIONS: readonly ["png", "json", "gif"];
|
|
4
4
|
export declare const ALLOWED_SIZES: readonly [16, 32, 64, 100, 128, 256, 512, 1024, 2048, 4096];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ALLOWED_TAG_BADGE_EXTENSIONS = exports.ALLOWED_SOUNDS_EXTENSIONS = exports.ALLOWED_SIZES = exports.ALLOWED_STICKER_EXTENSIONS = exports.ALLOWED_EXTENSIONS = exports.DefaultUserAgent = void 0;
|
|
4
|
-
exports.DefaultUserAgent = 'DiscordBot (https://seyfert.dev, v4.
|
|
4
|
+
exports.DefaultUserAgent = 'DiscordBot (https://seyfert.dev, v4.0.0)';
|
|
5
5
|
exports.ALLOWED_EXTENSIONS = ['webp', 'png', 'jpg', 'jpeg', 'gif'];
|
|
6
6
|
exports.ALLOWED_STICKER_EXTENSIONS = ['png', 'json', 'gif'];
|
|
7
7
|
exports.ALLOWED_SIZES = [16, 32, 64, 100, 128, 256, 512, 1_024, 2_048, 4_096];
|
package/lib/api/utils/utils.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Snowflake } from '../../types';
|
|
2
|
+
import type { UserAvatarDefault } from '../Routes/cdn';
|
|
2
3
|
/**
|
|
3
4
|
* Calculates the default avatar index for a given user id.
|
|
4
5
|
*
|
|
5
6
|
* @param userId - The user id to calculate the default avatar index for
|
|
6
7
|
*/
|
|
7
|
-
export declare function calculateUserDefaultAvatarIndex(userId: Snowflake, discriminator: string):
|
|
8
|
+
export declare function calculateUserDefaultAvatarIndex(userId: Snowflake, discriminator: string): UserAvatarDefault;
|
|
8
9
|
/**
|
|
9
10
|
* Verifies that a value is a buffer-like object.
|
|
10
11
|
*
|
package/lib/api/utils/utils.js
CHANGED
|
@@ -8,7 +8,7 @@ exports.isBufferLike = isBufferLike;
|
|
|
8
8
|
* @param userId - The user id to calculate the default avatar index for
|
|
9
9
|
*/
|
|
10
10
|
function calculateUserDefaultAvatarIndex(userId, discriminator) {
|
|
11
|
-
return discriminator === '0' ? Number(BigInt(userId) >> 22n) % 6 : Number.parseInt(discriminator) % 5;
|
|
11
|
+
return (discriminator === '0' ? Number(BigInt(userId) >> 22n) % 6 : Number.parseInt(discriminator) % 5);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Verifies that a value is a buffer-like object.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MediaGalleryItem = exports.MediaGallery = void 0;
|
|
4
|
+
const common_1 = require("../common");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const Base_1 = require("./Base");
|
|
6
7
|
/**
|
|
@@ -104,6 +105,15 @@ class MediaGalleryItem {
|
|
|
104
105
|
* @returns The JSON representation of the item data.
|
|
105
106
|
*/
|
|
106
107
|
toJSON() {
|
|
108
|
+
if (!this.data.media)
|
|
109
|
+
throw new common_1.SeyfertError('MISSING_MEDIA', {
|
|
110
|
+
metadata: {
|
|
111
|
+
...(0, common_1.createValidationMetadata)('media to be set before calling toJSON()', this.data.media, {
|
|
112
|
+
component: 'MediaGalleryItem',
|
|
113
|
+
}),
|
|
114
|
+
detail: 'Cannot convert to JSON without media.',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
107
117
|
return { ...this.data };
|
|
108
118
|
}
|
|
109
119
|
}
|
package/lib/builders/Modal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type RestOrArray } from '../common';
|
|
2
2
|
import { type APIModalInteractionResponseCallbackData, type APITextInputComponent, type TextInputStyle } from '../types';
|
|
3
3
|
import { BaseComponentBuilder, type OptionValuesLength } from './Base';
|
|
4
4
|
import type { ModalBuilderComponents, ModalSubmitCallback } from './types';
|
|
@@ -8,10 +8,16 @@ import type { ModalBuilderComponents, ModalSubmitCallback } from './types';
|
|
|
8
8
|
* @example
|
|
9
9
|
* const modal = new Modal();
|
|
10
10
|
* modal.setTitle("Sample Modal");
|
|
11
|
+
* modal.setCustomId("sample-modal");
|
|
11
12
|
* modal.addComponents(
|
|
12
|
-
* new
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* new Label()
|
|
14
|
+
* .setLabel("Enter text")
|
|
15
|
+
* .setComponent(
|
|
16
|
+
* new TextInput()
|
|
17
|
+
* .setCustomId("sample-input")
|
|
18
|
+
* .setStyle(TextInputStyle.Paragraph)
|
|
19
|
+
* )
|
|
20
|
+
* );
|
|
15
21
|
* modal.run((interaction) => {
|
|
16
22
|
* // Handle modal submission
|
|
17
23
|
* });
|
|
@@ -64,10 +70,14 @@ export declare class Modal {
|
|
|
64
70
|
/**
|
|
65
71
|
* Represents a text input component builder.
|
|
66
72
|
* @example
|
|
67
|
-
* const textInput = new TextInput()
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
73
|
+
* const textInput = new TextInput()
|
|
74
|
+
* .setCustomId("feedback")
|
|
75
|
+
* .setStyle(TextInputStyle.Paragraph)
|
|
76
|
+
* .setPlaceholder("Type here");
|
|
77
|
+
* const label = new Label()
|
|
78
|
+
* .setLabel("Feedback")
|
|
79
|
+
* .setComponent(textInput);
|
|
80
|
+
* const json = label.toJSON();
|
|
71
81
|
*/
|
|
72
82
|
export declare class TextInput extends BaseComponentBuilder<APITextInputComponent> {
|
|
73
83
|
/**
|
package/lib/builders/Modal.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TextInput = exports.Modal = void 0;
|
|
4
|
+
const common_1 = require("../common");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const _1 = require(".");
|
|
6
7
|
const Base_1 = require("./Base");
|
|
@@ -10,10 +11,16 @@ const Base_1 = require("./Base");
|
|
|
10
11
|
* @example
|
|
11
12
|
* const modal = new Modal();
|
|
12
13
|
* modal.setTitle("Sample Modal");
|
|
14
|
+
* modal.setCustomId("sample-modal");
|
|
13
15
|
* modal.addComponents(
|
|
14
|
-
* new
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* new Label()
|
|
17
|
+
* .setLabel("Enter text")
|
|
18
|
+
* .setComponent(
|
|
19
|
+
* new TextInput()
|
|
20
|
+
* .setCustomId("sample-input")
|
|
21
|
+
* .setStyle(TextInputStyle.Paragraph)
|
|
22
|
+
* )
|
|
23
|
+
* );
|
|
17
24
|
* modal.run((interaction) => {
|
|
18
25
|
* // Handle modal submission
|
|
19
26
|
* });
|
|
@@ -82,6 +89,24 @@ class Modal {
|
|
|
82
89
|
* @returns The modal data in JSON format.
|
|
83
90
|
*/
|
|
84
91
|
toJSON() {
|
|
92
|
+
if (!this.data.custom_id)
|
|
93
|
+
throw new common_1.SeyfertError('MISSING_MODAL_CUSTOM_ID', {
|
|
94
|
+
metadata: {
|
|
95
|
+
...(0, common_1.createValidationMetadata)('custom_id to be set before calling toJSON()', this.data.custom_id, {
|
|
96
|
+
component: 'Modal',
|
|
97
|
+
}),
|
|
98
|
+
detail: 'Cannot convert to JSON without a custom_id.',
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
if (!this.data.title)
|
|
102
|
+
throw new common_1.SeyfertError('MISSING_MODAL_TITLE', {
|
|
103
|
+
metadata: {
|
|
104
|
+
...(0, common_1.createValidationMetadata)('title to be set before calling toJSON()', this.data.title, {
|
|
105
|
+
component: 'Modal',
|
|
106
|
+
}),
|
|
107
|
+
detail: 'Cannot convert to JSON without a title.',
|
|
108
|
+
},
|
|
109
|
+
});
|
|
85
110
|
return {
|
|
86
111
|
custom_id: this.data.custom_id,
|
|
87
112
|
title: this.data.title,
|
|
@@ -93,10 +118,14 @@ exports.Modal = Modal;
|
|
|
93
118
|
/**
|
|
94
119
|
* Represents a text input component builder.
|
|
95
120
|
* @example
|
|
96
|
-
* const textInput = new TextInput()
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
121
|
+
* const textInput = new TextInput()
|
|
122
|
+
* .setCustomId("feedback")
|
|
123
|
+
* .setStyle(TextInputStyle.Paragraph)
|
|
124
|
+
* .setPlaceholder("Type here");
|
|
125
|
+
* const label = new Label()
|
|
126
|
+
* .setLabel("Feedback")
|
|
127
|
+
* .setComponent(textInput);
|
|
128
|
+
* const json = label.toJSON();
|
|
100
129
|
*/
|
|
101
130
|
class TextInput extends Base_1.BaseComponentBuilder {
|
|
102
131
|
/**
|
package/lib/builders/Poll.js
CHANGED
|
@@ -33,6 +33,24 @@ class PollBuilder {
|
|
|
33
33
|
return this;
|
|
34
34
|
}
|
|
35
35
|
toJSON() {
|
|
36
|
+
if (!this.data.question?.text && !this.data.question?.emoji)
|
|
37
|
+
throw new common_1.SeyfertError('MISSING_POLL_QUESTION', {
|
|
38
|
+
metadata: {
|
|
39
|
+
...(0, common_1.createValidationMetadata)('question to be set before calling toJSON()', this.data.question, {
|
|
40
|
+
component: 'PollBuilder',
|
|
41
|
+
}),
|
|
42
|
+
detail: 'Cannot convert to JSON without a question.',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
if (!this.data.answers?.length)
|
|
46
|
+
throw new common_1.SeyfertError('MISSING_POLL_ANSWERS', {
|
|
47
|
+
metadata: {
|
|
48
|
+
...(0, common_1.createValidationMetadata)('at least one answer to be set before calling toJSON()', this.data.answers, {
|
|
49
|
+
component: 'PollBuilder',
|
|
50
|
+
}),
|
|
51
|
+
detail: 'Cannot convert to JSON without answers.',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
36
54
|
return { ...this.data };
|
|
37
55
|
}
|
|
38
56
|
resolvedPollMedia(data) {
|