discord-message-transcript 1.3.1 → 1.3.2-dev.1.50

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 (75) hide show
  1. package/dist/core/{imageToBase64.d.ts → assetResolver/base64/imageToBase64.d.ts} +1 -1
  2. package/dist/core/{imageToBase64.js → assetResolver/base64/imageToBase64.js} +5 -4
  3. package/dist/core/assetResolver/cdn/cdnCustomError.d.ts +16 -0
  4. package/dist/core/assetResolver/cdn/cdnCustomError.js +28 -0
  5. package/dist/core/assetResolver/cdn/cdnResolver.d.ts +4 -0
  6. package/dist/core/assetResolver/cdn/cdnResolver.js +90 -0
  7. package/dist/core/assetResolver/cdn/cloudinaryCdnResolver.d.ts +1 -0
  8. package/dist/core/assetResolver/cdn/cloudinaryCdnResolver.js +120 -0
  9. package/dist/core/assetResolver/cdn/sanitizeFileName.d.ts +1 -0
  10. package/dist/core/assetResolver/cdn/sanitizeFileName.js +17 -0
  11. package/dist/core/assetResolver/cdn/uploadCareCdnResolver.d.ts +1 -0
  12. package/dist/core/assetResolver/cdn/uploadCareCdnResolver.js +137 -0
  13. package/dist/core/assetResolver/cdn/validateCdnUrl.d.ts +1 -0
  14. package/dist/core/assetResolver/cdn/validateCdnUrl.js +8 -0
  15. package/dist/core/assetResolver/contants.d.ts +1 -0
  16. package/dist/core/assetResolver/contants.js +1 -0
  17. package/dist/core/assetResolver/index.d.ts +8 -0
  18. package/dist/core/assetResolver/index.js +22 -0
  19. package/dist/core/assetResolver/url/authorUrlResolver.d.ts +3 -0
  20. package/dist/core/assetResolver/url/authorUrlResolver.js +10 -0
  21. package/dist/core/assetResolver/url/imageUrlResolver.d.ts +4 -0
  22. package/dist/core/{resolveImageUrl.js → assetResolver/url/imageUrlResolver.js} +3 -3
  23. package/dist/core/assetResolver/url/messageUrlResolver.d.ts +3 -0
  24. package/dist/core/{urlResolver.js → assetResolver/url/messageUrlResolver.js} +13 -44
  25. package/dist/core/assetResolver/url/urlResolver.d.ts +4 -0
  26. package/dist/core/assetResolver/url/urlResolver.js +24 -0
  27. package/dist/core/{componentToJson.d.ts → discordParser/componentToJson.d.ts} +1 -1
  28. package/dist/core/discordParser/componentToJson.js +158 -0
  29. package/dist/core/discordParser/fetchMessages.d.ts +7 -0
  30. package/dist/core/{fetchMessages.js → discordParser/fetchMessages.js} +1 -1
  31. package/dist/core/{getMentions.d.ts → discordParser/getMentions.d.ts} +1 -1
  32. package/dist/core/{getMentions.js → discordParser/getMentions.js} +1 -1
  33. package/dist/core/discordParser/index.d.ts +5 -0
  34. package/dist/core/discordParser/index.js +33 -0
  35. package/dist/core/mappers.d.ts +3 -2
  36. package/dist/core/mappers.js +3 -2
  37. package/dist/core/networkSecurity/dns.d.ts +1 -1
  38. package/dist/core/networkSecurity/urlSafety.d.ts +2 -2
  39. package/dist/core/networkSecurity/urlSafety.js +1 -1
  40. package/dist/core/output.d.ts +1 -1
  41. package/dist/core/output.js +1 -1
  42. package/dist/index.d.ts +4 -4
  43. package/dist/index.js +15 -58
  44. package/dist/renderers/json/json.d.ts +2 -2
  45. package/dist/renderers/json/json.js +3 -4
  46. package/dist/types/index.d.ts +3 -0
  47. package/dist/types/index.js +3 -0
  48. package/dist/types/private/cdn.d.ts +89 -0
  49. package/dist/types/private/cdn.js +1 -0
  50. package/dist/types/private/discordParser.d.ts +18 -0
  51. package/dist/types/private/discordParser.js +1 -0
  52. package/dist/types/private/maps.d.ts +17 -0
  53. package/dist/types/private/maps.js +1 -0
  54. package/dist/types/private/network.d.ts +12 -0
  55. package/dist/types/private/network.js +1 -0
  56. package/dist/types/private/others.d.ts +4 -0
  57. package/dist/types/private/others.js +1 -0
  58. package/dist/types/private/transcript.d.ts +123 -0
  59. package/dist/types/private/transcript.js +1 -0
  60. package/dist/types/public/createAndConvertTranscript.d.ts +32 -0
  61. package/dist/types/public/createAndConvertTranscript.js +1 -0
  62. package/dist/types/public/return.d.ts +37 -0
  63. package/dist/utils/sleep.d.ts +1 -0
  64. package/dist/utils/sleep.js +3 -0
  65. package/package.json +3 -3
  66. package/dist/core/cdnResolver.d.ts +0 -5
  67. package/dist/core/cdnResolver.js +0 -213
  68. package/dist/core/componentToJson.js +0 -145
  69. package/dist/core/fetchMessages.d.ts +0 -19
  70. package/dist/core/resolveImageUrl.d.ts +0 -4
  71. package/dist/core/urlResolver.d.ts +0 -5
  72. package/dist/types/types.d.ts +0 -300
  73. /package/dist/core/{limiter.d.ts → assetResolver/limiter.d.ts} +0 -0
  74. /package/dist/core/{limiter.js → assetResolver/limiter.js} +0 -0
  75. /package/dist/types/{types.js → public/return.js} +0 -0
