flarecord 0.0.1 → 0.0.3

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 CHANGED
@@ -1,4 +1,4 @@
1
- # flarecord
1
+ # flarecord 🌥️
2
2
 
3
3
  discord gateway client for cloudflare workers. built with typescript and optimized for durable objects.
4
4
 
@@ -8,6 +8,14 @@ discord gateway client for cloudflare workers. built with typescript and optimiz
8
8
  npm install flarecord
9
9
  ```
10
10
 
11
+ ## import
12
+
13
+ ```typescript
14
+ import { DiscordClient, GatewayIntents, MessageHelper } from "flarecord";
15
+ ```
16
+
17
+ flarecord uses source files by default for cloudflare workers.
18
+
11
19
  ## how it works
12
20
 
13
21
  flarecord connects to discord's gateway api using websockets. it runs inside cloudflare durable objects which provide:
@@ -31,7 +39,6 @@ the library handles all the complexity of the discord gateway protocol automatic
31
39
  - interaction events
32
40
  - all discord gateway events
33
41
  - typescript support
34
- - discord.js compatible builders (embeds, buttons, etc)
35
42
 
36
43
  ## example
37
44
 
@@ -119,7 +126,7 @@ available intents: GUILDS, GUILD_MEMBERS, GUILD_MODERATION, GUILD_EMOJIS_AND_STI
119
126
  use `MessageHelper` to send messages, embeds, buttons, and more:
120
127
 
121
128
  ```typescript
122
- import { MessageHelper, EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle } from "flarecord";
129
+ import { MessageHelper } from "flarecord";
123
130
 
124
131
  const helper = new MessageHelper(token);
125
132
 
@@ -127,18 +134,24 @@ const helper = new MessageHelper(token);
127
134
  await helper.send(channelId, "hello!");
128
135
 
129
136
  // send embed
130
- const embed = new EmbedBuilder()
131
- .setTitle("title")
132
- .setDescription("description")
133
- .setColor(0x00ff00);
137
+ const embed = {
138
+ title: "title",
139
+ description: "description",
140
+ color: 0x00ff00,
141
+ };
134
142
  await helper.send(channelId, embed);
135
143
 
136
144
  // send button
137
- const button = new ButtonBuilder()
138
- .setCustomId("button_id")
139
- .setLabel("click me")
140
- .setStyle(ButtonStyle.Primary);
141
- const row = new ActionRowBuilder().addComponents(button);
145
+ const button = {
146
+ type: 2,
147
+ style: 1,
148
+ custom_id: "button_id",
149
+ label: "click me",
150
+ };
151
+ const row = {
152
+ type: 1,
153
+ components: [button],
154
+ };
142
155
  await helper.send(channelId, row);
143
156
 
144
157
  // reply to message
package/dist/index.d.ts CHANGED
@@ -10,5 +10,4 @@ export { Logger, LogLevel, createLogger } from "./utils/logger";
10
10
  export type { GatewayPayload, HelloData, IdentifyData, ResumeData, ReadyData, GatewayState, GatewayConfig, MessageData, } from "./types";
11
11
  export { GatewayOpcode, GatewayEvent, GatewayIntents, WebSocketCloseCode, RESUMEABLE_CLOSE_CODES, GATEWAY_BASE_URL, GATEWAY_VERSION, GATEWAY_ENCODING, DEFAULT_RECONNECT_DELAYS, WEBSOCKET_READY_STATE_OPEN, DEFAULT_STORAGE_KEY, DEFAULT_MAX_RECONNECT_ATTEMPTS, } from "./types/constants";
12
12
  export { DEFAULT_IDENTIFY_PROPERTIES } from "./types";
