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.
- package/dist/core/{imageToBase64.d.ts → assetResolver/base64/imageToBase64.d.ts} +1 -1
- package/dist/core/{imageToBase64.js → assetResolver/base64/imageToBase64.js} +5 -4
- package/dist/core/assetResolver/cdn/cdnCustomError.d.ts +16 -0
- package/dist/core/assetResolver/cdn/cdnCustomError.js +28 -0
- package/dist/core/assetResolver/cdn/cdnResolver.d.ts +4 -0
- package/dist/core/assetResolver/cdn/cdnResolver.js +90 -0
- package/dist/core/assetResolver/cdn/cloudinaryCdnResolver.d.ts +1 -0
- package/dist/core/assetResolver/cdn/cloudinaryCdnResolver.js +120 -0
- package/dist/core/assetResolver/cdn/sanitizeFileName.d.ts +1 -0
- package/dist/core/assetResolver/cdn/sanitizeFileName.js +17 -0
- package/dist/core/assetResolver/cdn/uploadCareCdnResolver.d.ts +1 -0
- package/dist/core/assetResolver/cdn/uploadCareCdnResolver.js +137 -0
- package/dist/core/assetResolver/cdn/validateCdnUrl.d.ts +1 -0
- package/dist/core/assetResolver/cdn/validateCdnUrl.js +8 -0
- package/dist/core/assetResolver/contants.d.ts +1 -0
- package/dist/core/assetResolver/contants.js +1 -0
- package/dist/core/assetResolver/index.d.ts +8 -0
- package/dist/core/assetResolver/index.js +22 -0
- package/dist/core/assetResolver/url/authorUrlResolver.d.ts +3 -0
- package/dist/core/assetResolver/url/authorUrlResolver.js +10 -0
- package/dist/core/assetResolver/url/imageUrlResolver.d.ts +4 -0
- package/dist/core/{resolveImageUrl.js → assetResolver/url/imageUrlResolver.js} +3 -3
- package/dist/core/assetResolver/url/messageUrlResolver.d.ts +3 -0
- package/dist/core/{urlResolver.js → assetResolver/url/messageUrlResolver.js} +13 -44
- package/dist/core/assetResolver/url/urlResolver.d.ts +4 -0
- package/dist/core/assetResolver/url/urlResolver.js +24 -0
- package/dist/core/{componentToJson.d.ts → discordParser/componentToJson.d.ts} +1 -1
- package/dist/core/discordParser/componentToJson.js +158 -0
- package/dist/core/discordParser/fetchMessages.d.ts +7 -0
- package/dist/core/{fetchMessages.js → discordParser/fetchMessages.js} +1 -1
- package/dist/core/{getMentions.d.ts → discordParser/getMentions.d.ts} +1 -1
- package/dist/core/{getMentions.js → discordParser/getMentions.js} +1 -1
- package/dist/core/discordParser/index.d.ts +5 -0
- package/dist/core/discordParser/index.js +33 -0
- package/dist/core/mappers.d.ts +3 -2
- package/dist/core/mappers.js +3 -2
- package/dist/core/networkSecurity/dns.d.ts +1 -1
- package/dist/core/networkSecurity/urlSafety.d.ts +2 -2
- package/dist/core/networkSecurity/urlSafety.js +1 -1
- package/dist/core/output.d.ts +1 -1
- package/dist/core/output.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +15 -58
- package/dist/renderers/json/json.d.ts +2 -2
- package/dist/renderers/json/json.js +3 -4
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +3 -0
- package/dist/types/private/cdn.d.ts +89 -0
- package/dist/types/private/cdn.js +1 -0
- package/dist/types/private/discordParser.d.ts +18 -0
- package/dist/types/private/discordParser.js +1 -0
- package/dist/types/private/maps.d.ts +17 -0
- package/dist/types/private/maps.js +1 -0
- package/dist/types/private/network.d.ts +12 -0
- package/dist/types/private/network.js +1 -0
- package/dist/types/private/others.d.ts +4 -0
- package/dist/types/private/others.js +1 -0
- package/dist/types/private/transcript.d.ts +123 -0
- package/dist/types/private/transcript.js +1 -0
- package/dist/types/public/createAndConvertTranscript.d.ts +32 -0
- package/dist/types/public/createAndConvertTranscript.js +1 -0
- package/dist/types/public/return.d.ts +37 -0
- package/dist/utils/sleep.d.ts +1 -0
- package/dist/utils/sleep.js +3 -0
- package/package.json +3 -3
- package/dist/core/cdnResolver.d.ts +0 -5
- package/dist/core/cdnResolver.js +0 -213
- package/dist/core/componentToJson.js +0 -145
- package/dist/core/fetchMessages.d.ts +0 -19
- package/dist/core/resolveImageUrl.d.ts +0 -4
- package/dist/core/urlResolver.d.ts +0 -5
- package/dist/types/types.d.ts +0 -300
- /package/dist/core/{limiter.d.ts → assetResolver/limiter.d.ts} +0 -0
- /package/dist/core/{limiter.js → assetResolver/limiter.js} +0 -0
- /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,
|
|
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,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
|
+
}
|
package/dist/core/mappers.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ButtonStyle, ComponentType, SeparatorSpacingSize } from "discord.js";
|
|
2
|
-
import { JsonButtonStyle, JsonComponentType, JsonSeparatorSpacingSize
|
|
3
|
-
import { ReturnType } from "
|
|
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;
|
package/dist/core/mappers.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ButtonStyle, ComponentType, SeparatorSpacingSize } from "discord.js";
|
|
2
|
-
import { CustomError, JsonButtonStyle, JsonComponentType, JsonSeparatorSpacingSize
|
|
3
|
-
import { ReturnType } from "
|
|
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 "
|
|
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 "
|
|
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";
|
package/dist/core/output.d.ts
CHANGED
|
@@ -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>;
|
package/dist/core/output.js
CHANGED
|
@@ -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
|
|
2
|
-
export {
|
|
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 {
|
|
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
|
|
2
|
-
export {
|
|
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 {
|
|
6
|
-
import {
|
|
7
|
-
import { ReturnType } from "
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
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
|
|
59
|
-
|
|
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
|
|
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 "
|
|
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 "
|
|
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
|
|
46
|
+
const safeChannelImg = await imageUrlResolver(channelImg, this.options, true);
|
|
48
47
|
const guild = !channel.isDMBased() ? this.guild : null;
|
|
49
|
-
const guildIcon = guild ? await
|
|
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,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 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|