@@ -0,0 +1,4 @@
1
+ import { TranscriptOptionsBase } from "discord-message-transcript-base/internal";
2
+ import { safeUrlReturn } from "../../../types/private/network.js";
3
+ import { CDNOptions } from "../../../types/private/cdn.js";
4
+ export declare function urlResolver(safeUrlObject: safeUrlReturn, options: TranscriptOptionsBase, cdnOptions: CDNOptions | null, urlCache: Map<string, Promise<string>>): Promise<string>;
@@ -0,0 +1,24 @@
1
+ import { FALLBACK_PIXEL } from "discord-message-transcript-base/internal";
2
+ import { cdnResolver } from "../cdn/cdnResolver.js";
3
+ import { imageToBase64 } from "../base64/imageToBase64.js";
4
+ export async function urlResolver(safeUrlObject, options, cdnOptions, urlCache) {
5
+ if (safeUrlObject.safe == false)
6
+ return "";
7
+ if (safeUrlObject.url == FALLBACK_PIXEL)
8
+ return safeUrlObject.url;
9
+ if (urlCache.has(safeUrlObject.url)) {
10
+ const cache = urlCache.get(safeUrlObject.url);
11
+ if (cache)
12
+ return await cache;
13
+ }
14
+ let returnUrl;
15
+ if (cdnOptions)
16
+ returnUrl = cdnResolver(safeUrlObject, options, cdnOptions);
17
+ else if (options.saveImages)
18
+ returnUrl = imageToBase64(safeUrlObject, options.disableWarnings);
19
+ if (returnUrl) {
20
+ urlCache.set(safeUrlObject.url, returnUrl);
21
+ return await returnUrl;
22
+ }
23
+ return safeUrlObject.url;
24
+ }
@@ -1,4 +1,4 @@
1
1
  import { TopLevelComponent } from "discord.js";
2
- import { JsonTopLevelComponent, JsonComponentInContainer, TranscriptOptionsBase } from "discord-message-transcript-base";
2
+ import { JsonTopLevelComponent, TranscriptOptionsBase, JsonComponentInContainer } from "discord-message-transcript-base/internal";
3
3
  export declare function componentsToJson(components: TopLevelComponent[], options: TranscriptOptionsBase): Promise<JsonTopLevelComponent[]>;
4
4
  export declare function isJsonComponentInContainer(component: JsonTopLevelComponent): component is JsonComponentInContainer;
