@mks2508/telegram-message-builder 0.2.0 → 0.3.1

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 (57) hide show
  1. package/dist/builder/builder.d.ts +87 -0
  2. package/dist/builder/index.d.ts +2 -0
  3. package/dist/builder/media.d.ts +351 -0
  4. package/dist/formatters/index.d.ts +86 -0
  5. package/dist/formatters/markdown.d.ts +178 -0
  6. package/dist/formatters/markdownv2.d.ts +183 -0
  7. package/dist/index.cjs +1057 -12
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +11 -0
  10. package/dist/index.js +1022 -13
  11. package/dist/index.js.map +1 -1
  12. package/dist/keyboard/index.d.ts +113 -0
  13. package/dist/types/constants.d.ts +13 -0
  14. package/dist/types/core.types.d.ts +74 -0
  15. package/dist/types/index.d.ts +4 -0
  16. package/dist/types/keyboard-types.index.d.ts +1 -0
  17. package/dist/types/keyboard.types.d.ts +95 -0
  18. package/dist/types/main.types.d.ts +22 -0
  19. package/dist/types/media.types.d.ts +157 -0
  20. package/package.json +1 -1
  21. package/src/builder/builder.d.ts +55 -0
  22. package/src/builder/builder.d.ts.map +1 -1
  23. package/src/builder/builder.ts +145 -10
  24. package/src/builder/index.d.ts +2 -1
  25. package/src/builder/index.d.ts.map +1 -1
  26. package/src/builder/index.ts +2 -1
  27. package/src/builder/media.d.ts +352 -0
  28. package/src/builder/media.d.ts.map +1 -0
  29. package/src/builder/media.test.ts +664 -0
  30. package/src/builder/media.ts +484 -0
  31. package/src/builder.test.ts +465 -0
  32. package/src/escaping.test.ts +2 -2
  33. package/src/formatters/index.d.ts +47 -0
  34. package/src/formatters/index.d.ts.map +1 -1
  35. package/src/formatters/index.ts +92 -1
  36. package/src/formatters/markdown.d.ts +179 -0
  37. package/src/formatters/markdown.d.ts.map +1 -0
  38. package/src/formatters/markdown.test.ts +417 -0
  39. package/src/formatters/markdown.ts +220 -0
  40. package/src/formatters/markdownv2.d.ts +184 -0
  41. package/src/formatters/markdownv2.d.ts.map +1 -0
  42. package/src/formatters/markdownv2.ts +235 -0
  43. package/src/formatters.test.ts +17 -7
  44. package/src/index.d.ts +2 -0
  45. package/src/index.d.ts.map +1 -1
  46. package/src/index.ts +12 -0
  47. package/src/integration.test.ts +523 -0
  48. package/src/media-integration.test.ts +384 -0
  49. package/src/types/index.d.ts +1 -0
  50. package/src/types/index.d.ts.map +1 -1
  51. package/src/types/index.ts +1 -0
  52. package/src/types/media.types.d.ts +158 -0
  53. package/src/types/media.types.d.ts.map +1 -0
  54. package/src/types/media.types.ts +178 -0
  55. package/src/types.test.ts +539 -0
  56. package/src/utils/index.d.ts +1 -1
  57. package/src/utils/index.ts +0 -5
package/dist/index.cjs CHANGED
@@ -14,6 +14,435 @@ const DEFAULT_PREFIX = "Hello";
14
14
  */
15
15
  const DEFAULT_SUFFIX = "!";
16
16
 
