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