@@ -0,0 +1,158 @@
1
+ import { ComponentType } from "discord.js";
2
+ import { mapButtonStyle, mapSelectorType, mapSeparatorSpacing } from "../mappers.js";
3
+ import { JsonComponentType, isValidHexColor } from "discord-message-transcript-base/internal";
4
+ export async function componentsToJson(components, options) {
5
+ const filtered = components.filter(c => options.includeV2Components || c.type === ComponentType.ActionRow);
6
+ const processed = await Promise.all(filtered.map(c => convertComponent(c, options)));
7
+ return processed.filter(c => c != null);
8
+ }
9
+ async function convertComponent(component, options) {
10
+ switch (component.type) {
11
+ case ComponentType.ActionRow:
12
+ return convertActionRow(component, options);
13
+ case ComponentType.Container:
14
+ return convertContainer(component, options);
15
+ case ComponentType.File:
16
+ return convertFile(component);
17
+ case ComponentType.MediaGallery:
18
+ return convertMediaGallery(component);
19
+ case ComponentType.Section:
20
+ return convertSection(component);
21
+ case ComponentType.Separator:
22
+ return convertSeparator(component);
23
+ case ComponentType.TextDisplay:
24
+ return convertTextDisplay(component);
25
+ default:
26
+ return null;
27
+ }
28
+ }
29
+ async function convertActionRow(component, options) {
30
+ const rowComponents = await Promise.all(component.components
31
+ .filter(c => (c.type === ComponentType.Button ? options.includeButtons : options.includeComponents))
32
+ .map(c => convertActionRowChild(c)));
33
+ if (rowComponents.length === 0)
34
+ return null;
35
+ return { type: JsonComponentType.ActionRow, components: rowComponents };
36
+ }
37
+ async function convertActionRowChild(component) {
38
+ switch (component.type) {
39
+ case ComponentType.Button: {
40
+ return {
41
+ type: JsonComponentType.Button,
42
+ style: mapButtonStyle(component.style),
43
+ label: component.label,
44
+ emoji: component.emoji?.name ?? null,
45
+ url: component.url,
46
+ disabled: component.disabled,
47
+ };
48
+ }
49
+ case ComponentType.StringSelect: {
50
+ return {
51
+ type: JsonComponentType.StringSelect,
52
+ placeholder: component.placeholder,
53
+ disabled: component.disabled,
54
+ options: component.options.map(option => ({
55
+ label: option.label,
56
+ description: option.description ?? null,
57
+ emoji: option.emoji ? { id: option.emoji.id ?? null, name: option.emoji.name ?? null, animated: option.emoji.animated ?? false } : null,
58
+ })),
59
+ };
60
+ }
61
+ default: {
62
+ return {
63
+ type: mapSelectorType(component.type),
64
+ placeholder: component.placeholder,
65
+ disabled: component.disabled,
66
+ };
67
+ }
68
+ }
69
+ }
70
+ async function convertContainer(component, options) {
71
+ const newOptions = { ...options, includeComponents: true, includeButtons: true };
72
+ const componentsJson = await componentsToJson(component.components, newOptions);
73
+ return {
74
+ type: JsonComponentType.Container,
75
+ components: componentsJson.filter(isJsonComponentInContainer), // Input components that are container-safe must always produce container-safe output.
76
+ hexAccentColor: isValidHexColor(component.hexAccentColor, false),
77
+ spoiler: component.spoiler,
78
+ };
79
+ }
80
+ function convertFile(component) {
81
+ return {
82
+ type: JsonComponentType.File,
83
+ fileName: component.data.name ?? null,
84
+ size: component.data.size ?? 0,
85
+ url: component.file.url,
86
+ spoiler: component.spoiler,
87
+ };
88
+ }
89
+ async function convertMediaGallery(component) {
90
+ const mediaItems = await Promise.all(component.items.map(item => {
91
+ return {
92
+ media: { url: item.media.url },
93
+ spoiler: item.spoiler,
94
+ };
95
+ }));
96
+ return {
97
+ type: JsonComponentType.MediaGallery,
98
+ items: mediaItems,
99
+ };
100
+ }
101
+ function convertSection(component) {
102
+ let accessoryJson = null;
103
+ switch (component.accessory.type) {
104
+ case ComponentType.Button: {
105
+ accessoryJson = {
106
+ type: JsonComponentType.Button,
107
+ style: mapButtonStyle(component.accessory.style),
108
+ label: component.accessory.label,
109
+ emoji: component.accessory.emoji?.name ? component.accessory.emoji.name : null,
110
+ url: component.accessory.url,
111
+ disabled: component.accessory.disabled,
112
+ };
113
+ break;
114
+ }
115
+ case ComponentType.Thumbnail: {
116
+ accessoryJson = {
117
+ type: JsonComponentType.Thumbnail,
118
+ media: {
119
+ url: component.accessory.media.url,
120
+ },
121
+ spoiler: component.accessory.spoiler,
122
+ };
123
+ break;
124
+ }
125
+ default:
126
+ break;
127
+ }
128
+ const sectionComponents = component.components.map(c => ({
129
+ type: JsonComponentType.TextDisplay,
130
+ content: c.content,
131
+ }));
132
+ return {
133
+ type: JsonComponentType.Section,
134
+ accessory: accessoryJson,
135
+ components: sectionComponents,
136
+ };
137
+ }
138
+ function convertSeparator(component) {
139
+ return {
140
+ type: JsonComponentType.Separator,
141
+ spacing: mapSeparatorSpacing(component.spacing),
142
+ divider: component.divider,
143
+ };
144
+ }
145
+ function convertTextDisplay(component) {
146
+ return {
147
+ type: JsonComponentType.TextDisplay,
148
+ content: component.content,
149
+ };
150
+ }
151
+ export function isJsonComponentInContainer(component) {
152
+ return (component.type == JsonComponentType.ActionRow ||
153
+ component.type == JsonComponentType.File ||
154
+ component.type == JsonComponentType.MediaGallery ||
155
+ component.type == JsonComponentType.Section ||
156
+ component.type == JsonComponentType.Separator ||
157
+ component.type == JsonComponentType.TextDisplay);
158
+ }
@@ -0,0 +1,7 @@
1
+ import { JsonMessage } from "discord-message-transcript-base/internal";
2
+ import { FetchMessagesContext } from "../../types/private/discordParser.js";
3
+ export declare function fetchMessages(ctx: FetchMessagesContext): Promise<{
4
+ messages: JsonMessage[];
5
+ end: boolean;
6
+ newLastMessageId: string | undefined;
7
+ }>;
@@ -1,6 +1,6 @@
1
1
  import { EmbedType } from "discord.js";
