buncord-transcript 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.
@@ -0,0 +1,192 @@
1
+
2
+ import { createTranscript, type Message, type ChannelInfo } from '../src/index';
3
+
4
+ const channel: ChannelInfo = {
5
+ id: '123456789',
6
+ name: 'ticket-001',
7
+ topic: 'Support ticket for User #123',
8
+ guildName: 'Support Server',
9
+ guildIconUrl: 'https://cdn.discordapp.com/icons/887462826343510046/c9066666879e69c4fae958155bb3a8f9.png'
10
+ };
11
+
12
+ const messages: Message[] = [
13
+ {
14
+ id: '1',
15
+ content: 'Hello, I need help with my account.',
16
+ author: {
17
+ id: 'user1',
18
+ username: 'Customer',
19
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/0.png',
20
+ bot: false
21
+ },
22
+ timestamp: new Date(Date.now() - 1000000).toISOString(),
23
+ attachments: [],
24
+ embeds: [],
25
+ reactions: []
26
+ },
27
+ {
28
+ id: '2',
29
+ content: 'Hi! **Support Bot** here. What seems to be the issue?',
30
+ author: {
31
+ id: 'bot1',
32
+ username: 'Support Bot',
33
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/1.png',
34
+ bot: true
35
+ },
36
+ timestamp: new Date(Date.now() - 900000).toISOString(),
37
+ attachments: [],
38
+ embeds: [],
39
+ reactions: []
40
+ },
41
+ {
42
+ id: '3',
43
+ content: 'I cannot login. Here is a screenshot:',
44
+ author: {
45
+ id: 'user1',
46
+ username: 'Customer',
47
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/0.png',
48
+ bot: false
49
+ },
50
+ timestamp: new Date(Date.now() - 800000).toISOString(),
51
+ attachments: [
52
+ {
53
+ id: 'att1',
54
+ name: 'screenshot.png',
55
+ url: 'https://via.placeholder.com/350x150',
56
+ contentType: 'image/png'
57
+ }
58
+ ],
59
+ embeds: [],
60
+ reactions: []
61
+ },
62
+ {
63
+ id: '4',
64
+ content: '',
65
+ author: {
66
+ id: 'bot1',
67
+ username: 'Support Bot',
68
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/1.png',
69
+ bot: true
70
+ },
71
+ timestamp: new Date(Date.now() - 600000).toISOString(),
72
+ attachments: [],
73
+ embeds: [
74
+ {
75
+ title: 'Login Troubleshooting',
76
+ description: 'Please try the following steps:\n1. Reset password\n2. Clear cache',
77
+ color: 0x5865F2,
78
+ fields: [
79
+ { name: 'Step 1', value: 'Click [here](https://example.com) to reset.', inline: true },
80
+ { name: 'Step 2', value: 'Settings > Privacy > Clear', inline: true }
81
+ ],
82
+ footer: {
83
+ text: 'Automated Response'
84
+ }
85
+ }
86
+ ],
87
+ reactions: []
88
+ },
89
+ {
90
+ id: '5',
91
+ content: 'This message uses the new **Container** component:',
92
+ author: {
93
+ id: 'bot1',
94
+ username: 'Support Bot',
95
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/1.png',
96
+ bot: true
97
+ },
98
+ timestamp: new Date().toISOString(),
99
+ attachments: [],
100
+ embeds: [],
101
+ containers: [
102
+ {
103
+ content: "**Container Title**\nThis is content inside a container.\nIt has a different style than embeds."
104
+ }
105
+ ],
106
+ reactions: []
107
+ },
108
+ {
109
+ id: '6',
110
+ content: 'This message has interactive **components**:',
111
+ author: {
112
+ id: 'bot1',
113
+ username: 'Support Bot',
114
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/1.png',
115
+ bot: true
116
+ },
117
+ timestamp: new Date().toISOString(),
118
+ attachments: [],
119
+ embeds: [],
120
+ components: [
121
+ {
122
+ type: 1,
123
+ components: [
124
+ { type: 2, style: 1, label: 'Claim Ticket', customId: 'claim', emoji: { name: 'User', id: '123456789' } },
125
+ { type: 2, style: 4, label: 'Close Ticket', customId: 'close', emoji: { name: '🔒' } }
126
+ ]
127
+ },
128
+ {
129
+ type: 1,
130
+ components: [
131
+ {
132
+ type: 3,
133
+ customId: 'category',
134
+ placeholder: 'Select a category...',
135
+ options: [
136
+ { label: 'Support', value: 'support' },
137
+ { label: 'Billing', value: 'billing' }
138
+ ]
139
+ }
140
+ ]
141
+ }
142
+ ],
143
+ mediaGalleries: [
144
+ {
145
+ items: [
146
+ { media: { url: 'https://cdn.discordapp.com/embed/avatars/0.png' }, description: 'Gallery Image 1' },
147
+ { media: { url: 'https://cdn.discordapp.com/embed/avatars/1.png' }, description: 'Gallery Image 2' },
148
+ { media: { url: 'https://cdn.discordapp.com/embed/avatars/2.png' }, description: 'Gallery Image 3' }
149
+ ]
150
+ }
151
+ ],
152
+ separators: [
153
+ { divider: true, spacing: 3 }
154
+ ],
155
+ reactions: []
156
+ },
157
+ {
158
+ id: '7',
159
+ content: 'This message uses V2 Components (Type 17 Container):',
160
+ author: {
161
+ id: 'bot1',
162
+ username: 'Support Bot',
163
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/1.png',
164
+ bot: true
165
+ },
166
+ timestamp: new Date().toISOString(),
167
+ attachments: [],
168
+ embeds: [],
169
+ components: [
170
+ {
171
+ type: 17,
172
+ components: [
173
+ { type: 10, content: '**Text Display** inside container.' },
174
+ { type: 14, divider: true, spacing: 2 },
175
+ {
176
+ type: 1,
177
+ components: [
178
+ { type: 2, style: 1, label: 'Button Inside', customId: 'btn_in' }
179
+ ]
180
+ }
181
+ ]
182
+ }
183
+ ] as any, // Cast to avoid strict type checking in test file if types aren't fully updated in index export yet
184
+ reactions: []
185
+ }
186
+ ];
187
+
188
+ // Run
189
+ const htmlBuffer = await createTranscript(messages, channel, { returnType: 'buffer' });
190
+ const fs = require('fs');
191
+ fs.writeFileSync('test_transcript.html', htmlBuffer);
192
+ console.log('Transcript generated at test_transcript.html');
@@ -0,0 +1,78 @@
1
+
2
+ import { createTranscript, type Message, type ChannelInfo } from '../src/index';
3
+ import fs from 'fs';
4
+
5
+ const channel: ChannelInfo = {
6
+ id: '123456789',
7
+ name: 'mention-test',
8
+ topic: 'Testing mentions and timestamps',
9
+ };
10
+
11
+ const messages: Message[] = [
12
+ {
13
+ id: '1',
14
+ content: 'Hi <@22222>, I am <@11111>!',
15
+ author: {
16
+ id: '11111',
17
+ username: 'Customer',
18
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/0.png',
19
+ bot: false
20
+ },
21
+ timestamp: new Date().toISOString(),
22
+ attachments: [],
23
+ embeds: [],
24
+ reactions: []
25
+ },
26
+ {
27
+ id: '2',
28
+ content: 'Hello <@11111>! This ticket was claimed at <t:1737800000:R>. Mentioning unknown: <@99999>',
29
+ author: {
30
+ id: '22222',
31
+ username: 'Support Bot',
32
+ avatarURL: 'https://cdn.discordapp.com/embed/avatars/1.png',
33
+ bot: true
34
+ },
35
+ timestamp: new Date().toISOString(),
36
+ attachments: [],
37
+ embeds: [
38
+ {
39
+ description: 'Embed mentioning <@11111> and timestamp <t:1737801000:R>',
40
+ fields: [
41
+ { name: 'User', value: '<@11111>', inline: true }
42
+ ]
43
+ }
44
+ ],
45
+ reactions: []
46
+ }
47
+ ];
48
+
49
+ // Run
50
+ const html = await createTranscript(messages, channel, { returnType: 'string' }) as string;
51
+ fs.writeFileSync('test_mentions.html', html);
52
+ console.log('Transcript generated at test_mentions.html');
53
+
54
+ // Simple verification in console
55
+ if (html.includes('@Customer')) {
56
+ console.log('✅ Mention @Customer found');
57
+ } else {
58
+ console.log('❌ Mention @Customer NOT found');
59
+ }
60
+
61
+ if (html.includes('@Support Bot')) {
62
+ console.log('✅ Mention @Support Bot found');
63
+ } else {
64
+ console.log('❌ Mention @Support Bot NOT found');
65
+ }
66
+
67
+ if (html.includes('relative time')) {
68
+ console.log('❌ "relative time" found (should be formatted)');
69
+ } else {
70
+ console.log('✅ "relative time" NOT found');
71
+ }
72
+
73
+ if (html.includes('@User')) {
74
+ // Falls back to @User if id not in map?
75
+ // In my code: const username = userMap?.get(id) || 'User';
76
+ // So <@99999> becomes @User
77
+ console.log('✅ Mention @User (fallback) found');
78
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": true,
22
+ "noImplicitOverride": true,
23
+
24
+ // Some stricter flags (disabled by default)
25
+ "noUnusedLocals": false,
26
+ "noUnusedParameters": false,
27
+ "noPropertyAccessFromIndexSignature": false
28
+ }
29
+ }