Skip to content

Commit 6ff5e17

Browse files
docs: initialize TypeDoc
1 parent ab716fe commit 6ff5e17

File tree

8 files changed

+385
-58
lines changed

8 files changed

+385
-58
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
run: npm ci
2828

2929
- name: Build TypeDoc
30-
run: npx typedoc
30+
run: npm run doc:build
3131

3232
- name: Upload to GitHub Pages artifact
3333
uses: actions/upload-pages-artifact@v3

src/adapter/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/**
2+
* Represents a generic HTTP adapter for handling incoming requests and responses.
3+
*
4+
* **Required Methods:**
5+
* - `listen(endpoint, handler, ...args)` – Starts listening on a given endpoint and routes
6+
* incoming requests to the provided handler.
7+
* - `getRequestBody(req)` – Retrieves the raw body of a request as a `Uint8Array`.
8+
*
9+
* Any adapter must implement these methods to be compatible with this library.
10+
*
11+
* Prebuilt adapters are available:
12+
* - [Node.js Adapter](https://www.npmjs.com/package/@discordhttps/nodejs-adapter)
13+
* - [Cloudflare Adapter](https://www.npmjs.com/package/@discordhttps/cloudflare-adapter)
14+
*/
15+
116
export interface HttpAdapter {
217
listen(
318
endpoint: string,
@@ -8,12 +23,20 @@ export interface HttpAdapter {
823
getRequestBody(req: any): Promise<Uint8Array>;
924
}
1025

26+
/**
27+
* Represents a response object for an HTTP adapter.
28+
*/
29+
1130
export interface HttpAdapterSererResponse {
1231
headersSent: boolean;
1332
writeHead(status: number, headers?: Record<string, string>): void;
1433
end(chunk?: string): void;
1534
}
1635

36+
/**
37+
* Represents a request object for an HTTP adapter.
38+
*/
39+
1740
export interface HttpAdapterRequest {
1841
method: string;
1942
url: string;

src/index.ts

Lines changed: 126 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import HttpInteractionServer from "./interactionServer.js";
66
import InteractionRouterManger from "./interactionRouter/internal.js";
77
import AutoCompleteKeyBuilder from "./interactionRouter/autoCompleteKeyBuilder.js";
88

9-
109
import type { HttpAdapter, HttpAdapterSererResponse } from "./adapter/index.js";
1110

1211
import {
@@ -34,36 +33,131 @@ import type {
3433
CommandbuilderType,
3534
} from "./interactionRouter/internal.js";
3635

36+
import type { MessageMentionOptions } from "discord.js";
37+
3738
export interface ClientOptions {
3839
token: string;
3940
publicKey: string;
4041
httpAdapter: HttpAdapter;
4142
debug?: boolean;
4243
}
4344

45+
/**
46+
* Discord HTTPS Interaction Client.
47+
*
48+
* Handles registration of commands, buttons, modals, select menus, context menus,
49+
* and autocomplete interactions with their associated middleware.
50+
*
51+
* Also exposes a {@link REST} client for direct API calls.
52+
*
53+
* @example
54+
* ```ts
55+
* import Client from "./Client.js";
56+
* import NodeAdapter from "@discordhttps/nodejs-adapter";
57+
*
58+
* const client = new Client({
59+
* token: process.env.BOT_TOKEN!,
60+
* publicKey: process.env.PUBLIC_KEY!,
61+
* httpAdapter: new NodeAdapter(),
62+
* });
63+
*
64+
* client.command(
65+
* (builder) => builder.setName("ping").setDescription("Replies with Pong!"),
66+
* async (interaction, client, _, res) => {
67+
* res.writeHead(200, {
68+
* "Content-Type": "application/json",
69+
* });
70+
* const username = interaction.user
71+
* ? interaction.user.global_name
72+
* : interaction.member.user.global_name;
73+
* res.end(
74+
* JSON.stringify({
75+
* type: InteractionResponseType.ChannelMessageWithSource,
76+
* data: {
77+
* content: `Hello! ${username}`,
78+
* },
79+
* })
80+
* );
81+
* }
82+
* );
83+
*
84+
* await client.listen("interactions", 3000, () => {
85+
* console.log(
86+
* "Listening for interactions on port 3000 at the /interactions endpoint"
87+
* );
88+
* });
89+
* ```
90+
*/
91+
4492
class Client extends HttpInteractionServer {
93+
/** Interaction router manager responsible for routing incoming interactions. */
4594
private router = new InteractionRouterManger();
46-
client = new REST({
47-
version: "10",
48-
});
95+
96+
/**
97+
* REST API client instance used for interacting with Discord's HTTP API.
98+
*
99+
* @see {@link https://discord.js.org/docs/packages/rest/main | REST Documentation}
100+
*/
101+
readonly rest!: REST;
102+
103+
/**
104+
* Creates a new Discord HTTPS Interaction Client.
105+
*
106+
* @param options - Client configuration options.
107+
* @param options.token - Discord bot token.
108+
* @param options.publicKey - Discord public key for interaction verification.
109+
* @param options.httpAdapter - HTTP adapter to handle incoming requests.
110+
* @param options.debug - Optional. Enable debug logging. Defaults to `false`.
111+
*/
49112

50113
constructor({ httpAdapter, publicKey, token, debug = false }: ClientOptions) {
51114
super(publicKey, httpAdapter, debug);
52-
this.client.setToken(token);
115+
Object.defineProperty(this, "rest", {
116+
value: new REST({
117+
version: "10",
118+
}),
119+
});
120+
this.rest.setToken(token);
53121
}
54122

123+
/**
124+
* Registers interaction routes.
125+
*
126+
* @param routes - {@link InteractionRouter} or {@link InteractionRouterCollector} instances.
127+
*/
128+
55129
register(...routes: Array<InteractionRouter | InteractionRouterCollector>) {
56130
this.router.register(...routes);
57131
}
58132

133+
/**
134+
* Adds global middleware that runs on every interaction.
135+
*
136+
* Receives raw {@link APIInteraction} payload and response object.
137+
*
138+
* @param fns - Middleware functions to execute.
139+
*/
140+
59141
middleware(...fns: GeneralMiddleware[]) {
60142
this.router.middlewares.push(...fns);
61143
}
62144

145+
/**
146+
* Adds global middleware for unknown interactions.
147+
*
148+
* @param fns - Functions executed when no handler matches an interaction.
149+
*/
63150
unknown(...fns: UnknownMiddleware[]) {
64151
this.router._unknownInteraction.push(...fns);
65152
}
66153

154+
/**
155+
* Ensures all middleware functions are async.
156+
*
157+
* @internal
158+
* @param fns - Functions to check.
159+
* @throws If any function is not async.
160+
*/
67161
tryAsync(fns: Function[]) {
68162
fns.forEach((fn) => {
69163
if (fn.constructor.name !== "AsyncFunction")
@@ -82,9 +176,13 @@ class Client extends HttpInteractionServer {
82176
* ```ts
83177
* router.command(
84178
* (builder) => builder.setName("Ping!").setDescription("Returns Pong!"),
85-
* (interaction) => interaction.reply({ content: "pong!" })
179+
* async (interaction) => interaction.reply({ content: "pong!" })
86180
* );
87181
* ```
182+
*
183+
* @param commandbuilder - Function returning a {@link SlashCommandBuilder}.
184+
* @param fns - Middleware functions for the command.
185+
* @returns An {@link AutoCompleteKeyBuilder} for autocomplete options.
88186
*/
89187
command(commandbuilder: CommandbuilderType, ...fns: CommandMiddleware[]) {
90188
this.tryAsync(fns);
@@ -197,7 +295,7 @@ class Client extends HttpInteractionServer {
197295
* (builder) =>
198296
* builder
199297
* .setName("weather") // The command name
200-
* .setDescription("QuQuery weather information!") // The command description
298+
* .setDescription("Query weather information!") // The command description
201299
* .addStringOption(option =>
202300
* option
203301
* .setName("city") // Option name
@@ -224,6 +322,7 @@ class Client extends HttpInteractionServer {
224322
fns
225323
);
226324
}
325+
227326
/**
228327
* Registers a user context menu interaction with its associated middleware.
229328
*
@@ -249,11 +348,13 @@ class Client extends HttpInteractionServer {
249348
this.tryAsync(fns);
250349
this.router._register("messageContextMenu", customId, fns);
251350
}
252-
253-
// protected httpInteractionPayloadHandler(
254-
// body: APIInteraction,
255-
// res: HttpAdapterSererResponse
256-
// ) {
351+
/**
352+
* Handles incoming interaction payloads from Discord.
353+
*
354+
* @internal
355+
* @param body - The raw {@link APIInteraction} payload.
356+
* @param res - HTTP response object to reply to Discord.
357+
*/
257358
protected async httpInteractionPayloadHandler(
258359
body: APIInteraction,
259360
res: HttpAdapterSererResponse
@@ -271,13 +372,20 @@ class Client extends HttpInteractionServer {
271372
}
272373
this.debug("Interaction Request Received");
273374
// this.router.__internal_dispatch(res, body, this.client);
274-
await this.router.__internal_dispatch(res, body, this.client);
375+
await this.router.__internal_dispatch(res, body, this.rest);
275376
}
377+
378+
/**
379+
* Returns helpers for registering slash commands.
380+
*
381+
* @param log - Log progress. Defaults to true.
382+
* @returns Methods to register commands globally or locally.
383+
*/
276384
async getRegistar(log = true) {
277385
const commandsBody = this.router.CommandDefinitions;
278386
var currentClient: APIApplication;
279387
try {
280-
currentClient = (await this.client.get(
388+
currentClient = (await this.rest.get(
281389
Routes.currentApplication()
282390
)) as APIApplication;
283391
} catch (e) {
@@ -317,7 +425,7 @@ class Client extends HttpInteractionServer {
317425
}
318426

319427
try {
320-
await upperThis.client.put(
428+
await upperThis.rest.put(
321429
Routes.applicationCommands(currentClient.id),
322430
{ body: commandsBody }
323431
);
@@ -357,7 +465,7 @@ class Client extends HttpInteractionServer {
357465
}
358466

359467
try {
360-
await upperThis.client.put(
468+
await upperThis.rest.put(
361469
Routes.applicationGuildCommands(currentClient.id, guildId),
362470
{ body: commandsBody }
363471
);
@@ -385,3 +493,5 @@ class Client extends HttpInteractionServer {
385493
}
386494

387495
export default Client;
496+
export * from "@discordjs/builders";
497+
export * from "discord-api-types/v10";

0 commit comments

Comments
 (0)