telegram-inline-keyboard-builder 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,89 +1,178 @@
1
+
1
2
  export class InlineKeyboardBuilder {
2
- constructor(adapter, buttonsPerRow = 2, autoWrapMaxChars = 0) {
3
- if (!adapter) {
4
- throw new Error("InlineKeyboardBuilder requires an adapter");
5
- }
6
- this.adapter = adapter;
7
- this.buttonsPerRow = buttonsPerRow;
8
- this.autoWrapMaxChars = autoWrapMaxChars;
9
- this._buttons = [];
10
- }
11
-
12
- _pushButton(btn) {
13
- this._buttons.push(btn);
14
- return this;
15
- }
16
-
17
- addCallbackButton(text, callback_data, hide = false) {
18
- return this._pushButton(
19
- this.adapter.createCallback(text, callback_data, hide)
20
- );
21
- }
22
-
23
- addUrlButton(text, url, hide = false) {
24
- return this._pushButton(
25
- this.adapter.createUrl(text, url, hide)
26
- );
27
- }
28
-
29
- addPayButton(text, options = {}) {
30
- const hide = options.hide ?? false;
31
- return this._pushButton(
32
- this.adapter.createPay(text, hide)
33
- );
34
- }
35
-
36
- addCustomButton(btnObj) {
37
- return this._pushButton(btnObj);
38
- }
39
-
40
- newRow() {
41
- this._buttons.push({ __newRow: true });
42
- return this;
43
- }
44
- _layoutButtons() {
45
- const rows = [];
46
- let row = [];
47
- let rowChars = 0;
48
-
49
- const pushRow = () => {
50
- if (row.length > 0) {
51
- rows.push(row);
52
- row = [];
53
- rowChars = 0;
54
- }
55
- };
56
-
57
- for (const b of this._buttons) {
58
- if (b && b.__newRow) {
59
- pushRow();
60
- continue;
61
- }
62
-
63
- const text = b?.text || "";
64
- const len = String(text).length || 0;
65
-
66
- if (
67
- this.autoWrapMaxChars > 0 &&
68
- row.length > 0 &&
69
- rowChars + len > this.autoWrapMaxChars
70
- ) {
71
- pushRow();
72
- }
73
-
74
- if (row.length >= this.buttonsPerRow) {
75
- pushRow();
76
- }
77
-
78
- row.push(b);
79
- rowChars += len;
80
- }
81
-
82
- pushRow();
83
- return rows;
84
- }
85
-
86
- build() {
87
- return this.adapter.buildKeyboard(this._layoutButtons());
88
- }
3
+ constructor(buttonsPerRow = 2, autoWrapMaxChars = 0) {
4
+ this.buttonsPerRow = buttonsPerRow;
5
+ this.autoWrapMaxChars = autoWrapMaxChars; // 0 = disabled
6
+ this._buttons = []; // flat list of buttons + row markers
7
+ }
8
+
9
+ // ---------- internal ----------
10
+ _pushButton(btn) {
11
+ this._buttons.push(btn);
12
+ return this;
13
+ }
14
+
15
+ // ---------- button helpers ----------
16
+ addCallbackButton(text, callback_data) {
17
+ if (!text || !callback_data) {
18
+ throw new Error("Callback button requires text and callback_data");
19
+ }
20
+
21
+ return this._pushButton({
22
+ text,
23
+ callback_data,
24
+ });
25
+ }
26
+
27
+ addUrlButton(text, url) {
28
+ if (!text || !url) {
29
+ throw new Error("URL button requires text and url");
30
+ }
31
+
32
+ return this._pushButton({
33
+ text,
34
+ url,
35
+ });
36
+ }
37
+
38
+ addPayButton(text) {
39
+ if (!text) {
40
+ throw new Error("Pay button requires text");
41
+ }
42
+
43
+ return this._pushButton({
44
+ text,
45
+ pay: true,
46
+ });
47
+ }
48
+
49
+ addCustomButton(buttonObject) {
50
+ if (!buttonObject || !buttonObject.text) {
51
+ throw new Error("Custom button must be a valid InlineKeyboardButton object");
52
+ }
53
+
54
+ return this._pushButton(buttonObject);
55
+ }
56
+
57
+ // ---------- layout controls ----------
58
+ setButtonsPerRow(n) {
59
+ this.buttonsPerRow = Math.max(1, Math.floor(n));
60
+ return this;
61
+ }
62
+
63
+ setAutoWrapMaxChars(n) {
64
+ this.autoWrapMaxChars = Math.max(0, Math.floor(n));
65
+ return this;
66
+ }
67
+
68
+ newRow() {
69
+ this._buttons.push({ __newRow: true });
70
+ return this;
71
+ }
72
+
73
+ // ---------- config-based API ----------
74
+ _addButtonFromConfig(btn) {
75
+ const { type, text } = btn;
76
+
77
+ if (!type || !text) {
78
+ throw new Error("Button must have at least { type, text }");
79
+ }
80
+
81
+ switch (type) {
82
+ case "callback":
83
+ if (!btn.data) throw new Error("Callback button requires `data`");
84
+ this.addCallbackButton(text, btn.data);
85
+ break;
86
+
87
+ case "url":
88
+ if (!btn.url) throw new Error("URL button requires `url`");
89
+ this.addUrlButton(text, btn.url);
90
+ break;
91
+
92
+ case "pay":
93
+ this.addPayButton(text);
94
+ break;
95
+
96
+ case "custom":
97
+ if (!btn.button) throw new Error("Custom button requires `button`");
98
+ this.addCustomButton(btn.button);
99
+ break;
100
+
101
+ default:
102
+ throw new Error(`Unknown button type: ${type}`);
103
+ }
104
+ }
105
+
106
+ addButtons(config) {
107
+ // Case 1: array of buttons
108
+ if (Array.isArray(config)) {
109
+ for (const btn of config) {
110
+ this._addButtonFromConfig(btn);
111
+ }
112
+ return this;
113
+ }
114
+
115
+ // Case 2: grouped config
116
+ const { type, buttons } = config;
117
+ if (!type || !Array.isArray(buttons)) {
118
+ throw new Error("addButtons: invalid config");
119
+ }
120
+
121
+ for (const btn of buttons) {
122
+ this._addButtonFromConfig({ type, ...btn });
123
+ }
124
+
125
+ return this;
126
+ }
127
+
128
+ // ---------- layout engine ----------
129
+ _layoutButtons() {
130
+ const rows = [];
131
+ let row = [];
132
+ let rowChars = 0;
133
+
134
+ const pushRow = () => {
135
+ if (row.length > 0) {
136
+ rows.push(row);
137
+ row = [];
138
+ rowChars = 0;
139
+ }
140
+ };
141
+
142
+ for (const b of this._buttons) {
143
+ if (b.__newRow) {
144
+ pushRow();
145
+ continue;
146
+ }
147
+
148
+ const textLength = String(b.text || "").length;
149
+
150
+ if (
151
+ this.autoWrapMaxChars > 0 &&
152
+ row.length > 0 &&
153
+ rowChars + textLength > this.autoWrapMaxChars
154
+ ) {
155
+ pushRow();
156
+ }
157
+
158
+ if (row.length >= this.buttonsPerRow) {
159
+ pushRow();
160
+ }
161
+
162
+ row.push(b);
163
+ rowChars += textLength;
164
+ }
165
+
166
+ pushRow();
167
+ return rows;
168
+ }
169
+
170
+ // ---------- final output ----------
171
+ build() {
172
+ return {
173
+ reply_markup: {
174
+ inline_keyboard: this._layoutButtons(),
175
+ },
176
+ };
177
+ }
89
178
  }
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "telegram-inline-keyboard-builder",
3
- "version": "1.1.2",
3
+ "version": "2.0.0",
4
4
  "description": "Universal inline keyboard builder for Telegram APIs",
