district.js 0.7.0 → 0.8.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/client.d.ts +46 -2
- package/dist/client.js +41 -1
- package/dist/commands.d.ts +73 -0
- package/dist/commands.js +70 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -0
- package/dist/structures.d.ts +38 -2
- package/dist/structures.js +40 -2
- package/dist/types.d.ts +39 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import { EventEmitter } from "node:events";
|
|
|
2
2
|
import http from "node:http";
|
|
3
3
|
import { REST } from "./rest.js";
|
|
4
4
|
import { Store } from "./store.js";
|
|
5
|
+
import { type EmbedResolvable } from "./embed.js";
|
|
6
|
+
import { type CommandResolvable, type CommandData } from "./commands.js";
|
|
5
7
|
import { ClientUser, Message, TextChannel, Interaction, User, Space, type ClientContext, type MessageContent } from "./structures.js";
|
|
6
8
|
import { type EventHeaders } from "./webhook.js";
|
|
7
|
-
import type { ClientOptions, ReactionEvent, DeletedMessage } from "./types.js";
|
|
9
|
+
import type { ClientOptions, ReactionEvent, DeletedMessage, MemberEvent, ScheduledEvent, ScheduleInput } from "./types.js";
|
|
8
10
|
/** The events a Client emits, and their argument tuples. */
|
|
9
11
|
export interface ClientEvents {
|
|
10
12
|
ready: [user: ClientUser];
|
|
@@ -13,6 +15,9 @@ export interface ClientEvents {
|
|
|
13
15
|
messageDelete: [message: DeletedMessage];
|
|
14
16
|
messageReactionAdd: [reaction: ReactionEvent];
|
|
15
17
|
messageReactionRemove: [reaction: ReactionEvent];
|
|
18
|
+
memberJoin: [member: MemberEvent];
|
|
19
|
+
memberLeave: [member: MemberEvent];
|
|
20
|
+
scheduled: [event: ScheduledEvent];
|
|
16
21
|
interactionCreate: [interaction: Interaction];
|
|
17
22
|
error: [error: Error];
|
|
18
23
|
}
|
|
@@ -36,14 +41,53 @@ export declare class Client extends EventEmitter implements ClientContext {
|
|
|
36
41
|
/** Send a message to a channel (text or { content, embeds }). */
|
|
37
42
|
send: (channelId: string, content: MessageContent) => Promise<Message>;
|
|
38
43
|
};
|
|
39
|
-
/** Fetch users by id. */
|
|
44
|
+
/** Fetch users by id, or DM them. */
|
|
40
45
|
readonly users: {
|
|
41
46
|
fetch: (id: string) => Promise<User>;
|
|
47
|
+
/** Open (or reuse) a 1-on-1 DM with a user and send them a message. */
|
|
48
|
+
send: (userId: string, content: string | {
|
|
49
|
+
content?: string;
|
|
50
|
+
embeds?: EmbedResolvable[];
|
|
51
|
+
}) => Promise<{
|
|
52
|
+
channelId: string;
|
|
53
|
+
}>;
|
|
42
54
|
};
|
|
43
55
|
/** Fetch spaces by id. */
|
|
44
56
|
readonly spaces: {
|
|
45
57
|
fetch: (id: string) => Promise<Space>;
|
|
46
58
|
};
|
|
59
|
+
/** Register / list / delete this bot's slash commands (they show in the `/`
|
|
60
|
+
* picker). `set` replaces the entire command set, discord.js-style. */
|
|
61
|
+
readonly commands: {
|
|
62
|
+
/** Replace all of the bot's commands with this set. `handlerUrl` defaults to
|
|
63
|
+
* the app's active event-subscription endpoint. */
|
|
64
|
+
set: (commands: CommandResolvable[], opts?: {
|
|
65
|
+
handlerUrl?: string;
|
|
66
|
+
}) => Promise<{
|
|
67
|
+
ok: boolean;
|
|
68
|
+
count: number;
|
|
69
|
+
}>;
|
|
70
|
+
/** List the bot's currently-registered commands. */
|
|
71
|
+
list: () => Promise<CommandData[]>;
|
|
72
|
+
/** Delete one command by name. */
|
|
73
|
+
delete: (name: string) => Promise<void>;
|
|
74
|
+
};
|
|
75
|
+
/** Register / list / delete recurring scheduled jobs. When one is due District
|
|
76
|
+
* POSTs a `scheduled` event to the bot — listen with `client.on("scheduled", …)`. */
|
|
77
|
+
readonly schedules: {
|
|
78
|
+
/** Replace all schedules with this set (min interval 60s). `handlerUrl`
|
|
79
|
+
* defaults to the app's active event-subscription endpoint. */
|
|
80
|
+
set: (schedules: ScheduleInput[], opts?: {
|
|
81
|
+
handlerUrl?: string;
|
|
82
|
+
}) => Promise<{
|
|
83
|
+
ok: boolean;
|
|
84
|
+
count: number;
|
|
85
|
+
}>;
|
|
86
|
+
/** List the bot's registered schedules (with next/last run times). */
|
|
87
|
+
list: () => Promise<any[]>;
|
|
88
|
+
/** Delete one schedule by name. */
|
|
89
|
+
delete: (name: string) => Promise<void>;
|
|
90
|
+
};
|
|
47
91
|
/** Validate the token, load the bot's identity, and emit `ready`. */
|
|
48
92
|
login(): Promise<ClientUser>;
|
|
49
93
|
/**
|
package/dist/client.js
CHANGED
|
@@ -4,6 +4,8 @@ import { EventEmitter } from "node:events";
|
|
|
4
4
|
import http from "node:http";
|
|
5
5
|
import { REST } from "./rest.js";
|
|
6
6
|
import { Store } from "./store.js";
|
|
7
|
+
import { resolveEmbed } from "./embed.js";
|
|
8
|
+
import { resolveCommand } from "./commands.js";
|
|
7
9
|
import { ClientUser, Message, TextChannel, Interaction, User, Space } from "./structures.js";
|
|
8
10
|
import { verifyAndParse } from "./webhook.js";
|
|
9
11
|
export class Client extends EventEmitter {
|
|
@@ -45,14 +47,43 @@ export class Client extends EventEmitter {
|
|
|
45
47
|
/** Send a message to a channel (text or { content, embeds }). */
|
|
46
48
|
send: (channelId, content) => new TextChannel(this, channelId).send(content),
|
|
47
49
|
};
|
|
48
|
-
/** Fetch users by id. */
|
|
50
|
+
/** Fetch users by id, or DM them. */
|
|
49
51
|
users = {
|
|
50
52
|
fetch: (id) => this.rest.get(`/users/${id}`).then((r) => new User(r.user)),
|
|
53
|
+
/** Open (or reuse) a 1-on-1 DM with a user and send them a message. */
|
|
54
|
+
send: (userId, content) => {
|
|
55
|
+
const body = typeof content === "string"
|
|
56
|
+
? { content }
|
|
57
|
+
: { content: content.content, embeds: content.embeds?.map(resolveEmbed) };
|
|
58
|
+
return this.rest.post(`/users/${userId}/dm`, body);
|
|
59
|
+
},
|
|
51
60
|
};
|
|
52
61
|
/** Fetch spaces by id. */
|
|
53
62
|
spaces = {
|
|
54
63
|
fetch: (id) => this.rest.get(`/spaces/${id}`).then((r) => new Space(this, r.space)),
|
|
55
64
|
};
|
|
65
|
+
/** Register / list / delete this bot's slash commands (they show in the `/`
|
|
66
|
+
* picker). `set` replaces the entire command set, discord.js-style. */
|
|
67
|
+
commands = {
|
|
68
|
+
/** Replace all of the bot's commands with this set. `handlerUrl` defaults to
|
|
69
|
+
* the app's active event-subscription endpoint. */
|
|
70
|
+
set: (commands, opts = {}) => this.rest.put("/commands", { commands: commands.map(resolveCommand), ...(opts.handlerUrl ? { handlerUrl: opts.handlerUrl } : {}) }),
|
|
71
|
+
/** List the bot's currently-registered commands. */
|
|
72
|
+
list: () => this.rest.get("/commands").then((r) => r.commands),
|
|
73
|
+
/** Delete one command by name. */
|
|
74
|
+
delete: (name) => this.rest.delete(`/commands/${encodeURIComponent(name)}`).then(() => undefined),
|
|
75
|
+
};
|
|
76
|
+
/** Register / list / delete recurring scheduled jobs. When one is due District
|
|
77
|
+
* POSTs a `scheduled` event to the bot — listen with `client.on("scheduled", …)`. */
|
|
78
|
+
schedules = {
|
|
79
|
+
/** Replace all schedules with this set (min interval 60s). `handlerUrl`
|
|
80
|
+
* defaults to the app's active event-subscription endpoint. */
|
|
81
|
+
set: (schedules, opts = {}) => this.rest.put("/schedules", { schedules, ...(opts.handlerUrl ? { handlerUrl: opts.handlerUrl } : {}) }),
|
|
82
|
+
/** List the bot's registered schedules (with next/last run times). */
|
|
83
|
+
list: () => this.rest.get("/schedules").then((r) => r.schedules),
|
|
84
|
+
/** Delete one schedule by name. */
|
|
85
|
+
delete: (name) => this.rest.delete(`/schedules/${encodeURIComponent(name)}`).then(() => undefined),
|
|
86
|
+
};
|
|
56
87
|
/** Validate the token, load the bot's identity, and emit `ready`. */
|
|
57
88
|
async login() {
|
|
58
89
|
const res = await this.rest.get("/me");
|
|
@@ -142,6 +173,15 @@ export class Client extends EventEmitter {
|
|
|
142
173
|
case "message.reaction_remove":
|
|
143
174
|
this.emit("messageReactionRemove", toReaction(evt));
|
|
144
175
|
break;
|
|
176
|
+
case "member.join":
|
|
177
|
+
this.emit("memberJoin", { spaceId: evt.space_id, userId: evt.member.user_id, joinedAt: evt.member.joined_at ?? null });
|
|
178
|
+
break;
|
|
179
|
+
case "member.leave":
|
|
180
|
+
this.emit("memberLeave", { spaceId: evt.space_id, userId: evt.member.user_id, joinedAt: evt.member.joined_at ?? null });
|
|
181
|
+
break;
|
|
182
|
+
case "scheduled":
|
|
183
|
+
this.emit("scheduled", { schedule: evt.schedule, data: evt.data ?? {} });
|
|
184
|
+
break;
|
|
145
185
|
case "interaction.create":
|
|
146
186
|
this.emit("interactionCreate", new Interaction(this, evt));
|
|
147
187
|
break;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** Option value types a command argument can declare. */
|
|
2
|
+
export type CommandOptionType = "string" | "integer" | "number" | "boolean" | "user" | "channel" | "role" | "subcommand";
|
|
3
|
+
/** A fixed choice for an option (what the picker offers). */
|
|
4
|
+
export interface CommandOptionChoice {
|
|
5
|
+
name: string;
|
|
6
|
+
value: string | number;
|
|
7
|
+
}
|
|
8
|
+
/** One declared command argument (or a subcommand, when `type` is "subcommand"). */
|
|
9
|
+
export interface CommandOption {
|
|
10
|
+
type: CommandOptionType;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
choices?: CommandOptionChoice[];
|
|
15
|
+
/** Numeric bounds (integer/number options). */
|
|
16
|
+
minValue?: number;
|
|
17
|
+
maxValue?: number;
|
|
18
|
+
/** Nested options — present when `type` is "subcommand". */
|
|
19
|
+
options?: CommandOption[];
|
|
20
|
+
}
|
|
21
|
+
/** The serialized command payload sent to the API. */
|
|
22
|
+
export interface CommandData {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
options?: CommandOption[];
|
|
26
|
+
/** Permission bits required to invoke (0 = anyone). */
|
|
27
|
+
defaultPerms?: number;
|
|
28
|
+
}
|
|
29
|
+
type AddOpts = {
|
|
30
|
+
required?: boolean;
|
|
31
|
+
choices?: CommandOptionChoice[];
|
|
32
|
+
minValue?: number;
|
|
33
|
+
maxValue?: number;
|
|
34
|
+
};
|
|
35
|
+
/** Shared option-adding surface for both commands and subcommands. */
|
|
36
|
+
declare class OptionsBuilder {
|
|
37
|
+
options: CommandOption[];
|
|
38
|
+
protected addOption(type: CommandOptionType, name: string, description: string, opts?: AddOpts): this;
|
|
39
|
+
addStringOption(name: string, description: string, opts?: AddOpts): this;
|
|
40
|
+
addIntegerOption(name: string, description: string, opts?: AddOpts): this;
|
|
41
|
+
addNumberOption(name: string, description: string, opts?: AddOpts): this;
|
|
42
|
+
addBooleanOption(name: string, description: string, opts?: AddOpts): this;
|
|
43
|
+
addUserOption(name: string, description: string, opts?: AddOpts): this;
|
|
44
|
+
addChannelOption(name: string, description: string, opts?: AddOpts): this;
|
|
45
|
+
addRoleOption(name: string, description: string, opts?: AddOpts): this;
|
|
46
|
+
}
|
|
47
|
+
/** A subcommand under a top-level command (e.g. `/setup channels`). */
|
|
48
|
+
export declare class SlashCommandSubcommandBuilder extends OptionsBuilder {
|
|
49
|
+
name: string;
|
|
50
|
+
description: string;
|
|
51
|
+
setName(name: string): this;
|
|
52
|
+
setDescription(description: string): this;
|
|
53
|
+
toJSON(): CommandOption;
|
|
54
|
+
}
|
|
55
|
+
/** Fluent builder for a slash command. */
|
|
56
|
+
export declare class SlashCommandBuilder extends OptionsBuilder {
|
|
57
|
+
name: string;
|
|
58
|
+
description: string;
|
|
59
|
+
defaultPerms: number;
|
|
60
|
+
setName(name: string): this;
|
|
61
|
+
setDescription(description: string): this;
|
|
62
|
+
/** Permission bits required to run this command (see PermissionsBitField). */
|
|
63
|
+
setDefaultPerms(bits: number): this;
|
|
64
|
+
/** Add a subcommand (e.g. `/setup channels`). A command with subcommands is
|
|
65
|
+
* invoked as `/name subcommand …`; read the chosen one with
|
|
66
|
+
* `interaction.options.getSubcommand()`. */
|
|
67
|
+
addSubcommand(fn: (sub: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder): this;
|
|
68
|
+
toJSON(): CommandData;
|
|
69
|
+
}
|
|
70
|
+
/** Accept either a builder or a plain object anywhere a command is expected. */
|
|
71
|
+
export type CommandResolvable = SlashCommandBuilder | CommandData;
|
|
72
|
+
export declare function resolveCommand(c: CommandResolvable): CommandData;
|
|
73
|
+
export {};
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Slash command definitions — the district.js equivalent of Discord's
|
|
2
|
+
// SlashCommandBuilder. Build a command with typed options (and optional
|
|
3
|
+
// subcommands), then register your whole set with `client.commands.set([...])`
|
|
4
|
+
// so they show in the `/` picker.
|
|
5
|
+
//
|
|
6
|
+
// const roll = new SlashCommandBuilder()
|
|
7
|
+
// .setName("roll").setDescription("Roll a die")
|
|
8
|
+
// .addIntegerOption("sides", "How many sides", { minValue: 2, maxValue: 100 });
|
|
9
|
+
//
|
|
10
|
+
// const setup = new SlashCommandBuilder()
|
|
11
|
+
// .setName("setup").setDescription("Configure the bot")
|
|
12
|
+
// .addSubcommand(s => s.setName("channels").setDescription("Set channels")
|
|
13
|
+
// .addChannelOption("giveaway", "Where giveaways post", { required: true }));
|
|
14
|
+
/** Shared option-adding surface for both commands and subcommands. */
|
|
15
|
+
class OptionsBuilder {
|
|
16
|
+
options = [];
|
|
17
|
+
addOption(type, name, description, opts = {}) {
|
|
18
|
+
const o = { type, name, description, required: !!opts.required };
|
|
19
|
+
if (opts.choices && opts.choices.length)
|
|
20
|
+
o.choices = opts.choices;
|
|
21
|
+
if (opts.minValue != null)
|
|
22
|
+
o.minValue = opts.minValue;
|
|
23
|
+
if (opts.maxValue != null)
|
|
24
|
+
o.maxValue = opts.maxValue;
|
|
25
|
+
this.options.push(o);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
addStringOption(name, description, opts) { return this.addOption("string", name, description, opts); }
|
|
29
|
+
addIntegerOption(name, description, opts) { return this.addOption("integer", name, description, opts); }
|
|
30
|
+
addNumberOption(name, description, opts) { return this.addOption("number", name, description, opts); }
|
|
31
|
+
addBooleanOption(name, description, opts) { return this.addOption("boolean", name, description, opts); }
|
|
32
|
+
addUserOption(name, description, opts) { return this.addOption("user", name, description, opts); }
|
|
33
|
+
addChannelOption(name, description, opts) { return this.addOption("channel", name, description, opts); }
|
|
34
|
+
addRoleOption(name, description, opts) { return this.addOption("role", name, description, opts); }
|
|
35
|
+
}
|
|
36
|
+
/** A subcommand under a top-level command (e.g. `/setup channels`). */
|
|
37
|
+
export class SlashCommandSubcommandBuilder extends OptionsBuilder {
|
|
38
|
+
name = "";
|
|
39
|
+
description = "";
|
|
40
|
+
setName(name) { this.name = name; return this; }
|
|
41
|
+
setDescription(description) { this.description = description; return this; }
|
|
42
|
+
toJSON() {
|
|
43
|
+
return { type: "subcommand", name: this.name, description: this.description, options: this.options };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Fluent builder for a slash command. */
|
|
47
|
+
export class SlashCommandBuilder extends OptionsBuilder {
|
|
48
|
+
name = "";
|
|
49
|
+
description = "";
|
|
50
|
+
defaultPerms = 0;
|
|
51
|
+
setName(name) { this.name = name; return this; }
|
|
52
|
+
setDescription(description) { this.description = description; return this; }
|
|
53
|
+
/** Permission bits required to run this command (see PermissionsBitField). */
|
|
54
|
+
setDefaultPerms(bits) { this.defaultPerms = bits; return this; }
|
|
55
|
+
/** Add a subcommand (e.g. `/setup channels`). A command with subcommands is
|
|
56
|
+
* invoked as `/name subcommand …`; read the chosen one with
|
|
57
|
+
* `interaction.options.getSubcommand()`. */
|
|
58
|
+
addSubcommand(fn) {
|
|
59
|
+
const sub = new SlashCommandSubcommandBuilder();
|
|
60
|
+
fn(sub);
|
|
61
|
+
this.options.push(sub.toJSON());
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
toJSON() {
|
|
65
|
+
return { name: this.name, description: this.description, options: this.options, defaultPerms: this.defaultPerms };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function resolveCommand(c) {
|
|
69
|
+
return c instanceof SlashCommandBuilder ? c.toJSON() : c;
|
|
70
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export { Client, type ClientEvents } from "./client.js";
|
|
2
2
|
export { REST, DistrictAPIError, DEFAULT_API_BASE } from "./rest.js";
|
|
3
|
-
export { ClientUser, Message, TextChannel, Interaction, User, Space, SpaceMember, Role, Attachment, Ban, Invite, Webhook, type ClientContext, type MessageContent, } from "./structures.js";
|
|
3
|
+
export { ClientUser, Message, TextChannel, Interaction, User, Space, SpaceMember, Role, Attachment, Ban, Invite, Webhook, type ClientContext, type MessageContent, type MessageFile, } from "./structures.js";
|
|
4
4
|
export { EmbedBuilder, resolveEmbed, type EmbedData, type EmbedField, type EmbedResolvable } from "./embed.js";
|
|
5
5
|
export { ButtonBuilder, ActionRowBuilder, StringSelectMenuBuilder, ModalBuilder, TextInputBuilder, resolveComponent, type ButtonStyle, type ButtonData, type SelectData, type SelectOption, type ComponentData, type ModalData, type TextInputData, type ActionRowData, type ComponentResolvable, } from "./components.js";
|
|
6
6
|
export { Store, StoreCollection, type StoreDocument } from "./store.js";
|
|
7
|
+
export { SlashCommandBuilder, SlashCommandSubcommandBuilder, resolveCommand, type CommandData, type CommandOption, type CommandOptionType, type CommandOptionChoice, type CommandResolvable, } from "./commands.js";
|
|
7
8
|
export { Collection } from "./collection.js";
|
|
8
9
|
export { PermissionsBitField, type PermissionResolvable, type PermissionFlagName } from "./permissions.js";
|
|
9
10
|
export { Formatters } from "./formatters.js";
|
|
10
11
|
export { ChannelType, type ChannelTypeValue } from "./enums.js";
|
|
11
12
|
export { verifySignature, parseEvent, verifyAndParse, type EventHeaders } from "./webhook.js";
|
|
12
|
-
export type { ClientOptions, RawMessage, RawSelfUser, RawUser, RawSpace, RawChannel, RawRole, RawMember, RawAttachment, RawBan, RawInvite, RawWebhook, DistrictEvent, ReactionEvent, DeletedMessage, } from "./types.js";
|
|
13
|
+
export type { ClientOptions, RawMessage, RawSelfUser, RawUser, RawSpace, RawChannel, RawRole, RawMember, RawAttachment, RawBan, RawInvite, RawWebhook, DistrictEvent, ReactionEvent, DeletedMessage, MemberEvent, ScheduledEvent, ScheduleInput, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { ClientUser, Message, TextChannel, Interaction, User, Space, SpaceMember
|
|
|
10
10
|
export { EmbedBuilder, resolveEmbed } from "./embed.js";
|
|
11
11
|
export { ButtonBuilder, ActionRowBuilder, StringSelectMenuBuilder, ModalBuilder, TextInputBuilder, resolveComponent, } from "./components.js";
|
|
12
12
|
export { Store, StoreCollection } from "./store.js";
|
|
13
|
+
export { SlashCommandBuilder, SlashCommandSubcommandBuilder, resolveCommand, } from "./commands.js";
|
|
13
14
|
export { Collection } from "./collection.js";
|
|
14
15
|
export { PermissionsBitField } from "./permissions.js";
|
|
15
16
|
export { Formatters } from "./formatters.js";
|
package/dist/structures.d.ts
CHANGED
|
@@ -5,10 +5,19 @@ import { PermissionsBitField } from "./permissions.js";
|
|
|
5
5
|
import { type EmbedResolvable } from "./embed.js";
|
|
6
6
|
import { type ComponentResolvable } from "./components.js";
|
|
7
7
|
/** What you can pass to send/reply: a string, or content + embeds + components. */
|
|
8
|
+
/** A file to attach to a message. `data` is base64-encoded bytes. */
|
|
9
|
+
export interface MessageFile {
|
|
10
|
+
filename: string;
|
|
11
|
+
/** Base64-encoded file contents. */
|
|
12
|
+
data: string;
|
|
13
|
+
/** MIME type (e.g. "image/png"). Defaults to application/octet-stream. */
|
|
14
|
+
contentType?: string;
|
|
15
|
+
}
|
|
8
16
|
export type MessageContent = string | {
|
|
9
17
|
content?: string;
|
|
10
18
|
embeds?: EmbedResolvable[];
|
|
11
19
|
components?: ComponentResolvable[];
|
|
20
|
+
files?: MessageFile[];
|
|
12
21
|
};
|
|
13
22
|
/** Minimal client surface the structures need (avoids a circular import). */
|
|
14
23
|
export interface ClientContext {
|
|
@@ -110,6 +119,13 @@ export declare class Space {
|
|
|
110
119
|
members(limit?: number): Promise<Collection<string, SpaceMember>>;
|
|
111
120
|
/** The space's roles. */
|
|
112
121
|
roles(): Promise<Collection<string, Role>>;
|
|
122
|
+
/** A member's roles in this space — use to gate on "has role X". */
|
|
123
|
+
memberRoles(userId: string): Promise<Array<{
|
|
124
|
+
id: string;
|
|
125
|
+
name: string | null;
|
|
126
|
+
color: string | null;
|
|
127
|
+
position: number;
|
|
128
|
+
}>>;
|
|
113
129
|
/** The space owner's profile. */
|
|
114
130
|
fetchOwner(): Promise<User>;
|
|
115
131
|
/** Banned users. */
|
|
@@ -246,6 +262,26 @@ export declare class Interaction {
|
|
|
246
262
|
isModalSubmit(): boolean;
|
|
247
263
|
/** Get a submitted modal field value by its input customId. */
|
|
248
264
|
field(customId: string): string | undefined;
|
|
249
|
-
/**
|
|
250
|
-
|
|
265
|
+
/** Typed accessors for slash-command option values (read from `args`), à la
|
|
266
|
+
* discord.js: `interaction.options.getInteger("amount")`. Returns null when
|
|
267
|
+
* the option was not provided. `getUser` returns the user id. */
|
|
268
|
+
get options(): {
|
|
269
|
+
get: (name: string) => unknown;
|
|
270
|
+
getString: (name: string) => string | null;
|
|
271
|
+
getInteger: (name: string) => number | null;
|
|
272
|
+
getNumber: (name: string) => number | null;
|
|
273
|
+
getBoolean: (name: string) => boolean | null;
|
|
274
|
+
getUser: (name: string) => string | null;
|
|
275
|
+
getChannel: (name: string) => string | null;
|
|
276
|
+
getRole: (name: string) => string | null;
|
|
277
|
+
/** The chosen subcommand name (for commands with subcommands), or null. */
|
|
278
|
+
getSubcommand: () => string | null;
|
|
279
|
+
};
|
|
280
|
+
/** Respond to the command by posting a message in its channel. Pass
|
|
281
|
+
* `{ ephemeral: true }` to send a private reply only the invoking user sees
|
|
282
|
+
* (content + embeds only) — this resolves to null since no public message is
|
|
283
|
+
* created. */
|
|
284
|
+
reply(content: MessageContent, opts?: {
|
|
285
|
+
ephemeral?: boolean;
|
|
286
|
+
}): Promise<Message | null>;
|
|
251
287
|
}
|
package/dist/structures.js
CHANGED
|
@@ -11,6 +11,7 @@ function toPayload(input) {
|
|
|
11
11
|
content: input.content,
|
|
12
12
|
embeds: input.embeds?.map(resolveEmbed),
|
|
13
13
|
components: input.components?.map(resolveComponent),
|
|
14
|
+
files: input.files,
|
|
14
15
|
};
|
|
15
16
|
}
|
|
16
17
|
export class ClientUser {
|
|
@@ -211,6 +212,11 @@ export class Space {
|
|
|
211
212
|
out.set(r.id, new Role(r));
|
|
212
213
|
return out;
|
|
213
214
|
}
|
|
215
|
+
/** A member's roles in this space — use to gate on "has role X". */
|
|
216
|
+
async memberRoles(userId) {
|
|
217
|
+
const r = await this.client.rest.get(`/spaces/${this.id}/members/${userId}/roles`);
|
|
218
|
+
return r.roles ?? [];
|
|
219
|
+
}
|
|
214
220
|
/** The space owner's profile. */
|
|
215
221
|
async fetchOwner() {
|
|
216
222
|
const { user } = await this.client.rest.get(`/users/${this.ownerId}`);
|
|
@@ -416,9 +422,41 @@ export class Interaction {
|
|
|
416
422
|
isModalSubmit() { return this.type === "modal_submit"; }
|
|
417
423
|
/** Get a submitted modal field value by its input customId. */
|
|
418
424
|
field(customId) { return this.fields[customId]; }
|
|
419
|
-
/**
|
|
420
|
-
|
|
425
|
+
/** Typed accessors for slash-command option values (read from `args`), à la
|
|
426
|
+
* discord.js: `interaction.options.getInteger("amount")`. Returns null when
|
|
427
|
+
* the option was not provided. `getUser` returns the user id. */
|
|
428
|
+
get options() {
|
|
429
|
+
const args = this.args;
|
|
430
|
+
return {
|
|
431
|
+
get: (name) => args[name] ?? null,
|
|
432
|
+
getString: (name) => { const v = args[name]; return v == null ? null : String(v); },
|
|
433
|
+
getInteger: (name) => { const v = Number(args[name]); return Number.isFinite(v) ? Math.trunc(v) : null; },
|
|
434
|
+
getNumber: (name) => { const v = Number(args[name]); return Number.isFinite(v) ? v : null; },
|
|
435
|
+
getBoolean: (name) => {
|
|
436
|
+
const v = args[name];
|
|
437
|
+
if (typeof v === "boolean")
|
|
438
|
+
return v;
|
|
439
|
+
if (v == null)
|
|
440
|
+
return null;
|
|
441
|
+
return v === "true" || v === 1 || v === "1";
|
|
442
|
+
},
|
|
443
|
+
getUser: (name) => { const v = args[name]; return v == null ? null : String(v); },
|
|
444
|
+
getChannel: (name) => { const v = args[name]; return v == null ? null : String(v); },
|
|
445
|
+
getRole: (name) => { const v = args[name]; return v == null ? null : String(v); },
|
|
446
|
+
/** The chosen subcommand name (for commands with subcommands), or null. */
|
|
447
|
+
getSubcommand: () => { const v = args.subcommand; return v == null ? null : String(v); },
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
/** Respond to the command by posting a message in its channel. Pass
|
|
451
|
+
* `{ ephemeral: true }` to send a private reply only the invoking user sees
|
|
452
|
+
* (content + embeds only) — this resolves to null since no public message is
|
|
453
|
+
* created. */
|
|
454
|
+
async reply(content, opts) {
|
|
421
455
|
const p = toPayload(content);
|
|
456
|
+
if (opts?.ephemeral) {
|
|
457
|
+
await this.client.rest.post(`/channels/${this.channelId}/messages`, { ...p, ephemeral: true, userId: this.userId });
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
422
460
|
const { message } = await this.client.rest.post(`/channels/${this.channelId}/messages`, p);
|
|
423
461
|
return new Message(this.client, { ...message, content: p.content ?? "", author_id: this.client.user?.id ?? "" });
|
|
424
462
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -144,6 +144,24 @@ export type DistrictEvent = {
|
|
|
144
144
|
message_id: string;
|
|
145
145
|
user_id: string;
|
|
146
146
|
emoji: string;
|
|
147
|
+
} | {
|
|
148
|
+
event: "member.join";
|
|
149
|
+
space_id: string;
|
|
150
|
+
member: {
|
|
151
|
+
user_id: string;
|
|
152
|
+
joined_at?: string | null;
|
|
153
|
+
};
|
|
154
|
+
} | {
|
|
155
|
+
event: "member.leave";
|
|
156
|
+
space_id: string;
|
|
157
|
+
member: {
|
|
158
|
+
user_id: string;
|
|
159
|
+
joined_at?: string | null;
|
|
160
|
+
};
|
|
161
|
+
} | {
|
|
162
|
+
event: "scheduled";
|
|
163
|
+
schedule: string;
|
|
164
|
+
data?: Record<string, unknown>;
|
|
147
165
|
} | {
|
|
148
166
|
event: "interaction.create";
|
|
149
167
|
type?: "command" | "component" | "modal_submit";
|
|
@@ -167,6 +185,27 @@ export interface ReactionEvent {
|
|
|
167
185
|
userId: string;
|
|
168
186
|
emoji: string;
|
|
169
187
|
}
|
|
188
|
+
/** A member joining or leaving a space (`memberJoin` / `memberLeave`). */
|
|
189
|
+
export interface MemberEvent {
|
|
190
|
+
spaceId: string;
|
|
191
|
+
userId: string;
|
|
192
|
+
joinedAt: string | null;
|
|
193
|
+
}
|
|
194
|
+
/** A due scheduled job firing (`scheduled` event). */
|
|
195
|
+
export interface ScheduledEvent {
|
|
196
|
+
/** The schedule name you registered. */
|
|
197
|
+
schedule: string;
|
|
198
|
+
/** The arbitrary data you attached when registering it. */
|
|
199
|
+
data: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
/** One schedule to register with `client.schedules.set([...])`. */
|
|
202
|
+
export interface ScheduleInput {
|
|
203
|
+
name: string;
|
|
204
|
+
/** How often to fire, in seconds (minimum 60). */
|
|
205
|
+
intervalSeconds: number;
|
|
206
|
+
/** Arbitrary data delivered back on every tick. */
|
|
207
|
+
data?: Record<string, unknown>;
|
|
208
|
+
}
|
|
170
209
|
export interface DeletedMessage {
|
|
171
210
|
id: string;
|
|
172
211
|
channelId: string;
|
package/package.json
CHANGED