13
- export { EmbedBuilder, ActionRowBuilder, ButtonBuilder, StringSelectMenuBuilder, UserSelectMenuBuilder, RoleSelectMenuBuilder, ChannelSelectMenuBuilder, MentionableSelectMenuBuilder, ModalBuilder, TextInputBuilder, AttachmentBuilder, SlashCommandBuilder, ContextMenuCommandBuilder, SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder, SlashCommandOptionsOnlyBuilder, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption, REST, Routes, Colors, PermissionFlagsBits, GatewayIntentBits, Events, ActivityType, ChannelType, MessageType, InteractionType, ApplicationCommandType, ButtonStyle, TextInputStyle, ComponentType, Locale, type APIEmbed, type APIEmbedField, type APIButtonComponent, type APIActionRowComponent, type APIMessageComponent, type RESTPostAPIChannelMessageJSONBody, type RESTPostAPIChannelMessageResult, type APIInteractionResponse, type APIMessage, type APIUser, type APIGuild, type APIChannel, type APIInteraction, type APIChatInputApplicationCommandInteraction, type APIMessageApplicationCommandInteraction, type APIUserApplicationCommandInteraction, type APIMessageComponentInteraction, type APIModalSubmitInteraction, } from "discord.js";
14
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,YAAY,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAEtD,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,6BAA6B,EAC7B,kCAAkC,EAClC,8BAA8B,EAC9B,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,6BAA6B,EAC7B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,IAAI,EACJ,MAAM,EACN,MAAM,EACN,mBAAmB,EACnB,iBAAiB,EACjB,MAAM,EACN,YAAY,EACZ,WAAW,EACX,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,aAAa,EACb,MAAM,EACN,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iCAAiC,EACtC,KAAK,+BAA+B,EACpC,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,yCAAyC,EAC9C,KAAK,uCAAuC,EAC5C,KAAK,oCAAoC,EACzC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,YAAY,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -9,5 +9,4 @@ export { SessionManager } from "./utils/session";
9
9
  export { Logger, LogLevel, createLogger } from "./utils/logger";
10
10
  export { GatewayOpcode, GatewayEvent, GatewayIntents, WebSocketCloseCode, RESUMEABLE_CLOSE_CODES, GATEWAY_BASE_URL, GATEWAY_VERSION, GATEWAY_ENCODING, DEFAULT_RECONNECT_DELAYS, WEBSOCKET_READY_STATE_OPEN, DEFAULT_STORAGE_KEY, DEFAULT_MAX_RECONNECT_ATTEMPTS, } from "./types/constants";
11
11
  export { DEFAULT_IDENTIFY_PROPERTIES } from "./types";
12
- export { EmbedBuilder, ActionRowBuilder, ButtonBuilder, StringSelectMenuBuilder, UserSelectMenuBuilder, RoleSelectMenuBuilder, ChannelSelectMenuBuilder, MentionableSelectMenuBuilder, ModalBuilder, TextInputBuilder, AttachmentBuilder, SlashCommandBuilder, ContextMenuCommandBuilder, SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption, REST, Routes, Colors, PermissionFlagsBits, GatewayIntentBits, Events, ActivityType, ChannelType, MessageType, InteractionType, ApplicationCommandType, ButtonStyle, TextInputStyle, ComponentType, Locale, } from "discord.js";
13
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAA6B,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAYhE,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAEtD,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,6BAA6B,EAC7B,kCAAkC,EAElC,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,6BAA6B,EAC7B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,IAAI,EACJ,MAAM,EACN,MAAM,EACN,mBAAmB,EACnB,iBAAiB,EACjB,MAAM,EACN,YAAY,EACZ,WAAW,EACX,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,aAAa,EACb,MAAM,GAmBP,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAA6B,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAYhE,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC"}
@@ -1,11 +1,42 @@
1
- import { EmbedBuilder, ActionRowBuilder, type RESTPostAPIChannelMessageJSONBody } from "discord.js";
2
- type MessageContent = string | EmbedBuilder | ActionRowBuilder<never> | RESTPostAPIChannelMessageJSONBody | (EmbedBuilder | ActionRowBuilder<never>)[];
1
+ type DiscordBuilder = {
2
+ toJSON(): unknown;
3
+ };
4
+ type APIEmbed = {
5
+ title?: string;
6
+ description?: string;
7
+ color?: number;
8
+ fields?: unknown[];
9
+ [key: string]: unknown;
10
+ };
11
+ type MessageBody = {
12
+ content?: string;
13
+ embeds?: unknown[];
14
+ components?: unknown[];
15
+ message_reference?: {
16
+ message_id: string;
17
+ channel_id: string;
18
+ guild_id?: string;
19
+ };
20
+ };
21
+ type Component = {
22
+ type: number;
23
+ style?: number;
24
+ custom_id?: string;
25
+ label?: string;
26
+ components?: Component[];
27
+ [key: string]: unknown;
28
+ };
29
+ type MessageContent = string | DiscordBuilder | MessageBody | DiscordBuilder[] | APIEmbed | Component | (APIEmbed | Component)[];
3
30
  export declare class MessageHelper {
4
- private rest;
31
+ private token;
32
+ private readonly baseUrl;
5
33
  constructor(token: string);
6
34
  send(channelId: string, content: MessageContent): Promise<unknown>;
7
35
  reply(channelId: string, messageId: string, guildId: string | undefined, content: MessageContent): Promise<unknown>;
8
36
  private normalizeContent;
37
+ private isBuilder;
38
+ private isEmbedJSON;
39
+ private isComponent;
9
40
  }
