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 +25 -12
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/message-helper.d.ts +34 -3
- package/dist/utils/message-helper.d.ts.map +1 -1
- package/dist/utils/message-helper.js +78 -17
- package/dist/utils/message-helper.js.map +1 -1
- package/package.json +3 -9
- package/src/index.ts +0 -60
- package/src/utils/message-helper.ts +137 -38
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
|
|
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 =
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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 =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
2
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
2
|
+
token;
|
|
3
|
+
baseUrl = "https://discord.com/api/v10";
|
|
4
4
|
constructor(token) {
|
|
5
|
-
this.
|
|
5
|
+
this.token = token;
|
|
6
6
|
}
|
|
7
7
|
async send(channelId, content) {
|
|
8
8
|
const body = this.normalizeContent(content);
|
|
9
|
-
|
|
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
|
-
...
|
|
19
|
-
}
|
|
30
|
+
...guildId && { guild_id: guildId }
|
|
31
|
+
}
|
|
20
32
|
};
|
|
21
|
-
|
|
22
|
-
|
|
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
|
|
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
|
|
43
|
-
|
|
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
|
|
46
|
-
components.push(item
|
|
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":"
|
|
1
|
+
{"version":3,"file":"message-helper.js","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"AAoDA,MAAM,OAAO,aAAa;IAChB,KAAK,CAAS;IACL,OAAO,GAAG,6BAA6B,CAAC;IAEzD,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,OAAuB;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,aAAa,SAAS,WAAW,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE;gBAClC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,sBAAsB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC/D,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,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,GAAgB;YAC7B,GAAG,IAAI;YACP,iBAAiB,EAAE;gBACjB,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,SAAS;gBACrB,GAAG,OAAO,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE;aACpC;SACF,CAAC;QACF,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,aAAa,SAAS,WAAW,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE;gBAClC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,sBAAsB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC/D,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAEO,gBAAgB,CAAC,OAAuB;QAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3B,OAAO,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,CAAC;YACD,OAAO;gBACL,UAAU,EAAE,CAAC,IAAI,CAAC;aACnB,CAAC;QACJ,CAAC;QAED,4BAA4B;QAC5B,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,EAAE,MAAM,EAAE,CAAC,OAAmB,CAAC,EAAE,CAAC;QAC3C,CAAC;QAED,gCAAgC;QAChC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,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,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC3B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC3B,MAAM,CAAC,IAAI,CAAC,IAAgB,CAAC,CAAC;oBAChC,CAAC;yBAAM,CAAC;wBACN,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACxB,CAAC;gBACH,CAAC;qBAAM,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,MAAM,CAAC,IAAI,CAAC,IAAgB,CAAC,CAAC;gBAChC,CAAC;qBAAM,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxB,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,MAAM,CAAC;QAChB,CAAC;QAED,gDAAgD;QAChD,OAAO,OAAsB,CAAC;IAChC,CAAC;IAEO,SAAS,CAAC,KAAc;QAC9B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,QAAQ,IAAI,KAAK;YACjB,OAAQ,KAA6B,CAAC,MAAM,KAAK,UAAU,CAC5D,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,IAAa;QAC/B,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,OAAQ,IAA0B,CAAC,IAAI,KAAK,QAAQ,CAAC;YACzE,CAAC,OAAO,IAAI,IAAI;gBACd,aAAa,IAAI,IAAI;gBACrB,OAAO,IAAI,IAAI;gBACf,QAAQ,IAAI,IAAI,CAAC,CACpB,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,KAAc;QAChC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,MAAM,IAAI,KAAK;YACf,OAAQ,KAA2B,CAAC,IAAI,KAAK,QAAQ,CACtD,CAAC;IACJ,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flarecord",
|
|
3
|
-
"version": "0.0.
|
|
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
|
-
"
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
|
54
|
+
private token: string;
|
|
55
|
+
private readonly baseUrl = "https://discord.com/api/v10";
|
|
30
56
|
|
|
31
57
|
constructor(token: string) {
|
|
32
|
-
this.
|
|
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
|
-
|
|
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:
|
|
87
|
+
const replyBody: MessageBody = {
|
|
48
88
|
...body,
|
|
49
89
|
message_reference: {
|
|
50
90
|
message_id: messageId,
|
|
51
91
|
channel_id: channelId,
|
|
52
|
-
...
|
|
53
|
-
}
|
|
92
|
+
...guildId && { guild_id: guildId }
|
|
93
|
+
}
|
|
54
94
|
};
|
|
55
|
-
|
|
56
|
-
|
|
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):
|
|
112
|
+
private normalizeContent(content: MessageContent): MessageBody {
|
|
61
113
|
if (typeof content === "string") {
|
|
62
114
|
return { content };
|
|
63
115
|
}
|
|
64
116
|
|
|
65
|
-
if (content
|
|
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
|
-
}
|
|
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
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
161
|
+
return result;
|
|
96
162
|
}
|
|
97
163
|
|
|
98
|
-
|
|
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
|
}
|