2
2
  import { componentsToJson } from "./componentToJson.js";
3
- import { isValidHexColor, sanitize } from "discord-message-transcript-base";
3
+ import { isValidHexColor, sanitize } from "discord-message-transcript-base/internal";
4
4
  import { getMentions } from "./getMentions.js";
5
5
  export async function fetchMessages(ctx) {
6
6
  const { channel, options, transcriptState, lastMessageId } = ctx;
@@ -1,3 +1,3 @@
1
1
  import { Message } from "discord.js";
2
- import { MapMentions } from "@/types";
2
+ import { MapMentions } from "../../types/private/maps.js";
3
3
  export declare function getMentions(message: Message, mentions: MapMentions): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import { ChannelType } from "discord.js";
2
- import { isValidHexColor, sanitize } from "discord-message-transcript-base";
2
+ import { isValidHexColor, sanitize } from "discord-message-transcript-base/internal";
3
3
  export async function getMentions(message, mentions) {
4
4
  message.mentions.channels.forEach(channel => {
5
5
  if (!mentions.channels.has(channel.id)) {
@@ -0,0 +1,5 @@
1
+ import { TranscriptOptionsBase } from "discord-message-transcript-base/internal";
2
+ import { TextBasedChannel } from "discord.js";
3
+ import { ReturnDiscordParser } from "../../types/private/discordParser.js";
4
+ import { CDNOptions } from "../../types/private/cdn.js";
5
+ export declare function discordParser(channel: TextBasedChannel, options: TranscriptOptionsBase, cdnOptions: CDNOptions | null): Promise<ReturnDiscordParser>;
@@ -0,0 +1,33 @@
1
+ import { fetchMessages } from "./fetchMessages.js";
2
+ import { Json } from "../../renderers/json/json.js";
3
+ export async function discordParser(channel, options, cdnOptions) {
4
+ const urlCache = new Map();
5
+ const authors = new Map();
6
+ const mentions = {
7
+ channels: new Map(),
8
+ roles: new Map(),
9
+ users: new Map(),
10
+ };
11
+ const fetchMessageParameter = {
12
+ channel: channel,
13
+ options: options,
14
+ transcriptState: {
15
+ authors: authors,
16
+ mentions: mentions,
17
+ },
18
+ lastMessageId: undefined
19
+ };
20
+ const jsonTranscript = channel.isDMBased() ? new Json(null, channel, options, cdnOptions, urlCache) : new Json(channel.guild, channel, options, cdnOptions, urlCache);
21
+ while (true) {
22
+ const { messages, end, newLastMessageId } = await fetchMessages(fetchMessageParameter);
23
+ jsonTranscript.addMessages(messages);
24
+ fetchMessageParameter.lastMessageId = newLastMessageId;
25
+ if (end || (jsonTranscript.getMessages().length >= options.quantity && options.quantity != 0)) {
26
+ break;
27
+ }
28
+ }
29
+ if (options.quantity > 0 && jsonTranscript.getMessages().length > options.quantity) {
30
+ jsonTranscript.sliceMessages(options.quantity);
31
+ }
32
+ return [jsonTranscript, { ...fetchMessageParameter.transcriptState, urlCache }];
33
+ }
@@ -1,6 +1,7 @@
1
1
  import { ButtonStyle, ComponentType, SeparatorSpacingSize } from "discord.js";
2
- import { JsonButtonStyle, JsonComponentType, JsonSeparatorSpacingSize, ReturnTypeBase } from "discord-message-transcript-base";
3
- import { ReturnType } from "@/types";
2
+ import { JsonButtonStyle, JsonComponentType, JsonSeparatorSpacingSize } from "discord-message-transcript-base/internal";
3
+ import { ReturnType } from "../types/public/return.js";
4
+ import { ReturnType as ReturnTypeBase } from "discord-message-transcript-base";
4
5
  export declare function mapButtonStyle(style: ButtonStyle): JsonButtonStyle;
5
6
  export declare function mapSeparatorSpacing(spacing: SeparatorSpacingSize): JsonSeparatorSpacingSize;
6
7
  export declare function mapComponentType(componentType: ComponentType): JsonComponentType;
@@ -1,6 +1,7 @@
1
1
  import { ButtonStyle, ComponentType, SeparatorSpacingSize } from "discord.js";
2
- import { CustomError, JsonButtonStyle, JsonComponentType, JsonSeparatorSpacingSize, ReturnTypeBase } from "discord-message-transcript-base";
3
- import { ReturnType } from "@/types";
2
+ import { CustomError, JsonButtonStyle, JsonComponentType, JsonSeparatorSpacingSize } from "discord-message-transcript-base/internal";
3
+ import { ReturnType } from "../types/public/return.js";
4
+ import { ReturnType as ReturnTypeBase } from "discord-message-transcript-base";
4
5
  export function mapButtonStyle(style) {
5
6
  switch (style) {
6
7
  case ButtonStyle.Primary:
@@ -1,2 +1,2 @@
1
- import { LookupResult } from "@/types";
1
+ import { LookupResult } from "../../types/private/network.js";
2
2
  export declare function resolveAllIps(host: string): Promise<LookupResult[]>;
@@ -1,3 +1,3 @@
1
- import { TranscriptOptionsBase } from "discord-message-transcript-base";
2
- import { safeUrlReturn } from "@/types";
1
+ import { TranscriptOptionsBase } from "discord-message-transcript-base/internal";
2
+ import { safeUrlReturn } from "../../types/private/network.js";
3
3
  export declare function isSafeForHTML(url: string, options: TranscriptOptionsBase): Promise<safeUrlReturn>;
@@ -1,4 +1,4 @@
1
- import { CustomWarn } from "discord-message-transcript-base";
1
+ import { CustomWarn } from "discord-message-transcript-base/internal";
2
2
  import { TRUSTED_DISCORD_HOSTS } from "./constants.js";
3
3
  import { isPrivateIp } from "./ip.js";
4
4
  import { resolveAllIps } from "./dns.js";
@@ -1,4 +1,4 @@
1
1
  import { AttachmentBuilder } from "discord.js";
2
2
  import Stream from 'stream';
3
- import { JsonData, Uploadable } from "discord-message-transcript-base";
3
+ import { JsonData, Uploadable } from "discord-message-transcript-base/internal";
4
4
  export declare function output(json: JsonData): Promise<string | Stream | AttachmentBuilder | Buffer | Uploadable>;
@@ -1,5 +1,5 @@
1
1
  import { Readable } from 'stream';
2
- import { outputBase, CustomError } from "discord-message-transcript-base";
2
+ import { outputBase, CustomError } from "discord-message-transcript-base/internal";
3
3
  export async function output(json) {
4
4
  const stringJSON = JSON.stringify(json);
5
5
  if (json.options.returnFormat == "JSON") {
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { CreateTranscriptOptions, ConvertTranscriptOptions, TranscriptOptions, ReturnType, CDNOptions, MimeType } from "@/types";
2
- export { ReturnFormat, LocalDate, TimeZone } from "discord-message-transcript-base";
3
- export { setBase64Concurrency, setCDNConcurrency } from '@/core/limiter.js';
1
+ export * from "./types/index.js";
2
+ export { setBase64Concurrency, setCDNConcurrency } from './core/assetResolver/index.js';
4
3
  import { TextBasedChannel } from "discord.js";
5
- import { ConvertTranscriptOptions, CreateTranscriptOptions, OutputType, ReturnType } from "@/types";
4
+ import { OutputType, ReturnType } from "./types/public/return.js";
5
+ import { ConvertTranscriptOptions, CreateTranscriptOptions } from "./types/public/createAndConvertTranscript.js";
6
6
  /**
7
7
  * Creates a transcript of a Discord channel's messages.
8
8
  * Depending on the `returnType` option, this function can return an `AttachmentBuilder`,
package/dist/index.js CHANGED
@@ -1,14 +1,13 @@
1
- export { ReturnType } from "@/types";
2
- export { ReturnFormat } from "discord-message-transcript-base";
3
- export { setBase64Concurrency, setCDNConcurrency } from '@/core/limiter.js';
1
+ export * from "./types/index.js";
2
+ export { setBase64Concurrency, setCDNConcurrency } from './core/assetResolver/index.js';
4
3
  import { AttachmentBuilder } from "discord.js";
5
- import { Json } from "@/renderers/json/json.js";
6
- import { fetchMessages } from "@/core/fetchMessages.js";
7
- import { ReturnType } from "@/types";
8
- import { output } from "@/core/output.js";
9
- import { ReturnTypeBase, ReturnFormat, outputBase, CustomError, CustomWarn } from "discord-message-transcript-base";
10
- import { returnTypeMapper } from "@/core/mappers.js";
11
- import { authorUrlResolver, messagesUrlResolver } from "@/core/urlResolver.js";
4
+ import { output } from "./core/output.js";
5
+ import { ReturnFormat, outputBase, CustomError, CustomWarn } from "discord-message-transcript-base/internal";
6
+ import { ReturnType as ReturnTypeBase } from "discord-message-transcript-base";
7
+ import { returnTypeMapper } from "./core/mappers.js";
8
+ import { jsonAssetResolver } from "./core/assetResolver/index.js";
9
+ import { discordParser } from "./core/discordParser/index.js";
10
+ import { ReturnType } from "./types/public/return.js";
12
11
  /**
13
12
  * Creates a transcript of a Discord channel's messages.
14
13
  * Depending on the `returnType` option, this function can return an `AttachmentBuilder`,
@@ -55,60 +54,18 @@ export async function createTranscript(channel, options = {}) {
55
54
  timeZone,
56
55
  watermark
57
56
  };
58
- const urlCache = new Map();
59
- const authors = new Map();
60
- const mentions = {
61
- channels: new Map(),
62
- roles: new Map(),
63
- users: new Map(),
64
- };
65
- const fetchMessageParameter = {
66
- channel: channel,
67
- options: internalOptions,
68
- transcriptState: {
69
- authors: authors,
70
- mentions: mentions,
71
- },
72
- lastMessageId: undefined
73
- };
74
- const jsonTranscript = channel.isDMBased() ? new Json(null, channel, internalOptions, options.cdnOptions ?? null, urlCache) : new Json(channel.guild, channel, internalOptions, options.cdnOptions ?? null, urlCache);
75
- while (true) {
76
- const { messages, end, newLastMessageId } = await fetchMessages(fetchMessageParameter);
77
- jsonTranscript.addMessages(messages);
78
- fetchMessageParameter.lastMessageId = newLastMessageId;
79
- if (end || (jsonTranscript.getMessages().length >= quantity && quantity != 0)) {
80
- break;
81
- }
82
- }
83
- if (quantity > 0 && jsonTranscript.getMessages().length > quantity) {
84
- jsonTranscript.sliceMessages(quantity);
85
- }
86
- if (options.cdnOptions) {
87
- options.cdnOptions = {
57
+ const cdnOptions = options.cdnOptions ?
58
+ {
88
59
  includeAudio: true,
89
60
  includeImage: true,
90
61
  includeVideo: true,
91
62
  includeOthers: true,
92
63
  ...options.cdnOptions
93
- };
94
- }
95
- await Promise.all([
96
- (async () => {
97
- jsonTranscript.setAuthors(await authorUrlResolver(authors, internalOptions, options.cdnOptions ?? null, urlCache));
98
- authors.clear();
99
- })(),
100
- (() => {
101
- jsonTranscript.setMentions({ channels: Array.from(mentions.channels.values()), roles: Array.from(mentions.roles.values()), users: Array.from(mentions.users.values()) });
102
- mentions.channels.clear();
103
- mentions.roles.clear();
104
- mentions.users.clear();
105
- })(),
106
- (async () => {
107
- jsonTranscript.setMessages(await messagesUrlResolver(jsonTranscript.getMessages(), internalOptions, options.cdnOptions ?? null, urlCache));
108
- })()
109
- ]);
64
+ } : null;
65
+ const [jsonTranscript, maps] = await discordParser(channel, internalOptions, cdnOptions);
66
+ await jsonAssetResolver(jsonTranscript, maps, internalOptions, cdnOptions);
110
67
  const outputJson = await jsonTranscript.toJson();
111
- urlCache.clear();
68
+ maps.urlCache.clear();
112
69
  const result = await output(outputJson);
113
70
  if (!options.returnType || options.returnType == "attachment") {
114
71
  if (!(result instanceof Buffer)) {
@@ -1,6 +1,6 @@
1
1
  import { Guild, TextBasedChannel } from "discord.js";
2
- import { ArrayMentions, JsonAuthor, JsonMessage, TranscriptOptionsBase, JsonData } from "discord-message-transcript-base";
3
- import { CDNOptions } from "@/types";
2
+ import { ArrayMentions, JsonAuthor, JsonMessage, TranscriptOptionsBase, JsonData } from "discord-message-transcript-base/internal";
3
+ import { CDNOptions } from "../../types/private/cdn.js";
4
4
  export declare class Json {
5
5
  private guild;
6
6
  private channel;
@@ -1,6 +1,5 @@
1
1
  import { BaseGuildTextChannel, DMChannel } from "discord.js";
2
- import { urlResolver } from "@/core/urlResolver.js";
3
- import { resolveImageURL } from "@/core/resolveImageUrl.js";
2
+ import { imageUrlResolver, urlResolver } from "../../core/assetResolver/index.js";
4
3
  export class Json {
5
4
  guild;
6
5
  channel;
@@ -44,9 +43,9 @@ export class Json {
44
43
  async toJson() {
45
44
  const channel = await this.channel.fetch();
46
45
  const channelImg = channel instanceof DMChannel ? channel.recipient?.displayAvatarURL() ?? "cdn.discordapp.com/embed/avatars/4.png" : channel.isDMBased() ? channel.iconURL() ?? (await channel.fetchOwner()).displayAvatarURL() : null;
47
- const safeChannelImg = await resolveImageURL(channelImg, this.options, true);
46
+ const safeChannelImg = await imageUrlResolver(channelImg, this.options, true);
48
47
  const guild = !channel.isDMBased() ? this.guild : null;
49
- const guildIcon = guild ? await resolveImageURL(guild.iconURL(), this.options, true) : null;
48
+ const guildIcon = guild ? await imageUrlResolver(guild.iconURL(), this.options, true) : null;
50
49
  const guildJson = !guild ? null : {
51
50
  name: guild.name,
52
51
  id: guild.id,
@@ -0,0 +1,3 @@
1
+ export { ReturnFormat } from "discord-message-transcript-base/internal";
2
+ export * from "./public/return.js";
3
+ export * from "./public/createAndConvertTranscript.js";
@@ -0,0 +1,3 @@
1
+ export { ReturnFormat } from "discord-message-transcript-base/internal";
2
+ export * from "./public/return.js";
3
+ export * from "./public/createAndConvertTranscript.js";
@@ -0,0 +1,89 @@
1
+ import { MimeType } from "./others.js";
2
+ /**
3
+ * Base options applicable to all CDN providers.
4
+ */
5
+ export type CDNBase = Partial<{
6
+ /**
7
+ * Whether to upload audio files to the CDN.
8
+ * @default true
9
+ */
10
+ includeAudio: boolean;
11
+ /**
12
+ * Whether to upload image files (excluding GIFs) to the CDN.
13
+ * @default true
14
+ */
15
+ includeImage: boolean;
16
+ /**
17
+ * Whether to upload video files (and GIFs) to the CDN.
18
+ * @default true
19
+ */
20
+ includeVideo: boolean;
21
+ /**
22
+ * Whether to upload any other file types to the CDN.
23
+ * @default true
24
+ */
25
+ includeOthers: boolean;
26
+ }>;
27
+ /**
28
+ * A discriminated union of all possible CDN configurations.
29
+ */
30
+ export type CDNOptions = (CDNBase & CDNOptionsCustom<any>) | (CDNBase & CDNOptionsCloudinary) | (CDNBase & CDNOptionsUploadcare);
31
+ /**
32
+ * Configuration for using a custom, user-provided CDN resolver function.
33
+ */
34
+ export type CDNOptionsCustom<T = unknown> = {
35
+ /** Specifies the use of a custom CDN resolver. */
36
+ provider: "CUSTOM";
37
+ /**
38
+ * An async function that takes a URL and returns a new URL.
39
+ * @param url The original Discord asset URL.
40
+ * @param contentType The MIME type of the asset.
41
+ * @param customData Any additional data you want to pass to your resolver.
42
+ * @returns The new URL of the asset on your CDN.
43
+ */
44
+ resolver: (url: string, contentType: MimeType | null, customData: T) => Promise<string> | string;
45
+ /**
46
+ * Any custom data you wish to make available within your resolver function.
47
+ */
48
+ customData: T;
49
+ };
50
+ /**
51
+ * Configuration for using Cloudinary as the CDN.
52
+ */
53
+ export type CDNOptionsCloudinary = {
54
+ /**
55
+ * Specifies the use of the built-in Cloudinary provider.
56
+ */
57
+ provider: "CLOUDINARY";
58
+ /**
59
+ * Your Cloudinary cloud name.
60
+ */
61
+ cloudName: string;
62
+ /**
63
+ * Your Cloudinary API key.
64
+ * */
65
+ apiKey: string;
66
+ /**
67
+ * Your Cloudinary API secret.
68
+ */
69
+ apiSecret: string;
70
+ };
71
+ /**
72
+ * Configuration for using Uploadcare as the CDN.
73
+ */
74
+ export type CDNOptionsUploadcare = {
75
+ /**
76
+ * Specifies the use of the built-in Uploadcare provider.
77
+ */
78
+ provider: "UPLOADCARE";
79
+ /**
80
+ * Your Uploadcare public key.
81
+ */
82
+ publicKey: string;
83
+ /**
84
+ * Your Uploadcare CDN domain.
85
+ * Example: "aaa111aaa1.ucarecd.net".
86
+ * DO NOT INCLUDE https://
87
+ */
88
+ cdnDomain: string;
89
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { Json } from "../../renderers/json/json.js";
2
+ import { MapMentions, Maps } from "./maps.js";
3
+ import { TextBasedChannel } from "discord.js";
4
+ import { JsonAuthor, TranscriptOptionsBase } from "discord-message-transcript-base/internal";
5
+ export type ReturnDiscordParser = [
6
+ json: Json,
7
+ maps: Maps
8
+ ];
9
+ export type FetchMessagesContext = {
10
+ channel: TextBasedChannel;
11
+ options: TranscriptOptionsBase;
12
+ transcriptState: TranscriptState;
13
+ lastMessageId: string | undefined;
14
+ };
15
+ export type TranscriptState = {
16
+ authors: Map<string, JsonAuthor>;
17
+ mentions: MapMentions;
18
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import { JsonAuthor, JsonMessageMentionsChannels, JsonMessageMentionsRoles, JsonMessageMentionsUsers } from "discord-message-transcript-base/internal";
2
+ export type MapAuthors = Map<string, JsonAuthor>;
3
+ export type MapCache = Map<string, Promise<string>>;
4
+ /**
5
+ * Defines the structure for storing discovered mentions (users, roles, channels) during transcript creation.
6
+ * Uses Maps for efficient lookups.
7
+ */
8
+ export interface MapMentions {
9
+ channels: Map<string, JsonMessageMentionsChannels>;
10
+ roles: Map<string, JsonMessageMentionsRoles>;
11
+ users: Map<string, JsonMessageMentionsUsers>;
12
+ }
13
+ export type Maps = {
14
+ authors: MapAuthors;
15
+ mentions: MapMentions;
16
+ urlCache: MapCache;
17
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Result from dns.lookup
3
+ */
4
+ export type LookupResult = {
5
+ address: string;
6
+ family: 4 | 6;
7
+ };
8
+ export interface safeUrlReturn {
9
+ safe: boolean;
10
+ safeIps: string[];
11
+ url: string;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * A string template type for representing a MIME type (e.g., 'image/png', 'application/json').
3
+ */
4
+ export type MimeType = `${string}/${string}`;
@@ -0,0 +1 @@
1
+ export {};