17
+ //#endregion
18
+ //#region src/formatters/markdown.ts
19
+ /**
20
+ * @fileoverview Markdown (Legacy) Formatters
21
+ * @description Text formatting functions for Telegram's legacy Markdown parse mode
22
+ * @module telegram-message-builder/formatters
23
+ *
24
+ * @see {@link https://core.telegram.org/bots/api#formatting-options | Telegram Bot API - Formatting Options}
25
+ */
26
+ /**
27
+ * Formats text as bold in Markdown
28
+ *
29
+ * @param text - The text to format
30
+ * @returns Bold formatted text
31
+ * @example
32
+ * ```typescript
33
+ * boldMD("Hello") // "*Hello*"
34
+ * ```
35
+ */
36
+ function boldMD(text) {
37
+ return `*${text}*`;
38
+ }
39
+ /**
40
+ * Formats text as italic in Markdown
41
+ *
42
+ * @param text - The text to format
43
+ * @returns Italic formatted text
44
+ * @example
45
+ * ```typescript
46
+ * italicMD("Hello") // "_Hello_"
47
+ * ```
48
+ */
49
+ function italicMD(text) {
50
+ return `_${text}_`;
51
+ }
52
+ /**
53
+ * Formats text as monospace code in Markdown
54
+ *
55
+ * @param text - The text to format
56
+ * @returns Code formatted text
57
+ * @example
58
+ * ```typescript
59
+ * codeMD("const x = 1") // "`const x = 1`"
60
+ * ```
61
+ */
62
+ function codeMD(text) {
63
+ return `\`${text}\``;
64
+ }
65
+ /**
66
+ * Formats text as a code block in Markdown
67
+ *
68
+ * @param text - The code to format
69
+ * @param language - Optional programming language for syntax highlighting
70
+ * @returns Code block formatted text
71
+ * @example
72
+ * ```typescript
73
+ * codeBlockMD("console.log('Hello')") // "```console.log('Hello')```"
74
+ * codeBlockMD("const x = 1", "javascript") // "```javascript\nconst x = 1\n```"
75
+ * ```
76
+ */
77
+ function codeBlockMD(text, language) {
78
+ return language ? `${language}\n${text}\n` : `${text}\n`;
79
+ }
80
+ /**
81
+ * Creates a link in Markdown format
82
+ *
83
+ * @param text - The link text
84
+ * @param url - The URL to link to
85
+ * @returns Link formatted text
86
+ * @example
87
+ * ```typescript
88
+ * linkMD("Google", "https://google.com") // "[Google](https://google.com)"
89
+ * ```
90
+ */
91
+ function linkMD(text, url$1) {
92
+ return `[${text}](${url$1})`;
93
+ }
94
+ /**
95
+ * Creates a user mention link in Markdown format
96
+ *
97
+ * @param userId - The user's ID
98
+ * @param name - Optional display name
99
+ * @returns Mention formatted text
100
+ * @example
101
+ * ```typescript
102
+ * mentionMD(123456) // "tg://user?id=123456"
103
+ * mentionMD(123456, "John") // "tg://user?id=123456"
104
+ * ```
105
+ */
106
+ function mentionMD(userId, _name) {
107
+ return `tg://user?id=${userId}`;
108
+ }
109
+ /**
110
+ * Creates a hashtag link in Markdown format
111
+ *
112
+ * @param tag - The hashtag text (without #)
113
+ * @returns Hashtag formatted text
114
+ * @example
115
+ * ```typescript
116
+ * hashtagMD("test") // "#test"
117
+ * ```
118
+ */
119
+ function hashtagMD(tag) {
120
+ return `#${tag}`;
121
+ }
122
+ /**
123
+ * Formats text as underline in Markdown (limited support)
124
+ *
125
+ * Note: Standard Markdown doesn't support underline. This uses HTML which
126
+ * may not work in all Telegram clients.
127
+ *
128
+ * @param text - The text to format
129
+ * @returns Underline formatted text (HTML fallback)
130
+ * @example
131
+ * ```typescript
132
+ * underlineMD("Hello") // "<u>Hello</u>"
133
+ * ```
134
+ */
135
+ function underlineMD(text) {
136
+ return `<u>${text}</u>`;
137
+ }
138
+ /**
139
+ * Formats text as strikethrough in Markdown (limited support)
140
+ *
141
+ * Note: Standard Markdown doesn't support strikethrough. This uses HTML which
142
+ * may not work in all Telegram clients.
143
+ *
144
+ * @param text - The text to format
145
+ * @returns Strikethrough formatted text (HTML fallback)
146
+ * @example
147
+ * ```typescript
148
+ * strikethroughMD("Hello") // "<s>Hello</s>"
149
+ * ```
150
+ */
151
+ function strikethroughMD(text) {
152
+ return `<s>${text}</s>`;
153
+ }
154
+ /**
155
+ * Formats text as spoiler in Markdown (limited support)
156
+ *
157
+ * Note: Standard Markdown doesn't support spoiler. This uses HTML which
158
+ * may not work in all Telegram clients.
159
+ *
160
+ * @param text - The text to format
161
+ * @returns Spoiler formatted text (HTML fallback)
162
+ * @example
163
+ * ```typescript
164
+ * spoilerMD("Secret") // "<tg-spoiler>Secret</tg-spoiler>"
165
+ * ```
166
+ */
167
+ function spoilerMD(text) {
168
+ return `<tg-spoiler>${text}</tg-spoiler>`;
169
+ }
170
+ /**
171
+ * Creates an email link in Markdown format
172
+ *
173
+ * @param email - The email address
174
+ * @returns Email link formatted text
175
+ * @example
176
+ * ```typescript
177
+ * emailMD("test@example.com") // "[test@example.com](mailto:test@example.com)"
178
+ * ```
179
+ */
180
+ function emailMD(email$1) {
181
+ return `[${email$1}](mailto:${email$1})`;
182
+ }
183
+ /**
184
+ * Creates a URL link in Markdown format
185
+ *
186
+ * @param url - The URL
187
+ * @returns URL link formatted text
188
+ * @example
189
+ * ```typescript
190
+ * urlMD("https://example.com") // "[https://example.com](https://example.com)"
191
+ * ```
192
+ */
193
+ function urlMD(url$1) {
194
+ return `[${url$1}](${url$1})`;
195
+ }
196
+ /**
197
+ * Creates a custom emoji in Markdown format (limited support)
198
+ *
199
+ * Note: Standard Markdown doesn't support custom emoji. This uses HTML which
200
+ * may not work in all Telegram clients.
201
+ *
202
+ * @param emojiId - The custom emoji ID
203
+ * @returns Custom emoji formatted text (HTML fallback)
204
+ * @example
205
+ * ```typescript
206
+ * customEmojiMD("5368324170672642286") // "<tg-emoji emoji-id=\"5368324170672642286\">👻</tg-emoji>"
207
+ * ```
208
+ */
209
+ function customEmojiMD(emojiId) {
210
+ return `<tg-emoji emoji-id="${emojiId}">👻</tg-emoji>`;
211
+ }
212
+ /**
213
+ * Raw Markdown string - bypasses any automatic formatting
214
+ *
215
+ * @param markdown - Pre-formatted Markdown string
216
+ * @returns The Markdown string unchanged
217
+ * @example
218
+ * ```typescript
219
+ * rawMD("*Hello*") // "*Hello*"
220
+ * ```
221
+ */
222
+ function rawMD(markdown) {
223
+ return markdown;
224
+ }
225
+
226
+ //#endregion
227
+ //#region src/formatters/markdownv2.ts
228
+ /**
229
+ * @fileoverview MarkdownV2 Formatters
230
+ * @description Text formatting functions for Telegram's MarkdownV2 parse mode
231
+ * @module telegram-message-builder/formatters
232
+ *
233
+ * @see {@link https://core.telegram.org/bots/api#markdownv2-style | Telegram Bot API - MarkdownV2 Style}
234
+ */
235
+ /**
236
+ * Formats text as bold in MarkdownV2
237
+ *
238
+ * @param text - The text to format
239
+ * @returns Bold formatted text
240
+ * @example
241
+ * ```typescript
242
+ * boldMDv2("Hello") // "*Hello*"
243
+ * ```
244
+ */
245
+ function boldMDv2(text) {
246
+ return `*${text}*`;
247
+ }
248
+ /**
249
+ * Formats text as italic in MarkdownV2
250
+ *
251
+ * @param text - The text to format
252
+ * @returns Italic formatted text
253
+ * @example
254
+ * ```typescript
255
+ * italicMDv2("Hello") // "_Hello_"
256
+ * ```
257
+ */
258
+ function italicMDv2(text) {
259
+ return `_${text}_`;
260
+ }
261
+ /**
262
+ * Formats text as underline in MarkdownV2
263
+ *
264
+ * @param text - The text to format
265
+ * @returns Underline formatted text
266
+ * @example
267
+ * ```typescript
268
+ * underlineMDv2("Hello") // "__Hello__"
269
+ * ```
270
+ */
271
+ function underlineMDv2(text) {
272
+ return `__${text}__`;
273
+ }
274
+ /**
275
+ * Formats text as strikethrough in MarkdownV2
276
+ *
277
+ * @param text - The text to format
278
+ * @returns Strikethrough formatted text
279
+ * @example
280
+ * ```typescript
281
+ * strikethroughMDv2("Hello") // "~Hello~"
282
+ * ```
283
+ */
284
+ function strikethroughMDv2(text) {
285
+ return `~${text}~`;
286
+ }
287
+ /**
288
+ * Formats text as spoiler in MarkdownV2
289
+ *
290
+ * @param text - The text to format
291
+ * @returns Spoiler formatted text
292
+ * @example
293
+ * ```typescript
294
+ * spoilerMDv2("Secret") // "||Secret||"
295
+ * ```
296
+ */
297
+ function spoilerMDv2(text) {
298
+ return `||${text}||`;
299
+ }
300
+ /**
301
+ * Formats text as monospace code in MarkdownV2
302
+ *
303
+ * @param text - The text to format
304
+ * @returns Code formatted text
305
+ * @example
306
+ * ```typescript
307
+ * codeMDv2("const x = 1") // "`const x = 1`"
308
+ * ```
309
+ */
310
+ function codeMDv2(text) {
311
+ return `\`${text}\``;
312
+ }
313
+ /**
314
+ * Formats text as a code block in MarkdownV2
315
+ *
316
+ * @param text - The code to format
317
+ * @param language - Optional programming language for syntax highlighting
318
+ * @returns Code block formatted text
319
+ * @example
320
+ * ```typescript
321
+ * codeBlockMDv2("console.log('Hello')") // "```console.log('Hello')```"
322
+ * codeBlockMDv2("const x = 1", "javascript") // "```javascript\nconst x = 1\n```"
323
+ * ```
324
+ */
325
+ function codeBlockMDv2(text, language) {
326
+ return language ? `${language}\n${text}\n` : `${text}\n`;
327
+ }
328
+ /**
329
+ * Creates a link in MarkdownV2 format
330
+ *
331
+ * @param text - The link text
332
+ * @param url - The URL to link to
333
+ * @returns Link formatted text
334
+ * @example
335
+ * ```typescript
336
+ * linkMDv2("Google", "https://google.com") // "[Google](https://google.com)"
337
+ * ```
338
+ */
339
+ function linkMDv2(text, url$1) {
340
+ return `[${text}](${url$1})`;
341
+ }
342
+ /**
343
+ * Creates a user mention link in MarkdownV2 format
344
+ *
345
+ * @param userId - The user's ID
346
+ * @param name - Optional display name (ignored in MarkdownV2)
347
+ * @returns Mention formatted text
348
+ * @example
349
+ * ```typescript
350
+ * mentionMDv2(123456) // "[user](tg://user?id=123456)"
351
+ * mentionMDv2(123456, "John") // "[John](tg://user?id=123456)"
352
+ * ```
353
+ */
354
+ function mentionMDv2(userId, name) {
355
+ const display = name || `user`;
356
+ return `[${display}](tg://user?id=${userId})`;
357
+ }
358
+ /**
359
+ * Creates a hashtag link in MarkdownV2 format
360
+ *
361
+ * @param tag - The hashtag text (without #)
362
+ * @returns Hashtag formatted text
363
+ * @example
364
+ * ```typescript
365
+ * hashtagMDv2("test") // "#test"
366
+ * ```
367
+ */
368
+ function hashtagMDv2(tag) {
369
+ return `#${tag}`;
370
+ }
371
+ /**
372
+ * Creates an email link in MarkdownV2 format
373
+ *
374
+ * @param email - The email address
375
+ * @returns Email link formatted text
376
+ * @example
377
+ * ```typescript
378
+ * emailMDv2("test@example.com") // "[test@example.com](mailto:test@example.com)"
379
+ * ```
380
+ */
381
+ function emailMDv2(email$1) {
382
+ return `[${email$1}](mailto:${email$1})`;
383
+ }
384
+ /**
385
+ * Creates a URL link in MarkdownV2 format
386
+ *
387
+ * @param url - The URL
388
+ * @returns URL link formatted text
389
+ * @example
390
+ * ```typescript
391
+ * urlMDv2("https://example.com") // "[https://example.com](https://example.com)"
392
+ * ```
393
+ */
394
+ function urlMDv2(url$1) {
395
+ return `[${url$1}](${url$1})`;
396
+ }
397
+ /**
398
+ * Creates a custom emoji in MarkdownV2 format
399
+ *
400
+ * Note: Custom emoji syntax in MarkdownV2 uses a special format with the emoji
401
+ * ID wrapped in special syntax.
402
+ *
403
+ * @param emojiId - The custom emoji ID
404
+ * @returns Custom emoji formatted text
405
+ * @example
406
+ * ```typescript
407
+ * customEmojiMDv2("5368324170672642286") // "👻 [Custom emoji](tg://emoji?id=5368324170672642286)"
408
+ * ```
409
+ */
410
+ function customEmojiMDv2(emojiId) {
411
+ return `[👻](tg://emoji?id=${emojiId})`;
412
+ }
413
+ /**
414
+ * Raw MarkdownV2 string - bypasses any automatic formatting
415
+ *
416
+ * @param markdown - Pre-formatted MarkdownV2 string
417
+ * @returns The MarkdownV2 string unchanged
418
+ * @example
419
+ * ```typescript
420
+ * rawMDv2("*Hello*") // "*Hello*"
421
+ * ```
422
+ */
423
+ function rawMDv2(markdown) {
424
+ return markdown;
425
+ }
426
+ /**
427
+ * Pre-escapes text for safe use in MarkdownV2 formatting
428
+ *
429
+ * MarkdownV2 requires careful character escaping. This function escapes
430
+ * all reserved characters for safe use in formatted text.
431
+ *
432
+ * @param text - The text to escape
433
+ * @returns Escaped text safe for MarkdownV2
434
+ * @example
435
+ * ```typescript
436
+ * escapeMDv2("Hello_World") // "Hello\\_World"
437
+ * ```
438
+ */
439
+ function escapeMDv2(text) {
440
+ const reserved = "_*[]()~`>#+-=|{}.!";
441
+ let result = text;
442
+ for (const char of reserved) result = result.split(char).join(`\\${char}`);
443
+ return result;
444
+ }
445
+
17
446
  //#endregion
