@mks2508/telegram-message-builder 0.2.0 → 0.3.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.
Files changed (42) hide show
  1. package/dist/index.cjs +1057 -12
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1022 -13
  4. package/dist/index.js.map +1 -1
  5. package/package.json +1 -1
  6. package/src/builder/builder.d.ts +55 -0
  7. package/src/builder/builder.d.ts.map +1 -1
  8. package/src/builder/builder.ts +145 -10
  9. package/src/builder/index.d.ts +2 -1
  10. package/src/builder/index.d.ts.map +1 -1
  11. package/src/builder/index.ts +2 -1
  12. package/src/builder/media.d.ts +352 -0
  13. package/src/builder/media.d.ts.map +1 -0
  14. package/src/builder/media.test.ts +664 -0
  15. package/src/builder/media.ts +484 -0
  16. package/src/builder.test.ts +465 -0
  17. package/src/escaping.test.ts +2 -2
  18. package/src/formatters/index.d.ts +47 -0
  19. package/src/formatters/index.d.ts.map +1 -1
  20. package/src/formatters/index.ts +92 -1
  21. package/src/formatters/markdown.d.ts +179 -0
  22. package/src/formatters/markdown.d.ts.map +1 -0
  23. package/src/formatters/markdown.test.ts +417 -0
  24. package/src/formatters/markdown.ts +220 -0
  25. package/src/formatters/markdownv2.d.ts +184 -0
  26. package/src/formatters/markdownv2.d.ts.map +1 -0
  27. package/src/formatters/markdownv2.ts +235 -0
  28. package/src/formatters.test.ts +17 -7
  29. package/src/index.d.ts +2 -0
  30. package/src/index.d.ts.map +1 -1
  31. package/src/index.ts +12 -0
  32. package/src/integration.test.ts +523 -0
  33. package/src/media-integration.test.ts +384 -0
  34. package/src/types/index.d.ts +1 -0
  35. package/src/types/index.d.ts.map +1 -1
  36. package/src/types/index.ts +1 -0
  37. package/src/types/media.types.d.ts +158 -0
  38. package/src/types/media.types.d.ts.map +1 -0
  39. package/src/types/media.types.ts +178 -0
  40. package/src/types.test.ts +539 -0
  41. package/src/utils/index.d.ts +1 -1
  42. package/src/utils/index.ts +0 -5
