chapterjs 0.1.2 → 0.2.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/dist/assets/asset.d.ts +46 -0
- package/dist/assets/asset.js +86 -0
- package/dist/assets/public.d.ts +19 -0
- package/dist/assets/public.js +120 -0
- package/dist/cache/cache.d.ts +62 -0
- package/dist/cache/cache.js +80 -0
- package/dist/cache/store.d.ts +45 -0
- package/dist/cache/store.js +53 -0
- package/dist/cli/build.d.ts +41 -0
- package/dist/cli/build.js +205 -0
- package/dist/cli/cli.js +108 -25
- package/dist/cli/cluster.d.ts +70 -0
- package/dist/cli/cluster.js +213 -0
- package/dist/cli/dev.d.ts +18 -1
- package/dist/cli/dev.js +253 -198
- package/dist/cli/env.d.ts +31 -0
- package/dist/cli/env.js +93 -0
- package/dist/cli/log.d.ts +13 -0
- package/dist/cli/log.js +17 -0
- package/dist/cli/node-version.d.ts +8 -0
- package/dist/cli/node-version.js +13 -0
- package/dist/cli/preflight.d.ts +36 -0
- package/dist/cli/preflight.js +122 -0
- package/dist/cli/project.d.ts +135 -0
- package/dist/cli/project.js +517 -0
- package/dist/cli/start.d.ts +25 -0
- package/dist/cli/start.js +225 -0
- package/dist/commands/autocomplete.d.ts +13 -0
- package/dist/commands/autocomplete.js +159 -0
- package/dist/commands/command.d.ts +360 -0
- package/dist/commands/command.js +28 -0
- package/dist/commands/declaration.d.ts +77 -0
- package/dist/commands/declaration.js +492 -0
- package/dist/commands/register.d.ts +18 -0
- package/dist/commands/register.js +42 -0
- package/dist/commands/router.d.ts +20 -0
- package/dist/commands/router.js +228 -0
- package/dist/commands/tree.d.ts +47 -0
- package/dist/commands/tree.js +216 -0
- package/dist/commands/twins.d.ts +15 -0
- package/dist/commands/twins.js +78 -0
- package/dist/components/button.d.ts +79 -0
- package/dist/components/button.js +106 -0
- package/dist/components/component.d.ts +140 -0
- package/dist/components/component.js +39 -0
- package/dist/components/custom-id.d.ts +72 -0
- package/dist/components/custom-id.js +128 -0
- package/dist/components/declaration.d.ts +42 -0
- package/dist/components/declaration.js +342 -0
- package/dist/components/declared.d.ts +29 -0
- package/dist/components/declared.js +49 -0
- package/dist/components/embed.d.ts +29 -0
- package/dist/components/embed.js +11 -0
- package/dist/components/instance.d.ts +100 -0
- package/dist/components/instance.js +86 -0
- package/dist/components/layout.d.ts +103 -0
- package/dist/components/layout.js +279 -0
- package/dist/components/modal.d.ts +245 -0
- package/dist/components/modal.js +398 -0
- package/dist/components/options.d.ts +41 -0
- package/dist/components/options.js +101 -0
- package/dist/components/render.d.ts +12 -0
- package/dist/components/render.js +58 -0
- package/dist/components/router.d.ts +19 -0
- package/dist/components/router.js +251 -0
- package/dist/components/select.d.ts +146 -0
- package/dist/components/select.js +179 -0
- package/dist/core/bot.d.ts +99 -0
- package/dist/core/bot.js +174 -0
- package/dist/core/memory.d.ts +66 -0
- package/dist/core/memory.js +115 -0
- package/dist/discord/api.d.ts +112 -0
- package/dist/discord/api.js +115 -0
- package/dist/discord/cdn.d.ts +67 -0
- package/dist/discord/cdn.js +100 -0
- package/dist/discord/codes.d.ts +171 -0
- package/dist/discord/codes.js +421 -0
- package/dist/discord/endpoint.d.ts +56 -0
- package/dist/discord/endpoint.js +53 -0
- package/dist/discord/endpoints.d.ts +1529 -0
- package/dist/discord/endpoints.js +1139 -0
- package/dist/discord/formatting.d.ts +67 -0
- package/dist/discord/formatting.js +87 -0
- package/dist/discord/index.d.ts +10 -0
- package/dist/discord/index.js +13 -0
- package/dist/discord/intents.d.ts +48 -0
- package/dist/discord/intents.js +128 -0
- package/dist/discord/permissions.d.ts +94 -0
- package/dist/discord/permissions.js +185 -0
- package/dist/discord/snowflake.d.ts +21 -0
- package/dist/discord/snowflake.js +36 -0
- package/dist/discord/types/application-command.d.ts +332 -0
- package/dist/discord/types/application-command.js +48 -0
- package/dist/discord/types/application-role-connection-metadata.d.ts +42 -0
- package/dist/discord/types/application-role-connection-metadata.js +22 -0
- package/dist/discord/types/application.d.ts +208 -0
- package/dist/discord/types/application.js +48 -0
- package/dist/discord/types/audit-log.d.ts +255 -0
- package/dist/discord/types/audit-log.js +144 -0
- package/dist/discord/types/auto-moderation.d.ts +167 -0
- package/dist/discord/types/auto-moderation.js +52 -0
- package/dist/discord/types/channel.d.ts +557 -0
- package/dist/discord/types/channel.js +88 -0
- package/dist/discord/types/common.d.ts +54 -0
- package/dist/discord/types/common.js +38 -0
- package/dist/discord/types/component.d.ts +775 -0
- package/dist/discord/types/component.js +76 -0
- package/dist/discord/types/emoji.d.ts +74 -0
- package/dist/discord/types/emoji.js +1 -0
- package/dist/discord/types/entitlement.d.ts +84 -0
- package/dist/discord/types/entitlement.js +22 -0
- package/dist/discord/types/gateway-events.d.ts +1148 -0
- package/dist/discord/types/gateway-events.js +54 -0
- package/dist/discord/types/gateway.d.ts +38 -0
- package/dist/discord/types/gateway.js +1 -0
- package/dist/discord/types/guild-scheduled-event.d.ts +257 -0
- package/dist/discord/types/guild-scheduled-event.js +68 -0
- package/dist/discord/types/guild-template.d.ts +51 -0
- package/dist/discord/types/guild-template.js +1 -0
- package/dist/discord/types/guild.d.ts +910 -0
- package/dist/discord/types/guild.js +153 -0
- package/dist/discord/types/index.d.ts +31 -0
- package/dist/discord/types/index.js +31 -0
- package/dist/discord/types/interaction.d.ts +321 -0
- package/dist/discord/types/interaction.js +47 -0
- package/dist/discord/types/invite.d.ts +158 -0
- package/dist/discord/types/invite.js +39 -0
- package/dist/discord/types/message.d.ts +834 -0
- package/dist/discord/types/message.js +159 -0
- package/dist/discord/types/oauth2.d.ts +22 -0
- package/dist/discord/types/oauth2.js +1 -0
- package/dist/discord/types/permissions.d.ts +183 -0
- package/dist/discord/types/permissions.js +118 -0
- package/dist/discord/types/poll.d.ts +106 -0
- package/dist/discord/types/poll.js +8 -0
- package/dist/discord/types/sku.d.ts +47 -0
- package/dist/discord/types/sku.js +26 -0
- package/dist/discord/types/soundboard.d.ts +71 -0
- package/dist/discord/types/soundboard.js +1 -0
- package/dist/discord/types/stage-instance.d.ts +58 -0
- package/dist/discord/types/stage-instance.js +10 -0
- package/dist/discord/types/sticker.d.ts +115 -0
- package/dist/discord/types/sticker.js +20 -0
- package/dist/discord/types/subscription.d.ts +54 -0
- package/dist/discord/types/subscription.js +12 -0
- package/dist/discord/types/team.d.ts +55 -0
- package/dist/discord/types/team.js +21 -0
- package/dist/discord/types/user.d.ts +273 -0
- package/dist/discord/types/user.js +83 -0
- package/dist/discord/types/voice.d.ts +72 -0
- package/dist/discord/types/voice.js +1 -0
- package/dist/discord/types/webhook.d.ts +184 -0
- package/dist/discord/types/webhook.js +12 -0
- package/dist/events/declaration.d.ts +16 -0
- package/dist/events/declaration.js +80 -0
- package/dist/events/event.d.ts +45 -0
- package/dist/events/event.js +34 -0
- package/dist/events/registry.d.ts +697 -0
- package/dist/events/registry.js +839 -0
- package/dist/events/router.d.ts +46 -0
- package/dist/events/router.js +133 -0
- package/dist/gateway/errors.d.ts +18 -0
- package/dist/gateway/errors.js +47 -0
- package/dist/gateway/gateway.d.ts +64 -0
- package/dist/gateway/gateway.js +117 -0
- package/dist/gateway/identify-queue.d.ts +25 -0
- package/dist/gateway/identify-queue.js +29 -0
- package/dist/gateway/shard.d.ts +94 -0
- package/dist/gateway/shard.js +414 -0
- package/dist/gateway/state.d.ts +11 -0
- package/dist/gateway/state.js +184 -0
- package/dist/index.d.ts +57 -18
- package/dist/index.js +40 -12
- package/dist/interactions/cooldown.d.ts +33 -0
- package/dist/interactions/cooldown.js +74 -0
- package/dist/interactions/dispatch.d.ts +91 -0
- package/dist/interactions/dispatch.js +110 -0
- package/dist/loader/generated.d.ts +10 -0
- package/dist/loader/generated.js +80 -0
- package/dist/loader/hot.d.ts +13 -0
- package/dist/loader/hot.js +85 -0
- package/dist/loader/loader.d.ts +85 -0
- package/dist/loader/loader.js +119 -0
- package/dist/loader/locate.d.ts +10 -0
- package/dist/loader/locate.js +36 -0
- package/dist/loader/watch.d.ts +17 -0
- package/dist/loader/watch.js +66 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +5 -0
- package/dist/messages/commands.d.ts +23 -0
- package/dist/messages/commands.js +142 -0
- package/dist/messages/declaration.d.ts +89 -0
- package/dist/messages/declaration.js +455 -0
- package/dist/messages/messages.d.ts +241 -0
- package/dist/messages/messages.js +31 -0
- package/dist/messages/phrases.d.ts +23 -0
- package/dist/messages/phrases.js +44 -0
- package/dist/messages/translate.d.ts +100 -0
- package/dist/messages/translate.js +249 -0
- package/dist/presence/declaration.d.ts +19 -0
- package/dist/presence/declaration.js +118 -0
- package/dist/presence/presence.d.ts +57 -0
- package/dist/presence/presence.js +27 -0
- package/dist/rest/errors.d.ts +55 -0
- package/dist/rest/errors.js +92 -0
- package/dist/rest/rate-limiter.d.ts +46 -0
- package/dist/rest/rate-limiter.js +153 -0
- package/dist/rest/rest.d.ts +63 -0
- package/dist/rest/rest.js +194 -0
- package/dist/structures/base.d.ts +48 -0
- package/dist/structures/base.js +84 -0
- package/dist/structures/channel.d.ts +380 -0
- package/dist/structures/channel.js +627 -0
- package/dist/structures/context.d.ts +30 -0
- package/dist/structures/context.js +7 -0
- package/dist/structures/emoji.d.ts +46 -0
- package/dist/structures/emoji.js +65 -0
- package/dist/structures/entities.d.ts +62 -0
- package/dist/structures/entities.js +226 -0
- package/dist/structures/guild.d.ts +348 -0
- package/dist/structures/guild.js +466 -0
- package/dist/structures/interaction.d.ts +197 -0
- package/dist/structures/interaction.js +396 -0
- package/dist/structures/invite.d.ts +38 -0
- package/dist/structures/invite.js +57 -0
- package/dist/structures/known.d.ts +28 -0
- package/dist/structures/known.js +58 -0
- package/dist/structures/member.d.ts +140 -0
- package/dist/structures/member.js +260 -0
- package/dist/structures/message.d.ts +197 -0
- package/dist/structures/message.js +268 -0
- package/dist/structures/payload.d.ts +91 -0
- package/dist/structures/payload.js +184 -0
- package/dist/structures/role.d.ts +69 -0
- package/dist/structures/role.js +112 -0
- package/dist/structures/user.d.ts +59 -0
- package/dist/structures/user.js +94 -0
- package/dist/structures/webhook.d.ts +46 -0
- package/dist/structures/webhook.js +79 -0
- package/dist/tasks/declaration.d.ts +16 -0
- package/dist/tasks/declaration.js +56 -0
- package/dist/tasks/schedule.d.ts +54 -0
- package/dist/tasks/schedule.js +236 -0
- package/dist/tasks/scheduler.d.ts +35 -0
- package/dist/tasks/scheduler.js +107 -0
- package/dist/tasks/task.d.ts +75 -0
- package/dist/tasks/task.js +27 -0
- package/dist/util/case.d.ts +13 -0
- package/dist/util/case.js +54 -0
- package/dist/util/duration.d.ts +8 -0
- package/dist/util/duration.js +29 -0
- package/dist/util/websocket.d.ts +9 -0
- package/dist/util/websocket.js +31 -0
- package/dist/voice/connection.d.ts +90 -0
- package/dist/voice/connection.js +494 -0
- package/dist/voice/dave.d.ts +109 -0
- package/dist/voice/dave.js +245 -0
- package/dist/voice/opus.d.ts +19 -0
- package/dist/voice/opus.js +273 -0
- package/dist/voice/session.d.ts +55 -0
- package/dist/voice/session.js +405 -0
- package/dist/voice/source.d.ts +22 -0
- package/dist/voice/source.js +195 -0
- package/dist/voice/transport.d.ts +43 -0
- package/dist/voice/transport.js +140 -0
- package/dist/voice/usage.d.ts +4 -0
- package/dist/voice/usage.js +33 -0
- package/package.json +26 -7
- package/vendor/dave/LICENSE +231 -0
- package/vendor/dave/libdave.d.mts +99 -0
- package/vendor/dave/libdave.mjs +2 -0
- package/vendor/dave/libdave.wasm +0 -0
- package/dist/components.d.ts +0 -97
- package/dist/components.js +0 -260
- package/dist/context.d.ts +0 -72
- package/dist/context.js +0 -273
- package/dist/discord/client.d.ts +0 -35
- package/dist/discord/client.js +0 -66
- package/dist/discord/constants.d.ts +0 -49
- package/dist/discord/constants.js +0 -61
- package/dist/discord/events.d.ts +0 -129
- package/dist/discord/events.js +0 -102
- package/dist/discord/gateway.d.ts +0 -61
- package/dist/discord/gateway.js +0 -320
- package/dist/discord/payloads.d.ts +0 -275
- package/dist/discord/payloads.js +0 -3
- package/dist/discord/presence.d.ts +0 -42
- package/dist/discord/presence.js +0 -51
- package/dist/discord/rest.d.ts +0 -49
- package/dist/discord/rest.js +0 -271
- package/dist/discord/types.d.ts +0 -334
- package/dist/discord/types.js +0 -4
- package/dist/events.d.ts +0 -94
- package/dist/events.js +0 -255
- package/dist/presence.d.ts +0 -92
- package/dist/presence.js +0 -250
- package/dist/structures/Channel.d.ts +0 -110
- package/dist/structures/Channel.js +0 -171
- package/dist/structures/Guild.d.ts +0 -70
- package/dist/structures/Guild.js +0 -105
- package/dist/structures/Interaction.d.ts +0 -113
- package/dist/structures/Interaction.js +0 -274
- package/dist/structures/Member.d.ts +0 -70
- package/dist/structures/Member.js +0 -124
- package/dist/structures/Message.d.ts +0 -87
- package/dist/structures/Message.js +0 -182
- package/dist/structures/Reaction.d.ts +0 -38
- package/dist/structures/Reaction.js +0 -64
- package/dist/structures/Role.d.ts +0 -43
- package/dist/structures/Role.js +0 -77
- package/dist/structures/User.d.ts +0 -41
- package/dist/structures/User.js +0 -79
- package/dist/structures/utils.d.ts +0 -72
- package/dist/structures/utils.js +0 -59
- package/dist/utils/errors.d.ts +0 -5
- package/dist/utils/errors.js +0 -28
- package/dist/utils/modules.d.ts +0 -39
- package/dist/utils/modules.js +0 -156
package/dist/presence.d.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import type { Client } from './discord/client.js';
|
|
2
|
-
import type { Gateway } from './discord/gateway.js';
|
|
3
|
-
import type { Presence } from './discord/presence.js';
|
|
4
|
-
export interface PresenceContext {
|
|
5
|
-
client: Client;
|
|
6
|
-
}
|
|
7
|
-
/** Computes one presence. Can be async, e.g. to read from a database. */
|
|
8
|
-
export type PresenceFunction = (context: PresenceContext) => Presence | Promise<Presence>;
|
|
9
|
-
/** One step of a rotation, shown for `duration` milliseconds (minimum 5000). */
|
|
10
|
-
export type PresenceStep = (Presence & {
|
|
11
|
-
duration: number;
|
|
12
|
-
}) | {
|
|
13
|
-
duration: number;
|
|
14
|
-
presence: PresenceFunction;
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Computes either a presence or a whole rotation, e.g. from a database.
|
|
18
|
-
* A rotation is played in full, then the function is called again.
|
|
19
|
-
*/
|
|
20
|
-
export type PresenceSourceFunction = (context: PresenceContext) => Presence | PresenceStep[] | Promise<Presence | PresenceStep[]>;
|
|
21
|
-
/** Stops listening for changes. */
|
|
22
|
-
export type PresenceWatchCleanup = () => void;
|
|
23
|
-
export interface PresenceDefinition {
|
|
24
|
-
presence: PresenceSourceFunction;
|
|
25
|
-
/**
|
|
26
|
-
* When `presence` returns a single presence: delay before calling it again,
|
|
27
|
-
* in milliseconds (minimum 5000). Without it, it is called once.
|
|
28
|
-
*/
|
|
29
|
-
interval?: number;
|
|
30
|
-
/**
|
|
31
|
-
* Calls `refresh` whenever the data behind `presence` changes (database
|
|
32
|
-
* realtime, webhook…) to apply it right away. Return a cleanup function.
|
|
33
|
-
*/
|
|
34
|
-
watch?: (refresh: () => void) => void | PresenceWatchCleanup | Promise<void | PresenceWatchCleanup>;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* - `Presence`: a fixed presence
|
|
38
|
-
* - `PresenceStep[]`: a rotation, each step shown for its own `duration`
|
|
39
|
-
* - a function: a presence or a rotation computed at runtime
|
|
40
|
-
* - `PresenceDefinition`: a function with `interval` and/or `watch`
|
|
41
|
-
*/
|
|
42
|
-
export type PresenceInput = Presence | readonly PresenceStep[] | PresenceSourceFunction | PresenceDefinition;
|
|
43
|
-
/** Defines the bot's status and activity in `src/presence.ts`. */
|
|
44
|
-
export declare function definePresence<const T extends PresenceInput>(input: T & CheckDurations<T>): T;
|
|
45
|
-
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
46
|
-
type IntegerPart<S extends string> = S extends `${infer I}.${string}` ? I : S;
|
|
47
|
-
type IsAtLeast5000<N extends number> = number extends N ? true : `${N}` extends `-${string}` ? false : `${N}` extends `${string}e+${string}` ? true : IntegerPart<`${N}`> extends `${'5' | '6' | '7' | '8' | '9'}${Digit}${Digit}${Digit}` ? true : IntegerPart<`${N}`> extends `${Exclude<Digit, '0'>}${Digit}${Digit}${Digit}${Digit}${string}` ? true : false;
|
|
48
|
-
/** A required key that can't be provided: its name is the error shown in the editor. */
|
|
49
|
-
type Fails<Key extends string> = {
|
|
50
|
-
[K in Key]: never;
|
|
51
|
-
};
|
|
52
|
-
type CheckKey<T, Key extends string> = T extends {
|
|
53
|
-
readonly [K in Key]: infer N extends number;
|
|
54
|
-
} ? IsAtLeast5000<N> extends true ? unknown : Fails<`⛔ ${Key} must be at least 5000 ms`> : unknown;
|
|
55
|
-
type CheckDurations<T> = T extends readonly unknown[] ? {
|
|
56
|
-
[K in keyof T]: CheckKey<T[K], 'duration'>;
|
|
57
|
-
} : CheckKey<T, 'interval'>;
|
|
58
|
-
/** Recomputes the presence right away, e.g. after updating it in a database. */
|
|
59
|
-
export declare function refreshPresence(): void;
|
|
60
|
-
interface NormalizedStep {
|
|
61
|
-
/** Without duration, the rotation stops after this step. */
|
|
62
|
-
duration?: number;
|
|
63
|
-
presence: PresenceFunction;
|
|
64
|
-
}
|
|
65
|
-
interface PresenceLogger {
|
|
66
|
-
error: (error: unknown) => void;
|
|
67
|
-
warn: (message: string) => void;
|
|
68
|
-
}
|
|
69
|
-
/** Every input is normalized into a source giving the steps of each cycle. */
|
|
70
|
-
export interface PresenceSource {
|
|
71
|
-
load: (context: PresenceContext, warn: (message: string) => void) => Promise<NormalizedStep[]>;
|
|
72
|
-
watch?: PresenceDefinition['watch'];
|
|
73
|
-
/**
|
|
74
|
-
* First presence when it is known without running any code, sent when
|
|
75
|
-
* connecting: Discord shows it right away instead of a default presence.
|
|
76
|
-
*/
|
|
77
|
-
initial?: Presence;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Loads `src/presence.ts`, or returns null when the project has none. Errors
|
|
81
|
-
* are prefixed with the file (and line when known).
|
|
82
|
-
*/
|
|
83
|
-
export declare function loadPresence(cwd?: string): Promise<PresenceSource | null>;
|
|
84
|
-
export declare function watchPresence(onChange: () => void, cwd?: string): import("fs").FSWatcher | null;
|
|
85
|
-
/**
|
|
86
|
-
* Plays the steps of each cycle in order, then loads the next cycle. Each step
|
|
87
|
-
* waits for its `presence` call to settle, then for its `duration`, so slow
|
|
88
|
-
* calls never overlap. `refresh` (from `watch` or `refreshPresence`) restarts
|
|
89
|
-
* from a fresh cycle. Returns a stop function.
|
|
90
|
-
*/
|
|
91
|
-
export declare function startPresenceLoop(gateway: Gateway, source: PresenceSource, log: PresenceLogger): () => void;
|
|
92
|
-
export {};
|
package/dist/presence.js
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { describeLoadError, findFile, importFresh, watchFiles } from './utils/modules.js';
|
|
3
|
-
/** Defines the bot's status and activity in `src/presence.ts`. */
|
|
4
|
-
export function definePresence(input) {
|
|
5
|
-
return input;
|
|
6
|
-
}
|
|
7
|
-
let activeRefresh = null;
|
|
8
|
-
/** Recomputes the presence right away, e.g. after updating it in a database. */
|
|
9
|
-
export function refreshPresence() {
|
|
10
|
-
activeRefresh?.();
|
|
11
|
-
}
|
|
12
|
-
const PRESENCE_FILES = ['presence.ts', 'presence.mts', 'presence.js', 'presence.mjs'];
|
|
13
|
-
/** Matches the client throttle, a shorter duration would only skip updates. */
|
|
14
|
-
const MIN_DURATION = 5_000;
|
|
15
|
-
/** A `presence` call taking longer is considered failed. */
|
|
16
|
-
const PRESENCE_TIMEOUT = 10_000;
|
|
17
|
-
/** Delay before calling `presence` again when it gave nothing to show. */
|
|
18
|
-
const RETRY_DELAY = 30_000;
|
|
19
|
-
/** Groups the refresh calls fired by a burst of changes. */
|
|
20
|
-
const REFRESH_DEBOUNCE = 500;
|
|
21
|
-
const srcDir = (cwd) => resolve(cwd, 'src');
|
|
22
|
-
/**
|
|
23
|
-
* Loads `src/presence.ts`, or returns null when the project has none. Errors
|
|
24
|
-
* are prefixed with the file (and line when known).
|
|
25
|
-
*/
|
|
26
|
-
export async function loadPresence(cwd = process.cwd()) {
|
|
27
|
-
const path = findFile(srcDir(cwd), PRESENCE_FILES);
|
|
28
|
-
if (!path)
|
|
29
|
-
return null;
|
|
30
|
-
try {
|
|
31
|
-
const input = (await importFresh(path)).default;
|
|
32
|
-
if (!input || (typeof input !== 'object' && typeof input !== 'function')) {
|
|
33
|
-
throw new Error("doesn't export a presence. Add at the end of the file: export default definePresence({ activity: 'Hello' })");
|
|
34
|
-
}
|
|
35
|
-
return normalize(input);
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
throw new Error(describeLoadError(error, path, cwd), { cause: error });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function normalize(input) {
|
|
42
|
-
if (typeof input === 'function')
|
|
43
|
-
return { load: fromFunction(input) };
|
|
44
|
-
if (Array.isArray(input)) {
|
|
45
|
-
// Written in code: invalid steps are errors, reported before the bot starts
|
|
46
|
-
if (input.length === 0)
|
|
47
|
-
throw new Error('the list of presences is empty: add at least one.');
|
|
48
|
-
const steps = input.map((step, index) => {
|
|
49
|
-
assertDuration(step.duration, `step ${index + 1}: duration`);
|
|
50
|
-
return { duration: step.duration, presence: toFunction(step) };
|
|
51
|
-
});
|
|
52
|
-
const first = input[0];
|
|
53
|
-
const initial = 'presence' in first && typeof first.presence === 'function' ? undefined : first;
|
|
54
|
-
return { load: async () => steps, initial };
|
|
55
|
-
}
|
|
56
|
-
if ('presence' in input && typeof input.presence === 'function') {
|
|
57
|
-
if (input.interval !== undefined)
|
|
58
|
-
assertDuration(input.interval, 'interval');
|
|
59
|
-
return { load: fromFunction(input.presence, input.interval), watch: input.watch };
|
|
60
|
-
}
|
|
61
|
-
return { load: async () => [{ presence: () => input }], initial: input };
|
|
62
|
-
}
|
|
63
|
-
function fromFunction(fn, interval) {
|
|
64
|
-
return async (context, warn) => {
|
|
65
|
-
const result = await fn(context);
|
|
66
|
-
if (Array.isArray(result))
|
|
67
|
-
return sanitizeSteps(result, warn);
|
|
68
|
-
if (result && typeof result === 'object')
|
|
69
|
-
return [{ duration: interval, presence: () => result }];
|
|
70
|
-
throw new Error(`presence() returned ${result === undefined ? 'nothing' : JSON.stringify(result)}: it must return a presence, e.g. { activity: 'Hello' }, or a list of steps.`);
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Steps computed at runtime may come from a database edited by someone else,
|
|
75
|
-
* so they are fixed with a warning instead of stopping the bot.
|
|
76
|
-
*/
|
|
77
|
-
function sanitizeSteps(steps, warn) {
|
|
78
|
-
const valid = [];
|
|
79
|
-
steps.forEach((step, index) => {
|
|
80
|
-
const name = `step ${index + 1}`;
|
|
81
|
-
if (!step || typeof step !== 'object' || typeof step.duration !== 'number' || !(step.duration > 0)) {
|
|
82
|
-
warn(`${name} ignored: it needs a duration in milliseconds, e.g. duration: 10_000.`);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
let duration = step.duration;
|
|
86
|
-
if (duration < MIN_DURATION) {
|
|
87
|
-
warn(`${name}: duration ${duration} ms raised to ${MIN_DURATION} ms (Discord limits how often a presence can change).`);
|
|
88
|
-
duration = MIN_DURATION;
|
|
89
|
-
}
|
|
90
|
-
valid.push({ duration, presence: toFunction(step) });
|
|
91
|
-
});
|
|
92
|
-
return valid;
|
|
93
|
-
}
|
|
94
|
-
function toFunction(input) {
|
|
95
|
-
if ('presence' in input && typeof input.presence === 'function')
|
|
96
|
-
return input.presence;
|
|
97
|
-
// Extra keys such as `duration` are ignored when sent to Discord
|
|
98
|
-
return () => input;
|
|
99
|
-
}
|
|
100
|
-
function assertDuration(value, name) {
|
|
101
|
-
if (typeof value !== 'number' || value < MIN_DURATION) {
|
|
102
|
-
throw new Error(`${name} is ${typeof value === 'number' ? `${value} ms` : JSON.stringify(value)}, it must be at least ${MIN_DURATION} ms (${MIN_DURATION / 1000} seconds): ` +
|
|
103
|
-
'Discord limits how often a bot can change its presence.');
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
export function watchPresence(onChange, cwd = process.cwd()) {
|
|
107
|
-
return watchFiles(srcDir(cwd), PRESENCE_FILES, onChange);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Plays the steps of each cycle in order, then loads the next cycle. Each step
|
|
111
|
-
* waits for its `presence` call to settle, then for its `duration`, so slow
|
|
112
|
-
* calls never overlap. `refresh` (from `watch` or `refreshPresence`) restarts
|
|
113
|
-
* from a fresh cycle. Returns a stop function.
|
|
114
|
-
*/
|
|
115
|
-
export function startPresenceLoop(gateway, source, log) {
|
|
116
|
-
const context = { client: gateway.client };
|
|
117
|
-
let stopped = false;
|
|
118
|
-
/** Incremented on refresh and stop; a run whose generation is outdated exits. */
|
|
119
|
-
let generation = 0;
|
|
120
|
-
let lastSteps = null;
|
|
121
|
-
/**
|
|
122
|
-
* Issues of the previous and current cycle: an issue already reported in the
|
|
123
|
-
* previous cycle is not logged again, so a bad row isn't reported every cycle.
|
|
124
|
-
*/
|
|
125
|
-
let previousIssues = new Set();
|
|
126
|
-
let currentIssues = new Set();
|
|
127
|
-
let sleepTimeout;
|
|
128
|
-
let wake;
|
|
129
|
-
let refreshTimeout;
|
|
130
|
-
let cleanupWatch;
|
|
131
|
-
const report = (level, issue) => {
|
|
132
|
-
const message = issue instanceof Error ? issue.message : String(issue);
|
|
133
|
-
const key = `${level}:${message}`;
|
|
134
|
-
if (currentIssues.has(key))
|
|
135
|
-
return;
|
|
136
|
-
currentIssues.add(key);
|
|
137
|
-
if (!previousIssues.has(key))
|
|
138
|
-
log[level](message);
|
|
139
|
-
};
|
|
140
|
-
const startCycle = () => {
|
|
141
|
-
previousIssues = currentIssues;
|
|
142
|
-
currentIssues = new Set();
|
|
143
|
-
};
|
|
144
|
-
/** Resolves to false if a refresh or stop happened meanwhile. */
|
|
145
|
-
const sleep = (ms, id) => new Promise((resolve) => {
|
|
146
|
-
wake = resolve;
|
|
147
|
-
sleepTimeout = setTimeout(() => resolve(id === generation), ms);
|
|
148
|
-
});
|
|
149
|
-
const loadSteps = async (id) => {
|
|
150
|
-
try {
|
|
151
|
-
const warnings = [];
|
|
152
|
-
const steps = await withTimeout(source.load(context, (message) => warnings.push(message)), PRESENCE_TIMEOUT);
|
|
153
|
-
if (id !== generation)
|
|
154
|
-
return null;
|
|
155
|
-
for (const message of warnings)
|
|
156
|
-
report('warn', message);
|
|
157
|
-
if (steps.length > 0)
|
|
158
|
-
return (lastSteps = steps);
|
|
159
|
-
report('warn', `presence() returned an empty list, trying again in ${RETRY_DELAY / 1000}s.`);
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
if (id !== generation)
|
|
164
|
-
return null;
|
|
165
|
-
report('error', error);
|
|
166
|
-
// Keep playing the previous rotation until the next attempt
|
|
167
|
-
return lastSteps;
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
const run = async (id) => {
|
|
171
|
-
while (id === generation) {
|
|
172
|
-
startCycle();
|
|
173
|
-
const steps = await loadSteps(id);
|
|
174
|
-
if (id !== generation)
|
|
175
|
-
return;
|
|
176
|
-
if (!steps) {
|
|
177
|
-
if (!(await sleep(RETRY_DELAY, id)))
|
|
178
|
-
return;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
for (const step of steps) {
|
|
182
|
-
try {
|
|
183
|
-
const presence = await withTimeout(Promise.resolve(step.presence(context)), PRESENCE_TIMEOUT);
|
|
184
|
-
if (id === generation)
|
|
185
|
-
gateway.setPresence(presence);
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
// The previous presence stays in place, the rotation goes on
|
|
189
|
-
if (id === generation)
|
|
190
|
-
report('error', error);
|
|
191
|
-
}
|
|
192
|
-
if (id !== generation || step.duration === undefined)
|
|
193
|
-
return;
|
|
194
|
-
if (!(await sleep(step.duration, id)))
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
const restart = () => {
|
|
200
|
-
generation++;
|
|
201
|
-
clearTimeout(sleepTimeout);
|
|
202
|
-
wake?.(false);
|
|
203
|
-
void run(generation);
|
|
204
|
-
};
|
|
205
|
-
const refresh = () => {
|
|
206
|
-
if (stopped)
|
|
207
|
-
return;
|
|
208
|
-
clearTimeout(refreshTimeout);
|
|
209
|
-
refreshTimeout = setTimeout(restart, REFRESH_DEBOUNCE);
|
|
210
|
-
};
|
|
211
|
-
activeRefresh = refresh;
|
|
212
|
-
restart();
|
|
213
|
-
if (source.watch) {
|
|
214
|
-
Promise.resolve()
|
|
215
|
-
.then(() => source.watch(refresh))
|
|
216
|
-
.then((cleanup) => {
|
|
217
|
-
if (!cleanup)
|
|
218
|
-
return;
|
|
219
|
-
if (stopped)
|
|
220
|
-
cleanup();
|
|
221
|
-
else
|
|
222
|
-
cleanupWatch = cleanup;
|
|
223
|
-
})
|
|
224
|
-
.catch((error) => report('error', error));
|
|
225
|
-
}
|
|
226
|
-
return () => {
|
|
227
|
-
stopped = true;
|
|
228
|
-
generation++;
|
|
229
|
-
clearTimeout(sleepTimeout);
|
|
230
|
-
clearTimeout(refreshTimeout);
|
|
231
|
-
wake?.(false);
|
|
232
|
-
if (activeRefresh === refresh)
|
|
233
|
-
activeRefresh = null;
|
|
234
|
-
try {
|
|
235
|
-
cleanupWatch?.();
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
log.error(error);
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
function withTimeout(promise, ms) {
|
|
243
|
-
let timeout;
|
|
244
|
-
return Promise.race([
|
|
245
|
-
promise,
|
|
246
|
-
new Promise((_, reject) => {
|
|
247
|
-
timeout = setTimeout(() => reject(new Error(`presence() took more than ${ms / 1000}s to return, keeping the previous presence.`)), ms);
|
|
248
|
-
}),
|
|
249
|
-
]).finally(() => clearTimeout(timeout));
|
|
250
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import type { Client } from '../discord/client.js';
|
|
2
|
-
import type { APIChannel, Snowflake } from '../discord/types.js';
|
|
3
|
-
import { Guild } from './Guild.js';
|
|
4
|
-
import { Message } from './Message.js';
|
|
5
|
-
import { type MessageOptions } from './utils.js';
|
|
6
|
-
export declare const ChannelType: {
|
|
7
|
-
readonly GuildText: 0;
|
|
8
|
-
readonly DM: 1;
|
|
9
|
-
readonly GuildVoice: 2;
|
|
10
|
-
readonly GroupDM: 3;
|
|
11
|
-
readonly GuildCategory: 4;
|
|
12
|
-
readonly GuildAnnouncement: 5;
|
|
13
|
-
readonly AnnouncementThread: 10;
|
|
14
|
-
readonly PublicThread: 11;
|
|
15
|
-
readonly PrivateThread: 12;
|
|
16
|
-
readonly GuildStageVoice: 13;
|
|
17
|
-
readonly GuildDirectory: 14;
|
|
18
|
-
readonly GuildForum: 15;
|
|
19
|
-
readonly GuildMedia: 16;
|
|
20
|
-
};
|
|
21
|
-
export interface FetchMessagesOptions {
|
|
22
|
-
/** 1 to 100, defaults to 50. */
|
|
23
|
-
limit?: number;
|
|
24
|
-
before?: Snowflake;
|
|
25
|
-
after?: Snowflake;
|
|
26
|
-
around?: Snowflake;
|
|
27
|
-
}
|
|
28
|
-
export interface CreateThreadOptions {
|
|
29
|
-
/** 1 to 100 characters. */
|
|
30
|
-
name: string;
|
|
31
|
-
/** Minutes of inactivity before the thread is hidden: 60, 1440, 4320 or 10080. */
|
|
32
|
-
autoArchiveDuration?: 60 | 1440 | 4320 | 10080;
|
|
33
|
-
/** Seconds between two messages of a user, 0 to 21600. */
|
|
34
|
-
rateLimitPerUser?: number;
|
|
35
|
-
/** `ChannelType.PrivateThread` for a private thread. Without message only. */
|
|
36
|
-
type?: number;
|
|
37
|
-
/** Whether non-moderators can add other non-moderators. Private threads only. */
|
|
38
|
-
invitable?: boolean;
|
|
39
|
-
reason?: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* A channel or thread. Events often only send its id: fields Discord didn't
|
|
43
|
-
* send are undefined, `fetch()` returns the full channel.
|
|
44
|
-
* https://docs.discord.com/developers/resources/channel#channel-object
|
|
45
|
-
*/
|
|
46
|
-
export declare class Channel {
|
|
47
|
-
readonly client: Client;
|
|
48
|
-
readonly raw: Partial<APIChannel> & {
|
|
49
|
-
id: Snowflake;
|
|
50
|
-
};
|
|
51
|
-
readonly id: Snowflake;
|
|
52
|
-
/** See `ChannelType`. Undefined when only the id is known. */
|
|
53
|
-
readonly type: number | undefined;
|
|
54
|
-
readonly guildId: Snowflake | null;
|
|
55
|
-
readonly name: string | null | undefined;
|
|
56
|
-
readonly topic: string | null | undefined;
|
|
57
|
-
readonly nsfw: boolean | undefined;
|
|
58
|
-
readonly position: number | undefined;
|
|
59
|
-
/** Category of a channel, or parent channel of a thread. */
|
|
60
|
-
readonly parentId: Snowflake | null | undefined;
|
|
61
|
-
readonly lastMessageId: Snowflake | null | undefined;
|
|
62
|
-
/** Slowmode, in seconds. */
|
|
63
|
-
readonly rateLimitPerUser: number | undefined;
|
|
64
|
-
constructor(client: Client, raw: Partial<APIChannel> & {
|
|
65
|
-
id: Snowflake;
|
|
66
|
-
});
|
|
67
|
-
/** Server of the channel, null for DMs. */
|
|
68
|
-
get guild(): Guild | null;
|
|
69
|
-
get createdAt(): Date;
|
|
70
|
-
get url(): string;
|
|
71
|
-
isThread(): boolean;
|
|
72
|
-
isDM(): boolean;
|
|
73
|
-
isVoice(): boolean;
|
|
74
|
-
/** Mention, e.g. `${channel}` in a message. */
|
|
75
|
-
toString(): string;
|
|
76
|
-
/** https://docs.discord.com/developers/resources/message#create-message */
|
|
77
|
-
send(options: MessageOptions): Promise<Message>;
|
|
78
|
-
/**
|
|
79
|
-
* Shows "Bot is typing…" for 10 seconds or until the bot sends a message.
|
|
80
|
-
* https://docs.discord.com/developers/resources/channel#trigger-typing-indicator
|
|
81
|
-
*/
|
|
82
|
-
sendTyping(): Promise<void>;
|
|
83
|
-
/** https://docs.discord.com/developers/resources/message#get-channel-message */
|
|
84
|
-
fetchMessage(id: Snowflake): Promise<Message>;
|
|
85
|
-
/** Newest first. https://docs.discord.com/developers/resources/message#get-channel-messages */
|
|
86
|
-
fetchMessages(options?: FetchMessagesOptions): Promise<Message[]>;
|
|
87
|
-
/**
|
|
88
|
-
* Deletes 2 to 100 messages at once, none older than 2 weeks.
|
|
89
|
-
* https://docs.discord.com/developers/resources/message#bulk-delete-messages
|
|
90
|
-
*/
|
|
91
|
-
bulkDelete(messageIds: Snowflake[], reason?: string): Promise<void>;
|
|
92
|
-
/** https://docs.discord.com/developers/resources/channel#start-thread-without-message */
|
|
93
|
-
createThread(options: CreateThreadOptions): Promise<Channel>;
|
|
94
|
-
/** https://docs.discord.com/developers/resources/channel#get-channel */
|
|
95
|
-
fetch(): Promise<Channel>;
|
|
96
|
-
/**
|
|
97
|
-
* Updates the channel with fields of the documented JSON params (snake_case).
|
|
98
|
-
* https://docs.discord.com/developers/resources/channel#modify-channel
|
|
99
|
-
*/
|
|
100
|
-
edit(data: Record<string, unknown>, reason?: string): Promise<Channel>;
|
|
101
|
-
/** Cannot be undone for guild channels. https://docs.discord.com/developers/resources/channel#deleteclose-channel */
|
|
102
|
-
delete(reason?: string): Promise<void>;
|
|
103
|
-
}
|
|
104
|
-
export declare function toThreadBody(options: Omit<CreateThreadOptions, 'reason'>): {
|
|
105
|
-
name: string;
|
|
106
|
-
type?: number;
|
|
107
|
-
invitable?: boolean;
|
|
108
|
-
auto_archive_duration?: 60 | 1440 | 4320 | 10080 | undefined;
|
|
109
|
-
rate_limit_per_user?: number | undefined;
|
|
110
|
-
};
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { Guild } from './Guild.js';
|
|
2
|
-
import { Message } from './Message.js';
|
|
3
|
-
import { snowflakeDate, toMessageBody } from './utils.js';
|
|
4
|
-
// https://docs.discord.com/developers/resources/channel#channel-object-channel-types
|
|
5
|
-
export const ChannelType = {
|
|
6
|
-
GuildText: 0,
|
|
7
|
-
DM: 1,
|
|
8
|
-
GuildVoice: 2,
|
|
9
|
-
GroupDM: 3,
|
|
10
|
-
GuildCategory: 4,
|
|
11
|
-
GuildAnnouncement: 5,
|
|
12
|
-
AnnouncementThread: 10,
|
|
13
|
-
PublicThread: 11,
|
|
14
|
-
PrivateThread: 12,
|
|
15
|
-
GuildStageVoice: 13,
|
|
16
|
-
GuildDirectory: 14,
|
|
17
|
-
GuildForum: 15,
|
|
18
|
-
GuildMedia: 16,
|
|
19
|
-
};
|
|
20
|
-
const THREAD_TYPES = [
|
|
21
|
-
ChannelType.AnnouncementThread,
|
|
22
|
-
ChannelType.PublicThread,
|
|
23
|
-
ChannelType.PrivateThread,
|
|
24
|
-
];
|
|
25
|
-
/**
|
|
26
|
-
* A channel or thread. Events often only send its id: fields Discord didn't
|
|
27
|
-
* send are undefined, `fetch()` returns the full channel.
|
|
28
|
-
* https://docs.discord.com/developers/resources/channel#channel-object
|
|
29
|
-
*/
|
|
30
|
-
export class Channel {
|
|
31
|
-
client;
|
|
32
|
-
raw;
|
|
33
|
-
id;
|
|
34
|
-
/** See `ChannelType`. Undefined when only the id is known. */
|
|
35
|
-
type;
|
|
36
|
-
guildId;
|
|
37
|
-
name;
|
|
38
|
-
topic;
|
|
39
|
-
nsfw;
|
|
40
|
-
position;
|
|
41
|
-
/** Category of a channel, or parent channel of a thread. */
|
|
42
|
-
parentId;
|
|
43
|
-
lastMessageId;
|
|
44
|
-
/** Slowmode, in seconds. */
|
|
45
|
-
rateLimitPerUser;
|
|
46
|
-
constructor(client, raw) {
|
|
47
|
-
this.client = client;
|
|
48
|
-
this.raw = raw;
|
|
49
|
-
this.id = raw.id;
|
|
50
|
-
this.type = raw.type;
|
|
51
|
-
this.guildId = raw.guild_id ?? null;
|
|
52
|
-
this.name = raw.name;
|
|
53
|
-
this.topic = raw.topic;
|
|
54
|
-
this.nsfw = raw.nsfw;
|
|
55
|
-
this.position = raw.position;
|
|
56
|
-
this.parentId = raw.parent_id;
|
|
57
|
-
this.lastMessageId = raw.last_message_id;
|
|
58
|
-
this.rateLimitPerUser = raw.rate_limit_per_user;
|
|
59
|
-
}
|
|
60
|
-
/** Server of the channel, null for DMs. */
|
|
61
|
-
get guild() {
|
|
62
|
-
return this.guildId ? new Guild(this.client, { id: this.guildId }) : null;
|
|
63
|
-
}
|
|
64
|
-
get createdAt() {
|
|
65
|
-
return snowflakeDate(this.id);
|
|
66
|
-
}
|
|
67
|
-
get url() {
|
|
68
|
-
return `https://discord.com/channels/${this.guildId ?? '@me'}/${this.id}`;
|
|
69
|
-
}
|
|
70
|
-
isThread() {
|
|
71
|
-
return this.type !== undefined && THREAD_TYPES.includes(this.type);
|
|
72
|
-
}
|
|
73
|
-
isDM() {
|
|
74
|
-
return this.type === ChannelType.DM || this.type === ChannelType.GroupDM;
|
|
75
|
-
}
|
|
76
|
-
isVoice() {
|
|
77
|
-
return (this.type === ChannelType.GuildVoice ||
|
|
78
|
-
this.type === ChannelType.GuildStageVoice);
|
|
79
|
-
}
|
|
80
|
-
/** Mention, e.g. `${channel}` in a message. */
|
|
81
|
-
toString() {
|
|
82
|
-
return `<#${this.id}>`;
|
|
83
|
-
}
|
|
84
|
-
/** https://docs.discord.com/developers/resources/message#create-message */
|
|
85
|
-
async send(options) {
|
|
86
|
-
const { body, files } = toMessageBody(options);
|
|
87
|
-
const message = await this.client.rest.post(`/channels/${this.id}/messages`, {
|
|
88
|
-
body,
|
|
89
|
-
files,
|
|
90
|
-
});
|
|
91
|
-
return new Message(this.client, {
|
|
92
|
-
guild_id: this.guildId ?? undefined,
|
|
93
|
-
...message,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Shows "Bot is typing…" for 10 seconds or until the bot sends a message.
|
|
98
|
-
* https://docs.discord.com/developers/resources/channel#trigger-typing-indicator
|
|
99
|
-
*/
|
|
100
|
-
async sendTyping() {
|
|
101
|
-
await this.client.rest.post(`/channels/${this.id}/typing`);
|
|
102
|
-
}
|
|
103
|
-
/** https://docs.discord.com/developers/resources/message#get-channel-message */
|
|
104
|
-
async fetchMessage(id) {
|
|
105
|
-
const message = await this.client.rest.get(`/channels/${this.id}/messages/${id}`);
|
|
106
|
-
return new Message(this.client, {
|
|
107
|
-
guild_id: this.guildId ?? undefined,
|
|
108
|
-
...message,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
/** Newest first. https://docs.discord.com/developers/resources/message#get-channel-messages */
|
|
112
|
-
async fetchMessages(options = {}) {
|
|
113
|
-
const messages = await this.client.rest.get(`/channels/${this.id}/messages`, {
|
|
114
|
-
query: { ...options },
|
|
115
|
-
});
|
|
116
|
-
return messages.map(message => new Message(this.client, {
|
|
117
|
-
guild_id: this.guildId ?? undefined,
|
|
118
|
-
...message,
|
|
119
|
-
}));
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Deletes 2 to 100 messages at once, none older than 2 weeks.
|
|
123
|
-
* https://docs.discord.com/developers/resources/message#bulk-delete-messages
|
|
124
|
-
*/
|
|
125
|
-
async bulkDelete(messageIds, reason) {
|
|
126
|
-
await this.client.rest.post(`/channels/${this.id}/messages/bulk-delete`, {
|
|
127
|
-
body: { messages: messageIds },
|
|
128
|
-
reason,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
/** https://docs.discord.com/developers/resources/channel#start-thread-without-message */
|
|
132
|
-
async createThread(options) {
|
|
133
|
-
const { reason, ...thread } = options;
|
|
134
|
-
const channel = await this.client.rest.post(`/channels/${this.id}/threads`, {
|
|
135
|
-
body: toThreadBody(thread),
|
|
136
|
-
reason,
|
|
137
|
-
});
|
|
138
|
-
return new Channel(this.client, channel);
|
|
139
|
-
}
|
|
140
|
-
/** https://docs.discord.com/developers/resources/channel#get-channel */
|
|
141
|
-
async fetch() {
|
|
142
|
-
return new Channel(this.client, await this.client.rest.get(`/channels/${this.id}`));
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Updates the channel with fields of the documented JSON params (snake_case).
|
|
146
|
-
* https://docs.discord.com/developers/resources/channel#modify-channel
|
|
147
|
-
*/
|
|
148
|
-
async edit(data, reason) {
|
|
149
|
-
const channel = await this.client.rest.patch(`/channels/${this.id}`, {
|
|
150
|
-
body: data,
|
|
151
|
-
reason,
|
|
152
|
-
});
|
|
153
|
-
return new Channel(this.client, channel);
|
|
154
|
-
}
|
|
155
|
-
/** Cannot be undone for guild channels. https://docs.discord.com/developers/resources/channel#deleteclose-channel */
|
|
156
|
-
async delete(reason) {
|
|
157
|
-
await this.client.rest.delete(`/channels/${this.id}`, { reason });
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
export function toThreadBody(options) {
|
|
161
|
-
const { autoArchiveDuration, rateLimitPerUser, ...rest } = options;
|
|
162
|
-
return {
|
|
163
|
-
...rest,
|
|
164
|
-
...(autoArchiveDuration !== undefined && {
|
|
165
|
-
auto_archive_duration: autoArchiveDuration,
|
|
166
|
-
}),
|
|
167
|
-
...(rateLimitPerUser !== undefined && {
|
|
168
|
-
rate_limit_per_user: rateLimitPerUser,
|
|
169
|
-
}),
|
|
170
|
-
};
|
|
171
|
-
}
|