18
447
  //#region src/formatters/index.ts
19
448
  function escapeHTML(text) {
@@ -50,7 +479,7 @@ function pre(text) {
50
479
  return `<pre>${escapeHTML(text)}</pre>`;
51
480
  }
52
481
  function codeBlock(text, language) {
53
- return language ? `<pre><code class="language-${language}">${escapeHTML(text)}</code></pre>` : `<pre>${escapeHTML(text)}</pre>`;
482
+ return language ? `<pre><code class="language-${language}">${escapeHTML(text)}</code></pre>` : `<pre><code>${escapeHTML(text)}</code></pre>`;
54
483
  }
55
484
  function link(text, url$1) {
56
485
  return `<a href="${escapeHTML(url$1)}">${escapeHTML(text)}</a>`;
@@ -71,6 +500,21 @@ function email(email$1) {
71
500
  function url(link$1) {
72
501
  return `<a href="${escapeHTML(link$1)}">${escapeHTML(link$1)}</a>`;
73
502
  }
503
+ /**
504
+ * Raw HTML string - bypasses escaping for combining pre-formatted content
505
+ *
506
+ * @example
507
+ * ```typescript
508
+ * // Instead of this (which escapes inner tags):
509
+ * fmt.bold(fmt.italic("Text")) // <b>&lt;i&gt;Text&lt;/i&gt;</b>
510
+ *
511
+ * // Use this:
512
+ * fmt.bold(fmt.raw(fmt.italic("Text"))) // <b><i>Text</i></b>
513
+ * ```
514
+ */
515
+ function raw(html) {
516
+ return html;
517
+ }
74
518
  function escape(text, mode = "html") {
75
519
  switch (mode) {
76
520
  case "html": return escapeHTML(text);
@@ -96,7 +540,37 @@ const fmt = {
96
540
  escape,
97
541
  escapeHTML,
98
542
  escapeMarkdown,
99
- escapeMarkdownV2
543
+ escapeMarkdownV2,
544
+ raw,
545
+ boldMD,
546
+ italicMD,
547
+ codeMD,
548
+ codeBlockMD,
549
+ linkMD,
550
+ mentionMD,
551
+ hashtagMD,
552
+ underlineMD,
553
+ strikethroughMD,
554
+ spoilerMD,
555
+ emailMD,
556
+ urlMD,
557
+ customEmojiMD,
558
+ rawMD,
559
+ boldMDv2,
560
+ italicMDv2,
561
+ underlineMDv2,
562
+ strikethroughMDv2,
563
+ spoilerMDv2,
564
+ codeMDv2,
565
+ codeBlockMDv2,
566
+ linkMDv2,
567
+ mentionMDv2,
568
+ hashtagMDv2,
569
+ emailMDv2,
570
+ urlMDv2,
571
+ customEmojiMDv2,
572
+ rawMDv2,
573
+ escapeMDv2
100
574
  };
101
575
 
102
576
  //#endregion
@@ -331,6 +805,29 @@ var TelegramKeyboardBuilder = class TelegramKeyboardBuilder {
331
805
  //#region src/builder/builder.ts
332
806
  /**
333
807
  * Telegram Message Builder - Fluent API for building formatted Telegram messages
808
+ *
809
+ * Supports all three Telegram parse modes: HTML, Markdown, and MarkdownV2
810
+ *
811
+ * @example
812
+ * ```typescript
813
+ * // HTML mode (default)
814
+ * const msg1 = TelegramMessageBuilder.text()
815
+ * .title("Welcome")
816
+ * .line("Status", "Active", { bold: true })
817
+ * .build();
818
+ *
819
+ * // Markdown mode
820
+ * const msg2 = TelegramMessageBuilder.text()
821
+ * .setParseMode("markdown")
822
+ * .title("Welcome")
823
+ * .build();
824
+ *
825
+ * // MarkdownV2 mode
826
+ * const msg3 = TelegramMessageBuilder.text()
827
+ * .setParseMode("markdownv2")
828
+ * .title("Welcome")
829
+ * .build();
830
+ * ```
334
831
  */
335
832
  var TelegramMessageBuilder = class TelegramMessageBuilder {
336
833
  parts = [];
@@ -346,25 +843,105 @@ var TelegramMessageBuilder = class TelegramMessageBuilder {
346
843
  this.parseMode = mode;
347
844
  return this;
348
845
  }
846
+ /**
847
+ * Formats text as bold based on current parse mode
848
+ */
849
+ bold(text) {
850
+ switch (this.parseMode) {
851
+ case "html": return bold(text);
852
+ case "markdown": return boldMD(text);
853
+ case "markdownv2": return boldMDv2(text);
854
+ }
855
+ }
856
+ /**
857
+ * Formats text as italic based on current parse mode
858
+ */
859
+ italic(text) {
860
+ switch (this.parseMode) {
861
+ case "html": return italic(text);
862
+ case "markdown": return italicMD(text);
863
+ case "markdownv2": return italicMDv2(text);
864
+ }
865
+ }
866
+ /**
867
+ * Formats text as underline based on current parse mode
868
+ */
869
+ underline(text) {
870
+ switch (this.parseMode) {
871
+ case "html": return underline(text);
872
+ case "markdown": return underlineMD(text);
873
+ case "markdownv2": return underlineMDv2(text);
874
+ }
875
+ }
876
+ /**
877
+ * Formats text as code based on current parse mode
878
+ */
879
+ code(text) {
880
+ switch (this.parseMode) {
881
+ case "html": return code(text);
882
+ case "markdown": return codeMD(text);
883
+ case "markdownv2": return codeMDv2(text);
884
+ }
885
+ }
886
+ /**
887
+ * Formats text as code block based on current parse mode
888
+ */
889
+ codeBlockFormat(text, language) {
890
+ switch (this.parseMode) {
891
+ case "html": return codeBlock(text, language);
892
+ case "markdown": return codeBlockMD(text, language);
893
+ case "markdownv2": return codeBlockMDv2(text, language);
894
+ }
895
+ }
896
+ /**
897
+ * Creates a link based on current parse mode
898
+ */
899
+ linkFormat(text, url$1) {
900
+ switch (this.parseMode) {
901
+ case "html": return link(text, url$1);
902
+ case "markdown": return linkMD(text, url$1);
903
+ case "markdownv2": return linkMDv2(text, url$1);
904
+ }
905
+ }
906
+ /**
907
+ * Creates a mention based on current parse mode
908
+ */
909
+ mentionFormat(userId, name) {
910
+ switch (this.parseMode) {
911
+ case "html": return mention(userId, name);
912
+ case "markdown": return mentionMD(userId, name);
913
+ case "markdownv2": return mentionMDv2(userId, name);
914
+ }
915
+ }
916
+ /**
917
+ * Creates a hashtag based on current parse mode
918
+ */
919
+ hashtagFormat(tag) {
920
+ switch (this.parseMode) {
921
+ case "html": return hashtag(tag);
922
+ case "markdown": return hashtagMD(tag);
923
+ case "markdownv2": return hashtagMDv2(tag);
924
+ }
925
+ }
349
926
  title(text) {
350
- this.parts.push(bold(text));
927
+ this.parts.push(this.bold(text));
351
928
  return this;
352
929
  }
353
930
  section(text) {
354
- this.parts.push(underline(text));
931
+ this.parts.push(this.underline(text));
355
932
  return this;
356
933
  }
357
934
  line(key, value, opts) {
358
935
  let formattedValue = value;
359
- if (opts?.bold) formattedValue = bold(value);
360
- else if (opts?.italic) formattedValue = italic(value);
361
- else if (opts?.code) formattedValue = code(value);
362
- else if (opts?.underline) formattedValue = underline(value);
936
+ if (opts?.bold) formattedValue = this.bold(value);
937
+ else if (opts?.italic) formattedValue = this.italic(value);
938
+ else if (opts?.code) formattedValue = this.code(value);
939
+ else if (opts?.underline) formattedValue = this.underline(value);
363
940
  this.parts.push(`${key}: ${formattedValue}`);
364
941
  return this;
365
942
  }
366
943
  codeBlock(text, language) {
367
- this.parts.push(codeBlock(text, language));
944
+ this.parts.push(this.codeBlockFormat(text, language));
368
945
  return this;
369
946
  }
370
947
  listItem(text) {
@@ -384,15 +961,15 @@ var TelegramMessageBuilder = class TelegramMessageBuilder {
384
961
  return this;
385
962
  }
386
963
  link(text, url$1) {
387
- this.parts.push(link(text, url$1));
964
+ this.parts.push(this.linkFormat(text, url$1));
388
965
  return this;
389
966
  }
390
967
  mention(userId, name) {
391
- this.parts.push(mention(userId, name));
968
+ this.parts.push(this.mentionFormat(userId, name));
392
969
  return this;
393
970
  }
394
971
  hashtag(tag) {
395
- this.parts.push(hashtag(tag));
972
+ this.parts.push(this.hashtagFormat(tag));
396
973
  return this;
397
974
  }
398
975
  build() {
@@ -419,27 +996,495 @@ var TelegramMessageBuilder = class TelegramMessageBuilder {
419
996
  };
420
997
 
421
998
  //#endregion
999
+ //#region src/builder/media.ts
1000
+ /**
1001
+ * Telegram Media Builder - Fluent API for building media messages
1002
+ *
1003
+ * Provides a type-safe, fluent interface for constructing media messages
1004
+ * compatible with Telegram Bot API v9.3+.
1005
+ *
1006
+ * Supports all three Telegram parse modes (HTML, Markdown, MarkdownV2) for caption formatting.
1007
+ *
1008
+ * @example
1009
+ * ```typescript
1010
+ * // Simple photo with caption
1011
+ * const photo = TelegramMediaBuilder.photo("photo.jpg")
1012
+ * .caption("My photo")
1013
+ * .build();
1014
+ *
1015
+ * // Video with caption and options
1016
+ * const video = TelegramMediaBuilder.video("video.mp4")
1017
+ * .caption("My video")
1018
+ * .duration(120)
1019
+ * .thumbnail("thumb.jpg")
1020
+ * .setParseMode("markdown")
1021
+ * .build();
1022
+ *
1023
+ * // Document with custom options
1024
+ * const doc = TelegramMediaBuilder.document("report.pdf")
1025
+ * .caption("Q4 Report")
1026
+ * .fileName("q4_2024.pdf")
1027
+ * .mimeType("application/pdf")
1028
+ * .build();
1029
+ * ```
1030
+ */
1031
+ var TelegramMediaBuilder = class {
1032
+ source;
1033
+ mediaType;
1034
+ _caption;
1035
+ parseMode = "html";
1036
+ options = {};
1037
+ constructor(source, mediaType) {
1038
+ this.source = source;
1039
+ this.mediaType = mediaType;
1040
+ }
1041
+ /**
1042
+ * Create a photo message builder
1043
+ *
1044
+ * @param source - File ID, URL, Buffer, or file path
1045
+ * @returns Photo media builder with thumbnail() method
1046
+ *
1047
+ * @example
1048
+ * ```typescript
1049
+ * const photo = TelegramMediaBuilder.photo("https://example.com/photo.jpg")
1050
+ * .caption("Beautiful sunset")
1051
+ * .thumbnail("thumb.jpg")
1052
+ * .build();
1053
+ * ```
1054
+ */
1055
+ static photo(source) {
1056
+ return new PhotoBuilder(source, "photo");
1057
+ }
1058
+ /**
1059
+ * Create a video message builder
1060
+ *
1061
+ * @param source - File ID, URL, Buffer, or file path
1062
+ * @returns Video media builder with duration(), width(), height(), thumbnail(), enableStreaming() methods
1063
+ *
1064
+ * @example
1065
+ * ```typescript
1066
+ * const video = TelegramMediaBuilder.video("video.mp4")
1067
+ * .caption("My video")
1068
+ * .duration(120)
1069
+ * .width(1920)
1070
+ * .height(1080)
1071
+ * .build();
1072
+ * ```
1073
+ */
1074
+ static video(source) {
1075
+ return new VideoBuilder(source, "video");
1076
+ }
1077
+ /**
1078
+ * Create a document message builder
1079
+ *
1080
+ * @param source - File ID, URL, Buffer, or file path
1081
+ * @returns Document media builder with thumbnail(), fileName(), mimeType(), disableContentTypeDetection() methods
1082
+ *
1083
+ * @example
1084
+ * ```typescript
1085
+ * const doc = TelegramMediaBuilder.document("report.pdf")
1086
+ * .caption("Q4 Report")
1087
+ * .fileName("q4_2024.pdf")
1088
+ * .mimeType("application/pdf")
1089
+ * .build();
1090
+ * ```
1091
+ */
1092
+ static document(source) {
1093
+ return new DocumentBuilder(source, "document");
1094
+ }
1095
+ /**
1096
+ * Create an audio message builder
1097
+ *
1098
+ * @param source - File ID, URL, Buffer, or file path
1099
+ * @returns Audio media builder with duration(), performer(), title(), thumbnail() methods
1100
+ *
1101
+ * @example
1102
+ * ```typescript
1103
+ * const audio = TelegramMediaBuilder.audio("song.mp3")
1104
+ * .caption("My favorite song")
1105
+ * .duration(180)
1106
+ * .performer("Artist Name")
1107
+ * .title("Song Title")
1108
+ * .build();
1109
+ * ```
1110
+ */
1111
+ static audio(source) {
1112
+ return new AudioBuilder(source, "audio");
1113
+ }
1114
+ /**
1115
+ * Create a voice message builder
1116
+ *
1117
+ * @param source - File ID, URL, Buffer, or file path
1118
+ * @returns Voice media builder with duration() method
1119
+ *
1120
+ * @example
1121
+ * ```typescript
1122
+ * const voice = TelegramMediaBuilder.voice("voice.ogg")
1123
+ * .caption("Listen to this")
1124
+ * .duration(30)
1125
+ * .build();
1126
+ * ```
1127
+ */
1128
+ static voice(source) {
1129
+ return new VoiceBuilder(source, "voice");
1130
+ }
1131
+ /**
1132
+ * Set caption for the media
1133
+ *
1134
+ * @param text - Caption text (0-1024 characters)
1135
+ * @returns This builder for chaining
1136
+ */
1137
+ caption(text) {
1138
+ this._caption = text;
1139
+ return this;
1140
+ }
1141
+ /**
1142
+ * Set parse mode for caption formatting
1143
+ *
1144
+ * @param mode - Parse mode (html, markdown, or markdownv2)
1145
+ * @returns This builder for chaining
1146
+ */
1147
+ setParseMode(mode) {
1148
+ this.parseMode = mode;
1149
+ return this;
1150
+ }
1151
+ /**
1152
+ * Set a custom option
1153
+ *
1154
+ * @param key - Option name
1155
+ * @param value - Option value
1156
+ * @returns This builder for chaining
1157
+ */
1158
+ setOption(key, value) {
1159
+ this.options[key] = value;
1160
+ return this;
1161
+ }
1162
+ /**
1163
+ * Set multiple options at once
1164
+ *
1165
+ * @param opts - Object with options to set
1166
+ * @returns This builder for chaining
1167
+ */
1168
+ setOptions(opts) {
1169
+ this.options = {
1170
+ ...this.options,
1171
+ ...opts
1172
+ };
1173
+ return this;
1174
+ }
1175
+ /**
1176
+ * Build the media message object
1177
+ *
1178
+ * @returns Complete media message ready for Telegram Bot API
1179
+ */
1180
+ build() {
1181
+ const result = {
1182
+ media: this.source,
1183
+ type: this.mediaType
1184
+ };
1185
+ if (this._caption !== void 0) {
1186
+ result.caption = this.formatCaption(this._caption);
1187
+ result.parse_mode = this.parseMode;
1188
+ }
1189
+ Object.assign(result, this.options);
1190
+ return result;
1191
+ }
1192
+ /**
1193
+ * Format caption based on current parse mode
1194
+ *
1195
+ * @param text - Caption text to format
1196
+ * @returns Formatted caption
1197
+ */
1198
+ formatCaption(text) {
1199
+ switch (this.parseMode) {
1200
+ case "html": return escapeHTML(text);
1201
+ case "markdown": return escapeMarkdown(text);
1202
+ case "markdownv2": return escapeMarkdownV2(text);
1203
+ }
1204
+ }
1205
+ };
1206
+ /**
1207
+ * Photo-specific builder with convenience methods
1208
+ *
1209
+ * @example
1210
+ * ```typescript
1211
+ * const photo = TelegramMediaBuilder.photo("photo.jpg")
1212
+ * .caption("My photo")
1213
+ * .thumbnail("thumb.jpg")
1214
+ * .build();
1215
+ * ```
1216
+ */
1217
+ var PhotoBuilder = class extends TelegramMediaBuilder {
1218
+ /**
1219
+ * Set thumbnail for the photo
1220
+ *
1221
+ * @param thumb - Thumbnail as Buffer or file path
1222
+ * @returns This builder for chaining
1223
+ */
1224
+ thumbnail(thumb) {
1225
+ this.setOption("thumb", thumb);
1226
+ return this;
1227
+ }
1228
+ };
1229
+ /**
1230
+ * Video-specific builder with convenience methods
1231
+ *
1232
+ * @example
1233
+ * ```typescript
1234
+ * const video = TelegramMediaBuilder.video("video.mp4")
1235
+ * .caption("My video")
1236
+ * .duration(120)
1237
+ * .width(1920)
1238
+ * .height(1080)
1239
+ * .thumbnail("thumb.jpg")
1240
+ * .enableStreaming()
1241
+ * .build();
1242
+ * ```
1243
+ */
1244
+ var VideoBuilder = class extends TelegramMediaBuilder {
1245
+ /**
1246
+ * Set video duration
1247
+ *
1248
+ * @param seconds - Duration in seconds
1249
+ * @returns This builder for chaining
1250
+ */
1251
+ duration(seconds) {
1252
+ this.setOption("duration", seconds);
1253
+ return this;
1254
+ }
1255
+ /**
1256
+ * Set video width
1257
+ *
1258
+ * @param px - Width in pixels
1259
+ * @returns This builder for chaining
1260
+ */
1261
+ width(px) {
1262
+ this.setOption("width", px);
1263
+ return this;
1264
+ }
1265
+ /**
1266
+ * Set video height
1267
+ *
1268
+ * @param px - Height in pixels
1269
+ * @returns This builder for chaining
1270
+ */
1271
+ height(px) {
1272
+ this.setOption("height", px);
1273
+ return this;
1274
+ }
1275
+ /**
1276
+ * Set thumbnail for the video
1277
+ *
1278
+ * @param thumb - Thumbnail as Buffer or file path
1279
+ * @returns This builder for chaining
1280
+ */
1281
+ thumbnail(thumb) {
1282
+ this.setOption("thumb", thumb);
1283
+ return this;
1284
+ }
1285
+ /**
1286
+ * Enable streaming for the video
1287
+ *
1288
+ * @returns This builder for chaining
1289
+ */
1290
+ enableStreaming() {
1291
+ this.setOption("support_streaming", true);
1292
+ return this;
1293
+ }
1294
+ };
1295
+ /**
1296
+ * Document-specific builder with convenience methods
1297
+ *
1298
+ * @example
1299
+ * ```typescript
1300
+ * const doc = TelegramMediaBuilder.document("report.pdf")
1301
+ * .caption("Q4 Report")
1302
+ * .thumbnail("thumb.jpg")
1303
+ * .fileName("q4_2024.pdf")
1304
+ * .mimeType("application/pdf")
1305
+ * .disableContentTypeDetection()
1306
+ * .build();
1307
+ * ```
1308
+ */
1309
+ var DocumentBuilder = class extends TelegramMediaBuilder {
1310
+ /**
1311
+ * Set thumbnail for the document
1312
+ *
1313
+ * @param thumb - Thumbnail as Buffer or file path
1314
+ * @returns This builder for chaining
1315
+ */
1316
+ thumbnail(thumb) {
1317
+ this.setOption("thumb", thumb);
1318
+ return this;
1319
+ }
1320
+ /**
1321
+ * Set original filename
1322
+ *
1323
+ * @param name - File name
1324
+ * @returns This builder for chaining
1325
+ */
1326
+ fileName(name) {
1327
+ this.setOption("file_name", name);
1328
+ return this;
1329
+ }
1330
+ /**
1331
+ * Set MIME type
1332
+ *
1333
+ * @param type - MIME type string
1334
+ * @returns This builder for chaining
1335
+ */
1336
+ mimeType(type) {
1337
+ this.setOption("mime_type", type);
1338
+ return this;
1339
+ }
1340
+ /**
1341
+ * Disable automatic file type detection
1342
+ *
1343
+ * @returns This builder for chaining
1344
+ */
1345
+ disableContentTypeDetection() {
1346
+ this.setOption("disable_content_type_detection", true);
1347
+ return this;
1348
+ }
1349
+ };
1350
+ /**
1351
+ * Audio-specific builder with convenience methods
1352
+ *
1353
+ * @example
1354
+ * ```typescript
1355
+ * const audio = TelegramMediaBuilder.audio("song.mp3")
1356
+ * .caption("My favorite song")
1357
+ * .duration(180)
1358
+ * .performer("Artist Name")
1359
+ * .title("Song Title")
1360
+ * .thumbnail("album_art.jpg")
1361
+ * .build();
1362
+ * ```
1363
+ */
1364
+ var AudioBuilder = class extends TelegramMediaBuilder {
1365
+ /**
1366
+ * Set audio duration
1367
+ *
1368
+ * @param seconds - Duration in seconds
1369
+ * @returns This builder for chaining
1370
+ */
1371
+ duration(seconds) {
1372
+ this.setOption("duration", seconds);
1373
+ return this;
1374
+ }
1375
+ /**
1376
+ * Set performer name
1377
+ *
1378
+ * @param name - Performer name
1379
+ * @returns This builder for chaining
1380
+ */
1381
+ performer(name) {
1382
+ this.setOption("performer", name);
1383
+ return this;
1384
+ }
1385
+ /**
1386
+ * Set track title
1387
+ *
1388
+ * @param name - Track title
1389
+ * @returns This builder for chaining
1390
+ */
1391
+ title(name) {
1392
+ this.setOption("title", name);
1393
+ return this;
1394
+ }
1395
+ /**
1396
+ * Set thumbnail (album cover)
1397
+ *
1398
+ * @param thumb - Thumbnail as Buffer or file path
1399
+ * @returns This builder for chaining
1400
+ */
1401
+ thumbnail(thumb) {
1402
+ this.setOption("thumb", thumb);
1403
+ return this;
1404
+ }
1405
+ };
1406
+ /**
1407
+ * Voice-specific builder with convenience methods
1408
+ *
1409
+ * @example
1410
+ * ```typescript
1411
+ * const voice = TelegramMediaBuilder.voice("voice.ogg")
1412
+ * .caption("Listen to this")
1413
+ * .duration(30)
1414
+ * .build();
1415
+ * ```
1416
+ */
1417
+ var VoiceBuilder = class extends TelegramMediaBuilder {
1418
+ /**
1419
+ * Set voice duration
1420
+ *
1421
+ * @param seconds - Duration in seconds
1422
+ * @returns This builder for chaining
1423
+ */
1424
+ duration(seconds) {
1425
+ this.setOption("duration", seconds);
1426
+ return this;
1427
+ }
1428
+ };
1429
+
1430
+ //#endregion
1431
+ exports.AudioBuilder = AudioBuilder;
422
1432
  exports.DEFAULT_PREFIX = DEFAULT_PREFIX;
423
1433
  exports.DEFAULT_SUFFIX = DEFAULT_SUFFIX;
1434
+ exports.DocumentBuilder = DocumentBuilder;
1435
+ exports.PhotoBuilder = PhotoBuilder;
424
1436
  exports.TelegramKeyboardBuilder = TelegramKeyboardBuilder;
1437
+ exports.TelegramMediaBuilder = TelegramMediaBuilder;
425
1438
  exports.TelegramMessageBuilder = TelegramMessageBuilder;
1439
+ exports.VideoBuilder = VideoBuilder;
1440
+ exports.VoiceBuilder = VoiceBuilder;
426
1441
  exports.bold = bold;
1442
+ exports.boldMD = boldMD;
1443
+ exports.boldMDv2 = boldMDv2;
427
1444
  exports.code = code;
428
1445
  exports.codeBlock = codeBlock;
1446
+ exports.codeBlockMD = codeBlockMD;
1447
+ exports.codeBlockMDv2 = codeBlockMDv2;
1448
+ exports.codeMD = codeMD;
1449
+ exports.codeMDv2 = codeMDv2;
429
1450
  exports.customEmoji = customEmoji;
1451
+ exports.customEmojiMD = customEmojiMD;
1452
+ exports.customEmojiMDv2 = customEmojiMDv2;
430
1453
  exports.email = email;
1454
+ exports.emailMD = emailMD;
1455
+ exports.emailMDv2 = emailMDv2;
431
1456
  exports.escape = escape;
432
1457
  exports.escapeHTML = escapeHTML;
1458
+ exports.escapeMDv2 = escapeMDv2;
433
1459
  exports.escapeMarkdown = escapeMarkdown;
434
1460
  exports.escapeMarkdownV2 = escapeMarkdownV2;
435
1461
  exports.fmt = fmt;
436
1462
  exports.hashtag = hashtag;
1463
+ exports.hashtagMD = hashtagMD;
1464
+ exports.hashtagMDv2 = hashtagMDv2;
437
1465
  exports.italic = italic;
1466
+ exports.italicMD = italicMD;
1467
+ exports.italicMDv2 = italicMDv2;
438
1468
  exports.link = link;
1469
+ exports.linkMD = linkMD;
1470
+ exports.linkMDv2 = linkMDv2;
439
1471
  exports.mention = mention;
1472
+ exports.mentionMD = mentionMD;
1473
+ exports.mentionMDv2 = mentionMDv2;
440
1474
  exports.pre = pre;
1475
+ exports.raw = raw;
1476
+ exports.rawMD = rawMD;
1477
+ exports.rawMDv2 = rawMDv2;
441
1478
  exports.spoiler = spoiler;
1479
+ exports.spoilerMD = spoilerMD;
1480
+ exports.spoilerMDv2 = spoilerMDv2;
442
1481
  exports.strikethrough = strikethrough;
1482
+ exports.strikethroughMD = strikethroughMD;
1483
+ exports.strikethroughMDv2 = strikethroughMDv2;
443
1484
  exports.underline = underline;
1485
+ exports.underlineMD = underlineMD;
1486
+ exports.underlineMDv2 = underlineMDv2;
444
1487
  exports.url = url;
1488
+ exports.urlMD = urlMD;
1489
+ exports.urlMDv2 = urlMDv2;
445
1490
  //# sourceMappingURL=index.cjs.map