5
- "main": "builders/InlineKeyboardTelegraf.js",
5
+ "main": "core/InlineKeyboardBuilder.js",
6
6
  "type": "module",
7
7
  "keywords": [
8
8
  "telegram",
9
9
  "inline-keyboard",
10
10
  "telegraf",
11
- "aiogram",
11
+ "puregram",
12
+ "telebot",
12
13
  "builder",
13
- "python-telegram-bot",
14
+ "telegram-bot",
14
15
  "node-telegram-bot-api"
15
16
  ],
16
17
  "author": "neoncraftx",
@@ -1,21 +0,0 @@
1
- export class NodeTelegramInlineAdapter {
2
- createCallback(text, data) {
3
- return { text, callback_data: data };
4
- }
5
-
6
- createUrl(text, url) {
7
- return { text, url };
8
- }
9
-
10
- createPay(text) {
11
- return { text, pay: true };
12
- }
13
-
14
- buildKeyboard(rows) {
15
- return {
16
- reply_markup: {
17
- inline_keyboard: rows
18
- }
19
- };
20
- }
21
- }
@@ -1,17 +0,0 @@
1
- import { InlineKeyboard } from "puregram";
2
-
3
- export class PuregramInlineAdapter {
4
- createCallback(text, data) {
5
- return InlineKeyboard.textButton({ text, payload: data });
6
- }
7
- createUrl(text, url) {
8
- return InlineKeyboard.urlButton({ text, url });
9
- }
10
- createPay(text) {
11
- return InlineKeyboard.payButton({ text });
12
- }
13
- buildKeyboard(rows) {
14
- // maps array of rows of buttons en structure puregram
15
- return InlineKeyboard.keyboard(rows.map(r => r.map(btn => btn)));
16
- }
17
- }
@@ -1,14 +0,0 @@
1
- export class TelebotInlineAdapter {
2
- createCallback(text, data) {
3
- return { text, callback: data };
4
- }
5
- createUrl(text, url) {
6
- return { text, url };
7
- }
8
- createPay(text) {
9
- return { text, pay: true };
10
- }
11
- buildKeyboard(rows) {
12
- return Telebot.inlineKeyboard(rows);
13
- }
14
- }
@@ -1,19 +0,0 @@
1
- import { Markup } from "telegraf";
2
-
3
- export class TelegrafInlineAdapter {
4
- createCallback(text, data, hide = false) {
5
- return Markup.button.callback(text, data, hide);
6
- }
7
-
8
- createUrl(text, url, hide = false) {
9
- return Markup.button.url(text, url, hide);
10
- }
11
-
12
- createPay(text, hide = false) {
13
- return Markup.button.pay(text, hide);
14
- }
15
-
16
- buildKeyboard(rows) {
17
- return Markup.inlineKeyboard(rows);
18
- }
19
- }
@@ -1,13 +0,0 @@
1
-
2
- import { InlineKeyboardBuilder } from "../core/InlineKeyboardBuilder.js";
3
- import { NodeTelegramInlineAdapter } from "../adapters/node-telegram.adapter.js";
4
-
5
- export class InlineKeyboardNodeTelegram extends InlineKeyboardBuilder {
6
- constructor(options = {}) {
7
- super(
8
- new NodeTelegramInlineAdapter(),
9
- options.buttonsPerRow,
10
- options.autoWrapMaxChars
11
- );
12
- }
13
- }
@@ -1,12 +0,0 @@
1
- import { InlineKeyboardBuilder } from "../core/InlineKeyboardBuilder.js";
2
- import { PuregramInlineAdapter } from "../adapters/puregram.adapter.js";
3
-
4
- export class InlineKeyboardPuregram extends InlineKeyboardBuilder {
5
- constructor(options = {}) {
6
- super(
7
- new PuregramInlineAdapter(),
8
- options.buttonsPerRow,
9
- options.autoWrapMaxChars
10
- );
11
- }
12
- }
@@ -1,12 +0,0 @@
1
- import { InlineKeyboardBuilder } from "../core/InlineKeyboardBuilder.js";
2
- import { TelebotInlineAdapter } from "../adapters/telebot.adapter.js";
3
-
4
- export class InlineKeyboardTelegraf extends InlineKeyboardBuilder {
5
- constructor(options = {}) {
6
- super(
7
- new TelebotInlineAdapter(),
8
- options.buttonsPerRow,
9
- options.autoWrapMaxChars
10
- );
11
- }
12
- }
@@ -1,12 +0,0 @@
1
- import { InlineKeyboardBuilder } from "../core/InlineKeyboardBuilder.js";
2
- import { TelegrafInlineAdapter } from "../adapters/telegraf.adapter.js";
3
-
4
- export class InlineKeyboardTelegraf extends InlineKeyboardBuilder {
5
- constructor(options = {}) {
6
- super(
7
- new TelegrafInlineAdapter(),
8
- options.buttonsPerRow,
9
- options.autoWrapMaxChars
10
- );
11
- }
12
- }