10
41
  export {};
11
42
  //# sourceMappingURL=message-helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-helper.d.ts","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,gBAAgB,EAChB,KAAK,iCAAiC,EAEvC,MAAM,YAAY,CAAC;AAEpB,KAAK,cAAc,GACf,MAAM,GACN,YAAY,GACZ,gBAAgB,CAAC,KAAK,CAAC,GACvB,iCAAiC,GACjC,CAAC,YAAY,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AAa/C,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAO;gBAEP,KAAK,EAAE,MAAM;IAInB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlE,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC;IAenB,OAAO,CAAC,gBAAgB;CAwCzB"}
1
+ {"version":3,"file":"message-helper.d.ts","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG;IACpB,MAAM,IAAI,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,QAAQ,GAAG;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAaF,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,cAAc,GACf,MAAM,GACN,cAAc,GACd,WAAW,GACX,cAAc,EAAE,GAChB,QAAQ,GACR,SAAS,GACT,CAAC,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC;AAE7B,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;gBAE7C,KAAK,EAAE,MAAM;IAInB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlE,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC;IA2BnB,OAAO,CAAC,gBAAgB;IA0DxB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,WAAW;CAQpB"}
@@ -1,12 +1,24 @@
1
- import { REST, Routes, EmbedBuilder, ActionRowBuilder, } from "discord.js";
2
1
  export class MessageHelper {
3
- rest;
2
+ token;
3
+ baseUrl = "https://discord.com/api/v10";
4
4
  constructor(token) {
5
- this.rest = new REST().setToken(token);
5
+ this.token = token;
6
6
  }
7
7
  async send(channelId, content) {
8
8
  const body = this.normalizeContent(content);
9
- return this.rest.post(Routes.channelMessages(channelId), { body });
9
+ const url = `${this.baseUrl}/channels/${channelId}/messages`;
10
+ const response = await fetch(url, {
11
+ method: "POST",
12
+ headers: {
13
+ Authorization: `Bot ${this.token}`,
14
+ "Content-Type": "application/json"
15
+ },
16
+ body: JSON.stringify(body)
17
+ });
18
+ if (!response.ok) {
19
+ throw new Error(`Discord API error: ${response.status} ${response.statusText}`);
20
+ }
21
+ return response.json();
10
22
  }
11
23
  async reply(channelId, messageId, guildId, content) {
12
24
  const body = this.normalizeContent(content);
@@ -15,35 +27,62 @@ export class MessageHelper {
15
27
  message_reference: {
16
28
  message_id: messageId,
17
29
  channel_id: channelId,
18
- ...(guildId && { guild_id: guildId }),
19
- },
30
+ ...guildId && { guild_id: guildId }
31
+ }
20
32
  };
21
- return this.rest.post(Routes.channelMessages(channelId), {
22
- body: replyBody,
33
+ const url = `${this.baseUrl}/channels/${channelId}/messages`;
34
+ const response = await fetch(url, {
35
+ method: "POST",
36
+ headers: {
37
+ Authorization: `Bot ${this.token}`,
38
+ "Content-Type": "application/json"
39
+ },
40
+ body: JSON.stringify(replyBody)
23
41
  });
42
+ if (!response.ok) {
43
+ throw new Error(`Discord API error: ${response.status} ${response.statusText}`);
44
+ }
45
+ return response.json();
24
46
  }
25
47
  normalizeContent(content) {
26
48
  if (typeof content === "string") {
27
49
  return { content };
28
50
  }
29
- if (content instanceof EmbedBuilder) {
30
- return { embeds: [content.toJSON()] };
31
- }
32
- if (content instanceof ActionRowBuilder) {
51
+ if (this.isBuilder(content)) {
33
52
  const json = content.toJSON();
53
+ if (this.isEmbedJSON(json)) {
54
+ return { embeds: [json] };
55
+ }
34
56
  return {
35
- components: [json],
57
+ components: [json]
36
58
  };
37
59
  }
60
+ // Handle plain embed object
61
+ if (this.isEmbedJSON(content)) {
62
+ return { embeds: [content] };
63
+ }
64
+ // Handle plain component object
65
+ if (this.isComponent(content)) {
66
+ return { components: [content] };
67
+ }
38
68
  if (Array.isArray(content)) {
39
69
  const embeds = [];
40
70
  const components = [];
41
71
  for (const item of content) {
42
- if (item instanceof EmbedBuilder) {
43
- embeds.push(item.toJSON());
72
+ if (this.isBuilder(item)) {
73
+ const json = item.toJSON();
74
+ if (this.isEmbedJSON(json)) {
75
+ embeds.push(json);
76
+ }
77
+ else {
78
+ components.push(json);
79
+ }
80
+ }
81
+ else if (this.isEmbedJSON(item)) {
82
+ embeds.push(item);
44
83
  }
45
- else if (item instanceof ActionRowBuilder) {
46
- components.push(item.toJSON());
84
+ else if (this.isComponent(item)) {
85
+ components.push(item);
47
86
  }
48
87
  }
49
88
  const result = {};
@@ -55,7 +94,29 @@ export class MessageHelper {
55
94
  }
56
95
  return result;
57
96
  }
97
+ // If we get here, content should be MessageBody
58
98
  return content;
59
99
  }
100
+ isBuilder(value) {
101
+ return (typeof value === "object" &&
102
+ value !== null &&
103
+ "toJSON" in value &&
104
+ typeof value.toJSON === "function");
105
+ }
106
+ isEmbedJSON(json) {
107
+ return (typeof json === "object" &&
108
+ json !== null &&
109
+ !("type" in json && typeof json.type === "number") &&
110
+ ("title" in json ||
111
+ "description" in json ||
112
+ "color" in json ||
113
+ "fields" in json));
114
+ }
115
+ isComponent(value) {
116
+ return (typeof value === "object" &&
117
+ value !== null &&
118
+ "type" in value &&
119
+ typeof value.type === "number");
120
+ }
60
121
  }
61
122
  //# sourceMappingURL=message-helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-helper.js","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,gBAAgB,GAGjB,MAAM,YAAY,CAAC;AAoBpB,MAAM,OAAO,aAAa;IAChB,IAAI,CAAO;IAEnB,YAAY,KAAa;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,OAAuB;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,KAAK,CACT,SAAiB,EACjB,SAAiB,EACjB,OAA2B,EAC3B,OAAuB;QAEvB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAsC;YACnD,GAAG,IAAI;YACP,iBAAiB,EAAE;gBACjB,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,SAAS;gBACrB,GAAG,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;aACtC;SACF,CAAC;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;YACvD,IAAI,EAAE,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,OAAuB;QAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,YAAY,YAAY,EAAE,CAAC;YACpC,OAAO,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QACxC,CAAC;QAED,IAAI,OAAO,YAAY,gBAAgB,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO;gBACL,UAAU,EAAE,CAAC,IAAI,CAAC;aACkB,CAAC;QACzC,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAe,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAc,EAAE,CAAC;YAEjC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,IAAI,YAAY,YAAY,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC7B,CAAC;qBAAM,IAAI,IAAI,YAAY,gBAAgB,EAAE,CAAC;oBAC5C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAA0B,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACzB,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;YACjC,CAAC;YACD,OAAO,MAA2C,CAAC;QACrD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
1
+ {"version":3,"file":"message-helper.js","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,16 +1,11 @@
1
1
  {
2
2
  "name": "flarecord",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "discord gateway client for cloudflare workers. built with typescript and optimized for durable objects.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- }
13
- },
8
+ "source": "./dist/index.js",
14
9
  "files": [
15
10
  "dist",
16
11
  "src"
@@ -42,7 +37,6 @@
42
37
  "typescript": "^5.5.2"
43
38
  },
44
39
  "dependencies": {
45
- "discord-api-types": "^0.38.37",
46
- "discord.js": "^14.25.1"
40
+ "discord-api-types": "^0.38.37"
47
41
  }
48
42
  }
package/src/index.ts CHANGED
@@ -34,63 +34,3 @@ export {
34
34
  } from "./types/constants";
35
35
  export { DEFAULT_IDENTIFY_PROPERTIES } from "./types";
36
36
 
37
- export {
38
- EmbedBuilder,
39
- ActionRowBuilder,
40
- ButtonBuilder,
41
- StringSelectMenuBuilder,
42
- UserSelectMenuBuilder,
43
- RoleSelectMenuBuilder,
44
- ChannelSelectMenuBuilder,
45
- MentionableSelectMenuBuilder,
46
- ModalBuilder,
47
- TextInputBuilder,
48
- AttachmentBuilder,
49
- SlashCommandBuilder,
50
- ContextMenuCommandBuilder,
51
- SlashCommandSubcommandBuilder,
52
- SlashCommandSubcommandGroupBuilder,
53
- SlashCommandOptionsOnlyBuilder,
54
- SlashCommandBooleanOption,
55
- SlashCommandChannelOption,
56
- SlashCommandIntegerOption,
57
- SlashCommandMentionableOption,
58
- SlashCommandNumberOption,
59
- SlashCommandRoleOption,
60
- SlashCommandStringOption,
61
- SlashCommandUserOption,
62
- REST,
63
- Routes,
64
- Colors,
65
- PermissionFlagsBits,
66
- GatewayIntentBits,
67
- Events,
68
- ActivityType,
69
- ChannelType,
70
- MessageType,
71
- InteractionType,
72
- ApplicationCommandType,
73
- ButtonStyle,
74
- TextInputStyle,
75
- ComponentType,
76
- Locale,
77
- type APIEmbed,
78
- type APIEmbedField,
79
- type APIButtonComponent,
80
- type APIActionRowComponent,
81
- type APIMessageComponent,
82
- type RESTPostAPIChannelMessageJSONBody,
83
- type RESTPostAPIChannelMessageResult,
84
- type APIInteractionResponse,
85
- type APIMessage,
86
- type APIUser,
87
- type APIGuild,
88
- type APIChannel,
89
- type APIInteraction,
90
- type APIChatInputApplicationCommandInteraction,
91
- type APIMessageApplicationCommandInteraction,
92
- type APIUserApplicationCommandInteraction,
93
- type APIMessageComponentInteraction,
94
- type APIModalSubmitInteraction,
95
- } from "discord.js";
96
-
@@ -1,20 +1,27 @@
1
- import {
2
- REST,
3
- Routes,
4
- EmbedBuilder,
5
- ActionRowBuilder,
6
- type RESTPostAPIChannelMessageJSONBody,
7
- type APIEmbed,
8
- } from "discord.js";
1
+ type DiscordBuilder = {
2
+ toJSON(): unknown;
3
+ };
9
4
 
10
- type MessageContent =
11
- | string
12
- | EmbedBuilder
13
- | ActionRowBuilder<never>
14
- | RESTPostAPIChannelMessageJSONBody
15
- | (EmbedBuilder | ActionRowBuilder<never>)[];
5
+ type APIEmbed = {
6
+ title?: string;
7
+ description?: string;
8
+ color?: number;
9
+ fields?: unknown[];
10
+ [key: string]: unknown;
11
+ };
12
+
13
+ type MessageBody = {
14
+ content?: string;
15
+ embeds?: unknown[];
16
+ components?: unknown[];
17
+ message_reference?: {
18
+ message_id: string;
19
+ channel_id: string;
20
+ guild_id?: string;
21
+ };
22
+ };
16
23
 
17
- interface NormalizedMessageBody {
24
+ type NormalizedMessageBody = {
18
25
  content?: string;
19
26
  embeds?: APIEmbed[];
20
27
  components?: unknown[];
@@ -23,18 +30,51 @@ interface NormalizedMessageBody {
23
30
  channel_id: string;
24
31
  guild_id?: string;
25
32
  };
26
- }
33
+ };
34
+
35
+ type Component = {
36
+ type: number;
37
+ style?: number;
38
+ custom_id?: string;
39
+ label?: string;
40
+ components?: Component[];
41
+ [key: string]: unknown;
42
+ };
43
+
44
+ type MessageContent =
45
+ | string
46
+ | DiscordBuilder
47
+ | MessageBody
48
+ | DiscordBuilder[]
49
+ | APIEmbed
50
+ | Component
51
+ | (APIEmbed | Component)[];
27
52
 
28
53
  export class MessageHelper {
29
- private rest: REST;
54
+ private token: string;
55
+ private readonly baseUrl = "https://discord.com/api/v10";
30
56
 
31
57
  constructor(token: string) {
32
- this.rest = new REST().setToken(token);
58
+ this.token = token;
33
59
  }
34
60
 
35
61
  async send(channelId: string, content: MessageContent): Promise<unknown> {
36
62
  const body = this.normalizeContent(content);
37
- return this.rest.post(Routes.channelMessages(channelId), { body });
63
+ const url = `${this.baseUrl}/channels/${channelId}/messages`;
64
+ const response = await fetch(url, {
65
+ method: "POST",
66
+ headers: {
67
+ Authorization: `Bot ${this.token}`,
68
+ "Content-Type": "application/json"
69
+ },
70
+ body: JSON.stringify(body)
71
+ });
72
+ if (!response.ok) {
73
+ throw new Error(
74
+ `Discord API error: ${response.status} ${response.statusText}`
75
+ );
76
+ }
77
+ return response.json();
38
78
  }
39
79
 
40
80
  async reply(
@@ -44,33 +84,52 @@ export class MessageHelper {
44
84
  content: MessageContent
45
85
  ): Promise<unknown> {
46
86
  const body = this.normalizeContent(content);
47
- const replyBody: RESTPostAPIChannelMessageJSONBody = {
87
+ const replyBody: MessageBody = {
48
88
  ...body,
49
89
  message_reference: {
50
90
  message_id: messageId,
51
91
  channel_id: channelId,
52
- ...(guildId && { guild_id: guildId }),
53
- },
92
+ ...guildId && { guild_id: guildId }
93
+ }
54
94
  };
55
- return this.rest.post(Routes.channelMessages(channelId), {
56
- body: replyBody,
95
+ const url = `${this.baseUrl}/channels/${channelId}/messages`;
96
+ const response = await fetch(url, {
97
+ method: "POST",
98
+ headers: {
99
+ Authorization: `Bot ${this.token}`,
100
+ "Content-Type": "application/json"
101
+ },
102
+ body: JSON.stringify(replyBody)
57
103
  });
104
+ if (!response.ok) {
105
+ throw new Error(
106
+ `Discord API error: ${response.status} ${response.statusText}`
107
+ );
108
+ }
109
+ return response.json();
58
110
  }
59
111
 
60
- private normalizeContent(content: MessageContent): RESTPostAPIChannelMessageJSONBody {
112
+ private normalizeContent(content: MessageContent): MessageBody {
61
113
  if (typeof content === "string") {
62
114
  return { content };
63
115
  }
64
116
 
65
- if (content instanceof EmbedBuilder) {
66
- return { embeds: [content.toJSON()] };
67
- }
68
-
69
- if (content instanceof ActionRowBuilder) {
117
+ if (this.isBuilder(content)) {
70
118
  const json = content.toJSON();
119
+ if (this.isEmbedJSON(json)) {
120
+ return { embeds: [json] };
121
+ }
71
122
  return {
72
- components: [json],
73
- } as RESTPostAPIChannelMessageJSONBody;
123
+ components: [json]
124
+ };
125
+ }
126
+
127
+ if (this.isEmbedJSON(content)) {
128
+ return { embeds: [content as APIEmbed] };
129
+ }
130
+
131
+ if (this.isComponent(content)) {
132
+ return { components: [content] };
74
133
  }
75
134
 
76
135
  if (Array.isArray(content)) {
@@ -78,10 +137,17 @@ export class MessageHelper {
78
137
  const components: unknown[] = [];
79
138
 
80
139
  for (const item of content) {
81
- if (item instanceof EmbedBuilder) {
82
- embeds.push(item.toJSON());
83
- } else if (item instanceof ActionRowBuilder) {
84
- components.push(item.toJSON());
140
+ if (this.isBuilder(item)) {
141
+ const json = item.toJSON();
142
+ if (this.isEmbedJSON(json)) {
143
+ embeds.push(json as APIEmbed);
144
+ } else {
145
+ components.push(json);
146
+ }
147
+ } else if (this.isEmbedJSON(item)) {
148
+ embeds.push(item as APIEmbed);
149
+ } else if (this.isComponent(item)) {
150
+ components.push(item);
85
151
  }
86
152
  }
87
153
 
@@ -92,9 +158,42 @@ export class MessageHelper {
92
158
  if (components.length > 0) {
93
159
  result.components = components;
94
160
  }
95
- return result as RESTPostAPIChannelMessageJSONBody;
161
+ return result;
96
162
  }
97
163
 
98
- return content;
164
+ // If we get here, content should be MessageBody
165
+ return content as MessageBody;
166
+ }
167
+
168
+ private isBuilder(value: unknown): value is DiscordBuilder {
169
+ return (
170
+ typeof value === "object" &&
171
+ value !== null &&
172
+ "toJSON" in value &&
173
+ typeof (value as { toJSON: unknown }).toJSON === "function"
174
+ );
175
+ }
176
+
177
+ private isEmbedJSON(json: unknown): boolean {
178
+ return (
179
+ typeof json === "object" &&
180
+ json !== null &&
181
+ !(
182
+ "type" in json && typeof (json as { type: unknown }).type === "number"
183
+ ) &&
184
+ ("title" in json ||
185
+ "description" in json ||
186
+ "color" in json ||
187
+ "fields" in json)
188
+ );
189
+ }
190
+
191
+ private isComponent(value: unknown): value is Component {
192
+ return (
193
+ typeof value === "object" &&
194
+ value !== null &&
195
+ "type" in value &&
196
+ typeof (value as { type: unknown }).type === "number"
197
+ );
99
198
  }
100
199
  }