transcriptify 1.0.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/src/generateHtml.d.ts +3 -0
  4. package/dist/src/generateHtml.js +303 -0
  5. package/dist/src/index.d.ts +5 -0
  6. package/dist/src/index.js +252 -0
  7. package/dist/src/transcript.d.ts +12 -0
  8. package/dist/src/transcript.js +179 -0
  9. package/dist/src/types/entities.d.ts +30 -0
  10. package/dist/src/types/entities.js +2 -0
  11. package/dist/src/utils/assetManager.d.ts +12 -0
  12. package/dist/src/utils/assetManager.js +295 -0
  13. package/dist/src/utils/authors.d.ts +4 -0
  14. package/dist/src/utils/authors.js +115 -0
  15. package/dist/src/utils/cache.d.ts +16 -0
  16. package/dist/src/utils/cache.js +29 -0
  17. package/dist/src/utils/extractors.d.ts +112 -0
  18. package/dist/src/utils/extractors.js +223 -0
  19. package/dist/src/utils/polls.d.ts +2 -0
  20. package/dist/src/utils/polls.js +91 -0
  21. package/dist/src/utils/transformer.d.ts +6 -0
  22. package/dist/src/utils/transformer.js +78 -0
  23. package/dist/src/utils/user.d.ts +4 -0
  24. package/dist/src/utils/user.js +56 -0
  25. package/dist/src/web/client.d.ts +20 -0
  26. package/dist/src/web/client.js +21 -0
  27. package/dist/src/web/discord-components/AudioPlayer.d.ts +5 -0
  28. package/dist/src/web/discord-components/AudioPlayer.js +231 -0
  29. package/dist/src/web/discord-components/Button.d.ts +3 -0
  30. package/dist/src/web/discord-components/Button.js +27 -0
  31. package/dist/src/web/discord-components/ChannelPinnedMessage.d.ts +7 -0
  32. package/dist/src/web/discord-components/ChannelPinnedMessage.js +11 -0
  33. package/dist/src/web/discord-components/DateSeperator.d.ts +3 -0
  34. package/dist/src/web/discord-components/DateSeperator.js +19 -0
  35. package/dist/src/web/discord-components/Embed.d.ts +2 -0
  36. package/dist/src/web/discord-components/Embed.js +78 -0
  37. package/dist/src/web/discord-components/ForwardedMessage.d.ts +2 -0
  38. package/dist/src/web/discord-components/ForwardedMessage.js +44 -0
  39. package/dist/src/web/discord-components/Message.d.ts +2 -0
  40. package/dist/src/web/discord-components/Message.js +543 -0
  41. package/dist/src/web/discord-components/PinnedMessagesModal.d.ts +6 -0
  42. package/dist/src/web/discord-components/PinnedMessagesModal.js +119 -0
  43. package/dist/src/web/discord-components/PinnedMessagesOverview.d.ts +5 -0
  44. package/dist/src/web/discord-components/PinnedMessagesOverview.js +22 -0
  45. package/dist/src/web/discord-components/Reply.d.ts +2 -0
  46. package/dist/src/web/discord-components/Reply.js +42 -0
  47. package/dist/src/web/discord-components/StickerPreview.d.ts +6 -0
  48. package/dist/src/web/discord-components/StickerPreview.js +40 -0
  49. package/dist/src/web/discord-components/ThemeSwitcher.d.ts +2 -0
  50. package/dist/src/web/discord-components/ThemeSwitcher.js +54 -0
  51. package/dist/src/web/discord-components/Transcript.d.ts +2 -0
  52. package/dist/src/web/discord-components/Transcript.js +174 -0
  53. package/dist/src/web/discord-components/UserJoinMessage.d.ts +3 -0
  54. package/dist/src/web/discord-components/UserJoinMessage.js +33 -0
  55. package/dist/src/web/discord-components/VideoPlayer.d.ts +6 -0
  56. package/dist/src/web/discord-components/VideoPlayer.js +222 -0
  57. package/dist/src/web/discord-components/icons/ChevronDownIcon.d.ts +1 -0
  58. package/dist/src/web/discord-components/icons/ChevronDownIcon.js +7 -0
  59. package/dist/src/web/discord-components/icons/CloseIcon.d.ts +1 -0
  60. package/dist/src/web/discord-components/icons/CloseIcon.js +7 -0
  61. package/dist/src/web/discord-components/icons/ExternalLinkIcon.d.ts +1 -0
  62. package/dist/src/web/discord-components/icons/ExternalLinkIcon.js +7 -0
  63. package/dist/src/web/discord-components/icons/FileAudioIcon.d.ts +1 -0
  64. package/dist/src/web/discord-components/icons/FileAudioIcon.js +7 -0
  65. package/dist/src/web/discord-components/icons/FileCodeIcon.d.ts +1 -0
  66. package/dist/src/web/discord-components/icons/FileCodeIcon.js +7 -0
  67. package/dist/src/web/discord-components/icons/FileDocumentIcon.d.ts +1 -0
  68. package/dist/src/web/discord-components/icons/FileDocumentIcon.js +7 -0
  69. package/dist/src/web/discord-components/icons/PinIcon.d.ts +1 -0
  70. package/dist/src/web/discord-components/icons/PinIcon.js +7 -0
  71. package/dist/src/web/discord-components/icons/VerifiedIcon.d.ts +1 -0
  72. package/dist/src/web/discord-components/icons/VerifiedIcon.js +7 -0
  73. package/dist/src/web/discord-components/index.d.ts +11 -0
  74. package/dist/src/web/discord-components/index.js +24 -0
  75. package/dist/src/web/discord-components/messageHelpers.d.ts +8 -0
  76. package/dist/src/web/discord-components/messageHelpers.js +72 -0
  77. package/dist/src/web/discord-components/themeColors.d.ts +9 -0
  78. package/dist/src/web/discord-components/themeColors.js +320 -0
  79. package/dist/src/web/discord-components/transcriptHelpers.d.ts +19 -0
  80. package/dist/src/web/discord-components/transcriptHelpers.js +120 -0
  81. package/dist/src/web/discord-components/types.d.ts +1 -0
  82. package/dist/src/web/discord-components/types.js +2 -0
  83. package/dist/src/web/discord-components/utils/date.d.ts +3 -0
  84. package/dist/src/web/discord-components/utils/date.js +50 -0
  85. package/dist/src/web/discord-components/utils/markdown.d.ts +11 -0
  86. package/dist/src/web/discord-components/utils/markdown.js +538 -0
  87. package/dist/src/web/discord-components/utils/markdownUtils.d.ts +12 -0
  88. package/dist/src/web/discord-components/utils/markdownUtils.js +140 -0
  89. package/dist/src/web/helpers/avatarHelpers.d.ts +2 -0
  90. package/dist/src/web/helpers/avatarHelpers.js +15 -0
  91. package/dist/src/web/helpers/cdnHelpers.d.ts +5 -0
  92. package/dist/src/web/helpers/cdnHelpers.js +48 -0
  93. package/dist/src/web/helpers/contentHelpers.d.ts +9 -0
  94. package/dist/src/web/helpers/contentHelpers.js +41 -0
  95. package/dist/src/web/helpers/renderContent.d.ts +2 -0
  96. package/dist/src/web/helpers/renderContent.js +15 -0
  97. package/dist/src/web/helpers/scrollHelpers.d.ts +2 -0
  98. package/dist/src/web/helpers/scrollHelpers.js +31 -0
  99. package/dist/src/web/helpers/timestampHelpers.d.ts +6 -0
  100. package/dist/src/web/helpers/timestampHelpers.js +66 -0
  101. package/dist/src/web/hooks/useMessageContent.d.ts +5 -0
  102. package/dist/src/web/hooks/useMessageContent.js +37 -0
  103. package/dist/src/web/index.d.ts +1 -0
  104. package/dist/src/web/index.js +17 -0
  105. package/dist/src/web/types/attachment.d.ts +6 -0
  106. package/dist/src/web/types/attachment.js +2 -0
  107. package/dist/src/web/types/author.d.ts +14 -0
  108. package/dist/src/web/types/author.js +2 -0
  109. package/dist/src/web/types/channel.d.ts +8 -0
  110. package/dist/src/web/types/channel.js +2 -0
  111. package/dist/src/web/types/embed.d.ts +52 -0
  112. package/dist/src/web/types/embed.js +2 -0
  113. package/dist/src/web/types/interaction.d.ts +8 -0
  114. package/dist/src/web/types/interaction.js +2 -0
  115. package/dist/src/web/types/markdown.d.ts +5 -0
  116. package/dist/src/web/types/markdown.js +2 -0
  117. package/dist/src/web/types/message.d.ts +73 -0
  118. package/dist/src/web/types/message.js +2 -0
  119. package/dist/src/web/types/poll.d.ts +11 -0
  120. package/dist/src/web/types/poll.js +2 -0
  121. package/dist/src/web/types/props.d.ts +155 -0
  122. package/dist/src/web/types/props.js +2 -0
  123. package/dist/src/web/types/reaction.d.ts +6 -0
  124. package/dist/src/web/types/reaction.js +2 -0
  125. package/dist/src/web/types/theme.d.ts +14 -0
  126. package/dist/src/web/types/theme.js +2 -0
  127. package/dist/src/web/types/ui.d.ts +10 -0
  128. package/dist/src/web/types/ui.js +2 -0
  129. package/dist/types/download.d.ts +12 -0
  130. package/dist/types/download.js +2 -0
  131. package/dist/types/exportableTranscript.d.ts +169 -0
  132. package/dist/types/exportableTranscript.js +2 -0
  133. package/dist/types/general.d.ts +90 -0
  134. package/dist/types/general.js +2 -0
  135. package/package.json +46 -0
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.userColorCache = exports.guildTagCache = void 0;
4
+ class GuildTagCache {
5
+ cache = new Map();
6
+ get(userId) {
7
+ return this.cache.get(userId);
8
+ }
9
+ set(userId, tag) {
10
+ this.cache.set(userId, tag);
11
+ }
12
+ has(userId) {
13
+ return this.cache.has(userId);
14
+ }
15
+ }
16
+ class UserColorCache {
17
+ cache = new Map();
18
+ get(key) {
19
+ return this.cache.get(key);
20
+ }
21
+ set(key, color) {
22
+ this.cache.set(key, color);
23
+ }
24
+ has(key) {
25
+ return this.cache.has(key);
26
+ }
27
+ }
28
+ exports.guildTagCache = new GuildTagCache();
29
+ exports.userColorCache = new UserColorCache();
@@ -0,0 +1,112 @@
1
+ interface ExtractedEmbed {
2
+ title: string | null;
3
+ description: string | null;
4
+ url: string | null;
5
+ timestamp: string | null;
6
+ color: string | null;
7
+ footer: {
8
+ text: string | null;
9
+ iconUrl: string | null;
10
+ } | null;
11
+ image: {
12
+ url: string | null;
13
+ width: number | null;
14
+ height: number | null;
15
+ } | null;
16
+ thumbnail: {
17
+ url: string | null;
18
+ width: number | null;
19
+ height: number | null;
20
+ } | null;
21
+ author: {
22
+ name: string | null;
23
+ url: string | null;
24
+ iconUrl: string | null;
25
+ } | null;
26
+ fields?: Array<{
27
+ name: string;
28
+ value: string;
29
+ inline: boolean;
30
+ }>;
31
+ }
32
+ interface ExtractedAttachment {
33
+ id: string;
34
+ filename: string;
35
+ url: string;
36
+ proxyURL: string | null;
37
+ contentType: string | null;
38
+ size: number | undefined;
39
+ width: number | null;
40
+ height: number | null;
41
+ embedUrl?: string;
42
+ }
43
+ interface ExtractedSticker {
44
+ id: string;
45
+ name: string | null;
46
+ tags: string | null;
47
+ format: string | null;
48
+ }
49
+ interface ExtractedReaction {
50
+ emoji: {
51
+ id: string | null;
52
+ name: string | null;
53
+ animated: boolean;
54
+ };
55
+ count: number;
56
+ me: boolean;
57
+ }
58
+ interface ExtractedSelectOption {
59
+ label: string;
60
+ value: string;
61
+ description: string | null;
62
+ default: boolean;
63
+ }
64
+ interface ExtractedButtonComponent {
65
+ type: number;
66
+ customId: string | null;
67
+ label: string | null;
68
+ style: number | null;
69
+ url: string | null;
70
+ disabled: boolean | null;
71
+ emojiUrl?: string;
72
+ }
73
+ interface ExtractedSelectComponent {
74
+ customId: string | null;
75
+ placeholder: string | null;
76
+ minValues: number | null;
77
+ maxValues: number | null;
78
+ options?: ExtractedSelectOption[];
79
+ }
80
+ interface ExtractedComponents {
81
+ actionRows: Array<{
82
+ type: number;
83
+ components: Array<Record<string, unknown>>;
84
+ }>;
85
+ buttons: ExtractedButtonComponent[];
86
+ selects: ExtractedSelectComponent[];
87
+ }
88
+ interface ExtractedInteraction {
89
+ id: string | null;
90
+ type: number | null;
91
+ name: string | null;
92
+ user: {
93
+ id: string;
94
+ username: string;
95
+ } | null;
96
+ }
97
+ interface MessageLike {
98
+ embeds?: unknown;
99
+ attachments?: unknown;
100
+ stickers?: unknown;
101
+ stickerItems?: unknown;
102
+ reactions?: unknown;
103
+ components?: unknown;
104
+ interaction?: Partial<ExtractedInteraction>;
105
+ }
106
+ export declare function extractEmbeds(message: MessageLike): ExtractedEmbed[];
107
+ export declare function extractAttachments(message: MessageLike): ExtractedAttachment[];
108
+ export declare function extractStickers(message: MessageLike): ExtractedSticker[];
109
+ export declare function extractReactions(message: MessageLike): ExtractedReaction[];
110
+ export declare function extractComponents(message: MessageLike): ExtractedComponents | null;
111
+ export declare function extractInteraction(message: MessageLike): ExtractedInteraction | null;
112
+ export {};
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractEmbeds = extractEmbeds;
4
+ exports.extractAttachments = extractAttachments;
5
+ exports.extractStickers = extractStickers;
6
+ exports.extractReactions = extractReactions;
7
+ exports.extractComponents = extractComponents;
8
+ exports.extractInteraction = extractInteraction;
9
+ function ensureArray(value) {
10
+ if (!value)
11
+ return [];
12
+ if (Array.isArray(value))
13
+ return value;
14
+ if (typeof value.values === "function")
15
+ return Array.from(value.values());
16
+ return Array.from(value);
17
+ }
18
+ function extractEmbeds(message) {
19
+ try {
20
+ const embeds = ensureArray(message.embeds);
21
+ if (embeds.length === 0)
22
+ return [];
23
+ return embeds
24
+ .map((e) => {
25
+ const hasContent = e.title || e.description || e.author || (e.fields && e.fields.length > 0) || e.footer;
26
+ const imageUrl = e.image?.proxyURL ?? e.image?.proxy_url ?? e.image?.url ?? null;
27
+ const thumbnailUrl = e.thumbnail?.proxyURL ?? e.thumbnail?.proxy_url ?? e.thumbnail?.url ?? null;
28
+ if (!hasContent && (imageUrl || thumbnailUrl) && e.url) {
29
+ return null;
30
+ }
31
+ return {
32
+ title: e.title ?? null,
33
+ description: e.description ?? null,
34
+ url: e.url ?? null,
35
+ timestamp: e.timestamp ? new Date(e.timestamp).toISOString() : null,
36
+ color: typeof e.hexColor === "string"
37
+ ? e.hexColor
38
+ : typeof e.color === "string"
39
+ ? e.color
40
+ : typeof e.color === "number"
41
+ ? `#${e.color.toString(16).padStart(6, "0")}`
42
+ : null,
43
+ footer: e.footer ? { text: e.footer.text ?? null, iconUrl: e.footer.iconURL ?? null } : null,
44
+ image: e.image
45
+ ? {
46
+ url: imageUrl,
47
+ width: e.image?.width ?? null,
48
+ height: e.image?.height ?? null
49
+ }
50
+ : null,
51
+ thumbnail: e.thumbnail
52
+ ? {
53
+ url: thumbnailUrl,
54
+ width: e.thumbnail?.width ?? null,
55
+ height: e.thumbnail?.height ?? null
56
+ }
57
+ : null,
58
+ author: e.author
59
+ ? {
60
+ name: e.author.name ?? null,
61
+ url: e.author.url ?? null,
62
+ iconUrl: e.author.proxyIconURL ?? e.author.proxy_icon_url ?? e.author.iconURL ?? null
63
+ }
64
+ : null,
65
+ fields: Array.isArray(e.fields) ? e.fields.map((f) => ({ name: f.name, value: f.value, inline: !!f.inline })) : undefined
66
+ };
67
+ })
68
+ .filter((e) => e !== null);
69
+ }
70
+ catch {
71
+ return [];
72
+ }
73
+ }
74
+ function extractAttachments(message) {
75
+ try {
76
+ const attachments = ensureArray(message.attachments);
77
+ const mappedAttachments = attachments.map((a) => ({
78
+ id: a.id,
79
+ filename: a.name ?? a.filename ?? "",
80
+ url: a.url,
81
+ proxyURL: a.proxyURL ?? null,
82
+ contentType: a.contentType ?? null,
83
+ size: a.size ?? undefined,
84
+ width: a.width ?? null,
85
+ height: a.height ?? null
86
+ }));
87
+ const embeds = ensureArray(message.embeds);
88
+ for (const e of embeds) {
89
+ const hasContent = e.title || e.description || e.author || (e.fields && e.fields.length > 0) || e.footer;
90
+ const imageUrl = e.image?.proxyURL ?? e.image?.proxy_url ?? e.image?.url ?? null;
91
+ const thumbnailUrl = e.thumbnail?.proxyURL ?? e.thumbnail?.proxy_url ?? e.thumbnail?.url ?? null;
92
+ if (!hasContent && (imageUrl || thumbnailUrl) && e.url) {
93
+ const url = imageUrl || thumbnailUrl;
94
+ const filename = url.split("/").pop()?.split("?")[0] || "image";
95
+ mappedAttachments.push({
96
+ id: `embed-${Math.random().toString(36).substr(2, 9)}`,
97
+ filename: filename,
98
+ url: url,
99
+ proxyURL: url,
100
+ contentType: null,
101
+ size: undefined,
102
+ width: e.image?.width ?? e.thumbnail?.width ?? null,
103
+ height: e.image?.height ?? e.thumbnail?.height ?? null,
104
+ embedUrl: e.url
105
+ });
106
+ }
107
+ }
108
+ return mappedAttachments;
109
+ }
110
+ catch {
111
+ return [];
112
+ }
113
+ }
114
+ function extractStickers(message) {
115
+ try {
116
+ const stickers = ensureArray(message.stickers || message.stickerItems);
117
+ return stickers.length > 0
118
+ ? stickers.map((st) => ({
119
+ id: st.id,
120
+ name: st.name ?? null,
121
+ tags: st.tags ?? null,
122
+ format: st.format ?? null
123
+ }))
124
+ : [];
125
+ }
126
+ catch {
127
+ return [];
128
+ }
129
+ }
130
+ function extractReactions(message) {
131
+ try {
132
+ const reactionValue = message.reactions;
133
+ const reactions = reactionValue && typeof reactionValue === "object" && "cache" in reactionValue
134
+ ? ensureArray(reactionValue.cache)
135
+ : ensureArray(reactionValue);
136
+ return reactions.length > 0
137
+ ? reactions.map((r) => ({
138
+ emoji: {
139
+ id: r.emoji?.id ?? null,
140
+ name: r.emoji?.name ?? null,
141
+ animated: !!r.emoji?.animated
142
+ },
143
+ count: r.count ?? 0,
144
+ me: !!r.me
145
+ }))
146
+ : [];
147
+ }
148
+ catch {
149
+ return [];
150
+ }
151
+ }
152
+ function extractComponents(message) {
153
+ try {
154
+ const components = message.components;
155
+ if (!components || (Array.isArray(components) && components.length === 0))
156
+ return null;
157
+ const rows = Array.isArray(components) ? components : components;
158
+ const actionRows = rows.map((r) => ({
159
+ type: r.type,
160
+ components: Array.isArray(r.components) ? r.components : []
161
+ }));
162
+ const buttons = [];
163
+ const selects = [];
164
+ for (const r of rows) {
165
+ const rowComponents = Array.isArray(r.components)
166
+ ? r.components
167
+ : [];
168
+ for (const c of rowComponents) {
169
+ if (c.type === 2) {
170
+ const btn = {
171
+ type: 2,
172
+ customId: c.customId ?? null,
173
+ label: c.label ?? null,
174
+ style: c.style ?? null,
175
+ url: c.url ?? null,
176
+ disabled: typeof c.disabled === "boolean" ? c.disabled : null
177
+ };
178
+ if (c.emoji?.id) {
179
+ const animated = !!c.emoji.animated ? "true" : "false";
180
+ btn.emojiUrl = `https://cdn.discordapp.com/emojis/${c.emoji.id}.webp?size=96&animated=${animated}`;
181
+ }
182
+ buttons.push(btn);
183
+ }
184
+ if (c.type === 3) {
185
+ selects.push({
186
+ customId: c.customId ?? null,
187
+ placeholder: c.placeholder ?? null,
188
+ minValues: c.minValues ?? null,
189
+ maxValues: c.maxValues ?? null,
190
+ options: Array.isArray(c.options)
191
+ ? c.options.map((o) => ({
192
+ label: o.label,
193
+ value: o.value,
194
+ description: o.description ?? null,
195
+ default: !!o.default
196
+ }))
197
+ : undefined
198
+ });
199
+ }
200
+ }
201
+ }
202
+ return { actionRows, buttons, selects };
203
+ }
204
+ catch {
205
+ return null;
206
+ }
207
+ }
208
+ function extractInteraction(message) {
209
+ try {
210
+ const interaction = message.interaction;
211
+ if (!interaction)
212
+ return null;
213
+ return {
214
+ id: interaction.id ?? null,
215
+ type: interaction.type ?? null,
216
+ name: interaction.name ?? null,
217
+ user: interaction.user ? { id: interaction.user.id, username: interaction.user.username } : null
218
+ };
219
+ }
220
+ catch {
221
+ return null;
222
+ }
223
+ }
@@ -0,0 +1,2 @@
1
+ export declare function extractPoll(message: any): any;
2
+ export declare function enrichPollVoters(message: any, poll: any): Promise<void>;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractPoll = extractPoll;
4
+ exports.enrichPollVoters = enrichPollVoters;
5
+ function extractPoll(message) {
6
+ try {
7
+ const nativePoll = message.poll ?? null;
8
+ if (nativePoll) {
9
+ const answersArray = Array.isArray(nativePoll.answers)
10
+ ? nativePoll.answers
11
+ : Array.from(typeof nativePoll.answers?.values === "function" ? nativePoll.answers.values() : (nativePoll.answers ?? []));
12
+ const options = answersArray.map((a) => {
13
+ const label = a.text ?? a.name ?? a.label ?? null;
14
+ const count = typeof a.voteCount === "number" ? a.voteCount : typeof a.votes === "number" ? a.votes : typeof a.count === "number" ? a.count : null;
15
+ return { id: a.id ?? null, label, count };
16
+ });
17
+ const total = options.reduce((sum, o) => sum + (o.count || 0), 0);
18
+ return {
19
+ type: "native",
20
+ question: nativePoll.question?.text ?? null,
21
+ options,
22
+ totalVotes: total || null,
23
+ endsAt: nativePoll.expiresTimestamp ? new Date(nativePoll.expiresTimestamp).toISOString() : null,
24
+ allowMultiselect: !!nativePoll.allowMultiselect
25
+ };
26
+ }
27
+ return null;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ async function enrichPollVoters(message, poll) {
34
+ if (!poll || poll.type !== "native")
35
+ return;
36
+ try {
37
+ const nativePoll = message.poll;
38
+ if (!nativePoll || !nativePoll.answers)
39
+ return;
40
+ const answersArray = Array.isArray(nativePoll.answers)
41
+ ? nativePoll.answers
42
+ : Array.from(typeof nativePoll.answers?.values === "function" ? nativePoll.answers.values() : nativePoll.answers);
43
+ for (const ans of answersArray) {
44
+ let voterIds = null;
45
+ try {
46
+ if (ans.voters) {
47
+ if (Array.isArray(ans.voters)) {
48
+ voterIds = ans.voters.map((u) => u.id ?? u).filter(Boolean);
49
+ }
50
+ else if (typeof ans.voters.values === "function") {
51
+ voterIds = Array.from(ans.voters.values())
52
+ .map((u) => u?.id ?? u)
53
+ .filter(Boolean);
54
+ }
55
+ else if (ans.voters.cache && typeof ans.voters.cache.values === "function") {
56
+ voterIds = Array.from(ans.voters.cache.values())
57
+ .map((u) => u?.id ?? u)
58
+ .filter(Boolean);
59
+ }
60
+ }
61
+ }
62
+ catch {
63
+ voterIds = null;
64
+ }
65
+ const matchIndex = poll.options.findIndex((o) => {
66
+ if (o.id && ans.id)
67
+ return o.id === ans.id;
68
+ return o.label && o.label === (ans.text ?? ans.name ?? ans.label ?? null);
69
+ });
70
+ if (matchIndex !== -1) {
71
+ if (voterIds && voterIds.length) {
72
+ poll.options[matchIndex].voters = voterIds;
73
+ poll.options[matchIndex].count = voterIds.length;
74
+ }
75
+ else {
76
+ const cnt = typeof ans.voteCount === "number"
77
+ ? ans.voteCount
78
+ : typeof ans.votes === "number"
79
+ ? ans.votes
80
+ : typeof ans.count === "number"
81
+ ? ans.count
82
+ : null;
83
+ if (cnt !== null)
84
+ poll.options[matchIndex].count = cnt;
85
+ }
86
+ }
87
+ }
88
+ poll.totalVotes = poll.options.reduce((sum, o) => sum + (o.count || 0), 0);
89
+ }
90
+ catch { }
91
+ }
@@ -0,0 +1,6 @@
1
+ import type { Message } from "discord.js";
2
+ import type { SerializableMessage, SerializableAuthor } from "../../types/exportableTranscript";
3
+ export declare function messageToSerializable(message: Message): Promise<{
4
+ message: SerializableMessage;
5
+ author: SerializableAuthor | null;
6
+ } | null>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.messageToSerializable = messageToSerializable;
4
+ const user_1 = require("./user");
5
+ const extractors_1 = require("./extractors");
6
+ const polls_1 = require("./polls");
7
+ const authors_1 = require("./authors");
8
+ async function messageToSerializable(message) {
9
+ if (message.type === 24)
10
+ return null;
11
+ const attachments = (0, extractors_1.extractAttachments)(message);
12
+ const embeds = (0, extractors_1.extractEmbeds)(message);
13
+ const stickers = (0, extractors_1.extractStickers)(message);
14
+ const reactions = (0, extractors_1.extractReactions)(message);
15
+ const componentData = (0, extractors_1.extractComponents)(message);
16
+ const interaction = (0, extractors_1.extractInteraction)(message);
17
+ const poll = (0, polls_1.extractPoll)(message);
18
+ const referencedMessageId = message.reference?.messageId ?? null;
19
+ const hasAuthor = !!message.author;
20
+ const authorObj = hasAuthor
21
+ ? {
22
+ id: message.author.id,
23
+ username: message.author.username,
24
+ tag: message.author.tag ?? undefined,
25
+ guildTag: await (0, user_1.getGuildTagForUser)(message.author),
26
+ nickname: message.member?.nickname ?? null,
27
+ avatar: message.author.avatar ?? null,
28
+ bot: message.author.bot ?? false,
29
+ color: await (0, user_1.getColorForUser)(message.author, message.guild ?? null, message.member ?? null),
30
+ verified: extractBotVerified(message.author)
31
+ }
32
+ : (0, authors_1.buildSystemAuthor)(message.id, message.type);
33
+ const forwarded = await (0, authors_1.extractForwarded)(message);
34
+ const authorId = authorObj ? authorObj.id : null;
35
+ return {
36
+ message: {
37
+ id: message.id,
38
+ content: message.content ?? (typeof message.type !== "undefined" ? `[System message: type ${message.type}]` : ""),
39
+ author: authorId,
40
+ createdAt: message.createdAt.toISOString(),
41
+ messageType: message.type ?? undefined,
42
+ embeds: embeds.length > 0 ? embeds : undefined,
43
+ actionRows: componentData?.actionRows ?? undefined,
44
+ buttons: componentData?.buttons ?? undefined,
45
+ selects: componentData?.selects ?? undefined,
46
+ stickers: stickers.length > 0 ? stickers : undefined,
47
+ reactions: reactions.length > 0 ? reactions : undefined,
48
+ editedAt: message.editedAt ? message.editedAt.toISOString() : null,
49
+ attachments,
50
+ pinned: message.pinned ?? false,
51
+ interaction,
52
+ referencedMessageId: forwarded ? null : referencedMessageId,
53
+ poll,
54
+ forwarded
55
+ },
56
+ author: authorObj
57
+ };
58
+ }
59
+ function extractBotVerified(user) {
60
+ if (!user.bot)
61
+ return null;
62
+ try {
63
+ const flags = user.flags ?? null;
64
+ if (!flags)
65
+ return null;
66
+ if (typeof flags.has === "function") {
67
+ return !!(flags.has("VerifiedBot") || flags.has("VERIFIED_BOT") || flags.has("VERIFIED_DEVELOPER"));
68
+ }
69
+ if (typeof flags.bitfield === "number") {
70
+ return (flags.bitfield & 0x80) === 0x80;
71
+ }
72
+ if (typeof flags === "number") {
73
+ return (flags & 0x80) === 0x80;
74
+ }
75
+ }
76
+ catch { }
77
+ return null;
78
+ }
@@ -0,0 +1,4 @@
1
+ import type { User, GuildMember } from "discord.js";
2
+ import type { GuildTag } from "../types/entities";
3
+ export declare function getGuildTagForUser(user: User): Promise<GuildTag>;
4
+ export declare function getColorForUser(user: User, guild: any | null, member?: GuildMember | null): Promise<string | null>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGuildTagForUser = getGuildTagForUser;
4
+ exports.getColorForUser = getColorForUser;
5
+ const cache_1 = require("./cache");
6
+ async function getGuildTagForUser(user) {
7
+ const cached = cache_1.guildTagCache.get(user.id);
8
+ if (cached) {
9
+ return cached;
10
+ }
11
+ const primaryGuild = user.primaryGuild;
12
+ if (!user.bot && primaryGuild && primaryGuild.identityEnabled) {
13
+ const tag = {
14
+ name: primaryGuild.tag ?? undefined,
15
+ iconUrl: primaryGuild.identityGuildId && primaryGuild.badge
16
+ ? `https://cdn.discordapp.com/clan-badges/${primaryGuild.identityGuildId}/${primaryGuild.badge}.png`
17
+ : null
18
+ };
19
+ cache_1.guildTagCache.set(user.id, tag);
20
+ return tag;
21
+ }
22
+ const emptyTag = { name: null, iconUrl: null };
23
+ cache_1.guildTagCache.set(user.id, emptyTag);
24
+ return emptyTag;
25
+ }
26
+ async function getColorForUser(user, guild, member) {
27
+ const guildId = guild?.id ?? null;
28
+ if (!guildId)
29
+ return null;
30
+ const key = `${guildId}:${user.id}`;
31
+ if (cache_1.userColorCache.has(key)) {
32
+ return cache_1.userColorCache.get(key) ?? null;
33
+ }
34
+ let memberToUse = member ?? null;
35
+ if (!memberToUse) {
36
+ try {
37
+ memberToUse = await guild.members.fetch(user.id).catch(() => null);
38
+ }
39
+ catch {
40
+ memberToUse = null;
41
+ }
42
+ }
43
+ let result = null;
44
+ if (memberToUse) {
45
+ const highestHex = (memberToUse.roles?.highest?.hexColor ?? null);
46
+ const hex = highestHex && highestHex !== "#000000"
47
+ ? highestHex
48
+ : memberToUse.displayHexColor && memberToUse.displayHexColor !== "#000000"
49
+ ? memberToUse.displayHexColor
50
+ : null;
51
+ if (hex)
52
+ result = hex;
53
+ }
54
+ cache_1.userColorCache.set(key, result);
55
+ return result;
56
+ }
@@ -0,0 +1,20 @@
1
+ declare global {
2
+ interface Window {
3
+ __TRANSCRIPT_DATA__: {
4
+ channel: any;
5
+ messages: any[];
6
+ theme: string;
7
+ resolvedUsers: Record<string, unknown>;
8
+ resolvedRoles: Record<string, unknown>;
9
+ resolvedChannels?: Record<string, {
10
+ name?: string | null;
11
+ guildId?: string | null;
12
+ }>;
13
+ exportedAt: string;
14
+ allowThemeSwitching?: boolean;
15
+ allowThemeSwitchingPersist?: boolean;
16
+ poweredBy?: boolean;
17
+ };
18
+ }
19
+ }
20
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const client_1 = require("react-dom/client");
8
+ const Transcript_1 = __importDefault(require("./discord-components/Transcript"));
9
+ const data = window.__TRANSCRIPT_DATA__ ?? {
10
+ channel: null,
11
+ messages: [],
12
+ theme: "",
13
+ resolvedUsers: {},
14
+ resolvedRoles: {},
15
+ resolvedChannels: {},
16
+ exportedAt: "",
17
+ allowThemeSwitching: true,
18
+ allowThemeSwitchingPersist: true,
19
+ poweredBy: true
20
+ };
21
+ (0, client_1.hydrateRoot)(document.getElementById("root"), (0, jsx_runtime_1.jsx)(Transcript_1.default, { channel: data.channel, messages: data.messages, theme: data.theme, allowThemeSwitching: typeof data.allowThemeSwitching === "boolean" ? data.allowThemeSwitching : true, allowThemeSwitchingPersist: typeof data.allowThemeSwitchingPersist === "boolean" ? data.allowThemeSwitchingPersist : true, poweredBy: data.poweredBy, resolvedUsers: data.resolvedUsers, resolvedRoles: data.resolvedRoles, resolvedChannels: data.resolvedChannels, exportedAt: data.exportedAt, className: "transcript-ssr" }));
@@ -0,0 +1,5 @@
1
+ export default function AudioPlayer({ url, filename, filesize }: {
2
+ url: string;
3
+ filename: string;
4
+ filesize: string;
5
+ }): import("react/jsx-runtime").JSX.Element;