@@ -0,0 +1,220 @@
1
+ /**
2
+ * @fileoverview Markdown (Legacy) Formatters
3
+ * @description Text formatting functions for Telegram's legacy Markdown parse mode
4
+ * @module telegram-message-builder/formatters
5
+ *
6
+ * @see {@link https://core.telegram.org/bots/api#formatting-options | Telegram Bot API - Formatting Options}
7
+ */
8
+
9
+ /**
10
+ * Formats text as bold in Markdown
11
+ *
12
+ * @param text - The text to format
13
+ * @returns Bold formatted text
14
+ * @example
15
+ * ```typescript
16
+ * boldMD("Hello") // "*Hello*"
17
+ * ```
18
+ */
19
+ export function boldMD(text: string): string {
20
+ return `*${text}*`;
21
+ }
22
+
23
+ /**
24
+ * Formats text as italic in Markdown
25
+ *
26
+ * @param text - The text to format
27
+ * @returns Italic formatted text
28
+ * @example
29
+ * ```typescript
30
+ * italicMD("Hello") // "_Hello_"
31
+ * ```
32
+ */
33
+ export function italicMD(text: string): string {
34
+ return `_${text}_`;
35
+ }
36
+
37
+ /**
38
+ * Formats text as monospace code in Markdown
39
+ *
40
+ * @param text - The text to format
41
+ * @returns Code formatted text
42
+ * @example
43
+ * ```typescript
44
+ * codeMD("const x = 1") // "`const x = 1`"
45
+ * ```
46
+ */
47
+ export function codeMD(text: string): string {
48
+ return `\`${text}\``;
49
+ }
50
+
51
+ /**
52
+ * Formats text as a code block in Markdown
53
+ *
54
+ * @param text - The code to format
55
+ * @param language - Optional programming language for syntax highlighting
56
+ * @returns Code block formatted text
57
+ * @example
58
+ * ```typescript
59
+ * codeBlockMD("console.log('Hello')") // "```console.log('Hello')```"
60
+ * codeBlockMD("const x = 1", "javascript") // "```javascript\nconst x = 1\n```"
61
+ * ```
62
+ */
63
+ export function codeBlockMD(text: string, language?: string): string {
64
+ return language ? `${language}\n${text}\n` : `${text}\n`;
65
+ }
66
+
67
+ /**
68
+ * Creates a link in Markdown format
69
+ *
70
+ * @param text - The link text
71
+ * @param url - The URL to link to
72
+ * @returns Link formatted text
73
+ * @example
74
+ * ```typescript
75
+ * linkMD("Google", "https://google.com") // "[Google](https://google.com)"
76
+ * ```
77
+ */
78
+ export function linkMD(text: string, url: string): string {
79
+ return `[${text}](${url})`;
80
+ }
81
+
82
+ /**
83
+ * Creates a user mention link in Markdown format
84
+ *
85
+ * @param userId - The user's ID
86
+ * @param name - Optional display name
87
+ * @returns Mention formatted text
88
+ * @example
89
+ * ```typescript
90
+ * mentionMD(123456) // "tg://user?id=123456"
91
+ * mentionMD(123456, "John") // "tg://user?id=123456"
92
+ * ```
93
+ */
94
+ export function mentionMD(userId: number, _name?: string): string {
95
+ return `tg://user?id=${userId}`;
96
+ }
97
+
98
+ /**
99
+ * Creates a hashtag link in Markdown format
100
+ *
101
+ * @param tag - The hashtag text (without #)
102
+ * @returns Hashtag formatted text
103
+ * @example
104
+ * ```typescript
105
+ * hashtagMD("test") // "#test"
106
+ * ```
107
+ */
108
+ export function hashtagMD(tag: string): string {
109
+ return `#${tag}`;
110
+ }
111
+
112
+ /**
113
+ * Formats text as underline in Markdown (limited support)
114
+ *
115
+ * Note: Standard Markdown doesn't support underline. This uses HTML which
116
+ * may not work in all Telegram clients.
117
+ *
118
+ * @param text - The text to format
119
+ * @returns Underline formatted text (HTML fallback)
120
+ * @example
121
+ * ```typescript
122
+ * underlineMD("Hello") // "<u>Hello</u>"
123
+ * ```
124
+ */
125
+ export function underlineMD(text: string): string {
126
+ return `<u>${text}</u>`;
127
+ }
128
+
129
+ /**
130
+ * Formats text as strikethrough in Markdown (limited support)
131
+ *
132
+ * Note: Standard Markdown doesn't support strikethrough. This uses HTML which
133
+ * may not work in all Telegram clients.
134
+ *
135
+ * @param text - The text to format
136
+ * @returns Strikethrough formatted text (HTML fallback)
137
+ * @example
138
+ * ```typescript
139
+ * strikethroughMD("Hello") // "<s>Hello</s>"
140
+ * ```
141
+ */
142
+ export function strikethroughMD(text: string): string {
143
+ return `<s>${text}</s>`;
144
+ }
145
+
146
+ /**
147
+ * Formats text as spoiler in Markdown (limited support)
148
+ *
149
+ * Note: Standard Markdown doesn't support spoiler. This uses HTML which
150
+ * may not work in all Telegram clients.
151
+ *
152
+ * @param text - The text to format
153
+ * @returns Spoiler formatted text (HTML fallback)
154
+ * @example
155
+ * ```typescript
156
+ * spoilerMD("Secret") // "<tg-spoiler>Secret</tg-spoiler>"
157
+ * ```
158
+ */
159
+ export function spoilerMD(text: string): string {
160
+ return `<tg-spoiler>${text}</tg-spoiler>`;
161
+ }
162
+
163
+ /**
164
+ * Creates an email link in Markdown format
165
+ *
166
+ * @param email - The email address
167
+ * @returns Email link formatted text
168
+ * @example
169
+ * ```typescript
170
+ * emailMD("test@example.com") // "[test@example.com](mailto:test@example.com)"
171
+ * ```
172
+ */
173
+ export function emailMD(email: string): string {
174
+ return `[${email}](mailto:${email})`;
175
+ }
176
+
177
+ /**
178
+ * Creates a URL link in Markdown format
179
+ *
180
+ * @param url - The URL
181
+ * @returns URL link formatted text
182
+ * @example
183
+ * ```typescript
184
+ * urlMD("https://example.com") // "[https://example.com](https://example.com)"
185
+ * ```
186
+ */
187
+ export function urlMD(url: string): string {
188
+ return `[${url}](${url})`;
189
+ }
190
+
191
+ /**
192
+ * Creates a custom emoji in Markdown format (limited support)
193
+ *
194
+ * Note: Standard Markdown doesn't support custom emoji. This uses HTML which
195
+ * may not work in all Telegram clients.
196
+ *
197
+ * @param emojiId - The custom emoji ID
198
+ * @returns Custom emoji formatted text (HTML fallback)
199
+ * @example
200
+ * ```typescript
201
+ * customEmojiMD("5368324170672642286") // "<tg-emoji emoji-id=\"5368324170672642286\">👻</tg-emoji>"
202
+ * ```
203
+ */
204
+ export function customEmojiMD(emojiId: string): string {
205
+ return `<tg-emoji emoji-id="${emojiId}">👻</tg-emoji>`;
206
+ }
207
+
208
+ /**
209
+ * Raw Markdown string - bypasses any automatic formatting
210
+ *
211
+ * @param markdown - Pre-formatted Markdown string
212
+ * @returns The Markdown string unchanged
213
+ * @example
214
+ * ```typescript
215
+ * rawMD("*Hello*") // "*Hello*"
216
+ * ```
217
+ */
218
+ export function rawMD(markdown: string): string {
219
+ return markdown;
220
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * @fileoverview MarkdownV2 Formatters
3
+ * @description Text formatting functions for Telegram's MarkdownV2 parse mode
4
+ * @module telegram-message-builder/formatters
5
+ *
6
+ * @see {@link https://core.telegram.org/bots/api#markdownv2-style | Telegram Bot API - MarkdownV2 Style}
7
+ */
8
+ /**
9
+ * Formats text as bold in MarkdownV2
10
+ *
11
+ * @param text - The text to format
12
+ * @returns Bold formatted text
13
+ * @example
14
+ * ```typescript
15
+ * boldMDv2("Hello") // "*Hello*"
16
+ * ```
17
+ */
18
+ export declare function boldMDv2(text: string): string;
19
+ /**
20
+ * Formats text as italic in MarkdownV2
21
+ *
22
+ * @param text - The text to format
23
+ * @returns Italic formatted text
24
+ * @example
25
+ * ```typescript
26
+ * italicMDv2("Hello") // "_Hello_"
27
+ * ```
28
+ */
29
+ export declare function italicMDv2(text: string): string;
30
+ /**
31
+ * Formats text as underline in MarkdownV2
32
+ *
33
+ * @param text - The text to format
34
+ * @returns Underline formatted text
35
+ * @example
36
+ * ```typescript
37
+ * underlineMDv2("Hello") // "__Hello__"
38
+ * ```
39
+ */
40
+ export declare function underlineMDv2(text: string): string;
41
+ /**
42
+ * Formats text as strikethrough in MarkdownV2
43
+ *
44
+ * @param text - The text to format
45
+ * @returns Strikethrough formatted text
46
+ * @example
47
+ * ```typescript
48
+ * strikethroughMDv2("Hello") // "~Hello~"
49
+ * ```
50
+ */
51
+ export declare function strikethroughMDv2(text: string): string;
52
+ /**
53
+ * Formats text as spoiler in MarkdownV2
54
+ *
55
+ * @param text - The text to format
56
+ * @returns Spoiler formatted text
57
+ * @example
58
+ * ```typescript
59
+ * spoilerMDv2("Secret") // "||Secret||"
60
+ * ```
61
+ */
62
+ export declare function spoilerMDv2(text: string): string;
63
+ /**
64
+ * Formats text as monospace code in MarkdownV2
65
+ *
66
+ * @param text - The text to format
67
+ * @returns Code formatted text
68
+ * @example
69
+ * ```typescript
70
+ * codeMDv2("const x = 1") // "`const x = 1`"
71
+ * ```
72
+ */
73
+ export declare function codeMDv2(text: string): string;
74
+ /**
75
+ * Formats text as a code block in MarkdownV2
76
+ *
77
+ * @param text - The code to format
78
+ * @param language - Optional programming language for syntax highlighting
79
+ * @returns Code block formatted text
80
+ * @example
81
+ * ```typescript
82
+ * codeBlockMDv2("console.log('Hello')") // "```console.log('Hello')```"
83
+ * codeBlockMDv2("const x = 1", "javascript") // "```javascript\nconst x = 1\n```"
84
+ * ```
85
+ */
86
+ export declare function codeBlockMDv2(text: string, language?: string): string;
87
+ /**
88
+ * Creates a link in MarkdownV2 format
89
+ *
90
+ * @param text - The link text
91
+ * @param url - The URL to link to
92
+ * @returns Link formatted text
93
+ * @example
94
+ * ```typescript
95
+ * linkMDv2("Google", "https://google.com") // "[Google](https://google.com)"
96
+ * ```
97
+ */
98
+ export declare function linkMDv2(text: string, url: string): string;
99
+ /**
100
+ * Creates a user mention link in MarkdownV2 format
101
+ *
102
+ * @param userId - The user's ID
103
+ * @param name - Optional display name (ignored in MarkdownV2)
104
+ * @returns Mention formatted text
105
+ * @example
106
+ * ```typescript
107
+ * mentionMDv2(123456) // "[user](tg://user?id=123456)"
108
+ * mentionMDv2(123456, "John") // "[John](tg://user?id=123456)"
109
+ * ```
110
+ */
111
+ export declare function mentionMDv2(userId: number, name?: string): string;
112
+ /**
113
+ * Creates a hashtag link in MarkdownV2 format
114
+ *
115
+ * @param tag - The hashtag text (without #)
116
+ * @returns Hashtag formatted text
117
+ * @example
118
+ * ```typescript
119
+ * hashtagMDv2("test") // "#test"
120
+ * ```
121
+ */
122
+ export declare function hashtagMDv2(tag: string): string;
123
+ /**
124
+ * Creates an email link in MarkdownV2 format
125
+ *
126
+ * @param email - The email address
127
+ * @returns Email link formatted text
128
+ * @example
129
+ * ```typescript
130
+ * emailMDv2("test@example.com") // "[test@example.com](mailto:test@example.com)"
131
+ * ```
132
+ */
133
+ export declare function emailMDv2(email: string): string;
134
+ /**
135
+ * Creates a URL link in MarkdownV2 format
136
+ *
137
+ * @param url - The URL
138
+ * @returns URL link formatted text
139
+ * @example
140
+ * ```typescript
141
+ * urlMDv2("https://example.com") // "[https://example.com](https://example.com)"
142
+ * ```
143
+ */
144
+ export declare function urlMDv2(url: string): string;
145
+ /**
146
+ * Creates a custom emoji in MarkdownV2 format
147
+ *
148
+ * Note: Custom emoji syntax in MarkdownV2 uses a special format with the emoji
149
+ * ID wrapped in special syntax.
150
+ *
151
+ * @param emojiId - The custom emoji ID
152
+ * @returns Custom emoji formatted text
153
+ * @example
154
+ * ```typescript
155
+ * customEmojiMDv2("5368324170672642286") // "👻 [Custom emoji](tg://emoji?id=5368324170672642286)"
156
+ * ```
157
+ */
158
+ export declare function customEmojiMDv2(emojiId: string): string;
159
+ /**
160
+ * Raw MarkdownV2 string - bypasses any automatic formatting
161
+ *
162
+ * @param markdown - Pre-formatted MarkdownV2 string
163
+ * @returns The MarkdownV2 string unchanged
164
+ * @example
165
+ * ```typescript
166
+ * rawMDv2("*Hello*") // "*Hello*"
167
+ * ```
168
+ */
169
+ export declare function rawMDv2(markdown: string): string;
170
+ /**
171
+ * Pre-escapes text for safe use in MarkdownV2 formatting
172
+ *
173
+ * MarkdownV2 requires careful character escaping. This function escapes
174
+ * all reserved characters for safe use in formatted text.
175
+ *
176
+ * @param text - The text to escape
177
+ * @returns Escaped text safe for MarkdownV2
178
+ * @example
179
+ * ```typescript
180
+ * escapeMDv2("Hello_World") // "Hello\\_World"
181
+ * ```
182
+ */
183
+ export declare function escapeMDv2(text: string): string;
184
+ //# sourceMappingURL=markdownv2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownv2.d.ts","sourceRoot":"","sources":["markdownv2.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO/C"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * @fileoverview MarkdownV2 Formatters
3
+ * @description Text formatting functions for Telegram's MarkdownV2 parse mode
4
+ * @module telegram-message-builder/formatters
5
+ *
6
+ * @see {@link https://core.telegram.org/bots/api#markdownv2-style | Telegram Bot API - MarkdownV2 Style}
7
+ */
8
+
9
+ /**
10
+ * Formats text as bold in MarkdownV2
11
+ *
12
+ * @param text - The text to format
13
+ * @returns Bold formatted text
14
+ * @example
15
+ * ```typescript
16
+ * boldMDv2("Hello") // "*Hello*"
17
+ * ```
18
+ */
19
+ export function boldMDv2(text: string): string {
20
+ return `*${text}*`;
21
+ }
22
+
23
+ /**
24
+ * Formats text as italic in MarkdownV2
25
+ *
26
+ * @param text - The text to format
27
+ * @returns Italic formatted text
28
+ * @example
29
+ * ```typescript
30
+ * italicMDv2("Hello") // "_Hello_"
31
+ * ```
32
+ */
33
+ export function italicMDv2(text: string): string {
34
+ return `_${text}_`;
35
+ }
36
+
37
+ /**
38
+ * Formats text as underline in MarkdownV2
39
+ *
40
+ * @param text - The text to format
41
+ * @returns Underline formatted text
42
+ * @example
43
+ * ```typescript
44
+ * underlineMDv2("Hello") // "__Hello__"
45
+ * ```
46
+ */
47
+ export function underlineMDv2(text: string): string {
48
+ return `__${text}__`;
49
+ }
50
+
51
+ /**
52
+ * Formats text as strikethrough in MarkdownV2
53
+ *
54
+ * @param text - The text to format
55
+ * @returns Strikethrough formatted text
56
+ * @example
57
+ * ```typescript
58
+ * strikethroughMDv2("Hello") // "~Hello~"
59
+ * ```
60
+ */
61
+ export function strikethroughMDv2(text: string): string {
62
+ return `~${text}~`;
63
+ }
64
+
65
+ /**
66
+ * Formats text as spoiler in MarkdownV2
67
+ *
68
+ * @param text - The text to format
69
+ * @returns Spoiler formatted text
70
+ * @example
71
+ * ```typescript
72
+ * spoilerMDv2("Secret") // "||Secret||"
73
+ * ```
74
+ */
75
+ export function spoilerMDv2(text: string): string {
76
+ return `||${text}||`;
77
+ }
78
+
79
+ /**
80
+ * Formats text as monospace code in MarkdownV2
81
+ *
82
+ * @param text - The text to format
83
+ * @returns Code formatted text
84
+ * @example
85
+ * ```typescript
86
+ * codeMDv2("const x = 1") // "`const x = 1`"
87
+ * ```
88
+ */
89
+ export function codeMDv2(text: string): string {
90
+ return `\`${text}\``;
91
+ }
92
+
93
+ /**
94
+ * Formats text as a code block in MarkdownV2
95
+ *
96
+ * @param text - The code to format
97
+ * @param language - Optional programming language for syntax highlighting
98
+ * @returns Code block formatted text
99
+ * @example
100
+ * ```typescript
101
+ * codeBlockMDv2("console.log('Hello')") // "```console.log('Hello')```"
102
+ * codeBlockMDv2("const x = 1", "javascript") // "```javascript\nconst x = 1\n```"
103
+ * ```
104
+ */
105
+ export function codeBlockMDv2(text: string, language?: string): string {
106
+ return language ? `${language}\n${text}\n` : `${text}\n`;
107
+ }
108
+
109
+ /**
110
+ * Creates a link in MarkdownV2 format
111
+ *
112
+ * @param text - The link text
113
+ * @param url - The URL to link to
114
+ * @returns Link formatted text
115
+ * @example
116
+ * ```typescript
117
+ * linkMDv2("Google", "https://google.com") // "[Google](https://google.com)"
118
+ * ```
119
+ */
120
+ export function linkMDv2(text: string, url: string): string {
121
+ return `[${text}](${url})`;
122
+ }
123
+
124
+ /**
125
+ * Creates a user mention link in MarkdownV2 format
126
+ *
127
+ * @param userId - The user's ID
128
+ * @param name - Optional display name (ignored in MarkdownV2)
129
+ * @returns Mention formatted text
130
+ * @example
131
+ * ```typescript
132
+ * mentionMDv2(123456) // "[user](tg://user?id=123456)"
133
+ * mentionMDv2(123456, "John") // "[John](tg://user?id=123456)"
134
+ * ```
135
+ */
136
+ export function mentionMDv2(userId: number, name?: string): string {
137
+ const display = name || `user`;
138
+ return `[${display}](tg://user?id=${userId})`;
139
+ }
140
+
141
+ /**
142
+ * Creates a hashtag link in MarkdownV2 format
143
+ *
144
+ * @param tag - The hashtag text (without #)
145
+ * @returns Hashtag formatted text
146
+ * @example
147
+ * ```typescript
148
+ * hashtagMDv2("test") // "#test"
149
+ * ```
150
+ */
151
+ export function hashtagMDv2(tag: string): string {
152
+ return `#${tag}`;
153
+ }
154
+
155
+ /**
156
+ * Creates an email link in MarkdownV2 format
157
+ *
158
+ * @param email - The email address
159
+ * @returns Email link formatted text
160
+ * @example
161
+ * ```typescript
162
+ * emailMDv2("test@example.com") // "[test@example.com](mailto:test@example.com)"
163
+ * ```
164
+ */
165
+ export function emailMDv2(email: string): string {
166
+ return `[${email}](mailto:${email})`;
167
+ }
168
+
169
+ /**
170
+ * Creates a URL link in MarkdownV2 format
171
+ *
172
+ * @param url - The URL
173
+ * @returns URL link formatted text
174
+ * @example
175
+ * ```typescript
176
+ * urlMDv2("https://example.com") // "[https://example.com](https://example.com)"
177
+ * ```
178
+ */
179
+ export function urlMDv2(url: string): string {
180
+ return `[${url}](${url})`;
181
+ }
182
+
183
+ /**
184
+ * Creates a custom emoji in MarkdownV2 format
185
+ *
186
+ * Note: Custom emoji syntax in MarkdownV2 uses a special format with the emoji
187
+ * ID wrapped in special syntax.
188
+ *
189
+ * @param emojiId - The custom emoji ID
190
+ * @returns Custom emoji formatted text
191
+ * @example
192
+ * ```typescript
193
+ * customEmojiMDv2("5368324170672642286") // "👻 [Custom emoji](tg://emoji?id=5368324170672642286)"
194
+ * ```
195
+ */
196
+ export function customEmojiMDv2(emojiId: string): string {
197
+ // MarkdownV2 uses a link format for custom emojis
198
+ return `[👻](tg://emoji?id=${emojiId})`;
199
+ }
200
+
201
+ /**
202
+ * Raw MarkdownV2 string - bypasses any automatic formatting
203
+ *
204
+ * @param markdown - Pre-formatted MarkdownV2 string
205
+ * @returns The MarkdownV2 string unchanged
206
+ * @example
207
+ * ```typescript
208
+ * rawMDv2("*Hello*") // "*Hello*"
209
+ * ```
210
+ */
211
+ export function rawMDv2(markdown: string): string {
212
+ return markdown;
213
+ }
214
+
215
+ /**
216
+ * Pre-escapes text for safe use in MarkdownV2 formatting
217
+ *
218
+ * MarkdownV2 requires careful character escaping. This function escapes
219
+ * all reserved characters for safe use in formatted text.
220
+ *
221
+ * @param text - The text to escape
222
+ * @returns Escaped text safe for MarkdownV2
223
+ * @example
224
+ * ```typescript
225
+ * escapeMDv2("Hello_World") // "Hello\\_World"
226
+ * ```
227
+ */
228
+ export function escapeMDv2(text: string): string {
229
+ const reserved = "_*[]()~`>#+-=|{}.!";
230
+ let result = text;
231
+ for (const char of reserved) {
232
+ result = result.split(char).join(`\\${char}`);
233
+ }
234
+ return result;
235
+ }
@@ -40,7 +40,9 @@ describe("Formatters - fmt helpers", () => {
40
40
 
41
41
  it("should format code block", () => {
42
42
  const result = fmt.codeBlock('console.log("Hello")');
43
- expect(result).toBe('<pre><code>console.log("Hello")</code></pre>');
43
+ expect(result).toBe(
44
+ "<pre><code>console.log(&quot;Hello&quot;)</code></pre>",
45
+ );
44
46
  });
45
47
 
46
48
  it("should format code block with language", () => {
@@ -122,7 +124,7 @@ describe("Formatters - fmt helpers", () => {
122
124
  const text = "_*[]()~`>#+-=|{}.!";
123
125
  const result = fmt.escapeMarkdownV2(text);
124
126
  expect(result).toBe(
125
- "\\_\\*\\[\\]\\]\\]\\)\\~\\`\\>\\#\\+\\-\\=\\|\\{\\}\\}\\.!",
127
+ "\\_\\*\\[\\]\\(\\)\\~\\`\\>\\#\\+\\-\\=\\|\\{\\}\\.\\!",
126
128
  );
127
129
  });
128
130
 
@@ -132,9 +134,9 @@ describe("Formatters - fmt helpers", () => {
132
134
  const mdResult = fmt.escape(text, "markdown");
133
135
  const mdv2Result = fmt.escape(text, "markdownv2");
134
136
 
135
- expect(htmlResult).toContain("&lt;");
136
- expect(mdResult).toContain("<b>");
137
- expect(mdv2Result).toContain("<b>");
137
+ expect(htmlResult).toContain("&lt;"); // HTML escapes < as &lt;
138
+ expect(mdResult).toContain("<b>"); // Markdown does NOT escape <
139
+ expect(mdv2Result).toContain("<b"); // MarkdownV2 also does NOT escape < (not in reserved list)
138
140
  });
139
141
 
140
142
  it("should escape text in formatters", () => {
@@ -148,9 +150,17 @@ describe("Formatters - fmt helpers", () => {
148
150
  });
149
151
 
150
152
  describe("Combined Formatting", () => {
151
- it("should combine multiple formatters", () => {
153
+ it("should escape inner formatters (expected security behavior)", () => {
154
+ // Inner formatters get HTML-escaped by outer formatters for security
152
155
  const boldItalic = fmt.bold(fmt.italic("Text"));
153
- expect(boldItalic).toBe("<b><i>Text</i></b>");
156
+ expect(boldItalic).toBe("<b>&lt;i&gt;Text&lt;/i&gt;</b>");
157
+ });
158
+
159
+ it("raw() helper returns input unchanged for manual combining", () => {
160
+ // raw() is useful for when you want to manually combine pre-formatted strings
161
+ const preFormatted = fmt.italic("Text");
162
+ const wrapped = `<b>${fmt.raw(preFormatted)}</b>`;
163
+ expect(wrapped).toBe("<b><i>Text</i></b>");
154
164
  });
155
165
 
156
166
  it("should format a complex message", () => {
package/src/index.d.ts CHANGED
@@ -4,7 +4,9 @@ export * from "./keyboard";
4
4
  export * from "./builder";
5
5
  export type { ParseMode, FormatOpts, LineOpts, TelegramMessage, BuildResult, ValidationError, } from "./types/core.types";
6
6
  export type { IInlineKeyboardMarkup, IInlineKeyboardButton, IReplyKeyboardMarkup, IKeyboardButton, IForceReplyMarkup, } from "./types/keyboard.types";
7
+ export type { MediaSource, MediaType, IMediaCommonOptions, IMediaBuildResult, IPhotoOptions, IVideoOptions, IDocumentOptions, IAudioOptions, IVoiceOptions, } from "./types/media.types";
7
8
  export { fmt } from "./formatters";
8
9
  export { TelegramMessageBuilder } from "./builder";
9
10
  export { TelegramKeyboardBuilder } from "./keyboard";
11
+ export { TelegramMediaBuilder } from "./builder";
10
12
  //# sourceMappingURL=index.d.ts.map