@mks2508/telegram-message-builder 0.2.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 (44) hide show
  1. package/dist/index.cjs +445 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.js +422 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +39 -0
  6. package/src/builder/builder.d.ts +33 -0
  7. package/src/builder/builder.d.ts.map +1 -0
  8. package/src/builder/builder.ts +124 -0
  9. package/src/builder/index.d.ts +2 -0
  10. package/src/builder/index.d.ts.map +1 -0
  11. package/src/builder/index.ts +1 -0
  12. package/src/escaping.test.ts +133 -0
  13. package/src/formatters/index.d.ts +40 -0
  14. package/src/formatters/index.d.ts.map +1 -0
  15. package/src/formatters/index.ts +117 -0
  16. package/src/formatters.test.ts +163 -0
  17. package/src/index.d.ts +10 -0
  18. package/src/index.d.ts.map +1 -0
  19. package/src/index.ts +22 -0
  20. package/src/keyboard/index.d.ts +114 -0
  21. package/src/keyboard/index.d.ts.map +1 -0
  22. package/src/keyboard/index.ts +286 -0
  23. package/src/keyboard.test.ts +217 -0
  24. package/src/types/constants.d.ts +14 -0
  25. package/src/types/constants.d.ts.map +1 -0
  26. package/src/types/constants.ts +15 -0
  27. package/src/types/core.types.d.ts +75 -0
  28. package/src/types/core.types.d.ts.map +1 -0
  29. package/src/types/core.types.ts +80 -0
  30. package/src/types/index.d.ts +4 -0
  31. package/src/types/index.d.ts.map +1 -0
  32. package/src/types/index.ts +3 -0
  33. package/src/types/keyboard-types.index.d.ts +2 -0
  34. package/src/types/keyboard-types.index.d.ts.map +1 -0
  35. package/src/types/keyboard-types.index.ts +1 -0
  36. package/src/types/keyboard.types.d.ts +96 -0
  37. package/src/types/keyboard.types.d.ts.map +1 -0
  38. package/src/types/keyboard.types.ts +95 -0
  39. package/src/types/main.types.d.ts +23 -0
  40. package/src/types/main.types.d.ts.map +1 -0
  41. package/src/types/main.types.ts +25 -0
  42. package/src/utils/index.d.ts +6 -0
  43. package/src/utils/index.d.ts.map +1 -0
  44. package/src/utils/index.ts +5 -0
