@seedcord/http 0.10.2 → 0.11.0-next.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/README.md +55 -9
- package/dist/index.d.mts +42 -57
- package/dist/index.mjs +144 -239
- package/dist/index.mjs.map +1 -1
- package/dist/shared-vsj1uwIH.d.mts +977 -0
- package/dist/{edge.index-DCP1BD6f.mjs → username-3UsqzTSd.mjs} +1634 -1519
- package/dist/username-3UsqzTSd.mjs.map +1 -0
- package/dist/workerd.index.d.mts +65 -0
- package/dist/workerd.index.mjs +177 -0
- package/dist/workerd.index.mjs.map +1 -0
- package/package.json +19 -27
- package/dist/Manifest-D5MEsTmH.d.mts +0 -485
- package/dist/edge.index-DCP1BD6f.mjs.map +0 -1
- package/dist/edge.index-DFszgCJp.d.mts +0 -502
- package/dist/edge.index.d.mts +0 -10
- package/dist/edge.index.mjs +0 -15
- package/dist/manifest.index.d.mts +0 -10
- package/dist/manifest.index.mjs +0 -26
- package/dist/manifest.index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://seedcord.org">Website</a> ·
|
|
11
11
|
<a href="https://seedcord.org/guide">Guide</a> ·
|
|
12
12
|
<a href="https://seedcord.org/docs">Reference</a> ·
|
|
13
|
-
<a href="https://
|
|
13
|
+
<a href="https://seedcord.org/chat/">Discord</a>
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
16
|
<br />
|
|
@@ -23,22 +23,68 @@
|
|
|
23
23
|
|
|
24
24
|
## About
|
|
25
25
|
|
|
26
|
-
`@seedcord/http`
|
|
26
|
+
`@seedcord/http` is the transport for an http bot. Discord posts each interaction to your bot's URL, and the bot checks the request's Ed25519 signature before it runs your handler. It has no discord.js dependency and keeps no connection open, so it runs on your own server or on Cloudflare Workers.
|
|
27
27
|
|
|
28
|
-
Discord posts only interactions
|
|
28
|
+
Discord posts only interactions to that URL. Use [`@seedcord/gateway`](https://www.npmjs.com/package/@seedcord/gateway) when your bot reacts to messages, members, voice, or reactions.
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
seedcord is pre-1.0, so a minor version can break your bot. Each release's changelog says what changed and how to update.
|
|
31
31
|
|
|
32
32
|
## Installation
|
|
33
33
|
|
|
34
|
+
`pnpm create seedcord` sets up a new bot and asks where it runs. To add seedcord to an existing project:
|
|
35
|
+
|
|
34
36
|
```sh
|
|
35
|
-
pnpm add @seedcord/http
|
|
37
|
+
pnpm add @seedcord/http @discordjs/builders envapt
|
|
38
|
+
pnpm add -D seedcord vite typescript
|
|
36
39
|
```
|
|
37
40
|
|
|
38
|
-
`
|
|
41
|
+
`envapt` and `typescript` are peer dependencies. `seedcord` is the CLI that runs the bot in dev and builds it. In dev, it also opens a cloudflared tunnel and sets your app's interactions URL to it.
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
`bot.ts` creates the bot and tells it where your handlers are:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { Seedcord } from '@seedcord/http';
|
|
49
|
+
import { Converters, Envapter } from 'envapt';
|
|
50
|
+
|
|
51
|
+
export default new Seedcord({
|
|
52
|
+
bot: {
|
|
53
|
+
interactions: { path: './handlers' },
|
|
54
|
+
commands: {
|
|
55
|
+
path: './commands',
|
|
56
|
+
guilds: Envapter.getAs('TESTING_GUILD_IDS', Converters.array(), [])
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
subscribers: { path: null }
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Read your environment through [envapt](https://envapt.materwelon.dev), the way `TESTING_GUILD_IDS` is read above. seedcord loads your `.env` files into envapt, and binds a worker's `env` to it on Cloudflare Workers, so the same read works in dev, in a build, and on Workers. envapt also reads your shell's variables, while `process.env` misses everything in your `.env` files.
|
|
64
|
+
|
|
65
|
+
Handlers read raw payloads from `discord-api-types`. Slash commands, components, checks, and plugins work the same way as on the gateway. The [guide](https://seedcord.org/guide) covers them.
|
|
66
|
+
|
|
67
|
+
## Where it runs
|
|
39
68
|
|
|
40
|
-
|
|
69
|
+
### Its own server
|
|
70
|
+
|
|
71
|
+
On Node or Bun, `Seedcord` listens on `port`, 3000 by default.
|
|
72
|
+
|
|
73
|
+
### Inside your server
|
|
74
|
+
|
|
75
|
+
Set `port: false`, start the bot, then pass each request to `bot.fetch()`. It takes a web `Request` and returns a `Response`, so a Hono or Next.js route can forward to it:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { Hono } from 'hono';
|
|
79
|
+
|
|
80
|
+
import bot from './bot';
|
|
81
|
+
|
|
82
|
+
await bot.start();
|
|
83
|
+
|
|
84
|
+
const app = new Hono();
|
|
85
|
+
app.post('/interactions', (c) => bot.fetch(c.req.raw));
|
|
86
|
+
```
|
|
41
87
|
|
|
42
|
-
|
|
88
|
+
### Cloudflare Workers
|
|
43
89
|
|
|
44
|
-
|
|
90
|
+
The same `Seedcord` import runs on Cloudflare Workers. A `cloudflare.config.ts` beside `seedcord.config.ts` makes `seedcord build` write a worker, which you deploy with `cf deploy --prebuilt`. The [Workers guide](https://seedcord.org/guide/build/workers) covers the setup.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,91 +1,76 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as Core, a as RoleMenuHandler, b as HttpServerConfig, c as UserMenuHandler, d as RepliableHandler, g as AutocompleteHandler, h as SentMessage, i as MentionableMenuHandler, l as ComponentHandler, m as ReplySender, n as InteractionMiddleware, o as SelectMenuHandler, p as InteractionRef, r as ChannelMenuHandler, s as StringMenuHandler, t as Manifest, u as InteractionHandler, v as HttpConfig, y as HttpEdgeConfig } from "./Manifest-D5MEsTmH.mjs";
|
|
3
|
-
import "reflect-metadata";
|
|
4
|
-
import { REST } from "@discordjs/rest";
|
|
1
|
+
import { A as RoleMenuHandler, B as AutocompleteHandler, C as Plugin, D as InteractionMiddleware, E as EngineContext, F as InteractionHandler, H as HttpConfig, I as RepliableHandler, L as InteractionRef, M as StringMenuHandler, N as UserMenuHandler, O as ChannelMenuHandler, P as ComponentHandler, R as ReplySender, S as HttpPluginOptions, T as PluginOptions, U as HttpEdgeConfig, V as Core, W as HttpServerConfig, _ as Emojis, a as ArraySource, b as SelectedMentionables, c as Paginator, d as WebhookLog, f as ModalHandler, g as SlashHandler, h as UserContextMenuHandler, i as InteractionGateContext, j as SelectMenuHandler, k as MentionableMenuHandler, l as PageContext, m as MessageContextMenuHandler, n as version, o as CursorSource, p as ButtonHandler, r as Gated, s as PageSource, t as HmrModuleHandler, u as Subscriber, v as InjectedEmojiMap, w as PluginLifecycleSpec, x as SlashOptions, y as ModalFields, z as SentMessage } from "./shared-vsj1uwIH.mjs";
|
|
5
2
|
import { Bus } from "@seedcord/core";
|
|
6
|
-
import {
|
|
3
|
+
import { ServerHost } from "@seedcord/core/node";
|
|
4
|
+
import { HostAugmentTarget, HostListenHost, HostVersion, SeedcordBrand, SeedcordInstance } from "@seedcord/types/internal";
|
|
5
|
+
import { REST } from "@discordjs/rest";
|
|
7
6
|
import { WinstonConsoleSink, WinstonFileSink } from "@seedcord/logger/node";
|
|
8
|
-
import {
|
|
9
|
-
import { Plugin as Plugin$1, PluginLifecycleSpec, PluginOptions, PluginOptions as PluginOptions$1 } from "@seedcord/core/plugin";
|
|
10
|
-
import { IRateLimiter, TypedOmit } from "@seedcord/types";
|
|
11
|
-
export * from "@seedcord/logger";
|
|
12
|
-
export * from "@seedcord/core";
|
|
7
|
+
import { IRateLimiter } from "@seedcord/types";
|
|
13
8
|
export * from "@seedcord/errors";
|
|
14
|
-
export * from "@seedcord/
|
|
9
|
+
export * from "@seedcord/core";
|
|
10
|
+
export * from "@seedcord/logger";
|
|
15
11
|
export * from "@seedcord/event-emitter";
|
|
12
|
+
export * from "@seedcord/rate-limiter";
|
|
16
13
|
export * from "@seedcord/utils";
|
|
17
14
|
export * from "@seedcord/types";
|
|
18
15
|
//#region src/node/Seedcord.d.ts
|
|
19
|
-
type RuntimeOfConfig<Cfg extends HttpConfig> = Cfg extends {
|
|
20
|
-
runtime: 'edge';
|
|
21
|
-
} ? 'edge' : 'server';
|
|
22
16
|
/**
|
|
23
|
-
* The HTTP-interactions bot
|
|
17
|
+
* The HTTP-interactions bot on node. `start()` loads handlers from `config.bot.interactions.path`
|
|
18
|
+
* and binds a server on `port`. With `port: false`, your own server passes requests to `fetch()`.
|
|
24
19
|
*
|
|
25
|
-
*
|
|
26
|
-
* `start()`, and runs coordinated shutdown with an in-flight drain. The edge deploy path calls
|
|
27
|
-
* `createSeedcord` from a generated entry.
|
|
20
|
+
* Shutdown waits up to 5s for interactions that are still running.
|
|
28
21
|
*/
|
|
29
|
-
export declare class Seedcord
|
|
22
|
+
export declare class Seedcord extends ServerHost<'http'> implements SeedcordInstance {
|
|
23
|
+
#private;
|
|
30
24
|
/** @internal */
|
|
31
25
|
readonly [SeedcordBrand] = true;
|
|
32
26
|
/** @internal */
|
|
33
27
|
readonly [HostAugmentTarget] = "@seedcord/http";
|
|
34
28
|
/** @internal */
|
|
35
29
|
readonly [HostVersion]: string;
|
|
30
|
+
/** @internal */
|
|
31
|
+
[HostListenHost]?: string | undefined;
|
|
36
32
|
/** Discord REST client built from `bot.restOptions`. `start()` sets the token. */
|
|
37
33
|
readonly rest: REST;
|
|
38
34
|
/** @see {@link IRateLimiter} */
|
|
39
35
|
readonly rateLimiter: IRateLimiter;
|
|
40
36
|
/** @see {@link Bus} */
|
|
41
37
|
readonly bus: Bus;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
private token?;
|
|
49
|
-
private server?;
|
|
50
|
-
private boundPort?;
|
|
51
|
-
private fetchedUsername?;
|
|
52
|
-
readonly config: HttpConfig;
|
|
53
|
-
constructor(config: Cfg);
|
|
38
|
+
readonly config: HttpServerConfig;
|
|
39
|
+
/**
|
|
40
|
+
* @throws A **SeedcordError** when another `Seedcord` exists in this process and has not shut down.
|
|
41
|
+
* @throws A **SeedcordError** when the running Node or Bun is older than the range in `engines`.
|
|
42
|
+
*/
|
|
43
|
+
constructor(config: HttpServerConfig);
|
|
54
44
|
/** The bot's discord username, populated by the ready fetch. */
|
|
55
45
|
get username(): string | undefined;
|
|
56
|
-
/** The bound server port,
|
|
46
|
+
/** The bound server port, set once `start()` is listening. Stays `undefined` with `port: false`. */
|
|
57
47
|
get port(): number | undefined;
|
|
58
48
|
/**
|
|
59
49
|
* Starts the host and runs the startup tasks.
|
|
60
50
|
*/
|
|
61
51
|
start(): Promise<this>;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Answers one request to the interactions endpoint. Mount it in your own server when the
|
|
54
|
+
* config sets `port: false`.
|
|
55
|
+
*
|
|
56
|
+
* Rejects with `CoreFetchBeforeStart` until `start()` is called. A request that arrives while
|
|
57
|
+
* `start()` runs waits for all of startup, the command deploy included. Answers 503 once
|
|
58
|
+
* shutdown begins or `start()` fails.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* // Hono passes the untouched request through c.req.raw
|
|
63
|
+
* const seedcord = new Seedcord({ ...config, port: false });
|
|
64
|
+
* await seedcord.start();
|
|
65
|
+
*
|
|
66
|
+
* const app = new Hono();
|
|
67
|
+
* app.post('/interactions', (c) => seedcord.fetch(c.req.raw));
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
fetch(request: Request): Promise<Response>;
|
|
66
71
|
/** The bot's Discord application id. Throws if you read it before the Configuration phase. */
|
|
67
72
|
get applicationId(): string;
|
|
68
|
-
private listen;
|
|
69
|
-
private fetchUsername;
|
|
70
|
-
private stopServer;
|
|
71
73
|
}
|
|
72
74
|
//#endregion
|
|
73
|
-
|
|
74
|
-
/** The options an HTTP plugin declares, narrowed to the transports this base serves. */
|
|
75
|
-
type HttpPluginOptions = TypedOmit<PluginOptions$1, 'transport'> & {
|
|
76
|
-
transport?: 'http';
|
|
77
|
-
};
|
|
78
|
-
/**
|
|
79
|
-
* Base class for an HTTP plugin, binding `this.core` to the HTTP {@link Core}.
|
|
80
|
-
*
|
|
81
|
-
* A plugin that runs on either transport extends the base from `@seedcord/core/plugin`, whose
|
|
82
|
-
* `this.core` is typed to the shared members only.
|
|
83
|
-
*
|
|
84
|
-
* @typeParam Opts - The transport and runtime the plugin declares.
|
|
85
|
-
*/
|
|
86
|
-
export declare abstract class Plugin<Opts extends HttpPluginOptions = {
|
|
87
|
-
transport: 'http';
|
|
88
|
-
}> extends Plugin$1<Opts, Core> {}
|
|
89
|
-
//#endregion
|
|
90
|
-
export { ArraySource, AutocompleteHandler, ButtonHandler, ChannelMenuHandler, ComponentHandler, type Core, CursorSource, Emojis, type EngineContext, Gated, type HttpConfig, type HttpEdgeConfig, type HttpPluginOptions, type HttpServerConfig, type InjectedEmojiMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, type InteractionRef, type Manifest, MentionableMenuHandler, MessageContextMenuHandler, ModalFields, ModalHandler, type PageContext, type PageSource, Paginator, type PluginLifecycleSpec, type PluginOptions, RepliableHandler, ReplySender, RoleMenuHandler, SelectMenuHandler, type SelectedMentionables, type SentMessage, SlashHandler, type SlashOptions, StringMenuHandler, Subscriber, UserContextMenuHandler, UserMenuHandler, WebhookLog, WinstonConsoleSink, WinstonFileSink, createSeedcord, version };
|
|
75
|
+
export { ArraySource, AutocompleteHandler, ButtonHandler, ChannelMenuHandler, ComponentHandler, type Core, CursorSource, Emojis, type EngineContext, Gated, HmrModuleHandler, type HttpConfig, type HttpEdgeConfig, type HttpPluginOptions, type HttpServerConfig, type InjectedEmojiMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, type InteractionRef, MentionableMenuHandler, MessageContextMenuHandler, ModalFields, ModalHandler, type PageContext, type PageSource, Paginator, Plugin, type PluginLifecycleSpec, type PluginOptions, RepliableHandler, ReplySender, RoleMenuHandler, SelectMenuHandler, type SelectedMentionables, type SentMessage, SlashHandler, type SlashOptions, StringMenuHandler, Subscriber, UserContextMenuHandler, UserMenuHandler, WebhookLog, WinstonConsoleSink, WinstonFileSink, version };
|
|
91
76
|
//# sourceMappingURL=index.d.mts.map
|