@@ -0,0 +1,133 @@
1
+ import { describe, it, expect } from "bun:test";
2
+ import { fmt } from "../src";
3
+
4
+ describe("Escaping", () => {
5
+ describe("HTML Escaping", () => {
6
+ it("should escape ampersand", () => {
7
+ expect(fmt.escapeHTML("&")).toBe("&");
8
+ });
9
+
10
+ it("should escape less than", () => {
11
+ expect(fmt.escapeHTML("<")).toBe("&lt;");
12
+ });
13
+
14
+ it("should escape greater than", () => {
15
+ expect(fmt.escapeHTML(">")).toBe("&gt;");
16
+ });
17
+
18
+ it("should escape quote", () => {
19
+ expect(fmt.escapeHTML('"')).toBe("&quot;");
20
+ });
21
+
22
+ it("should escape multiple characters", () => {
23
+ expect(fmt.escapeHTML('<b>&"x"</b>')).toBe(
24
+ "&lt;b&gt;&amp;&quot;x&quot;&lt;/b&gt;",
25
+ );
26
+ });
27
+
28
+ it("should escape in bold formatter", () => {
29
+ const result = fmt.bold('<script>alert("xss")</script>');
30
+ expect(result).toBe(
31
+ "<b>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</b>",
32
+ );
33
+ });
34
+
35
+ it("should escape in link formatter", () => {
36
+ const result = fmt.link("Click <here>", "https://example.com?a=1&b=2");
37
+ expect(result).toContain("&lt;here&gt;");
38
+ expect(result).toContain("a=1&amp;b=2");
39
+ });
40
+ });
41
+
42
+ describe("Markdown Escaping", () => {
43
+ it("should escape underscore", () => {
44
+ expect(fmt.escapeMarkdown("_")).toBe("\\_");
45
+ });
46
+
47
+ it("should escape asterisk", () => {
48
+ expect(fmt.escapeMarkdown("*")).toBe("\\*");
49
+ });
50
+
51
+ it("should escape backtick", () => {
52
+ expect(fmt.escapeMarkdown("`")).toBe("\\`");
53
+ });
54
+
55
+ it("should escape square bracket", () => {
56
+ expect(fmt.escapeMarkdown("[")).toBe("\\[");
57
+ });
58
+
59
+ it("should escape multiple markdown characters", () => {
60
+ expect(fmt.escapeMarkdown("*bold* _italic_ `code`")).toBe(
61
+ "\\*bold\\* \\_italic\\_ \\`code\\`",
62
+ );
63
+ });
64
+ });
65
+
66
+ describe("MarkdownV2 Escaping", () => {
67
+ it("should escape all reserved characters", () => {
68
+ const reserved = "_*[]()~`>#+-=|{}.!";
69
+ const result = fmt.escapeMarkdownV2(reserved);
70
+ expect(result).toBe(
71
+ "\\_\\*\\[\\]\\]\\)\\~\\`\\>\\#\\+\\-\\=\\|\\{\\}\\}.\\!",
72
+ );
73
+ });
74
+
75
+ it("should not escape regular text", () => {
76
+ const result = fmt.escapeMarkdownV2("Hello World 123");
77
+ expect(result).toBe("Hello World 123");
78
+ });
79
+
80
+ it("should escape complex markdown", () => {
81
+ const text = "Click [link](url) or see *bold* text";
82
+ const result = fmt.escapeMarkdownV2(text);
83
+ expect(result).toContain("\\[");
84
+ expect(result).toContain("\\*");
85
+ });
86
+ });
87
+
88
+ describe("Edge Cases", () => {
89
+ it("should escape empty string", () => {
90
+ expect(fmt.escapeHTML("")).toBe("");
91
+ expect(fmt.escapeMarkdown("")).toBe("");
92
+ expect(fmt.escapeMarkdownV2("")).toBe("");
93
+ });
94
+
95
+ it("should escape string with no special chars", () => {
96
+ const text = "Hello World 123";
97
+ expect(fmt.escapeHTML(text)).toBe(text);
98
+ });
99
+
100
+ it("should escape repeated special chars", () => {
101
+ const text = "<<<>>>";
102
+ expect(fmt.escapeHTML(text)).toBe("&lt;&lt;&lt;&gt;&gt;&gt;");
103
+ });
104
+
105
+ it("should handle unicode in escaping", () => {
106
+ const text = "🎉 & 🎊";
107
+ expect(fmt.escapeHTML(text)).toBe("🎉 &amp; 🎊");
108
+ });
109
+ });
110
+
111
+ describe("Mode Selection", () => {
112
+ it("should select HTML mode", () => {
113
+ const text = "<b>Hello</b>";
114
+ expect(fmt.escape(text, "html")).toContain("&lt;");
115
+ });
116
+
117
+ it("should select Markdown mode", () => {
118
+ const text = "*Hello*";
119
+ expect(fmt.escape(text, "markdown")).toContain("\\*");
120
+ });
121
+
122
+ it("should select MarkdownV2 mode", () => {
123
+ const text = "[]()~`>#+-=|{}.!";
124
+ const result = fmt.escape(text, "markdownv2");
125
+ expect(result).toBe("\\[\\]\\)\\~\\`\\>\\#\\+\\-\\=\\|\\{\\}\\}.\\!");
126
+ });
127
+
128
+ it("should default to HTML mode", () => {
129
+ const text = "<b>Hello</b>";
130
+ expect(fmt.escape(text)).toContain("&lt;");
131
+ });
132
+ });
133
+ });
@@ -0,0 +1,40 @@
1
+ import type { ParseMode } from "../types";
2
+ export declare function escapeHTML(text: string): string;
3
+ export declare function escapeMarkdown(text: string): string;
4
+ export declare function escapeMarkdownV2(text: string): string;
5
+ export declare function bold(text: string): string;
6
+ export declare function italic(text: string): string;
7
+ export declare function underline(text: string): string;
8
+ export declare function strikethrough(text: string): string;
9
+ export declare function spoiler(text: string): string;
10
+ export declare function code(text: string): string;
11
+ export declare function pre(text: string): string;
12
+ export declare function codeBlock(text: string, language?: string): string;
13
+ export declare function link(text: string, url: string): string;
14
+ export declare function mention(userId: number, name?: string): string;
15
+ export declare function hashtag(tag: string): string;
16
+ export declare function customEmoji(emojiId: string): string;
17
+ export declare function email(email: string): string;
18
+ export declare function url(link: string): string;
19
+ export declare function escape(text: string, mode?: ParseMode): string;
20
+ export declare const fmt: {
21
+ bold: typeof bold;
22
+ italic: typeof italic;
23
+ underline: typeof underline;
24
+ strikethrough: typeof strikethrough;
25
+ spoiler: typeof spoiler;
26
+ code: typeof code;
27
+ pre: typeof pre;
28
+ codeBlock: typeof codeBlock;
29
+ link: typeof link;
30
+ mention: typeof mention;
31
+ hashtag: typeof hashtag;
32
+ email: typeof email;
33
+ url: typeof url;
34
+ customEmoji: typeof customEmoji;
35
+ escape: typeof escape;
36
+ escapeHTML: typeof escapeHTML;
37
+ escapeMarkdown: typeof escapeMarkdown;
38
+ escapeMarkdownV2: typeof escapeMarkdownV2;
39
+ };
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAIjE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,SAAkB,GAAG,MAAM,CASrE;AAED,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;CAmBf,CAAC"}
@@ -0,0 +1,117 @@
1
+ import type { ParseMode } from "../types";
2
+
3
+ export function escapeHTML(text: string): string {
4
+ return text
5
+ .replace(/&/g, "&amp;")
6
+ .replace(/</g, "&lt;")
7
+ .replace(/>/g, "&gt;")
8
+ .replace(/"/g, "&quot;");
9
+ }
10
+
11
+ export function escapeMarkdown(text: string): string {
12
+ return text
13
+ .replace(/_/g, "\\_")
14
+ .replace(/\*/g, "\\*")
15
+ .replace(/`/g, "\\`")
16
+ .replace(/\[/g, "\\[");
17
+ }
18
+
19
+ export function escapeMarkdownV2(text: string): string {
20
+ const reserved = "_*[]()~`>#+-=|{}.!";
21
+ let result = text;
22
+ for (const char of reserved) {
23
+ result = result.split(char).join(`\\${char}`);
24
+ }
25
+ return result;
26
+ }
27
+
28
+ export function bold(text: string): string {
29
+ return `<b>${escapeHTML(text)}</b>`;
30
+ }
31
+
32
+ export function italic(text: string): string {
33
+ return `<i>${escapeHTML(text)}</i>`;
34
+ }
35
+
36
+ export function underline(text: string): string {
37
+ return `<u>${escapeHTML(text)}</u>`;
38
+ }
39
+
40
+ export function strikethrough(text: string): string {
41
+ return `<s>${escapeHTML(text)}</s>`;
42
+ }
43
+
44
+ export function spoiler(text: string): string {
45
+ return `<tg-spoiler>${escapeHTML(text)}</tg-spoiler>`;
46
+ }
47
+
48
+ export function code(text: string): string {
49
+ return `<code>${escapeHTML(text)}</code>`;
50
+ }
51
+
52
+ export function pre(text: string): string {
53
+ return `<pre>${escapeHTML(text)}</pre>`;
54
+ }
55
+
56
+ export function codeBlock(text: string, language?: string): string {
57
+ return language
58
+ ? `<pre><code class="language-${language}">${escapeHTML(text)}</code></pre>`
59
+ : `<pre>${escapeHTML(text)}</pre>`;
60
+ }
61
+
62
+ export function link(text: string, url: string): string {
63
+ return `<a href="${escapeHTML(url)}">${escapeHTML(text)}</a>`;
64
+ }
65
+
66
+ export function mention(userId: number, name?: string): string {
67
+ const display = name ? escapeHTML(name) : escapeHTML(`user${userId}`);
68
+ return `<a href="tg://user?id=${userId}">${display}</a>`;
69
+ }
70
+
71
+ export function hashtag(tag: string): string {
72
+ return `<a href="tg://hashtag?tag=${escapeHTML(tag)}">#${escapeHTML(tag)}</a>`;
73
+ }
74
+
75
+ export function customEmoji(emojiId: string): string {
76
+ return `<tg-emoji emoji-id="${escapeHTML(emojiId)}">👻</tg-emoji>`;
77
+ }
78
+
79
+ export function email(email: string): string {
80
+ return `<a href="mailto:${escapeHTML(email)}">${escapeHTML(email)}</a>`;
81
+ }
82
+
83
+ export function url(link: string): string {
84
+ return `<a href="${escapeHTML(link)}">${escapeHTML(link)}</a>`;
85
+ }
86
+
87
+ export function escape(text: string, mode: ParseMode = "html"): string {
88
+ switch (mode) {
89
+ case "html":
90
+ return escapeHTML(text);
91
+ case "markdown":
92
+ return escapeMarkdown(text);
93
+ case "markdownv2":
94
+ return escapeMarkdownV2(text);
95
+ }
96
+ }
97
+
98
+ export const fmt = {
99
+ bold,
100
+ italic,
101
+ underline,
102
+ strikethrough,
103
+ spoiler,
104
+ code,
105
+ pre,
106
+ codeBlock,
107
+ link,
108
+ mention,
109
+ hashtag,
110
+ email,
111
+ url,
112
+ customEmoji,
113
+ escape,
114
+ escapeHTML,
115
+ escapeMarkdown,
116
+ escapeMarkdownV2,
117
+ };
@@ -0,0 +1,163 @@
1
+ import { describe, it, expect } from "bun:test";
2
+ import { fmt } from "../src";
3
+
4
+ describe("Formatters - fmt helpers", () => {
5
+ describe("HTML Formatting", () => {
6
+ it("should format bold text", () => {
7
+ const result = fmt.bold("Hello");
8
+ expect(result).toBe("<b>Hello</b>");
9
+ });
10
+
11
+ it("should format italic text", () => {
12
+ const result = fmt.italic("Hello");
13
+ expect(result).toBe("<i>Hello</i>");
14
+ });
15
+
16
+ it("should format underlined text", () => {
17
+ const result = fmt.underline("Hello");
18
+ expect(result).toBe("<u>Hello</u>");
19
+ });
20
+
21
+ it("should format strikethrough text", () => {
22
+ const result = fmt.strikethrough("Hello");
23
+ expect(result).toBe("<s>Hello</s>");
24
+ });
25
+
26
+ it("should format spoiler text", () => {
27
+ const result = fmt.spoiler("Secret");
28
+ expect(result).toBe("<tg-spoiler>Secret</tg-spoiler>");
29
+ });
30
+
31
+ it("should format code text", () => {
32
+ const result = fmt.code("const x = 1");
33
+ expect(result).toBe("<code>const x = 1</code>");
34
+ });
35
+
36
+ it("should format preformatted text", () => {
37
+ const result = fmt.pre("line1\nline2");
38
+ expect(result).toBe("<pre>line1\nline2</pre>");
39
+ });
40
+
41
+ it("should format code block", () => {
42
+ const result = fmt.codeBlock('console.log("Hello")');
43
+ expect(result).toBe('<pre><code>console.log("Hello")</code></pre>');
44
+ });
45
+
46
+ it("should format code block with language", () => {
47
+ const result = fmt.codeBlock("const x = 1", "javascript");
48
+ expect(result).toBe(
49
+ '<pre><code class="language-javascript">const x = 1</code></pre>',
50
+ );
51
+ });
52
+ });
53
+
54
+ describe("Links and Mentions", () => {
55
+ it("should format link", () => {
56
+ const result = fmt.link("Google", "https://google.com");
57
+ expect(result).toBe('<a href="https://google.com">Google</a>');
58
+ });
59
+
60
+ it("should format mention", () => {
61
+ const result = fmt.mention(123456);
62
+ expect(result).toBe('<a href="tg://user?id=123456">user123456</a>');
63
+ });
64
+
65
+ it("should format mention with name", () => {
66
+ const result = fmt.mention(123456, "John Doe");
67
+ expect(result).toBe('<a href="tg://user?id=123456">John Doe</a>');
68
+ });
69
+
70
+ it("should format hashtag", () => {
71
+ const result = fmt.hashtag("test");
72
+ expect(result).toBe('<a href="tg://hashtag?tag=test">#test</a>');
73
+ });
74
+
75
+ it("should format email", () => {
76
+ const result = fmt.email("test@example.com");
77
+ expect(result).toBe(
78
+ '<a href="mailto:test@example.com">test@example.com</a>',
79
+ );
80
+ });
81
+
82
+ it("should format URL", () => {
83
+ const result = fmt.url("https://example.com");
84
+ expect(result).toBe(
85
+ '<a href="https://example.com">https://example.com</a>',
86
+ );
87
+ });
88
+
89
+ it("should format custom emoji", () => {
90
+ const result = fmt.customEmoji("5368324170672642286");
91
+ expect(result).toContain('<tg-emoji emoji-id="5368324170672642286">');
92
+ });
93
+ });
94
+
95
+ describe("Escaping", () => {
96
+ it("should escape HTML", () => {
97
+ const text = '<b>Hello</b> & "World"';
98
+ const result = fmt.escapeHTML(text);
99
+ expect(result).toBe("&lt;b&gt;Hello&lt;/b&gt; &amp; &quot;World&quot;");
100
+ });
101
+
102
+ it("should escape Markdown", () => {
103
+ const text = "*Hello* _World_ `code` [link]";
104
+ const result = fmt.escapeMarkdown(text);
105
+ expect(result).toContain("\\*");
106
+ expect(result).toContain("\\_");
107
+ expect(result).toContain("\\`");
108
+ expect(result).toContain("\\[");
109
+ });
110
+
111
+ it("should escape MarkdownV2", () => {
112
+ const text = "*Hello* _World_ `code` [link]";
113
+ const result = fmt.escapeMarkdownV2(text);
114
+ expect(result).toContain("\\*");
115
+ expect(result).toContain("\\_");
116
+ expect(result).toContain("\\`");
117
+ expect(result).toContain("\\[");
118
+ expect(result).toContain("\\]");
119
+ });
120
+
121
+ it("should escape all reserved chars in MarkdownV2", () => {
122
+ const text = "_*[]()~`>#+-=|{}.!";
123
+ const result = fmt.escapeMarkdownV2(text);
124
+ expect(result).toBe(
125
+ "\\_\\*\\[\\]\\]\\]\\)\\~\\`\\>\\#\\+\\-\\=\\|\\{\\}\\}\\.!",
126
+ );
127
+ });
128
+
129
+ it("should escape with mode parameter", () => {
130
+ const text = "<b>Hello</b>";
131
+ const htmlResult = fmt.escape(text, "html");
132
+ const mdResult = fmt.escape(text, "markdown");
133
+ const mdv2Result = fmt.escape(text, "markdownv2");
134
+
135
+ expect(htmlResult).toContain("&lt;");
136
+ expect(mdResult).toContain("<b>");
137
+ expect(mdv2Result).toContain("<b>");
138
+ });
139
+
140
+ it("should escape text in formatters", () => {
141
+ const boldResult = fmt.bold("<b>Hello</b>");
142
+ expect(boldResult).toContain("&lt;b&gt;");
143
+ expect(boldResult).toContain("&lt;/b&gt;");
144
+
145
+ const linkResult = fmt.link("Text", "https://example.com?x=1&y=2");
146
+ expect(linkResult).toContain("https://example.com?x=1&amp;y=2");
147
+ });
148
+ });
149
+
150
+ describe("Combined Formatting", () => {
151
+ it("should combine multiple formatters", () => {
152
+ const boldItalic = fmt.bold(fmt.italic("Text"));
153
+ expect(boldItalic).toBe("<b><i>Text</i></b>");
154
+ });
155
+
156
+ it("should format a complex message", () => {
157
+ const message = `${fmt.bold("Title")}\n\n${fmt.code("const x = 1")}\n\nLink: ${fmt.link("Click here", "https://example.com")}`;
158
+ expect(message).toContain("<b>Title</b>");
159
+ expect(message).toContain("<code>const x = 1</code>");
160
+ expect(message).toContain('<a href="https://example.com">Click here</a>');
161
+ });
162
+ });
163
+ });
package/src/index.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export * from "./types";
2
+ export * from "./formatters";
3
+ export * from "./keyboard";
4
+ export * from "./builder";
5
+ export type { ParseMode, FormatOpts, LineOpts, TelegramMessage, BuildResult, ValidationError, } from "./types/core.types";
6
+ export type { IInlineKeyboardMarkup, IInlineKeyboardButton, IReplyKeyboardMarkup, IKeyboardButton, IForceReplyMarkup, } from "./types/keyboard.types";
7
+ export { fmt } from "./formatters";
8
+ export { TelegramMessageBuilder } from "./builder";
9
+ export { TelegramKeyboardBuilder } from "./keyboard";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,YAAY,EACV,SAAS,EACT,UAAU,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
package/src/index.ts ADDED
@@ -0,0 +1,22 @@
1
+ export * from "./types";
2
+ export * from "./formatters";
3
+ export * from "./keyboard";
4
+ export * from "./builder";
5
+ export type {
6
+ ParseMode,
7
+ FormatOpts,
8
+ LineOpts,
9
+ TelegramMessage,
10
+ BuildResult,
11
+ ValidationError,
12
+ } from "./types/core.types";
13
+ export type {
14
+ IInlineKeyboardMarkup,
15
+ IInlineKeyboardButton,
16
+ IReplyKeyboardMarkup,
17
+ IKeyboardButton,
18
+ IForceReplyMarkup,
19
+ } from "./types/keyboard.types";
20
+ export { fmt } from "./formatters";
21
+ export { TelegramMessageBuilder } from "./builder";
22
+ export { TelegramKeyboardBuilder } from "./keyboard";
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @fileoverview Keyboard Builders
3
+ * @description Fluent API for building Telegram keyboards
4
+ * @module telegram-message-builder/keyboard
5
+ */
6
+ import type { IInlineKeyboardMarkup, IInlineKeyboardButton, IReplyKeyboardMarkup, IKeyboardButton, IForceReplyMarkup } from "../types";
7
+ /**
8
+ * Telegram Keyboard Builder - Fluent API for building keyboards
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const keyboard = TelegramKeyboardBuilder.inline()
13
+ * .urlButton('Google', 'https://google.com')
14
+ * .row()
15
+ * .callbackButton('Yes', 'yes')
16
+ * .callbackButton('No', 'no')
17
+ * .buildMarkup()
18
+ * ```
19
+ */
20
+ export declare class TelegramKeyboardBuilder {
21
+ private rows;
22
+ private type;
23
+ private currentRow;
24
+ private constructor();
25
+ /**
26
+ * Create an inline keyboard builder
27
+ */
28
+ static inline(): TelegramKeyboardBuilder;
29
+ /**
30
+ * Create a reply keyboard builder
31
+ */
32
+ static reply(): TelegramKeyboardBuilder;
33
+ /**
34
+ * Create a force reply builder
35
+ */
36
+ static forceReply(): TelegramKeyboardBuilder;
37
+ /**
38
+ * Add a URL button (inline only)
39
+ */
40
+ urlButton(text: string, url: string): this;
41
+ /**
42
+ * Add a callback button (inline only)
43
+ */
44
+ callbackButton(text: string, data: string): this;
45
+ /**
46
+ * Add a web app button (inline only)
47
+ */
48
+ webAppButton(text: string, url: string): this;
49
+ /**
50
+ * Add a login button (inline only)
51
+ */
52
+ loginButton(text: string, url: string, options?: {
53
+ forwardText?: string;
54
+ botUsername?: string;
55
+ requestWriteAccess?: boolean;
56
+ }): this;
57
+ /**
58
+ * Add a switch inline query button (inline only)
59
+ */
60
+ switchInlineQueryButton(text: string, query: string): this;
61
+ /**
62
+ * Add a switch inline query current chat button (inline only)
63
+ */
64
+ switchInlineQueryCurrentChatButton(text: string, query: string): this;
65
+ /**
66
+ * Add a callback game button (inline only)
67
+ */
68
+ callbackGameButton(text: string, shortName: string): this;
69
+ /**
70
+ * Add a pay button (inline only)
71
+ */
72
+ payButton(text: string): this;
73
+ /**
74
+ * Add a text button (reply keyboard only)
75
+ */
76
+ textButton(text: string): this;
77
+ /**
78
+ * Add a request contact button (reply keyboard only)
79
+ */
80
+ requestContactButton(text: string): this;
81
+ /**
82
+ * Add a request location button (reply keyboard only)
83
+ */
84
+ requestLocationButton(text: string): this;
85
+ /**
86
+ * Add a request poll button (reply keyboard only)
87
+ */
88
+ requestPollButton(text: string, pollType: string): this;
89
+ /**
90
+ * Add a custom button to current row
91
+ */
92
+ button(button: IInlineKeyboardButton | IKeyboardButton): this;
93
+ /**
94
+ * Finish current row and start a new one
95
+ */
96
+ row(): this;
97
+ /**
98
+ * Build inline keyboard markup
99
+ */
100
+ buildMarkup(): IInlineKeyboardMarkup;
101
+ /**
102
+ * Build reply keyboard markup
103
+ */
104
+ buildReplyMarkup(): IReplyKeyboardMarkup;
105
+ /**
106
+ * Build force reply markup
107
+ */
108
+ buildForceReplyMarkup(): IForceReplyMarkup;
109
+ /**
110
+ * Build markup based on keyboard type
111
+ */
112
+ build(): IInlineKeyboardMarkup | IReplyKeyboardMarkup | IForceReplyMarkup;
113
+ }
114
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;GAYG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,IAAI,CAAuD;IACnE,OAAO,CAAC,IAAI,CAA0C;IACtD,OAAO,CAAC,UAAU,CAAmD;IAErE,OAAO,eAEN;IAED;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,uBAAuB,CAEvC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,uBAAuB,CAEtC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,uBAAuB,CAE3C;IAED;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAMzC;IAED;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAM/C;IAED;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAM5C;IAED;;OAEG;IACH,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,GACA,IAAI,CAcN;IAED;;OAEG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQzD;IAED;;OAEG;IACH,kCAAkC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQpE;IAED;;OAEG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAQxD;IAED;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM5B;IAED;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM7B;IAED;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQvC;IAED;;OAEG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQxC;IAED;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQtD;IAED;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,GAAG,IAAI,CAG5D;IAED;;OAEG;IACH,GAAG,IAAI,IAAI,CAMV;IAED;;OAEG;IACH,WAAW,IAAI,qBAAqB,CAOnC;IAED;;OAEG;IACH,gBAAgB,IAAI,oBAAoB,CAYvC;IAED;;OAEG;IACH,qBAAqB,IAAI,iBAAiB,CAEzC;IAED;;OAEG;IACH,KAAK,IAAI,qBAAqB,GAAG,oBAAoB,GAAG,iBAAiB,CASxE;CACF"}